-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#641 Added tooling tests #880
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import org.apache.tools.ant.filters.ReplaceTokens | ||
|
||
plugins { | ||
id 'archunit.java-production-conventions' | ||
} | ||
|
||
ext.moduleName = 'com.tngtech.archunit.tooling' | ||
ext.minimumJavaVersion = JavaVersion.VERSION_1_9 | ||
|
||
sourceSets { | ||
testFixtures { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't just apply |
||
java { | ||
compileClasspath += main.compileClasspath | ||
runtimeClasspath += main.runtimeClasspath | ||
} | ||
} | ||
main { | ||
java { | ||
compileClasspath += project.sourceSets.testFixtures.output | ||
runtimeClasspath += project.sourceSets.testFixtures.output | ||
} | ||
} | ||
test { | ||
java { | ||
compileClasspath += project.sourceSets.testFixtures.output | ||
runtimeClasspath += project.sourceSets.testFixtures.output | ||
} | ||
} | ||
} | ||
|
||
jar.enabled = false | ||
|
||
task copyFixtureSources(type: Copy) { | ||
into new File(project.sourceSets.testFixtures.output.resourcesDir, '@sources') | ||
from(project.sourceSets.testFixtures.java) { | ||
include '**/*.java' | ||
} | ||
} | ||
|
||
processTestFixturesResources { | ||
filesMatching(['**/pom.xml', '**/build.gradle']) { | ||
filter ReplaceTokens, tokens: [ | ||
"junitDependency.version": project.property("archunit.version") | ||
] | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation project(path: ':archunit-junit5-engine-api') | ||
implementation project(path: ':archunit-junit5-engine') | ||
implementation project(path: ':archunit-junit4') | ||
implementation dependency.junit5JupiterEngine | ||
implementation dependency.junit5VintageEngine | ||
implementation dependency.junitPlatform | ||
implementation dependency.junitPlatformLauncher | ||
implementation dependency.guava | ||
implementation dependency.systemLambda | ||
implementation dependency.mavenInvoker | ||
implementation dependency.surefireReportParser | ||
implementation dependency.commonsIo | ||
implementation dependency.gradleToolingApi | ||
implementation dependency.surefireSharedUtils | ||
|
||
compileOnly dependency.findBugsAnnotations | ||
|
||
testFixturesImplementation project(path: ':archunit') | ||
testFixturesImplementation project(path: ':archunit-junit5-engine-api') | ||
testFixturesImplementation project(path: ':archunit-junit5-api') | ||
testFixturesImplementation project(path: ':archunit-junit5-engine') | ||
testFixturesImplementation project(path: ':archunit-junit4') | ||
testFixturesImplementation dependency.junitPlatform | ||
testFixturesImplementation dependency.junit5JupiterEngine | ||
testFixturesImplementation dependency.junit5JupiterApi | ||
|
||
testImplementation dependency.assertj | ||
testImplementation dependency.junitJupiterParams | ||
testImplementation dependency.junitPioneer | ||
} | ||
|
||
String getMavenRepoPath(Project project) { | ||
def pubs = project.publishing.publications.findAll() as Set<MavenPublication> | ||
def pub = pubs[0] | ||
if (!pub){ | ||
return null | ||
} | ||
String groupPath = pub.groupId.replace('.', '/') | ||
return "$groupPath/$pub.artifactId" | ||
} | ||
|
||
def resolveAgainstMavenLocal(String path) { | ||
new File(new File(repositories.mavenLocal().url), path) | ||
} | ||
|
||
def deleteSafely(File file) { | ||
if (file.exists()) { | ||
println "Deleting ${file.toURI().toString()}" | ||
delete file | ||
} else { | ||
println "Could not find ${file.toURI().toString()}" | ||
} | ||
} | ||
|
||
task removeFromMavenLocal { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This task cleans the local Maven repo to make sure we are running the Surefire and Gradle tests with an up-to-date version of ArchUnit jars |
||
group = 'other' | ||
description = 'Remove artifact and all versions/classifiers/flavors from local maven repository.' | ||
doLast { | ||
[project(':archunit-junit5-engine-api'), | ||
project(':archunit-junit5-engine'), | ||
project(':archunit-junit5-api'), | ||
project(':archunit-junit5'), | ||
project(':archunit-junit4'), | ||
project(':archunit')].each { project -> | ||
File file = resolveAgainstMavenLocal(getMavenRepoPath(project)) | ||
deleteSafely file | ||
} | ||
} | ||
} | ||
|
||
task publishJUnitDepsToMavenLocal { | ||
group = 'other' | ||
description = 'Publishes ArchUnit JUnit artifacts to local Maven repo' | ||
dependsOn project(':archunit-junit5-engine-api').tasks.publishMavenJavaPublicationToMavenLocal | ||
dependsOn project(':archunit-junit5-engine').tasks.publishMavenJavaPublicationToMavenLocal | ||
dependsOn project(':archunit-junit5-api').tasks.publishMavenJavaPublicationToMavenLocal | ||
dependsOn project(':archunit-junit5').tasks.publishMavenJavaPublicationToMavenLocal | ||
dependsOn project(':archunit-junit4').tasks.publishMavenJavaPublicationToMavenLocal | ||
dependsOn project(':archunit').tasks.publishMavenJavaPublicationToMavenLocal | ||
} | ||
|
||
clean { | ||
dependsOn removeFromMavenLocal | ||
} | ||
|
||
test { | ||
dependsOn copyFixtureSources, publishJUnitDepsToMavenLocal | ||
useJUnitPlatform() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package com.tngtech.archunit.tooling; | ||
|
||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.regex.Pattern; | ||
|
||
public class ExecutedTestFile { | ||
private final String fixture; | ||
private final Map<String, TestResult> results = new ConcurrentHashMap<>(); | ||
|
||
public ExecutedTestFile(String fixture) { | ||
this.fixture = fixture; | ||
} | ||
|
||
public String getFixture() { | ||
return fixture; | ||
} | ||
|
||
public Map<String, TestResult> getResults() { | ||
return Collections.unmodifiableMap(results); | ||
} | ||
|
||
public int size() { | ||
return results.size(); | ||
} | ||
|
||
public Optional<TestResult> getResult(String testCase) { | ||
return Optional.ofNullable(results.get(testCase)) | ||
.or(() -> findMatchingParameterizedTestName(testCase).map(results::get)); | ||
} | ||
|
||
private Optional<String> findMatchingParameterizedTestName(String testCase) { | ||
Pattern parameterizedPattern = Pattern.compile(testCase + "\\(.*\\)"); | ||
return results.keySet().stream() | ||
.filter(key -> parameterizedPattern.matcher(key).matches()) | ||
.findAny(); | ||
} | ||
|
||
public void addResult(String testCase, TestResult result) { | ||
results.put(testCase, result); | ||
} | ||
|
||
public boolean hasInitializationError() { | ||
return getResult("initializationError").isPresent(); | ||
} | ||
|
||
public enum TestResult { | ||
SUCCESS, | ||
FAILURE, | ||
ERROR, | ||
SKIPPED | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.tngtech.archunit.tooling; | ||
|
||
public interface TestEngine { | ||
|
||
TestReport execute(TestFile testFiles) throws Exception; | ||
|
||
default boolean reportsErrors() { | ||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.tngtech.archunit.tooling; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
|
||
public class TestFile { | ||
private final Class<?> fixture; | ||
private final Set<String> testCases; | ||
|
||
public TestFile(Class<?> fixture, Set<String> testCases) { | ||
this.fixture = fixture; | ||
this.testCases = testCases; | ||
} | ||
|
||
public TestFile(Class<?> fixture, String testCase, String... more) { | ||
this(fixture, toSet(testCase, more)); | ||
} | ||
|
||
private static Set<String> toSet(String testCase, String[] more) { | ||
Set<String> result = new HashSet<>(); | ||
result.add(testCase); | ||
result.addAll(Arrays.asList(more)); | ||
return result; | ||
} | ||
|
||
public TestFile(Class<?> fixture) { | ||
this(fixture, null); | ||
} | ||
|
||
public Class<?> getFixture() { | ||
return fixture; | ||
} | ||
|
||
public Set<String> getTestCases() { | ||
return testCases; | ||
} | ||
|
||
public boolean hasTestCasesFilter() { | ||
return Objects.nonNull(testCases); | ||
} | ||
|
||
public boolean isSuite() { | ||
return fixture.getSimpleName().contains("Suite"); | ||
} | ||
|
||
public TestingFramework getTestingFramework() { | ||
if (fixture.getSimpleName().contains("JUnit4")) { | ||
return TestingFramework.JUNIT4; | ||
} | ||
if (fixture.getSimpleName().contains("JUnit5")) { | ||
return TestingFramework.JUNIT5; | ||
} | ||
throw new IllegalStateException("Could not determine testing framework"); | ||
} | ||
|
||
public enum TestingFramework { | ||
JUNIT4, | ||
JUNIT5 | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
if (hasTestCasesFilter()) { | ||
return testCases + " in " + fixture.getSimpleName(); | ||
} | ||
return "All tests in " + fixture.getSimpleName(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package com.tngtech.archunit.tooling; | ||
|
||
public interface TestPattern { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.tngtech.archunit.tooling; | ||
|
||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
public class TestReport { | ||
|
||
private final Set<ExecutedTestFile> files = new HashSet<>(); | ||
|
||
public Set<ExecutedTestFile> getFiles() { | ||
return Collections.unmodifiableSet(files); | ||
} | ||
|
||
public void addFile(ExecutedTestFile file) { | ||
files.add(file); | ||
} | ||
|
||
public Optional<ExecutedTestFile> getFile(String fixture) { | ||
return files.stream() | ||
.filter(file -> file.getFixture().equals(fixture)) | ||
.findFirst(); | ||
} | ||
|
||
public synchronized ExecutedTestFile ensureFileForFixture(String fixture) { | ||
return getFile(fixture) | ||
.orElseGet(() -> newTestFile(fixture)); | ||
} | ||
|
||
private ExecutedTestFile newTestFile(String fixture) { | ||
ExecutedTestFile result = new ExecutedTestFile(fixture); | ||
files.add(result); | ||
return result; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed this because Jupiter would group field-flavored and method-flavored test results under different parent nodes (one under FQ class name and the other under simple class name)