Coverage for tests / test_dtd / test_typescript.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 (TypeScript).""" 

2 

3from analyzers.typescript 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 --- 

20 

21def test_empty_function(): 

22 assert _dtd("function f() {}") == 0 

23 

24 

25# --- Flat structures --- 

26 

27def test_flat_object(): 

28 code = """ 

29function f() { 

30 return {a: 1, b: 2, c: 3}; 

31} 

32""" 

33 # object at depth 1, 3 pairs x 1 = 3 

34 assert _dtd(code) == 3 

35 

36 

37def test_flat_array(): 

38 code = """ 

39function f() { 

40 return [1, 2, 3]; 

41} 

42""" 

43 # array at depth 1, 3 elements x 1 = 3 

44 assert _dtd(code) == 3 

45 

46 

47# --- Nested --- 

48 

49def test_nested_object_in_array(): 

50 code = """ 

51function f() { 

52 return [{a: 1}, {b: 2}]; 

53} 

54""" 

55 # array at depth 1: 2 elements x 1 = 2 

56 # each object at depth 2: 1 pair x 2 = 2 each -> 4 

57 # total = 2 + 4 = 6 

58 assert _dtd(code) == 6 

59 

60 

61def test_deeply_nested(): 

62 code = """ 

63function f() { 

64 return {outer: {inner: [1, 2]}}; 

65} 

66""" 

67 # outer object depth 1: 1 pair x 1 = 1 

68 # inner object depth 2: 1 pair x 2 = 2 

69 # array depth 3: 2 elements x 3 = 6 

70 # total = 1 + 2 + 6 = 9 

71 assert _dtd(code) == 9 

72 

73 

74# --- Map call --- 

75 

76def test_map_call(): 

77 code = """ 

78function f(items: number[]) { 

79 return items.map(x => ({value: x})); 

80} 

81""" 

82 # .map() call at depth 1 (container) 

83 # Inside: object at depth 2, 1 pair x 2 = 2 

84 # total = 2 

85 assert _dtd(code) == 2 

86 

87 

88# --- Shorthand property --- 

89 

90def test_shorthand_property(): 

91 code = """ 

92function f(x: number, y: number) { 

93 return {x, y}; 

94} 

95""" 

96 # object at depth 1, 2 shorthand properties x 1 = 2 

97 assert _dtd(code) == 2 

98 

99 

100# --- Arrow expression body --- 

101 

102def test_arrow_expression_body(): 

103 code = """ 

104const f = (x: number) => ({value: x}); 

105""" 

106 # object at depth 1, 1 pair x 1 = 1 

107 assert _dtd(code) == 1 

108 

109 

110# --- Nested named arrow skipped --- 

111 

112def test_nested_named_arrow(): 

113 code = """ 

114function outer() { 

115 const x = {a: 1}; 

116 const inner = (y: number) => { 

117 return {b: 2, c: 3}; 

118 }; 

119} 

120""" 

121 dtds = _dtds(code) 

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

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