@suss/checker-intent 0.34.0 → 0.35.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/dist/index.cjs +31 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +31 -2
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -73,12 +73,19 @@ function checkCoveringTests(claims, lookup) {
|
|
|
73
73
|
}
|
|
74
74
|
const honouring = lookup.facts.reachedFromEach(
|
|
75
75
|
waiting.map((one) => one.test),
|
|
76
|
-
{ pastMocks: true }
|
|
76
|
+
{ pastMocks: true, certainOnly: true }
|
|
77
77
|
);
|
|
78
78
|
const missed = waiting.filter(
|
|
79
79
|
(one) => pathInto(one.test, honouring.get(one.test), one.subject) === null && callOnSubjectClass(one.test, one.subject, lookup, true) === null
|
|
80
80
|
);
|
|
81
|
-
const ignoring = missed.length === 0 ? /* @__PURE__ */ new Map() : lookup.facts.reachedFromEach(
|
|
81
|
+
const ignoring = missed.length === 0 ? /* @__PURE__ */ new Map() : lookup.facts.reachedFromEach(
|
|
82
|
+
missed.map((one) => one.test),
|
|
83
|
+
{ certainOnly: true }
|
|
84
|
+
);
|
|
85
|
+
const possibly = missed.length === 0 ? /* @__PURE__ */ new Map() : lookup.facts.reachedFromEach(
|
|
86
|
+
missed.map((one) => one.test),
|
|
87
|
+
{ pastMocks: true }
|
|
88
|
+
);
|
|
82
89
|
for (const one of waiting) {
|
|
83
90
|
const claim = claims[one.at];
|
|
84
91
|
if (!missed.includes(one)) {
|
|
@@ -95,6 +102,15 @@ function checkCoveringTests(claims, lookup) {
|
|
|
95
102
|
);
|
|
96
103
|
continue;
|
|
97
104
|
}
|
|
105
|
+
const throughPossible = pathInto(
|
|
106
|
+
one.test,
|
|
107
|
+
possibly.get(one.test),
|
|
108
|
+
one.subject
|
|
109
|
+
);
|
|
110
|
+
if (throughPossible !== null) {
|
|
111
|
+
verdicts[one.at] = reachesOnlyMaybe(claim, one.subject, throughPossible);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
98
114
|
const unfollowed = unfollowedOnTheWay(one.unit, one.test, reached, lookup);
|
|
99
115
|
const nameMatches = unfollowedToSubject(one.unit, one.subject, lookup);
|
|
100
116
|
verdicts[one.at] = unfollowed.length === 0 && nameMatches.length === 0 ? finding(
|
|
@@ -122,6 +138,19 @@ function notChecked(claim, subject, nameMatches, unfollowed) {
|
|
|
122
138
|
}
|
|
123
139
|
};
|
|
124
140
|
}
|
|
141
|
+
function reachesOnlyMaybe(claim, subject, path) {
|
|
142
|
+
const choosing = path.find((hop) => hop.recorded === "possible");
|
|
143
|
+
return {
|
|
144
|
+
kind: "unchecked",
|
|
145
|
+
unchecked: {
|
|
146
|
+
intent: claim.prd.title,
|
|
147
|
+
reason: "possibleCall",
|
|
148
|
+
scenario: claim.label,
|
|
149
|
+
coveredBy: claim.spelled.spelledAs,
|
|
150
|
+
detail: `Scenario ${claim.label} lists the test "${claim.spelled.spelledAs}": it reaches ${subject.label} only through ${choosing?.callee ?? "a call"}, which picks one of several functions at run time, so suss cannot say the test runs it (${(0, import_checker.callSpellings)(path).join(" -> ")}).`
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
125
154
|
function unfollowedOnTheWay(test, key, reached, lookup) {
|
|
126
155
|
const units = [
|
|
127
156
|
test,
|
package/dist/index.d.cts
CHANGED
|
@@ -125,7 +125,7 @@ type CheckedIntent = CheckedBoundaryIntent | CheckedPrd;
|
|
|
125
125
|
interface UncheckedIntent {
|
|
126
126
|
/** The intent doc's `name` (boundary) or `title` (prd). */
|
|
127
127
|
intent: string;
|
|
128
|
-
reason: "unkeyable" | "unreadValue" | "unfollowedCall";
|
|
128
|
+
reason: "unkeyable" | "unreadValue" | "unfollowedCall" | "possibleCall";
|
|
129
129
|
/** The outcome the claim is on, for a claim narrower than the document. */
|
|
130
130
|
outcomeId?: string;
|
|
131
131
|
/** The scenario the claim is on, by its title or its position, for a covering test. */
|
package/dist/index.d.ts
CHANGED
|
@@ -125,7 +125,7 @@ type CheckedIntent = CheckedBoundaryIntent | CheckedPrd;
|
|
|
125
125
|
interface UncheckedIntent {
|
|
126
126
|
/** The intent doc's `name` (boundary) or `title` (prd). */
|
|
127
127
|
intent: string;
|
|
128
|
-
reason: "unkeyable" | "unreadValue" | "unfollowedCall";
|
|
128
|
+
reason: "unkeyable" | "unreadValue" | "unfollowedCall" | "possibleCall";
|
|
129
129
|
/** The outcome the claim is on, for a claim narrower than the document. */
|
|
130
130
|
outcomeId?: string;
|
|
131
131
|
/** The scenario the claim is on, by its title or its position, for a covering test. */
|
package/dist/index.js
CHANGED
|
@@ -65,12 +65,19 @@ function checkCoveringTests(claims, lookup) {
|
|
|
65
65
|
}
|
|
66
66
|
const honouring = lookup.facts.reachedFromEach(
|
|
67
67
|
waiting.map((one) => one.test),
|
|
68
|
-
{ pastMocks: true }
|
|
68
|
+
{ pastMocks: true, certainOnly: true }
|
|
69
69
|
);
|
|
70
70
|
const missed = waiting.filter(
|
|
71
71
|
(one) => pathInto(one.test, honouring.get(one.test), one.subject) === null && callOnSubjectClass(one.test, one.subject, lookup, true) === null
|
|
72
72
|
);
|
|
73
|
-
const ignoring = missed.length === 0 ? /* @__PURE__ */ new Map() : lookup.facts.reachedFromEach(
|
|
73
|
+
const ignoring = missed.length === 0 ? /* @__PURE__ */ new Map() : lookup.facts.reachedFromEach(
|
|
74
|
+
missed.map((one) => one.test),
|
|
75
|
+
{ certainOnly: true }
|
|
76
|
+
);
|
|
77
|
+
const possibly = missed.length === 0 ? /* @__PURE__ */ new Map() : lookup.facts.reachedFromEach(
|
|
78
|
+
missed.map((one) => one.test),
|
|
79
|
+
{ pastMocks: true }
|
|
80
|
+
);
|
|
74
81
|
for (const one of waiting) {
|
|
75
82
|
const claim = claims[one.at];
|
|
76
83
|
if (!missed.includes(one)) {
|
|
@@ -87,6 +94,15 @@ function checkCoveringTests(claims, lookup) {
|
|
|
87
94
|
);
|
|
88
95
|
continue;
|
|
89
96
|
}
|
|
97
|
+
const throughPossible = pathInto(
|
|
98
|
+
one.test,
|
|
99
|
+
possibly.get(one.test),
|
|
100
|
+
one.subject
|
|
101
|
+
);
|
|
102
|
+
if (throughPossible !== null) {
|
|
103
|
+
verdicts[one.at] = reachesOnlyMaybe(claim, one.subject, throughPossible);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
90
106
|
const unfollowed = unfollowedOnTheWay(one.unit, one.test, reached, lookup);
|
|
91
107
|
const nameMatches = unfollowedToSubject(one.unit, one.subject, lookup);
|
|
92
108
|
verdicts[one.at] = unfollowed.length === 0 && nameMatches.length === 0 ? finding(
|
|
@@ -114,6 +130,19 @@ function notChecked(claim, subject, nameMatches, unfollowed) {
|
|
|
114
130
|
}
|
|
115
131
|
};
|
|
116
132
|
}
|
|
133
|
+
function reachesOnlyMaybe(claim, subject, path) {
|
|
134
|
+
const choosing = path.find((hop) => hop.recorded === "possible");
|
|
135
|
+
return {
|
|
136
|
+
kind: "unchecked",
|
|
137
|
+
unchecked: {
|
|
138
|
+
intent: claim.prd.title,
|
|
139
|
+
reason: "possibleCall",
|
|
140
|
+
scenario: claim.label,
|
|
141
|
+
coveredBy: claim.spelled.spelledAs,
|
|
142
|
+
detail: `Scenario ${claim.label} lists the test "${claim.spelled.spelledAs}": it reaches ${subject.label} only through ${choosing?.callee ?? "a call"}, which picks one of several functions at run time, so suss cannot say the test runs it (${callSpellings(path).join(" -> ")}).`
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
117
146
|
function unfollowedOnTheWay(test, key, reached, lookup) {
|
|
118
147
|
const units = [
|
|
119
148
|
test,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/checker-intent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Compare the intent your team wrote down against what suss read out of the code, and report where the two have drifted apart.",
|
|
6
6
|
"keywords": [
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"zod": "^4.0.0"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@suss/behavioral-ir": "0.
|
|
53
|
-
"@suss/checker": "0.
|
|
54
|
-
"@suss/intent-ir": "0.
|
|
55
|
-
"@suss/ir-core": "0.
|
|
52
|
+
"@suss/behavioral-ir": "0.35.0",
|
|
53
|
+
"@suss/checker": "0.35.0",
|
|
54
|
+
"@suss/intent-ir": "0.35.0",
|
|
55
|
+
"@suss/ir-core": "0.35.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"tsup": "*",
|