|
1 | | -// Copyright (c) 2023-2026 ktsu-dev contributors |
| 1 | +// Copyright (c) 2023-2026 ktsu-dev contributors |
2 | 2 |
|
3 | 3 | namespace TextFilter.Test; |
4 | 4 |
|
@@ -1167,4 +1167,67 @@ public void FuzzyFilterIgnoresFilterPadding(string paddedFilter) |
1167 | 1167 | CollectionAssert.AreEquivalent(HelMatches, result, |
1168 | 1168 | $"Padding in '{paddedFilter}' should not hide items that 'hel' matches."); |
1169 | 1169 | } |
| 1170 | + |
| 1171 | + [TestMethod] |
| 1172 | + [DataRow(TextFilterType.Glob, "*.cs")] |
| 1173 | + [DataRow(TextFilterType.Regex, "\\.cs$")] |
| 1174 | + public void FilterTakeStopsReadingOnceEnoughGlobOrRegexItemsMatch(TextFilterType filterType, string filter) |
| 1175 | + { |
| 1176 | + IEnumerable<string> items = Enumerable.Range(0, 10_000).Select(i => $"File{i}.cs"); |
| 1177 | + int calls = 0; |
| 1178 | + string CountingKey(string s) |
| 1179 | + { |
| 1180 | + calls++; |
| 1181 | + return s; |
| 1182 | + } |
| 1183 | + |
| 1184 | + List<string> page = [.. TextFilter.Filter(items, CountingKey, filter, filterType).Take(10)]; |
| 1185 | + |
| 1186 | + CollectionAssert.AreEqual(items.Take(10).ToList(), page); |
| 1187 | + Assert.AreEqual(10, calls, "Only the items needed for the first page should be matched."); |
| 1188 | + } |
| 1189 | + |
| 1190 | + [TestMethod] |
| 1191 | + public void FilterGlobFirstDoesNotReadPastTheFirstMatch() |
| 1192 | + { |
| 1193 | + // Stands in for an endless or streaming source: reading past the first page fails the test |
| 1194 | + // rather than hanging it. |
| 1195 | + static IEnumerable<string> StreamingLines() |
| 1196 | + { |
| 1197 | + for (int i = 0; i < 1_000; i++) |
| 1198 | + { |
| 1199 | + yield return i % 3 == 2 ? $"line{i}.log" : $"line{i}.txt"; |
| 1200 | + } |
| 1201 | + |
| 1202 | + throw new InvalidOperationException("Filter read the whole source before yielding its first match."); |
| 1203 | + } |
| 1204 | + |
| 1205 | + Assert.AreEqual("line2.log", TextFilter.Filter(StreamingLines(), "*.log").First()); |
| 1206 | + } |
| 1207 | + |
| 1208 | + [TestMethod] |
| 1209 | + [DataRow(TextFilterType.Glob, "b* a*")] |
| 1210 | + [DataRow(TextFilterType.Regex, "^(b|a)")] |
| 1211 | + public void FilterGlobOrRegexKeepsInputOrder(TextFilterType filterType, string filter) |
| 1212 | + { |
| 1213 | + List<string> strings = ["banana", "cherry", "apple", "blueberry", "avocado"]; |
| 1214 | + List<string> result = [.. TextFilter.Filter(strings, filter, filterType)]; |
| 1215 | + CollectionAssert.AreEqual(new List<string> { "banana", "apple", "blueberry", "avocado" }, result); |
| 1216 | + } |
| 1217 | + |
| 1218 | + [TestMethod] |
| 1219 | + public void FilterFuzzyStillSortsByDescendingScore() |
| 1220 | + { |
| 1221 | + List<string> strings = ["hello world", "yellow", "hello", "help"]; |
| 1222 | + List<string> result = [.. TextFilter.Filter(strings, "hello", TextFilterType.Fuzzy)]; |
| 1223 | + static int ScoreOf(string s) |
| 1224 | + { |
| 1225 | + TextFilter.IsMatch(s, "hello", out int score, TextFilterType.Fuzzy); |
| 1226 | + return score; |
| 1227 | + } |
| 1228 | + |
| 1229 | + List<int> scores = [.. result.Select(ScoreOf)]; |
| 1230 | + CollectionAssert.AreEqual(scores.OrderByDescending(s => s).ToList(), scores); |
| 1231 | + Assert.IsNotEmpty(result); |
| 1232 | + } |
1170 | 1233 | } |
0 commit comments