Coverage for tests/unit/misc/test_sequence.py: 100%

73 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-04-04 03:33 -0600

1import pytest 

2 

3from muutils.misc.sequence import ( 

4 list_split, 

5 list_join, 

6 flatten, 

7 apply_mapping_chain, 

8 apply_mapping, 

9) 

10 

11# Test data 

12simple_mapping = {1: "one", 2: "two", 3: "three"} 

13chain_mapping = {1: ["one", "uno"], 2: ["two", "dos"], 3: ["three", "tres"]} 

14 

15 

16def test_list_split(): 

17 # with integers 

18 assert list_split([1, 2, 3, 2, 4], 2) == [ 

19 [1], 

20 [3], 

21 [4], 

22 ], "List should be split correctly" 

23 assert list_split([1, 2, 2, 2, 4], 2) == [ 

24 [1], 

25 [], 

26 [], 

27 [4], 

28 ], "Empty sublists should be created for consecutive delimiters" 

29 assert list_split([], 2) == [ 

30 [] 

31 ], "Empty list should return a list with one empty sublist" 

32 

33 # with strings 

34 assert list_split(["a", "b", "c", "b", "d"], "b") == [ 

35 ["a"], 

36 ["c"], 

37 ["d"], 

38 ], "List should be split correctly" 

39 assert list_split(["a", "b", "b", "b", "d"], "b") == [ 

40 ["a"], 

41 [], 

42 [], 

43 ["d"], 

44 ], "Empty sublists should be created for consecutive delimiters" 

45 assert list_split([], "b") == [ 

46 [] 

47 ], "Empty list should return a list with one empty sublist" 

48 

49 # mixed types 

50 assert list_split([1, "b", 3, "b", 4], "b") == [ 

51 [1], 

52 [3], 

53 [4], 

54 ], "List should be split correctly" 

55 assert list_split([1, "b", "b", "b", 4], "b") == [ 

56 [1], 

57 [], 

58 [], 

59 [4], 

60 ], "Empty sublists should be created for consecutive delimiters" 

61 assert list_split([], "b") == [ 

62 [] 

63 ], "Empty list should return a list with one empty sublist" 

64 

65 assert list_split([1, 2, 3, 0, 4, 5, 0, 6], 0) == [[1, 2, 3], [4, 5], [6]] 

66 assert list_split([0, 1, 2, 3], 0) == [[], [1, 2, 3]] 

67 assert list_split([1, 2, 3], 0) == [[1, 2, 3]] 

68 assert list_split([], 0) == [[]] 

69 

70 

71def test_list_join(): 

72 # with integers 

73 assert list_join([1, 2, 3], lambda: 0) == [ 

74 1, 

75 0, 

76 2, 

77 0, 

78 3, 

79 ], "Items should be joined correctly with factory-produced values" 

80 assert list_join([1], lambda: 0) == [1], "Single item list should remain unchanged" 

81 assert list_join([], lambda: 0) == [], "Empty list should remain unchanged" 

82 

83 # with strings 

84 assert list_join(["a", "b", "c"], lambda: "x") == [ 

85 "a", 

86 "x", 

87 "b", 

88 "x", 

89 "c", 

90 ], "Items should be joined correctly with factory-produced values" 

91 assert list_join(["a"], lambda: "x") == [ 

92 "a" 

93 ], "Single item list should remain unchanged" 

94 assert list_join([], lambda: "x") == [], "Empty list should remain unchanged" 

95 

96 # mixed types 

97 assert list_join([1, "b", 3], lambda: "x") == [ 

98 1, 

99 "x", 

100 "b", 

101 "x", 

102 3, 

103 ], "Items should be joined correctly with factory-produced values" 

104 assert list_join([1], lambda: "x") == [ 

105 1 

106 ], "Single item list should remain unchanged" 

107 assert list_join([], lambda: "x") == [], "Empty list should remain unchanged" 

108 

109 

110# Testing the flatten function 

111def test_flatten_full_flattening(): 

112 assert list(flatten([1, [2, [3, 4]], 5])) == [1, 2, 3, 4, 5] 

