@ttt-productions/repo-guards 0.1.29 → 0.1.30
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/modules/repo/guards.d.ts +2 -0
- package/dist/modules/repo/guards.d.ts.map +1 -1
- package/dist/modules/repo/guards.js +2 -0
- package/dist/modules/repo/guards.js.map +1 -1
- package/dist/modules/repo/hand-built-reads.d.ts +9 -0
- package/dist/modules/repo/hand-built-reads.d.ts.map +1 -0
- package/dist/modules/repo/hand-built-reads.js +141 -0
- package/dist/modules/repo/hand-built-reads.js.map +1 -0
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ import { type DependencyOverrideFacts } from './dependency-overrides.js';
|
|
|
6
6
|
import { type DocumentDriftFacts } from './document-drift.js';
|
|
7
7
|
import { type E2eActionFacts } from './e2e-actions.js';
|
|
8
8
|
import { type EnvPublicValuesFacts } from './env-public-values.js';
|
|
9
|
+
import { type HandBuiltReadFacts } from './hand-built-reads.js';
|
|
9
10
|
import { type InstalledPackagesAgnosticFacts } from './installed-packages-agnostic.js';
|
|
10
11
|
import { type LineEndingFacts } from './line-endings.js';
|
|
11
12
|
import { type LocalOnlyVariablesFacts } from './local-only-variables.js';
|
|
@@ -33,6 +34,7 @@ export type RepoGuardFacts = {
|
|
|
33
34
|
swallowedRejections: SwallowedRejectionFacts;
|
|
34
35
|
sharedFakes: SharedFakeFacts;
|
|
35
36
|
typedMocks: TypedMockFacts;
|
|
37
|
+
handBuiltReads: HandBuiltReadFacts;
|
|
36
38
|
testTimeouts: TestTimeoutFacts;
|
|
37
39
|
localOnlyVariables: LocalOnlyVariablesFacts;
|
|
38
40
|
workerConfigIsolation: WorkerConfigFacts | Absent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../../src/modules/repo/guards.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../../src/modules/repo/guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { dependencyOverrideGuard } from './dependency-overrides.js';
|
|
|
5
5
|
import { documentDriftGuard } from './document-drift.js';
|
|
6
6
|
import { retryLoopActionGuard, swallowedActionGuard } from './e2e-actions.js';
|
|
7
7
|
import { envPublicValuesGuard } from './env-public-values.js';
|
|
8
|
+
import { handBuiltReadGuard } from './hand-built-reads.js';
|
|
8
9
|
import { installedPackagesAgnosticGuard, } from './installed-packages-agnostic.js';
|
|
9
10
|
import { lineEndingGuard } from './line-endings.js';
|
|
10
11
|
import { localOnlyVariablesGuard } from './local-only-variables.js';
|
|
@@ -32,6 +33,7 @@ export const REPO_GUARDS = Object.freeze([
|
|
|
32
33
|
swallowedRejectionGuard,
|
|
33
34
|
sharedFakeGuard,
|
|
34
35
|
typedMockGuard,
|
|
36
|
+
handBuiltReadGuard,
|
|
35
37
|
testTimeoutGuard,
|
|
36
38
|
localOnlyVariablesGuard,
|
|
37
39
|
workerConfigGuard,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../src/modules/repo/guards.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,GAKnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAsB,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAgC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAA2B,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAuB,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAA6B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACL,8BAA8B,GAE/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAwB,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAgC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAA2B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAA2B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAwB,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAuB,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAgC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EAAE,uBAAuB,EAAgC,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAuB,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAA4B,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,sBAAsB,EAA+B,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAA+B,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAA0B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../src/modules/repo/guards.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,GAKnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAsB,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAgC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAA2B,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAuB,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAA6B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAA2B,MAAM,uBAAuB,CAAC;AACpF,OAAO,EACL,8BAA8B,GAE/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAwB,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAgC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAA2B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAA2B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAwB,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAuB,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAgC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EAAE,uBAAuB,EAAgC,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAuB,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAA4B,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,sBAAsB,EAA+B,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAA+B,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAA0B,MAAM,oBAAoB,CAAC;AAgC/E,MAAM,CAAC,MAAM,WAAW,GAAiD,MAAM,CAAC,MAAM,CAAC;IACrF,cAAc;IACd,eAAe;IACf,gBAAgB;IAChB,oBAAoB;IACpB,oBAAoB;IACpB,sBAAsB;IACtB,mBAAmB;IACnB,uBAAuB;IACvB,uBAAuB;IACvB,eAAe;IACf,cAAc;IACd,kBAAkB;IAClB,gBAAgB;IAChB,uBAAuB;IACvB,iBAAiB;IACjB,sBAAsB;IACtB,kBAAkB;IAClB,kBAAkB;IAClB,eAAe;IACf,sBAAsB;IACtB,kBAAkB;IAClB,kBAAkB;IAClB,kBAAkB;IAClB,oBAAoB;IACpB,8BAA8B;IAC9B,aAAa;IACb,uBAAuB;CACwB,CAAC,CAAC","sourcesContent":["import type { Absent, GenericGuardDefinition } from '../../node/suite/config.js';\nimport {\n entryPointGuard,\n isolatedRootsGuard,\n noOutsideCheckoutGuard,\n tsconfigAliasGuard,\n type EntryPointFacts,\n type IsolatedRootsFacts,\n type NoOutsideCheckoutFacts,\n type TsconfigAliasFacts,\n} from './cross-root.js';\nimport { blanketCastGuard, type BlanketCastFacts } from './blanket-casts.js';\nimport { ciParityGuard, type CiParityFacts } from './ci-parity.js';\nimport { dependencyOverrideGuard, type DependencyOverrideFacts } from './dependency-overrides.js';\nimport { documentDriftGuard, type DocumentDriftFacts } from './document-drift.js';\nimport { retryLoopActionGuard, swallowedActionGuard, type E2eActionFacts } from './e2e-actions.js';\nimport { envPublicValuesGuard, type EnvPublicValuesFacts } from './env-public-values.js';\nimport { handBuiltReadGuard, type HandBuiltReadFacts } from './hand-built-reads.js';\nimport {\n installedPackagesAgnosticGuard,\n type InstalledPackagesAgnosticFacts,\n} from './installed-packages-agnostic.js';\nimport { lineEndingGuard, type LineEndingFacts } from './line-endings.js';\nimport { localOnlyVariablesGuard, type LocalOnlyVariablesFacts } from './local-only-variables.js';\nimport { projectScriptGuard, type ProjectScriptFacts } from './project-scripts.js';\nimport { secretBindingGuard, type SecretBindingFacts } from './secret-bindings.js';\nimport { sharedFakeGuard, type SharedFakeFacts } from './shared-fakes.js';\nimport { shellSafeGuard, type ShellSafeFacts } from './shell-safe.js';\nimport { swallowedRejectionGuard, type SwallowedRejectionFacts } from './swallowed-rejections.js';\nimport { testCaseModuleLoadGuard, type TestCaseModuleLoadFacts } from './test-case-module-loads.js';\nimport { testTimeoutGuard, type TestTimeoutFacts } from './test-timeouts.js';\nimport { typedMockGuard, type TypedMockFacts } from './typed-mocks.js';\nimport { testSourceRootGuard, type TestSourceRootFacts } from './test-source-root.js';\nimport { walkerReadFailureGuard, type WalkerReadFailureFacts } from './walker-read-failure.js';\nimport { workerBoundedBodyGuard, type WorkerBoundedBodyFacts } from './worker-bounded-body.js';\nimport { workerConfigGuard, type WorkerConfigFacts } from './worker-config.js';\n\nexport type RepoGuardFacts = {\n shellSafeChildProcesses: ShellSafeFacts;\n lineEndings: LineEndingFacts;\n blanketCasts: BlanketCastFacts;\n retryLoopActions: E2eActionFacts | Absent;\n swallowedE2eActions: E2eActionFacts | Absent;\n walkerReadFailure: WalkerReadFailureFacts;\n testSourceRoot: TestSourceRootFacts | Absent;\n testCaseModuleLoads: TestCaseModuleLoadFacts;\n swallowedRejections: SwallowedRejectionFacts;\n sharedFakes: SharedFakeFacts;\n typedMocks: TypedMockFacts;\n handBuiltReads: HandBuiltReadFacts;\n testTimeouts: TestTimeoutFacts;\n localOnlyVariables: LocalOnlyVariablesFacts;\n workerConfigIsolation: WorkerConfigFacts | Absent;\n workerBoundedBody: WorkerBoundedBodyFacts | Absent;\n isolatedRoots: IsolatedRootsFacts;\n tsconfigAliasesInRoot: TsconfigAliasFacts;\n packageEntryPoints: EntryPointFacts;\n noOutsideCheckout: NoOutsideCheckoutFacts;\n projectScripts: ProjectScriptFacts | Absent;\n secretBindings: SecretBindingFacts | Absent;\n documentDrift: DocumentDriftFacts | Absent;\n envPublicValues: EnvPublicValuesFacts | Absent;\n installedPackagesAgnostic: InstalledPackagesAgnosticFacts;\n ciParity: CiParityFacts | Absent;\n dependencyOverrides: DependencyOverrideFacts | Absent;\n};\n\nexport const REPO_GUARDS: ReadonlyArray<GenericGuardDefinition<never>> = Object.freeze([\n shellSafeGuard,\n lineEndingGuard,\n blanketCastGuard,\n retryLoopActionGuard,\n swallowedActionGuard,\n walkerReadFailureGuard,\n testSourceRootGuard,\n testCaseModuleLoadGuard,\n swallowedRejectionGuard,\n sharedFakeGuard,\n typedMockGuard,\n handBuiltReadGuard,\n testTimeoutGuard,\n localOnlyVariablesGuard,\n workerConfigGuard,\n workerBoundedBodyGuard,\n isolatedRootsGuard,\n tsconfigAliasGuard,\n entryPointGuard,\n noOutsideCheckoutGuard,\n projectScriptGuard,\n secretBindingGuard,\n documentDriftGuard,\n envPublicValuesGuard,\n installedPackagesAgnosticGuard,\n ciParityGuard,\n dependencyOverrideGuard,\n] as ReadonlyArray<GenericGuardDefinition<never>>);\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GenericGuardDefinition } from '../../node/suite/config.js';
|
|
2
|
+
import { type FileView } from '../../reader/view.js';
|
|
3
|
+
import { type AnchoredEntry, type Occurrence } from '../../support/anchored-review.js';
|
|
4
|
+
export declare function handBuiltReads(source: FileView | string): Occurrence[];
|
|
5
|
+
export interface HandBuiltReadFacts {
|
|
6
|
+
reviewed: readonly AnchoredEntry[];
|
|
7
|
+
}
|
|
8
|
+
export declare const handBuiltReadGuard: GenericGuardDefinition<HandBuiltReadFacts>;
|
|
9
|
+
//# sourceMappingURL=hand-built-reads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hand-built-reads.d.ts","sourceRoot":"","sources":["../../../src/modules/repo/hand-built-reads.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEzE,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAwC1C,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,EAAE,CA6EtE;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CACpC;AAED,eAAO,MAAM,kBAAkB,EAAE,sBAAsB,CAAC,kBAAkB,CA+BzE,CAAC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { viewOfText } from '../../reader/view.js';
|
|
3
|
+
import { forEachNode, unwrap } from '../../support/ast.js';
|
|
4
|
+
import { anchoredFindings, anchoredProblems, } from '../../support/anchored-review.js';
|
|
5
|
+
import { objectProblem } from '../../support/facts.js';
|
|
6
|
+
import { REPOSITORY_GUARD_TIMEOUT_MS } from '../../support/timeouts.js';
|
|
7
|
+
const SCOPE = {
|
|
8
|
+
roots: ['app', 'functions', 'scripts', 'workers'],
|
|
9
|
+
kinds: ['code'],
|
|
10
|
+
tests: 'only',
|
|
11
|
+
optionalRoots: ['functions', 'scripts', 'workers'],
|
|
12
|
+
};
|
|
13
|
+
const OBSERVERS = new Set(['QueryObserver', 'InfiniteQueryObserver']);
|
|
14
|
+
const propertyNameOf = (name) => ts.isIdentifier(name) || ts.isStringLiteralLike(name) ? name.text : null;
|
|
15
|
+
const calledMember = (node, member) => {
|
|
16
|
+
const inner = unwrap(node);
|
|
17
|
+
return ts.isCallExpression(inner) &&
|
|
18
|
+
ts.isPropertyAccessExpression(inner.expression) &&
|
|
19
|
+
inner.expression.name.text === member
|
|
20
|
+
? inner
|
|
21
|
+
: null;
|
|
22
|
+
};
|
|
23
|
+
const isRetryStateType = (type) => !!type &&
|
|
24
|
+
ts.isTypeReferenceNode(type) &&
|
|
25
|
+
ts.isIdentifier(type.typeName) &&
|
|
26
|
+
type.typeName.text === 'ReadRetryState';
|
|
27
|
+
const constructedObserver = (node) => {
|
|
28
|
+
const inner = unwrap(node);
|
|
29
|
+
return ts.isNewExpression(inner) &&
|
|
30
|
+
ts.isIdentifier(inner.expression) &&
|
|
31
|
+
OBSERVERS.has(inner.expression.text)
|
|
32
|
+
? inner.expression.text
|
|
33
|
+
: null;
|
|
34
|
+
};
|
|
35
|
+
export function handBuiltReads(source) {
|
|
36
|
+
const file = typeof source === 'string' ? viewOfText('sample.test.ts', source) : source;
|
|
37
|
+
const sf = file.sourceFile;
|
|
38
|
+
const hits = [];
|
|
39
|
+
const hit = (node, detail) => hits.push({ start: node.getStart(sf), end: node.getEnd(), detail });
|
|
40
|
+
const declaredIn = (scope, name) => {
|
|
41
|
+
const statements = ts.isSourceFile(scope) || ts.isBlock(scope) ? scope.statements : [];
|
|
42
|
+
for (const statement of statements) {
|
|
43
|
+
if (!ts.isVariableStatement(statement))
|
|
44
|
+
continue;
|
|
45
|
+
for (const declaration of statement.declarationList.declarations)
|
|
46
|
+
if (ts.isIdentifier(declaration.name) && declaration.name.text === name)
|
|
47
|
+
return declaration;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
};
|
|
51
|
+
const declarationOf = (identifier) => {
|
|
52
|
+
for (let scope = identifier.parent; scope; scope = scope.parent) {
|
|
53
|
+
const declaration = declaredIn(scope, identifier.text);
|
|
54
|
+
if (declaration)
|
|
55
|
+
return declaration;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
};
|
|
59
|
+
const subscribed = new Set();
|
|
60
|
+
forEachNode(sf, (node) => {
|
|
61
|
+
if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression))
|
|
62
|
+
return;
|
|
63
|
+
if (node.expression.name.text !== 'subscribe')
|
|
64
|
+
return;
|
|
65
|
+
const target = unwrap(node.expression.expression);
|
|
66
|
+
const declaration = ts.isIdentifier(target) ? declarationOf(target) : null;
|
|
67
|
+
if (declaration)
|
|
68
|
+
subscribed.add(declaration);
|
|
69
|
+
});
|
|
70
|
+
const observerOf = (node) => {
|
|
71
|
+
const inner = unwrap(node);
|
|
72
|
+
if (!ts.isIdentifier(inner)) {
|
|
73
|
+
const kind = constructedObserver(inner);
|
|
74
|
+
return kind ? { kind, site: inner } : null;
|
|
75
|
+
}
|
|
76
|
+
const declaration = declarationOf(inner);
|
|
77
|
+
if (!declaration?.initializer || subscribed.has(declaration))
|
|
78
|
+
return null;
|
|
79
|
+
const kind = constructedObserver(declaration.initializer);
|
|
80
|
+
return kind ? { kind, site: declaration.initializer } : null;
|
|
81
|
+
};
|
|
82
|
+
const reported = new Set();
|
|
83
|
+
forEachNode(sf, (node) => {
|
|
84
|
+
if (ts.isPropertyAssignment(node) &&
|
|
85
|
+
propertyNameOf(node.name) === 'retryState' &&
|
|
86
|
+
ts.isObjectLiteralExpression(unwrap(node.initializer)))
|
|
87
|
+
hit(node, 'a read’s retryState is written as a literal');
|
|
88
|
+
else if (ts.isVariableDeclaration(node) &&
|
|
89
|
+
isRetryStateType(node.type) &&
|
|
90
|
+
node.initializer &&
|
|
91
|
+
ts.isObjectLiteralExpression(unwrap(node.initializer)))
|
|
92
|
+
hit(node, 'a ReadRetryState is written as a literal');
|
|
93
|
+
else if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
94
|
+
if (node.expression.name.text === 'getCurrentResult') {
|
|
95
|
+
const observer = observerOf(node.expression.expression);
|
|
96
|
+
if (observer && !reported.has(observer.site)) {
|
|
97
|
+
reported.add(observer.site);
|
|
98
|
+
hit(observer.site, `a test reads a result off an observer it built itself (${observer.kind})`);
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (node.expression.name.text !== 'setState')
|
|
103
|
+
return;
|
|
104
|
+
const build = calledMember(node.expression.expression, 'build');
|
|
105
|
+
if (build && ts.isPropertyAccessExpression(build.expression)) {
|
|
106
|
+
const cache = calledMember(build.expression.expression, 'getQueryCache');
|
|
107
|
+
if (cache)
|
|
108
|
+
hit(node, 'a test seeds a query’s state into the cache by hand');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return hits;
|
|
113
|
+
}
|
|
114
|
+
export const handBuiltReadGuard = {
|
|
115
|
+
id: 'handBuiltReads',
|
|
116
|
+
absentWhen: false,
|
|
117
|
+
factProblems(facts) {
|
|
118
|
+
const problems = [];
|
|
119
|
+
if (!objectProblem(facts, 'the facts', problems))
|
|
120
|
+
return problems;
|
|
121
|
+
anchoredProblems(facts.reviewed, 'reviewed', problems);
|
|
122
|
+
return problems;
|
|
123
|
+
},
|
|
124
|
+
build(facts) {
|
|
125
|
+
return [
|
|
126
|
+
{
|
|
127
|
+
title: 'no test builds a read’s state by hand',
|
|
128
|
+
description: 'A test takes a read’s state from the read builders or from the real hook, never from a hand-written ' +
|
|
129
|
+
'`retryState` or `ReadRetryState` literal, a result read off a `QueryObserver` / `InfiniteQueryObserver` ' +
|
|
130
|
+
'it constructed itself, or a query cache seeded with `getQueryCache().build(…).setState(…)`. Each of those type-checks ' +
|
|
131
|
+
'while combining flags no real read reaches, so a case passes on a state the product never sees. An ' +
|
|
132
|
+
'observer the test subscribes, watching a real query run, is not a hand-built state and passes. A ' +
|
|
133
|
+
'test whose subject is that shape itself is a reviewed entry whose anchor names the one construct, ' +
|
|
134
|
+
'with its why; an entry that no longer matches one is stale.',
|
|
135
|
+
timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,
|
|
136
|
+
run: (context) => anchoredFindings(context.files(SCOPE).map((file) => ({ file, hits: handBuiltReads(file) })), facts.reviewed, 'its anchor names no hand-built read'),
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=hand-built-reads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hand-built-reads.js","sourceRoot":"","sources":["../../../src/modules/repo/hand-built-reads.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { Scope } from '../../node/reader.js';\nimport { viewOfText, type FileView } from '../../reader/view.js';\nimport { forEachNode, unwrap } from '../../support/ast.js';\nimport {\n anchoredFindings,\n anchoredProblems,\n type AnchoredEntry,\n type Occurrence,\n} from '../../support/anchored-review.js';\nimport { objectProblem } from '../../support/facts.js';\nimport { REPOSITORY_GUARD_TIMEOUT_MS } from '../../support/timeouts.js';\n\nconst SCOPE: Scope = {\n roots: ['app', 'functions', 'scripts', 'workers'],\n kinds: ['code'],\n tests: 'only',\n optionalRoots: ['functions', 'scripts', 'workers'],\n};\n\nconst OBSERVERS = new Set(['QueryObserver', 'InfiniteQueryObserver']);\n\nconst propertyNameOf = (name: ts.PropertyName): string | null =>\n ts.isIdentifier(name) || ts.isStringLiteralLike(name) ? name.text : null;\n\nconst calledMember = (node: ts.Expression, member: string): ts.CallExpression | null => {\n const inner = unwrap(node);\n return ts.isCallExpression(inner) &&\n ts.isPropertyAccessExpression(inner.expression) &&\n inner.expression.name.text === member\n ? inner\n : null;\n};\n\nconst isRetryStateType = (type: ts.TypeNode | undefined): boolean =>\n !!type &&\n ts.isTypeReferenceNode(type) &&\n ts.isIdentifier(type.typeName) &&\n type.typeName.text === 'ReadRetryState';\n\nconst constructedObserver = (node: ts.Expression): string | null => {\n const inner = unwrap(node);\n return ts.isNewExpression(inner) &&\n ts.isIdentifier(inner.expression) &&\n OBSERVERS.has(inner.expression.text)\n ? inner.expression.text\n : null;\n};\n\nexport function handBuiltReads(source: FileView | string): Occurrence[] {\n const file = typeof source === 'string' ? viewOfText('sample.test.ts', source) : source;\n const sf = file.sourceFile;\n const hits: Occurrence[] = [];\n const hit = (node: ts.Node, detail: string) =>\n hits.push({ start: node.getStart(sf), end: node.getEnd(), detail });\n const declaredIn = (scope: ts.Node, name: string): ts.VariableDeclaration | null => {\n const statements = ts.isSourceFile(scope) || ts.isBlock(scope) ? scope.statements : [];\n for (const statement of statements) {\n if (!ts.isVariableStatement(statement)) continue;\n for (const declaration of statement.declarationList.declarations)\n if (ts.isIdentifier(declaration.name) && declaration.name.text === name) return declaration;\n }\n return null;\n };\n const declarationOf = (identifier: ts.Identifier): ts.VariableDeclaration | null => {\n for (let scope: ts.Node | undefined = identifier.parent; scope; scope = scope.parent) {\n const declaration = declaredIn(scope, identifier.text);\n if (declaration) return declaration;\n }\n return null;\n };\n const subscribed = new Set<ts.VariableDeclaration>();\n forEachNode(sf, (node) => {\n if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression)) return;\n if (node.expression.name.text !== 'subscribe') return;\n const target = unwrap(node.expression.expression);\n const declaration = ts.isIdentifier(target) ? declarationOf(target) : null;\n if (declaration) subscribed.add(declaration);\n });\n const observerOf = (node: ts.Expression): { kind: string; site: ts.Node } | null => {\n const inner = unwrap(node);\n if (!ts.isIdentifier(inner)) {\n const kind = constructedObserver(inner);\n return kind ? { kind, site: inner } : null;\n }\n const declaration = declarationOf(inner);\n if (!declaration?.initializer || subscribed.has(declaration)) return null;\n const kind = constructedObserver(declaration.initializer);\n return kind ? { kind, site: declaration.initializer } : null;\n };\n const reported = new Set<ts.Node>();\n forEachNode(sf, (node) => {\n if (\n ts.isPropertyAssignment(node) &&\n propertyNameOf(node.name) === 'retryState' &&\n ts.isObjectLiteralExpression(unwrap(node.initializer))\n )\n hit(node, 'a read’s retryState is written as a literal');\n else if (\n ts.isVariableDeclaration(node) &&\n isRetryStateType(node.type) &&\n node.initializer &&\n ts.isObjectLiteralExpression(unwrap(node.initializer))\n )\n hit(node, 'a ReadRetryState is written as a literal');\n else if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {\n if (node.expression.name.text === 'getCurrentResult') {\n const observer = observerOf(node.expression.expression);\n if (observer && !reported.has(observer.site)) {\n reported.add(observer.site);\n hit(\n observer.site,\n `a test reads a result off an observer it built itself (${observer.kind})`,\n );\n }\n return;\n }\n if (node.expression.name.text !== 'setState') return;\n const build = calledMember(node.expression.expression, 'build');\n if (build && ts.isPropertyAccessExpression(build.expression)) {\n const cache = calledMember(build.expression.expression, 'getQueryCache');\n if (cache) hit(node, 'a test seeds a query’s state into the cache by hand');\n }\n }\n });\n return hits;\n}\n\nexport interface HandBuiltReadFacts {\n reviewed: readonly AnchoredEntry[];\n}\n\nexport const handBuiltReadGuard: GenericGuardDefinition<HandBuiltReadFacts> = {\n id: 'handBuiltReads',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n if (!objectProblem(facts, 'the facts', problems)) return problems;\n anchoredProblems(facts.reviewed, 'reviewed', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no test builds a read’s state by hand',\n description:\n 'A test takes a read’s state from the read builders or from the real hook, never from a hand-written ' +\n '`retryState` or `ReadRetryState` literal, a result read off a `QueryObserver` / `InfiniteQueryObserver` ' +\n 'it constructed itself, or a query cache seeded with `getQueryCache().build(…).setState(…)`. Each of those type-checks ' +\n 'while combining flags no real read reaches, so a case passes on a state the product never sees. An ' +\n 'observer the test subscribes, watching a real query run, is not a hand-built state and passes. A ' +\n 'test whose subject is that shape itself is a reviewed entry whose anchor names the one construct, ' +\n 'with its why; an entry that no longer matches one is stale.',\n timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,\n run: (context) =>\n anchoredFindings(\n context.files(SCOPE).map((file) => ({ file, hits: handBuiltReads(file) })),\n facts.reviewed,\n 'its anchor names no hand-built read',\n ),\n },\n ];\n },\n};\n"]}
|