feat(runner): before_all, before_each, after_each, after_all hooks (#10) #28
No reviewers
Labels
No labels
area:assertions
area:cli
area:client
area:harness
area:meta
area:reporting
area:runner
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/ws-rpc-test!28
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/10-runner-hooks"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #10. Stacked on #27.
Summary
Adds the four lifecycle hooks with the exact failure semantics from the issue and spec-review §4/§5.
Semantics
before_allbefore_eachafter_eachstill runsafter_eachafter_allTestReport.after_all_failed = trueAPI
Internals
Option<BoxedTestFn>fields onTestRunner(same closure shape as test bodies).run()destructures&mut selfinto disjoint field borrows at the top, so iteratingtests.iter_mut()doesn't conflict with calling the hook closures on the side.TestReport.after_all_failed: boolfield,falseby default.Checklist (from issue #10)
before_allruns once, failure aborts the runbefore_eachruns before each test; failure marks that test Failed, body skipped,after_eachstill runsafter_eachruns after each test regardless; failure logged, outcome preservedafter_allruns once after all tests; failure logged +after_all_failedflag, harness still stopsArc<RpcClient>and returnFuture<Output = TestResult>Test plan (5 new tests)
hooks_run_in_expected_order— registers all four hooks + two tests, usesArc<Mutex<Vec<String>>>to log execution, asserts the exact sequence[before_all, before_each, t1, after_each, before_each, t2, after_each, after_all]before_all_failure_aborts_run— assertsrun()returnsErrand no test body ranbefore_each_failure_marks_test_failed_and_after_each_runs— body must NOT run,after_eachmust runafter_each_failure_is_logged_but_test_still_passes— test body isOk, status staysPassedafter_all_failure_sets_flag_but_tests_still_recorded—passed == 1,after_all_failed == truejust qagreen locally — 74/74 unit testsNotes for the reviewer
before_all) and §5 (missingafter_each). The original spec only listedbefore_each+after_all, which was insufficient for common patterns.let Self { harness, tests, .., before_each, .. } = self;) is the cleanest way I found to iteratetests.iter_mut()while also callingbefore_each(Arc::clone(&client)).awaitin the same loop. An alternative would bemem::take()ing the hooks, but destructuring is less surgical.Review — before_all, before_each, after_each, after_all hooks (#10)
Destructuring
selfpour les emprunts disjointsPattern correct pour itérer mutablement
testspendant qu'on appelle les hooks. Idiomatic Rust pour ce cas.before_eachfailure →after_eachtoujours exécutéComportement conforme au cahier des charges : si
before_eachéchoue, le corps du test est ignoré maisafter_eachtourne quand même. Le timing destarted.elapsed()est capturé avantbefore_each— le temps du hook de setup est donc inclus dans la durée reportée. C'est acceptable mais ça mérite peut-être un commentaire.Un seul hook de chaque type
Enregistrer un deuxième
before_allécrase silencieusement le premier. C'est intentionnel (doc-comment absent mais simple à ajouter). Pour v0.1 c'est suffisant. À documenter.after_all_failed— flag sans impact sur les testsBon choix de séparation des concerns : les outcomes des tests ne sont pas affectés, mais le runner peut propager ça dans le code de sortie.
Tests
hooks_run_in_expected_order: log partagé viaArc<Mutex<Vec<String>>>— pattern propre pour vérifier l'ordre d'exécution.before_all_failure_aborts_run+before_each_failure_marks_test_failed_and_after_each_runs+after_each_failure_is_logged_but_test_still_passes— les quatre variantes de failure sont couvertes.Aucun bloquant.
✅ Pas de bloquant — lifecycle des hooks correct, ordre d'exécution vérifié rigoureusement.