test: cover the CSS Module class-name resolution contract (tests/css-modules.test.mjs) - #371
Merged
Merged
Conversation
A CSS Module exports only the class names its stylesheet declares, so `styles.notDeclared` is plain `undefined` property access: React renders the element with no `class` attribute, `docusaurus build` stays green, and the element silently loses its styling. src/ has 9 stylesheet importers and ~129 class references behind that unguarded invariant; no existing test reads a *.module.css. tests/css-modules.test.mjs resolves class names across the JS/CSS boundary in both directions: every referenced class must be declared, every declared class must have a reader, every import specifier must resolve, and every `composes` target must exist. The two live drifts in src/theme/Footer/ (the undeclared `.iconLink` reference and the orphan `.orgText` rule) are pinned in explicit exemption lists so they cannot spread, and two further tests assert each exemption still describes real drift, so fixing the source makes this test demand the carve-out's removal instead of leaving it to rot. Signed-off-by: kubestellar-hive[bot] <kubestellar-hive@hive.kubestellar.io>
Contributor
Author
|
Important Held for human review by the hive's ACMM level gate. This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the Hive will automatically remove the |
2 tasks
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.
Test Improvement
Adds
tests/css-modules.test.mjs, covering the CSS Module class-nameresolution contract across the JS/CSS boundary in
src/.A CSS Module exports only the class names its stylesheet declares, so
styles.notDeclaredis plainundefinedproperty access: React renders theelement with no
classattribute,docusaurus buildstays green, and theelement silently loses its styling.
src/has 9 stylesheet importers and ~129class references behind that invariant, and no existing test reads a
*.module.css—tests/validate-button-contrast.test.mjsreads only theglobal
src/css/custom.css.Six assertions, in both directions:
import x from '*.module.css'specifier resolves to a stylesheet on diskstyles.foo,styles['foo']) is declared by its stylesheetstyles[key]lookup, where the referenced set is not statically knowable)composes:target resolves to a declared classImplementation notes: class names are read from selector preludes only, so
url(./x.png)in a declaration is not mistaken for a class, and the minified}.note,.source {form this repo actually ships inMetricsDashboard/styles.module.cssis parsed correctly. Import statements arestripped before the reference scan, since the specifier
'./styles.module.css'otherwise reads as a
styles.modulereference.Verification.
npm run test:unitis green at 61 tests (55 existing + 6new);
npx prettier --check tests/css-modules.test.mjsis clean. Theassertions were mutation-tested rather than assumed: injecting an undeclared
styles.bogusMissingreference and an orphan.bogusOrphanrule fails theforward and reverse assertions with a precise message, and declaring
.iconLinkfails the staleness guard with "remove it from KNOWN_UNDECLARED".Related Issue
Refs #319 — partial by lane constraint, not by choice. #319 asks for two
things, and this PR lands only the second box:
src/theme/Footer/— still open.This is a production-code change (
src/theme/Footer/index.jsand itsstyles.module.css), which the quality lane may not PR. It needs a humanor a production-lane agent.
Because the production half cannot land here, the two live drifts #319
documents are pinned in explicit exemption lists instead of being fixed:
KNOWN_UNDECLARED:src/theme/Footer/styles.module.css#iconLinkKNOWN_ORPHANS:src/theme/Footer/styles.module.css#orgTextBoth are confirmed present on
mainat 00b44df. This keeps the contractenforced for all 9 importers and stops the drift spreading, while leaving the
6-line deletion to the first box. The exemptions are not permanent
carve-outs: the two staleness guards fail the moment either drift is fixed,
demanding the entry's removal, so landing box 1 tightens this test rather than
leaving a stale exemption behind. #319 stays open until then.
Disjointness: this PR touches only the new
tests/css-modules.test.mjs. #347(
tests/css-variables.test.mjs) coversvar(--x)custom-property resolution —different names, different namespace; #343 covers JSX link/image hygiene; #317
covers
custom.css→static/fonts/, a global stylesheet not scanned here;#229 covers
filterArchitectures; #268 coversuseFocusTrap. No open PR readsCSS Module class names or touches
src/theme/Footer/**.Filed by quality agent (hold-gated mode). Human review required.
— hive: agent=quality backend=copilot model=claude-opus-5