Disclosure: I build Reqlan. This is a walkthrough of what it does today on a tiny repo, including the bit that surprised me while writing it.
You write a requirement, agree it matters, and then nothing in the code ever points at it. Nobody deleted it. It just never got wired up. That is an orphaned requirement, and in a repo where an agent writes most of the code it is easy to end up with several.
Here's how I find one with Reqlan on a two-idea repo. Every command below was run on reqlan CLI 0.10.0 and the output is pasted as it came out.
1. The tiny repo
repo/
.reqlan/ # created by `reqlan init .`
spec.rq
src/cart.ts
src/cart.test.ts
package.json # vitest + typescript, so the test runs (`npx vitest run`)
spec.rq holds two named ideas:
cart_total {
The cart total is the sum of line prices times quantities.
implemented in ["./src/cart.ts"]
proven by ["./src/cart.test.ts"]
@status in-progress
}
free_shipping {
Orders over 50 pounds ship free.
@status in-progress
}
The code and the test pin themselves back to cart_total with an rq: comment:
// src/cart.ts
// rq:["../spec.rq".cart_total]
export function cartTotal(lines: { price: number; qty: number }[]): number {
return lines.reduce((sum, l) => sum + l.price * l.qty, 0);
}
src/cart.test.ts carries the same pin (and imports test/expect from vitest). Nothing anywhere mentions free_shipping.
2. Run the check, and notice what it doesn't say
$ reqlan check
No issues.
This is the seam I want to be upfront about. reqlan check looks for references that don't resolve: pins to ideas that don't exist, and file refs to files that aren't there. An idea with nothing pointing at it isn't a broken reference, so check is happy. On 0.10.0 it doesn't report orphans on its own.
3. Ask the graph about the idea
$ reqlan analyse -i free_shipping
## Graph (center spec.rq#free_shipping, depth 2)
### Nodes
### free_shipping (spec.rq:8)
Orders over 50 pounds ship free.
Status: in-progress
### Edges
(none)
Edges: (none) is the orphan. No implementation, no proven by, no rq: pin. Compare it with reqlan analyse -i cart_total, which lists edges to src/cart.ts and src/cart.test.ts.
4. Wire it up, and get it slightly wrong
I add the shipping code with a pin and, being me, make a typo in the name:
// src/shipping.ts
// rq:["../spec.rq".free_shiping]
export function shippingCost(total: number): number {
return total > 50 ? 0 : 4.99;
}
$ reqlan check
## Issues (1)
../spec.rq.free_shiping
- src/shipping.ts:1 [comment_link]
It exits 1, so this fails in CI. This is the part check is built for: the pin names an idea that doesn't exist.
5. Fix the name and look again
$ reqlan check
No issues.
$ reqlan analyse -i free_shipping
...
### Edges
spec.rq#free_shipping -[comment_link]-> src/shipping.ts
The idea has an edge now, so it isn't orphaned. It still has no proven by, which is the next thing I'd add.
6. Bonus: the test file goes missing
If I move src/cart.test.ts out of the repo, the proven by edge on cart_total no longer resolves:
$ reqlan check
## Issues (2)
./src/cart.test.ts
- spec.rq:4 cart_total [file_reference]
- spec.rq:4 cart_total [file_reference]
(Yes, it lists the same line twice. I've noted that as something for us to tidy up.)
What it won't do
- It checks named bindings, not meaning. If
shippingCostships free at 40 pounds, the pin still resolves andcheckstill passes. - It won't catch a pinned test that asserts
1 == 1. For test quality, use mutation testing alongside it. - It flags a missing test file, not a deleted test case inside a file that still exists. I tried
proven by ["./src/a.test.ts:does not exist case"]against a file without that case, andcheckstill saidNo issues. - The CLI resolves a symbol ref like
["./src/cart.ts".cartTotal], but the VS Code extension (1.16.0 and 1.19.0) flags it as unresolved, so this repo uses a whole-file ref. - Finding orphans is a query today (
analyse -i, orreqlan click <idea>, which showsbacklinks (0)), not acheckfailure.
Takeaway
Name the idea, pin the code to the name, and the graph tells you two different things: reqlan check catches pins and test files that point at nothing, and reqlan analyse -i shows ideas that nothing points at. Five minutes, two commands.
Docs: https://reqlan.com. (Unrelated to SPARQL, which also uses .rq.)
Reproduce it: ./replay.sh in this folder runs every step and prints the output above (saved in output.txt).
Comments
Post a Comment