001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.lang.text;
019:
020: import java.util.HashMap;
021: import java.util.Map;
022:
023: import org.apache.commons.lang.mutable.MutableObject;
024:
025: import junit.framework.Test;
026: import junit.framework.TestCase;
027: import junit.framework.TestSuite;
028: import junit.textui.TestRunner;
029:
030: /**
031: * Test class for StrSubstitutor.
032: *
033: * @author Oliver Heger
034: * @version $Id: StrSubstitutorTest.java 437554 2006-08-28 06:21:41Z bayard $
035: */
036: public class StrSubstitutorTest extends TestCase {
037:
038: private Map values;
039:
040: /**
041: * Main method.
042: *
043: * @param args command line arguments, ignored
044: */
045: public static void main(String[] args) {
046: TestRunner.run(suite());
047: }
048:
049: /**
050: * Return a new test suite containing this test case.
051: *
052: * @return a new test suite containing this test case
053: */
054: public static Test suite() {
055: TestSuite suite = new TestSuite(StrSubstitutorTest.class);
056: suite.setName("StrSubstitutor Tests");
057: return suite;
058: }
059:
060: protected void setUp() throws Exception {
061: super .setUp();
062: values = new HashMap();
063: values.put("animal", "quick brown fox");
064: values.put("target", "lazy dog");
065: }
066:
067: protected void tearDown() throws Exception {
068: super .tearDown();
069: values = null;
070: }
071:
072: //-----------------------------------------------------------------------
073: /**
074: * Tests simple key replace.
075: */
076: public void testReplaceSimple() {
077: doTestReplace("The quick brown fox jumps over the lazy dog.",
078: "The ${animal} jumps over the ${target}.", true);
079: }
080:
081: /**
082: * Tests simple key replace.
083: */
084: public void testReplaceSolo() {
085: doTestReplace("quick brown fox", "${animal}", false);
086: }
087:
088: /**
089: * Tests replace with no variables.
090: */
091: public void testReplaceNoVariables() {
092: doTestNoReplace("The balloon arrived.");
093: }
094:
095: /**
096: * Tests replace with null.
097: */
098: public void testReplaceNull() {
099: doTestNoReplace(null);
100: }
101:
102: /**
103: * Tests replace with null.
104: */
105: public void testReplaceEmpty() {
106: doTestNoReplace("");
107: }
108:
109: /**
110: * Tests key replace changing map after initialization (not recommended).
111: */
112: public void testReplaceChangedMap() {
113: StrSubstitutor sub = new StrSubstitutor(values);
114: values.put("target", "moon");
115: assertEquals("The quick brown fox jumps over the moon.", sub
116: .replace("The ${animal} jumps over the ${target}."));
117: }
118:
119: /**
120: * Tests unknown key replace.
121: */
122: public void testReplaceUnknownKey() {
123: doTestReplace("The ${person} jumps over the lazy dog.",
124: "The ${person} jumps over the ${target}.", true);
125: }
126:
127: /**
128: * Tests adjacent keys.
129: */
130: public void testReplaceAdjacentAtStart() {
131: values.put("code", "GBP");
132: values.put("amount", "12.50");
133: StrSubstitutor sub = new StrSubstitutor(values);
134: assertEquals("GBP12.50 charged", sub
135: .replace("${code}${amount} charged"));
136: }
137:
138: /**
139: * Tests adjacent keys.
140: */
141: public void testReplaceAdjacentAtEnd() {
142: values.put("code", "GBP");
143: values.put("amount", "12.50");
144: StrSubstitutor sub = new StrSubstitutor(values);
145: assertEquals("Amount is GBP12.50", sub
146: .replace("Amount is ${code}${amount}"));
147: }
148:
149: /**
150: * Tests simple recursive replace.
151: */
152: public void testReplaceRecursive() {
153: values.put("animal", "${critter}");
154: values.put("target", "${pet}");
155: values.put("pet", "${petCharacteristic} dog");
156: values.put("petCharacteristic", "lazy");
157: values.put("critter",
158: "${critterSpeed} ${critterColor} ${critterType}");
159: values.put("critterSpeed", "quick");
160: values.put("critterColor", "brown");
161: values.put("critterType", "fox");
162: doTestReplace("The quick brown fox jumps over the lazy dog.",
163: "The ${animal} jumps over the ${target}.", true);
164: }
165:
166: /**
167: * Tests escaping.
168: */
169: public void testReplaceEscaping() {
170: doTestReplace("The ${animal} jumps over the lazy dog.",
171: "The $${animal} jumps over the ${target}.", true);
172: }
173:
174: /**
175: * Tests escaping.
176: */
177: public void testReplaceSoloEscaping() {
178: doTestReplace("${animal}", "$${animal}", false);
179: }
180:
181: /**
182: * Tests complex escaping.
183: */
184: public void testReplaceComplexEscaping() {
185: doTestReplace(
186: "The ${quick brown fox} jumps over the lazy dog.",
187: "The $${${animal}} jumps over the ${target}.", true);
188: }
189:
190: /**
191: * Tests when no prefix or suffix.
192: */
193: public void testReplaceNoPefixNoSuffix() {
194: doTestReplace("The animal jumps over the lazy dog.",
195: "The animal jumps over the ${target}.", true);
196: }
197:
198: /**
199: * Tests when no incomplete prefix.
200: */
201: public void testReplaceIncompletePefix() {
202: doTestReplace("The {animal} jumps over the lazy dog.",
203: "The {animal} jumps over the ${target}.", true);
204: }
205:
206: /**
207: * Tests when prefix but no suffix.
208: */
209: public void testReplacePrefixNoSuffix() {
210: doTestReplace(
211: "The ${animal jumps over the ${target} lazy dog.",
212: "The ${animal jumps over the ${target} ${target}.",
213: true);
214: }
215:
216: /**
217: * Tests when suffix but no prefix.
218: */
219: public void testReplaceNoPrefixSuffix() {
220: doTestReplace("The animal} jumps over the lazy dog.",
221: "The animal} jumps over the ${target}.", true);
222: }
223:
224: /**
225: * Tests when no variable name.
226: */
227: public void testReplaceEmptyKeys() {
228: doTestReplace("The ${} jumps over the lazy dog.",
229: "The ${} jumps over the ${target}.", true);
230: }
231:
232: /**
233: * Tests replace creates output same as input.
234: */
235: public void testReplaceToIdentical() {
236: values.put("animal", "$${${thing}}");
237: values.put("thing", "animal");
238: doTestReplace("The ${animal} jumps.", "The ${animal} jumps.",
239: true);
240: }
241:
242: /**
243: * Tests a cyclic replace operation.
244: * The cycle should be detected and cause an exception to be thrown.
245: */
246: public void testCyclicReplacement() {
247: Map map = new HashMap();
248: map.put("animal", "${critter}");
249: map.put("target", "${pet}");
250: map.put("pet", "${petCharacteristic} dog");
251: map.put("petCharacteristic", "lazy");
252: map.put("critter",
253: "${critterSpeed} ${critterColor} ${critterType}");
254: map.put("critterSpeed", "quick");
255: map.put("critterColor", "brown");
256: map.put("critterType", "${animal}");
257: StrSubstitutor sub = new StrSubstitutor(map);
258: try {
259: sub.replace("The ${animal} jumps over the ${target}.");
260: fail("Cyclic replacement was not detected!");
261: } catch (IllegalStateException ex) {
262: // expected
263: }
264: }
265:
266: /**
267: * Tests interpolation with weird boundary patterns.
268: */
269: public void testReplaceWeirdPattens() {
270: doTestNoReplace("");
271: doTestNoReplace("${}");
272: doTestNoReplace("${ }");
273: doTestNoReplace("${\t}");
274: doTestNoReplace("${\n}");
275: doTestNoReplace("${\b}");
276: doTestNoReplace("${");
277: doTestNoReplace("$}");
278: doTestNoReplace("}");
279: doTestNoReplace("${}$");
280: doTestNoReplace("${${");
281: doTestNoReplace("${${}}");
282: doTestNoReplace("${$${}}");
283: doTestNoReplace("${$$${}}");
284: doTestNoReplace("${$$${$}}");
285: doTestNoReplace("${${}}");
286: doTestNoReplace("${${ }}");
287: }
288:
289: /**
290: * Tests simple key replace.
291: */
292: public void testReplacePartialString_noReplace() {
293: StrSubstitutor sub = new StrSubstitutor();
294: assertEquals("${animal} jumps", sub.replace(
295: "The ${animal} jumps over the ${target}.", 4, 15));
296: }
297:
298: //-----------------------------------------------------------------------
299: /**
300: * Tests protected.
301: */
302: public void testResolveVariable() {
303: final StrBuilder builder = new StrBuilder("Hi ${name}!");
304: Map map = new HashMap();
305: map.put("name", "commons");
306: StrSubstitutor sub = new StrSubstitutor(map) {
307: protected String resolveVariable(String variableName,
308: StrBuilder buf, int startPos, int endPos) {
309: assertEquals("name", variableName);
310: assertSame(builder, buf);
311: assertEquals(3, startPos);
312: assertEquals(10, endPos);
313: return "jakarta";
314: }
315: };
316: sub.replaceIn(builder);
317: assertEquals("Hi jakarta!", builder.toString());
318: }
319:
320: //-----------------------------------------------------------------------
321: /**
322: * Tests constructor.
323: */
324: public void testConstructorNoArgs() {
325: StrSubstitutor sub = new StrSubstitutor();
326: assertEquals("Hi ${name}", sub.replace("Hi ${name}"));
327: }
328:
329: /**
330: * Tests constructor.
331: */
332: public void testConstructorMapPrefixSuffix() {
333: Map map = new HashMap();
334: map.put("name", "commons");
335: StrSubstitutor sub = new StrSubstitutor(map, "<", ">");
336: assertEquals("Hi < commons", sub.replace("Hi $< <name>"));
337: }
338:
339: /**
340: * Tests constructor.
341: */
342: public void testConstructorMapFull() {
343: Map map = new HashMap();
344: map.put("name", "commons");
345: StrSubstitutor sub = new StrSubstitutor(map, "<", ">", '!');
346: assertEquals("Hi < commons", sub.replace("Hi !< <name>"));
347: }
348:
349: //-----------------------------------------------------------------------
350: /**
351: * Tests get set.
352: */
353: public void testGetSetEscape() {
354: StrSubstitutor sub = new StrSubstitutor();
355: assertEquals('$', sub.getEscapeChar());
356: sub.setEscapeChar('<');
357: assertEquals('<', sub.getEscapeChar());
358: }
359:
360: /**
361: * Tests get set.
362: */
363: public void testGetSetPrefix() {
364: StrSubstitutor sub = new StrSubstitutor();
365: assertEquals(
366: true,
367: sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
368: sub.setVariablePrefix('<');
369: assertEquals(
370: true,
371: sub.getVariablePrefixMatcher() instanceof StrMatcher.CharMatcher);
372:
373: sub.setVariablePrefix("<<");
374: assertEquals(
375: true,
376: sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
377: try {
378: sub.setVariablePrefix((String) null);
379: fail();
380: } catch (IllegalArgumentException ex) {
381: // expected
382: }
383: assertEquals(
384: true,
385: sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher);
386:
387: StrMatcher matcher = StrMatcher.commaMatcher();
388: sub.setVariablePrefixMatcher(matcher);
389: assertSame(matcher, sub.getVariablePrefixMatcher());
390: try {
391: sub.setVariablePrefixMatcher((StrMatcher) null);
392: fail();
393: } catch (IllegalArgumentException ex) {
394: // expected
395: }
396: assertSame(matcher, sub.getVariablePrefixMatcher());
397: }
398:
399: /**
400: * Tests get set.
401: */
402: public void testGetSetSuffix() {
403: StrSubstitutor sub = new StrSubstitutor();
404: assertEquals(
405: true,
406: sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
407: sub.setVariableSuffix('<');
408: assertEquals(
409: true,
410: sub.getVariableSuffixMatcher() instanceof StrMatcher.CharMatcher);
411:
412: sub.setVariableSuffix("<<");
413: assertEquals(
414: true,
415: sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
416: try {
417: sub.setVariableSuffix((String) null);
418: fail();
419: } catch (IllegalArgumentException ex) {
420: // expected
421: }
422: assertEquals(
423: true,
424: sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher);
425:
426: StrMatcher matcher = StrMatcher.commaMatcher();
427: sub.setVariableSuffixMatcher(matcher);
428: assertSame(matcher, sub.getVariableSuffixMatcher());
429: try {
430: sub.setVariableSuffixMatcher((StrMatcher) null);
431: fail();
432: } catch (IllegalArgumentException ex) {
433: // expected
434: }
435: assertSame(matcher, sub.getVariableSuffixMatcher());
436: }
437:
438: //-----------------------------------------------------------------------
439: /**
440: * Tests static.
441: */
442: public void testStaticReplace() {
443: Map map = new HashMap();
444: map.put("name", "commons");
445: assertEquals("Hi commons!", StrSubstitutor.replace(
446: "Hi ${name}!", map));
447: }
448:
449: /**
450: * Tests static.
451: */
452: public void testStaticReplacePrefixSuffix() {
453: Map map = new HashMap();
454: map.put("name", "commons");
455: assertEquals("Hi commons!", StrSubstitutor.replace(
456: "Hi <name>!", map, "<", ">"));
457: }
458:
459: /**
460: * Tests interpolation with system properties.
461: */
462: public void testStaticReplaceSystemProperties() {
463: StrBuilder buf = new StrBuilder();
464: buf.append("Hi ").append(System.getProperty("user.name"));
465: buf.append(", you are working with ");
466: buf.append(System.getProperty("os.name"));
467: buf.append(", your home directory is ");
468: buf.append(System.getProperty("user.home")).append('.');
469: assertEquals(buf.toString(), StrSubstitutor
470: .replaceSystemProperties("Hi ${user.name}, you are "
471: + "working with ${os.name}, your home "
472: + "directory is ${user.home}."));
473: }
474:
475: //-----------------------------------------------------------------------
476: private void doTestReplace(String expectedResult,
477: String replaceTemplate, boolean substring) {
478: String expectedShortResult = expectedResult.substring(1,
479: expectedResult.length() - 1);
480: StrSubstitutor sub = new StrSubstitutor(values);
481:
482: // replace using String
483: assertEquals(expectedResult, sub.replace(replaceTemplate));
484: if (substring) {
485: assertEquals(expectedShortResult, sub.replace(
486: replaceTemplate, 1, replaceTemplate.length() - 2));
487: }
488:
489: // replace using char[]
490: char[] chars = replaceTemplate.toCharArray();
491: assertEquals(expectedResult, sub.replace(chars));
492: if (substring) {
493: assertEquals(expectedShortResult, sub.replace(chars, 1,
494: chars.length - 2));
495: }
496:
497: // replace using StringBuffer
498: StringBuffer buf = new StringBuffer(replaceTemplate);
499: assertEquals(expectedResult, sub.replace(buf));
500: if (substring) {
501: assertEquals(expectedShortResult, sub.replace(buf, 1, buf
502: .length() - 2));
503: }
504:
505: // replace using StrBuilder
506: StrBuilder bld = new StrBuilder(replaceTemplate);
507: assertEquals(expectedResult, sub.replace(bld));
508: if (substring) {
509: assertEquals(expectedShortResult, sub.replace(bld, 1, bld
510: .length() - 2));
511: }
512:
513: // replace using object
514: MutableObject obj = new MutableObject(replaceTemplate); // toString returns template
515: assertEquals(expectedResult, sub.replace(obj));
516:
517: // replace in StringBuffer
518: buf = new StringBuffer(replaceTemplate);
519: assertEquals(true, sub.replaceIn(buf));
520: assertEquals(expectedResult, buf.toString());
521: if (substring) {
522: buf = new StringBuffer(replaceTemplate);
523: assertEquals(true, sub.replaceIn(buf, 1, buf.length() - 2));
524: assertEquals(expectedResult, buf.toString()); // expect full result as remainder is untouched
525: }
526:
527: // replace in StrBuilder
528: bld = new StrBuilder(replaceTemplate);
529: assertEquals(true, sub.replaceIn(bld));
530: assertEquals(expectedResult, bld.toString());
531: if (substring) {
532: bld = new StrBuilder(replaceTemplate);
533: assertEquals(true, sub.replaceIn(bld, 1, bld.length() - 2));
534: assertEquals(expectedResult, bld.toString()); // expect full result as remainder is untouched
535: }
536: }
537:
538: private void doTestNoReplace(String replaceTemplate) {
539: StrSubstitutor sub = new StrSubstitutor(values);
540:
541: if (replaceTemplate == null) {
542: assertEquals(null, sub.replace((String) null));
543: assertEquals(null, sub.replace((String) null, 0, 100));
544: assertEquals(null, sub.replace((char[]) null));
545: assertEquals(null, sub.replace((char[]) null, 0, 100));
546: assertEquals(null, sub.replace((StringBuffer) null));
547: assertEquals(null, sub.replace((StringBuffer) null, 0, 100));
548: assertEquals(null, sub.replace((StrBuilder) null));
549: assertEquals(null, sub.replace((StrBuilder) null, 0, 100));
550: assertEquals(null, sub.replace((Object) null));
551: assertEquals(false, sub.replaceIn((StringBuffer) null));
552: assertEquals(false, sub.replaceIn((StringBuffer) null, 0,
553: 100));
554: assertEquals(false, sub.replaceIn((StrBuilder) null));
555: assertEquals(false, sub
556: .replaceIn((StrBuilder) null, 0, 100));
557: } else {
558: assertEquals(replaceTemplate, sub.replace(replaceTemplate));
559: StrBuilder bld = new StrBuilder(replaceTemplate);
560: assertEquals(false, sub.replaceIn(bld));
561: assertEquals(replaceTemplate, bld.toString());
562: }
563: }
564:
565: }
|