1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.codec.language.bm;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotEquals;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTimeout;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.time.Duration;
28 import java.util.Random;
29 import java.util.regex.Pattern;
30
31 import org.apache.commons.codec.AbstractStringEncoderTest;
32 import org.apache.commons.codec.EncoderException;
33 import org.apache.commons.codec.StringEncoder;
34 import org.apache.commons.lang3.StringUtils;
35 import org.junit.jupiter.api.Disabled;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.params.ParameterizedTest;
38 import org.junit.jupiter.params.provider.ValueSource;
39
40
41
42
43 class BeiderMorseEncoderTest extends AbstractStringEncoderTest<StringEncoder> {
44
45 private static final Pattern PIPE_PATTERN = Pattern.compile("\\|");
46
47 private static final char[] TEST_CHARS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'o', 'u' };
48
49 private void assertNotEmpty(final BeiderMorseEncoder bmpm, final String value) throws EncoderException {
50 assertNotEquals("", bmpm.encode(value), value);
51 }
52
53 private BeiderMorseEncoder createGenericApproxEncoder() {
54 final BeiderMorseEncoder encoder = new BeiderMorseEncoder();
55 encoder.setNameType(NameType.GENERIC);
56 encoder.setRuleType(RuleType.APPROX);
57 return encoder;
58 }
59
60 @Override
61 protected StringEncoder createStringEncoder() {
62 return new BeiderMorseEncoder();
63 }
64
65
66
67
68
69 @Test
70 void testAllChars() throws EncoderException {
71 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
72 for (char c = Character.MIN_VALUE; c < Character.MAX_VALUE; c++) {
73 bmpm.encode(Character.toString(c));
74 }
75 }
76
77 @Test
78 void testAsciiEncodeNotEmpty1Letter() throws EncoderException {
79 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
80 for (char c = 'a'; c <= 'z'; c++) {
81 final String value = Character.toString(c);
82 final String valueU = value.toUpperCase();
83 assertNotEmpty(bmpm, value);
84 assertNotEmpty(bmpm, valueU);
85 }
86 }
87
88 @Test
89 void testAsciiEncodeNotEmpty2Letters() throws EncoderException {
90 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
91 for (char c1 = 'a'; c1 <= 'z'; c1++) {
92 for (char c2 = 'a'; c2 <= 'z'; c2++) {
93 final String value = new String(new char[] { c1, c2 });
94 final String valueU = value.toUpperCase();
95 assertNotEmpty(bmpm, value);
96 assertNotEmpty(bmpm, valueU);
97 }
98 }
99 }
100
101 @ParameterizedTest
102 @ValueSource(ints = { 20_000, 100_000, 200_000, 400_000 })
103 void testDQuoteRepeatLarge(final int repeat) throws Exception {
104 final String source = StringUtils.repeat("d'", repeat) + "aaa";
105 assertEquals("(D|a|i|o)-(dD|da|di|do)",
106 BeiderMorseEncoder.builder().setPhoneticEngine(PhoneticEngine.builder().setMaxInputLength(source.length()).get()).get().encode(source));
107 }
108
109 @Test
110 void testEncodeAtzNotEmpty() throws EncoderException {
111 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
112
113 final String[] names = { "\u00e1cz", "\u00e1tz", "Ign\u00e1cz", "Ign\u00e1tz", "Ign\u00e1c" };
114 for (final String name : names) {
115 assertNotEmpty(bmpm, name);
116 }
117 }
118
119
120
121
122
123
124
125 @Test
126 void testEncodeGna() throws EncoderException {
127 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
128 bmpm.encode("gna");
129 }
130
131 @Disabled("For performance testing.")
132 @ParameterizedTest
133 @ValueSource(ints = { 2_000, 8_000, 16_000, 32_000 })
134 void testEncodeLargePerf(final int target) throws EncoderException {
135 final String[] units = { "a", "e", "i", "o", "u", "ai", "ei", "ou", "au", "ie", "tsch", "sch", "zh", "kh", "ye", "yo" };
136 final Random r = new Random(1);
137
138 final BeiderMorseEncoder enc = new BeiderMorseEncoder();
139 final StringBuilder sb = new StringBuilder();
140 while (sb.length() < target) {
141 sb.append(units[r.nextInt(units.length)]);
142 }
143 assertTrue(enc.encode(sb.toString()).length() > 0);
144 }
145
146 @Test
147 void testInvalidLangIllegalArgumentException() {
148 assertThrows(IllegalArgumentException.class, () -> Rule.getInstance(NameType.GENERIC, RuleType.APPROX, "noSuchLanguage"));
149 }
150
151 @Test
152 void testInvalidLangIllegalStateException() {
153 assertThrows(IllegalArgumentException.class, () -> Lang.loadFromResource("thisIsAMadeUpResourceName", Languages.getInstance(NameType.GENERIC)));
154 }
155
156 @Test
157 void testInvalidLanguageIllegalArgumentException() {
158 assertThrows(IllegalArgumentException.class, () -> Languages.getInstance("thereIsNoSuchLanguage"));
159 }
160
161 @Test
162 void testLongestEnglishSurname() {
163 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
164 assertTimeout(Duration.ofMillis(10000L), () -> bmpm.encode("MacGhilleseatheanaich"));
165 }
166
167 @Test
168 void testNegativeIndexForRuleMatchIndexOutOfBoundsException() {
169 final Rule r = new Rule("a", "", "", new Rule.Phoneme("", Languages.ANY_LANGUAGE));
170 assertThrows(IndexOutOfBoundsException.class, () -> r.patternAndContextMatches("bob", -1));
171 }
172
173 @Test
174 void testOOM() throws EncoderException {
175 final String phrase = "200697900'-->�</ bceaeef >aadaabcf\"aedfbff<!--\'-->?>cae" +
176 "cfaaa><?&#<!--</script>&lang&fc;aadeaf?>>&bdquo< cc =\"abff\" /></ afe >" +
177 "<script><!-- f(';< cf aefbeef = \"bfabadcf\" ebbfeedd = fccabeb >";
178
179 final BeiderMorseEncoder encoder = new BeiderMorseEncoder();
180 encoder.setNameType(NameType.GENERIC);
181 encoder.setRuleType(RuleType.EXACT);
182 encoder.setMaxPhonemes(10);
183
184 final String phonemes = encoder.encode(phrase);
185 assertFalse(phonemes.isEmpty());
186
187 final String[] phonemeArr = PIPE_PATTERN.split(phonemes);
188 assertTrue(phonemeArr.length <= 10);
189 }
190
191 @Test
192 void testSetConcat() {
193 final BeiderMorseEncoder bmpm = new BeiderMorseEncoder();
194 bmpm.setConcat(false);
195 assertFalse(bmpm.isConcat(), "Should be able to set concat to false");
196 }
197
198 @Test
199 void testSetNameTypeAsh() {
200 final BeiderMorseEncoder bmpm = new BeiderMorseEncoder();
201 bmpm.setNameType(NameType.ASHKENAZI);
202 assertEquals(NameType.ASHKENAZI, bmpm.getNameType(), "Name type should have been set to ash");
203 }
204
205 @Test
206 void testSetRuleTypeExact() {
207 final BeiderMorseEncoder bmpm = new BeiderMorseEncoder();
208 bmpm.setRuleType(RuleType.EXACT);
209 assertEquals(RuleType.EXACT, bmpm.getRuleType(), "Rule type should have been set to exact");
210 }
211
212 @Test
213 void testSetRuleTypeToRulesIllegalArgumentException() {
214 final BeiderMorseEncoder bmpm = new BeiderMorseEncoder();
215 assertThrows(IllegalArgumentException.class, () -> bmpm.setRuleType(RuleType.RULES));
216 }
217
218
219
220
221
222
223 @Test
224 void testSpeedCheck() throws EncoderException {
225 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
226 final StringBuilder stringBuffer = new StringBuilder();
227 stringBuffer.append(TEST_CHARS[0]);
228 for (int i = 0, j = 1; i < 40; i++, j++) {
229 if (j == TEST_CHARS.length) {
230 j = 0;
231 }
232 bmpm.encode(stringBuffer.toString());
233 stringBuffer.append(TEST_CHARS[j]);
234 }
235 }
236
237 @Test
238 void testSpeedCheck2() throws EncoderException {
239 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
240 final String phrase = "ItstheendoftheworldasweknowitandIfeelfine";
241
242 for (int i = 1; i <= phrase.length(); i++) {
243 bmpm.encode(phrase.subSequence(0, i));
244 }
245 }
246
247 @Test
248 void testSpeedCheck3() throws EncoderException {
249 final BeiderMorseEncoder bmpm = createGenericApproxEncoder();
250 final String phrase = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
251
252 for (int i = 1; i <= phrase.length(); i++) {
253 bmpm.encode(phrase.subSequence(0, i));
254 }
255 }
256 }