From af2f2b21443073a112aedb5da5d3221efe6aee64 Mon Sep 17 00:00:00 2001 From: jleo3 Date: Tue, 18 Aug 2026 12:01:34 -0400 Subject: [PATCH] Expand conformance suite to per-rule fixture coverage, gated (herb-embedded-ag7) Adds one hand-written .html.erb fixture per rule the vendored bundle registers (100 rules, verified as the true complete count against node_modules/@herb-tools/linter's src/rules/), under spec/conformance/fixtures/rules/. Each fixture is authored by reading the rule's TypeScript source and validated to trigger the rule via the real reference linter CLI. conformance_spec.rb's existing reference_offenses/bridge_offenses helpers gain optional only:/rules: args (not duplicated) so a per-rule fixture can run --only / rules: [rule] the same way gu7/ada's Bridge#lint specs already do - this also lets not-enabled-by-default rules get exercised directly. A new test enumerates bridge.rule_names and asserts every one has a fixture, so a newly-added upstream rule with no fixture fails the build instead of going untested silently. Three rules that only enable themselves for partial files (basename starting with _) get underscore-prefixed fixture filenames to trigger correctly. Running the full suite surfaced a real, previously-undetected bridge bug: __herbLint/__herbAutofix construct the vendored Linter without its 4th constructor arg (allAvailableRules), which defaults to just the currently-selected rule subset when omitted. herb-disable-comment-unnecessary reads context.validRuleNames (derived from that arg) to recognize other rules referenced in a herb:disable comment, so under our one-rule-at-a-time execution model it could never recognize any rule but itself. Fixed by passing HerbLinter.rules (the full registry) explicitly at both call sites. CHARTER.md's "conformance punch list isn't closed" open question is updated to reflect that the fixture-coverage dimension is now closed, without overclaiming the separate .herb.yml config-application item it also named. --- CHARTER.md | 17 +++-- js/ruby_backend.js | 13 +++- spec/conformance/conformance_spec.rb | 64 +++++++++++++++++-- ...tionview-strict-locals-first-line.html.erb | 2 + ...no-instance-variables-in-partials.html.erb | 1 + .../_erb-strict-locals-required.html.erb | 1 + .../a11y-avoid-generic-link-text.html.erb | 1 + .../rules/a11y-disabled-attribute.html.erb | 1 + .../a11y-nested-interactive-elements.html.erb | 1 + .../a11y-no-accesskey-attribute.html.erb | 1 + .../rules/a11y-no-aria-label-misuse.html.erb | 1 + ...a11y-no-aria-unsupported-elements.html.erb | 1 + .../a11y-no-autofocus-attribute.html.erb | 1 + .../a11y-no-redundant-image-alt.html.erb | 1 + .../a11y-svg-has-accessible-text.html.erb | 1 + .../actionview-no-silent-helper.html.erb | 1 + .../actionview-no-silent-render.html.erb | 1 + ...iew-no-unnecessary-tag-attributes.html.erb | 1 + ...ctionview-no-void-element-content.html.erb | 1 + ...onview-strict-locals-partial-only.html.erb | 3 + .../rules/erb-comment-syntax.html.erb | 1 + .../rules/erb-no-case-node-children.html.erb | 5 ++ .../erb-no-commented-out-output-tags.html.erb | 1 + .../erb-no-conditional-html-element.html.erb | 7 ++ .../erb-no-conditional-open-tag.html.erb | 7 ++ .../rules/erb-no-debug-output.html.erb | 1 + .../erb-no-duplicate-branch-elements.html.erb | 5 ++ .../rules/erb-no-empty-control-flow.html.erb | 2 + .../fixtures/rules/erb-no-empty-tags.html.erb | 1 + .../rules/erb-no-extra-newline.html.erb | 5 ++ ...b-no-extra-whitespace-inside-tags.html.erb | 1 + .../erb-no-inline-case-conditions.html.erb | 3 + .../erb-no-interpolated-class-names.html.erb | 1 + .../erb-no-javascript-tag-helper.html.erb | 3 + .../rules/erb-no-output-control-flow.html.erb | 3 + .../erb-no-output-in-attribute-name.html.erb | 1 + ...b-no-output-in-attribute-position.html.erb | 1 + ...-no-raw-output-in-attribute-value.html.erb | 1 + .../rules/erb-no-silent-statement.html.erb | 1 + ...b-no-silent-tag-in-attribute-name.html.erb | 1 + .../rules/erb-no-statement-in-script.html.erb | 3 + .../erb-no-then-in-control-flow.html.erb | 3 + .../rules/erb-no-trailing-whitespace.html.erb | 2 + .../rules/erb-no-unsafe-js-attribute.html.erb | 1 + .../fixtures/rules/erb-no-unsafe-raw.html.erb | 1 + ...rb-no-unsafe-script-interpolation.html.erb | 3 + .../rules/erb-no-unused-expressions.html.erb | 1 + .../rules/erb-no-unused-literals.html.erb | 1 + .../rules/erb-prefer-direct-output.html.erb | 1 + .../erb-prefer-image-tag-helper.html.erb | 1 + .../erb-require-trailing-newline.html.erb | 2 + ...rb-require-whitespace-inside-tags.html.erb | 1 + .../fixtures/rules/erb-right-trim.html.erb | 1 + .../erb-strict-locals-comment-syntax.html.erb | 1 + .../herb-disable-comment-malformed.html.erb | 1 + ...erb-disable-comment-missing-rules.html.erb | 1 + ...isable-comment-no-duplicate-rules.html.erb | 1 + ...-disable-comment-no-redundant-all.html.erb | 1 + .../herb-disable-comment-unnecessary.html.erb | 1 + ...b-disable-comment-valid-rule-name.html.erb | 1 + .../rules/html-allowed-script-type.html.erb | 1 + .../rules/html-anchor-require-href.html.erb | 1 + ...html-aria-attribute-must-be-valid.html.erb | 1 + ...html-aria-label-is-well-formatted.html.erb | 1 + .../html-aria-level-must-be-valid.html.erb | 1 + ...-aria-role-heading-requires-level.html.erb | 1 + .../html-aria-role-must-be-valid.html.erb | 1 + .../html-attribute-double-quotes.html.erb | 1 + .../html-attribute-equals-spacing.html.erb | 1 + ...l-attribute-values-require-quotes.html.erb | 1 + ...d-both-disabled-and-aria-disabled.html.erb | 1 + .../rules/html-body-only-elements.html.erb | 6 ++ .../html-boolean-attributes-no-value.html.erb | 1 + .../rules/html-details-has-summary.html.erb | 3 + .../rules/html-head-only-elements.html.erb | 6 ++ .../rules/html-iframe-has-title.html.erb | 1 + .../rules/html-img-require-alt.html.erb | 1 + .../html-input-require-autocomplete.html.erb | 1 + .../rules/html-navigation-has-label.html.erb | 1 + .../rules/html-no-abstract-roles.html.erb | 1 + .../html-no-aria-hidden-on-body.html.erb | 3 + .../html-no-aria-hidden-on-focusable.html.erb | 1 + .../html-no-block-inside-inline.html.erb | 1 + .../html-no-duplicate-attributes.html.erb | 1 + .../rules/html-no-duplicate-ids.html.erb | 2 + .../html-no-duplicate-meta-names.html.erb | 4 ++ .../rules/html-no-empty-attributes.html.erb | 1 + .../rules/html-no-empty-headings.html.erb | 1 + .../rules/html-no-nested-links.html.erb | 1 + .../rules/html-no-positive-tab-index.html.erb | 1 + .../rules/html-no-self-closing.html.erb | 1 + .../rules/html-no-space-in-tag.html.erb | 1 + .../rules/html-no-title-attribute.html.erb | 1 + ...no-underscores-in-attribute-names.html.erb | 1 + .../rules/html-no-unescaped-entities.html.erb | 1 + .../rules/html-no-unknown-tag.html.erb | 1 + .../rules/html-require-closing-tags.html.erb | 4 ++ .../rules/html-require-script-nonce.html.erb | 3 + .../rules/html-tag-name-lowercase.html.erb | 1 + .../fixtures/rules/parser-no-errors.html.erb | 1 + .../rules/source-indentation.html.erb | 3 + .../svg-tag-name-capitalization.html.erb | 1 + .../rules/turbo-permanent-require-id.html.erb | 1 + 103 files changed, 248 insertions(+), 13 deletions(-) create mode 100644 spec/conformance/fixtures/rules/_actionview-strict-locals-first-line.html.erb create mode 100644 spec/conformance/fixtures/rules/_erb-no-instance-variables-in-partials.html.erb create mode 100644 spec/conformance/fixtures/rules/_erb-strict-locals-required.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-avoid-generic-link-text.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-disabled-attribute.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-nested-interactive-elements.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-no-accesskey-attribute.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-no-aria-label-misuse.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-no-aria-unsupported-elements.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-no-autofocus-attribute.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-no-redundant-image-alt.html.erb create mode 100644 spec/conformance/fixtures/rules/a11y-svg-has-accessible-text.html.erb create mode 100644 spec/conformance/fixtures/rules/actionview-no-silent-helper.html.erb create mode 100644 spec/conformance/fixtures/rules/actionview-no-silent-render.html.erb create mode 100644 spec/conformance/fixtures/rules/actionview-no-unnecessary-tag-attributes.html.erb create mode 100644 spec/conformance/fixtures/rules/actionview-no-void-element-content.html.erb create mode 100644 spec/conformance/fixtures/rules/actionview-strict-locals-partial-only.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-comment-syntax.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-case-node-children.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-commented-out-output-tags.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-conditional-html-element.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-conditional-open-tag.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-debug-output.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-duplicate-branch-elements.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-empty-control-flow.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-empty-tags.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-extra-newline.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-extra-whitespace-inside-tags.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-inline-case-conditions.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-interpolated-class-names.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-javascript-tag-helper.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-output-control-flow.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-output-in-attribute-name.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-output-in-attribute-position.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-raw-output-in-attribute-value.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-silent-statement.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-silent-tag-in-attribute-name.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-statement-in-script.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-then-in-control-flow.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-trailing-whitespace.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-unsafe-js-attribute.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-unsafe-raw.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-unsafe-script-interpolation.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-unused-expressions.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-no-unused-literals.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-prefer-direct-output.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-prefer-image-tag-helper.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-require-trailing-newline.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-require-whitespace-inside-tags.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-right-trim.html.erb create mode 100644 spec/conformance/fixtures/rules/erb-strict-locals-comment-syntax.html.erb create mode 100644 spec/conformance/fixtures/rules/herb-disable-comment-malformed.html.erb create mode 100644 spec/conformance/fixtures/rules/herb-disable-comment-missing-rules.html.erb create mode 100644 spec/conformance/fixtures/rules/herb-disable-comment-no-duplicate-rules.html.erb create mode 100644 spec/conformance/fixtures/rules/herb-disable-comment-no-redundant-all.html.erb create mode 100644 spec/conformance/fixtures/rules/herb-disable-comment-unnecessary.html.erb create mode 100644 spec/conformance/fixtures/rules/herb-disable-comment-valid-rule-name.html.erb create mode 100644 spec/conformance/fixtures/rules/html-allowed-script-type.html.erb create mode 100644 spec/conformance/fixtures/rules/html-anchor-require-href.html.erb create mode 100644 spec/conformance/fixtures/rules/html-aria-attribute-must-be-valid.html.erb create mode 100644 spec/conformance/fixtures/rules/html-aria-label-is-well-formatted.html.erb create mode 100644 spec/conformance/fixtures/rules/html-aria-level-must-be-valid.html.erb create mode 100644 spec/conformance/fixtures/rules/html-aria-role-heading-requires-level.html.erb create mode 100644 spec/conformance/fixtures/rules/html-aria-role-must-be-valid.html.erb create mode 100644 spec/conformance/fixtures/rules/html-attribute-double-quotes.html.erb create mode 100644 spec/conformance/fixtures/rules/html-attribute-equals-spacing.html.erb create mode 100644 spec/conformance/fixtures/rules/html-attribute-values-require-quotes.html.erb create mode 100644 spec/conformance/fixtures/rules/html-avoid-both-disabled-and-aria-disabled.html.erb create mode 100644 spec/conformance/fixtures/rules/html-body-only-elements.html.erb create mode 100644 spec/conformance/fixtures/rules/html-boolean-attributes-no-value.html.erb create mode 100644 spec/conformance/fixtures/rules/html-details-has-summary.html.erb create mode 100644 spec/conformance/fixtures/rules/html-head-only-elements.html.erb create mode 100644 spec/conformance/fixtures/rules/html-iframe-has-title.html.erb create mode 100644 spec/conformance/fixtures/rules/html-img-require-alt.html.erb create mode 100644 spec/conformance/fixtures/rules/html-input-require-autocomplete.html.erb create mode 100644 spec/conformance/fixtures/rules/html-navigation-has-label.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-abstract-roles.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-aria-hidden-on-body.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-aria-hidden-on-focusable.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-block-inside-inline.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-duplicate-attributes.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-duplicate-ids.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-duplicate-meta-names.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-empty-attributes.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-empty-headings.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-nested-links.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-positive-tab-index.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-self-closing.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-space-in-tag.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-title-attribute.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-underscores-in-attribute-names.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-unescaped-entities.html.erb create mode 100644 spec/conformance/fixtures/rules/html-no-unknown-tag.html.erb create mode 100644 spec/conformance/fixtures/rules/html-require-closing-tags.html.erb create mode 100644 spec/conformance/fixtures/rules/html-require-script-nonce.html.erb create mode 100644 spec/conformance/fixtures/rules/html-tag-name-lowercase.html.erb create mode 100644 spec/conformance/fixtures/rules/parser-no-errors.html.erb create mode 100644 spec/conformance/fixtures/rules/source-indentation.html.erb create mode 100644 spec/conformance/fixtures/rules/svg-tag-name-capitalization.html.erb create mode 100644 spec/conformance/fixtures/rules/turbo-permanent-require-id.html.erb diff --git a/CHARTER.md b/CHARTER.md index 52b3a11..e83a7fd 100644 --- a/CHARTER.md +++ b/CHARTER.md @@ -157,11 +157,18 @@ already sitting in the `herb` gem's native C extension the whole time. `herb-lint-rb` are the current names. If Marco's gem claims `Herb::Linter` or a conflicting convention before herb-embedded sunsets, a rename may be needed in the meantime — low stakes given the planned sunset, but worth a glance when his gem surfaces. -3. **Conformance punch list isn't closed.** The design spec's differential run against - `npx @herb-tools/linter` wasn't yet clean end-to-end — missing `LintContext` (filename), - missing `.herb.yml` config application, and per-rule `parserOptions` forwarding. Each has - a named cause and is tracked as implementation work in `bd` (see `herb-embedded-6dp` and - related beads), not a design gap. +3. **Conformance punch list, fixture-coverage dimension: closed.** The design spec's + differential run against `npx @herb-tools/linter` originally wasn't clean end-to-end — + missing `LintContext` (filename), missing `.herb.yml` config application, and per-rule + `parserOptions` forwarding. `LintContext` and `parserOptions` forwarding (including + `prism_program`/`prism_nodes`, see the Shape decisions entry above) are resolved; each had + a named cause tracked as implementation work in `bd` (`herb-embedded-6dp` and related + beads), not a design gap. `spec/conformance/conformance_spec.rb` now runs the differential + offense-for-offense diff against a hand-written fixture for every one of the 100 rules the + vendored bundle registers (`herb-embedded-ag7`), gated so an upstream rule with no fixture + fails the build — not just the 5 general-purpose fixtures from before. `.herb.yml` config + application is unaffected by that work and still worth a look if it's ever suspected of + drifting from upstream. 4. **Config schema stability.** `.herb.yml` config currently passes through to the engine whole. Per-rule options can change across Herb releases, so Ruby may eventually need version-aware translation instead of passthrough. Unresolved until it's actually observed diff --git a/js/ruby_backend.js b/js/ruby_backend.js index 722a630..fa4a4dc 100644 --- a/js/ruby_backend.js +++ b/js/ruby_backend.js @@ -161,7 +161,7 @@ function __herbRegisterCustomRule(rewrittenSource, path) { function __herbAutofix(source, file, ruleNames, includeUnsafe) { var ruleClasses = __herbSelectRules(ruleNames); var context = { fileName: file, filename: file }; - var linter = new HerbLinter.Linter(__herbEmbeddedBridge.instance, ruleClasses); + var linter = new HerbLinter.Linter(__herbEmbeddedBridge.instance, ruleClasses, undefined, HerbLinter.rules); var result = linter.autofix(source, context, undefined, { includeUnsafe: !!includeUnsafe }); return JSON.stringify({ source: result.source, fixed: result.fixed }); @@ -171,6 +171,15 @@ function __herbAutofix(source, file, ruleNames, includeUnsafe) { // throws must not abort the run (spike 2 finding) — the real Linter#lint // has no such isolation internally, since it runs every selected rule's // check() in one uncaught loop. +// +// The 4th constructor arg (allAvailableRules) must be the full registry, +// not just the one rule being run: herb-disable-comment-unnecessary reads +// context.validRuleNames (built from Linter#getAvailableRules, which +// falls back to allAvailableRules) to decide whether a `herb:disable +// some-other-rule` comment references a real rule — omitting this arg +// left validRuleNames scoped to whatever single rule __herbLint happened +// to be running, so the rule silently never matched anything outside +// itself. Caught by conformance fixture coverage (herb-embedded-ag7). function __herbLint(source, file, ruleNames) { var ruleClasses = __herbSelectRules(ruleNames); var context = { fileName: file, filename: file }; @@ -178,7 +187,7 @@ function __herbLint(source, file, ruleNames) { ruleClasses.forEach(function (ruleClass) { try { - var linter = new HerbLinter.Linter(__herbEmbeddedBridge.instance, [ruleClass]); + var linter = new HerbLinter.Linter(__herbEmbeddedBridge.instance, [ruleClass], undefined, HerbLinter.rules); var result = linter.lint(source, context); offenses = offenses.concat(result.offenses); } catch (e) { diff --git a/spec/conformance/conformance_spec.rb b/spec/conformance/conformance_spec.rb index 3d419af..fcff14f 100644 --- a/spec/conformance/conformance_spec.rb +++ b/spec/conformance/conformance_spec.rb @@ -10,6 +10,18 @@ CONFORMANCE_ROOT = File.expand_path("../..", __dir__) CONFORMANCE_REFERENCE_LINTER = File.join(CONFORMANCE_ROOT, "node_modules", ".bin", "herb-lint") CONFORMANCE_FIXTURES = Dir.glob(File.join(__dir__, "fixtures", "*.html.erb")) +CONFORMANCE_RULE_FIXTURES = Dir.glob(File.join(__dir__, "fixtures", "rules", "*.html.erb")) + +# A handful of rules (erb-no-instance-variables-in-partials and friends) +# only enable themselves for partial files (basename starting with `_`), +# so their fixture is named with that leading underscore to trigger +# correctly — this strips it back off to recover the rule code the +# coverage-gate test and --only/rules: need. Top-level (not an instance +# method) since it's needed both at spec-definition time, to build each +# `it` description, and at example-run time. +def conformance_rule_name_for(fixture_path) + File.basename(fixture_path, ".html.erb").sub(/\A_/, "") +end # Node at test time is acceptable — the guarantee this repo makes is # about *user* time (see spec/no_node_spec.rb). This is the differential @@ -23,16 +35,24 @@ after { adapter.dispose } - def reference_offenses(fixture_path) + def reference_offenses(fixture_path, only: nil) # --no-github: herb-lint auto-enables GitHub Actions annotations whenever # GITHUB_ACTIONS=true is set (i.e. inside our own CI job), which then # conflicts fatally with --json ("--github cannot be used with --json # format"). Explicitly disabling it makes --json behavior independent of # the invoking environment. - stdout, stderr, status = Open3.capture3( + # + # --only ignores .herb.yml config entirely (including a rule's own + # defaultConfig.enabled), matching rules: [...] on the bridge side — + # both let a per-rule fixture exercise a not-enabled-by-default rule + # directly, the same way gu7/ada's Bridge#lint specs already do. + args = [ CONFORMANCE_REFERENCE_LINTER, fixture_path, "--json", "--no-custom-rules", "--no-color", "--no-github", - "--jobs", "1", chdir: CONFORMANCE_ROOT - ) + "--jobs", "1" + ] + args += ["--only", only] if only + + stdout, stderr, status = Open3.capture3(*args, chdir: CONFORMANCE_ROOT) unless status.exitstatus.zero? || status.exitstatus == 1 raise "reference herb-lint failed (exit #{status.exitstatus}): #{stderr}" end @@ -44,9 +64,9 @@ def reference_offenses(fixture_path) JSON.parse(stdout)["offenses"].map { |o| [o["code"], o["location"]["start"]["line"], o["location"]["start"]["column"]] } end - def bridge_offenses(fixture_path) + def bridge_offenses(fixture_path, rules: nil) source = File.read(fixture_path) - bridge.lint(source, file: File.basename(fixture_path)).map { |d| [d.rule, d.line, d.column] } + bridge.lint(source, file: File.basename(fixture_path), rules: rules).map { |d| [d.rule, d.line, d.column] } end CONFORMANCE_FIXTURES.each do |fixture_path| @@ -71,4 +91,36 @@ def bridge_offenses(fixture_path) expect(present).to include(*required) end + + CONFORMANCE_RULE_FIXTURES.each do |fixture_path| + rule = conformance_rule_name_for(fixture_path) + + it "matches npx @herb-tools/linter offense-for-offense on the #{rule} fixture, exercising the rule" do + reference = reference_offenses(fixture_path, only: rule).sort + actual = bridge_offenses(fixture_path, rules: [rule]).sort + + expect(reference).not_to be_empty, + "Fixture #{File.basename(fixture_path)} produced no reference offenses for " \ + "#{rule} — it doesn't actually trigger the rule" + + missing = reference - actual + extra = actual - reference + + expect([missing, extra]).to eq([[], []]), <<~MSG + Conformance mismatch for #{rule} (#{File.basename(fixture_path)}) — [rule, line, column] tuples: + Missing (npx found it, bridge did not): #{missing.inspect} + Extra (bridge found it, npx did not): #{extra.inspect} + MSG + end + end + + it "has a conformance fixture for every rule the vendored bundle registers" do + registered = bridge.rule_names + covered = CONFORMANCE_RULE_FIXTURES.map { |f| conformance_rule_name_for(f) } + + missing = registered - covered + expect(missing).to be_empty, + "Rules registered by the vendored bundle with no conformance fixture under " \ + "spec/conformance/fixtures/rules/: #{missing.sort.inspect}" + end end diff --git a/spec/conformance/fixtures/rules/_actionview-strict-locals-first-line.html.erb b/spec/conformance/fixtures/rules/_actionview-strict-locals-first-line.html.erb new file mode 100644 index 0000000..3653be2 --- /dev/null +++ b/spec/conformance/fixtures/rules/_actionview-strict-locals-first-line.html.erb @@ -0,0 +1,2 @@ +

Header

+<%# locals: (title:) %> diff --git a/spec/conformance/fixtures/rules/_erb-no-instance-variables-in-partials.html.erb b/spec/conformance/fixtures/rules/_erb-no-instance-variables-in-partials.html.erb new file mode 100644 index 0000000..02613be --- /dev/null +++ b/spec/conformance/fixtures/rules/_erb-no-instance-variables-in-partials.html.erb @@ -0,0 +1 @@ +<%= @widget_name %> diff --git a/spec/conformance/fixtures/rules/_erb-strict-locals-required.html.erb b/spec/conformance/fixtures/rules/_erb-strict-locals-required.html.erb new file mode 100644 index 0000000..98d12dd --- /dev/null +++ b/spec/conformance/fixtures/rules/_erb-strict-locals-required.html.erb @@ -0,0 +1 @@ +

Hi

diff --git a/spec/conformance/fixtures/rules/a11y-avoid-generic-link-text.html.erb b/spec/conformance/fixtures/rules/a11y-avoid-generic-link-text.html.erb new file mode 100644 index 0000000..aa414e6 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-avoid-generic-link-text.html.erb @@ -0,0 +1 @@ +Click here diff --git a/spec/conformance/fixtures/rules/a11y-disabled-attribute.html.erb b/spec/conformance/fixtures/rules/a11y-disabled-attribute.html.erb new file mode 100644 index 0000000..2aa0e78 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-disabled-attribute.html.erb @@ -0,0 +1 @@ +
Unavailable
diff --git a/spec/conformance/fixtures/rules/a11y-nested-interactive-elements.html.erb b/spec/conformance/fixtures/rules/a11y-nested-interactive-elements.html.erb new file mode 100644 index 0000000..2545218 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-nested-interactive-elements.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/a11y-no-accesskey-attribute.html.erb b/spec/conformance/fixtures/rules/a11y-no-accesskey-attribute.html.erb new file mode 100644 index 0000000..0722fff --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-no-accesskey-attribute.html.erb @@ -0,0 +1 @@ +
Save
diff --git a/spec/conformance/fixtures/rules/a11y-no-aria-label-misuse.html.erb b/spec/conformance/fixtures/rules/a11y-no-aria-label-misuse.html.erb new file mode 100644 index 0000000..c90b8f7 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-no-aria-label-misuse.html.erb @@ -0,0 +1 @@ +

Welcome

diff --git a/spec/conformance/fixtures/rules/a11y-no-aria-unsupported-elements.html.erb b/spec/conformance/fixtures/rules/a11y-no-aria-unsupported-elements.html.erb new file mode 100644 index 0000000..d3a2e67 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-no-aria-unsupported-elements.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/a11y-no-autofocus-attribute.html.erb b/spec/conformance/fixtures/rules/a11y-no-autofocus-attribute.html.erb new file mode 100644 index 0000000..5c41ee7 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-no-autofocus-attribute.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/a11y-no-redundant-image-alt.html.erb b/spec/conformance/fixtures/rules/a11y-no-redundant-image-alt.html.erb new file mode 100644 index 0000000..2d5fab2 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-no-redundant-image-alt.html.erb @@ -0,0 +1 @@ +a cat image diff --git a/spec/conformance/fixtures/rules/a11y-svg-has-accessible-text.html.erb b/spec/conformance/fixtures/rules/a11y-svg-has-accessible-text.html.erb new file mode 100644 index 0000000..4a65311 --- /dev/null +++ b/spec/conformance/fixtures/rules/a11y-svg-has-accessible-text.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/actionview-no-silent-helper.html.erb b/spec/conformance/fixtures/rules/actionview-no-silent-helper.html.erb new file mode 100644 index 0000000..af2de83 --- /dev/null +++ b/spec/conformance/fixtures/rules/actionview-no-silent-helper.html.erb @@ -0,0 +1 @@ +<% link_to "Home", "/" %> diff --git a/spec/conformance/fixtures/rules/actionview-no-silent-render.html.erb b/spec/conformance/fixtures/rules/actionview-no-silent-render.html.erb new file mode 100644 index 0000000..d420d57 --- /dev/null +++ b/spec/conformance/fixtures/rules/actionview-no-silent-render.html.erb @@ -0,0 +1 @@ +<% render "header" %> diff --git a/spec/conformance/fixtures/rules/actionview-no-unnecessary-tag-attributes.html.erb b/spec/conformance/fixtures/rules/actionview-no-unnecessary-tag-attributes.html.erb new file mode 100644 index 0000000..21dfc2e --- /dev/null +++ b/spec/conformance/fixtures/rules/actionview-no-unnecessary-tag-attributes.html.erb @@ -0,0 +1 @@ +
>
diff --git a/spec/conformance/fixtures/rules/actionview-no-void-element-content.html.erb b/spec/conformance/fixtures/rules/actionview-no-void-element-content.html.erb new file mode 100644 index 0000000..507389a --- /dev/null +++ b/spec/conformance/fixtures/rules/actionview-no-void-element-content.html.erb @@ -0,0 +1 @@ +<%= tag.hr "divider text" %> diff --git a/spec/conformance/fixtures/rules/actionview-strict-locals-partial-only.html.erb b/spec/conformance/fixtures/rules/actionview-strict-locals-partial-only.html.erb new file mode 100644 index 0000000..cf26216 --- /dev/null +++ b/spec/conformance/fixtures/rules/actionview-strict-locals-partial-only.html.erb @@ -0,0 +1,3 @@ +<%# locals: (title:) %> + +

Content

diff --git a/spec/conformance/fixtures/rules/erb-comment-syntax.html.erb b/spec/conformance/fixtures/rules/erb-comment-syntax.html.erb new file mode 100644 index 0000000..0200c1f --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-comment-syntax.html.erb @@ -0,0 +1 @@ +<% # oops this should be an ERB comment %> diff --git a/spec/conformance/fixtures/rules/erb-no-case-node-children.html.erb b/spec/conformance/fixtures/rules/erb-no-case-node-children.html.erb new file mode 100644 index 0000000..e5b537e --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-case-node-children.html.erb @@ -0,0 +1,5 @@ +<% case status %> + stray text +<% when :ok %> + fine +<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-commented-out-output-tags.html.erb b/spec/conformance/fixtures/rules/erb-no-commented-out-output-tags.html.erb new file mode 100644 index 0000000..e5fc01d --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-commented-out-output-tags.html.erb @@ -0,0 +1 @@ +<%#= old_helper %> diff --git a/spec/conformance/fixtures/rules/erb-no-conditional-html-element.html.erb b/spec/conformance/fixtures/rules/erb-no-conditional-html-element.html.erb new file mode 100644 index 0000000..07cfdce --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-conditional-html-element.html.erb @@ -0,0 +1,7 @@ +<% if show %> +
+<% end %> +content +<% if show %> +
+<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-conditional-open-tag.html.erb b/spec/conformance/fixtures/rules/erb-no-conditional-open-tag.html.erb new file mode 100644 index 0000000..9b1b786 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-conditional-open-tag.html.erb @@ -0,0 +1,7 @@ +<% if active %> +
+<% else %> +
+<% end %> +content +
diff --git a/spec/conformance/fixtures/rules/erb-no-debug-output.html.erb b/spec/conformance/fixtures/rules/erb-no-debug-output.html.erb new file mode 100644 index 0000000..558dcbc --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-debug-output.html.erb @@ -0,0 +1 @@ +<% byebug %> diff --git a/spec/conformance/fixtures/rules/erb-no-duplicate-branch-elements.html.erb b/spec/conformance/fixtures/rules/erb-no-duplicate-branch-elements.html.erb new file mode 100644 index 0000000..965667e --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-duplicate-branch-elements.html.erb @@ -0,0 +1,5 @@ +<% if cond %> +
A
+<% else %> +
B
+<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-empty-control-flow.html.erb b/spec/conformance/fixtures/rules/erb-no-empty-control-flow.html.erb new file mode 100644 index 0000000..30613b5 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-empty-control-flow.html.erb @@ -0,0 +1,2 @@ +<% if cond %> +<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-empty-tags.html.erb b/spec/conformance/fixtures/rules/erb-no-empty-tags.html.erb new file mode 100644 index 0000000..52e5ffa --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-empty-tags.html.erb @@ -0,0 +1 @@ +<% %> diff --git a/spec/conformance/fixtures/rules/erb-no-extra-newline.html.erb b/spec/conformance/fixtures/rules/erb-no-extra-newline.html.erb new file mode 100644 index 0000000..0ca258d --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-extra-newline.html.erb @@ -0,0 +1,5 @@ +

first

+ + + +

second

diff --git a/spec/conformance/fixtures/rules/erb-no-extra-whitespace-inside-tags.html.erb b/spec/conformance/fixtures/rules/erb-no-extra-whitespace-inside-tags.html.erb new file mode 100644 index 0000000..4e4f1c6 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-extra-whitespace-inside-tags.html.erb @@ -0,0 +1 @@ +<%= name %> diff --git a/spec/conformance/fixtures/rules/erb-no-inline-case-conditions.html.erb b/spec/conformance/fixtures/rules/erb-no-inline-case-conditions.html.erb new file mode 100644 index 0000000..6808eb5 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-inline-case-conditions.html.erb @@ -0,0 +1,3 @@ +<% case status; when :ok %> + fine +<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-interpolated-class-names.html.erb b/spec/conformance/fixtures/rules/erb-no-interpolated-class-names.html.erb new file mode 100644 index 0000000..e6b8caf --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-interpolated-class-names.html.erb @@ -0,0 +1 @@ +
diff --git a/spec/conformance/fixtures/rules/erb-no-javascript-tag-helper.html.erb b/spec/conformance/fixtures/rules/erb-no-javascript-tag-helper.html.erb new file mode 100644 index 0000000..8d3f499 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-javascript-tag-helper.html.erb @@ -0,0 +1,3 @@ +<%= javascript_tag do %> + console.log("hi"); +<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-output-control-flow.html.erb b/spec/conformance/fixtures/rules/erb-no-output-control-flow.html.erb new file mode 100644 index 0000000..bb76757 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-output-control-flow.html.erb @@ -0,0 +1,3 @@ +<%= if cond %> + yes +<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-output-in-attribute-name.html.erb b/spec/conformance/fixtures/rules/erb-no-output-in-attribute-name.html.erb new file mode 100644 index 0000000..f28b365 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-output-in-attribute-name.html.erb @@ -0,0 +1 @@ +
="value">
diff --git a/spec/conformance/fixtures/rules/erb-no-output-in-attribute-position.html.erb b/spec/conformance/fixtures/rules/erb-no-output-in-attribute-position.html.erb new file mode 100644 index 0000000..3585cfa --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-output-in-attribute-position.html.erb @@ -0,0 +1 @@ +
>
diff --git a/spec/conformance/fixtures/rules/erb-no-raw-output-in-attribute-value.html.erb b/spec/conformance/fixtures/rules/erb-no-raw-output-in-attribute-value.html.erb new file mode 100644 index 0000000..976456a --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-raw-output-in-attribute-value.html.erb @@ -0,0 +1 @@ +
diff --git a/spec/conformance/fixtures/rules/erb-no-silent-statement.html.erb b/spec/conformance/fixtures/rules/erb-no-silent-statement.html.erb new file mode 100644 index 0000000..5869c7f --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-silent-statement.html.erb @@ -0,0 +1 @@ +<% track_view %> diff --git a/spec/conformance/fixtures/rules/erb-no-silent-tag-in-attribute-name.html.erb b/spec/conformance/fixtures/rules/erb-no-silent-tag-in-attribute-name.html.erb new file mode 100644 index 0000000..d781ce8 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-silent-tag-in-attribute-name.html.erb @@ -0,0 +1 @@ +
-label="x">
diff --git a/spec/conformance/fixtures/rules/erb-no-statement-in-script.html.erb b/spec/conformance/fixtures/rules/erb-no-statement-in-script.html.erb new file mode 100644 index 0000000..b35aa01 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-statement-in-script.html.erb @@ -0,0 +1,3 @@ + diff --git a/spec/conformance/fixtures/rules/erb-no-then-in-control-flow.html.erb b/spec/conformance/fixtures/rules/erb-no-then-in-control-flow.html.erb new file mode 100644 index 0000000..35aa644 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-then-in-control-flow.html.erb @@ -0,0 +1,3 @@ +<% if true then %> + yes +<% end %> diff --git a/spec/conformance/fixtures/rules/erb-no-trailing-whitespace.html.erb b/spec/conformance/fixtures/rules/erb-no-trailing-whitespace.html.erb new file mode 100644 index 0000000..8e0dce4 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-trailing-whitespace.html.erb @@ -0,0 +1,2 @@ +

Hello +

diff --git a/spec/conformance/fixtures/rules/erb-no-unsafe-js-attribute.html.erb b/spec/conformance/fixtures/rules/erb-no-unsafe-js-attribute.html.erb new file mode 100644 index 0000000..4553f1e --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-unsafe-js-attribute.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/erb-no-unsafe-raw.html.erb b/spec/conformance/fixtures/rules/erb-no-unsafe-raw.html.erb new file mode 100644 index 0000000..1726b8a --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-unsafe-raw.html.erb @@ -0,0 +1 @@ +
<%= raw(comment_body) %>
diff --git a/spec/conformance/fixtures/rules/erb-no-unsafe-script-interpolation.html.erb b/spec/conformance/fixtures/rules/erb-no-unsafe-script-interpolation.html.erb new file mode 100644 index 0000000..1bb8509 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-unsafe-script-interpolation.html.erb @@ -0,0 +1,3 @@ + diff --git a/spec/conformance/fixtures/rules/erb-no-unused-expressions.html.erb b/spec/conformance/fixtures/rules/erb-no-unused-expressions.html.erb new file mode 100644 index 0000000..1144dcf --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-unused-expressions.html.erb @@ -0,0 +1 @@ +<% @user.name %> diff --git a/spec/conformance/fixtures/rules/erb-no-unused-literals.html.erb b/spec/conformance/fixtures/rules/erb-no-unused-literals.html.erb new file mode 100644 index 0000000..a260b11 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-no-unused-literals.html.erb @@ -0,0 +1 @@ +<% "unused" %> diff --git a/spec/conformance/fixtures/rules/erb-prefer-direct-output.html.erb b/spec/conformance/fixtures/rules/erb-prefer-direct-output.html.erb new file mode 100644 index 0000000..89385bf --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-prefer-direct-output.html.erb @@ -0,0 +1 @@ +<%= "hello" %> diff --git a/spec/conformance/fixtures/rules/erb-prefer-image-tag-helper.html.erb b/spec/conformance/fixtures/rules/erb-prefer-image-tag-helper.html.erb new file mode 100644 index 0000000..491b4d7 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-prefer-image-tag-helper.html.erb @@ -0,0 +1 @@ +pic diff --git a/spec/conformance/fixtures/rules/erb-require-trailing-newline.html.erb b/spec/conformance/fixtures/rules/erb-require-trailing-newline.html.erb new file mode 100644 index 0000000..f55a604 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-require-trailing-newline.html.erb @@ -0,0 +1,2 @@ +

Hi

+ diff --git a/spec/conformance/fixtures/rules/erb-require-whitespace-inside-tags.html.erb b/spec/conformance/fixtures/rules/erb-require-whitespace-inside-tags.html.erb new file mode 100644 index 0000000..9a472a2 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-require-whitespace-inside-tags.html.erb @@ -0,0 +1 @@ +<%=x%> diff --git a/spec/conformance/fixtures/rules/erb-right-trim.html.erb b/spec/conformance/fixtures/rules/erb-right-trim.html.erb new file mode 100644 index 0000000..6ca0b26 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-right-trim.html.erb @@ -0,0 +1 @@ +<% x = 1 =%> diff --git a/spec/conformance/fixtures/rules/erb-strict-locals-comment-syntax.html.erb b/spec/conformance/fixtures/rules/erb-strict-locals-comment-syntax.html.erb new file mode 100644 index 0000000..7c0bea1 --- /dev/null +++ b/spec/conformance/fixtures/rules/erb-strict-locals-comment-syntax.html.erb @@ -0,0 +1 @@ +<% # locals: (name:) %> diff --git a/spec/conformance/fixtures/rules/herb-disable-comment-malformed.html.erb b/spec/conformance/fixtures/rules/herb-disable-comment-malformed.html.erb new file mode 100644 index 0000000..ec4af8a --- /dev/null +++ b/spec/conformance/fixtures/rules/herb-disable-comment-malformed.html.erb @@ -0,0 +1 @@ +
<%# herb:disable foo, %>
diff --git a/spec/conformance/fixtures/rules/herb-disable-comment-missing-rules.html.erb b/spec/conformance/fixtures/rules/herb-disable-comment-missing-rules.html.erb new file mode 100644 index 0000000..85cd8be --- /dev/null +++ b/spec/conformance/fixtures/rules/herb-disable-comment-missing-rules.html.erb @@ -0,0 +1 @@ +
<%# herb:disable %>
diff --git a/spec/conformance/fixtures/rules/herb-disable-comment-no-duplicate-rules.html.erb b/spec/conformance/fixtures/rules/herb-disable-comment-no-duplicate-rules.html.erb new file mode 100644 index 0000000..d69d3ed --- /dev/null +++ b/spec/conformance/fixtures/rules/herb-disable-comment-no-duplicate-rules.html.erb @@ -0,0 +1 @@ +
<%# herb:disable parser-no-errors, parser-no-errors %>
diff --git a/spec/conformance/fixtures/rules/herb-disable-comment-no-redundant-all.html.erb b/spec/conformance/fixtures/rules/herb-disable-comment-no-redundant-all.html.erb new file mode 100644 index 0000000..59146a0 --- /dev/null +++ b/spec/conformance/fixtures/rules/herb-disable-comment-no-redundant-all.html.erb @@ -0,0 +1 @@ +
<%# herb:disable all, parser-no-errors %>
diff --git a/spec/conformance/fixtures/rules/herb-disable-comment-unnecessary.html.erb b/spec/conformance/fixtures/rules/herb-disable-comment-unnecessary.html.erb new file mode 100644 index 0000000..9908d27 --- /dev/null +++ b/spec/conformance/fixtures/rules/herb-disable-comment-unnecessary.html.erb @@ -0,0 +1 @@ +
<%# herb:disable svg-tag-name-capitalization %>
diff --git a/spec/conformance/fixtures/rules/herb-disable-comment-valid-rule-name.html.erb b/spec/conformance/fixtures/rules/herb-disable-comment-valid-rule-name.html.erb new file mode 100644 index 0000000..f44d9cd --- /dev/null +++ b/spec/conformance/fixtures/rules/herb-disable-comment-valid-rule-name.html.erb @@ -0,0 +1 @@ +
<%# herb:disable totally-not-a-real-rule %>
diff --git a/spec/conformance/fixtures/rules/html-allowed-script-type.html.erb b/spec/conformance/fixtures/rules/html-allowed-script-type.html.erb new file mode 100644 index 0000000..014231e --- /dev/null +++ b/spec/conformance/fixtures/rules/html-allowed-script-type.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-anchor-require-href.html.erb b/spec/conformance/fixtures/rules/html-anchor-require-href.html.erb new file mode 100644 index 0000000..e16163a --- /dev/null +++ b/spec/conformance/fixtures/rules/html-anchor-require-href.html.erb @@ -0,0 +1 @@ +Learn more diff --git a/spec/conformance/fixtures/rules/html-aria-attribute-must-be-valid.html.erb b/spec/conformance/fixtures/rules/html-aria-attribute-must-be-valid.html.erb new file mode 100644 index 0000000..b8a8923 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-aria-attribute-must-be-valid.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-aria-label-is-well-formatted.html.erb b/spec/conformance/fixtures/rules/html-aria-label-is-well-formatted.html.erb new file mode 100644 index 0000000..d56ae11 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-aria-label-is-well-formatted.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-aria-level-must-be-valid.html.erb b/spec/conformance/fixtures/rules/html-aria-level-must-be-valid.html.erb new file mode 100644 index 0000000..f924ed7 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-aria-level-must-be-valid.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-aria-role-heading-requires-level.html.erb b/spec/conformance/fixtures/rules/html-aria-role-heading-requires-level.html.erb new file mode 100644 index 0000000..31d460d --- /dev/null +++ b/spec/conformance/fixtures/rules/html-aria-role-heading-requires-level.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-aria-role-must-be-valid.html.erb b/spec/conformance/fixtures/rules/html-aria-role-must-be-valid.html.erb new file mode 100644 index 0000000..0836081 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-aria-role-must-be-valid.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-attribute-double-quotes.html.erb b/spec/conformance/fixtures/rules/html-attribute-double-quotes.html.erb new file mode 100644 index 0000000..3ce26f0 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-attribute-double-quotes.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-attribute-equals-spacing.html.erb b/spec/conformance/fixtures/rules/html-attribute-equals-spacing.html.erb new file mode 100644 index 0000000..4ebc575 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-attribute-equals-spacing.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-attribute-values-require-quotes.html.erb b/spec/conformance/fixtures/rules/html-attribute-values-require-quotes.html.erb new file mode 100644 index 0000000..cafa5e9 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-attribute-values-require-quotes.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-avoid-both-disabled-and-aria-disabled.html.erb b/spec/conformance/fixtures/rules/html-avoid-both-disabled-and-aria-disabled.html.erb new file mode 100644 index 0000000..56ffb85 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-avoid-both-disabled-and-aria-disabled.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-body-only-elements.html.erb b/spec/conformance/fixtures/rules/html-body-only-elements.html.erb new file mode 100644 index 0000000..d89df07 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-body-only-elements.html.erb @@ -0,0 +1,6 @@ + + +

Content

+ + + diff --git a/spec/conformance/fixtures/rules/html-boolean-attributes-no-value.html.erb b/spec/conformance/fixtures/rules/html-boolean-attributes-no-value.html.erb new file mode 100644 index 0000000..9190a02 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-boolean-attributes-no-value.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-details-has-summary.html.erb b/spec/conformance/fixtures/rules/html-details-has-summary.html.erb new file mode 100644 index 0000000..4e90180 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-details-has-summary.html.erb @@ -0,0 +1,3 @@ +
+

Content

+
diff --git a/spec/conformance/fixtures/rules/html-head-only-elements.html.erb b/spec/conformance/fixtures/rules/html-head-only-elements.html.erb new file mode 100644 index 0000000..0353fe0 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-head-only-elements.html.erb @@ -0,0 +1,6 @@ + + + + + + diff --git a/spec/conformance/fixtures/rules/html-iframe-has-title.html.erb b/spec/conformance/fixtures/rules/html-iframe-has-title.html.erb new file mode 100644 index 0000000..eaa96f6 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-iframe-has-title.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-img-require-alt.html.erb b/spec/conformance/fixtures/rules/html-img-require-alt.html.erb new file mode 100644 index 0000000..47afe54 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-img-require-alt.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-input-require-autocomplete.html.erb b/spec/conformance/fixtures/rules/html-input-require-autocomplete.html.erb new file mode 100644 index 0000000..6c92fdc --- /dev/null +++ b/spec/conformance/fixtures/rules/html-input-require-autocomplete.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-navigation-has-label.html.erb b/spec/conformance/fixtures/rules/html-navigation-has-label.html.erb new file mode 100644 index 0000000..47f176d --- /dev/null +++ b/spec/conformance/fixtures/rules/html-navigation-has-label.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-no-abstract-roles.html.erb b/spec/conformance/fixtures/rules/html-no-abstract-roles.html.erb new file mode 100644 index 0000000..29b5eb0 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-abstract-roles.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-no-aria-hidden-on-body.html.erb b/spec/conformance/fixtures/rules/html-no-aria-hidden-on-body.html.erb new file mode 100644 index 0000000..59a0793 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-aria-hidden-on-body.html.erb @@ -0,0 +1,3 @@ + +

Content

+ diff --git a/spec/conformance/fixtures/rules/html-no-aria-hidden-on-focusable.html.erb b/spec/conformance/fixtures/rules/html-no-aria-hidden-on-focusable.html.erb new file mode 100644 index 0000000..fddfa8f --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-aria-hidden-on-focusable.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/html-no-block-inside-inline.html.erb b/spec/conformance/fixtures/rules/html-no-block-inside-inline.html.erb new file mode 100644 index 0000000..2665f1d --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-block-inside-inline.html.erb @@ -0,0 +1 @@ +
Nested block
diff --git a/spec/conformance/fixtures/rules/html-no-duplicate-attributes.html.erb b/spec/conformance/fixtures/rules/html-no-duplicate-attributes.html.erb new file mode 100644 index 0000000..f8d331a --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-duplicate-attributes.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-no-duplicate-ids.html.erb b/spec/conformance/fixtures/rules/html-no-duplicate-ids.html.erb new file mode 100644 index 0000000..76dd666 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-duplicate-ids.html.erb @@ -0,0 +1,2 @@ +
A
+
B
diff --git a/spec/conformance/fixtures/rules/html-no-duplicate-meta-names.html.erb b/spec/conformance/fixtures/rules/html-no-duplicate-meta-names.html.erb new file mode 100644 index 0000000..56c5fc4 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-duplicate-meta-names.html.erb @@ -0,0 +1,4 @@ + + + + diff --git a/spec/conformance/fixtures/rules/html-no-empty-attributes.html.erb b/spec/conformance/fixtures/rules/html-no-empty-attributes.html.erb new file mode 100644 index 0000000..1ddde5c --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-empty-attributes.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-no-empty-headings.html.erb b/spec/conformance/fixtures/rules/html-no-empty-headings.html.erb new file mode 100644 index 0000000..71379cd --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-empty-headings.html.erb @@ -0,0 +1 @@ +

diff --git a/spec/conformance/fixtures/rules/html-no-nested-links.html.erb b/spec/conformance/fixtures/rules/html-no-nested-links.html.erb new file mode 100644 index 0000000..94e2bb5 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-nested-links.html.erb @@ -0,0 +1 @@ +Inner diff --git a/spec/conformance/fixtures/rules/html-no-positive-tab-index.html.erb b/spec/conformance/fixtures/rules/html-no-positive-tab-index.html.erb new file mode 100644 index 0000000..c848485 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-positive-tab-index.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-no-self-closing.html.erb b/spec/conformance/fixtures/rules/html-no-self-closing.html.erb new file mode 100644 index 0000000..a8beed5 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-self-closing.html.erb @@ -0,0 +1 @@ +
diff --git a/spec/conformance/fixtures/rules/html-no-space-in-tag.html.erb b/spec/conformance/fixtures/rules/html-no-space-in-tag.html.erb new file mode 100644 index 0000000..3d42051 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-space-in-tag.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-no-title-attribute.html.erb b/spec/conformance/fixtures/rules/html-no-title-attribute.html.erb new file mode 100644 index 0000000..88a254c --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-title-attribute.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-no-underscores-in-attribute-names.html.erb b/spec/conformance/fixtures/rules/html-no-underscores-in-attribute-names.html.erb new file mode 100644 index 0000000..feb4491 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-underscores-in-attribute-names.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/html-no-unescaped-entities.html.erb b/spec/conformance/fixtures/rules/html-no-unescaped-entities.html.erb new file mode 100644 index 0000000..1a69ddd --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-unescaped-entities.html.erb @@ -0,0 +1 @@ +

1 < 2

diff --git a/spec/conformance/fixtures/rules/html-no-unknown-tag.html.erb b/spec/conformance/fixtures/rules/html-no-unknown-tag.html.erb new file mode 100644 index 0000000..64f094f --- /dev/null +++ b/spec/conformance/fixtures/rules/html-no-unknown-tag.html.erb @@ -0,0 +1 @@ +Content diff --git a/spec/conformance/fixtures/rules/html-require-closing-tags.html.erb b/spec/conformance/fixtures/rules/html-require-closing-tags.html.erb new file mode 100644 index 0000000..6318b8d --- /dev/null +++ b/spec/conformance/fixtures/rules/html-require-closing-tags.html.erb @@ -0,0 +1,4 @@ +
    +
  • One +
  • Two +
diff --git a/spec/conformance/fixtures/rules/html-require-script-nonce.html.erb b/spec/conformance/fixtures/rules/html-require-script-nonce.html.erb new file mode 100644 index 0000000..3f8eeb5 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-require-script-nonce.html.erb @@ -0,0 +1,3 @@ + diff --git a/spec/conformance/fixtures/rules/html-tag-name-lowercase.html.erb b/spec/conformance/fixtures/rules/html-tag-name-lowercase.html.erb new file mode 100644 index 0000000..a83d558 --- /dev/null +++ b/spec/conformance/fixtures/rules/html-tag-name-lowercase.html.erb @@ -0,0 +1 @@ +
Content
diff --git a/spec/conformance/fixtures/rules/parser-no-errors.html.erb b/spec/conformance/fixtures/rules/parser-no-errors.html.erb new file mode 100644 index 0000000..e54a273 --- /dev/null +++ b/spec/conformance/fixtures/rules/parser-no-errors.html.erb @@ -0,0 +1 @@ +
diff --git a/spec/conformance/fixtures/rules/source-indentation.html.erb b/spec/conformance/fixtures/rules/source-indentation.html.erb new file mode 100644 index 0000000..3f5b8fb --- /dev/null +++ b/spec/conformance/fixtures/rules/source-indentation.html.erb @@ -0,0 +1,3 @@ +
+ hi +
diff --git a/spec/conformance/fixtures/rules/svg-tag-name-capitalization.html.erb b/spec/conformance/fixtures/rules/svg-tag-name-capitalization.html.erb new file mode 100644 index 0000000..573a99b --- /dev/null +++ b/spec/conformance/fixtures/rules/svg-tag-name-capitalization.html.erb @@ -0,0 +1 @@ + diff --git a/spec/conformance/fixtures/rules/turbo-permanent-require-id.html.erb b/spec/conformance/fixtures/rules/turbo-permanent-require-id.html.erb new file mode 100644 index 0000000..1c2d8c7 --- /dev/null +++ b/spec/conformance/fixtures/rules/turbo-permanent-require-id.html.erb @@ -0,0 +1 @@ +