/* * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a> * * Licensed 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.ocpsoft.rewrite.param; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.ocpsoft.rewrite.MockEvaluationContext; import org.ocpsoft.rewrite.MockRewrite; import org.ocpsoft.rewrite.context.EvaluationContext; import org.ocpsoft.rewrite.util.ParseTools.CaptureType; /** * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a> * */ public class ParameterizedPatternTest { private MockRewrite event; private EvaluationContext context; public static void initialize(ParameterStore store, Parameterized parameterized) { Set<String> names = parameterized.getRequiredParameterNames(); for (String name : names) { store.get(name, new DefaultParameter(name)); } parameterized.setParameterStore(store); } @Before public void before() { event = new MockRewrite(); context = new MockEvaluationContext(); context.put(ParameterStore.class, new DefaultParameterStore()); context.put(ParameterValueStore.class, new DefaultParameterValueStore()); } @Test public void testComplexMatchingWithMutipleAdjacentParameters() throws Exception { String url = "http://domain.com:8080/context/application/pathy?foo=bar&baz=bazaar"; ParameterizedPatternParser path = new RegexParameterizedPatternParser( "{prefix}/application/{seg}{suffix}"); ParameterStore store = DefaultParameterStore.getInstance(context); initialize(store, path); ((ConfigurableParameter<?>) store.get("prefix")).constrainedBy(new RegexConstraint(".*")); ((ConfigurableParameter<?>) store.get("seg")).constrainedBy(new RegexConstraint("[^/]+")); ((ConfigurableParameter<?>) store.get("suffix")).constrainedBy(new RegexConstraint("\\?.*")); initialize(store, path); Assert.assertTrue(path.parse(url).matches()); String[] expected = new String[] { "http://domain.com:8080/context", "pathy", "?foo=bar&baz=bazaar" }; Map<Parameter<?>, String> parsed = path.parse(url).getParameters(context); int index = 0; for (Entry<Parameter<?>, String> entry : parsed.entrySet()) { String value = entry.getValue(); Assert.assertEquals(expected[index++], value); } } @Test public void testComplexMatchingWithGroupsInRegexConstraints() throws Exception { String url = "http://domain.com:8080/context/application/pathy?foo=bar&baz=bazaar"; ParameterizedPatternParser path = new RegexParameterizedPatternParser( "{prefix}/application/{seg}{suffix}"); ParameterStore store = DefaultParameterStore.getInstance(context); initialize(store, path); ((ConfigurableParameter<?>) store.get("prefix")).constrainedBy(new RegexConstraint("((.*)?)")); ((ConfigurableParameter<?>) store.get("seg")) .constrainedBy(new RegexConstraint("([^/]+)")) .constrainedBy(new RegexConstraint("(pathy)")) .constrainedBy(new RegexConstraint("\\w{5}")); ((ConfigurableParameter<?>) store.get("suffix")).constrainedBy(new RegexConstraint("\\?.*")); initialize(store, path); Assert.assertTrue(path.parse(url).matches()); String[] expected = new String[] { "http://domain.com:8080/context", "pathy", "?foo=bar&baz=bazaar" }; Map<Parameter<?>, String> parsed = path.parse(url).getParameters(context); int index = 0; for (Entry<Parameter<?>, String> entry : parsed.entrySet()) { String value = entry.getValue(); Assert.assertEquals(expected[index++], value); } } @Test public void testEscapingWindowsFilePathsNoParams() { String pattern = "c:\\\\Users\\\\Admin\\\\Documents and Settings\\\\Folder"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(0, parameterized.getRequiredParameterNames().size()); Assert.assertFalse(parameterized.parse(pattern).matches()); String value = pattern.replaceAll("\\\\\\\\", "\\\\"); Assert.assertTrue(parameterized.parse(value).matches()); } @Test public void testEscapingWindowsFilePathsWithParams() { String pattern = "c:\\\\Users\\\\{user}\\\\Documents and Settings\\\\Folder"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(1, parameterized.getRequiredParameterNames().size()); Assert.assertFalse(parameterized.parse(pattern).matches()); String value = pattern.replaceAll("\\\\\\\\", "\\\\"); Assert.assertTrue(parameterized.parse(value).matches()); } @Test public void testEscapingParams() { String pattern = "Something \\{wicked this way comes."; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(0, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("Something {wicked this way comes.").matches()); } @Test public void testEscapingParams1() { String pattern = "Something \\{wicked this way comes.}"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(0, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("Something {wicked this way comes.}").matches()); } @Test public void testEscapingParams2() { String pattern = "Something \\{{wicked this way comes}."; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(1, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("Something {cool.").matches()); } @Test public void testEscapingParams3() { String pattern = "Something \\{{wicked this way comes}. More {stuff}"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(2, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("Something {cool. More anything").matches()); } @Test public void testEscapingParams4() { String pattern = "beginning \\{middle\\} end"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(0, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("beginning {middle\\} end").matches()); } @Test public void testEscapingParamsWithNewlines() { String pattern = "beginning {\nmiddle\n} end"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(1, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("beginning middle end").matches()); } @Test public void testEscapingParamsWithNewlines2() { String pattern = "beginning \\{\n ...\n } end"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(0, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("beginning {\n ...\n } end").matches()); } @Test public void testEscapingWithNewlines() { String pattern = "beginning \\{\nmiddle\n} end"; ParameterizedPatternParser parameterized = new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); Assert.assertEquals(0, parameterized.getRequiredParameterNames().size()); Assert.assertTrue(parameterized.parse("beginning {\nmiddle\n} end").matches()); } @Test(expected = ParameterizedPatternSyntaxException.class) public void testIllegalEscapingParams() { String pattern = "Something {wicked\\}."; new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); } @Test(expected = ParameterizedPatternSyntaxException.class) public void testIllegalEscaping() { String pattern = "\\c"; new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); } @Test(expected = ParameterizedPatternSyntaxException.class) public void testIllegalPartialEscapingAtStart() { String pattern = "\\"; new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); } @Test(expected = ParameterizedPatternSyntaxException.class) public void testIllegalPartialEscapingAtEnd() { String pattern = "asdfdsf\\"; new RegexParameterizedPatternParser(CaptureType.BRACE, pattern); } @Test public void testCannotUseRegularExpressionsWithoutParameter() { ParameterizedPatternParser path = new RegexParameterizedPatternParser(CaptureType.BRACE, ".*"); Assert.assertEquals(0, path.getRequiredParameterNames().size()); Assert.assertFalse(path.parse("/omg/doesnt/matter").matches()); } @Test public void testMatchesEmptyPath() { ParameterizedPatternParser path = new RegexParameterizedPatternParser(CaptureType.BRACE, ""); Assert.assertEquals(0, path.getRequiredParameterNames().size()); Assert.assertTrue(path.parse("").matches()); Map<Parameter<?>, String> results = path.parse("").getParameters(context); Assert.assertNotNull(results); } @Test public void testMatchesEmptyPathNoTransforms() { ParameterizedPatternParser path = new RegexParameterizedPatternParser(CaptureType.BRACE, ""); Assert.assertEquals(0, path.getRequiredParameterNames().size()); Assert.assertTrue(path.parse("").matches()); Map<Parameter<?>, String> results = path.parse("").getParameters(context); Assert.assertNotNull(results); } @Test public void testMatchesBarePath() { ParameterizedPatternParser path = new RegexParameterizedPatternParser("/"); Assert.assertEquals(0, path.getRequiredParameterNames().size()); Assert.assertTrue(path.parse("/").matches()); Map<Parameter<?>, String> results = path.parse("/").getParameters(context); Assert.assertNotNull(results); } @Test public void testMatchesWithParameters() { ParameterizedPatternParser path = new RegexParameterizedPatternParser("[^/]+", "/{customer}/orders/{id}"); ParameterStore parameters = DefaultParameterStore.getInstance(context); initialize(parameters, path); Assert.assertEquals(2, parameters.size()); Assert.assertEquals("customer", parameters.get("customer").getName()); Assert.assertEquals("id", parameters.get("id").getName()); Map<Parameter<?>, String> results = path.parse("/lincoln/orders/24").getParameters(context); Assert.assertEquals("lincoln", results.get(parameters.get("customer"))); Assert.assertEquals("24", results.get(parameters.get("id"))); } @Test public void testMatchesWithParametersNoTransforms() { ParameterizedPatternParser path = new RegexParameterizedPatternParser("[^/]+", "/{customer}/orders/{id}"); ParameterStore parameters = DefaultParameterStore.getInstance(context); initialize(parameters, path); Assert.assertEquals(2, parameters.size()); Assert.assertEquals("customer", parameters.get("customer").getName()); Assert.assertEquals("id", parameters.get("id").getName()); Map<Parameter<?>, String> results = path.parse("/lincoln/orders/24").getParameters(context); Assert.assertEquals("lincoln", results.get(parameters.get("customer"))); Assert.assertEquals("24", results.get(parameters.get("id"))); } @Test public void testMatchesWithParametersRespectsTrailingCharsWithWildcardParameter() { ParameterizedPatternParser path = new RegexParameterizedPatternParser(".*", "/{customer}/"); ParameterStore parameters = new DefaultParameterStore(); initialize(parameters, path); Assert.assertTrue(path.parse("/lincoln/").matches()); Assert.assertFalse(path.parse("/lincoln/foo").matches()); } @Test public void testRegularExpressionsAreDisabled() { ParameterizedPatternParser path = new RegexParameterizedPatternParser("[^/]+", ".*/{customer}/"); Assert.assertTrue(path.parse(".*/lincoln/").matches()); Assert.assertFalse(path.parse("foobar/lincoln/").matches()); } @Test public void testAccessExistingParameterSucceeds() { ParameterizedPatternParser path = new RegexParameterizedPatternParser("[^/]+", ".*/{customer}/"); ParameterStore parameters = new DefaultParameterStore(); initialize(parameters, path); Parameter<?> parameter = parameters.get("customer"); Assert.assertNotNull(parameter); } @Test(expected = IllegalArgumentException.class) public void testAccessNonExistentParameterThrowsException() { ParameterizedPatternParser path = new RegexParameterizedPatternParser("[^/]+", ".*/{customer}/"); ParameterStore parameters = new DefaultParameterStore(); initialize(parameters, path); parameters.get("something else"); } @Test public void testParametersUsedMultipleRequireSingleConfiguration() { ParameterizedPatternParser path = new RegexParameterizedPatternParser("/{f}/{f}/"); ParameterStore parameters = new DefaultParameterStore(); initialize(parameters, path); ((ConfigurableParameter<?>) parameters.get("f")).constrainedBy(new RegexConstraint("foo")); Assert.assertTrue(path.parse("/foo/foo/").matches()); Assert.assertFalse(path.parse("/foo/bar/").matches()); } @Test public void testParsesWithParametersRespectsTrailingCharsWithWildcardParameter() { ParameterizedPatternParser path = new RegexParameterizedPatternParser(".*", "/{customer}/"); ParameterStore parameters = DefaultParameterStore.getInstance(context); initialize(parameters, path); Assert.assertEquals(1, parameters.size()); Assert.assertEquals("customer", parameters.get("customer").getName()); Map<Parameter<?>, String> results = path.parse("/lincoln/").getParameters(context); Assert.assertEquals("lincoln", results.get(parameters.get("customer"))); } @Test public void testParsesWithParametersEscapesTrailingChars() { ParameterizedPatternParser path = new RegexParameterizedPatternParser(".*", "/{customer}."); ParameterStore parameters = DefaultParameterStore.getInstance(context); initialize(parameters, path); Assert.assertEquals(1, parameters.size()); Assert.assertEquals("customer", parameters.get("customer").getName()); Assert.assertFalse(path.parse("/lincolnX").matches()); Assert.assertFalse(path.parse("/lincolnX").isValid(event, context)); Assert.assertFalse(path.parse("/lincoln/").submit(event, context)); Assert.assertTrue(path.parse("/lincoln.").matches()); } @Test public void testMatchesWithParametersAndTrailingSlash() { ParameterizedPatternParser path = new RegexParameterizedPatternBuilder("[^/]+", "/{customer}/orders/{id}/") .getParser(); ParameterStore parameters = DefaultParameterStore.getInstance(context); initialize(parameters, path); Assert.assertEquals(2, parameters.size()); Assert.assertEquals("customer", parameters.get("customer").getName()); Assert.assertEquals("id", parameters.get("id").getName()); ParameterizedPatternResult result = path.parse("/lincoln/orders/24/"); Assert.assertTrue(result.matches()); Assert.assertTrue(result.isValid(event, context)); Assert.assertTrue(result.submit(event, context)); Map<Parameter<?>, String> results = result.getParameters(context); Assert.assertEquals("lincoln", results.get(parameters.get("customer"))); Assert.assertEquals("24", results.get(parameters.get("id"))); } @Test(expected = IllegalArgumentException.class) public void testBuildNull() { ParameterizedPatternBuilder path = new RegexParameterizedPatternBuilder(null); Assert.assertEquals("", path.build(new LinkedHashMap<String, Object>())); } @Test public void testBuildEmpty() { ParameterizedPatternBuilder path = new RegexParameterizedPatternBuilder(""); Assert.assertEquals("", path.build(new LinkedHashMap<String, Object>())); } @Test public void testBuildBarePath() { ParameterizedPatternBuilder path = new RegexParameterizedPatternBuilder("/"); Assert.assertEquals("/", path.build(new LinkedHashMap<String, Object>())); } @Test public void testBuildWithMapParameters() { ParameterizedPatternBuilder path = new RegexParameterizedPatternParser("[^/]*", "/{customer}/orders/{id}") .getBuilder(); Map<String, Object> map = new LinkedHashMap<String, Object>(); map.put("customer", "lincoln"); map.put("id", "24"); Assert.assertEquals("/lincoln/orders/24", path.build(map)); } @Test public void testBuildWithListParameters() { ParameterizedPatternBuilder path = new RegexParameterizedPatternBuilder("[^/]*", "/{customer}/orders/{id}"); Assert.assertEquals("/lincoln/orders/24", path.build(Arrays.<Object> asList("lincoln", "24"))); } }