diff --git a/.ref-cache.json b/.ref-cache.json index 3cccd32..0b596f1 100644 --- a/.ref-cache.json +++ b/.ref-cache.json @@ -4619,7 +4619,7 @@ "https://www.intercom.com/help/en/articles/9515824-what-is-fin": 200, "https://www.intercom.com/help/en/articles/9929230-the-fin-ai-engine": 200, "https://www.iso.org/standard/81870.html": 200, - "https://www.iso20022.org/": "TimeoutError", + "https://www.iso20022.org/": "403 then HTTPError", "https://www.jaegertracing.io/": 200, "https://www.jaegertracing.io/docs/1.6/architecture/": 200, "https://www.jaegertracing.io/docs/2.dev/deployment/configuration/": 200, @@ -4849,12 +4849,12 @@ "https://www.reactive-streams.org/": 200, "https://www.research.ed.ac.uk/en/publications/handlers-of-algebraic-effects": 200, "https://www.research.ed.ac.uk/en/publications/monads-for-functional-programming/": 200, - "https://www.researchgate.net/publication/221366961_Relationship-based_access_control_policies_and_their_policy_languages": "429 then HTTPError", - "https://www.researchgate.net/publication/228342050_Software_design_patterns_for_message_driven_service_oriented_integration_of_stovepipe_applications_in_healthcare_enterprise": "429 then HTTPError", - "https://www.researchgate.net/publication/2378571_Ideal_Hash_Trees": "429 then HTTPError", - "https://www.researchgate.net/publication/2949837_Virtual_Time_and_Global_States_of_Distributed_Systems": "429 then HTTPError", - "https://www.researchgate.net/publication/342799123_RefactoringMiner_20": "429 then HTTPError", - "https://www.researchgate.net/publication/43921655_Combinators_for_bidirectional_tree_transformations_A_linguistic_approach_to_the_view-update_problem": "429 then HTTPError", + "https://www.researchgate.net/publication/221366961_Relationship-based_access_control_policies_and_their_policy_languages": "403 then HTTPError", + "https://www.researchgate.net/publication/228342050_Software_design_patterns_for_message_driven_service_oriented_integration_of_stovepipe_applications_in_healthcare_enterprise": "403 then HTTPError", + "https://www.researchgate.net/publication/2378571_Ideal_Hash_Trees": "403 then HTTPError", + "https://www.researchgate.net/publication/2949837_Virtual_Time_and_Global_States_of_Distributed_Systems": "403 then HTTPError", + "https://www.researchgate.net/publication/342799123_RefactoringMiner_20": "403 then HTTPError", + "https://www.researchgate.net/publication/43921655_Combinators_for_bidirectional_tree_transformations_A_linguistic_approach_to_the_view-update_problem": "403 then HTTPError", "https://www.rfc-editor.org/info/rfc5246": 200, "https://www.rfc-editor.org/info/rfc6265/": 200, "https://www.rfc-editor.org/info/rfc6749": 200, diff --git a/tools/check-duplicates-test.py b/tools/check-duplicates-test.py index 34d8c9b..7abf6ce 100644 --- a/tools/check-duplicates-test.py +++ b/tools/check-duplicates-test.py @@ -92,9 +92,46 @@ def test_analyze_repository(self): queue_file = ROOT / "docs" / "AUTHORING-QUEUE.json" results = analyze_repository(queue_file) self.assertGreater(results["published_count"], 0) - self.assertGreater(results["queue_count"], 0) + self.assertGreaterEqual(results["queue_count"], 0) self.assertIsInstance(results["collisions"], list) + def test_deferred_queue_filtering(self): + import json + import tempfile + + queue_data = [ + { + "name": "Virtual List", + "slug": "virtual-list", + "path": "patterns/13-frontend-ui/virtual-list-deferred.md", + "status": "deferred", + "reason": "Deferred test item", + }, + { + "name": "Virtual List", + "slug": "virtual-list", + "path": "patterns/13-frontend-ui/virtual-list-active.md", + "reason": "Active duplicate test item", + }, + ] + + with tempfile.NamedTemporaryFile("w+", suffix=".json", delete=False) as tf: + json.dump(queue_data, tf) + tf.flush() + temp_path = Path(tf.name) + + try: + results = analyze_repository(temp_path) + self.assertEqual(results["queue_count"], 1) + collisions = results["collisions"] + queue_paths = {c["queue_path"] for c in collisions} + self.assertIn("patterns/13-frontend-ui/virtual-list-active.md", queue_paths) + self.assertNotIn( + "patterns/13-frontend-ui/virtual-list-deferred.md", queue_paths + ) + finally: + temp_path.unlink(missing_ok=True) + def test_historical_proposal_detection(self): history = fetch_historical_proposals() self.assertIsInstance(history, list) @@ -111,9 +148,23 @@ def test_historical_proposal_collision_mock(self): ] original_fetch = check_duplicates.fetch_historical_proposals check_duplicates.fetch_historical_proposals = lambda: fake_history + import json + import tempfile + + active_queue = [ + { + "name": "Windowing", + "slug": "windowing", + "path": "patterns/24-stream-processing/windowing.md", + } + ] + with tempfile.NamedTemporaryFile("w+", suffix=".json", delete=False) as tf: + json.dump(active_queue, tf) + tf.flush() + temp_path = Path(tf.name) + try: - queue_file = ROOT / "docs" / "AUTHORING-QUEUE.json" - results = analyze_repository(queue_file) + results = analyze_repository(temp_path) historical_collisions = [ c for c in results["collisions"] @@ -122,6 +173,7 @@ def test_historical_proposal_collision_mock(self): self.assertGreater(len(historical_collisions), 0) finally: check_duplicates.fetch_historical_proposals = original_fetch + temp_path.unlink(missing_ok=True) def test_collision_deduplication(self): queue_file = ROOT / "docs" / "AUTHORING-QUEUE.json" @@ -136,17 +188,44 @@ def test_collision_deduplication(self): def test_main_check_and_strict_exit_codes(self): import unittest.mock + with unittest.mock.patch.object( sys, "argv", ["check-duplicates.py", "--check"] ): code_check = check_duplicates.main() - self.assertEqual(code_check, 1) + self.assertEqual(code_check, 0) with unittest.mock.patch.object( sys, "argv", ["check-duplicates.py", "--strict"] ): code_strict = check_duplicates.main() - self.assertEqual(code_strict, 1) + self.assertEqual(code_strict, 0) + + fake_collisions = { + "published_count": 1, + "queue_count": 1, + "historical_count": 0, + "collisions": [ + { + "type": "QUEUE_VS_PUBLISHED", + "queue_path": "patterns/13-frontend-ui/test.md", + "published_path": "patterns/13-frontend-ui/virtual-list.md", + "matched_term": "virtual-list", + "normalized_key": "virtuallist", + "queue_name": "Virtual List", + "published_name": "Virtual List", + } + ], + "semantic_collisions": [], + } + with unittest.mock.patch.object( + check_duplicates, "analyze_repository", lambda _: fake_collisions + ): + with unittest.mock.patch.object( + sys, "argv", ["check-duplicates.py", "--strict"] + ): + code_mock_strict = check_duplicates.main() + self.assertEqual(code_mock_strict, 1) if __name__ == "__main__": diff --git a/tools/check-duplicates.py b/tools/check-duplicates.py index dd0f286..fc432d7 100644 --- a/tools/check-duplicates.py +++ b/tools/check-duplicates.py @@ -194,7 +194,8 @@ def analyze_repository(queue_path: Path) -> dict: queue = [] if queue_path.exists(): try: - queue = json.loads(queue_path.read_text(encoding="utf-8")) + raw_queue = json.loads(queue_path.read_text(encoding="utf-8")) + queue = [q for q in raw_queue if q.get("status") != "deferred"] except Exception: queue = []