1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
//! Shared helpers for the crate's in-tree unit tests.
//!
//! Every metric module under `src/metrics/` drives its assertions through
//! the same handful of parse-and-inspect shims. They live here, in a
//! `#[cfg(test)]`-only module, rather than in a production file: the
//! self-scan gate measures production files, and helpers parked in one
//! would spend that file's metric budget on code that never ships
//! (#1066). `.bcaignore` excludes this file from the walk for the same
//! reason.
use PathBuf;
use cratemetrics_inner;
use crateParserTrait;
use crate::;
/// Parses `source` as `filename` under `options` and hands the resulting
/// root [`FuncSpace`] to `check`.
///
/// The source is normalised the way [`crate::read_file_with_eol`] would
/// normalise it on the way in: CRLF/CR collapse to LF, and the trailing
/// newline is regularised to exactly one. Use [`metrics_verbatim`] when a
/// test's input must reach the parser untouched.
/// Parses `source` as `filename` with **every** metric selected and hands
/// the resulting root [`FuncSpace`] to `check`.
///
/// Prefer [`check_func_space_only`] whenever the assertions name a known,
/// bounded set of metrics: computing all thirteen families to inspect one
/// is what made the unit suite pay for ~15 walks per assertion (#1127).
/// This full-set variant remains for tests whose subject *is* the whole
/// surface.
pub
/// [`check_func_space`], restricted to `metrics` and the dependencies
/// [`MetricsOptions::with_only`] resolves for them.
///
/// The space *tree* is metric-independent — `is_func_space` and
/// `get_space_kind` run regardless of the selection — so structural
/// assertions (`assert_child_space_kind`, `child_space`, nesting) hold
/// identically under either variant.
pub
/// Parses `source` as `filename` and hands the root space's
/// [`CodeMetrics`] to `check`, computing only `metrics` and the
/// dependencies [`MetricsOptions::with_only`] resolves for them.
///
/// There is deliberately no full-set counterpart: every caller is a
/// per-metric test module asserting one family, and the removed variant
/// is what made each of those ~2 300 assertions pay for thirteen metric
/// walks (#1127). Reach for [`check_func_space`] if a test's subject
/// really is the whole surface.
///
/// Values are identical to the full-set run for every selected metric —
/// `metric_selection_parity` in `src/spaces_tests.rs` pins that across
/// each metric and a multi-language fixture set, so a migrated test
/// asserting the same numbers is asserting the same thing.
pub
/// Defines a module-local `check_metrics`-shaped shim bound to a fixed
/// metric list.
///
/// Every per-metric module under `src/metrics/` asserts one family
/// across hundreds of call sites. Rather than repeat the metric list at
/// each one, each module invokes this once at the top of its `mod tests`
/// — in place of the `use crate::test_support::check_metrics;` it
/// replaces, so the shim is the only `check_metrics` in scope there and
/// there is nothing to confuse it with.
///
/// Emits `fn $name<T: ParserTrait>(source, filename, check)`, delegating
/// to [`check_metrics_only`]:
///
/// ```ignore
/// check_metrics_only_shim!(check_metrics, Abc);
/// check_metrics_only_shim!(check_cognitive_and_cyclomatic, Cognitive, Cyclomatic);
/// ```
/// [`check_metrics_only_shim`]'s `FuncSpace` counterpart: emits
/// `fn $name<T: ParserTrait, F: Fn(FuncSpace)>(source, filename, check)`
/// delegating to [`check_func_space_only`].
pub use ;
/// Analyses `source` **byte-for-byte** and returns its metrics.
///
/// Use this, not [`check_metrics_only`], when a test's input must reach
/// the parser unaltered: [`check_func_space_with`] normalises CRLF and
/// trims then re-appends a trailing newline, so a construct ending at
/// EOF is unreachable through it and such a test passes vacuously
/// (#1051). It also returns a value, which the `check_metrics`-shaped
/// helpers' bare `fn` callback cannot. `options` is caller-supplied
/// rather than fixed; prefer restricting it, as the per-metric modules
/// do (#1127). Most existing callers still pass
/// `MetricsOptions::default()` — that is a leftover, not a pattern to
/// copy.
pub
/// Analyses `source` **byte-for-byte** and returns its root
/// [`FuncSpace`], nested spaces included.
///
/// The [`metrics_verbatim`] rationale applies verbatim; use this variant
/// when the assertion is about a *nested* space's metrics rather than the
/// root's aggregate (e.g. #1067's per-function `sloc`).
pub
/// Parses `source` as `lang` through the [`crate::Ast`] seam, naming the
/// unit `name`.
///
/// Returns the [`crate::Ast`] rather than one of its projections so a
/// caller can reach both the seam's output (`ops`, `metrics`) and the
/// underlying tree-sitter tree; the `ops` tests need both to compare a
/// space count against a node count.
pub
/// Asserts a per-language fixture list is non-empty.
///
/// Lists of this shape gate each entry on its own language feature, so a
/// build with none of them enabled leaves an empty list, a loop with zero
/// iterations, and a test that reports as passing while asserting
/// nothing. Calling this is what makes that state loud.
pub
/// Asserts that `func_space` has a direct child space named `name` and that
/// its `kind` matches `expected`.
///
/// Used by annotation-type / class / interface tests that need to verify
/// the structural FuncSpace tree (not just metric values), since vacuous
/// metric assertions can pass even when `is_func_space` has been reverted
/// for the node kind under test.
pub
/// Returns the direct child [`FuncSpace`] named `name`, panicking if
/// absent. Lets per-space-metric tests assert accessors on the owning
/// class / interface space (where the value is nonzero) rather than on the
/// always-zero file-unit root.
pub
/// Returns the [`SpaceKind::Function`] space named `name` anywhere in
/// `func_space`'s subtree, panicking unless exactly one matches.
///
/// [`child_space`] looks only at direct children and ignores `kind`, so it
/// cannot reach a function nested inside a class inside a function — the
/// shape a cross-language nested-function comparison needs. Requiring a
/// unique match keeps a fixture that later grows a second same-named
/// function from silently asserting on whichever one the walk reached
/// first.
pub
/// Asserts `src` parses to exactly `want` nodes of each given kind id.
///
/// The anchor for a fixture whose construct under test contributes
/// *nothing* once the fix lands — a relational pattern's operator after
/// #1383, a `goto case`'s `case` token after #1450 — and so has no
/// second axis for the metric assertions to rest on. Trimming `> 5` down
/// to `5`, or deleting `goto case 2;`, leaves every metric assertion
/// satisfied and the construct gone (`.claude/rules/testing.md`,
/// "Perturb the fixture as well as the production line"). Editing a
/// spelling out of the source now fails here by name instead of silently
/// turning the method into a copy of its control.
///
/// Counts rather than presence, because these fixtures carry several
/// methods spelling the same construct: a bare [`ast_has_kind_id`] is
/// still satisfied after one method loses its pattern, which is exactly
/// the decay that turns that method into a silent duplicate of the
/// control. Measured — with presence-only anchoring, rewriting
/// `if (x is > 0)` to `if (x > 0)` in one method of five failed nothing.
pub
/// The C# binding of [`assert_fixture_spells`]. Every caller passes a
/// `foo.cs` fixture, so the parser and path are fixed here rather than
/// repeated at each one.
// Gated to match the Perl binding below: every caller of this one is a
// `#[cfg(feature = "csharp")]` test now too, so the definition says the
// same thing they do. `lib.rs`'s `allow(dead_code)` would have kept a
// partial build quiet either way — the gate is for the reader and for
// the derivation, not for a lint (#1472).
pub
/// The Perl binding of [`assert_fixture_spells`], with the same
/// fixed-parser rationale as the C# one above.
pub
// The parse-only helpers live beside the parse layer and are shared with
// its own tests through the `test-support` feature.
//
// Left ungated on purpose: these are re-exported to call sites across
// seven metric modules, so which build uses them depends on which
// per-language tests it compiled, and enumerating that union here would
// be a hand-maintained copy of seven files' gates. The crate-level
// `cfg_attr` in `lib.rs` silences the partial builds; an item-level
// `allow` on top of it would be live only in the *full* build, which is
// the one that should still police this (#1472).
pub use ;