113 assert list(flatten([1, [2, [3, [4, [5]]]]])) == [1, 2, 3, 4, 5] 

114 assert list(flatten([])) == [] 

115 

116 

117def test_flatten_partial_flattening(): 

118 assert list(flatten([1, [2, [3, 4]], 5], levels_to_flatten=1)) == [1, 2, [3, 4], 5] 

119 assert list(flatten([1, [2, [3, [4, [5]]]]], levels_to_flatten=2)) == [ 

120 1, 

121 2, 

122 3, 

123 [4, [5]], 

124 ] 

125 

126 

127def test_flatten_with_non_iterables(): 

128 assert list(flatten([1, 2, 3])) == [1, 2, 3] 

129 assert list(flatten([1, "abc", 2, [3, 4], 5])) == [1, "abc", 2, 3, 4, 5] 

130 

131 

132def test_apply_mapping_basic(): 

133 assert apply_mapping(simple_mapping, [1, 2, 3]) == ["one", "two", "three"] 

134 

135 

136def test_apply_mapping_missing_skip(): 

137 assert apply_mapping(simple_mapping, [1, 4, 2], when_missing="skip") == [ 

138 "one", 

139 "two", 

140 ] 

141 

142 

143def test_apply_mapping_missing_include(): 

144 assert apply_mapping(simple_mapping, [1, 4, 2], when_missing="include") == [ 

145 "one", 

146 4, 

147 "two", 

148 ] 

149 

150 

151def test_apply_mapping_missing_except(): 

152 with pytest.raises(KeyError): 

153 apply_mapping(simple_mapping, [1, 4, 2], when_missing="except") 

154 

155 

156def test_apply_mapping_invalid_when_missing(): 

157 with pytest.raises(ValueError): 

158 apply_mapping(simple_mapping, [1, 2, 3, 4], when_missing="invalid") # type: ignore[arg-type] 

159 

160 

161def test_apply_mapping_empty_input(): 

162 assert apply_mapping(simple_mapping, []) == [] 

163 

164 

165def test_apply_mapping_empty_mapping(): 

166 assert apply_mapping({}, [1, 2, 3], when_missing="include") == [1, 2, 3] 

167 

168 

169def test_apply_mapping_chain_basic(): 

170 assert apply_mapping_chain(chain_mapping, [1, 2, 3]) == [ 

171 "one", 

172 "uno", 

173 "two", 

174 "dos", 

175 "three", 

176 "tres", 

177 ] 

178 

179 

180def test_apply_mapping_chain_missing_skip(): 

181 assert apply_mapping_chain(chain_mapping, [1, 4, 2], when_missing="skip") == [ 

182 "one", 

183 "uno", 

184 "two", 

185 "dos", 

186 ] 

187 

188 

189def test_apply_mapping_chain_missing_include(): 

190 assert apply_mapping_chain(chain_mapping, [1, 4, 2], when_missing="include") == [ 

191 "one", 

192 "uno", 

193 4, 

194 "two", 

195 "dos", 

196 ] 

197 

198 

199def test_apply_mapping_chain_missing_except(): 

200 with pytest.raises(KeyError): 

201 apply_mapping_chain(chain_mapping, [1, 4, 2], when_missing="except") 

202 

203 

204def test_apply_mapping_chain_invalid_when_missing(): 

205 with pytest.raises(ValueError): 

206 apply_mapping_chain(chain_mapping, [1, 2, 3, 4], when_missing="invalid") # type: ignore[arg-type] 

207 

208 

209def test_apply_mapping_chain_empty_input(): 

210 assert apply_mapping_chain(chain_mapping, []) == [] 

211 

212 

213def test_apply_mapping_chain_empty_mapping(): 

214 assert apply_mapping_chain({}, [1, 2, 3], when_missing="include") == [1, 2, 3] 

215 

216 

217def test_apply_mapping_chain_empty_values(): 

218 empty_chain_mapping = {1: [], 2: ["two"], 3: []} 

219 assert apply_mapping_chain(empty_chain_mapping, [1, 2, 3]) == ["two"]