# build-aux/measurestack/test_analyze.py - Tests for analyze.py # # Copyright (C) 2025 Luke T. Shumaker # SPDX-License-Identifier: AGPL-3.0-or-later # pylint: disable=unused-variable import re import typing import pytest from . import analyze, testutil, util def test_name_base() -> None: assert analyze.QName("foo.c:bar.1").base() == analyze.BaseName("bar") def test_name_pretty() -> None: name = analyze.QName("foo.c:bar.1") assert f"{name}" == "QName('foo.c:bar.1')" assert f"{name.base()}" == "BaseName('bar')" assert f"{[name]}" == "[QName('foo.c:bar.1')]" assert f"{[name.base()]}" == "[BaseName('bar')]" def test_name_eq() -> None: name = analyze.QName("foo.c:bar.1") with pytest.raises(AssertionError) as e: if name == "foo": pass assert "comparing QName with str" in str(e) with pytest.raises(AssertionError) as e: if name.base() == "foo": pass assert "comparing BaseName with str" in str(e) def test_max_call_depth() -> None: graph: typing.Sequence[tuple[str, typing.Collection[str]]] = [ ("a", {"b"}), # 1 ("b", {"c"}), # 2 ("c", {"d"}), # 3 ("d", {"e"}), # 4 ("e", {}), # 5 ] testcases: dict[int, bool] = { 1: True, 2: True, 3: True, 4: True, 5: False, 6: False, 7: False, } def test_filter(name: analyze.QName) -> tuple[int, bool]: if str(name.base()) in ["a"]: return 1, True return 0, False def doit(depth: int, graph_plugin: util.Plugin) -> None: analyze.analyze( ci_fnames=[], app_func_filters={"Main": test_filter}, app=util.PluginApplication(testutil.nop_location_xform, [graph_plugin]), cfg_max_call_depth=depth, ) pat = re.compile("^max call depth exceeded: ") for depth, should_fail in testcases.items(): graph_plugin = testutil.GraphProviderPlugin(depth, graph) if should_fail: with pytest.raises(ValueError, match=pat): doit(depth, graph_plugin) else: doit(depth, graph_plugin)