mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
fix(testrun): the refusal asks whether the generator drove, not whether anything did
A dead provider against folio exited 0 on a real emulator: the login setup dispatched three actions before the generator was consulted, so DispatchedActions was 3 and the gate never fired while the generator drove the app zero times across 83 steps. Any spec with a login setup was immune, which is the normal case. Summary counts generator actions separately and the refusal reads that. NoActionsDispatchedError becomes NoGeneratorActionsError, because a run that dispatched three login taps was lying in the old name.
This commit is contained in:
1 parent
5a36b583ea
commit
58168a6a3e
6 files changed
+274
-29
No files matched your search
+23
-18
@@ -265,13 +265,16 @@ func Execute(ctx context.Context, options Options, stdout io.Writer) error {
|
||||
// fraction of them: a screen that composes now and then costs a healthy android
|
||||
// run a step or two, and a check that fired on those would be red on every run.
|
||||
//
|
||||
// A run that dispatched no action at all fails on the same grounds, and the
|
||||
// A run whose generator dispatched no action fails on the same grounds, and the
|
||||
// threshold is zero for the same reason: a generator with nothing to offer on
|
||||
// some screens is ordinary, one with nothing to offer on every screen of a whole
|
||||
// run drove nothing. --exit-on-violation keeps precedence over it so a run that
|
||||
// found something still exits on its evidence, and the property-free opt-out
|
||||
// exempts the sweeps, whose measurement is where a generator reaches and for
|
||||
// which "nowhere on this build" is a result rather than a broken run.
|
||||
// run drove nothing. The count is the generator's alone because a spec's setup
|
||||
// drives the app before the generator is consulted, so a login that ran leaves
|
||||
// dispatched actions behind whatever the generator then did.
|
||||
// --exit-on-violation keeps precedence over it so a run that found something
|
||||
// still exits on its evidence, and the property-free opt-out exempts the sweeps,
|
||||
// whose measurement is where a generator reaches and for which "nowhere on this
|
||||
// build" is a result rather than a broken run.
|
||||
func runOutcome(options Options, summary runner.Summary) error {
|
||||
if summary.Steps > 0 && summary.SkippedVerification == summary.Steps {
|
||||
return VacuousRunError{Steps: summary.Steps}
|
||||
@@ -279,8 +282,8 @@ func runOutcome(options Options, summary runner.Summary) error {
|
||||
if options.ExitOnViolation && len(summary.Violations) > 0 {
|
||||
return ViolationsError{Count: len(summary.Violations)}
|
||||
}
|
||||
if !options.AllowNoProperties && summary.Steps > 0 && summary.DispatchedActions == 0 {
|
||||
return NoActionsDispatchedError{
|
||||
if !options.AllowNoProperties && summary.Steps > 0 && summary.GeneratorActions == 0 {
|
||||
return NoGeneratorActionsError{
|
||||
Steps: summary.Steps,
|
||||
SkippedActions: summary.SkippedActions,
|
||||
}
|
||||
@@ -352,13 +355,14 @@ func (e NoPropertiesError) Error() string {
|
||||
e.Spec)
|
||||
}
|
||||
|
||||
// NoActionsDispatchedError reports a run not one of whose steps drove the app.
|
||||
// Every screen it judged was the one it launched on, so its empty violation list
|
||||
// says as much about the app as a spec with no properties would: the run
|
||||
// observed, judged the same state over and over, and exercised nothing. It stays
|
||||
// untyped to the CLI's violation path like VacuousRunError, so it exits 1 as a
|
||||
// run that holds no verdict rather than 2.
|
||||
type NoActionsDispatchedError struct {
|
||||
// NoGeneratorActionsError reports a run not one of whose steps was driven by the
|
||||
// action generator. Setup can put the app in position, but only the generator
|
||||
// explores it, so every screen this run judged was one setup left it on and its
|
||||
// empty violation list says as much about the app as a spec with no properties
|
||||
// would: the run observed, judged the same state over and over, and exercised
|
||||
// nothing. It stays untyped to the CLI's violation path like VacuousRunError, so
|
||||
// it exits 1 as a run that holds no verdict rather than 2.
|
||||
type NoGeneratorActionsError struct {
|
||||
Steps int
|
||||
// SkippedActions is the runner's per-reason count of actions that never
|
||||
// reached the app, which is where the cause is: a picker with no candidate
|
||||
@@ -366,11 +370,12 @@ type NoActionsDispatchedError struct {
|
||||
SkippedActions map[string]int
|
||||
}
|
||||
|
||||
func (e NoActionsDispatchedError) Error() string {
|
||||
func (e NoGeneratorActionsError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"%d step(s) ran and none of them dispatched an action: the run observed the app "+
|
||||
"and never drove it, so it judged its launch screen over and over and its "+
|
||||
"violation count says nothing about the rest of the app%s",
|
||||
"%d step(s) ran and the action generator drove the app in none of them: whatever "+
|
||||
"the spec's setup did to get the app into position, nothing explored it from "+
|
||||
"there, so the run judged one screen over and over and its violation count "+
|
||||
"says nothing about the rest of the app%s",
|
||||
e.Steps, skipReasonSuffix(e.SkippedActions))
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user