Skip to content

Commit 5028583

Browse files
committed
GH-3178: Refactor Runner code for test manifests
1 parent 561d15d commit 5028583

File tree

4 files changed

+186
-130
lines changed

4 files changed

+186
-130
lines changed

jena-arq/src/test/java/org/apache/jena/arq/junit/TextTestRunner.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@
2020

2121
import java.util.function.Function;
2222

23+
import org.junit.runner.JUnitCore;
24+
import org.junit.runner.Result;
25+
import org.junit.runner.Runner;
26+
2327
import org.apache.jena.arq.junit.manifest.Manifest;
2428
import org.apache.jena.arq.junit.manifest.ManifestEntry;
25-
import org.apache.jena.arq.junit.runners.AbstractRunnerOfTests;
26-
import org.apache.jena.arq.junit.runners.RunnerOneManifest;
29+
import org.apache.jena.arq.junit.runners.SetupManifests;
2730
import org.apache.jena.atlas.junit.TextListenerLong;
2831
import org.apache.jena.sparql.expr.E_Function;
2932
import org.apache.jena.sparql.expr.NodeValue;
3033
import org.apache.jena.sparql.junit.EarlReport;
31-
import org.junit.runner.JUnitCore;
32-
import org.junit.runner.Result;
3334

3435
public class TextTestRunner {
3536

@@ -39,7 +40,7 @@ public static void runOne(String manifestFile, Function<ManifestEntry, Runnable>
3940

4041
public static void runOne(EarlReport report, String manifestFile, Function<ManifestEntry, Runnable> testMaker) {
4142
Manifest manifest = Manifest.parse(manifestFile);
42-
RunnerOneManifest top = AbstractRunnerOfTests.build(report, manifest, testMaker, null);
43+
Runner top = SetupManifests.build(report, manifest, testMaker, null);
4344

4445
NodeValue.VerboseWarnings = false ;
4546
E_Function.WarnOnUnknownFunction = false ;

jena-arq/src/test/java/org/apache/jena/arq/junit/runners/AbstractRunnerOfTests.java

Lines changed: 30 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,11 @@
1919
package org.apache.jena.arq.junit.runners;
2020

2121
import java.util.ArrayList;
22-
import java.util.Iterator;
2322
import java.util.List;
2423
import java.util.function.Function;
2524

2625
import org.apache.jena.arq.junit.manifest.*;
27-
import org.apache.jena.atlas.io.IndentedWriter;
28-
import org.apache.jena.rdf.model.Statement;
29-
import org.apache.jena.sparql.junit.EarlReport;
30-
import org.apache.jena.sparql.vocabulary.VocabTestQuery;
26+
3127
import org.junit.runner.Description;
3228
import org.junit.runner.Runner;
3329
import org.junit.runner.notification.RunNotifier;
@@ -47,7 +43,7 @@
4743
* This class sorts out the annotations, including providing before/after class, then
4844
* creates a hierarchy of tests to run.
4945
*
50-
* @see RunnerOneTest
46+
* @see SetupManifests
5147
*/
5248
public abstract class AbstractRunnerOfTests extends ParentRunner<Runner> {
5349
private Description description;
@@ -57,138 +53,48 @@ public abstract class AbstractRunnerOfTests extends ParentRunner<Runner> {
5753

5854
public AbstractRunnerOfTests(Class<? > klass, Function<ManifestEntry, Runnable> maker) throws InitializationError {
5955
super(klass);
60-
String label = getLabel(klass);
56+
String label = SetupManifests.getLabel(klass);
6157
if ( label == null )
6258
label = klass.getName();
63-
String prefix = getPrefix(klass);
64-
String[] manifests = getManifests(klass);
65-
if ( manifests.length == 0 )
59+
60+
// Get the annotation arguments.
61+
String prefix = SetupManifests.getPrefix(klass);
62+
description = Description.createSuiteDescription(label);
63+
prepare(klass, maker,prefix);
64+
}
65+
66+
private void prepare(Class<? > klass, Function<ManifestEntry, Runnable> maker, String prefix) throws InitializationError {
67+
List<String> manifests = SetupManifests.getManifests(klass);
68+
if ( manifests.isEmpty() )
6669
//System.err.println("No manifests: "+label);
6770
throw new InitializationError("No manifests");
68-
description = Description.createSuiteDescription(label);
71+
prepare(manifests, klass.getSimpleName(), maker, prefix);
72+
}
6973

74+
private void prepare(List<String> manifests, String traceName, Function<ManifestEntry, Runnable> maker, String prefix) throws InitializationError {
75+
// For each manifest
7076
for ( String manifestFile : manifests ) {
7177
//System.out.println("** "+klass.getSimpleName()+" -- "+manifestFile);
72-
if ( PrintManifests ) {
73-
out.println("** "+klass.getSimpleName()+" -- "+manifestFile);
74-
out.incIndent();
78+
if ( SetupManifests.PrintManifests ) {
79+
if ( traceName != null )
80+
SetupManifests.out.println("** "+traceName+" -- "+manifestFile);
81+
else
82+
SetupManifests.out.println("** Manifest: "+manifestFile);
83+
SetupManifests.out.incIndent();
7584
}
7685
Manifest manifest = Manifest.parse(manifestFile);
77-
if ( PrintManifests ) {
86+
if ( SetupManifests.PrintManifests ) {
7887
// Record manifests.
79-
Manifest.walk(manifest, m->out.println(m.getFileName()+" :: "+m.getName()), e->{});
88+
Manifest.walk(manifest, m->SetupManifests.out.println(m.getFileName()+" :: "+m.getName()), e->{});
8089
}
81-
Runner runner = build(null, manifest, maker, prefix);
90+
Runner runner = SetupManifests.build(null, manifest, maker, prefix);
8291
description.addChild(runner.getDescription());
8392
children.add(runner);
84-
if ( PrintManifests )
85-
out.decIndent();
86-
}
87-
if ( PrintManifests )
88-
out.flush();
89-
}
90-
91-
// Print all manifests, top level and included.
92-
private static boolean PrintManifests = false;
93-
private static IndentedWriter out = IndentedWriter.stdout;
94-
95-
/**
96-
* Do one level of tests. test are {@link Runnable Runnables} that each succeed or fail with an exception.
97-
*/
98-
public static RunnerOneManifest build(EarlReport report, Manifest manifest, Function<ManifestEntry, Runnable> maker, String prefix) {
99-
Description description = Description.createSuiteDescription(manifest.getName());
100-
if ( PrintManifests )
101-
out.println(manifest.getFileName()+" :: "+manifest.getName());
102-
RunnerOneManifest thisLevel = new RunnerOneManifest(manifest, description);
103-
104-
Iterator<String> sub = manifest.includedManifests();
105-
while(sub.hasNext() ) {
106-
if ( PrintManifests )
107-
out.incIndent();
108-
109-
String mf = sub.next();
110-
Manifest manifestSub = Manifest.parse(mf);
111-
Runner runner = build(report, manifestSub, maker, prefix);
112-
thisLevel.add(runner);
113-
if ( PrintManifests )
114-
out.decIndent();
115-
}
116-
117-
// Check entries do have test targets.
118-
119-
manifest.entries().forEach(entry->{
120-
if ( entry.getAction() == null )
121-
throw new RuntimeException("Missing: action ["+entry.getEntry()+"]");
122-
if ( entry.getName() == null )
123-
throw new RuntimeException("Missing: label ["+entry.getEntry()+"]");
124-
});
125-
126-
prepareTests(report, thisLevel, manifest, maker, prefix);
127-
return thisLevel;
128-
}
129-
130-
private static String prepareTestLabel(ManifestEntry entry, String prefix) {
131-
String label = fixupName(entry.getName());
132-
if ( prefix != null )
133-
label = prefix+label;
134-
135-
// action URI or action -> qt:query
136-
String str = null;
137-
138-
if ( entry.getAction() != null ) {
139-
if ( entry.getAction().isURIResource() )
140-
str = entry.getAction().getURI();
141-
else if ( entry.getAction().isAnon() ) {
142-
Statement stmt = entry.getAction().getProperty(VocabTestQuery.query);
143-
if ( stmt != null && stmt.getObject().isURIResource() )
144-
str = stmt.getObject().asResource().getURI();
145-
}
146-
}
147-
148-
if ( str != null ) {
149-
int x = str.lastIndexOf('/');
150-
if ( x > 0 && x < str.length() ) {
151-
String fn = str.substring(x+1) ;
152-
label = label+" ("+fn+")";
153-
}
154-
}
155-
return label;
156-
}
157-
158-
public static void prepareTests(EarlReport report, RunnerOneManifest level, Manifest manifest, Function<ManifestEntry, Runnable> maker, String prefix) {
159-
manifest.entries().forEach(entry->{
160-
String label = prepareTestLabel(entry, prefix);
161-
Runnable runnable = maker.apply(entry);
162-
if ( runnable != null ) {
163-
Runner r = new RunnerOneTest(label, runnable, entry.getURI(), report);
164-
level.add(r);
165-
}
166-
});
167-
}
168-
169-
public static String fixupName(String string) {
170-
// Eclipse used to parse test names and () were special.
171-
// string = string.replace('(', '[');
172-
// string = string.replace(')', ']');
173-
return string;
174-
}
175-
176-
private static String getLabel(Class<? > klass) {
177-
Label annotation = klass.getAnnotation(Label.class);
178-
return ( annotation == null ) ? null : annotation.value();
179-
}
180-
181-
private static String getPrefix(Class<? > klass) {
182-
Prefix annotation = klass.getAnnotation(Prefix.class);
183-
return ( annotation == null ) ? null : annotation.value();
184-
}
185-
186-
private static String[] getManifests(Class<? > klass) throws InitializationError {
187-
Manifests annotation = klass.getAnnotation(Manifests.class);
188-
if ( annotation == null ) {
189-
throw new InitializationError(String.format("class '%s' must have a @Manifests annotation", klass.getName()));
93+
if ( SetupManifests.PrintManifests )
94+
SetupManifests.out.decIndent();
19095
}
191-
return annotation.value();
96+
if ( SetupManifests.PrintManifests )
97+
SetupManifests.out.flush();
19298
}
19399

194100
@Override
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.jena.arq.junit.runners;
20+
21+
import java.util.Iterator;
22+
import java.util.List;
23+
import java.util.function.Function;
24+
25+
import org.junit.runner.Description;
26+
import org.junit.runner.Runner;
27+
import org.junit.runners.model.InitializationError;
28+
29+
import org.apache.jena.arq.junit.manifest.Manifest;
30+
import org.apache.jena.arq.junit.manifest.ManifestEntry;
31+
import org.apache.jena.arq.junit.manifest.Manifests;
32+
import org.apache.jena.arq.junit.manifest.Prefix;
33+
import org.apache.jena.atlas.io.IndentedWriter;
34+
import org.apache.jena.rdf.model.Statement;
35+
import org.apache.jena.sparql.junit.EarlReport;
36+
import org.apache.jena.sparql.vocabulary.VocabTestQuery;
37+
38+
public class SetupManifests {
39+
40+
// Print all manifests, top level and included.
41+
/*package*/ static boolean PrintManifests = false;
42+
/*package*/ static IndentedWriter out = IndentedWriter.stdout;
43+
44+
/**
45+
* Do one level of tests. test are {@link Runnable Runnables} that each succeed or fail with an exception.
46+
*/
47+
public static Runner build(EarlReport report, Manifest manifest, Function<ManifestEntry, Runnable> maker, String prefix) {
48+
return buildForManifest(report, manifest, maker, prefix);
49+
}
50+
51+
/**
52+
* Do one level of tests, recurse into sub-levels.
53+
* A test is a {@link Runnable} that succeeds or fails with an exception.
54+
*/
55+
private static RunnerOneManifest buildForManifest(EarlReport report, Manifest manifest, Function<ManifestEntry, Runnable> maker, String prefix) {
56+
Description description = Description.createSuiteDescription(manifest.getName());
57+
if ( PrintManifests )
58+
out.println(manifest.getFileName()+" :: "+manifest.getName());
59+
RunnerOneManifest thisLevel = new RunnerOneManifest(manifest, description);
60+
61+
Iterator<String> sub = manifest.includedManifests();
62+
while(sub.hasNext() ) {
63+
if ( PrintManifests )
64+
out.incIndent();
65+
66+
String mf = sub.next();
67+
Manifest manifestSub = Manifest.parse(mf);
68+
Runner runner = buildForManifest(report, manifestSub, maker, prefix);
69+
thisLevel.add(runner);
70+
if ( PrintManifests )
71+
out.decIndent();
72+
}
73+
74+
// Check entries do have test targets.
75+
76+
manifest.entries().forEach(entry->{
77+
if ( entry.getAction() == null )
78+
throw new RuntimeException("Missing: action ["+entry.getEntry()+"]");
79+
if ( entry.getName() == null )
80+
throw new RuntimeException("Missing: label ["+entry.getEntry()+"]");
81+
});
82+
83+
prepareTests(report, thisLevel, manifest, maker, prefix);
84+
return thisLevel;
85+
}
86+
87+
public static void prepareTests(EarlReport report, RunnerOneManifest level, Manifest manifest, Function<ManifestEntry, Runnable> maker, String prefix) {
88+
manifest.entries().forEach(entry->{
89+
String label = prepareTestLabel(entry, prefix);
90+
Runnable runnable = maker.apply(entry);
91+
if ( runnable != null ) {
92+
Runner r = new RunnerOneTest(label, runnable, entry.getURI(), report);
93+
level.add(r);
94+
}
95+
});
96+
}
97+
98+
private static String prepareTestLabel(ManifestEntry entry, String prefix) {
99+
String label = fixupName(entry.getName());
100+
if ( prefix != null )
101+
label = prefix+label;
102+
103+
// action URI or action -> qt:query
104+
String str = null;
105+
106+
if ( entry.getAction() != null ) {
107+
if ( entry.getAction().isURIResource() )
108+
str = entry.getAction().getURI();
109+
else if ( entry.getAction().isAnon() ) {
110+
Statement stmt = entry.getAction().getProperty(VocabTestQuery.query);
111+
if ( stmt != null && stmt.getObject().isURIResource() )
112+
str = stmt.getObject().asResource().getURI();
113+
}
114+
}
115+
116+
if ( str != null ) {
117+
int x = str.lastIndexOf('/');
118+
if ( x > 0 && x < str.length() ) {
119+
String fn = str.substring(x+1) ;
120+
label = label+" ("+fn+")";
121+
}
122+
}
123+
return label;
124+
}
125+
126+
private static String fixupName(String string) {
127+
// Eclipse used to parse test names and () were special.
128+
// string = string.replace('(', '[');
129+
// string = string.replace(')', ']');
130+
return string;
131+
}
132+
133+
/*package*/ static String getLabel(Class<? > klass) {
134+
Label annotation = klass.getAnnotation(Label.class);
135+
return ( annotation == null ) ? null : annotation.value();
136+
}
137+
138+
/*package*/ static String getPrefix(Class<? > klass) {
139+
Prefix annotation = klass.getAnnotation(Prefix.class);
140+
return ( annotation == null ) ? null : annotation.value();
141+
}
142+
143+
/*package*/ static List<String> getManifests(Class<? > klass) throws InitializationError {
144+
Manifests annotation = klass.getAnnotation(Manifests.class);
145+
if ( annotation == null ) {
146+
throw new InitializationError(String.format("class '%s' must have a @Manifests annotation", klass.getName()));
147+
}
148+
return List.of(annotation.value());
149+
}
150+
}

jena-arq/src/test/java/org/apache/jena/sparql/Scripts_ARQ.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,4 @@ public static void afterClass() {
5555
NodeValue.VerboseWarnings = bVerboseWarnings;
5656
E_Function.WarnOnUnknownFunction = bWarnOnUnknownFunction;
5757
}
58-
5958
}

0 commit comments

Comments
 (0)