Coverage for tests/test_call_graph/test_formatters.py: 100%

1"""Tests for DOT format and external call filtering."""

2

3 from __future__ import annotations

4

5 from pathlib import Path

6 import tempfile

7

8 from call_graph import build_call_graph

9 from call_graph.formatters import format_dot

10

11

12 def test_format_dot():

13 code = """

14 def foo():

15 bar()

16

17 def bar():

18 baz()

19

20 def baz():

21 pass

22 """

23 with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:

24 f.write(code)

25 f.flush()

26

27 graph = build_call_graph([Path(f.name)])

28 dot_output = format_dot(graph)

29

30 assert "digraph call_graph" in dot_output

31 # Node IDs now use filepath:function_name format

32 filepath = f.name

33 assert f'"{filepath}:foo" -> "{filepath}:bar"' in dot_output

34 assert f'"{filepath}:bar" -> "{filepath}:baz"' in dot_output

35

36 Path(f.name).unlink()

37

38

39 def test_format_dot_filters_external():

40 code = """

41 def foo():

42 print("hello")

43 bar()

44

45 def bar():

46 pass

47 """

48 with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:

49 f.write(code)

50 f.flush()

51

52 graph = build_call_graph([Path(f.name)])

53 dot_output = format_dot(graph)

54

55 # External calls should be filtered out

56 assert "print" not in dot_output

57 # Only internal calls should appear

58 filepath = f.name

59 assert f'"{filepath}:foo" -> "{filepath}:bar"' in dot_output

60

61 Path(f.name).unlink()