diff --git a/matcher/src/main/java/com/pressassociation/pr/match/Matcher.java b/matcher/src/main/java/com/pressassociation/pr/match/Matcher.java index 94131f1..17587a1 100644 --- a/matcher/src/main/java/com/pressassociation/pr/match/Matcher.java +++ b/matcher/src/main/java/com/pressassociation/pr/match/Matcher.java @@ -54,6 +54,13 @@ public static Matcher all() { return AllMatcher.INSTANCE; } + /** + * Return a Matcher that will not match any path. Equivalent to {@code Matchers.of("")}. + */ + public static Matcher none() { + return NoneMatcher.INSTANCE; + } + /** * Get a new Matcher that will match against the given fields string. The string should be a valid fields string, * something like {@code items/name(type,value)}. @@ -66,6 +73,9 @@ public static Matcher of(CharSequence fields) { if ("*".equals(fields)) { return all(); } + if (fields.toString().isEmpty()) { + return none(); + } return new AstMatcher(new Parser().parse(checkNotNull(fields))); } diff --git a/matcher/src/main/java/com/pressassociation/pr/match/NoneMatcher.java b/matcher/src/main/java/com/pressassociation/pr/match/NoneMatcher.java new file mode 100644 index 0000000..427ba33 --- /dev/null +++ b/matcher/src/main/java/com/pressassociation/pr/match/NoneMatcher.java @@ -0,0 +1,60 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2014 Press Association Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.pressassociation.pr.match; + +/** + * Matcher implementation that doesn't match anything. + * + * @author Matt Nathan + */ +class NoneMatcher extends Matcher { + + static final Matcher INSTANCE = new NoneMatcher(); + + @Override + public boolean matches(Leaf leaf) { + return false; + } + + @Override + public boolean matchesAll() { + return false; + } + + @Override + public boolean matchesParent(Leaf node) { + return false; + } + + @Override + protected String patternString() { + return ""; + } + + @Override + public String toString() { + return "Matcher.none()"; + } +} diff --git a/matcher/src/test/java/com/pressassociation/pr/match/MatcherTest.java b/matcher/src/test/java/com/pressassociation/pr/match/MatcherTest.java index f969419..ea676d1 100644 --- a/matcher/src/test/java/com/pressassociation/pr/match/MatcherTest.java +++ b/matcher/src/test/java/com/pressassociation/pr/match/MatcherTest.java @@ -67,12 +67,29 @@ public void testReadmeExamples() { assertFalse(matcher.matches("/spouse/children")); } + @Test + public void testEmptyIsNone() { + assertSame(Matcher.none(), Matcher.of("")); + } + @Test public void testMatchesAll() { assertTrue(Matcher.of("*").matchesAll()); assertTrue(Matcher.all().matchesAll()); assertFalse(Matcher.of("all").matchesAll()); assertFalse(Matcher.of("all/*").matchesAll()); + assertFalse(Matcher.of("").matchesAll()); + assertFalse(Matcher.none().matchesAll()); + } + + @Test + @Parameters({ + "a", + "a/b", + "foo/bar/baz" + }) + public void testNoneMatchesNothing(CharSequence path) { + assertFalse(Matcher.none().matches(path)); } @Test @@ -122,6 +139,16 @@ public void testMatchesParentAll() { assertTrue(Matcher.all().matchesParent("my/node/continues")); } + @Test + @Parameters({ + "a", + "a/b", + "foo/bar/baz" + }) + public void testNoneMatchesNothingParent(CharSequence path) { + assertFalse(Matcher.none().matchesParent(path)); + } + @Test public void testTransform() { assertEquals("*", Matcher.all().transform(Functions.constant("foo")).patternString());