Skip to content

Commit 0f6117b

Browse files
committed
oracle: exclude dotted .NET test dirs (Newtonsoft.Json.Tests) from product diff
_is_test_path matched a path segment only as a whole word, so the .NET <Project>.Tests / Foo.Benchmarks convention slipped through: the dir 'Newtonsoft.Json.Tests' is one segment, never equal to 'tests', so ~485 test findings leaked into the product diff (own-only 489 vs the true 4). Match each dot-component of a segment instead — catching the 'tests' tail while leaving single-component product dirs (SnippetEngine, Documentation, Newtonsoft.Json) untouched. Adds selftest cases for the dotted dir and its product sibling. Verified on the recorded Newtonsoft oracle output: own-only 489 -> 4, oracle_other 903 -> 235. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011YMngnax1jsy378fSAZb9r
1 parent 67073f5 commit 0f6117b

2 files changed

Lines changed: 31 additions & 15 deletions

File tree

‎corpus/oracle-target.txt‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# or "local:<in-repo path>" (a fixture copied into the oracle's target/).
44
# Optional lines: ref=, paths=, build=, include_tests=. Dev-branch only.
55
#
6-
# Blind cross-tool run on an HTTP client lib — HttpClient/HttpRequestMessage
7-
# ownership-transfer patterns (the Polly Bulkhead shape that exercised our
8-
# escape analysis). Triage oracle-only into field-notes per the oracle.md
9-
# maintenance requirement.
10-
RestSharp/RestSharp
6+
# Clean re-run after fixing _is_test_path to drop dotted .NET test dirs
7+
# (Newtonsoft.Json.Tests). The first run leaked ~485 test findings into the diff
8+
# (own-only 489); with the fix the product picture is own-only 4. This confirms it
9+
# on fresh cross-tool output, not just the local replay.
10+
JamesNK/Newtonsoft.Json

‎scripts/oracle_compare.py‎

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -379,13 +379,18 @@ def _is_test_path(path: str) -> bool:
379379
examples are never disposed by design) — counting them as product leaks inflates
380380
the oracle-only recall gap with example code that was never meant to dispose."""
381381
for seg in path.lower().split("/"):
382-
# Exact match for short, collision-prone names — a `snippet` *prefix* would
383-
# wrongly drop product dirs like `SnippetEngine`/`SnippetService` (Polly's
384-
# `src/Snippets/Docs/*` is caught by the exact `snippets`/`docs` segments
385-
# anyway). Prefix match only for the long, unambiguous plural-able ones.
386-
if (seg in ("test", "tests", "doc", "docs", "snippet", "snippets")
387-
or seg.startswith(("benchmark", "sample", "example"))):
388-
return True
382+
# Split each segment on '.' before matching, for the ubiquitous .NET
383+
# `<Project>.Tests` / `Foo.Benchmarks` directory convention: the dir
384+
# `Newtonsoft.Json.Tests` is ONE path segment, so a bare-segment check
385+
# misses it (and silently drags ~485 test findings into the diff). Matching
386+
# each dot-component catches the `tests` tail while keeping the original
387+
# guards intact — exact match for short, collision-prone names (so a single
388+
# component `SnippetEngine`/`Documentation` is NOT dropped, only an exact
389+
# `snippet`/`doc`), prefix only for the long, unambiguous plural-able ones.
390+
for part in seg.split("."):
391+
if (part in ("test", "tests", "doc", "docs", "snippet", "snippets")
392+
or part.startswith(("benchmark", "sample", "example"))):
393+
return True
389394
return False
390395

391396

@@ -560,10 +565,21 @@ def _selftest() -> int:
560565
("tests/Foo/Bar.cs", "benchmarks/X/Y.cs", "src/Test/Z.cs",
561566
"src/Snippets/Docs/Fallback.cs", "src/MyLib/docs/Example.cs")):
562567
fails.append("_is_test_path should match test/benchmark/doc/snippet trees")
568+
# The .NET `<Project>.Tests` / `Foo.Benchmarks` convention: the dotted dir is a
569+
# single path segment, so it must be matched on its dot-components — else a repo
570+
# like Newtonsoft.Json (test tree `Newtonsoft.Json.Tests`) leaks ~485 test
571+
# findings into the product diff (own-only 489 vs the true 4). The sibling
572+
# product dir `Newtonsoft.Json` must stay IN scope.
573+
if not all(_is_test_path(p) for p in
574+
("Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs",
575+
"src/Foo.Benchmarks/Bench.cs")):
576+
fails.append("_is_test_path should match dotted .NET test/benchmark project dirs")
563577
# ...but a product dir whose name merely *starts with* a marker word is NOT
564-
# excluded — exact match for snippet/doc guards against dropping real code.
578+
# excluded — exact match for snippet/doc guards against dropping real code, and
579+
# the dot-split must leave a non-test dotted product namespace untouched.
565580
if any(_is_test_path(p) for p in ("Dapper/SqlMapper.cs", "src/Lib/A.cs",
566-
"src/SnippetEngine/Foo.cs", "src/Documentation/Api.cs")):
581+
"src/SnippetEngine/Foo.cs", "src/Documentation/Api.cs",
582+
"Src/Newtonsoft.Json/JsonSerializer.cs")):
567583
fails.append("_is_test_path should not match product paths")
568584
# the scope note is gated on mode, not count: a product-only run that excluded
569585
# nothing must still say so (else it reads like a full-scope run).
@@ -607,7 +623,7 @@ def _selftest() -> int:
607623
fails.append(f"non-SARIF JSON masked as clean: {len(not_sarif)} findings, "
608624
f"{ns_drift} unparsed")
609625

610-
total = 24
626+
total = 25
611627
for f in fails:
612628
print(f"ORACLE SELFTEST FAIL: {f}")
613629
print(f"oracle_compare selftest: {total - len(fails)}/{total} checks passed")

0 commit comments

Comments
 (0)