Last active
February 13, 2016 22:20
-
-
Save cardil/244e839008a649de4033 to your computer and use it in GitHub Desktop.
An example of proposed JavaSpec as a direct port of RSpec
This file contains hidden or 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
import pl.wavesoftware.exampleapp.MainController | |
import static pl.wavesoftware.jspec.DSL.* | |
describe(MainController, { | |
let 'instance', { describedClass.newInstance } | |
sharedExamples('not throwing any errors', { | |
it { expect { subject }.notTo raiseError } | |
it { expect(subject).notTo beNull } | |
}) | |
// describing #execute method of MainController | |
describe(MainController#execute, { | |
let('params', { | |
def map = [:] | |
map['url'] = url | |
map['method'] = 'GET' | |
map | |
}) | |
subject { instance.execute(params) } | |
context('for url /', { | |
let 'url', { '/' } | |
it { isExpected.to eq '/index.html' } | |
}) | |
context('for url /home', { | |
let 'url', { '/home' } | |
it { isExpected.to eq '/home.html' } | |
}) | |
}) | |
// describing #configure method of MainController | |
describe(MainController#configure, { | |
subject { instance.configure() } | |
itBehavesLike 'not throwing any errors' | |
}) | |
}) |
This file contains hidden or 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
class JavaSpec { | |
private static final String DESCRIBE = 'describe' | |
private static final String CONTEXT = 'context' | |
protected JavaSpec parent | |
protected Map<String, Closure> lets = new HashMap<>() | |
protected Map<String, Object> letsEvaluated = new HashMap<>() | |
JavaSpec() { | |
this(null) | |
} | |
JavaSpec(JavaSpec parent) { | |
this.parent = parent | |
} | |
def let(String name, Closure closure) { | |
lets[name] = closure | |
if (letsEvaluated.containsKey(name)) { | |
letsEvaluated.remove(name) | |
} | |
} | |
// public for testing, should be protected | |
def invoke(Closure closure) { | |
def cloned = closure.clone() | |
cloned.delegate = this | |
cloned() | |
} | |
def describe(Object object, Closure description) { | |
newContext(DESCRIBE, object, description) | |
} | |
def context(Object context, Closure description) { | |
newContext(CONTEXT, context, description) | |
} | |
def methodMissing(String name, args) { | |
if (containsLet(name)) { | |
evaluateLet(name) | |
} else { | |
throw new MissingMethodException(name, this.class, args) | |
} | |
} | |
def propertyMissing(String name) { | |
if (containsLet(name)) { | |
evaluateLet(name) | |
} else { | |
throw new MissingPropertyException(name, this.class) | |
} | |
} | |
private String newContext(String name, Object context, Closure description) { | |
def testName = makeTestNameFromObject(context) | |
return testName | |
} | |
private String makeTestNameFromObject(Object object) { | |
if (object instanceof String) { | |
return object.toString() | |
} | |
Class cls | |
if (object instanceof Class) { | |
cls = object | |
} else { | |
cls = object.getClass() | |
} | |
String pkg = cls.getPackage().getName() | |
String replaced = pkg.replaceAll(/\.([a-z])/) { all, first -> | |
first.toUpperCase() | |
} | |
String capitalized = replaced.capitalize() | |
String.format("%s%sContext", capitalized, cls.getSimpleName()) | |
} | |
private boolean containsLet(String name) { | |
lets.containsKey(name) | |
} | |
private Object evaluateLet(String name) { | |
if (!letsEvaluated.containsKey(name)) { | |
letsEvaluated[name] = lets.get(name).call() | |
} | |
letsEvaluated[name] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment