Skip to content

Commit

Permalink
additional tests for contains and trigrams (#1078)
Browse files Browse the repository at this point in the history
Put in some additional test cases for extracting contained
strings and trigrams from patterns. Fixes some cases with
trigram extraction for repeats that can be absent from the
string and still match.
  • Loading branch information
brharrington authored Aug 29, 2023
1 parent 9e8a488 commit 19e5a8f
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ String pattern() {
return pattern;
}

@Override
public String containedString() {
return pattern;
}

@Override
public SortedSet<String> trigrams() {
return PatternUtils.computeTrigrams(pattern);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.netflix.spectator.impl.matcher;

import java.io.Serializable;
import java.util.Collections;
import java.util.Objects;
import java.util.SortedSet;
import java.util.function.Function;
Expand Down Expand Up @@ -48,9 +49,14 @@ int max() {
return max;
}

@Override
public String containedString() {
return min == 0 ? null : repeated.containedString();
}

@Override
public SortedSet<String> trigrams() {
return repeated.trigrams();
return min == 0 ? Collections.emptySortedSet() : repeated.trigrams();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ public String prefix() {

@Override
public String containedString() {
return matchers[0].containedString();
String str = null;
for (Matcher m : matchers) {
str = m.containedString();
if (str != null) break;
}
return str;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.io.Serializable;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -49,12 +48,14 @@ Matcher next() {
return next;
}

@Override
public String containedString() {
return next.containedString();
}

@Override
public SortedSet<String> trigrams() {
SortedSet<String> ts = new TreeSet<>();
ts.addAll(repeated.trigrams());
ts.addAll(next.trigrams());
return ts;
return next.trigrams();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.io.Serializable;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -49,12 +48,14 @@ Matcher next() {
return next;
}

@Override
public String containedString() {
return next.containedString();
}

@Override
public SortedSet<String> trigrams() {
SortedSet<String> ts = new TreeSet<>();
ts.addAll(repeated.trigrams());
ts.addAll(next.trigrams());
return ts;
return next.trigrams();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,14 @@ public void zeroOrMoreWithOr() {
testRE("(a|b|c)*d", "ababcd");
}

@Test
public void repeatZero() {
testRE("(abc){0,3}def", "def");
testRE("(abc){0,3}def", "abcdef");
testRE("(abc){1,3}def", "def");
testRE("(abc){1,3}def", "abcdef");
}

@Test
public void repeatWithOr() {
testRE("(a|b|c){1,3}d", "aaad");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2014-2023 Netflix, Inc.
*
* 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 com.netflix.spectator.impl.matcher;

import com.netflix.spectator.impl.PatternMatcher;
import org.junit.jupiter.api.Assertions;

public class ContainsPatternMatcherTest extends AbstractPatternMatcherTest {

@Override
protected void testRE(String regex, String value) {
PatternMatcher matcher = PatternMatcher.compile(regex);
String str = matcher.containedString();

// Contains should be more lenient than the actual pattern, so anything that is matched
// by the pattern must be a possible match with the trigrams.
if (str != null && matcher.matches(value)) {
Assertions.assertTrue(value.contains(str));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,46 @@ public void notContains() {
public void containedString() {
Assertions.assertEquals("abc", re("abc").containedString());
Assertions.assertEquals("abc", re(".*abc").containedString());
Assertions.assertEquals("abc", re(".*abc$").containedString());
Assertions.assertEquals("ab", re(".*ab[cd]").containedString());
Assertions.assertEquals("abc", re("abc.def").containedString());
Assertions.assertEquals("abc.def", re("abc\\.def").containedString());
Assertions.assertEquals("abc", re("^abc.def").containedString());
Assertions.assertEquals("abc.def", re("^abc\\.def").containedString());
}

@Test
public void containsZeroOrMore() {
Assertions.assertEquals("def", re("(abc)*def").containedString());
}

@Test
public void containsZeroOrOne() {
Assertions.assertEquals("def", re("(abc)?def").containedString());
}

@Test
public void containsOneOrMore() {
Assertions.assertEquals("abc", re("(abc)+def").containedString());
}

@Test
public void containsRepeat() {
Assertions.assertEquals("def", re("(abc){0,5}def").containedString());
}

@Test
public void containsRepeatAtLeastOne() {
Assertions.assertEquals("abc", re("(abc){1,5}def").containedString());
}

@Test
public void containsPartOfSequence() {
Assertions.assertEquals("abcd", re(".*[0-9]abcd[efg]hij").containedString());
}

@Test
public void containsMultiple() {
Assertions.assertEquals("abc", re("^abc.*def.*ghi").containedString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2014-2023 Netflix, Inc.
*
* 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 com.netflix.spectator.impl.matcher;

import com.netflix.spectator.impl.PatternMatcher;
import org.junit.jupiter.api.Assertions;

import java.util.SortedSet;

public class TrigramsPatternMatcherTest extends AbstractPatternMatcherTest {

@Override
protected void testRE(String regex, String value) {
PatternMatcher matcher = PatternMatcher.compile(regex);
SortedSet<String> trigrams = matcher.trigrams();

// Trigrams should be more lenient than the actual pattern, so anything that is matched
// by the pattern must be a possible match with the trigrams.
if (matcher.matches(value)) {
Assertions.assertTrue(couldMatch(trigrams, value));
}
}

private boolean couldMatch(SortedSet<String> trigrams, String value) {
return trigrams.stream().allMatch(value::contains);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ public void endsWith() {
@Test
public void zeroOrMore() {
PatternMatcher m = PatternMatcher.compile("(abc)*def");
Assertions.assertEquals(sortedSet("abc", "def"), m.trigrams());
Assertions.assertEquals(sortedSet("def"), m.trigrams());
}

@Test
public void zeroOrOne() {
PatternMatcher m = PatternMatcher.compile("(abc)?def");
Assertions.assertEquals(sortedSet("abc", "def"), m.trigrams());
Assertions.assertEquals(sortedSet("def"), m.trigrams());
}

@Test
Expand All @@ -66,6 +66,12 @@ public void oneOrMore() {
@Test
public void repeat() {
PatternMatcher m = PatternMatcher.compile("(abc){0,5}def");
Assertions.assertEquals(sortedSet("def"), m.trigrams());
}

@Test
public void repeatAtLeastOne() {
PatternMatcher m = PatternMatcher.compile("(abc){1,5}def");
Assertions.assertEquals(sortedSet("abc", "def"), m.trigrams());
}

Expand Down

0 comments on commit 19e5a8f

Please sign in to comment.