Summary#
Once you have chosen a kit, osy kits <kit> --surface shows how to connect it — not as a description, but as working
code. For each seam an app connects, it prints the kit's own test app declaration that connects it, verbatim — the
[On] handler, the policy line, the app.X = new … setting, the contribution to a slot — and the tests that show
that seam working. Copy the shape; --tests-for <seam> prints the tests whole.
$ osy kits Osysharp.SatisfactionSurveys --surface
Policies — your app defines these
policy ManagesFeedback; — your app defines it
Who decides whether, when and for how long people are asked — the settings page.
── tests/model/app.osy:17 ──
policy ManagesFeedback => IsOwner;
shown by tests/ui.test.osy::the_owner_decides_whether_and_when_people_are_asked · …
Events — what happens; hear one with `[On] void H(TheEvent e)`
[Event("Feedback answered")] FeedbackAnswered { Ask, Change }
Somebody answered (`FeedbackChange.First`) or changed their answer (`Changed`).
raised by ApplyFeedbackReply
── tests/model/app.osy:48 ──
/// What the workshop does as customers answer: the answer is noted on the repair.
[On]
void RepairAnswered(FeedbackAnswered e) {
if (e.Ask.About is Repair r) {
new RepairNote { Repair = r, Says = (e.Change == FeedbackChange.First ? "answered " : "changed to ")
+ (e.Ask.Rating == FeedbackRating.Bad ? "bad" : "good") };
}
}
shown by tests/answers.test.osy::a_finished_repair_asks_its_customer_and_one_click_answers · …Signature#
osy kits <kit> --surface # every seam, each with its test app code and the tests that show it
osy kits <kit> --tests-for <seam> # the tests for one seam, whole, with the test app code they call
--offline # a kit not on this machine: do not fetch its examples from its release
--project <dir> # where to look for kits (default: the current directory)
--json # { seams: [{ kind, name, signature, doc, declaredAt, examples, tests, mustBeTested }] }<kit> is a package name (Osysharp.SatisfactionSurveys), its last segment (feedback) or its directory in this repository. A
kit this project does not use yet is fetched from its newest release, so you can read it before writing the use line.
Description#
What the seams are#
| kind | what your app writes | the example shown |
|---|---|---|
| setting | app.Feedback = new FeedbackSetup { … } | the test app's line; fields with no default are marked |
| policy | policy ReadsFeedback => …; — a question the kit asks, which your app answers with its own roles | the test app's definition |
| base | a type of your own derived from the kit's (Customer : Party) — required when the base is abstract | the test app's subtype |
| grant | partial entity FeedbackAsk { security { allow create when IsStaff; } } | the test app's grant |
| event | [On] void H(TheEvent e) { … } to react after the commit | the test app's handler; who raises it |
| slot | a component : TheSlot drawn where the kit's page draws the slot | the test app's contribution |
| contract | a class implementing the kit's interface, named in its setting | the test app's implementation |
| extension | nothing — a bridge adds these members to another kit's record | the tests that read them |
| action | nothing — an action the kit offers on a record | the test app code that runs it |
| appPage | a page at the route the kit links to (appPage "/bag";) | the test app's page |
| page · hears · starts | nothing — pages the kit serves, events it hears, what it starts by itself | — |
| call | the kit's functions your test app calls | the test app code that calls it |
A bridge that completes the kit with another is listed first: it arrives by itself in an app that uses both (Bridges — a package that arrives when an app uses the two it completes).
Which test shows a seam#
The mapping is derived, never written by hand. Each test's names are followed through the test app's declarations and
the kit's — a test calls the test app's FinishRepair, which calls the kit's AskForFeedback, … which raises
FeedbackAnswered — and a test that reaches the seam in at most four steps shows it. The nearest come first; a test that
also reaches what the test app's code LEAVES BEHIND (the record a handler creates, the contribution a slot draws) comes
before one that only touches the seam.
Two things a test does without naming them count too. A test that opens a page by its address —
Ui.Visit("/orders/" + id) for [Route("/orders/{id}")] — reaches that page and everything it draws. And a setting is
shown by a test that asserts a value the test app gave it: the test app's AppName = "Studio", read back in
Assert.Equal("1 thing waiting for you in Studio", …), because a setting is usually read by work the kit delivers after
the commit, which no test calls by name.
An abstract base the kit completes itself — the shared half of two connectors it ships — is the kit's own plumbing, not a seam: an app declares a connector and never derives the base, so it is listed only where the test app does.
A seam no test shows is said to be one — no test shows it — and osy kits check reports it as KIT_SEAM_UNTESTED,
which osy publish refuses (Checking a kit composes — osy kits check).
The tests for one seam#
--tests-for <seam> prints the seam, the test app code that connects it, then up to three tests whole — the one that
shows the outcome first — and the test app's own declarations those tests call, so the arrange step is visible:
$ osy kits Osysharp.SatisfactionSurveys --tests-for FeedbackAnswered
[Event("Feedback answered")] FeedbackAnswered { Ask, Change } (event of Osysharp.SatisfactionSurveys)
── tests/model/app.osy:48 — the test app fills it ──
[On]
void RepairAnswered(FeedbackAnswered e) { … }
── tests/answers.test.osy:9 — the test ──
[Test(Workshop)]
void a_finished_repair_asks_its_customer_and_one_click_answers() {
Finish("city bike");
…
Assert.Equal(["answered good"], NotesOn("city bike"));
…
}
── tests/workshop.test.osy:… — the test app's NotesOn, which the test calls ──
…Where the examples come from#
In a repository that holds the kit, from its directory: the test app named by tests "…"; in its package.osy. For a
kit fetched from GitHub, from examples.zip, the second file of every release — osy publish uploads the test app
and its tests beside package.zip. They are not inside the package on purpose: a package's address is the hash of what
an app compiles, and a test is not compiled into anyone's app. The examples are cached beside the package, so a kit is
fetched once. A release published before kits shipped their tests says so, naming the file it did not find.
See also#
- Finding a kit, and learning one from its tests —
osy kits find: kits by what they do;osy kits <kit>: its purpose and every test - Composing kits — what they give together, and what is left for you —
osy compose: what kits give together and what is left for you - Checking a kit composes — osy kits check —
osy kits check:KIT_SEAM_UNTESTED - [Event] — what happens to a record, declared once · [On] — hear an event, after the commit that raised it — events, and hearing one
- Slot (child content) · [Slot] and contributions — a place on a page that other kits, and the app, add to — slots, and contributing to one
- settings a package asks its app for (app settings) —
app.X = new …