Skip to content

Commit

Permalink
Wildcard prefix matching
Browse files Browse the repository at this point in the history
Fixes #430

Example:
prefixes.properties: com.example.dir.*=Wildcard
Test File:           com/example/dir/subdir/Test.java
Test Name:           WildcardTest
  • Loading branch information
brunobowden committed Oct 5, 2015
1 parent d9c4bfe commit dbb7626
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.github.j2objccontrib.j2objcgradle.tasks

import com.github.j2objccontrib.j2objcgradle.J2objcConfig
import com.google.common.annotations.VisibleForTesting
import groovy.transform.CompileStatic
import org.gradle.api.DefaultTask
import org.gradle.api.InvalidUserDataException
Expand All @@ -31,6 +32,7 @@ import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

import java.util.regex.Matcher
import java.util.regex.Pattern

/**
* Test task to run all unit tests and verify results.
Expand Down Expand Up @@ -226,6 +228,8 @@ class TestTask extends DefaultTask {
// depends on --prefixes dir/prefixes.properties in translateArgs
// Before: src/test/java/com/example/dir/SomeTest.java
// After: com.example.dir.SomeTest or PREFIXSomeTest
// TODO: Complexity is O(testCount * prefixCount), make more efficient if needed
@VisibleForTesting
static List<String> getTestNames(Project proj, FileCollection srcFiles, Properties packagePrefixes) {
List<String> testNames = srcFiles.collect { File file ->
// Back off to a fragile method that makes assumptions about source directories
Expand All @@ -242,17 +246,40 @@ class TestTask extends DefaultTask {
// Test Name: com.example.dir.SomeTest => PREFIXSomeTest

// First match against the set of Java packages, excluding the filename
Matcher matcher = (testName =~ /^(([^.]+\.)+)[^.]+$/) // (com.example.dir.)SomeTest
if (matcher.find()) {
String namespace = matcher.group(1) // com.example.dir.
String namespaceChopped = namespace[0..-2] // com.example.dir
if (packagePrefixes.containsKey(namespaceChopped)) {
String prefix = packagePrefixes.getProperty(namespaceChopped)
testName = testName.replace(namespace, prefix) // PREFIXSomeTest
Matcher packageMatcher = (testName =~ /^(.+)\.([^.]+)$/) // (com.example.dir.)SomeTest
if (packageMatcher.find()) {
String clazz = packageMatcher.group(packageMatcher.groupCount()) // SomeTest
String namespace = packageMatcher.group(1) // com.example.dir

for (Map.Entry<Object, Object> property in packagePrefixes.entrySet()) {
String keyStr = property.key as String
String valStr = property.value as String
assert null != keyStr
assert null != valStr

String keyRegex = wildcardToRegex(keyStr)
Matcher keyMatcher = (namespace =~ keyRegex)
if (keyMatcher.find()) {
testName = valStr + clazz // PrefixSomeTest
break
}
}
}
return testName // com.example.dir.SomeTest or PREFIXSomeTest
return testName // com.example.dir.SomeTest or PrefixSomeTest
}
return testNames
}

@VisibleForTesting
// Adapted from J2ObjC's PackagePrefixes.wildcardToRegex()
// https://github.com/google/j2objc/blob/master/translator/src/main/java/com/google/devtools/j2objc/util/PackagePrefixes.java#L219
static String wildcardToRegex(String s) {
if (s.endsWith(".*")) {
// Include root package in regex. For example, foo.bar.* needs to match
// foo.bar, foo.bar.mumble, etc.
String root = s.substring(0, s.length() - 2).replace(".", "\\.");
return String.format('^(%s|%s\\..*)$', root, root);
}
return String.format('^%s$', s.replace(".", "\\.").replace("\\*", ".*"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,32 +70,62 @@ class TestTaskTest {
@Test
void testGetTestNames_PackagePrefixes() {
Properties packagePrefixes = new Properties()
packagePrefixes.setProperty('com.example.parent', 'PrntPrefix')
packagePrefixes.setProperty('com.example.parent.subdir', 'SubPrefix')
packagePrefixes.setProperty('com.example.other', 'OthPrefix')
packagePrefixes.setProperty('com.example.parent', 'ParentPrefix')
packagePrefixes.setProperty('com.example.parent.subdir', 'SubDirPrefix')
packagePrefixes.setProperty('com.example.other', 'OtherPrefix')
packagePrefixes.setProperty('com.example.wildcard.*', 'WildcardPrefix')

// These are nonsense paths for files that don't exist
proj = ProjectBuilder.builder().build()
FileCollection srcFiles = proj.files([
"${proj.rootDir}/src/test/java/com/example/parent/ParentOneClass.java",
"${proj.rootDir}/src/test/java/com/example/parent/ParentTwoClass.java",
"${proj.rootDir}/src/test/java/com/example/parent/subdir/SubdirClass.java",
"${proj.rootDir}/src/test/java/com/example/other/OtherClass.java",
"${proj.rootDir}/src/test/java/com/example/noprefix/NoPrefixClass.java"])
"${proj.rootDir}/src/test/java/com/example/parent/ParentOne.java",
"${proj.rootDir}/src/test/java/com/example/parent/ParentTwo.java",
"${proj.rootDir}/src/test/java/com/example/parent/subdir/Subdir.java",
"${proj.rootDir}/src/test/java/com/example/other/Other.java",
"${proj.rootDir}/src/test/java/com/example/wildcard/Wildcard.java",
"${proj.rootDir}/src/test/java/com/example/wildcard/subdir/SubDirWildcard.java",
"${proj.rootDir}/src/test/java/com/example/noprefix/NoPrefix.java"])


List<String> testNames = TestTask.getTestNames(proj, srcFiles, packagePrefixes)

List<String> expectedTestNames = [
"PrntPrefixParentOneClass",
"PrntPrefixParentTwoClass",
"SubPrefixSubdirClass",
"OthPrefixOtherClass",
"ParentPrefixParentOne",
"ParentPrefixParentTwo",
"SubDirPrefixSubdir",
"OtherPrefixOther",
"WildcardPrefixWildcard",
"WildcardPrefixSubDirWildcard",
// No package prefix in this case
"com.example.noprefix.NoPrefixClass"]
"com.example.noprefix.NoPrefix"]

assert expectedTestNames == testNames
}

@Test
// Adapted from J2ObjC's PackagePrefixesTest.testWildcardToRegex()
// https://github.com/google/j2objc/blob/master/translator/src/test/java/com/google/devtools/j2objc/util/PackagePrefixesTest.java#L97
void testWildcardToRegex() throws IOException {
// Verify normal package name only matches itself.
String regex = TestTask.wildcardToRegex("com.example.dir");
assert '^com\\.example\\.dir$' == regex
assert 'com.example.dir'.matches(regex)
assert ! 'com example dir'.matches(regex) // Would match if wildcard wasn't converted.
assert ! 'com.example.dir.annotations'.matches(regex)

regex = TestTask.wildcardToRegex("foo.bar.*");
assert '^(foo\\.bar|foo\\.bar\\..*)$' == regex
assert 'foo.bar'.matches(regex)
assert 'foo.bar.mumble'.matches(regex)
assert 'foo.bar'.matches(regex)

regex = TestTask.wildcardToRegex("foo.\\*.bar");
assert '^foo\\..*\\.bar$' == regex
assert 'foo.some.bar'.matches(regex)
assert 'foo..bar'.matches(regex)
assert ! 'foobar'.matches(regex)
}

private void setupTask() {
(proj, j2objcHome, j2objcConfig) = TestingUtils.setupProject(new TestingUtils.ProjectConfig(
applyJavaPlugin: true,
Expand Down

0 comments on commit dbb7626

Please sign in to comment.