Skip to content

Commit

Permalink
Merge branch '160-options'
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed Mar 17, 2012
2 parents 78cc1d9 + 783433c commit 1b48a60
Show file tree
Hide file tree
Showing 49 changed files with 680 additions and 662 deletions.
7 changes: 6 additions & 1 deletion core/pom.xml
@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand All @@ -22,6 +23,10 @@
<groupId>info.cukes</groupId>
<artifactId>cucumber-html</artifactId>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
</dependency>
<!-- These dependencies are packaged to prevent conflicts with users' own code -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/cucumber/DateFormat.java
Expand Up @@ -29,7 +29,7 @@
* <pre>
* &#064;Given("^the date is (\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})$")
* public void the_date_is(@DateFormat("yyyy-MM-dd'T'HH:mm:ss") Calendar cal) {
* this.date = date;
* this.cal = cal;
* }
* </pre>
* <p>
Expand Down
13 changes: 0 additions & 13 deletions core/src/main/java/cucumber/cli/DefaultRuntimeFactory.java

This file was deleted.

97 changes: 7 additions & 90 deletions core/src/main/java/cucumber/cli/Main.java
@@ -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);
}
}
10 changes: 0 additions & 10 deletions core/src/main/java/cucumber/cli/RuntimeFactory.java

This file was deleted.

@@ -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 core/src/main/java/cucumber/formatter/FormatterConverter.java
@@ -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 core/src/main/java/cucumber/formatter/FormatterFactory.java

This file was deleted.

0 comments on commit 1b48a60

Please sign in to comment.