@vitest-agent/sdk 2.5.1 → 3.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/index.d.ts +608 -14
- package/index.js +12 -8
- package/layers/DataReaderLive.js +90 -0
- package/layers/DataStoreLive.js +48 -2
- package/migrations/0002_test_artifacts.js +30 -0
- package/migrations/index.js +26 -0
- package/package.json +7 -6
- package/schemas/CoverageTargets.js +9 -4
- package/schemas/Options.js +20 -4
- package/schemas/RunEvent.js +8 -2
- package/schemas/RunReportFile.js +51 -0
- package/schemas/TestArtifacts.js +74 -0
- package/schemas/Thresholds.js +23 -3
- package/schemas/run-report-file-1.0.0.json +963 -0
- package/services/DataStore.js +8 -1
- package/testing/layers.js +2 -2
- package/testing.d.ts +165 -2
- package/testing.js +5 -4
- package/utils/ensure-migrated.js +2 -2
- package/utils/test-location.js +11 -1
- package/utils/validate-coverage-targets-shape.js +12 -4
package/services/DataStore.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { Context } from "effect";
|
|
2
2
|
|
|
3
3
|
//#region src/services/DataStore.ts
|
|
4
|
+
/**
|
|
5
|
+
* Ceiling on an inline attachment body. Vitest has already copied file
|
|
6
|
+
* attachments into `.vitest/attachments/`, so a large body is referenced
|
|
7
|
+
* by `path` rather than duplicated into `data.db`.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
const INLINE_ATTACHMENT_BODY_CAP_BYTES = 65536;
|
|
4
11
|
/** @public */
|
|
5
12
|
var DataStore = class extends Context.Service()("vitest-agent/DataStore") {};
|
|
6
13
|
|
|
7
14
|
//#endregion
|
|
8
|
-
export { DataStore };
|
|
15
|
+
export { DataStore, INLINE_ATTACHMENT_BODY_CAP_BYTES };
|
package/testing/layers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DataReaderLive } from "../layers/DataReaderLive.js";
|
|
2
2
|
import { DataStoreLive } from "../layers/DataStoreLive.js";
|
|
3
|
-
import
|
|
3
|
+
import { PROJECT_MIGRATIONS } from "../migrations/index.js";
|
|
4
4
|
import { Layer } from "effect";
|
|
5
5
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
6
6
|
import { layer } from "@effect/sql-sqlite-node/SqliteClient";
|
|
@@ -11,7 +11,7 @@ import * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator";
|
|
|
11
11
|
function makeTestLayer(filename) {
|
|
12
12
|
const SqliteLayer = layer({ filename });
|
|
13
13
|
const PlatformLayer = NodeServices.layer;
|
|
14
|
-
const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord(
|
|
14
|
+
const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord(PROJECT_MIGRATIONS) }).pipe(Layer.provide(Layer.merge(SqliteLayer, PlatformLayer)));
|
|
15
15
|
return Layer.mergeAll(DataStoreLive.pipe(Layer.provide(SqliteLayer)), DataReaderLive.pipe(Layer.provide(SqliteLayer)), MigratorLayer, SqliteLayer, PlatformLayer);
|
|
16
16
|
}
|
|
17
17
|
/** @public */
|
package/testing.d.ts
CHANGED
|
@@ -100,6 +100,12 @@ export declare const AgentReport: Schema.Struct<{
|
|
|
100
100
|
readonly functions: Schema.optional<Schema.Number>;
|
|
101
101
|
readonly branches: Schema.optional<Schema.Number>;
|
|
102
102
|
readonly statements: Schema.optional<Schema.Number>;
|
|
103
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
104
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
105
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
106
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
107
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
108
|
+
}>]>>;
|
|
103
109
|
}>]>>, never>;
|
|
104
110
|
}>;
|
|
105
111
|
readonly targets: Schema.optional<Schema.Struct<{
|
|
@@ -114,6 +120,12 @@ export declare const AgentReport: Schema.Struct<{
|
|
|
114
120
|
readonly functions: Schema.optional<Schema.Number>;
|
|
115
121
|
readonly branches: Schema.optional<Schema.Number>;
|
|
116
122
|
readonly statements: Schema.optional<Schema.Number>;
|
|
123
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
124
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
125
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
126
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
127
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
128
|
+
}>]>>;
|
|
117
129
|
}>]>>, never>;
|
|
118
130
|
}>>;
|
|
119
131
|
readonly baselines: Schema.optional<Schema.Struct<{
|
|
@@ -128,6 +140,12 @@ export declare const AgentReport: Schema.Struct<{
|
|
|
128
140
|
readonly functions: Schema.optional<Schema.Number>;
|
|
129
141
|
readonly branches: Schema.optional<Schema.Number>;
|
|
130
142
|
readonly statements: Schema.optional<Schema.Number>;
|
|
143
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
144
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
145
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
146
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
147
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
148
|
+
}>]>>;
|
|
131
149
|
}>]>>, never>;
|
|
132
150
|
}>>;
|
|
133
151
|
readonly scoped: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
|
|
@@ -198,6 +216,12 @@ export declare const CoverageBaselines: Schema.Struct<{
|
|
|
198
216
|
readonly functions: Schema.optional<Schema.Number>;
|
|
199
217
|
readonly branches: Schema.optional<Schema.Number>;
|
|
200
218
|
readonly statements: Schema.optional<Schema.Number>;
|
|
219
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
220
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
221
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
222
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
223
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
224
|
+
}>]>>;
|
|
201
225
|
}>]>>, never>;
|
|
202
226
|
}>;
|
|
203
227
|
/** @public */
|
|
@@ -262,6 +286,12 @@ export declare const CoverageReport: Schema.Struct<{
|
|
|
262
286
|
readonly functions: Schema.optional<Schema.Number>;
|
|
263
287
|
readonly branches: Schema.optional<Schema.Number>;
|
|
264
288
|
readonly statements: Schema.optional<Schema.Number>;
|
|
289
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
290
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
291
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
292
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
293
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
294
|
+
}>]>>;
|
|
265
295
|
}>]>>, never>;
|
|
266
296
|
}>;
|
|
267
297
|
readonly targets: Schema.optional<Schema.Struct<{
|
|
@@ -276,6 +306,12 @@ export declare const CoverageReport: Schema.Struct<{
|
|
|
276
306
|
readonly functions: Schema.optional<Schema.Number>;
|
|
277
307
|
readonly branches: Schema.optional<Schema.Number>;
|
|
278
308
|
readonly statements: Schema.optional<Schema.Number>;
|
|
309
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
310
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
311
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
312
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
313
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
314
|
+
}>]>>;
|
|
279
315
|
}>]>>, never>;
|
|
280
316
|
}>>;
|
|
281
317
|
readonly baselines: Schema.optional<Schema.Struct<{
|
|
@@ -290,6 +326,12 @@ export declare const CoverageReport: Schema.Struct<{
|
|
|
290
326
|
readonly functions: Schema.optional<Schema.Number>;
|
|
291
327
|
readonly branches: Schema.optional<Schema.Number>;
|
|
292
328
|
readonly statements: Schema.optional<Schema.Number>;
|
|
329
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
330
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
331
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
332
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
333
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
334
|
+
}>]>>;
|
|
293
335
|
}>]>>, never>;
|
|
294
336
|
}>>;
|
|
295
337
|
readonly scoped: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
|
|
@@ -698,12 +740,23 @@ declare const ResolvedThresholds: Schema.Struct<{
|
|
|
698
740
|
readonly branches: Schema.optional<Schema.Number>;
|
|
699
741
|
readonly statements: Schema.optional<Schema.Number>;
|
|
700
742
|
}>;
|
|
701
|
-
readonly perFile: Schema.withDecodingDefaultKey<Schema.Boolean,
|
|
743
|
+
readonly perFile: Schema.withDecodingDefaultKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
744
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
745
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
746
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
747
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
748
|
+
}>]>, never>;
|
|
702
749
|
readonly patterns: Schema.withDecodingDefaultKey<Schema.$Array<Schema.Tuple<readonly [Schema.String, Schema.Struct<{
|
|
703
750
|
readonly lines: Schema.optional<Schema.Number>;
|
|
704
751
|
readonly functions: Schema.optional<Schema.Number>;
|
|
705
752
|
readonly branches: Schema.optional<Schema.Number>;
|
|
706
753
|
readonly statements: Schema.optional<Schema.Number>;
|
|
754
|
+
readonly perFile: Schema.optionalKey<Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
755
|
+
readonly lines: Schema.optional<Schema.Number>;
|
|
756
|
+
readonly functions: Schema.optional<Schema.Number>;
|
|
757
|
+
readonly branches: Schema.optional<Schema.Number>;
|
|
758
|
+
readonly statements: Schema.optional<Schema.Number>;
|
|
759
|
+
}>]>>;
|
|
707
760
|
}>]>>, never>;
|
|
708
761
|
}>;
|
|
709
762
|
/** @public */
|
|
@@ -877,6 +930,41 @@ interface TestErrorInput {
|
|
|
877
930
|
readonly ordinal?: number;
|
|
878
931
|
}
|
|
879
932
|
/** @public */
|
|
933
|
+
interface TestAttachmentInput {
|
|
934
|
+
readonly contentType?: string;
|
|
935
|
+
/** Post-resolution path under `.vitest/attachments/`, or an http(s) URL. */
|
|
936
|
+
readonly path?: string;
|
|
937
|
+
/** Inline body; persisted only when `byteSize` is under the 64 KiB cap. */
|
|
938
|
+
readonly body?: string;
|
|
939
|
+
/** How to read `body`. Vitest treats a string body as base64 unless `"utf-8"`. */
|
|
940
|
+
readonly bodyEncoding?: "base64" | "utf-8";
|
|
941
|
+
readonly byteSize: number;
|
|
942
|
+
}
|
|
943
|
+
/** @public */
|
|
944
|
+
interface TestAnnotationInput {
|
|
945
|
+
readonly testCaseId: number;
|
|
946
|
+
/** Arbitrary Vitest annotation type -- not an enum. */
|
|
947
|
+
readonly type: string;
|
|
948
|
+
readonly message: string;
|
|
949
|
+
readonly locationFile?: string;
|
|
950
|
+
readonly locationLine?: number;
|
|
951
|
+
readonly locationColumn?: number;
|
|
952
|
+
readonly attachments?: ReadonlyArray<TestAttachmentInput>;
|
|
953
|
+
}
|
|
954
|
+
/** @public */
|
|
955
|
+
interface TestArtifactInput {
|
|
956
|
+
readonly testCaseId: number;
|
|
957
|
+
/** `pkg:name`; `internal:` types are Vitest's own and are never written. */
|
|
958
|
+
readonly type: string;
|
|
959
|
+
readonly message?: string;
|
|
960
|
+
/** JSON of the artifact's custom fields, minus attachments and location. */
|
|
961
|
+
readonly data?: string;
|
|
962
|
+
readonly locationFile?: string;
|
|
963
|
+
readonly locationLine?: number;
|
|
964
|
+
readonly locationColumn?: number;
|
|
965
|
+
readonly attachments?: ReadonlyArray<TestAttachmentInput>;
|
|
966
|
+
}
|
|
967
|
+
/** @public */
|
|
880
968
|
interface FileCoverageInput {
|
|
881
969
|
readonly fileId: number;
|
|
882
970
|
readonly statements: number;
|
|
@@ -1090,6 +1178,17 @@ declare const DataStore_base: Context.ServiceClass<DataStore, "vitest-agent/Data
|
|
|
1090
1178
|
readonly writeSuites: (moduleId: number, suites: ReadonlyArray<SuiteInput>) => Effect.Effect<ReadonlyArray<number>, DataStoreError>;
|
|
1091
1179
|
readonly writeTestCases: (moduleId: number, tests: ReadonlyArray<TestCaseInput>) => Effect.Effect<ReadonlyArray<number>, DataStoreError>;
|
|
1092
1180
|
readonly writeErrors: (runId: number, errors: ReadonlyArray<TestErrorInput>) => Effect.Effect<void, DataStoreError>;
|
|
1181
|
+
/**
|
|
1182
|
+
* Persist `context.annotate` notes and their attachment descriptors.
|
|
1183
|
+
* `runId` is carried for log correlation only -- `test_annotations`
|
|
1184
|
+
* rows are reachable through `test_cases`.
|
|
1185
|
+
*/
|
|
1186
|
+
readonly writeAnnotations: (runId: number, annotations: ReadonlyArray<TestAnnotationInput>) => Effect.Effect<void, DataStoreError>;
|
|
1187
|
+
/**
|
|
1188
|
+
* Persist `recordArtifact` payloads and their attachment
|
|
1189
|
+
* descriptors. `runId` is carried for log correlation only.
|
|
1190
|
+
*/
|
|
1191
|
+
readonly writeArtifacts: (runId: number, artifacts: ReadonlyArray<TestArtifactInput>) => Effect.Effect<void, DataStoreError>;
|
|
1093
1192
|
readonly writeCoverage: (runId: number, coverage: ReadonlyArray<FileCoverageInput>) => Effect.Effect<void, DataStoreError>;
|
|
1094
1193
|
readonly writeHistory: (project: string, fullName: string, modulePath: string, runId: number, timestamp: string, state: string, duration: number | null, flaky: boolean, retryCount: number, errorMessage: string | null) => Effect.Effect<void, DataStoreError>;
|
|
1095
1194
|
readonly writeBaselines: (baselines: CoverageBaselines) => Effect.Effect<void, DataStoreError>;
|
|
@@ -1515,6 +1614,45 @@ interface TagInventoryRow {
|
|
|
1515
1614
|
*/
|
|
1516
1615
|
readonly testCount: number;
|
|
1517
1616
|
}
|
|
1617
|
+
/** @public */
|
|
1618
|
+
interface TestArtifactQueryOptions {
|
|
1619
|
+
/** Disambiguates a fullName that exists in more than one module. */
|
|
1620
|
+
readonly modulePath?: string;
|
|
1621
|
+
}
|
|
1622
|
+
/** @public */
|
|
1623
|
+
interface PersistedAttachment {
|
|
1624
|
+
readonly contentType?: string;
|
|
1625
|
+
readonly path?: string;
|
|
1626
|
+
readonly body?: string;
|
|
1627
|
+
/** How to read `body`. Absent when nothing was stored inline. */
|
|
1628
|
+
readonly bodyEncoding?: "base64" | "utf-8";
|
|
1629
|
+
readonly byteSize: number | null;
|
|
1630
|
+
}
|
|
1631
|
+
/** @public */
|
|
1632
|
+
interface TestAnnotationRow {
|
|
1633
|
+
readonly id: number;
|
|
1634
|
+
readonly type: string;
|
|
1635
|
+
readonly message: string;
|
|
1636
|
+
readonly location?: {
|
|
1637
|
+
readonly file: string;
|
|
1638
|
+
readonly line: number;
|
|
1639
|
+
readonly column: number;
|
|
1640
|
+
};
|
|
1641
|
+
readonly attachments: ReadonlyArray<PersistedAttachment>;
|
|
1642
|
+
}
|
|
1643
|
+
/** @public */
|
|
1644
|
+
interface TestArtifactRow {
|
|
1645
|
+
readonly id: number;
|
|
1646
|
+
readonly type: string;
|
|
1647
|
+
readonly message: string | null;
|
|
1648
|
+
readonly data: string | null;
|
|
1649
|
+
readonly location?: {
|
|
1650
|
+
readonly file: string;
|
|
1651
|
+
readonly line: number;
|
|
1652
|
+
readonly column: number;
|
|
1653
|
+
};
|
|
1654
|
+
readonly attachments: ReadonlyArray<PersistedAttachment>;
|
|
1655
|
+
}
|
|
1518
1656
|
declare const DataReader_base: Context.ServiceClass<DataReader, "vitest-agent/DataReader", {
|
|
1519
1657
|
readonly getLatestRun: (project: string) => Effect.Effect<Option.Option<AgentReport>, DataStoreError>;
|
|
1520
1658
|
readonly getRunsByProject: () => Effect.Effect<ReadonlyArray<ProjectRunSummary>, DataStoreError>;
|
|
@@ -1527,6 +1665,10 @@ declare const DataReader_base: Context.ServiceClass<DataReader, "vitest-agent/Da
|
|
|
1527
1665
|
readonly getCoverage: (project: string) => Effect.Effect<Option.Option<CoverageReport>, DataStoreError>;
|
|
1528
1666
|
readonly getTestsForFile: (filePath: string) => Effect.Effect<ReadonlyArray<string>, DataStoreError>;
|
|
1529
1667
|
readonly getErrors: (project: string, errorName?: string) => Effect.Effect<ReadonlyArray<TestError>, DataStoreError>;
|
|
1668
|
+
/** Annotations recorded for a test in the project's latest run. */
|
|
1669
|
+
readonly getAnnotationsForTest: (project: string, fullName: string, options?: TestArtifactQueryOptions) => Effect.Effect<ReadonlyArray<TestAnnotationRow>, DataStoreError>;
|
|
1670
|
+
/** Artifacts recorded for a test in the project's latest run. */
|
|
1671
|
+
readonly getArtifactsForTest: (project: string, fullName: string, options?: TestArtifactQueryOptions) => Effect.Effect<ReadonlyArray<TestArtifactRow>, DataStoreError>;
|
|
1530
1672
|
readonly getNotes: (scope?: string, project?: string, testFullName?: string) => Effect.Effect<ReadonlyArray<NoteRow>, DataStoreError>;
|
|
1531
1673
|
readonly getNoteById: (id: number) => Effect.Effect<Option.Option<NoteRow>, DataStoreError>;
|
|
1532
1674
|
readonly searchNotes: (query: string) => Effect.Effect<ReadonlyArray<NoteRow>, DataStoreError>;
|
|
@@ -1677,6 +1819,27 @@ declare const DataReader_base: Context.ServiceClass<DataReader, "vitest-agent/Da
|
|
|
1677
1819
|
/** @public */
|
|
1678
1820
|
export declare class DataReader extends DataReader_base {}
|
|
1679
1821
|
//#endregion
|
|
1822
|
+
//#region src/migrations/index.d.ts
|
|
1823
|
+
/**
|
|
1824
|
+
* Every migration that must run against a per-project `data.db`, keyed by
|
|
1825
|
+
* migration id in application order.
|
|
1826
|
+
*
|
|
1827
|
+
* This is the single source of truth for the project database's migration
|
|
1828
|
+
* set: `ensureMigrated`, the sdk testing layer, `ReporterLive`, `McpLive`,
|
|
1829
|
+
* `CliLive` and `SidecarLive` all pass it straight to
|
|
1830
|
+
* `SqliteMigrator.fromRecord`, so adding a migration file and registering it
|
|
1831
|
+
* here is enough to reach every process that opens a project database.
|
|
1832
|
+
*
|
|
1833
|
+
* The session-map and discovery-registry databases are separate schemas with
|
|
1834
|
+
* their own migrations and are deliberately not listed here.
|
|
1835
|
+
*
|
|
1836
|
+
* @public
|
|
1837
|
+
*/
|
|
1838
|
+
export declare const PROJECT_MIGRATIONS: {
|
|
1839
|
+
readonly "0001_initial": import("effect/Effect").Effect<void, import("effect/unstable/sql/SqlError").SqlError, import("effect/unstable/sql/SqlClient").SqlClient>;
|
|
1840
|
+
readonly "0002_test_artifacts": import("effect/Effect").Effect<void, import("effect/unstable/sql/SqlError").SqlError, import("effect/unstable/sql/SqlClient").SqlClient>;
|
|
1841
|
+
};
|
|
1842
|
+
//#endregion
|
|
1680
1843
|
//#region src/testing/layers.d.ts
|
|
1681
1844
|
/** @public */
|
|
1682
1845
|
export declare function makeTestLayer(filename: string): Layer.Layer<DataReader | DataStore | import("effect/unstable/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | NodeServices.NodeServices, SqliteMigrator.MigrationError | import("effect/unstable/sql/SqlError").SqlError, never>;
|
|
@@ -1695,5 +1858,5 @@ export declare function flaky(filename: string): Layer.Layer<DataReader | DataSt
|
|
|
1695
1858
|
/** @public */
|
|
1696
1859
|
export declare function withTddTask(filename: string): Layer.Layer<DataReader | DataStore | import("effect/unstable/sql/SqlClient").SqlClient | import("@effect/sql-sqlite-node/SqliteClient").SqliteClient | import("@effect/platform-node/NodeServices").NodeServices, BehaviorNotFoundError | DataStoreError | GoalNotFoundError | IllegalStatusTransitionError | import("@effect/sql-sqlite-node/SqliteMigrator").MigrationError | import("effect/unstable/sql/SqlError").SqlError | TddTaskAlreadyEndedError | TddTaskNotFoundError, never>;
|
|
1697
1860
|
//#endregion
|
|
1698
|
-
export type { AcceptanceMetrics, ArtifactKind, ArtifactSuite, AssociateRunSessionInput, ChangeKind, CitedArtifact, CitedArtifactRow, ClassificationQueryOptions, CommitChangesEntry, CreateBehaviorInput, CreateGoalInput, CurrentTddPhase, EndTddTaskInput, FailureSignatureDetail, FailureSignatureWriteInput, FileCoverageInput, FlakyTest, HistoryQueryOptions, HypothesisDetail, HypothesisInput, IdempotentResponseInput, IllegalStatusTransitionEntity, ModuleInput, ModuleListEntry, NoteInput, NoteRow, PersistentFailure, Phase, ProjectRunSummary, RegisterAgentInput, ResolvedThresholds, RunChangedFile, RunInvocationMethod, SessionDetail, SessionInput, SettingsInput, SettingsListEntry, SettingsRow, StackFrameInput, SuiteInput, SuiteListEntry, TagInventoryRow, TddArtifactDetail, TddArtifactRow, TddPhaseDetail, TddTaskDetail, TddTaskEndOutcome, TddTaskInput, TddTaskSummary, TestCaseInput, TestError, TestErrorInput, TestListEntry, TestLookupOptions, TestRunInput, TurnInput, TurnSearchOptions, TurnSummary, UpdateBehaviorInput, UpdateGoalInput, ValidateHypothesisInput, WriteCommitInput, WriteRunChangedFilesInput, WriteTddArtifactInput, WriteTddPhaseInput, WriteTddPhaseOutput };
|
|
1861
|
+
export type { AcceptanceMetrics, ArtifactKind, ArtifactSuite, AssociateRunSessionInput, ChangeKind, CitedArtifact, CitedArtifactRow, ClassificationQueryOptions, CommitChangesEntry, CreateBehaviorInput, CreateGoalInput, CurrentTddPhase, EndTddTaskInput, FailureSignatureDetail, FailureSignatureWriteInput, FileCoverageInput, FlakyTest, HistoryQueryOptions, HypothesisDetail, HypothesisInput, IdempotentResponseInput, IllegalStatusTransitionEntity, ModuleInput, ModuleListEntry, NoteInput, NoteRow, PersistedAttachment, PersistentFailure, Phase, ProjectRunSummary, RegisterAgentInput, ResolvedThresholds, RunChangedFile, RunInvocationMethod, SessionDetail, SessionInput, SettingsInput, SettingsListEntry, SettingsRow, StackFrameInput, SuiteInput, SuiteListEntry, TagInventoryRow, TddArtifactDetail, TddArtifactRow, TddPhaseDetail, TddTaskDetail, TddTaskEndOutcome, TddTaskInput, TddTaskSummary, TestAnnotationInput, TestAnnotationRow, TestArtifactInput, TestArtifactQueryOptions, TestArtifactRow, TestAttachmentInput, TestCaseInput, TestError, TestErrorInput, TestListEntry, TestLookupOptions, TestRunInput, TurnInput, TurnSearchOptions, TurnSummary, UpdateBehaviorInput, UpdateGoalInput, ValidateHypothesisInput, WriteCommitInput, WriteRunChangedFilesInput, WriteTddArtifactInput, WriteTddPhaseInput, WriteTddPhaseOutput };
|
|
1699
1862
|
//# sourceMappingURL=testing.d.ts.map
|
package/testing.js
CHANGED
|
@@ -5,6 +5,7 @@ import { DataReader } from "./services/DataReader.js";
|
|
|
5
5
|
import { AgentId, ChatId } from "./schemas/Identity.js";
|
|
6
6
|
import { Agent, IdempotencyHit } from "./schemas/Agent.js";
|
|
7
7
|
import { DataStore } from "./services/DataStore.js";
|
|
8
|
+
import { PROJECT_MIGRATIONS } from "./migrations/index.js";
|
|
8
9
|
import { CoverageReport, FileCoverageReport } from "./schemas/Coverage.js";
|
|
9
10
|
import { AgentReport } from "./schemas/AgentReport.js";
|
|
10
11
|
import { CoverageBaselines } from "./schemas/Baselines.js";
|
|
@@ -26,7 +27,7 @@ function singlePassingRun(filename) {
|
|
|
26
27
|
const seed = Effect.gen(function* () {
|
|
27
28
|
const store = yield* DataStore;
|
|
28
29
|
yield* store.writeSettings("hash-preset-spr", {
|
|
29
|
-
vitestVersion: "
|
|
30
|
+
vitestVersion: "5.0.0",
|
|
30
31
|
pool: "forks"
|
|
31
32
|
}, {});
|
|
32
33
|
const runId = yield* store.writeRun({
|
|
@@ -80,7 +81,7 @@ function withFailures(filename) {
|
|
|
80
81
|
const seed = Effect.gen(function* () {
|
|
81
82
|
const store = yield* DataStore;
|
|
82
83
|
yield* store.writeSettings("hash-preset-wf", {
|
|
83
|
-
vitestVersion: "
|
|
84
|
+
vitestVersion: "5.0.0",
|
|
84
85
|
pool: "forks"
|
|
85
86
|
}, {});
|
|
86
87
|
const runId = yield* store.writeRun({
|
|
@@ -140,7 +141,7 @@ function flaky(filename) {
|
|
|
140
141
|
const seed = Effect.gen(function* () {
|
|
141
142
|
const store = yield* DataStore;
|
|
142
143
|
yield* store.writeSettings("hash-preset-flaky", {
|
|
143
|
-
vitestVersion: "
|
|
144
|
+
vitestVersion: "5.0.0",
|
|
144
145
|
pool: "forks"
|
|
145
146
|
}, {});
|
|
146
147
|
const runId1 = yield* store.writeRun({
|
|
@@ -250,4 +251,4 @@ function withTddTask(filename) {
|
|
|
250
251
|
}
|
|
251
252
|
|
|
252
253
|
//#endregion
|
|
253
|
-
export { Agent, AgentId, AgentNotFoundError, AgentReport, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorStatus, CacheManifest, ChatId, CoverageBaselines, CoverageReport, DataReader, DataStore, DataStoreError, DataStoreTestLayer, FileCoverageReport, GoalDetail, GoalNotFoundError, GoalRow, GoalStatus, HistoryRecord, IdempotencyHit, IllegalStatusTransitionError, RegistrationConflictError, TddTaskAlreadyEndedError, TddTaskNotFoundError, TrendEntry, TrendRecord, empty, flaky, makeTestLayer, singlePassingRun, withFailures, withTddTask };
|
|
254
|
+
export { Agent, AgentId, AgentNotFoundError, AgentReport, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorStatus, CacheManifest, ChatId, CoverageBaselines, CoverageReport, DataReader, DataStore, DataStoreError, DataStoreTestLayer, FileCoverageReport, GoalDetail, GoalNotFoundError, GoalRow, GoalStatus, HistoryRecord, IdempotencyHit, IllegalStatusTransitionError, PROJECT_MIGRATIONS, RegistrationConflictError, TddTaskAlreadyEndedError, TddTaskNotFoundError, TrendEntry, TrendRecord, empty, flaky, makeTestLayer, singlePassingRun, withFailures, withTddTask };
|
package/utils/ensure-migrated.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LoggerLive } from "../layers/LoggerLive.js";
|
|
2
|
-
import
|
|
2
|
+
import { PROJECT_MIGRATIONS } from "../migrations/index.js";
|
|
3
3
|
import { Effect, Layer } from "effect";
|
|
4
4
|
import { SqlClient } from "effect/unstable/sql/SqlClient";
|
|
5
5
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
@@ -30,7 +30,7 @@ function ensureMigrated(dbPath, logLevel, logFile) {
|
|
|
30
30
|
if (cached) return cached;
|
|
31
31
|
const SqliteLayer = layer({ filename: dbPath });
|
|
32
32
|
const PlatformLayer = NodeServices.layer;
|
|
33
|
-
const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord(
|
|
33
|
+
const MigratorLayer = SqliteMigrator.layer({ loader: SqliteMigrator.fromRecord(PROJECT_MIGRATIONS) }).pipe(Layer.provide(Layer.merge(SqliteLayer, PlatformLayer)));
|
|
34
34
|
const program = Effect.gen(function* () {
|
|
35
35
|
yield* SqlClient;
|
|
36
36
|
}).pipe(Effect.provide(MigratorLayer), Effect.provide(Layer.merge(SqliteLayer, PlatformLayer)), Effect.provide(LoggerLive(logLevel, logFile)));
|
package/utils/test-location.js
CHANGED
|
@@ -14,6 +14,16 @@ const TEST_HELPER_DIRS = [
|
|
|
14
14
|
/** Glob suffix matching every discoverable test file. @public */
|
|
15
15
|
const TEST_FILE_GLOB_SUFFIX = "*.{test,spec}.{ts,tsx,js,jsx}";
|
|
16
16
|
/**
|
|
17
|
+
* Glob suffix matching every Bats shell test file. Bats tests are run by
|
|
18
|
+
* `bats`, not Vitest — a package whose `__test__/` directory holds only
|
|
19
|
+
* `.bats` files (plus any of {@link TEST_HELPER_DIRS}) is a fully supported,
|
|
20
|
+
* intentional layout, not an orphaned test directory. Paired with
|
|
21
|
+
* {@link TEST_FILE_GLOB_SUFFIX} by `@vitest-agent/plugin`'s
|
|
22
|
+
* `isTestShapedPackage` to decide whether a package without a discoverable
|
|
23
|
+
* Vitest project still warrants a warning. @public
|
|
24
|
+
*/
|
|
25
|
+
const BATS_FILE_GLOB_SUFFIX = "*.bats";
|
|
26
|
+
/**
|
|
17
27
|
* Directory names discovery never walks into, and therefore never collects
|
|
18
28
|
* tests from. Keep in step with {@link TEST_FILE_GLOB_SUFFIX}'s extension set:
|
|
19
29
|
* this is the directory half of the same "what can Vitest reach" question.
|
|
@@ -114,4 +124,4 @@ function classifyTestPath(workspaces, filePath) {
|
|
|
114
124
|
}
|
|
115
125
|
|
|
116
126
|
//#endregion
|
|
117
|
-
export { NON_DISCOVERABLE_DIRS, SRC_DIR, TEST_DIR, TEST_FILE_GLOB_SUFFIX, TEST_HELPER_DIRS, classifyTestPath, findOwningWorkspace, isTestFileName };
|
|
127
|
+
export { BATS_FILE_GLOB_SUFFIX, NON_DISCOVERABLE_DIRS, SRC_DIR, TEST_DIR, TEST_FILE_GLOB_SUFFIX, TEST_HELPER_DIRS, classifyTestPath, findOwningWorkspace, isTestFileName };
|
|
@@ -24,9 +24,15 @@ function checkBooleanShortcut(key, path, errors) {
|
|
|
24
24
|
message: `Coverage target at "${path}" cannot be true. The "true" shorthand is only valid at key "100" (meaning 100% across all metrics).`
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Checks all values inside a nested per-metric object (glob-pattern entry).
|
|
29
|
+
* `perFile` is a legal key inside a glob entry under Vitest 5 — a glob entry
|
|
30
|
+
* no longer inherits the top-level setting — so it is skipped here rather
|
|
31
|
+
* than run through the boolean-shortcut check.
|
|
32
|
+
*/
|
|
28
33
|
function checkNestedMetrics(nested, prefix, errors) {
|
|
29
34
|
for (const [metricKey, metricValue] of Object.entries(nested)) {
|
|
35
|
+
if (metricKey === "perFile") continue;
|
|
30
36
|
const path = `${prefix}.${metricKey}`;
|
|
31
37
|
if (typeof metricValue === "number") checkNumericValue(metricValue, path, errors);
|
|
32
38
|
else if (metricValue === true) checkBooleanShortcut(metricKey, path, errors);
|
|
@@ -41,8 +47,10 @@ function checkNestedMetrics(nested, prefix, errors) {
|
|
|
41
47
|
* OR a literal `true` appears at any key other than `"100"`. The
|
|
42
48
|
* offending `path` is included (e.g. `"lines"`, `"src/**.ts.lines"`,
|
|
43
49
|
* or `"statements"` when misused as a boolean shortcut).
|
|
44
|
-
* - `PERFILE_ON_TARGETS` —
|
|
45
|
-
*
|
|
50
|
+
* - `PERFILE_ON_TARGETS` — a top-level `perFile` key appears in
|
|
51
|
+
* coverageTargets; the top-level setting belongs on
|
|
52
|
+
* `coverage.thresholds.perFile`. A `perFile` inside a glob-pattern entry
|
|
53
|
+
* is legal and is not reported.
|
|
46
54
|
*
|
|
47
55
|
* @param input - The raw value passed as coverageTargets.
|
|
48
56
|
* @returns A result object with errors, warnings, and info arrays.
|
|
@@ -62,7 +70,7 @@ function validateCoverageTargetsShape(input) {
|
|
|
62
70
|
warnings.push({
|
|
63
71
|
code: "PERFILE_ON_TARGETS",
|
|
64
72
|
path: key,
|
|
65
|
-
message: "
|
|
73
|
+
message: "A top-level \"perFile\" key is not valid inside coverageTargets. Set coverage.thresholds.perFile instead, or move it inside a glob-pattern entry — under Vitest 5 a glob-pattern entry carries its own perFile and no longer inherits the top-level one."
|
|
66
74
|
});
|
|
67
75
|
continue;
|
|
68
76
|
}
|