Files
akadeepeshandClaude Opus 5.5 517e7eca4e test: add test suite and cross-platform CI
Covers project-root detection, path matching, three-way merges, apply-zip
end to end, snapshots and CONTEXTZIP.md, workspace detection and git
changes in nested repos. Runs on Windows, macOS and Linux with Python
3.9, 3.12 and 3.13: python -m unittest discover -s tests -t .

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:43:08 +05:30

85 lines
3.5 KiB
Python

"""Pins down exclusion matching so the pathspec backend can change safely."""
from __future__ import annotations
from contextzip.filters import build_force_include_spec, build_spec, resolve_files
from tests.helpers import TempProject
class SpecMatchingTests(TempProject):
def spec(self, *extra, modules=("base",), gitignore=None):
gi = None
if gitignore is not None:
gi = self.write(".gitignore", gitignore)
return build_spec(rule_modules=list(modules), extra_exclude=list(extra) or None, gitignore_path=gi)
def test_base_rules(self):
s = self.spec()
for path in [".git/config", "a/.git/config", ".env", "app/.env.local", "x.log", "logs/a.txt", "img/a.png", ".contextzip/x"]:
self.assertTrue(s.match_file(path), path)
for path in ["src/app.py", "README.md", "env.ts", "docs/guide.md"]:
self.assertFalse(s.match_file(path), path)
def test_directory_patterns_match_at_any_depth(self):
s = self.spec("dist/", modules=())
self.assertTrue(s.match_file("dist/a.js"))
self.assertTrue(s.match_file("pkg/dist/a.js"))
self.assertFalse(s.match_file("distance.js"))
def test_anchored_patterns(self):
s = self.spec("/build", "docs/internal/", modules=())
self.assertTrue(s.match_file("build/a"))
self.assertFalse(s.match_file("sub/build/a"))
self.assertTrue(s.match_file("docs/internal/x.md"))
self.assertFalse(s.match_file("other/docs/internal/x.md"))
def test_globs(self):
s = self.spec("*.snap", "**/fixtures/**", modules=())
self.assertTrue(s.match_file("a/b/c.snap"))
self.assertTrue(s.match_file("x/fixtures/y.json"))
self.assertFalse(s.match_file("snap.ts"))
def test_gitignore_negation(self):
s = self.spec(modules=(), gitignore="*.log\n!keep.log\n")
self.assertTrue(s.match_file("a.log"))
self.assertFalse(s.match_file("keep.log"))
def test_force_include(self):
fi = build_force_include_spec([".env", "docs/"])
self.assertTrue(fi.match_file(".env"))
self.assertTrue(fi.match_file("docs/a.md"))
self.assertFalse(fi.match_file("src/.env.example"))
self.assertIsNone(build_force_include_spec([]))
class ResolveFilesTests(TempProject):
def setUp(self):
super().setUp()
self.write("src/app.py", "x")
self.write("src/.env", "A=1")
self.write(".env", "A=1")
self.write("dist/out.js", "x")
self.write("dist/node_modules/p/i.js", "x")
self.write("logs/app.log", "x")
def rels(self, result):
return sorted(p.relative_to(self.root).as_posix() for p in result.included)
def test_default(self):
spec = build_spec(rule_modules=["base", "node"])
self.assertEqual(self.rels(resolve_files(self.root, spec)), ["src/app.py"])
def test_explicit_include_brings_back_excluded_paths(self):
spec = build_spec(rule_modules=["base", "node"])
got = self.rels(resolve_files(self.root, spec, include_only=[".env", "dist/", "logs"]))
self.assertEqual(got, [".env", "dist/out.js", "logs/app.log"])
def test_including_a_folder_does_not_bring_back_its_secrets(self):
spec = build_spec(rule_modules=["base"])
self.assertEqual(self.rels(resolve_files(self.root, spec, include_only=["src"])), ["src/app.py"])
def test_always_include(self):
spec = build_spec(rule_modules=["base"])
fi = build_force_include_spec([".env"])
self.assertIn(".env", self.rels(resolve_files(self.root, spec, force_include=fi)))