test: cover three modules that had no unit spec at all - #2464
Merged
Conversation
`GoRouteGroupScope`, `JSObjectConfigExtractor` and `NoirAIContext::SourceReader` had no direct unit spec — not one reference anywhere under `spec/`. All three are pure, deterministic logic sitting under decisions that matter: * `GoRouteGroupScope` resolves which URL prefix a Go middleware registration guards. `go_auth` and `go_security` both build their guarded-prefix list from it, so a wrong answer is a security-tag false positive. The specs pin the behaviours the module's header comment says it exists for: sibling assignment groups staying independent rather than accumulating into `/api/admin`, a non-literal group path resolving to `Unknown` rather than collapsing to `Global`, and a line that is both a closure and an assignment group not folding its prefix in twice. * `SourceReader` extracts the snippets the AI context is built from. Its character budget is load-bearing — a snippet truncated before the suppressing evidence turns into a false positive downstream — so the specs cover the budget and the block-boundary walk across all four styles (brace / python / ruby / bare statement), including the decorator lead-in and the indent guard behind the django `/public/` false positive. * `JSObjectConfigExtractor` decodes Payload CMS and Strapi configs. The specs cover each declaration shape its header comment claims to handle, the value decoder, and the depth guards. `code_locator.cr` referenced `NoirLogger` and `any_to_bool` without requiring either; it compiled only because every real entry point happens to require `logger.cr` first. Requiring a file's own dependencies is what makes anything downstream of it unit-testable in isolation — without it `require`-ing `source_reader.cr` alone fails to compile. 125 new examples. Full unit + functional suites and `just check` pass.
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.
Motivation
Mapping spec coverage across the tree turned up three files with no direct unit spec — not one reference anywhere under
spec/, despite being pure, deterministic logic sitting under decisions that matter:src/tagger/framework_taggers/go/group_scope.crsrc/miniparsers/js_object_config_extractor.crsrc/ai_context/source_reader.crEach was reachable only through functional tests of its callers, so a regression in the shared logic would surface (if at all) as a puzzling endpoint diff several layers away.
What's covered
GoRouteGroupScope(39 examples) —go_authandgo_securityboth build their guarded-prefix list from this module, so a wrong answer here is a security-tag false positive. The specs pin the behaviours its header comment says it exists for:apithenadminmust not resolve to/api/admin)r.Group(cfg.APIBase)) resolving toUnknownrather than collapsing toGlobal— collapsing would tag every endpoint, including the explicitly public ones, as guardedGroup(...).Use(...), andParty/Prerouter dialectsNoirAIContext::SourceReader(47 examples) — its character budget is load-bearing: a snippet truncated before the suppressing evidence becomes a false positive downstream. Covers the budget (default, caller-supplied, and the exact-fit boundary), the three caches, and the block-boundary walk across all four styles — brace / python / ruby / bare statement — including the decorator lead-in and the indent guard behind the django/public/false positive.Noir::JSObjectConfigExtractor(39 examples) — every declaration shape its header comment claims to handle (TS type annotation,satisfies, call argument,module.exports), the value decoder including the statically-unresolvable-but-key-still-recorded case, and both depth guards.Drive-by fix
src/models/code_locator.crreferencedNoirLoggerandany_to_boolwithout requiring either. It compiled only because every real entry point happens to requirelogger.crfirst —require-ingsource_reader.cron its own failed to compile. Requiring a file's own dependencies is what makes anything downstream of it unit-testable in isolation.Verification
crystal spec spec/unit_test— 4619 examples, 0 failurescrystal spec spec/functional_test— 22647 examples, 0 failuresjust check— 1842 files inspected, 0 failuresNo production behaviour changes; the only
src/edit is tworequirelines.