1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.text.similarity;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertNull;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22
23 import java.util.Arrays;
24 import java.util.stream.Stream;
25
26 import org.junit.jupiter.api.BeforeAll;
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.params.ParameterizedTest;
29 import org.junit.jupiter.params.provider.Arguments;
30 import org.junit.jupiter.params.provider.MethodSource;
31
32
33
34
35 public class DamerauLevenshteinDistanceTest {
36
37 private static DamerauLevenshteinDistance defaultInstance;
38
39 @BeforeAll
40 static void createInstance() {
41 defaultInstance = new DamerauLevenshteinDistance();
42 }
43
44 static Stream<Arguments> limitedDamerauLevenshteinDistanceTestCases() {
45 return Stream.of(
46 Arguments.of("", "test", 10, 4),
47 Arguments.of("test", "", 10, 4),
48 Arguments.of("", "test", 2, -1),
49 Arguments.of("test", "", 2, -1),
50 Arguments.of("testing long string", "testing", 2, -1),
51 Arguments.of("kitten", "sitting", 1, -1),
52 Arguments.of("saturday", "sunday", 3, 3),
53 Arguments.of("hello", "world", 6, 4),
54 Arguments.of("algorithm", "logarithm", 1, -1),
55 Arguments.of("computer", "comptuer", 1, 1),
56 Arguments.of("receive", "recieve", 3, 1),
57 Arguments.of("programming", "porgramming", 0, -1),
58 Arguments.of("test", "tset", 1, 1),
59 Arguments.of("example", "exmaple", 3, 1),
60 Arguments.of("transform", "transfrom", 0, -1),
61 Arguments.of("information", "infromation", 1, 1),
62 Arguments.of("development", "developemnt", 3, 1),
63 Arguments.of("password", "passwrod", 0, -1),
64 Arguments.of("separate", "seperate", 1, 1),
65 Arguments.of("definitely", "definately", 3, 1),
66 Arguments.of("occurrence", "occurence", 0, -1),
67 Arguments.of("necessary", "neccessary", 1, 1),
68 Arguments.of("restaurant", "restaraunt", 4, 2),
69 Arguments.of("beginning", "begining", 0, -1),
70 Arguments.of("government", "goverment", 1, 1),
71 Arguments.of("abcdefghijklmnop", "ponmlkjihgfedcba", 17, 15),
72 Arguments.of("AAAAAAAAAA", "BBBBBBBBBB", 5, -1),
73 Arguments.of("abababababab", "babababababa", 2, 2),
74 Arguments.of("supercalifragilisticexpialidocious", "supercalifragilisticexpialidocous", 3, 1),
75 Arguments.of("pneumonoultramicroscopicsilicovolcanoconiosiss", "pneumonoultramicroscopicsilicovolcanoconiosis", 0, -1),
76 Arguments.of("abcdefg", "gfedcba", 6, 6),
77 Arguments.of("xyxyxyxyxy", "yxyxyxyxyx", 4, 2),
78 Arguments.of("aaaaabbbbbccccc", "cccccbbbbbaaaaa", 5, -1),
79 Arguments.of("thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsovrethelazydog", 1, 1),
80 Arguments.of("antidisestablishmentarianism", "antidisestablishmentarianisn", 3, 1)
81 );
82 }
83
84 static Stream<Arguments> limitedDamerauLevenshteinDistanceTestCases_SimilarityInput() {
85 return SimilarityInputTest.similarityInputs()
86 .flatMap(cls -> limitedDamerauLevenshteinDistanceTestCases().map(arguments -> {
87 final Object[] values = Arrays.copyOf(arguments.get(), arguments.get().length + 1);
88 values[values.length - 1] = cls;
89 return Arguments.of(values);
90 }));
91 }
92
93 static Stream<Arguments> unlimitedDamerauLevenshteinDistanceTestCases() {
94 return Stream.of(
95 Arguments.of("", "test", 4),
96 Arguments.of("test", "", 4),
97 Arguments.of("kitten", "sitting", 3),
98 Arguments.of("saturday", "sunday", 3),
99 Arguments.of("hello", "world", 4),
100 Arguments.of("algorithm", "logarithm", 3),
101 Arguments.of("computer", "comptuer", 1),
102 Arguments.of("receive", "recieve", 1),
103 Arguments.of("programming", "porgramming", 1),
104 Arguments.of("test", "tset", 1),
105 Arguments.of("example", "exmaple", 1),
106 Arguments.of("transform", "transfrom", 1),
107 Arguments.of("information", "infromation", 1),
108 Arguments.of("development", "developemnt", 1),
109 Arguments.of("password", "passwrod", 1),
110 Arguments.of("separate", "seperate", 1),
111 Arguments.of("definitely", "definately", 1),
112 Arguments.of("occurrence", "occurence", 1),
113 Arguments.of("necessary", "neccessary", 1),
114 Arguments.of("restaurant", "restaraunt", 2),
115 Arguments.of("beginning", "begining", 1),
116 Arguments.of("government", "goverment", 1),
117 Arguments.of("abcdefghijklmnop", "ponmlkjihgfedcba", 15),
118 Arguments.of("AAAAAAAAAA", "BBBBBBBBBB", 10),
119 Arguments.of("abababababab", "babababababa", 2),
120 Arguments.of("supercalifragilisticexpialidocious", "supercalifragilisticexpialidocous", 1),
121 Arguments.of("pneumonoultramicroscopicsilicovolcanoconiosiss", "pneumonoultramicroscopicsilicovolcanoconiosis", 1),
122 Arguments.of("abcdefg", "gfedcba", 6),
123 Arguments.of("xyxyxyxyxy", "yxyxyxyxyx", 2),
124 Arguments.of("aaaaabbbbbccccc", "cccccbbbbbaaaaa", 10),
125 Arguments.of("thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsovrethelazydog", 1),
126 Arguments.of("antidisestablishmentarianism", "antidisestablishmentarianisn", 1)
127 );
128 }
129
130 static Stream<Arguments> unlimitedDamerauLevenshteinDistanceTestCases_SimilarityInput() {
131 return SimilarityInputTest.similarityInputs()
132 .flatMap(cls -> unlimitedDamerauLevenshteinDistanceTestCases().map(arguments -> {
133 final Object[] values = Arrays.copyOf(arguments.get(), arguments.get().length + 1);
134 values[values.length - 1] = cls;
135 return Arguments.of(values);
136 }));
137 }
138
139 @ParameterizedTest(name = "DamerauLevenshteinDistance.unlimitedCompare(\"{0}\", \"{1}\") should return {2}")
140 @MethodSource("unlimitedDamerauLevenshteinDistanceTestCases")
141 void testCalculateDamerauLevenshteinDistance(final String left, final String right, final int expectedDistance) {
142 final int leftRightDistance = defaultInstance.apply(left, right);
143 final int rightLeftDistance = defaultInstance.apply(right, left);
144 assertEquals(expectedDistance, leftRightDistance);
145 assertEquals(expectedDistance, rightLeftDistance);
146 }
147
148 @ParameterizedTest(name = "DamerauLevenshteinDistance.limitedCompare(\"{0}\", \"{1}\") should return {2}")
149 @MethodSource("limitedDamerauLevenshteinDistanceTestCases")
150 void testCalculateDamerauLevenshteinDistance(final String left, final String right, final int threshold, final int expectedDistance) {
151 final DamerauLevenshteinDistance instance = new DamerauLevenshteinDistance(threshold);
152 final int leftRightDistance = instance.apply(left, right);
153 final int rightLeftDistance = instance.apply(right, left);
154 assertEquals(expectedDistance, leftRightDistance);
155 assertEquals(expectedDistance, rightLeftDistance);
156 }
157
158 @ParameterizedTest(name = "DamerauLevenshteinDistance.unlimitedCompare(\"{0}\", \"{1}\") should return {2} ({3})")
159 @MethodSource("unlimitedDamerauLevenshteinDistanceTestCases_SimilarityInput")
160 void testCalculateDamerauLevenshteinDistance_SimilarityInput(final String left, final String right, final int expectedDistance, final Class<?> cls) {
161 final SimilarityInput<Object> leftInput = SimilarityInputTest.build(cls, left);
162 final SimilarityInput<Object> rightInput = SimilarityInputTest.build(cls, right);
163 final int leftRightDistance = defaultInstance.apply(leftInput, rightInput);
164 final int rightLeftDistance = defaultInstance.apply(rightInput, leftInput);
165 assertEquals(expectedDistance, leftRightDistance);
166 assertEquals(expectedDistance, rightLeftDistance);
167 }
168
169 @ParameterizedTest(name = "DamerauLevenshteinDistance.limitedCompare(\"{0}\", \"{1}\") should return {2}")
170 @MethodSource("limitedDamerauLevenshteinDistanceTestCases_SimilarityInput")
171 void testCalculateDamerauLevenshteinDistance_SimilarityInput(final String left, final String right, final int threshold, final int expectedDistance,
172 final Class<?> cls) {
173 final DamerauLevenshteinDistance instance = new DamerauLevenshteinDistance(threshold);
174 final SimilarityInput<Object> leftInput = SimilarityInputTest.build(cls, left);
175 final SimilarityInput<Object> rightInput = SimilarityInputTest.build(cls, right);
176 final int leftRightDistance = instance.apply(leftInput, rightInput);
177 final int rightLeftDistance = instance.apply(rightInput, leftInput);
178 assertEquals(expectedDistance, leftRightDistance);
179 assertEquals(expectedDistance, rightLeftDistance);
180 }
181
182 @Test
183 void testGetThresholdDirectlyAfterObjectInstantiation() {
184 assertNull(defaultInstance.getThreshold());
185 }
186
187 @Test
188 void testGetThresholdIsCorrect() {
189 final DamerauLevenshteinDistance distance = new DamerauLevenshteinDistance(10);
190 assertEquals(10, distance.getThreshold());
191 }
192
193 @Test
194 void testInvalidThresholdThrows() {
195 assertThrows(IllegalArgumentException.class, () -> new DamerauLevenshteinDistance(-1));
196 }
197
198 @Test
199 void testNullInputsThrowLimited() {
200 final DamerauLevenshteinDistance instance = new DamerauLevenshteinDistance(10);
201 assertThrows(IllegalArgumentException.class, () -> instance.apply(null, "test"));
202 assertThrows(IllegalArgumentException.class, () -> instance.apply("test", null));
203 assertThrows(IllegalArgumentException.class, () -> instance.apply(null, SimilarityInput.input("test")));
204 assertThrows(IllegalArgumentException.class, () -> instance.apply(SimilarityInput.input("test"), null));
205 }
206
207 @Test
208 void testNullInputsThrowUnlimited() {
209 assertThrows(IllegalArgumentException.class, () -> defaultInstance.apply(null, "test"));
210 assertThrows(IllegalArgumentException.class, () -> defaultInstance.apply("test", null));
211 assertThrows(IllegalArgumentException.class, () -> defaultInstance.apply(null, SimilarityInput.input("test")));
212 assertThrows(IllegalArgumentException.class, () -> defaultInstance.apply(SimilarityInput.input("test"), null));
213 }
214 }