feat(spec): init spec plugin#235
Draft
roxblnfk wants to merge 2 commits into
Draft
Conversation
Numbered headers now read `#[SpecHeader('5.2', 'My title')]` (number first,
matching the constructor); unnumbered ones keep the named `title:` form.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was changed
Adds a new
testo/specplugin that blends BDD, Spec-Driven and TDD: you write the behaviour a test proves right next to it, and Testo turns the suite into living documentation — and can run the tests in the order the spec describes.Write the spec next to the test
#[Spec]carries the story;#[SpecHeader]carries the heading and number (on a class it opens a numbered section, on a method it titles/pins an item):Even with no plugin registered, each fragment is published to the
spec.mdmessenger channel, so it travels with that test's output.Generate the document
Register the plugin and either pass
--spec/--spec-dir=<dir>or setcollect: true:The run is rendered into a single ordered
spec.md:Sections are sorted by number; items are auto-numbered
{section}.{n}; colliding numbers get a(1)/(2)suffix; fragments with no section number fall into an# Uncategorizedtail (bulleted when they have a header, plain paragraphs otherwise).Run tests in spec order
By default the plugin also reorders execution to match the document — Test Cases run in section-number order, tests in item-number order, unnumbered ones last. Turn it off with
new SpecPlugin(reorder: false).Under the hood
TestSuiteRunInterceptor/TestCaseRunInterceptor, backed by two newsort()methods on coreCaseDefinitions/TestDefinitions.TestSuiteFinished, so it works whether the plugin is application-wide or per-suite.composer.json,testo.php, release-please,resources/version.json,split-publish.yml) so the plugin ships as its own mirror repo on release.Why?
Projects that want SDK/framework-grade test workflows need their tests to double as the spec. This gives Testo a first-class spec-driven mode: the specification lives in the tests, the generated
spec.mdstays in sync by construction, and execution order follows the spec numbering.Checklist
🤖 Generated with Claude Code