http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java new file mode 100755 index 0000000..7143b97 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java @@ -0,0 +1,748 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.utils; + +import static org.apache.juneau.TestUtils.*; +import static org.apache.juneau.internal.StringUtils.*; +import static org.junit.Assert.*; + +import java.math.*; +import java.util.*; +import java.util.concurrent.atomic.*; + +import org.apache.juneau.*; +import org.apache.juneau.json.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.serializer.*; +import org.apache.juneau.transforms.*; +import org.junit.*; + +@SuppressWarnings("javadoc") +public class StringUtilsTest { + + //==================================================================================================== + // isNumeric(String,Class) + // parseNumber(String,Class) + //==================================================================================================== + @Test + public void testParseNumber() throws Exception { + + // Integers + assertTrue(isNumeric("123")); + assertEquals(123, parseNumber("123", null)); + assertEquals(123, parseNumber("123", Integer.class)); + assertEquals((short)123, parseNumber("123", Short.class)); + assertEquals((long)123, parseNumber("123", Long.class)); + + assertTrue(isNumeric("0123")); + assertEquals(0123, parseNumber("0123", null)); + + assertTrue(isNumeric("-0123")); + assertEquals(-0123, parseNumber("-0123", null)); + + // Hexadecimal + assertTrue(isNumeric("0x123")); + assertEquals(0x123, parseNumber("0x123", null)); + + assertTrue(isNumeric("-0x123")); + assertEquals(-0x123, parseNumber("-0x123", null)); + + assertTrue(isNumeric("0X123")); + assertEquals(0X123, parseNumber("0X123", null)); + + assertTrue(isNumeric("-0X123")); + assertEquals(-0X123, parseNumber("-0X123", null)); + + assertTrue(isNumeric("#123")); + assertEquals(0x123, parseNumber("#123", null)); + + assertTrue(isNumeric("-#123")); + assertEquals(-0x123, parseNumber("-#123", null)); + + assertFalse(isNumeric("x123")); + assertFalse(isNumeric("0x123x")); + + // Decimal + assertTrue(isNumeric("0.123")); + assertEquals(0.123f, parseNumber("0.123", null)); + + assertTrue(isNumeric("-0.123")); + assertEquals(-0.123f, parseNumber("-0.123", null)); + + assertTrue(isNumeric(".123")); + assertEquals(.123f, parseNumber(".123", null)); + + assertTrue(isNumeric("-.123")); + assertEquals(-.123f, parseNumber("-.123", null)); + + assertFalse(isNumeric("0.123.4")); + + assertTrue(isNumeric("0.84370821629078d")); + assertEquals(0.84370821629078d, parseNumber("0.84370821629078d", null)); + + assertTrue(isNumeric("84370821629078.8437d")); + assertEquals(84370821629078.8437d, parseNumber("84370821629078.8437d", null)); + + assertTrue(isNumeric("0.16666666666666666d")); + assertEquals(0.16666666666666666d, parseNumber("0.16666666666666666d", null)); + + assertTrue(isNumeric("0.16666666f")); + assertEquals(0.16666666f, parseNumber("0.16666666f", null)); + + assertTrue(isNumeric("0.16666666d")); + assertEquals(0.16666666f, parseNumber("0.16666666d", null)); + + assertTrue(isNumeric("3.140000000000000124344978758017532527446746826171875d")); + assertEquals(3.14f, parseNumber("3.140000000000000124344978758017532527446746826171875d", null)); + + assertTrue(isNumeric("12345.678f")); + assertEquals(1.2345678e4f, parseNumber("12345.678f", null)); + + // Scientific notation + assertTrue(isNumeric("1e1")); + assertEquals(1e1f, parseNumber("1e1", null)); + + assertTrue(isNumeric("1e+1")); + assertEquals(1e+1f, parseNumber("1e+1", null)); + + assertTrue(isNumeric("1e-1")); + assertEquals(1e-1f, parseNumber("1e-1", null)); + + assertTrue(isNumeric("1.1e1")); + assertEquals(1.1e1f, parseNumber("1.1e1", null)); + + assertTrue(isNumeric("1.1e+1")); + assertEquals(1.1e+1f, parseNumber("1.1e+1", null)); + + assertTrue(isNumeric("1.1e-1")); + assertEquals(1.1e-1f, parseNumber("1.1e-1", null)); + + assertTrue(isNumeric(".1e1")); + assertEquals(.1e1f, parseNumber(".1e1", null)); + + assertTrue(isNumeric(".1e+1")); + assertEquals(.1e+1f, parseNumber(".1e+1", null)); + + assertTrue(isNumeric(".1e-1")); + assertEquals(.1e-1f, parseNumber(".1e-1", null)); + + // Hexadecimal + scientific + assertTrue(isNumeric("0x123e1")); + assertEquals(0x123e1, parseNumber("0x123e1", null)); + + try { + parseNumber("x", Number.class); + fail(); + } catch (ParseException e) { + assertTrue(e.getCause() instanceof NumberFormatException); + } + + try { + parseNumber("x", null); + fail(); + } catch (ParseException e) { + assertTrue(e.getCause() instanceof NumberFormatException); + } + + try { + parseNumber("x", BadNumber.class); + fail(); + } catch (ParseException e) { + assertTrue(e.getLocalizedMessage().startsWith("Unsupported Number type")); + } + } + + @SuppressWarnings("serial") + private abstract static class BadNumber extends Number {} + + //==================================================================================================== + // parseNumber(ParserReader,Class) + //==================================================================================================== + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testParseNumberFromReader() throws Exception { + ParserReader in; + Number n; + + for (Class c : new Class[]{ Integer.class, Double.class, Float.class, Long.class, Short.class, Byte.class, BigInteger.class, BigDecimal.class, Number.class, AtomicInteger.class, AtomicLong.class}) { + in = new ParserReader(new ParserPipe("123'")); + n = parseNumber(in, c); + assertTrue(c.isInstance(n)); + assertEquals(123, n.intValue()); + } + } + + //==================================================================================================== + // test - Basic tests + //==================================================================================================== + @Test + public void testNumberRanges() throws Exception { + String s; + + // An integer range is -2,147,483,648 to 2,147,483,647 + + assertFalse(isNumeric(null)); + assertFalse(isNumeric("")); + assertFalse(isNumeric("x")); + + s = "-2147483648"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Integer); + assertEquals(-2147483648, parseNumber(s, null)); + + s = "2147483647"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Integer); + assertEquals(2147483647, parseNumber(s, null)); + + s = "-2147483649"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Long); + assertEquals(-2147483649L, parseNumber(s, null)); + + s = "2147483648"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Long); + assertEquals(2147483648L, parseNumber(s, null)); + + // An long range is -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807 + + s = "-9223372036854775808"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Long); + assertEquals(-9223372036854775808L, parseNumber(s, null)); + + s = "9223372036854775807"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Long); + assertEquals(9223372036854775807L, parseNumber(s, null)); + + // Anything that falls outside this range should be a double. + + s = "-9223372036854775809"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Double); + assertEquals(-9223372036854775808L, parseNumber(s, null).longValue()); + assertEquals(-9.223372036854776E18, parseNumber(s, null)); + + s = "9223372036854775808"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Double); + assertEquals(9223372036854775807L, parseNumber(s, null).longValue()); + assertEquals(9.223372036854776E18, parseNumber(s, null)); + + // Check case where string is longer than 20 characters since it's a different code path. + + s = "-123456789012345678901"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Double); + assertEquals(-9223372036854775808L, parseNumber(s, null).longValue()); + assertEquals(-1.2345678901234568E20, parseNumber(s, null)); + + s = "123456789012345678901"; + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Double); + assertEquals(9223372036854775807L, parseNumber(s, null).longValue()); + assertEquals(1.2345678901234568E20, parseNumber(s, null)); + + // Autodetected floating point numbers smaller than Float.MAX_VALUE + s = String.valueOf(Float.MAX_VALUE / 2); + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Float); + assertEquals(1.7014117E38f, parseNumber(s, null)); + + s = String.valueOf((-Float.MAX_VALUE) / 2); + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Float); + assertEquals(-1.7014117E38f, parseNumber(s, null)); + + // Autodetected floating point numbers larger than Float.MAX_VALUE + s = String.valueOf((double)Float.MAX_VALUE * 2); + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Double); + assertEquals("6.805646932770577E38", parseNumber(s, null).toString()); + + s = String.valueOf((double)Float.MAX_VALUE * -2); + assertTrue(isNumeric(s)); + assertTrue(parseNumber(s, null) instanceof Double); + assertEquals("-6.805646932770577E38", parseNumber(s, null).toString()); + + s = String.valueOf("214748364x"); + assertFalse(isNumeric(s)); + try { + parseNumber(s, Number.class); + } catch (ParseException e) {} + + s = String.valueOf("2147483640x"); + assertFalse(isNumeric(s)); + try { + parseNumber(s, Long.class); + } catch (ParseException e) {} + + + } + + //==================================================================================================== + // testReplaceVars + //==================================================================================================== + @Test + public void testReplaceVars() throws Exception { + ObjectMap m = new ObjectMap("{a:'A',b:1,c:true,d:'{e}',e:'E{f}E',f:'F',g:'{a}',h:'a',i:null}"); + + String s = "xxx"; + assertEquals("xxx", replaceVars(s, m)); + + s = "{a}"; + assertEquals("A", replaceVars(s, m)); + s = "{a}{a}"; + assertEquals("AA", replaceVars(s, m)); + s = "x{a}x"; + assertEquals("xAx", replaceVars(s, m)); + s = "x{a}x{a}x"; + assertEquals("xAxAx", replaceVars(s, m)); + + s = "{b}"; + assertEquals("1", replaceVars(s, m)); + s = "{b}{b}"; + assertEquals("11", replaceVars(s, m)); + s = "x{b}x"; + assertEquals("x1x", replaceVars(s, m)); + s = "x{b}x{b}x"; + assertEquals("x1x1x", replaceVars(s, m)); + + s = "{c}"; + assertEquals("true", replaceVars(s, m)); + s = "{c}{c}"; + assertEquals("truetrue", replaceVars(s, m)); + s = "x{c}x{c}x"; + assertEquals("xtruextruex", replaceVars(s, m)); + + s = "{d}"; + assertEquals("EFE", replaceVars(s, m)); + s = "{d}{d}"; + assertEquals("EFEEFE", replaceVars(s, m)); + s = "x{d}x"; + assertEquals("xEFEx", replaceVars(s, m)); + s = "x{d}x{d}x"; + assertEquals("xEFExEFEx", replaceVars(s, m)); + + s = "{g}"; + assertEquals("A", replaceVars(s, m)); + s = "{g}{g}"; + assertEquals("AA", replaceVars(s, m)); + s = "x{g}x"; + assertEquals("xAx", replaceVars(s, m)); + s = "x{g}x{g}x"; + assertEquals("xAxAx", replaceVars(s, m)); + + s = "{x}"; + assertEquals("{x}", replaceVars(s, m)); + s = "{x}{x}"; + assertEquals("{x}{x}", replaceVars(s, m)); + s = "x{x}x{x}x"; + assertEquals("x{x}x{x}x", replaceVars(s, m)); + + s = "{{g}}"; + assertEquals("{A}", replaceVars(s, m)); + s = "{{h}}"; + assertEquals("A", replaceVars(s, m)); + + s = "{{i}}"; + assertEquals("{}", replaceVars(s, m)); + s = "{}"; + assertEquals("{}", replaceVars(s, m)); + } + + //==================================================================================================== + // isFloat(String) + //==================================================================================================== + @Test + public void testisFloat() throws Exception { + String[] valid = { + "+1.0", + "-1.0", + ".0", + "NaN", + "Infinity", + "1e1", + "-1e-1", + "+1e+1", + "-1.1e-1", + "+1.1e+1", + "1.1f", + "1.1F", + "1.1d", + "1.1D", + "0x1.fffffffffffffp1023", + "0x1.FFFFFFFFFFFFFP1023", + }; + for (String s : valid) + assertTrue(isFloat(s)); + + String[] invalid = { + null, + "", + "a", + "+", + "-", + ".", + "a", + "+a", + "11a", + }; + for (String s : invalid) + assertFalse(isFloat(s)); + } + + //==================================================================================================== + // isDecimal(String) + //==================================================================================================== + @Test + public void testisDecimal() throws Exception { + String[] valid = { + "+1", + "-1", + "0x123", + "0X123", + "0xdef", + "0XDEF", + "#def", + "#DEF", + "0123", + }; + for (String s : valid) + assertTrue(isDecimal(s)); + + String[] invalid = { + null, + "", + "a", + "+", + "-", + ".", + "0xdeg", + "0XDEG", + "#deg", + "#DEG", + "0128", + "012A", + }; + for (String s : invalid) + assertFalse(isDecimal(s)); + } + + //==================================================================================================== + // join(Object[],String) + // join(int[],String) + // join(Collection,String) + // join(Object[],char) + // join(int[],char) + // join(Collection,char) + //==================================================================================================== + @Test + public void testJoin() throws Exception { + assertNull(join((Object[])null, ",")); + assertEquals("1", join(new Object[]{1}, ",")); + assertEquals("1,2", join(new Object[]{1,2}, ",")); + + assertNull(join((int[])null, ",")); + assertEquals("1", join(new int[]{1}, ",")); + assertEquals("1,2", join(new int[]{1,2}, ",")); + + assertNull(join((Collection<?>)null, ",")); + assertEquals("1", join(Arrays.asList(new Integer[]{1}), ",")); + assertEquals("1,2", join(Arrays.asList(new Integer[]{1,2}), ",")); + + assertNull(join((Object[])null, ',')); + assertEquals("1", join(new Object[]{1}, ',')); + assertEquals("1,2", join(new Object[]{1,2}, ',')); + + assertNull(join((int[])null, ',')); + assertEquals("1", join(new int[]{1}, ',')); + assertEquals("1,2", join(new int[]{1,2}, ',')); + + assertNull(join((Collection<?>)null, ',')); + assertEquals("1", join(Arrays.asList(new Integer[]{1}), ',')); + assertEquals("1,2", join(Arrays.asList(new Integer[]{1,2}), ',')); + } + + //==================================================================================================== + // split(String,char) + //==================================================================================================== + @Test + public void testSplit() throws Exception { + String[] r; + + assertNull(split((String)null)); + assertObjectEquals("[]", split("")); + assertObjectEquals("['1']", split("1")); + assertObjectEquals("['1','2']", split("1,2")); + assertObjectEquals("['1,2']", split("1\\,2")); + + r = split("1\\\\,2"); + assertEquals("1\\", r[0]); + assertEquals("2", r[1]); + + r = split("1\\\\\\,2"); + assertEquals(1, r.length); + assertEquals("1\\,2", r[0]); + + r = split("1,2\\"); + assertEquals("2\\", r[1]); + + r = split("1,2\\\\"); + assertEquals("2\\", r[1]); + + r = split("1,2\\,"); + assertEquals("2,", r[1]); + + r = split("1,2\\\\,"); + assertEquals("2\\", r[1]); + assertEquals("", r[2]); + } + + //==================================================================================================== + // nullIfEmpty(String) + //==================================================================================================== + @Test + public void testNullIfEmpty() throws Exception { + assertNull(nullIfEmpty(null)); + assertNull(nullIfEmpty("")); + assertNotNull(nullIfEmpty("x")); + } + + //==================================================================================================== + // unescapeChars(String,char[],char) + //==================================================================================================== + @Test + public void testUnescapeChars() throws Exception { + char[] toEscape = {'\\',',','|'}; + char escape = '\\'; + + assertNull(unEscapeChars(null, toEscape, escape)); + assertEquals("xxx", unEscapeChars("xxx", new char[0], escape)); + assertEquals("xxx", unEscapeChars("xxx", null, escape)); + assertEquals("xxx", unEscapeChars("xxx", toEscape, (char)0)); + + assertEquals("xxx", unEscapeChars("xxx", toEscape, escape)); + assertEquals("x,xx", unEscapeChars("x\\,xx", toEscape, escape)); + assertEquals("x\\xx", unEscapeChars("x\\xx", toEscape, escape)); + assertEquals("x\\,xx", unEscapeChars("x\\\\,xx", toEscape, escape)); + assertEquals("x\\,xx", unEscapeChars("x\\\\\\,xx", toEscape, escape)); + assertEquals("\\", unEscapeChars("\\", toEscape, escape)); + assertEquals(",", unEscapeChars("\\,", toEscape, escape)); + assertEquals("|", unEscapeChars("\\|", toEscape, escape)); + + toEscape = new char[] {',','|'}; + assertEquals("x\\\\xx", unEscapeChars("x\\\\xx", toEscape, escape)); + } + + //==================================================================================================== + // decodeHex(String) + //==================================================================================================== + @Test + public void testDecodeHex() throws Exception { + assertNull(decodeHex(null)); + assertEquals("19azAZ", decodeHex("19azAZ")); + assertEquals("[0][1][ffff]", decodeHex("\u0000\u0001\uFFFF")); + } + + //==================================================================================================== + // startsWith(String,char) + //==================================================================================================== + @Test + public void testStartsWith() throws Exception { + assertFalse(startsWith(null, 'a')); + assertFalse(startsWith("", 'a')); + assertTrue(startsWith("a", 'a')); + assertTrue(startsWith("ab", 'a')); + } + + //==================================================================================================== + // endsWith(String,char) + //==================================================================================================== + @Test + public void testEndsWith() throws Exception { + assertFalse(endsWith(null, 'a')); + assertFalse(endsWith("", 'a')); + assertTrue(endsWith("a", 'a')); + assertTrue(endsWith("ba", 'a')); + } + + //==================================================================================================== + // base64EncodeToString(String) + // base64DecodeToString(String) + //==================================================================================================== + @Test + public void testBase64EncodeToString() throws Exception { + String s = null; + + assertEquals(s, base64DecodeToString(base64EncodeToString(s))); + s = ""; + assertEquals(s, base64DecodeToString(base64EncodeToString(s))); + s = "foobar"; + assertEquals(s, base64DecodeToString(base64EncodeToString(s))); + s = "\u0000\uffff"; + assertEquals(s, base64DecodeToString(base64EncodeToString(s))); + + try { + base64Decode("a"); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Invalid BASE64 string length. Must be multiple of 4.", e.getLocalizedMessage()); + // OK. + } + try { + base64Decode("aaa"); + fail(); + } catch (IllegalArgumentException e) { + // OK. + } + } + + //==================================================================================================== + // generateUUID(String) + //==================================================================================================== + @Test + public void testGenerateUUID() throws Exception { + for (int i = 0; i < 10; i++) { + String s = generateUUID(i); + assertEquals(i, s.length()); + for (char c : s.toCharArray()) + assertTrue(Character.isLowerCase(c) || Character.isDigit(c)); + } + } + + //==================================================================================================== + // trim(String) + //==================================================================================================== + @Test + public void testTrim() throws Exception { + assertNull(trim(null)); + assertEquals("", trim("")); + assertEquals("", trim(" ")); + } + + //==================================================================================================== + // parseISO8601Date(String) + //==================================================================================================== + @Test + public void testParseISO8601Date() throws Exception { + WriterSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(DateSwap.ISO8601DTPZ.class).timeZone(TimeZone.getTimeZone("GMT")).build(); + + assertNull(parseISO8601Date(null)); + assertNull(parseISO8601Date("")); + + TestUtils.setTimeZone("GMT"); + try { + + assertEquals("'2000-01-01T00:00:00.000Z'", s.serialize(parseISO8601Date("2000"))); + assertEquals("'2000-02-01T00:00:00.000Z'", s.serialize(parseISO8601Date("2000-02"))); + assertEquals("'2000-02-03T00:00:00.000Z'", s.serialize(parseISO8601Date("2000-02-03"))); + assertEquals("'2000-02-03T04:00:00.000Z'", s.serialize(parseISO8601Date("2000-02-03T04"))); + assertEquals("'2000-02-03T04:05:00.000Z'", s.serialize(parseISO8601Date("2000-02-03T04:05"))); + assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseISO8601Date("2000-02-03T04:05:06"))); + assertEquals("'2000-02-03T04:00:00.000Z'", s.serialize(parseISO8601Date("2000-02-03 04"))); + assertEquals("'2000-02-03T04:05:00.000Z'", s.serialize(parseISO8601Date("2000-02-03 04:05"))); + assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseISO8601Date("2000-02-03 04:05:06"))); + + // ISO8601 doesn't support milliseconds, so it gets trimmed. + assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseISO8601Date("2000-02-03 04:05:06,789"))); + } finally { + TestUtils.unsetTimeZone(); + } + } + + //==================================================================================================== + // pathStartsWith(String, String) + //==================================================================================================== + @Test + public void testPathStartsWith() throws Exception { + assertTrue(pathStartsWith("foo", "foo")); + assertTrue(pathStartsWith("foo/bar", "foo")); + assertFalse(pathStartsWith("foo2/bar", "foo")); + assertFalse(pathStartsWith("foo2", "foo")); + assertFalse(pathStartsWith("foo2", "")); + } + + //==================================================================================================== + // getField(int, String, char) + //==================================================================================================== + @Test + public void testGetField() { + String in = "0,1,2"; + assertEquals("0", getField(0, in, ',')); + assertEquals("1", getField(1, in, ',')); + assertEquals("2", getField(2, in, ',')); + assertEquals("", getField(3, in, ',')); + + in = ",1,,3,"; + assertEquals("", getField(0, in, ',')); + assertEquals("1", getField(1, in, ',')); + assertEquals("", getField(2, in, ',')); + assertEquals("3", getField(3, in, ',')); + assertEquals("", getField(4, in, ',')); + assertEquals("", getField(5, in, ',')); + + in = ""; + assertEquals("", getField(0, in, ',')); + + in = null; + assertEquals("", getField(0, in, ',')); + } + + //==================================================================================================== + // parseMap(String,char,char,boolean) + //==================================================================================================== + @Test + public void testSplitMap() { + assertObjectEquals("{a:'1'}", splitMap("a=1", ',', '=', true)); + assertObjectEquals("{a:'1',b:'2'}", splitMap("a=1,b=2", ',', '=', true)); + assertObjectEquals("{a:'1',b:'2'}", splitMap(" a = 1 , b = 2 ", ',', '=', true)); + assertObjectEquals("{' a ':' 1 ',' b ':' 2 '}", splitMap(" a = 1 , b = 2 ", ',', '=', false)); + assertObjectEquals("{a:''}", splitMap("a", ',', '=', true)); + assertObjectEquals("{a:'',b:''}", splitMap("a,b", ',', '=', true)); + assertObjectEquals("{a:'1',b:''}", splitMap("a=1,b", ',', '=', true)); + assertObjectEquals("{a:'',b:'1'}", splitMap("a,b=1", ',', '=', true)); + assertObjectEquals("{'a=':'1'}", splitMap("a\\==1", ',', '=', true)); + assertObjectEquals("{'a\\\\':'1'}", splitMap("a\\\\=1", ',', '=', true)); + } + + //==================================================================================================== + // isAbsoluteUri(String) + //==================================================================================================== + @Test + public void testIsAbsoluteUri() { + assertFalse(isAbsoluteUri(null)); + assertFalse(isAbsoluteUri("")); + assertTrue(isAbsoluteUri("http://foo")); + assertTrue(isAbsoluteUri("x://x")); + assertFalse(isAbsoluteUri("xX://x")); + assertFalse(isAbsoluteUri("x ://x")); + assertFalse(isAbsoluteUri("x: //x")); + assertFalse(isAbsoluteUri("x:/ /x")); + assertFalse(isAbsoluteUri("x:x//x")); + assertFalse(isAbsoluteUri("x:/x/x")); + } + + //==================================================================================================== + // getAuthorityUri(String) + //==================================================================================================== + @Test + public void testGetAuthorityUri() { + assertEquals("http://foo", getAuthorityUri("http://foo")); + assertEquals("http://foo:123", getAuthorityUri("http://foo:123")); + assertEquals("http://foo:123", getAuthorityUri("http://foo:123/")); + assertEquals("http://foo:123", getAuthorityUri("http://foo:123/bar")); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java new file mode 100755 index 0000000..364e233 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java @@ -0,0 +1,337 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.utils; + +import static org.junit.Assert.*; +import static org.apache.juneau.internal.StringUtils.*; + +import org.apache.juneau.svl.*; +import org.junit.*; + +@SuppressWarnings("javadoc") +public class StringVarResolverTest { + + //==================================================================================================== + // test - Basic tests + //==================================================================================================== + @Test + public void test() throws Exception { + VarResolver vr = new VarResolverBuilder().vars(XVar.class).build(); + String t; + + t = null; + assertEquals("", vr.resolve(t)); + + t = ""; + assertEquals("", vr.resolve(t)); + + t = "foo"; + assertEquals("foo", vr.resolve(t)); + + t = "$X{y}"; + assertEquals("xyx", vr.resolve(t)); + + t = "$X{y}x"; + assertEquals("xyxx", vr.resolve(t)); + + t = "x$X{y}"; + assertEquals("xxyx", vr.resolve(t)); + + t = "$X{y}$X{y}"; + assertEquals("xyxxyx", vr.resolve(t)); + + t = "z$X{y}z$X{y}z"; + assertEquals("zxyxzxyxz", vr.resolve(t)); + + t = "$X{$X{y}}"; + assertEquals("xxyxx", vr.resolve(t)); + + t = "$X{z$X{y}z}"; + assertEquals("xzxyxzx", vr.resolve(t)); + + t = "$X.{y}"; + assertEquals("$X.{y}", vr.resolve(t)); + + t = "z$X.{y}z"; + assertEquals("z$X.{y}z", vr.resolve(t)); + + t = "z$X.{$X.{z}}z"; + assertEquals("z$X.{$X.{z}}z", vr.resolve(t)); + + // Non-existent vars + t = "$Y{y}"; + assertEquals("$Y{y}", vr.resolve(t)); + + t = "$Y{y}x"; + assertEquals("$Y{y}x", vr.resolve(t)); + + t = "x$Y{y}"; + assertEquals("x$Y{y}", vr.resolve(t)); + + // Incomplete vars + // TODO - fix +// t = "x$Y{y"; +// assertEquals("x$Y{y", vr.resolve(t)); + } + + public static class XVar extends SimpleVar { + public XVar() { + super("X"); + } + @Override + public String resolve(VarResolverSession session, String arg) { + return "x" + arg + "x"; + } + } + + //==================================================================================================== + // test - No-name variables + //==================================================================================================== + @Test + public void test2() throws Exception { + VarResolver vr = new VarResolverBuilder().vars(BlankVar.class).build(); + String t; + + t = "${y}"; + assertEquals("xyx", vr.resolve(t)); + + t = "${${y}}"; + assertEquals("xxyxx", vr.resolve(t)); + + t = "${${y}${y}}"; + assertEquals("xxyxxyxx", vr.resolve(t)); + + t = "z${z${y}z}z"; + assertEquals("zxzxyxzxz", vr.resolve(t)); + } + + public static class BlankVar extends SimpleVar { + public BlankVar() { + super(""); + } + @Override + public String resolve(VarResolverSession session, String arg) { + return "x" + arg + "x"; + } + } + + //==================================================================================================== + // test - No-name variables + //==================================================================================================== + @Test + public void testEscaped$() throws Exception { + VarResolver vr = new VarResolverBuilder().vars(BlankVar.class).build(); + String t; + + t = "${y}"; + assertEquals("xyx", vr.resolve(t)); + t = "\\${y}"; + assertEquals("${y}", vr.resolve(t)); + + t = "foo\\${y}foo"; + assertEquals("foo${y}foo", vr.resolve(t)); + + // TODO - This doesn't work. + //t = "${\\${y}}"; + //assertEquals("x${y}x", vr.resolve(t)); + } + + //==================================================================================================== + // test - Escape sequences. + //==================================================================================================== + @Test + public void testEscapedSequences() throws Exception { + VarResolver vr = new VarResolverBuilder().vars(XVar.class).build(); + String t; + char b = '\\'; + + t = "A|A".replace('|',b); + assertEquals("A|A".replace('|',b), vr.resolve(t)); + t = "A||A".replace('|',b); + assertEquals("A|A".replace('|',b), vr.resolve(t)); + t = "A|A$X{B}".replace('|',b); + assertEquals("A|AxBx".replace('|',b), vr.resolve(t)); + t = "A||A$X{B}".replace('|',b); + assertEquals("A|AxBx".replace('|',b), vr.resolve(t)); + t = "A|$X{B}".replace('|',b); + assertEquals("A$X{B}".replace('|',b), vr.resolve(t)); + t = "A||$X{B}".replace('|',b); + assertEquals("A|xBx".replace('|',b), vr.resolve(t)); + t = "A$X|{B}".replace('|',b); + assertEquals("A$X{B}".replace('|',b), vr.resolve(t)); + t = "A$X{B|}".replace('|',b); + assertEquals("A$X{B}".replace('|',b), vr.resolve(t)); + t = "A$X{B}|".replace('|',b); + assertEquals("AxBx|".replace('|',b), vr.resolve(t)); + } + + //==================================================================================================== + // Test $E variables + //==================================================================================================== + @Test + public void test$E() throws Exception { + String t; + + t = "$E{PATH}"; + assertFalse(isEmpty(VarResolver.DEFAULT.resolve(t))); + } + + //==================================================================================================== + // Test that StringResolver(parent) works as expected. + //==================================================================================================== + @Test + public void testParent() throws Exception { + VarResolver vr = new VarResolverBuilder().defaultVars().vars(XMultipartVar.class).build(); + String t; + System.setProperty("a", "a1"); + System.setProperty("b", "b1"); + + t = "$X{$S{a},$S{b}}"; + assertEquals("a1+b1", vr.resolve(t)); + t = "$X{$S{a}}"; + assertEquals("a1", vr.resolve(t)); + } + + public static class XMultipartVar extends MultipartVar { + public XMultipartVar() { + super("X"); + } + @Override /* MultipartVar */ + public String resolve(VarResolverSession session, String[] args) { + return join(args, '+'); + } + } + + //==================================================================================================== + // Test false triggers. + //==================================================================================================== + @Test + public void testFalseTriggers() throws Exception { + VarResolverBuilder vrb = new VarResolverBuilder().defaultVars(); + String in = null; + + // Should reject names with characters outside A-Za-z + for (Class<?> c : new Class[]{InvalidVar1.class, InvalidVar2.class, InvalidVar3.class, InvalidVar4.class, InvalidVar5.class}) { + try { + vrb.vars(c); + fail(); + } catch (RuntimeException e) { + // OK. + } + } + + VarResolver vr = vrb.build(); + + // These should all be unchanged. + in = "$@{foobar}"; + assertEquals(in, vr.resolve(in)); + in = "$[{foobar}"; + assertEquals(in, vr.resolve(in)); + in = "$`{foobar}"; + assertEquals(in, vr.resolve(in)); + in = "$|{foobar}"; + assertEquals(in, vr.resolve(in)); + in = "${{foobar}"; + assertEquals(in, vr.resolve(in)); + in = "${$foobar}"; + assertEquals(in, vr.resolve(in)); + + System.setProperty("foobar", "baz"); + + in = "$"; + assertEquals(in, vr.resolve(in)); + + in = "$S"; + assertEquals(in, vr.resolve(in)); + + in = "$S{"; + assertEquals(in, vr.resolve(in)); + + in = "$S{foobar"; + + assertEquals(in, vr.resolve(in)); + in = "$S{foobar}$"; + assertEquals("baz$", vr.resolve(in)); + + in = "$S{foobar}$S"; + assertEquals("baz$S", vr.resolve(in)); + + in = "$S{foobar}$S{"; + assertEquals("baz$S{", vr.resolve(in)); + + in = "$S{foobar}$S{foobar"; + assertEquals("baz$S{foobar", vr.resolve(in)); + + System.clearProperty("foobar"); + in = "$S{foobar}"; + + // Test nulls returned by StringVar. + // Should be converted to blanks. + vrb.vars(AlwaysNullVar.class); + + vr = vrb.build(); + + in = "$A{xxx}"; + assertEquals("", vr.resolve(in)); + in = "x$A{xxx}"; + assertEquals("x", vr.resolve(in)); + in = "$A{xxx}x"; + assertEquals("x", vr.resolve(in)); + } + + public static class AlwaysNullVar extends SimpleVar { + public AlwaysNullVar() { + super("A"); + } + @Override + public String resolve(VarResolverSession session, String key) { + return null; + } + } + + public static class InvalidVar extends SimpleVar { + public InvalidVar(String c) { + super(c); + } + @Override + public String resolve(VarResolverSession session, String key) { + return null; + } + } + + public static class InvalidVar1 extends InvalidVar { + public InvalidVar1() { + super(null); + } + } + public static class InvalidVar2 extends InvalidVar { + public InvalidVar2() { + super("@"); + } + } + public static class InvalidVar3 extends InvalidVar { + public InvalidVar3() { + super("["); + } + } + public static class InvalidVar4 extends InvalidVar { + public InvalidVar4() { + super("`"); + } + } + public static class InvalidVar5 extends InvalidVar { + public InvalidVar5() { + super("|"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextResolutionComboTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextResolutionComboTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextResolutionComboTest.java new file mode 100644 index 0000000..8e3b43b --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextResolutionComboTest.java @@ -0,0 +1,1054 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.utils; + +import static org.apache.juneau.TestUtils.*; +import static org.apache.juneau.UriRelativity.*; +import static org.apache.juneau.UriResolution.*; + +import java.util.*; + +import org.apache.juneau.*; +import org.junit.*; +import org.junit.runner.*; +import org.junit.runners.*; + +/** + * Verifies that the resolveUri() methods in UriContext work correctly. + */ +@RunWith(Parameterized.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class UriContextResolutionComboTest { + + @Parameterized.Parameters + public static Collection<Object[]> getInput() { + return Arrays.asList(new Object[][] { + + // Happy cases - All URL parts known. + { /* 0 */ + "Happy-1a", + input( + "http://host:port","/context","/resource","/path", + "http://foo.com:123/foobar" + ), + results( + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar" + ) + }, + { /* 1 */ + "Happy-2", + input( + "http://host:port","/context","/resource","/path", + "http://foo.com:123" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123" + ) + }, + { /* 2 */ + "Happy-3", + input( + "http://host:port","/context","/resource","/path", + "/foobar" + ), + results( + "http://host:port/foobar", + "http://host:port/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar" + ) + }, + { /* 3 */ + "Happy-4", + input( + "http://host:port","/context","/resource","/path", + "/" + ), + results( + "http://host:port", + "http://host:port", + "/", + "/", + "/", + "/" + ) + }, + { /* 4 */ + "Happy-5", + input( + "http://host:port","/context","/resource","/path", + "foobar" + ), + results( + "http://host:port/context/resource/foobar", + "http://host:port/context/resource/foobar", + "/context/resource/foobar", + "/context/resource/foobar", + "foobar", + "foobar" + ) + }, + { /* 5 */ + "Happy-6", + input( + "http://host:port","/context","/resource","/path", + "" + ), + results( + "http://host:port/context/resource", + "http://host:port/context/resource/path", + "/context/resource", + "/context/resource/path", + "", + "" + ) + }, + { /* 6 */ + "Happy-7", + input( + "http://host:port","/context","/resource","/path", + "context:/foo" + ), + results( + "http://host:port/context/foo", + "http://host:port/context/foo", + "/context/foo", + "/context/foo", + "/context/foo", + "/context/foo" + ) + }, + { /* 7 */ + "Happy-8", + input( + "http://host:port","/context","/resource","/path", + "context:/" + ), + results( + "http://host:port/context", + "http://host:port/context", + "/context", + "/context", + "/context", + "/context" + ) + }, + { /* 8 */ + "Happy-9", + input( + "http://host:port","/context","/resource","/path", + "servlet:/foo" + ), + results( + "http://host:port/context/resource/foo", + "http://host:port/context/resource/foo", + "/context/resource/foo", + "/context/resource/foo", + "/context/resource/foo", + "/context/resource/foo" + ) + }, + { /* 9 */ + "Happy-10", + input( + "http://host:port","/context","/resource","/path", + "servlet:/" + ), + results( + "http://host:port/context/resource", + "http://host:port/context/resource", + "/context/resource", + "/context/resource", + "/context/resource", + "/context/resource" + ) + }, + + // Multiple context and resource parts + { /* 10 */ + "MultiContextResource-1", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "http://foo.com:123/foobar" + ), + results( + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar" + ) + }, + { /* 11 */ + "MultiContextResource-2", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "http://foo.com:123" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123" + ) + }, + { /* 12 */ + "MultiContextResource-3", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "/foobar" + ), + results( + "http://host:port/foobar", + "http://host:port/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar" + ) + }, + { /* 13 */ + "MultiContextResource-4", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "/" + ), + results( + "http://host:port", + "http://host:port", + "/", + "/", + "/", + "/" + ) + }, + { /* 14 */ + "MultiContextResource-5", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "foobar" + ), + results( + "http://host:port/c1/c2/r1/r2/foobar", + "http://host:port/c1/c2/r1/r2/p1/foobar", + "/c1/c2/r1/r2/foobar", + "/c1/c2/r1/r2/p1/foobar", + "foobar", + "foobar" + ) + }, + { /* 15 */ + "MultiContextResource-6", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "" + ), + results( + "http://host:port/c1/c2/r1/r2", + "http://host:port/c1/c2/r1/r2/p1/p2", + "/c1/c2/r1/r2", + "/c1/c2/r1/r2/p1/p2", + "", + "" + ) + }, + { /* 16 */ + "MultiContextResource-7", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "context:/foo" + ), + results( + "http://host:port/c1/c2/foo", + "http://host:port/c1/c2/foo", + "/c1/c2/foo", + "/c1/c2/foo", + "/c1/c2/foo", + "/c1/c2/foo" + ) + }, + { /* 17 */ + "MultiContextResource-8", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "context:/" + ), + results( + "http://host:port/c1/c2", + "http://host:port/c1/c2", + "/c1/c2", + "/c1/c2", + "/c1/c2", + "/c1/c2" + ) + }, + { /* 18 */ + "MultiContextResource-9", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "servlet:/foo" + ), + results( + "http://host:port/c1/c2/r1/r2/foo", + "http://host:port/c1/c2/r1/r2/foo", + "/c1/c2/r1/r2/foo", + "/c1/c2/r1/r2/foo", + "/c1/c2/r1/r2/foo", + "/c1/c2/r1/r2/foo" + ) + }, + { /* 19 */ + "MultiContextResource-10", + input( + "http://host:port","/c1/c2","/r1/r2","/p1/p2", + "servlet:/" + ), + results( + "http://host:port/c1/c2/r1/r2", + "http://host:port/c1/c2/r1/r2", + "/c1/c2/r1/r2", + "/c1/c2/r1/r2", + "/c1/c2/r1/r2", + "/c1/c2/r1/r2" + ) + }, + + // No authority given + { /* 20 */ + "NoAuthority-1", + input( + "","/context","/resource","/path", + "http://foo.com:123/foobar" + ), + results( + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar" + ) + }, + { /* 21 */ + "NoAuthority-2", + input( + "","/context","/resource","/path", + "http://foo.com:123" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123" + ) + }, + { /* 22 */ + "NoAuthority-3", + input( + "","/context","/resource","/path", + "/foobar" + ), + results( + "/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar" + ) + }, + { /* 23 */ + "NoAuthority-4", + input( + "","/context","/resource","/path", + "/" + ), + results( + "/", + "/", + "/", + "/", + "/", + "/" + ) + }, + { /* 24 */ + "NoAuthority-5", + input( + "","/context","/resource","/path", + "foobar" + ), + results( + "/context/resource/foobar", + "/context/resource/foobar", + "/context/resource/foobar", + "/context/resource/foobar", + "foobar", + "foobar" + ) + }, + { /* 25 */ + "NoAuthority-6", + input( + "","/context","/resource","/path", + "" + ), + results( + "/context/resource", + "/context/resource/path", + "/context/resource", + "/context/resource/path", + "", + "" + ) + }, + { /* 26 */ + "NoAuthority-7", + input( + "","/context","/resource","/path", + "context:/foo" + ), + results( + "/context/foo", + "/context/foo", + "/context/foo", + "/context/foo", + "/context/foo", + "/context/foo" + ) + }, + { /* 27 */ + "NoAuthority-8", + input( + "","/context","/resource","/path", + "context:/" + ), + results( + "/context", + "/context", + "/context", + "/context", + "/context", + "/context" + ) + }, + { /* 28 */ + "NoAuthority-9", + input( + "","/context","/resource","/path", + "servlet:/foo" + ), + results( + "/context/resource/foo", + "/context/resource/foo", + "/context/resource/foo", + "/context/resource/foo", + "/context/resource/foo", + "/context/resource/foo" + ) + }, + { /* 29 */ + "NoAuthority-10", + input( + "","/context","/resource","/path", + "servlet:/" + ), + results( + "/context/resource", + "/context/resource", + "/context/resource", + "/context/resource", + "/context/resource", + "/context/resource" + ) + }, + + // No authority or context given + { /* 30 */ + "NoAuthorityOrContext-1", + input( + "","","/resource","/path", + "http://foo.com:123/foobar" + ), + results( + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar" + ) + }, + { /* 31 */ + "NoAuthorityOrContext-2", + input( + "","","/resource","/path", + "http://foo.com:123" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123" + ) + }, + { /* 32 */ + "NoAuthorityOrContext-3", + input( + "","","/resource","/path", + "/foobar" + ), + results( + "/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar" + ) + }, + { /* 33 */ + "NoAuthorityOrContext-4", + input( + "","","/resource","/path", + "/" + ), + results( + "/", + "/", + "/", + "/", + "/", + "/" + ) + }, + { /* 34 */ + "NoAuthorityOrContext-5", + input( + "","","/resource","/path", + "foobar" + ), + results( + "/resource/foobar", + "/resource/foobar", + "/resource/foobar", + "/resource/foobar", + "foobar", + "foobar" + ) + }, + { /* 35 */ + "NoAuthorityOrContext-6", + input( + "","","/resource","/path", + "" + ), + results( + "/resource", + "/resource/path", + "/resource", + "/resource/path", + "", + "" + ) + }, + { /* 36 */ + "NoAuthorityOrContext-7", + input( + "","","/resource","/path", + "context:/foo" + ), + results( + "/foo", + "/foo", + "/foo", + "/foo", + "/foo", + "/foo" + ) + }, + { /* 37 */ + "NoAuthorityOrContext-8", + input( + "","","/resource","/path", + "context:/" + ), + results( + "/", + "/", + "/", + "/", + "/", + "/" + ) + }, + { /* 38 */ + "NoAuthorityOrContext-9", + input( + "","","/resource","/path", + "servlet:/foo" + ), + results( + "/resource/foo", + "/resource/foo", + "/resource/foo", + "/resource/foo", + "/resource/foo", + "/resource/foo" + ) + }, + { /* 39 */ + "NoAuthorityOrContext-10", + input( + "","","/resource","/path", + "servlet:/" + ), + results( + "/resource", + "/resource", + "/resource", + "/resource", + "/resource", + "/resource" + ) + }, + + // No authority or context or resource given + { /* 40 */ + "NoAuthorityOrContextOrResource-1", + input( + "","","","/path", + "http://foo.com:123/foobar" + ), + results( + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar" + ) + }, + { /* 41 */ + "NoAuthorityOrContextOrResource-2", + input( + "","","","/path", + "http://foo.com:123" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123" + ) + }, + { /* 42 */ + "NoAuthorityOrContextOrResource-3", + input( + "","","","/path", + "/foobar" + ), + results( + "/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar" + ) + }, + { /* 43 */ + "NoAuthorityOrContextOrResource-4", + input( + "","","","/path", + "/" + ), + results( + "/", + "/", + "/", + "/", + "/", + "/" + ) + }, + { /* 44 */ + "NoAuthorityOrContextOrResource-5", + input( + "","","","/path", + "foobar" + ), + results( + "/foobar", + "/foobar", + "/foobar", + "/foobar", + "foobar", + "foobar" + ) + }, + { /* 45 */ + "NoAuthorityOrContextOrResource-6", + input( + "","","","/path", + "" + ), + results( + "/", + "/path", + "/", + "/path", + "", + "" + ) + }, + { /* 46 */ + "NoAuthorityOrContextOrResource-7", + input( + "","","","/path", + "context:/foo" + ), + results( + "/foo", + "/foo", + "/foo", + "/foo", + "/foo", + "/foo" + ) + }, + { /* 47 */ + "NoAuthorityOrContextOrResource-8", + input( + "","","","/path", + "context:/" + ), + results( + "/", + "/", + "/", + "/", + "/", + "/" + ) + }, + { /* 48 */ + "NoAuthorityOrContextOrResource-9", + input( + "","","","/path", + "servlet:/foo" + ), + results( + "/foo", + "/foo", + "/foo", + "/foo", + "/foo", + "/foo" + ) + }, + { /* 49 */ + "NoAuthorityOrContextOrResource-10", + input( + "","","","/path", + "servlet:/" + ), + results( + "/", + "/", + "/", + "/", + "/", + "/" + ) + }, + + // No context or resource given. + { /* 50 */ + "NoContextOrResource-1", + input( + "http://host:port","","","/path", + "http://foo.com:123/foobar" + ), + results( + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar", + "http://foo.com:123/foobar" + ) + }, + { /* 51 */ + "NoContextOrResource-2", + input( + "http://host:port","","","/path", + "http://foo.com:123" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123" + ) + }, + { /* 52 */ + "NoContextOrResource-3", + input( + "http://host:port","","","/path", + "/foobar" + ), + results( + "http://host:port/foobar", + "http://host:port/foobar", + "/foobar", + "/foobar", + "/foobar", + "/foobar" + ) + }, + { /* 53 */ + "NoContextOrResource-4", + input( + "http://host:port","","","/path", + "/" + ), + results( + "http://host:port", + "http://host:port", + "/", + "/", + "/", + "/" + ) + }, + { /* 54 */ + "NoContextOrResource-5", + input( + "http://host:port","","","/path", + "foobar" + ), + results( + "http://host:port/foobar", + "http://host:port/foobar", + "/foobar", + "/foobar", + "foobar", + "foobar" + ) + }, + { /* 55 */ + "NoContextOrResource-6", + input( + "http://host:port","","","/path", + "" + ), + results( + "http://host:port", + "http://host:port/path", + "/", + "/path", + "", + "" + ) + }, + { /* 56 */ + "NoContextOrResource-7", + input( + "http://host:port","","","/path", + "context:/foo" + ), + results( + "http://host:port/foo", + "http://host:port/foo", + "/foo", + "/foo", + "/foo", + "/foo" + ) + }, + { /* 57 */ + "NoContextOrResource-8", + input( + "http://host:port","","","/path", + "context:/" + ), + results( + "http://host:port", + "http://host:port", + "/", + "/", + "/", + "/" + ) + }, + { /* 58 */ + "NoContextOrResource-9", + input( + "http://host:port","","","/path", + "servlet:/foo" + ), + results( + "http://host:port/foo", + "http://host:port/foo", + "/foo", + "/foo", + "/foo", + "/foo" + ) + }, + { /* 59 */ + "NoContextOrResource-10", + input( + "http://host:port","","","/path", + "servlet:/" + ), + results( + "http://host:port", + "http://host:port", + "/", + "/", + "/", + "/" + ) + }, + }); + } + + public static Input input(String authority, String context, String resource, String path, String uri) { + return new Input(authority, context, resource, path, uri); + } + + public static Results results(String eAbsResource, String eAbsPathInfo, String eRrResource, String eRrPathInfo, String eNoneResource, String eNonePathInfo) { + return new Results(eAbsResource, eAbsPathInfo, eRrResource, eRrPathInfo, eNoneResource, eNonePathInfo); + } + + public static class Input { + private final String uri; + private final String authority, context, resource, path; + + public Input(String authority, String context, String resource, String path, String uri) { + this.authority = authority; + this.context = context; + this.resource = resource; + this.path = path; + this.uri = uri; + } + } + + public static class Results { + private final String aResource, aPathInfo, rrResource, rrPathInfo, nResource, nPathInfo; + + public Results(String aResource, String aPathInfo, String rrResource, String rrPathInfo, String nResource, String nPathInfo) { + this.aResource = aResource; + this.aPathInfo = aPathInfo; + this.rrResource = rrResource; + this.rrPathInfo = rrPathInfo; + this.nResource = nResource; + this.nPathInfo = nPathInfo; + } + } + + private String label; + private Input in; + private Results r; + + public UriContextResolutionComboTest(String label, Input in, Results r) throws Exception { + this.label = label; + this.in = in; + this.r = r; + } + + @Test + public void a01_testAbsoluteResource() { + assertEquals(r.aResource, new UriResolver(ABSOLUTE, RESOURCE, new UriContext(in.authority, in.context, in.resource, in.path)).resolve(in.uri), "{0}: testAbsolute() failed", label); + } + + @Test + public void a02_testAppendAbsoluteResource() { + assertEquals(r.aResource, new UriResolver(ABSOLUTE, RESOURCE, new UriContext(in.authority, in.context, in.resource, in.path)).append(new StringBuilder(), in.uri).toString(), "{0}: testAbsolute() failed", label); + } + + @Test + public void a03_testAbsolutePathInfo() { + assertEquals(r.aPathInfo, new UriResolver(ABSOLUTE, PATH_INFO, new UriContext(in.authority, in.context, in.resource, in.path)).resolve(in.uri), "{0}: testAbsolute() failed", label); + } + + @Test + public void a04_testAppendAbsolutePathInfo() { + assertEquals(r.aPathInfo, new UriResolver(ABSOLUTE, PATH_INFO, new UriContext(in.authority, in.context, in.resource, in.path)).append(new StringBuilder(), in.uri).toString(), "{0}: testAbsolute() failed", label); + } + + @Test + public void a05_testRootRelativeResource() { + assertEquals(r.rrResource, new UriResolver(ROOT_RELATIVE, RESOURCE, new UriContext(in.authority, in.context, in.resource, in.path)).resolve(in.uri), "{0}: testAbsolute() failed", label); + } + + @Test + public void a06_testAppendRootRelativeResource() { + assertEquals(r.rrResource, new UriResolver(ROOT_RELATIVE, RESOURCE, new UriContext(in.authority, in.context, in.resource, in.path)).append(new StringBuilder(), in.uri).toString(), "{0}: testAbsolute() failed", label); + } + + @Test + public void a07_testRootRelativePathInfo() { + assertEquals(r.rrPathInfo, new UriResolver(ROOT_RELATIVE, PATH_INFO, new UriContext(in.authority, in.context, in.resource, in.path)).resolve(in.uri), "{0}: testAbsolute() failed", label); + } + + @Test + public void a08_testAppendRootRelativePathInfo() { + assertEquals(r.rrPathInfo, new UriResolver(ROOT_RELATIVE, PATH_INFO, new UriContext(in.authority, in.context, in.resource, in.path)).append(new StringBuilder(), in.uri).toString(), "{0}: testAbsolute() failed", label); + } + + @Test + public void a09_testNoneResource() { + assertEquals(r.nResource, new UriResolver(NONE, RESOURCE, new UriContext(in.authority, in.context, in.resource, in.path)).resolve(in.uri), "{0}: testAbsolute() failed", label); + } + + @Test + public void a10_testAppendNoneResource() { + assertEquals(r.nResource, new UriResolver(NONE, RESOURCE, new UriContext(in.authority, in.context, in.resource, in.path)).append(new StringBuilder(), in.uri).toString(), "{0}: testAbsolute() failed", label); + } + + @Test + public void a11_testNonePathInfo() { + assertEquals(r.nPathInfo, new UriResolver(NONE, PATH_INFO, new UriContext(in.authority, in.context, in.resource, in.path)).resolve(in.uri), "{0}: testAbsolute() failed", label); + } + + @Test + public void a12_testAppendNonePathInfo() { + assertEquals(r.nPathInfo, new UriResolver(NONE, PATH_INFO, new UriContext(in.authority, in.context, in.resource, in.path)).append(new StringBuilder(), in.uri).toString(), "{0}: testAbsolute() failed", label); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextUriComboTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextUriComboTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextUriComboTest.java new file mode 100644 index 0000000..408c594 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/UriContextUriComboTest.java @@ -0,0 +1,265 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.utils; + +import static org.apache.juneau.TestUtils.*; + +import java.util.*; + +import org.apache.juneau.*; +import org.junit.*; +import org.junit.runner.*; +import org.junit.runners.*; + +/** + * Verifies that the getUri() methods in UriContext work correctly. + */ +@RunWith(Parameterized.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class UriContextUriComboTest { + + @Parameterized.Parameters + public static Collection<Object[]> getInput() { + return Arrays.asList(new Object[][] { + + // Happy cases - All URL parts known. + { + "Happy-1", + input( + "http://foo.com:123","/context","/resource","/path" + ), + results( + "http://foo.com:123", + "http://foo.com:123/context", + "http://foo.com:123/context/resource", + "http://foo.com:123/context/resource/path", + "/context", + "/context/resource", + "/context/resource/path" + ) + }, + { + "Happy-2", + input( + "http://foo.com:123","/c1/c2","/r1/r2","/p1/p2" + ), + results( + "http://foo.com:123", + "http://foo.com:123/c1/c2", + "http://foo.com:123/c1/c2/r1/r2", + "http://foo.com:123/c1/c2/r1/r2/p1/p2", + "/c1/c2", + "/c1/c2/r1/r2", + "/c1/c2/r1/r2/p1/p2" + ) + }, + { + "NoAuthority-1", + input( + "","/context","/resource","/path" + ), + results( + "/", + "/context", + "/context/resource", + "/context/resource/path", + "/context", + "/context/resource", + "/context/resource/path" + ) + }, + { + "NoContext-1", + input( + "http://foo.com:123","","/resource","/path" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123/resource", + "http://foo.com:123/resource/path", + "/", + "/resource", + "/resource/path" + ) + }, + { + "NoResource-1", + input( + "http://foo.com:123","/context","","/path" + ), + results( + "http://foo.com:123", + "http://foo.com:123/context", + "http://foo.com:123/context", + "http://foo.com:123/context/path", + "/context", + "/context", + "/context/path" + ) + }, + { + "NoPath-1", + input( + "http://foo.com:123","/context","/resource","" + ), + results( + "http://foo.com:123", + "http://foo.com:123/context", + "http://foo.com:123/context/resource", + "http://foo.com:123/context/resource", + "/context", + "/context/resource", + "/context/resource" + ) + }, + { + "NoAuthorityNoContext-1", + input( + "","","/resource","/path" + ), + results( + "/", + "/", + "/resource", + "/resource/path", + "/", + "/resource", + "/resource/path" + ) + }, + { + "NoContextNoResource-1", + input( + "http://foo.com:123","","","/path" + ), + results( + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123", + "http://foo.com:123/path", + "/", + "/", + "/path" + ) + }, + { + "NoAuthorityNoContextNoResource-1", + input( + "","","","/path" + ), + results( + "/", + "/", + "/", + "/path", + "/", + "/", + "/path" + ) + }, + { + "Nothing-1", + input( + "","","","" + ), + results( + "/", + "/", + "/", + "/", + "/", + "/", + "/" + ) + }, + }); + } + + public static Input input(String authority, String context, String resource, String path) { + return new Input(authority, context, resource, path); + } + + public static Results results(String eAbsoluteAuthority, String eAbsoluteContext, String eAbsoluteResource, String eAbsolutePath, + String eRootRelativeContext, String eRootRelativeResource, String eRootRelativePath) { + return new Results(eAbsoluteAuthority, eAbsoluteContext, eAbsoluteResource, eAbsolutePath, eRootRelativeContext, eRootRelativeResource, eRootRelativePath); + } + + public static class Input { + private final UriContext uriContext; + + public Input(String authority, String context, String resource, String path) { + this.uriContext = new UriContext(authority, context, resource, path); + } + } + + public static class Results { + private final String eAbsoluteAuthority, eAbsoluteContext, eAbsoluteResource, eAbsolutePath, eRootRelativeContext, eRootRelativeResource, eRootRelativePath; + + public Results(String eAbsoluteAuthority, String eAbsoluteContext, String eAbsoluteResource, String eAbsolutePath, + String eRootRelativeContext, String eRootRelativeResource, String eRootRelativePath) { + this.eAbsoluteAuthority = eAbsoluteAuthority; + this.eAbsoluteContext = eAbsoluteContext; + this.eAbsoluteResource = eAbsoluteResource; + this.eAbsolutePath = eAbsolutePath; + this.eRootRelativeContext = eRootRelativeContext; + this.eRootRelativeResource = eRootRelativeResource; + this.eRootRelativePath = eRootRelativePath; + } + } + + private String label; + private Input in; + private Results r; + + public UriContextUriComboTest(String label, Input in, Results r) throws Exception { + this.label = label; + this.in = in; + this.r = r; + } + + @Test + public void a1_testAbsoluteAuthority() { + assertEquals(r.eAbsoluteAuthority, in.uriContext.getAbsoluteAuthority(), "{0}: testAbsoluteAuthority() failed", label); + } + + @Test + public void a2_testAbsoluteContext() { + assertEquals(r.eAbsoluteContext, in.uriContext.getAbsoluteContextRoot(), "{0}: testAbsoluteContext() failed", label); + } + + @Test + public void a3_testAbsoluteResource() { + assertEquals(r.eAbsoluteResource, in.uriContext.getAbsoluteServletPath(), "{0}: testAbsoluteResource() failed", label); + } + + @Test + public void a4_testAbsolutePath() { + assertEquals(r.eAbsolutePath, in.uriContext.getAbsolutePathInfo(), "{0}: testAbsolutePath() failed", label); + } + + @Test + public void a5_testRootRelativeContext() { + assertEquals(r.eRootRelativeContext, in.uriContext.getRootRelativeContextRoot(), "{0}: testRootRelativeContext() failed", label); + } + + @Test + public void a6_testRootRelativeResource() { + assertEquals(r.eRootRelativeResource, in.uriContext.getRootRelativeServletPath(), "{0}: testRootRelativeResource() failed", label); + } + + @Test + public void a7_testRootRelativePath() { + assertEquals(r.eRootRelativePath, in.uriContext.getRootRelativePathInfo(), "{0}: testRootRelativePath() failed", label); + } +}
