package org.basex.http.restxq; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; import static java.math.BigInteger.TEN; import static org.junit.Assert.*; import org.basex.query.value.item.QNm; import org.hamcrest.CustomTypeSafeMatcher; import org.junit.Ignore; import org.junit.Test; import java.math.BigInteger; import java.util.Arrays; import java.util.Map; import java.util.Objects; /** * Path matcher tests. * * @author BaseX Team 2005-17, BSD License * @author Dimitar Popov */ public final class RestXqPathMatcherTest { /** Test. * @throws Exception exception */ @Test public void testParseEmptyPath() throws Exception { testParse("", "/", 0, ZERO); } /** Test. * @throws Exception exception */ @Test public void testParseSimplePath() throws Exception { testParse("/a/b/c#xyz", "/a/b/c#xyz", 3, ZERO); } /** Test. * @throws Exception exception */ @Test public void testParseSimplePathWithoutSlash() throws Exception { testParse("a/b/c#xyz", "/a/b/c#xyz", 3, ZERO); } /** Test. * @throws Exception exception */ @Test public void testParseRegexEscape() throws Exception { testParse("/a/b/c-d.f#xyz", "/a/b/c\\-d\\.f#xyz", 3, ZERO); } /** Test. * @throws Exception exception */ @Test public void testParseSimpleVariables() throws Exception { testParse( "/a1/{ $var1 }/a2/{ $var2 }/a3", "/a1/([^/]+?)/a2/([^/]+?)/a3", 5, TEN, new QNm("var1"), new QNm("var2")); } /** Test. * @throws Exception exception */ @Test public void testParseQualifiedVariables() throws Exception { testParse( "/a1/{ $n:var1 }/a2/{ $m:var2 }/a3", "/a1/([^/]+?)/a2/([^/]+?)/a3", 5, TEN, new QNm("n:var1"), new QNm("m:var2")); } /** Test. * @throws Exception exception */ @Ignore @Test public void testParseExtendedQualifiedVariables() throws Exception { testParse( "/a1/{ $n:var1 }/a2/{ $Q{m}var2 }/a3", "/a1/([^/]+?)/a2/([^/]+?)/a3", 5, TEN, new QNm("n:var1"), new QNm("var2", "m")); } /** Test. * @throws Exception exception */ @Test public void testParseVariablesWithSimpleRegex() throws Exception { testParse( "/a1/{ $n:var1\t=\t.+ }/a2/{$m:var2=[1-9][0-9]+}/a3", "/a1/(.+)/a2/([1-9][0-9]+)/a3", 5, TEN, new QNm("n:var1"), new QNm("m:var2")); } /** Test. * @throws Exception exception */ @Test public void testParseVariablesWithComplexRegex() throws Exception { testParse( "/a1/{ $n:var1\t=\t.+ }/a2/{ $m:var2 = [1-9][0-9]{3,10} }/a3", "/a1/(.+)/a2/([1-9][0-9]{3,10})/a3", 5, TEN, new QNm("n:var1"), new QNm("m:var2")); } /** Test. * @throws Exception exception */ @Test public void testParseVariablesWithGroupsInRegex() throws Exception { testParse( "/a1{$p=(/.*)?}", "/a1((/.*)?)", 1, ONE, new QNm("p")); } /** Test. * @throws Exception exception */ @Test public void testValuesNoMatch() throws Exception { testValues("/a1{$p=(/.*)?}", "/a1b/c", "p", null); } /** Test. * @throws Exception exception */ @Test public void testValuesNoTrailingSlash() throws Exception { testValues("/a1{$p=(/.*)?}", "/a1", "p", ""); } /** Test. * @throws Exception exception */ @Test public void testValuesWithTrailingSlash() throws Exception { testValues("/a1{$p=(/.*)?}", "/a1/", "p", "/"); } /** Test. * @throws Exception exception */ @Test public void testValuesMatched() throws Exception { testValues("/a1{$p=(/.*)?}", "/a1/b/c/d", "p", "/b/c/d"); } /** Test. * @throws Exception exception */ @Test public void testValuesMatchedSeveralVariables() throws Exception { testValues("/a1/{$l=(b|d)}/{$d=(0|((12)?3))}", "/a1/b/123", "l", "b"); testValues("/a1/{$l=(b|d)}/{$d=(0|((12)?3))}", "/a1/b/123", "d", "123"); } /** * Performs a test. * @param template template * @param path path * @param var variable * @param val value * @throws Exception arbitrary exception */ private static void testValues(final String template, final String path, final String var, final String val) throws Exception { final Map<QNm, String> actual = RestXqPathMatcher.parse(template, null).values(path); assertThat(actual, new CustomTypeSafeMatcher<Map<QNm, String>>("values differ") { @Override protected boolean matchesSafely(final Map<QNm, String> item) { return Objects.equals(val, item.get(new QNm(var))); } }); } /** * Parses the specified input. * @param input input * @param regex regular expression * @param segments number of segments * @param variables variable positions * @param vars variables * @throws Exception exception */ private static void testParse(final String input, final String regex, final int segments, final BigInteger variables, final QNm... vars) throws Exception { final RestXqPathMatcher p = RestXqPathMatcher.parse(input, null); assertEquals(regex, p.pattern.toString()); assertEquals(Arrays.asList(vars), p.vars); assertEquals(segments, p.segments); assertEquals(variables, p.varsPos); } }