create-backbone-template 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/bin/create-backbone-template.js +5 -0
- package/package.json +30 -0
- package/src/create-backbone-template.js +204 -0
- package/template/.agents/skills/agent-browser/SKILL.md +55 -0
- package/template/.agents/skills/create-plan/SKILL.md +52 -0
- package/template/.agents/skills/create-plan/agents/openai.yaml +4 -0
- package/template/.agents/skills/create-pr-presentation/SKILL.md +86 -0
- package/template/.agents/skills/create-pr-presentation/agents/openai.yaml +4 -0
- package/template/.agents/skills/implement-plan/SKILL.md +26 -0
- package/template/.agents/skills/implement-plan/agents/openai.yaml +4 -0
- package/template/.agents/skills/review-plan/SKILL.md +38 -0
- package/template/.agents/skills/review-plan/agents/openai.yaml +4 -0
- package/template/.env.schema +30 -0
- package/template/.env.test +6 -0
- package/template/.oxlintrc.json +67 -0
- package/template/.vscode/extensions.json +3 -0
- package/template/.vscode/settings.json +23 -0
- package/template/AGENTS.md +55 -0
- package/template/Cargo.lock +2648 -0
- package/template/Cargo.toml +29 -0
- package/template/Justfile +140 -0
- package/template/README.md +72 -0
- package/template/TODO.md +1 -0
- package/template/_gitignore +12 -0
- package/template/buf.gen.yaml +7 -0
- package/template/buf.yaml +10 -0
- package/template/client/.oxfmtrc.json +8 -0
- package/template/client/.oxlintrc.json +57 -0
- package/template/client/README.md +19 -0
- package/template/client/_gitignore +5 -0
- package/template/client/index.html +12 -0
- package/template/client/package.json +47 -0
- package/template/client/packages/design-system/package.json +19 -0
- package/template/client/packages/design-system/src/index.ts +2 -0
- package/template/client/packages/design-system-basic/package.json +18 -0
- package/template/client/packages/design-system-basic/src/button.stories.tsx +50 -0
- package/template/client/packages/design-system-basic/src/button.tsx +26 -0
- package/template/client/packages/design-system-basic/src/empty-state.stories.tsx +18 -0
- package/template/client/packages/design-system-basic/src/empty-state.tsx +17 -0
- package/template/client/packages/design-system-basic/src/form-field.stories.tsx +15 -0
- package/template/client/packages/design-system-basic/src/form-field.tsx +10 -0
- package/template/client/packages/design-system-basic/src/form.stories.tsx +27 -0
- package/template/client/packages/design-system-basic/src/form.tsx +9 -0
- package/template/client/packages/design-system-basic/src/heading.stories.tsx +14 -0
- package/template/client/packages/design-system-basic/src/heading.tsx +25 -0
- package/template/client/packages/design-system-basic/src/index.tsx +15 -0
- package/template/client/packages/design-system-basic/src/inline.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/inline.tsx +5 -0
- package/template/client/packages/design-system-basic/src/layout.stories.tsx +24 -0
- package/template/client/packages/design-system-basic/src/layout.tsx +14 -0
- package/template/client/packages/design-system-basic/src/loader.stories.tsx +8 -0
- package/template/client/packages/design-system-basic/src/loader.tsx +11 -0
- package/template/client/packages/design-system-basic/src/navigation.stories.tsx +16 -0
- package/template/client/packages/design-system-basic/src/navigation.tsx +18 -0
- package/template/client/packages/design-system-basic/src/notice.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/notice.tsx +5 -0
- package/template/client/packages/design-system-basic/src/stack.stories.tsx +17 -0
- package/template/client/packages/design-system-basic/src/stack.tsx +5 -0
- package/template/client/packages/design-system-basic/src/styles.css +254 -0
- package/template/client/packages/design-system-basic/src/text-input.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/text-input.tsx +5 -0
- package/template/client/packages/design-system-basic/src/text.stories.tsx +21 -0
- package/template/client/packages/design-system-basic/src/text.tsx +5 -0
- package/template/client/packages/design-system-contract/package.json +15 -0
- package/template/client/packages/design-system-contract/src/button.ts +10 -0
- package/template/client/packages/design-system-contract/src/empty-state.ts +9 -0
- package/template/client/packages/design-system-contract/src/form-field.ts +9 -0
- package/template/client/packages/design-system-contract/src/form.ts +9 -0
- package/template/client/packages/design-system-contract/src/heading.ts +9 -0
- package/template/client/packages/design-system-contract/src/index.ts +13 -0
- package/template/client/packages/design-system-contract/src/inline.ts +7 -0
- package/template/client/packages/design-system-contract/src/layout.ts +8 -0
- package/template/client/packages/design-system-contract/src/loader.ts +7 -0
- package/template/client/packages/design-system-contract/src/navigation.ts +13 -0
- package/template/client/packages/design-system-contract/src/notice.ts +8 -0
- package/template/client/packages/design-system-contract/src/stack.ts +8 -0
- package/template/client/packages/design-system-contract/src/text-input.ts +5 -0
- package/template/client/packages/design-system-contract/src/text.ts +9 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/external-ui-import.tsx +5 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/raw-dom-jsx.tsx +3 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/two-violations.tsx +7 -0
- package/template/client/packages/design-system-lint/fixtures/valid/design-system-only.tsx +13 -0
- package/template/client/packages/design-system-lint/package.json +23 -0
- package/template/client/packages/design-system-lint/src/check-design-system-architecture.ts +22 -0
- package/template/client/packages/design-system-lint/src/design-system-architecture.ts +286 -0
- package/template/client/packages/design-system-lint/src/oxlint-plugin.ts +11 -0
- package/template/client/packages/design-system-lint/src/page-architecture.ts +382 -0
- package/template/client/packages/design-system-lint/src/rules.ts +111 -0
- package/template/client/packages/design-system-lint/test/design-system-architecture.test.ts +243 -0
- package/template/client/packages/design-system-lint/test/oxlint-fixtures.test.ts +159 -0
- package/template/client/packages/design-system-lint/test/page-architecture.test.ts +175 -0
- package/template/client/packages/design-system-lint/test/rules.test.ts +65 -0
- package/template/client/packages/design-system-lint/tsconfig.json +29 -0
- package/template/client/src/App.tsx +77 -0
- package/template/client/src/design-system-components.test.tsx +75 -0
- package/template/client/src/gen/helloworld/v1/helloworld_pb.ts +63 -0
- package/template/client/src/main.tsx +18 -0
- package/template/client/src/pages/hello/hello-page.stories.tsx +20 -0
- package/template/client/src/pages/hello/hello-page.test.tsx +90 -0
- package/template/client/src/pages/hello/hello-page.tsx +126 -0
- package/template/client/src/pages/page.ts +20 -0
- package/template/client/src/testing/create-preview-events.test.ts +36 -0
- package/template/client/src/testing/create-preview-events.ts +30 -0
- package/template/client/src/vite-env.d.ts +1 -0
- package/template/client/tsconfig.json +32 -0
- package/template/client/vite.config.ts +21 -0
- package/template/client/vite.ladle.config.ts +5 -0
- package/template/e2e/.gherkin-lintrc +20 -0
- package/template/e2e/.oxfmtrc.json +15 -0
- package/template/e2e/.oxlintrc.json +37 -0
- package/template/e2e/_gitignore +4 -0
- package/template/e2e/features/helloworld.feature +10 -0
- package/template/e2e/package.json +42 -0
- package/template/e2e/playwright.config.ts +16 -0
- package/template/e2e/support/app-gherkin.ts +4 -0
- package/template/e2e/support/fixtures.ts +236 -0
- package/template/e2e/support/gherkin-fixtures/duplicate-id.feature +9 -0
- package/template/e2e/support/gherkin-fixtures/duplicate-id.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/extra-implementation.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/extra-step.spec.ts +10 -0
- package/template/e2e/support/gherkin-fixtures/happy-path.spec.ts +4 -0
- package/template/e2e/support/gherkin-fixtures/missing-id.feature +4 -0
- package/template/e2e/support/gherkin-fixtures/missing-id.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/missing-implementation.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/missing-step.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/playwright.config.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/scenario-outline.feature +9 -0
- package/template/e2e/support/gherkin-fixtures/scenario-outline.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/step-mismatch.spec.ts +9 -0
- package/template/e2e/support/gherkin-fixtures/valid-implementations.ts +23 -0
- package/template/e2e/support/gherkin-fixtures/valid-scenarios.feature +26 -0
- package/template/e2e/support/gherkin.test.ts +184 -0
- package/template/e2e/support/gherkin.ts +321 -0
- package/template/e2e/support/oxlint-plugin.test.ts +328 -0
- package/template/e2e/support/oxlint-plugin.ts +485 -0
- package/template/e2e/tests/helloworld.spec.ts +39 -0
- package/template/e2e/tsconfig.json +26 -0
- package/template/e2e/tsconfig.oxlint-plugin.json +12 -0
- package/template/package.json +9 -0
- package/template/pnpm-lock.yaml +10723 -0
- package/template/pnpm-workspace.yaml +8 -0
- package/template/pr-slide/README.md +95 -0
- package/template/pr-slide/package.json +23 -0
- package/template/pr-slide/src/cli.js +262 -0
- package/template/pr-slide/src/generate-pr-deck.js +833 -0
- package/template/pr-slide/src/git-context.js +91 -0
- package/template/pr-slide/src/presentation-paths.js +9 -0
- package/template/pr-slide/src/presentations.js +53 -0
- package/template/pr-slide/test/generate-pr-deck.test.js +118 -0
- package/template/pr-slide/test/presentation-paths.test.js +14 -0
- package/template/pr-slide/test/presentations.test.js +50 -0
- package/template/proto/helloworld/v1/helloworld.proto +15 -0
- package/template/scripts/run-e2e.sh +10 -0
- package/template/server/Cargo.toml +26 -0
- package/template/server/build.rs +9 -0
- package/template/server/dylint/backbone_server_lints/.cargo/config.toml +6 -0
- package/template/server/dylint/backbone_server_lints/Cargo.lock +1581 -0
- package/template/server/dylint/backbone_server_lints/Cargo.toml +21 -0
- package/template/server/dylint/backbone_server_lints/README.md +5 -0
- package/template/server/dylint/backbone_server_lints/_gitignore +1 -0
- package/template/server/dylint/backbone_server_lints/rust-toolchain +3 -0
- package/template/server/dylint/backbone_server_lints/src/lib.rs +612 -0
- package/template/server/dylint/backbone_server_lints/ui/lib.rs +4 -0
- package/template/server/dylint/backbone_server_lints/ui/lib.stderr +10 -0
- package/template/server/dylint/backbone_server_lints/ui/long_file.rs +303 -0
- package/template/server/dylint/backbone_server_lints/ui/long_file.stderr +6 -0
- package/template/server/dylint/backbone_server_lints/ui/main.rs +59 -0
- package/template/server/dylint/backbone_server_lints/ui/main.stderr +85 -0
- package/template/server/migrations/20260520120000_create_projects.sql +12 -0
- package/template/server/migrations/20260524160000_create_hello_world_inputs.sql +12 -0
- package/template/server/src/config.rs +27 -0
- package/template/server/src/db/hello_world.rs +34 -0
- package/template/server/src/db/hello_world_tests.rs +11 -0
- package/template/server/src/db/mod.rs +39 -0
- package/template/server/src/lib.rs +10 -0
- package/template/server/src/main.rs +43 -0
- package/template/server/src/rpc/greeter/mod.rs +31 -0
- package/template/server/src/rpc/greeter/say_hello.rs +27 -0
- package/template/server/src/rpc/mod.rs +8 -0
- package/template/server/src/state.rs +13 -0
- package/template/skills-lock.json +11 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import assert from "node:assert/strict"
|
|
2
|
+
import { spawnSync } from "node:child_process"
|
|
3
|
+
import fs from "node:fs"
|
|
4
|
+
import os from "node:os"
|
|
5
|
+
import path from "node:path"
|
|
6
|
+
import test from "node:test"
|
|
7
|
+
|
|
8
|
+
type OxlintDiagnostic = {
|
|
9
|
+
code?: string
|
|
10
|
+
filename?: string
|
|
11
|
+
labels?: Array<{
|
|
12
|
+
span?: {
|
|
13
|
+
column?: number
|
|
14
|
+
line?: number
|
|
15
|
+
}
|
|
16
|
+
}>
|
|
17
|
+
message?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type OxlintJsonOutput = {
|
|
21
|
+
diagnostics?: OxlintDiagnostic[]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const packageRoot = process.cwd()
|
|
25
|
+
|
|
26
|
+
test("valid Gherkin-backed Playwright specs pass real oxlint", () => {
|
|
27
|
+
const fixture = createFixture({
|
|
28
|
+
feature: `Feature: Greeting
|
|
29
|
+
|
|
30
|
+
@id:greeting.say-hello
|
|
31
|
+
Scenario: Say hello
|
|
32
|
+
Given the visitor is on the hello page
|
|
33
|
+
When they ask to greet Playwright
|
|
34
|
+
Then they see the Playwright greeting
|
|
35
|
+
`,
|
|
36
|
+
spec: `import { feature } from "../../support/gherkin"
|
|
37
|
+
|
|
38
|
+
feature("../features/greeting.feature", {
|
|
39
|
+
"greeting.say-hello": async ({ scenario }) => {
|
|
40
|
+
await scenario.step("Given the visitor is on the hello page", async () => {})
|
|
41
|
+
await scenario.step("When they ask to greet Playwright", async () => {})
|
|
42
|
+
await scenario.step("Then they see the Playwright greeting", async () => {})
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
`,
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const result = runOxlint(fixture.path)
|
|
50
|
+
|
|
51
|
+
assert.equal(result.status, 0)
|
|
52
|
+
assert.deepEqual(result.diagnostics, [])
|
|
53
|
+
} finally {
|
|
54
|
+
fixture.dispose()
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test("drift between Gherkin and Playwright specs reports stable oxlint diagnostics", () => {
|
|
59
|
+
const fixture = createFixture({
|
|
60
|
+
feature: `Feature: Greeting
|
|
61
|
+
|
|
62
|
+
@id:greeting.say-hello
|
|
63
|
+
Scenario: Say hello
|
|
64
|
+
Given the visitor is on the hello page
|
|
65
|
+
When they ask to greet Playwright
|
|
66
|
+
Then they see the Playwright greeting
|
|
67
|
+
`,
|
|
68
|
+
spec: `import { feature } from "../../support/gherkin"
|
|
69
|
+
|
|
70
|
+
feature("../features/greeting.feature", {
|
|
71
|
+
"greeting.say-hello": async ({ scenario }) => {
|
|
72
|
+
await scenario.step("Given the visitor is on the hello page", async () => {})
|
|
73
|
+
await scenario.step("Then they see the Playwright greeting", async () => {})
|
|
74
|
+
},
|
|
75
|
+
"greeting.extra": async ({ scenario }) => {
|
|
76
|
+
await scenario.step("Given an extra implementation", async () => {})
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
`,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const result = runOxlint(fixture.path)
|
|
84
|
+
|
|
85
|
+
assert.equal(result.status, 1)
|
|
86
|
+
assert.deepEqual(
|
|
87
|
+
result.diagnostics.map((diagnostic) => ({
|
|
88
|
+
code: diagnostic.code,
|
|
89
|
+
column: diagnostic.column,
|
|
90
|
+
file: path.basename(diagnostic.filename ?? ""),
|
|
91
|
+
line: diagnostic.line,
|
|
92
|
+
message: diagnostic.message,
|
|
93
|
+
})),
|
|
94
|
+
[
|
|
95
|
+
{
|
|
96
|
+
code: "backbone-e2e/valid-gherkin-feature",
|
|
97
|
+
column: 3,
|
|
98
|
+
file: "greeting.spec.ts",
|
|
99
|
+
line: 4,
|
|
100
|
+
message:
|
|
101
|
+
'missing implemented step for "greeting.say-hello" from ' +
|
|
102
|
+
`${path.join(fixture.path, "features/greeting.feature")}:4: ` +
|
|
103
|
+
'"When they ask to greet Playwright".',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
code: "backbone-e2e/valid-gherkin-feature",
|
|
107
|
+
column: 3,
|
|
108
|
+
file: "greeting.spec.ts",
|
|
109
|
+
line: 8,
|
|
110
|
+
message: 'implementation id "greeting.extra" has no matching scenario.',
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
)
|
|
114
|
+
} finally {
|
|
115
|
+
fixture.dispose()
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test("renamed scenario.step labels report missing and unexpected step diagnostics", () => {
|
|
120
|
+
const fixture = createFixture({
|
|
121
|
+
feature: `Feature: Greeting
|
|
122
|
+
|
|
123
|
+
@id:greeting.say-hello
|
|
124
|
+
Scenario: Say hello
|
|
125
|
+
Given the visitor is on the hello page
|
|
126
|
+
When they ask to greet Playwright
|
|
127
|
+
Then they see the Playwright greeting
|
|
128
|
+
`,
|
|
129
|
+
spec: `import { feature } from "../../support/gherkin"
|
|
130
|
+
|
|
131
|
+
feature("../features/greeting.feature", {
|
|
132
|
+
"greeting.say-hello": async ({ scenario }) => {
|
|
133
|
+
await scenario.step("Given the visitor is on the hello page", async () => {})
|
|
134
|
+
await scenario.step("When they ask to greet Cypress", async () => {})
|
|
135
|
+
await scenario.step("Then they see the Playwright greeting", async () => {})
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
`,
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const result = runOxlint(fixture.path)
|
|
143
|
+
|
|
144
|
+
assert.equal(result.status, 1)
|
|
145
|
+
assert.deepEqual(
|
|
146
|
+
result.diagnostics.map((diagnostic) => ({
|
|
147
|
+
code: diagnostic.code,
|
|
148
|
+
column: diagnostic.column,
|
|
149
|
+
file: path.basename(diagnostic.filename ?? ""),
|
|
150
|
+
line: diagnostic.line,
|
|
151
|
+
message: diagnostic.message,
|
|
152
|
+
})),
|
|
153
|
+
[
|
|
154
|
+
{
|
|
155
|
+
code: "backbone-e2e/valid-gherkin-feature",
|
|
156
|
+
column: 3,
|
|
157
|
+
file: "greeting.spec.ts",
|
|
158
|
+
line: 4,
|
|
159
|
+
message:
|
|
160
|
+
'missing implemented step for "greeting.say-hello" from ' +
|
|
161
|
+
`${path.join(fixture.path, "features/greeting.feature")}:4: ` +
|
|
162
|
+
'"When they ask to greet Playwright".',
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
code: "backbone-e2e/valid-gherkin-feature",
|
|
166
|
+
column: 25,
|
|
167
|
+
file: "greeting.spec.ts",
|
|
168
|
+
line: 6,
|
|
169
|
+
message:
|
|
170
|
+
'unexpected implemented step for "greeting.say-hello": ' +
|
|
171
|
+
'"When they ask to greet Cypress". No step with this label exists in the feature scenario.',
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
)
|
|
175
|
+
} finally {
|
|
176
|
+
fixture.dispose()
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
test("extra scenario.step labels report implementation and step diagnostics", () => {
|
|
181
|
+
const fixture = createFixture({
|
|
182
|
+
feature: `Feature: Greeting
|
|
183
|
+
|
|
184
|
+
@id:greeting.say-hello
|
|
185
|
+
Scenario: Say hello
|
|
186
|
+
Given the visitor is on the hello page
|
|
187
|
+
When they ask to greet Playwright
|
|
188
|
+
Then they see the Playwright greeting
|
|
189
|
+
`,
|
|
190
|
+
spec: `import { feature } from "../../support/gherkin"
|
|
191
|
+
|
|
192
|
+
feature("../features/greeting.feature", {
|
|
193
|
+
"greeting.say-hello": async ({ scenario }) => {
|
|
194
|
+
await scenario.step("Given the visitor is on the hello page", async () => {})
|
|
195
|
+
await scenario.step("When they ask to greet Playwright", async () => {})
|
|
196
|
+
await scenario.step("Then they see an extra Cypress greeting", async () => {})
|
|
197
|
+
await scenario.step("Then they see the Playwright greeting", async () => {})
|
|
198
|
+
},
|
|
199
|
+
})
|
|
200
|
+
`,
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
const result = runOxlint(fixture.path)
|
|
205
|
+
|
|
206
|
+
assert.equal(result.status, 1)
|
|
207
|
+
assert.deepEqual(
|
|
208
|
+
result.diagnostics.map((diagnostic) => ({
|
|
209
|
+
code: diagnostic.code,
|
|
210
|
+
column: diagnostic.column,
|
|
211
|
+
file: path.basename(diagnostic.filename ?? ""),
|
|
212
|
+
line: diagnostic.line,
|
|
213
|
+
message: diagnostic.message,
|
|
214
|
+
})),
|
|
215
|
+
[
|
|
216
|
+
{
|
|
217
|
+
code: "backbone-e2e/valid-gherkin-feature",
|
|
218
|
+
column: 3,
|
|
219
|
+
file: "greeting.spec.ts",
|
|
220
|
+
line: 4,
|
|
221
|
+
message:
|
|
222
|
+
'extra implemented step(s) for "greeting.say-hello" not present in ' +
|
|
223
|
+
`${path.join(fixture.path, "features/greeting.feature")}:4: ` +
|
|
224
|
+
'"Then they see an extra Cypress greeting".',
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
code: "backbone-e2e/valid-gherkin-feature",
|
|
228
|
+
column: 25,
|
|
229
|
+
file: "greeting.spec.ts",
|
|
230
|
+
line: 7,
|
|
231
|
+
message:
|
|
232
|
+
'unexpected implemented step for "greeting.say-hello": ' +
|
|
233
|
+
'"Then they see an extra Cypress greeting". ' +
|
|
234
|
+
"No step with this label exists in the feature scenario.",
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
)
|
|
238
|
+
} finally {
|
|
239
|
+
fixture.dispose()
|
|
240
|
+
}
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
function createFixture(files: { feature: string; spec: string }) {
|
|
244
|
+
const fixturePath = fs.mkdtempSync(path.join(os.tmpdir(), "backbone-e2e-oxlint-"))
|
|
245
|
+
|
|
246
|
+
fs.mkdirSync(path.join(fixturePath, "features"))
|
|
247
|
+
fs.mkdirSync(path.join(fixturePath, "tests"))
|
|
248
|
+
fs.writeFileSync(path.join(fixturePath, "features/greeting.feature"), files.feature)
|
|
249
|
+
fs.writeFileSync(path.join(fixturePath, "tests/greeting.spec.ts"), files.spec)
|
|
250
|
+
fs.writeFileSync(
|
|
251
|
+
path.join(fixturePath, "oxlint.json"),
|
|
252
|
+
JSON.stringify({
|
|
253
|
+
jsPlugins: [path.join(packageRoot, "support/dist/oxlint-plugin.js")],
|
|
254
|
+
rules: {
|
|
255
|
+
"backbone-e2e/valid-gherkin-feature": "error",
|
|
256
|
+
},
|
|
257
|
+
}),
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
return {
|
|
261
|
+
path: fixturePath,
|
|
262
|
+
dispose() {
|
|
263
|
+
fs.rmSync(fixturePath, { force: true, recursive: true })
|
|
264
|
+
},
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function runOxlint(fixturePath: string) {
|
|
269
|
+
const result = spawnSync(
|
|
270
|
+
process.platform === "win32" ? "pnpm.cmd" : "pnpm",
|
|
271
|
+
[
|
|
272
|
+
"exec",
|
|
273
|
+
"oxlint",
|
|
274
|
+
"--config",
|
|
275
|
+
path.join(fixturePath, "oxlint.json"),
|
|
276
|
+
"--format",
|
|
277
|
+
"json",
|
|
278
|
+
path.join(fixturePath, "tests"),
|
|
279
|
+
],
|
|
280
|
+
{
|
|
281
|
+
cwd: packageRoot,
|
|
282
|
+
encoding: "utf8",
|
|
283
|
+
},
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
if (result.error !== undefined && result.status === null) {
|
|
287
|
+
throw result.error
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
diagnostics: parseDiagnostics(result.stdout),
|
|
292
|
+
status: result.status,
|
|
293
|
+
stderr: result.stderr,
|
|
294
|
+
stdout: result.stdout,
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function parseDiagnostics(output: string) {
|
|
299
|
+
if (output.trim() === "") {
|
|
300
|
+
return []
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const parsed = JSON.parse(output) as OxlintJsonOutput
|
|
304
|
+
|
|
305
|
+
return (parsed.diagnostics ?? [])
|
|
306
|
+
.filter((diagnostic) => diagnostic.code?.startsWith("backbone-e2e"))
|
|
307
|
+
.map((diagnostic) => ({
|
|
308
|
+
code: normalizeRuleCode(diagnostic.code),
|
|
309
|
+
column: diagnostic.labels?.[0]?.span?.column,
|
|
310
|
+
filename: diagnostic.filename,
|
|
311
|
+
line: diagnostic.labels?.[0]?.span?.line,
|
|
312
|
+
message: diagnostic.message,
|
|
313
|
+
}))
|
|
314
|
+
.sort((left, right) => {
|
|
315
|
+
const leftLine = left.line ?? 0
|
|
316
|
+
const rightLine = right.line ?? 0
|
|
317
|
+
|
|
318
|
+
if (leftLine !== rightLine) {
|
|
319
|
+
return leftLine - rightLine
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return (left.message ?? "").localeCompare(right.message ?? "")
|
|
323
|
+
})
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function normalizeRuleCode(code: string | undefined) {
|
|
327
|
+
return code?.replace(/^backbone-e2e\((.+)\)$/, "backbone-e2e/$1")
|
|
328
|
+
}
|