import os import time from pathlib import Path def test_external_changes_scanner_marks_dirty_and_clears(tmp_path, monkeypatch): # Ensure the scanner is active for this unit-style test (not gated by PYTEST_CURRENT_TEST). monkeypatch.delenv("PYTEST_CURRENT_TEST", raising=False) from services.state.external_changes_scanner import ExternalChangesScanner # Create a minimal Unity-like layout root = tmp_path / "Project" (root / "Assets").mkdir(parents=True) (root / "ProjectSettings").mkdir(parents=True) (root / "Packages").mkdir(parents=True) inst = "Test@deadbeef" s = ExternalChangesScanner(scan_interval_ms=0, max_entries=10000) s.set_project_root(inst, str(root)) # Create a file before baseline so the initial scan establishes a stable reference point. p = root / "Assets" / "x.txt" p.write_text("hi") # Baseline scan: should not be dirty. first = s.update_and_get(inst) assert first["external_changes_dirty"] is False # Touch the file and scan again: should become dirty. now = time.time() os.utime(p, (now + 10.0, now + 10.0)) second = s.update_and_get(inst) assert second["external_changes_dirty"] is True assert isinstance(second["external_changes_last_seen_unix_ms"], int) assert isinstance(second["dirty_since_unix_ms"], int) # Clear and confirm dirty flag resets. s.clear_dirty(inst) third = s.update_and_get(inst) assert third["external_changes_dirty"] is False assert isinstance(third["last_cleared_unix_ms"], int) def test_external_changes_scanner_includes_file_dependency_roots(tmp_path, monkeypatch): # Ensure the scanner is active for this unit-style test (not gated by PYTEST_CURRENT_TEST). monkeypatch.delenv("PYTEST_CURRENT_TEST", raising=False) from services.state.external_changes_scanner import ExternalChangesScanner # Unity project root root = tmp_path / "Project" (root / "Assets").mkdir(parents=True) (root / "ProjectSettings").mkdir(parents=True) (root / "Packages").mkdir(parents=True) # External local package root (outside project root) pkg = tmp_path / "ExternalPkg" (pkg / "Editor").mkdir(parents=True) target = pkg / "Editor" / "Some.cs" target.write_text("// v1") # manifest.json referencing file: dependency manifest = root / "Packages" / "manifest.json" manifest.write_text( '{\n "dependencies": {\n "com.example.pkg": "file:../../ExternalPkg"\n }\n}\n', encoding="utf-8", ) inst = "Test@deadbeef" s = ExternalChangesScanner(scan_interval_ms=0, max_entries=10000) s.set_project_root(inst, str(root)) # Baseline scan captures current mtimes across project + external pkg baseline = s.update_and_get(inst) assert baseline["external_changes_dirty"] is False # Touch external package file and scan again -> should mark dirty now = time.time() os.utime(target, (now + 10.0, now + 10.0)) changed = s.update_and_get(inst) assert changed["external_changes_dirty"] is True