@sun-asterisk/sungen 3.1.2-beta.126 → 3.1.2-beta.128
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/dist/harness/data-driven-lint.d.ts.map +1 -1
- package/dist/harness/data-driven-lint.js +23 -0
- package/dist/harness/data-driven-lint.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-skill-api-design.md +12 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +12 -0
- package/package.json +2 -2
- package/src/harness/data-driven-lint.ts +20 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-api-design.md +12 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +12 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-driven-lint.d.ts","sourceRoot":"","sources":["../../src/harness/data-driven-lint.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAwBD,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"data-driven-lint.d.ts","sourceRoot":"","sources":["../../src/harness/data-driven-lint.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAwBD,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,iBAAiB,EAAE,CAgGlG"}
|
|
@@ -140,6 +140,29 @@ function lintDataDriven(screenDir, cwd = process.cwd()) {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
+
// --- orphan test-data: a top-level key never referenced (dead data — generated but not
|
|
144
|
+
// materialized into a scenario). Referenced = a `{{key…}}` in any step, a `@cases:<key>`
|
|
145
|
+
// dataset, or an override value `…={{key…}}` on an @api/@query annotation.
|
|
146
|
+
const usedHeads = new Set();
|
|
147
|
+
const usedDatasets = new Set();
|
|
148
|
+
for (const sc of scenarios) {
|
|
149
|
+
for (const r of collectRefs(sc))
|
|
150
|
+
usedHeads.add(r.split(/[.[]/)[0]);
|
|
151
|
+
for (const t of sc.tags || []) {
|
|
152
|
+
const cm = t.match(/^@cases:(.+)$/);
|
|
153
|
+
if (cm)
|
|
154
|
+
usedDatasets.add(cm[1].trim());
|
|
155
|
+
const om = t.match(/^@(?:api|query):[A-Za-z_]\w*\((.*)\)$/);
|
|
156
|
+
if (om)
|
|
157
|
+
for (const ref of om[1].matchAll(/\{\{\s*([^}]+?)\s*\}\}/g))
|
|
158
|
+
usedHeads.add(ref[1].split(/[.[]/)[0].trim());
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
for (const k of topKeys) {
|
|
162
|
+
if (!usedHeads.has(k) && !usedDatasets.has(k)) {
|
|
163
|
+
warns.push({ message: `test-data key "${k}" is defined but never referenced ({{${k}}}, a @cases dataset, or an override) — dead data: bind it into a scenario or remove it.` });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
143
166
|
// Catalog-level lint (SELECT-only, params declared/used, datasource present).
|
|
144
167
|
try {
|
|
145
168
|
for (const e of (0, query_catalog_1.lintCatalog)(screenName, null, cwd).errors)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-driven-lint.js","sourceRoot":"","sources":["../../src/harness/data-driven-lint.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,
|
|
1
|
+
{"version":3,"file":"data-driven-lint.js","sourceRoot":"","sources":["../../src/harness/data-driven-lint.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,7 +44,19 @@ Stop when the gate PASSes + businessDepth ≥ 0.7, or the budget is exhausted
|
|
|
44
44
|
### 5. Record + converge
|
|
45
45
|
`sungen manifest --area <name>` (reuse) and ledger each phase; show the trace + the HUMAN-LOOP FOCUS. (Integrity `script-check`/`trace` for api: see run-test.)
|
|
46
46
|
|
|
47
|
+
## Taxonomy (label scenarios correctly)
|
|
48
|
+
|
|
49
|
+
| Class | What | Examples |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Functional** | single-endpoint behaviour | happy contract · error/validation (`@cases`) · boundary/edge |
|
|
52
|
+
| **Functional — flow/integration** | multi-endpoint journeys | auth/CRUD lifecycle (`create → login → get → delete`), cross-endpoint invariants |
|
|
53
|
+
| **Non-Functional** | performance · reliability · **security** · concurrency/idempotency | `@concurrent` race/idempotency |
|
|
54
|
+
|
|
55
|
+
A flow (`create → login → delete`) is a **Functional integration** test, **not** non-functional — don't file it under "Non-Functional". Reserve non-functional for perf/security/concurrency.
|
|
56
|
+
|
|
47
57
|
## Rules
|
|
48
58
|
- **No HTTP, no selectors** — only `.feature` + the reviewed `apis.yaml` + `test-data`.
|
|
49
59
|
- **Non-prod default** — a `production` datasource is refused unless `SUNGEN_ALLOW_PROD=1`.
|
|
50
60
|
- **The DB is the oracle** for idempotency/side-effects — HTTP status alone can lie; pair `@api` with `@query`.
|
|
61
|
+
- **`@parallel` + mutating endpoints** — give each scenario **isolated data** (a `{{$uuid}}` email, a `@cases` row, or its own created resource) and **self-clean** (delete what it created); shared inputs race under parallel execution.
|
|
62
|
+
- **No dead data** — every `test-data` key must be bound into a scenario (`{{key}}`, a `@cases` dataset, or an override). `sungen audit`/the generate lint flag unreferenced keys.
|
|
@@ -44,7 +44,19 @@ Stop when the gate PASSes + businessDepth ≥ 0.7, or the budget is exhausted
|
|
|
44
44
|
### 5. Record + converge
|
|
45
45
|
`sungen manifest --area <name>` (reuse) and ledger each phase; show the trace + the HUMAN-LOOP FOCUS. (Integrity `script-check`/`trace` for api: see run-test.)
|
|
46
46
|
|
|
47
|
+
## Taxonomy (label scenarios correctly)
|
|
48
|
+
|
|
49
|
+
| Class | What | Examples |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Functional** | single-endpoint behaviour | happy contract · error/validation (`@cases`) · boundary/edge |
|
|
52
|
+
| **Functional — flow/integration** | multi-endpoint journeys | auth/CRUD lifecycle (`create → login → get → delete`), cross-endpoint invariants |
|
|
53
|
+
| **Non-Functional** | performance · reliability · **security** · concurrency/idempotency | `@concurrent` race/idempotency |
|
|
54
|
+
|
|
55
|
+
A flow (`create → login → delete`) is a **Functional integration** test, **not** non-functional — don't file it under "Non-Functional". Reserve non-functional for perf/security/concurrency.
|
|
56
|
+
|
|
47
57
|
## Rules
|
|
48
58
|
- **No HTTP, no selectors** — only `.feature` + the reviewed `apis.yaml` + `test-data`.
|
|
49
59
|
- **Non-prod default** — a `production` datasource is refused unless `SUNGEN_ALLOW_PROD=1`.
|
|
50
60
|
- **The DB is the oracle** for idempotency/side-effects — HTTP status alone can lie; pair `@api` with `@query`.
|
|
61
|
+
- **`@parallel` + mutating endpoints** — give each scenario **isolated data** (a `{{$uuid}}` email, a `@cases` row, or its own created resource) and **self-clean** (delete what it created); shared inputs race under parallel execution.
|
|
62
|
+
- **No dead data** — every `test-data` key must be bound into a scenario (`{{key}}`, a `@cases` dataset, or an override). `sungen audit`/the generate lint flag unreferenced keys.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sungen",
|
|
3
|
-
"version": "3.1.2-beta.
|
|
3
|
+
"version": "3.1.2-beta.128",
|
|
4
4
|
"description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=18.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@sungen/driver-ui": "3.1.2-beta.
|
|
36
|
+
"@sungen/driver-ui": "3.1.2-beta.128",
|
|
37
37
|
"@anthropic-ai/sdk": "^0.71.0",
|
|
38
38
|
"@babel/parser": "^7.28.5",
|
|
39
39
|
"@babel/traverse": "^7.28.5",
|
|
@@ -109,6 +109,26 @@ export function lintDataDriven(screenDir: string, cwd: string = process.cwd()):
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
// --- orphan test-data: a top-level key never referenced (dead data — generated but not
|
|
113
|
+
// materialized into a scenario). Referenced = a `{{key…}}` in any step, a `@cases:<key>`
|
|
114
|
+
// dataset, or an override value `…={{key…}}` on an @api/@query annotation.
|
|
115
|
+
const usedHeads = new Set<string>();
|
|
116
|
+
const usedDatasets = new Set<string>();
|
|
117
|
+
for (const sc of scenarios) {
|
|
118
|
+
for (const r of collectRefs(sc)) usedHeads.add(r.split(/[.[]/)[0]);
|
|
119
|
+
for (const t of sc.tags || []) {
|
|
120
|
+
const cm = t.match(/^@cases:(.+)$/);
|
|
121
|
+
if (cm) usedDatasets.add(cm[1].trim());
|
|
122
|
+
const om = t.match(/^@(?:api|query):[A-Za-z_]\w*\((.*)\)$/);
|
|
123
|
+
if (om) for (const ref of om[1].matchAll(/\{\{\s*([^}]+?)\s*\}\}/g)) usedHeads.add(ref[1].split(/[.[]/)[0].trim());
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
for (const k of topKeys) {
|
|
127
|
+
if (!usedHeads.has(k) && !usedDatasets.has(k)) {
|
|
128
|
+
warns.push({ message: `test-data key "${k}" is defined but never referenced ({{${k}}}, a @cases dataset, or an override) — dead data: bind it into a scenario or remove it.` });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
112
132
|
// Catalog-level lint (SELECT-only, params declared/used, datasource present).
|
|
113
133
|
try {
|
|
114
134
|
for (const e of lintCatalog(screenName, null, cwd).errors) warns.push({ message: e });
|
|
@@ -44,7 +44,19 @@ Stop when the gate PASSes + businessDepth ≥ 0.7, or the budget is exhausted
|
|
|
44
44
|
### 5. Record + converge
|
|
45
45
|
`sungen manifest --area <name>` (reuse) and ledger each phase; show the trace + the HUMAN-LOOP FOCUS. (Integrity `script-check`/`trace` for api: see run-test.)
|
|
46
46
|
|
|
47
|
+
## Taxonomy (label scenarios correctly)
|
|
48
|
+
|
|
49
|
+
| Class | What | Examples |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Functional** | single-endpoint behaviour | happy contract · error/validation (`@cases`) · boundary/edge |
|
|
52
|
+
| **Functional — flow/integration** | multi-endpoint journeys | auth/CRUD lifecycle (`create → login → get → delete`), cross-endpoint invariants |
|
|
53
|
+
| **Non-Functional** | performance · reliability · **security** · concurrency/idempotency | `@concurrent` race/idempotency |
|
|
54
|
+
|
|
55
|
+
A flow (`create → login → delete`) is a **Functional integration** test, **not** non-functional — don't file it under "Non-Functional". Reserve non-functional for perf/security/concurrency.
|
|
56
|
+
|
|
47
57
|
## Rules
|
|
48
58
|
- **No HTTP, no selectors** — only `.feature` + the reviewed `apis.yaml` + `test-data`.
|
|
49
59
|
- **Non-prod default** — a `production` datasource is refused unless `SUNGEN_ALLOW_PROD=1`.
|
|
50
60
|
- **The DB is the oracle** for idempotency/side-effects — HTTP status alone can lie; pair `@api` with `@query`.
|
|
61
|
+
- **`@parallel` + mutating endpoints** — give each scenario **isolated data** (a `{{$uuid}}` email, a `@cases` row, or its own created resource) and **self-clean** (delete what it created); shared inputs race under parallel execution.
|
|
62
|
+
- **No dead data** — every `test-data` key must be bound into a scenario (`{{key}}`, a `@cases` dataset, or an override). `sungen audit`/the generate lint flag unreferenced keys.
|
|
@@ -44,7 +44,19 @@ Stop when the gate PASSes + businessDepth ≥ 0.7, or the budget is exhausted
|
|
|
44
44
|
### 5. Record + converge
|
|
45
45
|
`sungen manifest --area <name>` (reuse) and ledger each phase; show the trace + the HUMAN-LOOP FOCUS. (Integrity `script-check`/`trace` for api: see run-test.)
|
|
46
46
|
|
|
47
|
+
## Taxonomy (label scenarios correctly)
|
|
48
|
+
|
|
49
|
+
| Class | What | Examples |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Functional** | single-endpoint behaviour | happy contract · error/validation (`@cases`) · boundary/edge |
|
|
52
|
+
| **Functional — flow/integration** | multi-endpoint journeys | auth/CRUD lifecycle (`create → login → get → delete`), cross-endpoint invariants |
|
|
53
|
+
| **Non-Functional** | performance · reliability · **security** · concurrency/idempotency | `@concurrent` race/idempotency |
|
|
54
|
+
|
|
55
|
+
A flow (`create → login → delete`) is a **Functional integration** test, **not** non-functional — don't file it under "Non-Functional". Reserve non-functional for perf/security/concurrency.
|
|
56
|
+
|
|
47
57
|
## Rules
|
|
48
58
|
- **No HTTP, no selectors** — only `.feature` + the reviewed `apis.yaml` + `test-data`.
|
|
49
59
|
- **Non-prod default** — a `production` datasource is refused unless `SUNGEN_ALLOW_PROD=1`.
|
|
50
60
|
- **The DB is the oracle** for idempotency/side-effects — HTTP status alone can lie; pair `@api` with `@query`.
|
|
61
|
+
- **`@parallel` + mutating endpoints** — give each scenario **isolated data** (a `{{$uuid}}` email, a `@cases` row, or its own created resource) and **self-clean** (delete what it created); shared inputs race under parallel execution.
|
|
62
|
+
- **No dead data** — every `test-data` key must be bound into a scenario (`{{key}}`, a `@cases` dataset, or an override). `sungen audit`/the generate lint flag unreferenced keys.
|