Pulls in updates to more recent Rhino.
This commit is contained in:
commit
3fef5237aa
|
@ -1,203 +1,214 @@
|
||||||
package be.klak.junit.jasmine;
|
package be.klak.junit.jasmine;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.runner.Description;
|
import org.junit.runner.Description;
|
||||||
import org.junit.runner.Runner;
|
import org.junit.runner.Runner;
|
||||||
import org.junit.runner.notification.RunNotifier;
|
import org.junit.runner.notification.RunNotifier;
|
||||||
import org.mozilla.javascript.ContextFactory;
|
import org.mozilla.javascript.ContextFactory;
|
||||||
import org.mozilla.javascript.NativeArray;
|
import org.mozilla.javascript.NativeArray;
|
||||||
import org.mozilla.javascript.tools.debugger.Main;
|
import org.mozilla.javascript.tools.debugger.Main;
|
||||||
|
|
||||||
import be.klak.rhino.RhinoContext;
|
import be.klak.rhino.RhinoContext;
|
||||||
|
|
||||||
public class JasmineTestRunner extends Runner {
|
public class JasmineTestRunner extends Runner {
|
||||||
|
|
||||||
private static final int SLEEP_TIME_MILISECONDS = 50;
|
private static final int SLEEP_TIME_MILISECONDS = 50;
|
||||||
private static final String JASMINE_LIB_DIR = "/lib/jasmine-1.0.2/";
|
private static final String JASMINE_LIB_DIR = "/lib/jasmine-1.0.2/";
|
||||||
|
|
||||||
private JasmineDescriptions jasmineSuite;
|
private JasmineDescriptions jasmineSuite;
|
||||||
|
|
||||||
private final RhinoContext rhinoContext;
|
protected final RhinoContext rhinoContext;
|
||||||
private final JasmineSuite suiteAnnotation;
|
protected final JasmineSuite suiteAnnotation;
|
||||||
private final Class<?> testClass;
|
private final Class<?> testClass;
|
||||||
|
|
||||||
@JasmineSuite
|
@JasmineSuite
|
||||||
private class DefaultSuite {
|
private class DefaultSuite {
|
||||||
}
|
}
|
||||||
|
|
||||||
public JasmineTestRunner(Class<?> testClass) {
|
public JasmineTestRunner(Class<?> testClass) {
|
||||||
this.testClass = testClass;
|
this.testClass = testClass;
|
||||||
this.suiteAnnotation = getJasmineSuiteAnnotationFromTestClass();
|
this.suiteAnnotation = getJasmineSuiteAnnotationFromTestClass();
|
||||||
|
|
||||||
Main debugger = null;
|
Main debugger = null;
|
||||||
if (this.suiteAnnotation.debug()) {
|
if (this.suiteAnnotation.debug()) {
|
||||||
debugger = createDebugger();
|
debugger = createDebugger();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rhinoContext = setUpRhinoScope();
|
this.rhinoContext = setUpRhinoScope();
|
||||||
|
|
||||||
if (this.suiteAnnotation.debug()) {
|
if (this.suiteAnnotation.debug()) {
|
||||||
debugger.doBreak();
|
debugger.doBreak();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RhinoContext setUpRhinoScope() {
|
private RhinoContext setUpRhinoScope() {
|
||||||
RhinoContext context = new RhinoContext();
|
RhinoContext context = new RhinoContext();
|
||||||
context.loadEnv(suiteAnnotation.jsRootDir());
|
|
||||||
setUpJasmine(context);
|
pre(context);
|
||||||
|
|
||||||
context.load(suiteAnnotation.sourcesRootDir() + "/", suiteAnnotation.sources());
|
context.loadEnv(suiteAnnotation.jsRootDir());
|
||||||
context.load(suiteAnnotation.jsRootDir() + "/specs/", getJasmineSpecs(suiteAnnotation));
|
setUpJasmine(context);
|
||||||
return context;
|
|
||||||
}
|
context.load(suiteAnnotation.sourcesRootDir() + "/", suiteAnnotation.sources());
|
||||||
|
context.load(suiteAnnotation.jsRootDir() + "/specs/", getJasmineSpecs(suiteAnnotation));
|
||||||
private void setUpJasmine(RhinoContext context) {
|
return context;
|
||||||
context.load(getJsLibDir() + "jasmine.js");
|
}
|
||||||
context.load(getJsLibDir() + "jasmine.delegator_reporter.js");
|
|
||||||
|
protected void pre(RhinoContext context) {
|
||||||
context.evalJS("jasmine.getEnv().addReporter(new jasmine.DelegatorJUnitReporter());");
|
}
|
||||||
}
|
|
||||||
|
private void setUpJasmine(RhinoContext context) {
|
||||||
private Main createDebugger() {
|
context.load(getJsLibDir() + "jasmine.js");
|
||||||
Main debugger = new Main("JS Debugger");
|
context.load(getJsLibDir() + "jasmine.delegator_reporter.js");
|
||||||
|
|
||||||
debugger.setExitAction(new Runnable() {
|
context.evalJS("jasmine.getEnv().addReporter(new jasmine.DelegatorJUnitReporter());");
|
||||||
public void run() {
|
}
|
||||||
System.exit(0);
|
|
||||||
}
|
private Main createDebugger() {
|
||||||
});
|
Main debugger = new Main("JS Debugger");
|
||||||
|
|
||||||
debugger.attachTo(ContextFactory.getGlobal());
|
debugger.setExitAction(new Runnable() {
|
||||||
debugger.pack();
|
public void run() {
|
||||||
debugger.setSize(600, 460);
|
System.exit(0);
|
||||||
debugger.setVisible(true);
|
}
|
||||||
|
});
|
||||||
return debugger;
|
|
||||||
}
|
debugger.attachTo(ContextFactory.getGlobal());
|
||||||
|
debugger.pack();
|
||||||
private JasmineSuite getJasmineSuiteAnnotationFromTestClass() {
|
debugger.setSize(600, 460);
|
||||||
JasmineSuite suiteAnnotation = testClass.getAnnotation(JasmineSuite.class);
|
debugger.setVisible(true);
|
||||||
if (suiteAnnotation == null) {
|
|
||||||
suiteAnnotation = DefaultSuite.class.getAnnotation(JasmineSuite.class);
|
return debugger;
|
||||||
}
|
}
|
||||||
return suiteAnnotation;
|
|
||||||
}
|
private JasmineSuite getJasmineSuiteAnnotationFromTestClass() {
|
||||||
|
JasmineSuite suiteAnnotation = testClass.getAnnotation(JasmineSuite.class);
|
||||||
private String[] getJasmineSpecs(JasmineSuite suiteAnnotation) {
|
if (suiteAnnotation == null) {
|
||||||
if (suiteAnnotation.specs().length == 0) {
|
suiteAnnotation = DefaultSuite.class.getAnnotation(JasmineSuite.class);
|
||||||
return new String[] { StringUtils.uncapitalize(testClass.getSimpleName()).replace("Test", "Spec") + ".js" };
|
}
|
||||||
}
|
return suiteAnnotation;
|
||||||
return suiteAnnotation.specs();
|
}
|
||||||
}
|
|
||||||
|
private String[] getJasmineSpecs(JasmineSuite suiteAnnotation) {
|
||||||
private void resetEnvjsWindowSpace() {
|
if (suiteAnnotation.specs().length == 0) {
|
||||||
this.rhinoContext.evalJS("window.location = '" + suiteAnnotation.jsRootDir() + "/lib/blank.html';");
|
return new String[] { StringUtils.uncapitalize(testClass.getSimpleName()).replace("Test", "Spec") + ".js" };
|
||||||
}
|
}
|
||||||
|
return suiteAnnotation.specs();
|
||||||
private String getJsLibDir() {
|
}
|
||||||
return suiteAnnotation.jsRootDir() + JASMINE_LIB_DIR;
|
|
||||||
}
|
private void resetEnvjsWindowSpace() {
|
||||||
|
this.rhinoContext.evalJS("window.location = '" + suiteAnnotation.jsRootDir() + "/lib/blank.html';");
|
||||||
private JasmineDescriptions getJasmineDescriptions() {
|
}
|
||||||
if (this.jasmineSuite == null) {
|
|
||||||
NativeArray baseSuites = (NativeArray) rhinoContext.evalJS("jasmine.getEnv().currentRunner().suites()");
|
private String getJsLibDir() {
|
||||||
this.jasmineSuite = new JasmineJSSuiteConverter(rhinoContext).convertToJunitDescriptions(testClass, baseSuites);
|
return suiteAnnotation.jsRootDir() + JASMINE_LIB_DIR;
|
||||||
}
|
}
|
||||||
return this.jasmineSuite;
|
|
||||||
}
|
private JasmineDescriptions getJasmineDescriptions() {
|
||||||
|
if (this.jasmineSuite == null) {
|
||||||
@Override
|
NativeArray baseSuites = (NativeArray) rhinoContext.evalJS("jasmine.getEnv().currentRunner().suites()");
|
||||||
public Description getDescription() {
|
this.jasmineSuite = new JasmineJSSuiteConverter(rhinoContext).convertToJunitDescriptions(testClass, baseSuites);
|
||||||
return getJasmineDescriptions().getRootDescription();
|
}
|
||||||
}
|
return this.jasmineSuite;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void run(RunNotifier notifier) {
|
@Override
|
||||||
generateSpecRunnerIfNeeded();
|
public Description getDescription() {
|
||||||
|
return getJasmineDescriptions().getRootDescription();
|
||||||
for (JasmineSpec spec : getJasmineDescriptions().getSpecs()) {
|
}
|
||||||
Object testClassInstance = createTestClassInstance();
|
|
||||||
fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, Before.class);
|
@Override
|
||||||
|
public void run(RunNotifier notifier) {
|
||||||
try {
|
generateSpecRunnerIfNeeded();
|
||||||
notifier.fireTestStarted(spec.getDescription());
|
|
||||||
spec.execute(rhinoContext);
|
for (JasmineSpec spec : getJasmineDescriptions().getSpecs()) {
|
||||||
while (!spec.isDone()) {
|
Object testClassInstance = createTestClassInstance();
|
||||||
waitALittle();
|
fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, Before.class);
|
||||||
}
|
|
||||||
|
try {
|
||||||
reportSpecResultToNotifier(notifier, spec);
|
notifier.fireTestStarted(spec.getDescription());
|
||||||
resetEnvjsWindowSpace();
|
spec.execute(rhinoContext);
|
||||||
} finally {
|
while (!spec.isDone()) {
|
||||||
fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, After.class);
|
waitALittle();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
reportSpecResultToNotifier(notifier, spec);
|
||||||
this.rhinoContext.exit();
|
resetEnvjsWindowSpace();
|
||||||
}
|
} finally {
|
||||||
|
fireMethodsWithSpecifiedAnnotationIfAny(testClassInstance, After.class);
|
||||||
private Object createTestClassInstance() {
|
}
|
||||||
try {
|
}
|
||||||
return testClass.newInstance();
|
|
||||||
} catch (Exception ex) {
|
after();
|
||||||
throw new RuntimeException("Unable to create a new instance of testClass " + testClass.getSimpleName()
|
}
|
||||||
+ " using a no-arg constructor", ex);
|
|
||||||
}
|
protected void after() {
|
||||||
}
|
this.rhinoContext.exit();
|
||||||
|
}
|
||||||
private void fireMethodsWithSpecifiedAnnotationIfAny(Object testClassInstance, Class<? extends Annotation> annotation) {
|
|
||||||
for (Method method : testClass.getMethods()) {
|
|
||||||
|
private Object createTestClassInstance() {
|
||||||
try {
|
try {
|
||||||
if (method.getAnnotation(annotation) != null) {
|
return testClass.newInstance();
|
||||||
method.setAccessible(true);
|
} catch (Exception ex) {
|
||||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
throw new RuntimeException("Unable to create a new instance of testClass " + testClass.getSimpleName()
|
||||||
if (parameterTypes.length == 0) {
|
+ " using a no-arg constructor", ex);
|
||||||
method.invoke(testClassInstance, (Object[]) null);
|
}
|
||||||
} else if (parameterTypes.length == 1 && RhinoContext.class.isAssignableFrom(parameterTypes[0])) {
|
}
|
||||||
method.invoke(testClassInstance, new Object[] { this.rhinoContext });
|
|
||||||
} else {
|
private void fireMethodsWithSpecifiedAnnotationIfAny(Object testClassInstance, Class<? extends Annotation> annotation) {
|
||||||
throw new IllegalStateException("Annotated method does not have zero or rhinoContext as parameterTypes");
|
for (Method method : testClass.getMethods()) {
|
||||||
}
|
|
||||||
}
|
try {
|
||||||
} catch (Exception ex) {
|
if (method.getAnnotation(annotation) != null) {
|
||||||
throw new RuntimeException(
|
method.setAccessible(true);
|
||||||
"Exception while firing " + annotation.getSimpleName() + " method: " + method.getName(), ex);
|
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||||
}
|
if (parameterTypes.length == 0) {
|
||||||
}
|
method.invoke(testClassInstance, (Object[]) null);
|
||||||
}
|
} else if (parameterTypes.length == 1 && RhinoContext.class.isAssignableFrom(parameterTypes[0])) {
|
||||||
|
method.invoke(testClassInstance, new Object[] { this.rhinoContext });
|
||||||
private void generateSpecRunnerIfNeeded() {
|
} else {
|
||||||
if (suiteAnnotation.generateSpecRunner()) {
|
throw new IllegalStateException("Annotated method does not have zero or rhinoContext as parameterTypes");
|
||||||
String[] jasmineSpecs = getJasmineSpecs(suiteAnnotation);
|
}
|
||||||
new JasmineSpecRunnerGenerator(jasmineSpecs, suiteAnnotation, suiteAnnotation.jsRootDir() + "/runners",
|
}
|
||||||
testClass.getSimpleName()
|
} catch (Exception ex) {
|
||||||
+ "Runner.html")
|
throw new RuntimeException(
|
||||||
.generate();
|
"Exception while firing " + annotation.getSimpleName() + " method: " + method.getName(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void reportSpecResultToNotifier(RunNotifier notifier, JasmineSpec spec) {
|
|
||||||
if (spec.isPassed(rhinoContext)) {
|
private void generateSpecRunnerIfNeeded() {
|
||||||
notifier.fireTestFinished(spec.getDescription());
|
if (suiteAnnotation.generateSpecRunner()) {
|
||||||
} else if (spec.isFailed(rhinoContext)) {
|
String[] jasmineSpecs = getJasmineSpecs(suiteAnnotation);
|
||||||
notifier.fireTestFailure(spec.getJunitFailure(rhinoContext));
|
new JasmineSpecRunnerGenerator(jasmineSpecs, suiteAnnotation, suiteAnnotation.jsRootDir() + "/runners",
|
||||||
} else {
|
testClass.getSimpleName()
|
||||||
throw new IllegalStateException("Unexpected spec status received: " + spec);
|
+ "Runner.html")
|
||||||
}
|
.generate();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void waitALittle() {
|
|
||||||
try {
|
private void reportSpecResultToNotifier(RunNotifier notifier, JasmineSpec spec) {
|
||||||
Thread.sleep(SLEEP_TIME_MILISECONDS);
|
if (spec.isPassed(rhinoContext)) {
|
||||||
} catch (Exception e) {
|
notifier.fireTestFinished(spec.getDescription());
|
||||||
throw new RuntimeException(e);
|
} else if (spec.isFailed(rhinoContext)) {
|
||||||
}
|
notifier.fireTestFailure(spec.getJunitFailure(rhinoContext));
|
||||||
}
|
} else {
|
||||||
|
throw new IllegalStateException("Unexpected spec status received: " + spec);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitALittle() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(SLEEP_TIME_MILISECONDS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -54,10 +54,11 @@
|
||||||
/**
|
/**
|
||||||
* Envjs specific hacks
|
* Envjs specific hacks
|
||||||
* 1) Fix Envjs relative path system to work with Windows path systems
|
* 1) Fix Envjs relative path system to work with Windows path systems
|
||||||
* 2) Fix window.setTimeout() using Rhino specific functions
|
* 2) Fix CSS2Properties support for parsing style attributes: get from raw node context.
|
||||||
* 3) Fix CSS2Properties support for parsing style attributes: get from raw node context.
|
* 3) Fix CSS2Properties support for setting values: all properties have the same objmaps, wtf?
|
||||||
* 4) Fix CSS2Properties support for setting values: all properties have the same objmaps, wtf?
|
* 4) Fix focus() which sets document.activeElement correctly for jQuery:focus
|
||||||
*/
|
* 5) Fix Input click() behavior for checkboxes. Warning: jQ's click() <-> DOM's click (checked value too late set)!
|
||||||
|
**/
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var oldEnvjsUriFn = Envjs.uri;
|
var oldEnvjsUriFn = Envjs.uri;
|
||||||
|
@ -68,13 +69,6 @@
|
||||||
return oldEnvjsUriFn(path, "file:///" + ("" + Envjs.getcwd()).replace(/\\/g, '/') + "/");
|
return oldEnvjsUriFn(path, "file:///" + ("" + Envjs.getcwd()).replace(/\\/g, '/') + "/");
|
||||||
};
|
};
|
||||||
|
|
||||||
window.setTimeout = function(closure, timeout) {
|
|
||||||
spawn(function() {
|
|
||||||
java.lang.Thread.sleep(timeout);
|
|
||||||
closure();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
(function(Element) {
|
(function(Element) {
|
||||||
|
|
||||||
var style = "style";
|
var style = "style";
|
||||||
|
@ -97,6 +91,35 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
})(HTMLElement.prototype);
|
})(HTMLElement.prototype);
|
||||||
|
|
||||||
|
(function(input) {
|
||||||
|
var oldClick = input.prototype.click;
|
||||||
|
input.prototype.click = function() {
|
||||||
|
if(this.type === "checkbox") {
|
||||||
|
this.checked = !this.checked;
|
||||||
|
}
|
||||||
|
oldClick.apply(this, arguments);
|
||||||
|
}
|
||||||
|
})(HTMLInputElement);
|
||||||
|
|
||||||
|
(function(Input, Textarea, document) {
|
||||||
|
var activeElement;
|
||||||
|
function fixFocusForPrototype(element) {
|
||||||
|
var originalFocus = element.prototype.focus;
|
||||||
|
element.prototype.focus = function(element) {
|
||||||
|
activeElement = this;
|
||||||
|
originalFocus.apply(this, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fixFocusForPrototype(Input);
|
||||||
|
fixFocusForPrototype(Textarea);
|
||||||
|
|
||||||
|
document.__defineGetter__("activeElement", function() {
|
||||||
|
return activeElement;
|
||||||
|
});
|
||||||
|
|
||||||
|
})(HTMLInputElement, HTMLTextAreaElement, document);
|
||||||
|
|
||||||
(function(css) {
|
(function(css) {
|
||||||
|
|
||||||
|
@ -111,3 +134,58 @@
|
||||||
}
|
}
|
||||||
})(CSS2Properties);
|
})(CSS2Properties);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Envjs timeout fixes which use native Java code to re-implement setTimeout and setInterval
|
||||||
|
* also sets clearTimeout & clearInterval on same level.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
var threadTimeoutPool = {};
|
||||||
|
|
||||||
|
window.setTimeout = function(closure, timeout) {
|
||||||
|
var thread = spawn(function() {
|
||||||
|
try {
|
||||||
|
java.lang.Thread.sleep(timeout);
|
||||||
|
closure();
|
||||||
|
} catch(e) {
|
||||||
|
// ignore InterruptedExceptions, is probably due to clearTimeout
|
||||||
|
if (!(e.javaException instanceof java.lang.InterruptedException)) {
|
||||||
|
throw(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
threadTimeoutPool[thread.getId()] = thread;
|
||||||
|
return thread.getId();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.setInterval = function(closure, timeout) {
|
||||||
|
var thread = spawn(function() {
|
||||||
|
try {
|
||||||
|
while(true) {
|
||||||
|
java.lang.Thread.sleep(timeout);
|
||||||
|
closure();
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
// ignore InterruptedExceptions, is probably due to clearTimeout
|
||||||
|
if (!(e.javaException instanceof java.lang.InterruptedException)) {
|
||||||
|
throw(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
threadTimeoutPool[thread.getId()] = thread;
|
||||||
|
return thread.getId();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.clearTimeout = function(threadId) {
|
||||||
|
if (threadId) {
|
||||||
|
if(threadTimeoutPool[threadId]) {
|
||||||
|
threadTimeoutPool[threadId].interrupt();
|
||||||
|
delete threadTimeoutPool[threadId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.clearInterval = window.clearTimeout;
|
||||||
|
})();
|
||||||
|
|
|
@ -1,6 +1,72 @@
|
||||||
|
|
||||||
describe("envjs fixes", function() {
|
describe("envjs fixes", function() {
|
||||||
|
|
||||||
|
describe("Envjs event handling fixes", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
loadFixtures("formevents.html");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("focussing events", function() {
|
||||||
|
it("should set activeElement when focussing an input element", function() {
|
||||||
|
$("#input").focus();
|
||||||
|
expect(document.activeElement.id).toBe("input");
|
||||||
|
expect($(":focus")).toBe("#input");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should set activeElement when focussing a textarea element", function() {
|
||||||
|
$("#area").focus();
|
||||||
|
expect(document.activeElement.id).toBe("area");
|
||||||
|
expect($(":focus")).toBe("#area");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("form submit events", function() {
|
||||||
|
it("should be able to catch a formsubmit event", function() {
|
||||||
|
var submitted = false;
|
||||||
|
$("#form").submit(function() {
|
||||||
|
submitted = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#form").submit();
|
||||||
|
waitsFor(function() {
|
||||||
|
return submitted === true;
|
||||||
|
});
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(submitted).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Checkbox click events", function() {
|
||||||
|
it("should set the state of the checkbox to checked if not checked when clicked", function() {
|
||||||
|
$("#checkbox").click();
|
||||||
|
expect($("#checkbox")).toBeChecked();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should set the state of the checkbox to unchecked if checked when clicked", function() {
|
||||||
|
$("#checkbox").attr('checked', true);
|
||||||
|
$("#checkbox").click();
|
||||||
|
expect($("#checkbox")).not.toBeChecked();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should still fire the click event after clicking on a checkbox", function() {
|
||||||
|
var clicked = false;
|
||||||
|
$("#checkbox").click(function() {
|
||||||
|
clicked = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return clicked;
|
||||||
|
});
|
||||||
|
$("#checkbox").click();
|
||||||
|
runs(function() {
|
||||||
|
expect(clicked).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("CSS2 style property support for parsing style attributes", function() {
|
describe("CSS2 style property support for parsing style attributes", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
loadFixtures("styleAttributes.html");
|
loadFixtures("styleAttributes.html");
|
||||||
|
@ -52,20 +118,111 @@ describe("envjs fixes", function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("window setTimeout", function() {
|
describe("timer based events", function() {
|
||||||
|
|
||||||
it("should wait one second before executing", function() {
|
describe("setTimeout", function() {
|
||||||
var done = false;
|
it("should wait one second before executing", function() {
|
||||||
window.setTimeout(function() {
|
var done = false;
|
||||||
done = true;
|
window.setTimeout(function() {
|
||||||
}, 1000);
|
done = true;
|
||||||
|
}, 50);
|
||||||
waitsFor(function() {
|
|
||||||
return done === true;
|
waitsFor(function() {
|
||||||
|
return done === true;
|
||||||
|
});
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(done).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should return a unique timerID when the timeout has been set which can be cancelled", function() {
|
||||||
|
var done = false;
|
||||||
|
var timerID = window.setTimeout(function() {
|
||||||
|
done = true;
|
||||||
|
}, 10);
|
||||||
|
var timerID2 = window.setTimeout(function() { }, 10);
|
||||||
|
|
||||||
|
window.clearTimeout(timerID);
|
||||||
|
waits(50);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(typeof(timerID)).toEqual("number");
|
||||||
|
expect(timerID).not.toEqual(timerID2);
|
||||||
|
expect(done).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be able to use clearInterval for timeouts", function() {
|
||||||
|
var done = false;
|
||||||
|
var timerID = window.setTimeout(function() {
|
||||||
|
done = true;
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
window.clearInterval(timerID);
|
||||||
|
waits(50);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(done).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
runs(function() {
|
describe("setInterval", function() {
|
||||||
expect(done).toBeTruthy();
|
it("should call the callback method x times until the interval has been stopped", function() {
|
||||||
|
var count = 0, storedCount;
|
||||||
|
var intervalId = window.setInterval(function() {
|
||||||
|
count++;
|
||||||
|
}, 20);
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return count > 3;
|
||||||
|
});
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
storedCount = count;
|
||||||
|
window.clearInterval(intervalId);
|
||||||
|
});
|
||||||
|
waits(100);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(storedCount).toEqual(count);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be able to use setTimeout and setInterval which create unique return IDs", function() {
|
||||||
|
var id1 = window.setTimeout(function() {}, 10);
|
||||||
|
var id2 = window.setInterval(function() {}, 10);
|
||||||
|
|
||||||
|
waits(50);
|
||||||
|
this.after(function() {
|
||||||
|
window.clearInterval(id2);
|
||||||
|
});
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(id1 < id2).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be able to use clearTimeout for intervals", function() {
|
||||||
|
var count = 0, storedCount;
|
||||||
|
var intervalId = window.setInterval(function() {
|
||||||
|
count++;
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return count > 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
storedCount = count;
|
||||||
|
window.clearTimeout(intervalId);
|
||||||
|
});
|
||||||
|
waits(100);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(storedCount).toEqual(count);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
<form id="form">
|
||||||
|
<input type="text" id="input" value="text"></input>
|
||||||
|
<input type="checkbox" id="checkbox"></input>
|
||||||
|
<textarea id="area"></textarea>
|
||||||
|
<input type="submit" id="submit"></input>
|
||||||
|
</form>
|
Reference in New Issue