import importlib.util import tracemalloc import unittest from pathlib import Path from unittest.mock import patch _HELPER = Path(__file__).with_name("revision_state_policy.py") _SPEC = importlib.util.spec_from_file_location("revision_state_policy", _HELPER) assert _SPEC is not None and _SPEC.loader is not None _MODULE = importlib.util.module_from_spec(_SPEC) _SPEC.loader.exec_module(_MODULE) analyze_batch = _MODULE.analyze_batch has_revision_state = _MODULE.has_revision_state class RevisionStatePolicyTests(unittest.TestCase): def test_ast_access_and_f_strings(self): for source in ( "old = revision.state", 'old = workspaceRevision["state"]', 'old = record["selectedWorkspace"].state', 'old = f"{revision.state}"', 'old = revision["st" + "ate"]', 'old = record["revi" + "sion"].state', 'old = revision[f"state"]', 'old = record[f"revision"].state', "old = revision[f\"st{'a'}te\"]", "old = revision[f\"{'state'}\"]", "old = record[f\"revi{'sion'}\"].state", "old = revision[f\"{'st' + 'ate'}\"]", "old = record[f\"{'revi' + 'sion'}\"].state", "old = revision[f\"{'state':s}\"]", ): with self.subTest(source=source): self.assertTrue(has_revision_state(source)) def test_static_format_bindings(self): for source in ( '"{0.state}".format(revision)', '"{0[state]}".format(workspaceRevision)', '"{item.state}".format(item=selectedWorkspace)', '"{item[state]}".format_map({"item": revision})', '("{0.state}").format(revision)', '"{0:{1.state}}".format(value, revision)', '"{0.state}".format(*[revision])', '"{0[state]}".format(*(revision,))', '"{1[state]}".format(*[other, workspaceRevision])', '"{item.state}".format(**{"item": selectedWorkspace})', '"{item[state]}".format(**{"outer": other, **{"item": revision}})', '"{item.state}".format_map({**{"item": workspaceRevision}})', '"{.state}".format(revision)', '"{[state]}".format(revision)', '"{:{.state}}".format(value, revision)', '"{.name} {[state]}".format(other, revision)', '"{item.state}".format(item=revision, **values)', ): with self.subTest(source=source): self.assertTrue(has_revision_state(source)) self.assertFalse(has_revision_state('"{0.state}".format(other)')) # Dynamic unpacking is intentionally unresolved rather than guessed. self.assertFalse(has_revision_state('"{0.state}".format(*values)')) self.assertFalse(has_revision_state('"{.name} {[state]}".format(other, other)')) self.assertFalse(has_revision_state('"{item.state}".format(**values)')) # FormattedValue keys are dynamic and are not treated as static strings. self.assertFalse(has_revision_state('revision[f"st{suffix}"]')) def test_literals_are_not_active(self): self.assertFalse(has_revision_state('text = "{revision.state}"')) self.assertFalse(has_revision_state('text = "{{revision.state}}".format(value)')) def test_oversized_static_format_fails_before_formatting(self): tracemalloc.start() with patch("builtins.format") as format_mock: with self.assertRaisesRegex(ValueError, "width or precision"): has_revision_state('revision[f"{1:.1000000000f}"]') format_mock.assert_not_called() _current, peak = tracemalloc.get_traced_memory() tracemalloc.stop() self.assertLess(peak, 1_000_000) self.assertFalse(has_revision_state('revision[f"{1:04d}"]')) def test_batch_contract(self): self.assertEqual( analyze_batch([{"label": "one.py", "source": "revision.state"}]), ["one.py"], ) if __name__ == "__main__": unittest.main()