Source code: com/tripi/asp/test/TestComparator.java
1 /**
2 * ArrowHead ASP Server
3 * This is a source file for the ArrowHead ASP Server - an 100% Java
4 * VBScript interpreter and ASP server.
5 *
6 * For more information, see http://www.tripi.com/arrowhead
7 *
8 * Copyright (C) 2002 Terence Haddock
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25 package com.tripi.asp.test;
26
27 import org.apache.log4j.Category;
28 import junit.framework.*;
29 import jregex.*;
30
31 /**
32 * TestComparator is a class which can compare a string to a template,
33 * including embedded regular expressions.
34 *
35 * @author Terence Haddock
36 */
37 public class TestComparator
38 {
39 /** Debugging category */
40 static final Category DBG = Category.getInstance(TestComparator.class);
41
42 /** Template */
43 String templ;
44
45 /**
46 * Constructor with template.
47 * @param templ Template to use
48 */
49 public TestComparator(String templ)
50 {
51 /** XXX Only temporary */
52 org.apache.log4j.BasicConfigurator.configure();
53 this.templ = templ;
54 }
55
56 /**
57 * Tests if the current string matches the template.
58 * @param str String to test
59 */
60 public boolean matches(String str)
61 {
62 int strIndex = 0;
63 int tmpIndex = 0;
64
65 final Pattern p = new Pattern("[\\^][^\\^\\$]*\\$");
66 Matcher m = p.matcher(templ);
67 MatchIterator mi = m.findAll();
68 MatchResult mr = null;
69 boolean done = !mi.hasMore();
70 if (mi.hasMore()) mr = mi.nextMatch();
71 while (!done)
72 {
73 String regex = mr.toString();
74 if (DBG.isDebugEnabled()) {
75 DBG.debug("Prefix: " + mr.prefix());
76 DBG.debug("Regex: " + regex);
77 DBG.debug("End: " + mr.end());
78 }
79 /* Compare everything up to the regex pattern */
80 int diff = mr.start() - tmpIndex;
81 if (DBG.isDebugEnabled())
82 DBG.debug("Diff: " + diff);
83 if (!simpleMatch(str.substring(strIndex, strIndex + diff),
84 templ.substring(tmpIndex, tmpIndex + diff))) {
85 if (DBG.isDebugEnabled())
86 DBG.debug("Failed simple match");
87 return false;
88 }
89 strIndex += diff;
90 tmpIndex = mr.end();
91 if (DBG.isDebugEnabled()) {
92 DBG.debug("After prefix match");
93 DBG.debug("strIndex: " + strIndex);
94 DBG.debug("tmpIndex: " + tmpIndex);
95 }
96
97 /* Figure out what to match */
98 int nextMatch = templ.length();
99 boolean last;
100 if (mi.hasMore()) {
101 mr = mi.nextMatch();
102 nextMatch = mr.start();
103 last = false;
104 } else {
105 done = true;
106 last = true;
107 }
108 String toFind = templ.substring(tmpIndex, nextMatch);
109 if (DBG.isDebugEnabled()) {
110 DBG.debug("String to find: [" + toFind + "]");
111 }
112 int nextstrIndex;
113 if (last)
114 {
115 nextstrIndex = str.substring(strIndex).lastIndexOf(toFind);
116 if (nextstrIndex == -1) {
117 if (DBG.isDebugEnabled())
118 DBG.debug("Failed to find next string.");
119 return false;
120 }
121 nextstrIndex += strIndex;
122 } else {
123 nextstrIndex = str.substring(strIndex).indexOf(toFind);
124 if (nextstrIndex == -1) {
125 if (DBG.isDebugEnabled())
126 DBG.debug("Failed to find next string.");
127 return false;
128 }
129 nextstrIndex += strIndex;
130 }
131 String subString = str.substring(strIndex, nextstrIndex);
132 /* Here we compare the string to the regex prepared */
133 if (DBG.isDebugEnabled()) {
134 DBG.debug("String to match: [" + subString + "]");
135 }
136 Pattern sp = new Pattern(regex);
137 Matcher sm = sp.matcher(subString);
138 if (!sm.matches()) return false;
139 strIndex = nextstrIndex;
140 }
141 if (!simpleMatch(str.substring(strIndex), templ.substring(tmpIndex)))
142 return false;
143 return true;
144 }
145
146 /**
147 * Internal function which performs a 'simple' match, matching two
148 * strings handling the ^^ escape sequence.
149 * @param str String to compare
150 * @param templ Template to user
151 */
152 public boolean simpleMatch(String str, String templ)
153 {
154 if (DBG.isDebugEnabled()) {
155 DBG.debug("Str: [" + str + "]");
156 DBG.debug("tmp: [" + templ + "]");
157 }
158 final Pattern p = new Pattern("\\^\\^");
159 Replacer r = p.replacer("\\^");
160 String replaced = r.replace(templ);
161 return replaced.equals(str);
162 }
163
164 /**
165 * Test suite
166 * @return tests for this class
167 */
168 public static Test suite()
169 {
170 return new TestSuite(TestComparatorTests.class);
171 }
172
173 /**
174 * Test class which contains tests for the TestComparator class
175 */
176 public static class TestComparatorTests extends TestCase
177 {
178 /**
179 * Constructor.
180 * @param name Test name
181 */
182 public TestComparatorTests(String name)
183 {
184 super(name);
185 }
186
187 /**
188 * Basic test case, matches.
189 */
190 public void testBasicMatch()
191 {
192 String templ = "Hello this is a test.";
193 String input = "Hello this is a test.";
194 TestComparator cmp = new TestComparator(templ);
195 Assert.assertTrue(cmp.matches(input));
196 }
197
198 public void testBasicMatchWithNewlines()
199 {
200 String templ = "Hello this is a test.\nMulti line test\nCha cha cha\n";
201 String input = "Hello this is a test.\nMulti line test\nCha cha cha\n";
202 TestComparator cmp = new TestComparator(templ);
203 Assert.assertTrue(cmp.matches(input));
204 }
205
206 public void testBasicMatchWithCarets()
207 {
208 String templ = "Hello this is a test. ^^ Gotta ^^ match these ^^ chars.";
209 String input = "Hello this is a test. ^ Gotta ^ match these ^ chars.";
210 TestComparator cmp = new TestComparator(templ);
211 Assert.assertTrue(cmp.matches(input));
212 }
213
214 /**
215 * Basic test case, does not match.
216 */
217 public void testBasicNoMatch1()
218 {
219 String templ = "Hello this is a test.";
220 String input = "Hello this is not a test.";
221 TestComparator cmp = new TestComparator(templ);
222 Assert.assertTrue(!cmp.matches(input));
223 }
224
225 public void testBasicNoMatch2()
226 {
227 String templ = "Hello this is a test. Too much in the template.";
228 String input = "Hello this is a test.";
229 TestComparator cmp = new TestComparator(templ);
230 Assert.assertTrue(!cmp.matches(input));
231 }
232
233 public void testBasicNoMatch3()
234 {
235 String templ = "Hello this is a test.";
236 String input = "Hello this is a test. Too little in the template.";
237 TestComparator cmp = new TestComparator(templ);
238 Assert.assertTrue(!cmp.matches(input));
239 }
240
241 public void testBasicNoMatch4()
242 {
243 String templ = "Template has a prefix. Hello this is a test.";
244 String input = "Hello this is a test.";
245 TestComparator cmp = new TestComparator(templ);
246 Assert.assertTrue(!cmp.matches(input));
247 }
248
249
250 public void testBasicNoMatch5()
251 {
252 String templ = "Hello this is a test.";
253 String input = "Input has a prefix. Hello this is a test.";
254 TestComparator cmp = new TestComparator(templ);
255 Assert.assertTrue(!cmp.matches(input));
256 }
257
258 public void testSimpleRegex1()
259 {
260 String templ = "This is a ^[a-zA-Z]*$.";
261 String input = "This is a test.";
262
263 TestComparator cmp = new TestComparator(templ);
264 Assert.assertTrue(cmp.matches(input));
265 }
266
267 public void testSimpleRegex2()
268 {
269 String templ = "This is a ^[a-zA-Z]*$.";
270 String input = "This is a frog.";
271
272 TestComparator cmp = new TestComparator(templ);
273 Assert.assertTrue(cmp.matches(input));
274 }
275
276 public void testSimpleRegex3()
277 {
278 String templ = "This is a ^[a-zA-Z]*$.";
279 String input = "This is a cha cha cha.";
280
281 TestComparator cmp = new TestComparator(templ);
282 Assert.assertTrue(!cmp.matches(input));
283 }
284
285 public void testSimpleRegex4()
286 {
287 String templ = "This is a ^[a-zA-Z]*$.";
288 String input = "This is a 1stplace.";
289
290 TestComparator cmp = new TestComparator(templ);
291 Assert.assertTrue(!cmp.matches(input));
292 }
293
294 public void testSimpleRegex5()
295 {
296 String templ = "This is a ^[a-zA-Z]*$.";
297 String input = "This is a .";
298
299 TestComparator cmp = new TestComparator(templ);
300 Assert.assertTrue(cmp.matches(input));
301 }
302
303 public void testSimpleRegex6()
304 {
305 String templ = "^[a-zA-Z]*$ is a test.";
306 String input = "This is a test.";
307
308 TestComparator cmp = new TestComparator(templ);
309 Assert.assertTrue(cmp.matches(input));
310 }
311
312 public void testSimpleRegex7()
313 {
314 String templ = "This is a ^[a-zA-Z]*$";
315 String input = "This is a test";
316
317 TestComparator cmp = new TestComparator(templ);
318 Assert.assertTrue(cmp.matches(input));
319 }
320
321 public void testMultipleRegex1()
322 {
323 String templ = "^[a-zA-Z]*$ blah ^[0-9]*$ cha cha ^quack|crack$";
324 String input = "qjkej blah 90839829 cha cha quack";
325
326 TestComparator cmp = new TestComparator(templ);
327 Assert.assertTrue(cmp.matches(input));
328 }
329
330 public void testMultipleRegex2()
331 {
332 String templ = "^[a-zA-Z]*$ blah ^[0-9]*$ cha cha ^quack|crack$";
333 String input = "jdjlk blah cha cha crack";
334
335 TestComparator cmp = new TestComparator(templ);
336 Assert.assertTrue(cmp.matches(input));
337 }
338
339 public void testMultipleRegex3()
340 {
341 String templ = "^[a-zA-Z]*$ blah ^[0-9]*$ cha cha ^quack|crack$";
342 String input = "jdjlk blah da90d cha cha crack";
343
344 TestComparator cmp = new TestComparator(templ);
345 Assert.assertTrue(!cmp.matches(input));
346 }
347
348 public void testMultipleRegex4()
349 {
350 String templ = "^[a-zA-Z]*$ blah ^[0-9]*$ cha cha ^quack|crack$";
351 String input = "kjdjkdjkl blh 39089389 cha cha quack";
352
353 TestComparator cmp = new TestComparator(templ);
354 Assert.assertTrue(!cmp.matches(input));
355 }
356 }
357 }
358