Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
49 changed files
with
680 additions
and
662 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 0 additions & 13 deletions
13
core/src/main/java/cucumber/cli/DefaultRuntimeFactory.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,25 @@ | ||
package cucumber.cli; | ||
|
||
import cucumber.formatter.FormatterFactory; | ||
import cucumber.formatter.MultiFormatter; | ||
import cucumber.io.FileResourceLoader; | ||
import cucumber.runtime.Runtime; | ||
import cucumber.runtime.snippets.SummaryPrinter; | ||
import gherkin.formatter.Formatter; | ||
import gherkin.formatter.Reporter; | ||
import cucumber.runtime.RuntimeOptions; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.ResourceBundle; | ||
import java.util.Stack; | ||
|
||
import static java.util.Arrays.asList; | ||
|
||
public class Main { | ||
private static final String USAGE = "TODO - Write the help"; | ||
static final String VERSION = ResourceBundle.getBundle("cucumber.version").getString("cucumber-jvm.version"); | ||
|
||
public static void main(String[] argv) throws Throwable { | ||
run(argv, Thread.currentThread().getContextClassLoader(), new DefaultRuntimeFactory()); | ||
run(argv, Thread.currentThread().getContextClassLoader()); | ||
} | ||
|
||
public static void run(String[] argv, ClassLoader classLoader, RuntimeFactory runtimeFactory) throws IOException { | ||
List<String> featurePaths = new ArrayList<String>(); | ||
List<String> gluePaths = new ArrayList<String>(); | ||
List<Object> filters = new ArrayList<Object>(); | ||
Stack<String> format = new Stack<String>(); | ||
List<String> args = new ArrayList<String>(asList(argv)); | ||
String dotCucumber = null; | ||
boolean isDryRun = false; | ||
|
||
FormatterFactory formatterFactory = new FormatterFactory(classLoader); | ||
MultiFormatter multiFormatter = new MultiFormatter(classLoader); | ||
|
||
while (!args.isEmpty()) { | ||
String arg = args.remove(0); | ||
|
||
if (arg.equals("--help") || arg.equals("-h")) { | ||
System.out.println(USAGE); | ||
System.exit(0); | ||
} else if (arg.equals("--version") || arg.equals("-v")) { | ||
System.out.println(VERSION); | ||
System.exit(0); | ||
} else if (arg.equals("--glue") || arg.equals("-g")) { | ||
String gluePath = args.remove(0); | ||
gluePaths.add(gluePath); | ||
} else if (arg.equals("--tags") || arg.equals("-t")) { | ||
filters.add(args.remove(0)); | ||
} else if (arg.equals("--format") || arg.equals("-f")) { | ||
format.push(args.remove(0)); | ||
} else if (arg.equals("--out") || arg.equals("-o")) { | ||
File out = new File(args.remove(0)); | ||
Formatter formatter = formatterFactory.createFormatter(format.pop(), out); | ||
multiFormatter.add(formatter); | ||
} else if (arg.equals("--dotcucumber")) { | ||
dotCucumber = args.remove(0); | ||
} else if (arg.equals("--dry-run") || arg.equals("-d")) { | ||
isDryRun = true; | ||
} else { | ||
// TODO: Use PathWithLines and add line filter if any | ||
featurePaths.add(arg); | ||
} | ||
} | ||
|
||
//Grab any formatters left on the stack and create a multiformatter for them to stdout | ||
// yes this will be ugly, but maybe people are crazy | ||
if (!format.isEmpty()) { | ||
multiFormatter.add(formatterFactory.createFormatter(format.pop(), System.out)); | ||
} else { | ||
//Default formatter is progress unless otherwise specified or if they have piped all their other formatters | ||
// to an output thing | ||
multiFormatter.add(formatterFactory.createFormatter("progress", System.out)); | ||
} | ||
|
||
if (gluePaths.isEmpty()) { | ||
System.out.println("Missing option: --glue"); | ||
System.exit(1); | ||
} | ||
public static void run(String[] argv, ClassLoader classLoader) throws IOException { | ||
RuntimeOptions runtimeOptions = new RuntimeOptions(argv); | ||
|
||
Runtime runtime = runtimeFactory.createRuntime(new FileResourceLoader(), gluePaths, classLoader, isDryRun); | ||
|
||
if (dotCucumber != null) { | ||
writeDotCucumber(featurePaths, dotCucumber, runtime); | ||
} | ||
Formatter formatter = multiFormatter.formatterProxy(); | ||
Reporter reporter = multiFormatter.reporterProxy(); | ||
runtime.run(featurePaths, filters, formatter, reporter); | ||
formatter.done(); | ||
printSummary(runtime); | ||
formatter.close(); | ||
Runtime runtime = new Runtime(new FileResourceLoader(), classLoader, runtimeOptions); | ||
runtime.writeStepdefsJson(); | ||
runtime.run(); | ||
System.exit(runtime.exitStatus()); | ||
} | ||
|
||
private static void writeDotCucumber(List<String> featurePaths, String dotCucumberPath, Runtime runtime) throws IOException { | ||
File dotCucumber = new File(dotCucumberPath); | ||
dotCucumber.mkdirs(); | ||
runtime.writeStepdefsJson(featurePaths, dotCucumber); | ||
} | ||
|
||
private static void printSummary(Runtime runtime) { | ||
new SummaryPrinter(System.out).print(runtime); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
9 changes: 9 additions & 0 deletions
9
core/src/main/java/cucumber/formatter/CucumberPrettyFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package cucumber.formatter; | ||
|
||
import gherkin.formatter.PrettyFormatter; | ||
|
||
public class CucumberPrettyFormatter extends PrettyFormatter { | ||
public CucumberPrettyFormatter(Appendable out) { | ||
super(out, true, true); | ||
} | ||
} |
126 changes: 126 additions & 0 deletions
126
core/src/main/java/cucumber/formatter/FormatterConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package cucumber.formatter; | ||
|
||
import com.beust.jcommander.IStringConverter; | ||
import cucumber.runtime.CucumberException; | ||
import gherkin.formatter.Formatter; | ||
import gherkin.formatter.JSONFormatter; | ||
import gherkin.formatter.JSONPrettyFormatter; | ||
|
||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import static java.util.Arrays.asList; | ||
|
||
public class FormatterConverter implements IStringConverter<Formatter> { | ||
private Class[] CTOR_ARGS = new Class[]{Appendable.class, File.class}; | ||
|
||
private static final Map<String, Class<? extends Formatter>> FORMATTER_CLASSES = new HashMap<String, Class<? extends Formatter>>() {{ | ||
put("junit", JUnitFormatter.class); | ||
put("html", HTMLFormatter.class); | ||
put("pretty", CucumberPrettyFormatter.class); | ||
put("progress", ProgressFormatter.class); | ||
put("json", JSONFormatter.class); | ||
put("json-pretty", JSONPrettyFormatter.class); | ||
}}; | ||
private static final Pattern FORMATTER_WITH_FILE_PATTERN = Pattern.compile("([^:]+):(.*)"); | ||
private Appendable defaultOut = System.out; | ||
|
||
@Override | ||
public Formatter convert(String formatterString) { | ||
Matcher formatterWithFile = FORMATTER_WITH_FILE_PATTERN.matcher(formatterString); | ||
String formatterName; | ||
Object ctorArg; | ||
if (formatterWithFile.matches()) { | ||
formatterName = formatterWithFile.group(1); | ||
ctorArg = new File(formatterWithFile.group(2)); | ||
} else { | ||
formatterName = formatterString; | ||
ctorArg = defaultOutIfAvailable(); | ||
} | ||
Class<? extends Formatter> formatterClass = formatterClass(formatterName); | ||
try { | ||
return instantiate(formatterClass, ctorArg); | ||
} catch (IOException e) { | ||
throw new CucumberException(e); | ||
} | ||
} | ||
|
||
private Formatter instantiate(Class<? extends Formatter> formatterClass, Object ctorArg) throws IOException { | ||
Constructor<? extends Formatter> constructor; | ||
|
||
for (Class ctorArgClass : CTOR_ARGS) { | ||
constructor = findConstructor(formatterClass, ctorArgClass); | ||
if (constructor != null) { | ||
ctorArg = convert(ctorArg, ctorArgClass); | ||
if (ctorArg != null) { | ||
try { | ||
return constructor.newInstance(ctorArg); | ||
} catch (InstantiationException e) { | ||
throw new CucumberException(e); | ||
} catch (IllegalAccessException e) { | ||
throw new CucumberException(e); | ||
} catch (InvocationTargetException e) { | ||
throw new CucumberException(e.getTargetException()); | ||
} | ||
} | ||
} | ||
} | ||
throw new CucumberException(String.format("%s must have a single-argument constructor that takes one of the following: %s", formatterClass, asList(CTOR_ARGS))); | ||
} | ||
|
||
private Object convert(Object ctorArg, Class ctorArgClass) throws IOException { | ||
if (ctorArgClass.isAssignableFrom(ctorArg.getClass())) { | ||
return ctorArg; | ||
} | ||
if (ctorArgClass.equals(File.class) && ctorArg instanceof File) { | ||
return ctorArg; | ||
} | ||
if (ctorArgClass.equals(Appendable.class) && ctorArg instanceof File) { | ||
return new FileWriter((File) ctorArg); | ||
} | ||
return null; | ||
} | ||
|
||
private Constructor<? extends Formatter> findConstructor(Class<? extends Formatter> formatterClass, Class<?> ctorArgClass) { | ||
try { | ||
return formatterClass.getConstructor(ctorArgClass); | ||
} catch (NoSuchMethodException e) { | ||
return null; | ||
} | ||
} | ||
|
||
private Class<? extends Formatter> formatterClass(String formatterName) { | ||
Class<? extends Formatter> formatterClass = FORMATTER_CLASSES.get(formatterName); | ||
if (formatterClass == null) { | ||
formatterClass = loadClass(formatterName); | ||
} | ||
return formatterClass; | ||
} | ||
|
||
private Class<? extends Formatter> loadClass(String className) { | ||
try { | ||
return (Class<? extends Formatter>) Thread.currentThread().getContextClassLoader().loadClass(className); | ||
} catch (ClassNotFoundException e) { | ||
throw new CucumberException("Couldn't load formatter class: " + className, e); | ||
} | ||
} | ||
|
||
private Appendable defaultOutIfAvailable() { | ||
try { | ||
if (defaultOut != null) { | ||
return defaultOut; | ||
} else { | ||
throw new CucumberException("Only one formatter can use STDOUT. If you use more than one formatter you must specify output path with FORMAT:PATH"); | ||
} | ||
} finally { | ||
defaultOut = null; | ||
} | ||
} | ||
} |
66 changes: 0 additions & 66 deletions
66
core/src/main/java/cucumber/formatter/FormatterFactory.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.