Coverage for tests / test_dtd / test_python.py: 100%

36 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-08 15:04 -0800

1"""Tests for Data Transformation Density (Python).""" 

2 

3from analyzers.python import analyze_source 

4 

5 

6def _dtd(code: str) -> int: 

7 """Return DTD of the first function in code.""" 

8 result = analyze_source(code) 

9 assert result.functions, f"No functions found in:\n{code}" 

10 return result.functions[0].dtd 

11 

12 

13def _dtds(code: str) -> dict[str, int]: 

14 """Return {name: dtd} for all functions in code.""" 

15 result = analyze_source(code) 

16 return {f.name: f.dtd for f in result.functions} 

17 

18 

19# --- Empty / no data --- 

20 

21def test_empty_function(): 

22 assert _dtd("def f(): pass") == 0 

23 

24 

25def test_no_data_structures(): 

26 code = """ 

27def f(x): 

28 return x + 1 

29""" 

30 assert _dtd(code) == 0 

31 

32 

33# --- Flat structures --- 

34 

35def test_flat_dict(): 

36 code = """ 

37def f(): 

38 return {"a": 1, "b": 2, "c": 3} 

39""" 

40 # dict at depth 1, 3 pairs x 1 = 3 

41 assert _dtd(code) == 3 

42 

43 

44def test_flat_list(): 

45 code = """ 

46def f(): 

47 return [1, 2, 3] 

48""" 

49 # list at depth 1, 3 elements x 1 = 3 

50 assert _dtd(code) == 3 

51 

52 

53# --- Nested structures --- 

54 

55def test_nested_dict_in_list(): 

56 code = """ 

57def f(): 

58 return [{"a": 1}, {"b": 2}] 

59""" 

60 # list at depth 1: 2 elements x 1 = 2 

61 # each dict at depth 2: 1 pair x 2 = 2 each -> 4 

62 # total = 2 + 4 = 6 

63 assert _dtd(code) == 6 

64 

65 

66def test_deeply_nested(): 

67 code = """ 

68def f(): 

69 return {"outer": {"inner": [1, 2]}} 

70""" 

71 # outer dict depth 1: 1 pair x 1 = 1 

72 # inner dict depth 2: 1 pair x 2 = 2 

73 # list depth 3: 2 elements x 3 = 6 

74 # total = 1 + 2 + 6 = 9 

75 assert _dtd(code) == 9 

76 

77 

78# --- Nested function skipped --- 

79 

80def test_nested_function_skipped(): 

81 code = """ 

82def outer(): 

83 x = {"a": 1} 

84 def inner(): 

85 y = {"b": 2, "c": 3} 

86 return x 

87""" 

88 dtds = _dtds(code) 

89 assert dtds["outer"] == 1 # only {"a": 1} 

90 assert dtds["inner"] == 2 # {"b": 2, "c": 3} -> 2 pairs x 1 

91 

92 

93# --- Comprehensions --- 

94 

95def test_dict_comprehension(): 

96 code = """ 

97def f(items): 

98 return {k: v for k, v in items} 

99""" 

100 # dict_comprehension is a container at depth 1 

101 # pair inside at depth 1: 1 pair x 1 = 1 

102 assert _dtd(code) == 1 

103 

104 

105def test_list_comprehension(): 

106 code = """ 

107def f(items): 

108 return [x for x in items] 

109""" 

110 # list_comprehension is a container at depth 1 

111 # no explicit payload children (the inner expression isn't a pair/keyword_arg) 

112 assert _dtd(code) == 0