diff --git a/GOALS_2.0.md b/GOALS_2.0.md new file mode 100644 index 00000000..e6e9a45a --- /dev/null +++ b/GOALS_2.0.md @@ -0,0 +1,46 @@ +# (Vague) Jasmine 2.0 Goals/(Guidelines) + +1. No globals! + * jasmine library is entirely inside `jasmine` namespace + * globals required for backwards compatibility should be added in `boot.js` (EG, var describe = jasmine.getCurrentEnv().describe lives in boot.js) +1. Don't use properties as getters. Use methods. + * Properties aren't encapsulated -- can be mutated, unsafe. +1. Reporters get data objects (no methods). + * easier to refactor as needed +1. More unit tests - fewer nasty integration tests + +## Remaining non-story-able work: +* Make a `TODO` list + +### Hard +* Finish killing Globals + * Guidelines: + * New objects can have constructors on `jasmine` + * Top level functions can live on `jasmine` + * Top level (i.e., any `jasmine` property) should only be referenced inside the `Env` constructor + * Spies + * isA functions: + * isArray_ - used in matchers and spies + * isString_ + * isDOMNode_ + * isA_ + * unimplementedMethod_, used by PrettyPrinter + * jasmine.util should be util closure inside of env or something + * argsToArray is used for Spies and matching + * inherit is for how matchers are added/mixed in, reporters, and pretty printers + * formatException is used only inside Env/spec + * htmlEscape is for messages in matchers - should this be HTML at all? Is that * Matchers improvements + * move AddMatchers to Env & global (away from spec) + * make matchers unit-testable + * write doc on how to make a matcher + +### Easy + +## Other Topics + +* Build - can we, should we redo the build and release process AGAIN in order to make it less arcane + * Want to add JSHint to build + * Use a standard JS/Node based concat system instead of custom Ruby? +* Docs + * JsDoc is a pain to host and RubyMine is pretty good at navigating. I say we kill it officially + * Docco has gone over well. Should we annotate all the sources and then have Pages be more complex, having tutorials and annotated source like Backbone? Are we small enough? diff --git a/Gemfile b/Gemfile index 5d929af7..845c0c50 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,11 @@ source :rubygems gem "rake" -gem "jasmine", git: 'https://github.com/pivotal/jasmine-gem.git' +gem "jasmine", :git => 'https://github.com/pivotal/jasmine-gem.git', :branch => '2_0' unless ENV["TRAVIS"] group :debug do gem 'debugger' end end - + gemspec diff --git a/Rakefile b/Rakefile index 18530c8a..c2f7160d 100644 --- a/Rakefile +++ b/Rakefile @@ -55,9 +55,10 @@ end namespace :jasmine do task :server do port = ENV['JASMINE_PORT'] || 8888 - Jasmine.load_configuration_from_yaml(File.join(Dir.pwd, 'spec', 'jasmine.yml')) + jasmine_yml = ENV['JASMINE_YML'] || 'jasmine.yml' + Jasmine.load_configuration_from_yaml(File.join(Dir.pwd, 'spec', jasmine_yml)) config = Jasmine.config - server = Jasmine::Server.new(8888, Jasmine::Application.app(config)) + server = Jasmine::Server.new(port, Jasmine::Application.app(config)) server.start puts "your tests are here:" diff --git a/lib/jasmine-core.rb b/lib/jasmine-core.rb index ecf968a6..3bf880c3 100644 --- a/lib/jasmine-core.rb +++ b/lib/jasmine-core.rb @@ -23,6 +23,14 @@ module Jasmine spec_files("node") end + def boot_files + ["boot.js"] + end + + def boot_dir + File.join(path, 'boot') + end + def spec_files(type) raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type) (Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq diff --git a/lib/jasmine-core/boot/boot.js b/lib/jasmine-core/boot/boot.js new file mode 100644 index 00000000..bd649473 --- /dev/null +++ b/lib/jasmine-core/boot/boot.js @@ -0,0 +1,92 @@ +(function() { + var env = jasmine.getEnv(); + + var jasmineInterface = { + describe: function(description, specDefinitions) { + return env.describe(description, specDefinitions); + }, + + xdescribe: function(description, specDefinitions) { + return env.xdescribe(description, specDefinitions); + }, + + it: function(desc, func) { + return env.it(desc, func); + }, + + xit: function(desc, func) { + return env.xit(desc, func); + }, + + beforeEach: function(beforeEachFunction) { + return env.beforeEach(beforeEachFunction); + }, + + afterEach: function(afterEachFunction) { + return env.afterEach(afterEachFunction); + }, + + expect: function(actual) { + return env.expect(actual); + }, + + addMatchers: function(matchers) { + return env.addMatchers(matchers); + }, + + spyOn: function(obj, methodName) { + return env.spyOn(obj, methodName); + }, + + clock: env.clock, + setTimeout: env.clock.setTimeout, + clearTimeout: env.clock.clearTimeout, + setInterval: env.clock.setInterval, + clearInterval: env.clock.clearInterval, + + jsApiReporter: new jasmine.JsApiReporter(jasmine) + }; + + if (typeof window == "undefined" && typeof exports == "object") { + extend(exports, jasmineInterface); + } else { + extend(window, jasmineInterface); + } + + var queryString = new jasmine.QueryString({ + getWindowLocation: function() { return window.location; } + }); + + env.catchExceptions(queryString.getParam("catch")); + + var htmlReporter = new jasmine.HtmlReporter({ + env: env, + queryString: queryString, + getContainer: function() { return document.body; }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); } + }); + + env.addReporter(jasmineInterface.jsApiReporter); + env.addReporter(htmlReporter); + + env.specFilter = function(spec) { + return htmlReporter.specFilter(spec); + }; + + var currentWindowOnload = window.onload; + + window.onload = function() { + if (currentWindowOnload) { + currentWindowOnload(); + } + htmlReporter.initialize(); + env.execute(); + }; + + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + +}()); diff --git a/lib/jasmine-core/example/SpecRunner.html b/lib/jasmine-core/example/SpecRunner.html deleted file mode 100644 index ea58503d..00000000 --- a/lib/jasmine-core/example/SpecRunner.html +++ /dev/null @@ -1,54 +0,0 @@ - - -
-jasmine.log in production code.
- */
-jasmine.log = function() {
- var spec = jasmine.getEnv().currentSpec;
- spec.log.apply(spec, arguments);
-};
-
-/**
- * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
- *
- * @example
- * // spy example
- * var foo = {
- * not: function(bool) { return !bool; }
- * }
- * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
- *
- * @see jasmine.createSpy
- * @param obj
- * @param methodName
- * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
- */
-var spyOn = function(obj, methodName) {
- return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
-};
-if (isCommonJS) exports.spyOn = spyOn;
-
-/**
- * Creates a Jasmine spec that will be added to the current suite.
- *
- * // TODO: pending tests
- *
- * @example
- * it('should be true', function() {
- * expect(true).toEqual(true);
- * });
- *
- * @param {String} desc description of this specification
- * @param {Function} func defines the preconditions and expectations of the spec
- */
-var it = function(desc, func) {
- return jasmine.getEnv().it(desc, func);
-};
-if (isCommonJS) exports.it = it;
-
-/**
- * Creates a disabled Jasmine spec.
- *
- * A convenience method that allows existing specs to be disabled temporarily during development.
- *
- * @param {String} desc description of this specification
- * @param {Function} func defines the preconditions and expectations of the spec
- */
-var xit = function(desc, func) {
- return jasmine.getEnv().xit(desc, func);
-};
-if (isCommonJS) exports.xit = xit;
-
-/**
- * Starts a chain for a Jasmine expectation.
- *
- * It is passed an Object that is the actual value and should chain to one of the many
- * jasmine.Matchers functions.
- *
- * @param {Object} actual Actual value to test against and expected value
- * @return {jasmine.Matchers}
- */
-var expect = function(actual) {
- return jasmine.getEnv().currentSpec.expect(actual);
-};
-if (isCommonJS) exports.expect = expect;
-
-/**
- * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
- *
- * @param {Function} func Function that defines part of a jasmine spec.
- */
-var runs = function(func) {
- jasmine.getEnv().currentSpec.runs(func);
-};
-if (isCommonJS) exports.runs = runs;
-
-/**
- * Waits a fixed time period before moving to the next block.
- *
- * @deprecated Use waitsFor() instead
- * @param {Number} timeout milliseconds to wait
- */
-var waits = function(timeout) {
- jasmine.getEnv().currentSpec.waits(timeout);
-};
-if (isCommonJS) exports.waits = waits;
-
-/**
- * Waits for the latchFunction to return true before proceeding to the next block.
- *
- * @param {Function} latchFunction
- * @param {String} optional_timeoutMessage
- * @param {Number} optional_timeout
- */
-var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
- jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
-};
-if (isCommonJS) exports.waitsFor = waitsFor;
-
-/**
- * A function that is called before each spec in a suite.
- *
- * Used for spec setup, including validating assumptions.
- *
- * @param {Function} beforeEachFunction
- */
-var beforeEach = function(beforeEachFunction) {
- jasmine.getEnv().beforeEach(beforeEachFunction);
-};
-if (isCommonJS) exports.beforeEach = beforeEach;
-
-/**
- * A function that is called after each spec in a suite.
- *
- * Used for restoring any state that is hijacked during spec execution.
- *
- * @param {Function} afterEachFunction
- */
-var afterEach = function(afterEachFunction) {
- jasmine.getEnv().afterEach(afterEachFunction);
-};
-if (isCommonJS) exports.afterEach = afterEach;
-
-/**
- * Defines a suite of specifications.
- *
- * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
- * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
- * of setup in some tests.
- *
- * @example
- * // TODO: a simple suite
- *
- * // TODO: a simple suite with a nested describe block
- *
- * @param {String} description A string, usually the class under test.
- * @param {Function} specDefinitions function that defines several specs.
- */
-var describe = function(description, specDefinitions) {
- return jasmine.getEnv().describe(description, specDefinitions);
-};
-if (isCommonJS) exports.describe = describe;
-
-/**
- * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
- *
- * @param {String} description A string, usually the class under test.
- * @param {Function} specDefinitions function that defines several specs.
- */
-var xdescribe = function(description, specDefinitions) {
- return jasmine.getEnv().xdescribe(description, specDefinitions);
-};
-if (isCommonJS) exports.xdescribe = xdescribe;
-
-
-// Provide the XMLHttpRequest class for IE 5.x-6.x:
-jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
- function tryIt(f) {
- try {
- return f();
- } catch(e) {
- }
- return null;
- }
-
- var xhr = tryIt(function() {
- return new ActiveXObject("Msxml2.XMLHTTP.6.0");
- }) ||
- tryIt(function() {
- return new ActiveXObject("Msxml2.XMLHTTP.3.0");
- }) ||
- tryIt(function() {
- return new ActiveXObject("Msxml2.XMLHTTP");
- }) ||
- tryIt(function() {
- return new ActiveXObject("Microsoft.XMLHTTP");
- });
-
- if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
-
- return xhr;
-} : XMLHttpRequest;
/**
* @namespace
*/
@@ -703,485 +439,572 @@ jasmine.util.argsToArray = function(args) {
var arrayOfArgs = [];
for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
return arrayOfArgs;
+};jasmine.exceptionMessageFor = function(e) {
+ var message = e.name
+ + ': '
+ + e.message
+ + ' in '
+ + (e.fileName || e.sourceURL || '')
+ + ' (line '
+ + (e.line || e.lineNumber || '')
+ + ')';
+
+ return message;
};
-
-jasmine.util.extend = function(destination, source) {
- for (var property in source) destination[property] = source[property];
- return destination;
-};
-
-/**
- * Environment for Jasmine
- *
- * @constructor
- */
-jasmine.Env = function() {
- this.currentSpec = null;
- this.currentSuite = null;
- this.currentRunner_ = new jasmine.Runner(this);
-
- this.reporter = new jasmine.MultiReporter();
-
- this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
- this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
- this.lastUpdate = 0;
- this.specFilter = function() {
- return true;
+//TODO: expectation result may make more sense as a presentation of an expectation.
+jasmine.buildExpectationResult = function(params) {
+ return {
+ type: 'expect',
+ matcherName: params.matcherName,
+ expected: params.expected,
+ actual: params.actual,
+ message: params.passed ? 'Passed.' : params.message,
+ trace: params.passed ? '' : (params.trace || new Error(this.message)),
+ passed: params.passed
};
-
- this.nextSpecId_ = 0;
- this.nextSuiteId_ = 0;
- this.equalityTesters_ = [];
-
- // wrap matchers
- this.matchersClass = function() {
- jasmine.Matchers.apply(this, arguments);
- };
- jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
-
- jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
};
+(function() {
+ jasmine.Env = function(options) {
+ options = options || {};
+ var self = this;
+ var global = options.global || jasmine.getGlobal();
+
+ var catchExceptions = true;
+
+ this.clock = new jasmine.Clock(global, new jasmine.DelayedFunctionScheduler());
+
+ this.jasmine = jasmine;
+ this.spies_ = [];
+ this.currentSpec = null;
+
+ this.undefined = jasmine.undefined;
+
+ this.reporter = new jasmine.ReportDispatcher([
+ "jasmineStarted",
+ "jasmineDone",
+ "suiteStarted",
+ "suiteDone",
+ "specStarted",
+ "specDone"
+ ]);
+
+ this.lastUpdate = 0;
+ this.specFilter = function() {
+ return true;
+ };
+
+ this.nextSpecId_ = 0;
+ this.nextSuiteId_ = 0;
+ this.equalityTesters_ = [];
+
+ // wrap matchers
+ this.matchersClass = function() {
+ jasmine.Matchers.apply(this, arguments);
+ };
+ jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
+
+ jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
+
+ var expectationFactory = function(actual, spec) {
+ var expect = new (self.matchersClass)(self, actual, spec);
+ expect.not = new (self.matchersClass)(self, actual, spec, true);
+ return expect;
+ };
+
+ var specStarted = function(spec) {
+ self.currentSpec = spec;
+ self.reporter.specStarted(spec.result);
+ };
+
+ var beforeFns = function(currentSuite) {
+ return function() {
+ var befores = [];
+ for (var suite = currentSuite; suite; suite = suite.parentSuite) {
+ befores = befores.concat(suite.beforeFns)
+ }
+ return befores.reverse();
+ }
+ };
+
+ var afterFns = function(currentSuite) {
+ return function() {
+ var afters = [];
+ for (var suite = currentSuite; suite; suite = suite.parentSuite) {
+ afters = afters.concat(suite.afterFns)
+ }
+ return afters;
+ }
+ };
+
+ var exceptionFormatter = jasmine.exceptionFormatter;
+
+ var specConstructor = jasmine.Spec;
+
+ var getSpecName = function(spec, currentSuite) {
+ return currentSuite.getFullName() + ' ' + spec.description + '.';
+ };
+
+ var buildExpectationResult = jasmine.buildExpectationResult;
+ var expectationResultFactory = function(attrs) {
+ return buildExpectationResult(attrs);
+ };
+
+ // TODO: fix this naming, and here's where the value comes in
+ this.catchExceptions = function(value) {
+ catchExceptions = !!value;
+ return catchExceptions;
+ };
+
+ this.catchingExceptions = function() {
+ return catchExceptions;
+ };
+
+ var maximumSpecCallbackDepth = 100;
+ var currentSpecCallbackDepth = 0;
+
+ function encourageGarbageCollection(fn) {
+ currentSpecCallbackDepth++;
+ if (currentSpecCallbackDepth > maximumSpecCallbackDepth) {
+ currentSpecCallbackDepth = 0;
+ global.setTimeout(fn, 0);
+ } else {
+ fn();
+ }
+ }
+
+ var queueRunnerFactory = function(options) {
+ options.catchingExceptions = self.catchingExceptions;
+ options.encourageGC = options.encourageGarbageCollection || encourageGarbageCollection;
+
+ new jasmine.QueueRunner(options).run(options.fns, 0);
+ };
-jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
-jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
-jasmine.Env.prototype.setInterval = jasmine.setInterval;
-jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
+ var totalSpecsDefined = 0;
+ this.specFactory = function(description, fn, suite) {
+ totalSpecsDefined++;
-/**
- * @returns an object containing jasmine version build info, if set.
- */
-jasmine.Env.prototype.version = function () {
- if (jasmine.version_) {
- return jasmine.version_;
- } else {
- throw new Error('Version not set');
- }
-};
+ var spec = new specConstructor({
+ id: self.nextSpecId(),
+ beforeFns: beforeFns(suite),
+ afterFns: afterFns(suite),
+ expectationFactory: expectationFactory,
+ exceptionFormatter: exceptionFormatter,
+ resultCallback: specResultCallback,
+ getSpecName: function(spec) {
+ return getSpecName(spec, suite)
+ },
+ onStart: specStarted,
+ description: description,
+ expectationResultFactory: expectationResultFactory,
+ queueRunner: queueRunnerFactory,
+ fn: fn
+ });
-/**
- * @returns string containing jasmine version build info, if set.
- */
-jasmine.Env.prototype.versionString = function() {
- if (!jasmine.version_) {
- return "version unknown";
- }
+ if (!self.specFilter(spec)) {
+ spec.disable();
+ }
- var version = this.version();
- var versionString = version.major + "." + version.minor + "." + version.build;
- if (version.release_candidate) {
- versionString += ".rc" + version.release_candidate;
- }
- versionString += " revision " + version.revision;
- return versionString;
-};
+ return spec;
-/**
- * @returns a sequential integer starting at 0
- */
-jasmine.Env.prototype.nextSpecId = function () {
- return this.nextSpecId_++;
-};
+ function specResultCallback(result) {
+ self.removeAllSpies();
+ self.clock.uninstall();
+ self.currentSpec = null;
+ self.reporter.specDone(result);
+ }
+ };
-/**
- * @returns a sequential integer starting at 0
- */
-jasmine.Env.prototype.nextSuiteId = function () {
- return this.nextSuiteId_++;
-};
+ var suiteStarted = function(suite) {
+ self.reporter.suiteStarted(suite.result);
+ };
-/**
- * Register a reporter to receive status updates from Jasmine.
- * @param {jasmine.Reporter} reporter An object which will receive status updates.
- */
-jasmine.Env.prototype.addReporter = function(reporter) {
- this.reporter.addReporter(reporter);
-};
+ var suiteConstructor = jasmine.Suite;
-jasmine.Env.prototype.execute = function() {
- this.currentRunner_.execute();
-};
-
-jasmine.Env.prototype.describe = function(description, specDefinitions) {
- var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
-
- var parentSuite = this.currentSuite;
- if (parentSuite) {
- parentSuite.add(suite);
- } else {
- this.currentRunner_.add(suite);
- }
-
- this.currentSuite = suite;
-
- var declarationError = null;
- try {
- specDefinitions.call(suite);
- } catch(e) {
- declarationError = e;
- }
-
- if (declarationError) {
- this.it("encountered a declaration exception", function() {
- throw declarationError;
+ this.topSuite = new jasmine.Suite({
+ env: this,
+ id: this.nextSuiteId(),
+ description: 'Jasmine__TopLevel__Suite',
+ queueRunner: queueRunnerFactory,
+ completeCallback: function() {}, // TODO - hook this up
+ resultCallback: function() {} // TODO - hook this up
});
- }
+ this.currentSuite = this.topSuite;
- this.currentSuite = parentSuite;
+ this.suiteFactory = function(description) {
+ return new suiteConstructor({
+ env: self,
+ id: self.nextSuiteId(),
+ description: description,
+ parentSuite: self.currentSuite,
+ queueRunner: queueRunnerFactory,
+ onStart: suiteStarted,
+ resultCallback: function(attrs) {
+ self.reporter.suiteDone(attrs);
+ }
+ });
+ };
- return suite;
-};
-
-jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
- if (this.currentSuite) {
- this.currentSuite.beforeEach(beforeEachFunction);
- } else {
- this.currentRunner_.beforeEach(beforeEachFunction);
- }
-};
-
-jasmine.Env.prototype.currentRunner = function () {
- return this.currentRunner_;
-};
-
-jasmine.Env.prototype.afterEach = function(afterEachFunction) {
- if (this.currentSuite) {
- this.currentSuite.afterEach(afterEachFunction);
- } else {
- this.currentRunner_.afterEach(afterEachFunction);
- }
-
-};
-
-jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
- return {
- execute: function() {
- }
- };
-};
-
-jasmine.Env.prototype.it = function(description, func) {
- var spec = new jasmine.Spec(this, this.currentSuite, description);
- this.currentSuite.add(spec);
- this.currentSpec = spec;
-
- if (func) {
- spec.runs(func);
- }
-
- return spec;
-};
-
-jasmine.Env.prototype.xit = function(desc, func) {
- return {
- id: this.nextSpecId(),
- runs: function() {
- }
- };
-};
-
-jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
- if (a.source != b.source)
- mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
-
- if (a.ignoreCase != b.ignoreCase)
- mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
-
- if (a.global != b.global)
- mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
-
- if (a.multiline != b.multiline)
- mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
-
- if (a.sticky != b.sticky)
- mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
-
- return (mismatchValues.length === 0);
-};
-
-jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
- if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
- return true;
- }
-
- a.__Jasmine_been_here_before__ = b;
- b.__Jasmine_been_here_before__ = a;
-
- var hasKey = function(obj, keyName) {
- return obj !== null && obj[keyName] !== jasmine.undefined;
+ this.execute = function() {
+ this.reporter.jasmineStarted({
+ totalSpecsDefined: totalSpecsDefined
+ });
+ this.topSuite.execute(this.reporter.jasmineDone);
+ };
};
- for (var property in b) {
- if (!hasKey(a, property) && hasKey(b, property)) {
- mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+ //TODO: shim Spec addMatchers behavior into Env. Should be rewritten to remove globals, etc.
+ jasmine.Env.prototype.addMatchers = function(matchersPrototype) {
+ var parent = this.matchersClass;
+ var newMatchersClass = function() {
+ parent.apply(this, arguments);
+ };
+ jasmine.util.inherit(newMatchersClass, parent);
+ jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
+ this.matchersClass = newMatchersClass;
+ };
+
+ jasmine.Env.prototype.version = function() {
+ if (this.jasmine.version_) {
+ return this.jasmine.version_;
+ } else {
+ throw new Error('Version not set');
}
- }
- for (property in a) {
- if (!hasKey(b, property) && hasKey(a, property)) {
- mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
+ };
+
+ jasmine.Env.prototype.expect = function(actual) {
+ return this.currentSpec.expect(actual);
+ };
+
+ jasmine.Env.prototype.spyOn = function(obj, methodName) {
+ if (obj == this.undefined) {
+ throw "spyOn could not find an object to spy upon for " + methodName + "()";
}
- }
- for (property in b) {
- if (property == '__Jasmine_been_here_before__') continue;
- if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
- mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
+
+ if (obj[methodName] === this.undefined) {
+ throw methodName + '() method does not exist';
}
- }
- if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
- mismatchValues.push("arrays were not the same length");
- }
-
- delete a.__Jasmine_been_here_before__;
- delete b.__Jasmine_been_here_before__;
- return (mismatchKeys.length === 0 && mismatchValues.length === 0);
-};
-
-jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
- mismatchKeys = mismatchKeys || [];
- mismatchValues = mismatchValues || [];
-
- for (var i = 0; i < this.equalityTesters_.length; i++) {
- var equalityTester = this.equalityTesters_[i];
- var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
- if (result !== jasmine.undefined) return result;
- }
-
- if (a === b) return true;
-
- if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
- return (a == jasmine.undefined && b == jasmine.undefined);
- }
-
- if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
- return a === b;
- }
-
- if (a instanceof Date && b instanceof Date) {
- return a.getTime() == b.getTime();
- }
-
- if (a.jasmineMatches) {
- return a.jasmineMatches(b);
- }
-
- if (b.jasmineMatches) {
- return b.jasmineMatches(a);
- }
-
- if (a instanceof jasmine.Matchers.ObjectContaining) {
- return a.matches(b);
- }
-
- if (b instanceof jasmine.Matchers.ObjectContaining) {
- return b.matches(a);
- }
-
- if (jasmine.isString_(a) && jasmine.isString_(b)) {
- return (a == b);
- }
-
- if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
- return (a == b);
- }
-
- if (a instanceof RegExp && b instanceof RegExp) {
- return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
- }
-
- if (typeof a === "object" && typeof b === "object") {
- return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
- }
-
- //Straight check
- return (a === b);
-};
-
-jasmine.Env.prototype.contains_ = function(haystack, needle) {
- if (jasmine.isArray_(haystack)) {
- for (var i = 0; i < haystack.length; i++) {
- if (this.equals_(haystack[i], needle)) return true;
+ if (obj[methodName] && obj[methodName].isSpy) {
+ //TODO?: should this return the current spy? Downside: may cause user confusion about spy state
+ throw new Error(methodName + ' has already been spied upon');
}
- return false;
- }
- return haystack.indexOf(needle) >= 0;
-};
-jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
- this.equalityTesters_.push(equalityTester);
-};
-/** No-op base class for Jasmine reporters.
- *
- * @constructor
- */
-jasmine.Reporter = function() {
-};
+ var spyObj = jasmine.createSpy(methodName);
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
-};
+ this.spies_.push(spyObj);
+ spyObj.baseObj = obj;
+ spyObj.methodName = methodName;
+ spyObj.originalValue = obj[methodName];
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
-};
+ obj[methodName] = spyObj;
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
-};
+ return spyObj;
+ };
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
-};
+ // TODO: move this to closure
+ jasmine.Env.prototype.removeAllSpies = function() {
+ for (var i = 0; i < this.spies_.length; i++) {
+ var spy = this.spies_[i];
+ spy.baseObj[spy.methodName] = spy.originalValue;
+ }
+ this.spies_ = [];
+ };
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportSpecResults = function(spec) {
-};
+ // TODO: move this to closure
+ jasmine.Env.prototype.versionString = function() {
+ if (!this.jasmine.version_) {
+ return "version unknown";
+ }
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.log = function(str) {
-};
+ var version = this.version();
+ var versionString = version.major + "." + version.minor + "." + version.build;
+ if (version.release_candidate) {
+ versionString += ".rc" + version.release_candidate;
+ }
+ versionString += " revision " + version.revision;
+ return versionString;
+ };
-/**
- * Blocks are functions with executable code that make up a spec.
- *
- * @constructor
- * @param {jasmine.Env} env
- * @param {Function} func
- * @param {jasmine.Spec} spec
- */
-jasmine.Block = function(env, func, spec) {
- this.env = env;
- this.func = func;
- this.spec = spec;
-};
+ // TODO: move this to closure
+ jasmine.Env.prototype.nextSpecId = function() {
+ return this.nextSpecId_++;
+ };
-jasmine.Block.prototype.execute = function(onComplete) {
- if (!jasmine.CATCH_EXCEPTIONS) {
- this.func.apply(this.spec);
- }
- else {
+ // TODO: move this to closure
+ jasmine.Env.prototype.nextSuiteId = function() {
+ return this.nextSuiteId_++;
+ };
+
+ // TODO: move this to closure
+ jasmine.Env.prototype.addReporter = function(reporter) {
+ this.reporter.addReporter(reporter);
+ };
+
+ // TODO: move this to closure
+ jasmine.Env.prototype.describe = function(description, specDefinitions) {
+ var suite = this.suiteFactory(description, specDefinitions);
+
+ var parentSuite = this.currentSuite;
+ parentSuite.addSuite(suite);
+ this.currentSuite = suite;
+
+ var declarationError = null;
try {
- this.func.apply(this.spec);
+ specDefinitions.call(suite);
} catch (e) {
- this.spec.fail(e);
+ declarationError = e;
}
- }
- onComplete();
-};
-/** JavaScript API reporter.
- *
- * @constructor
- */
-jasmine.JsApiReporter = function() {
+
+ if (declarationError) {
+ this.it("encountered a declaration exception", function() {
+ throw declarationError;
+ });
+ }
+
+ this.currentSuite = parentSuite;
+
+ return suite;
+ };
+
+ // TODO: move this to closure
+ jasmine.Env.prototype.xdescribe = function(description, specDefinitions) {
+ var suite = this.describe(description, specDefinitions);
+ suite.disable();
+ return suite;
+ };
+
+ // TODO: move this to closure
+ jasmine.Env.prototype.it = function(description, fn) {
+ var spec = this.specFactory(description, fn, this.currentSuite);
+ this.currentSuite.addSpec(spec);
+ return spec;
+ };
+
+ // TODO: move this to closure
+ jasmine.Env.prototype.xit = function(description, fn) {
+ var spec = this.it(description, fn);
+ spec.disable();
+ return spec;
+ };
+
+ // TODO: move this to closure
+ jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
+ this.currentSuite.beforeEach(beforeEachFunction);
+ };
+
+ // TODO: move this to closure
+ jasmine.Env.prototype.afterEach = function(afterEachFunction) {
+ this.currentSuite.afterEach(afterEachFunction);
+ };
+
+ // TODO: Still needed?
+ jasmine.Env.prototype.currentRunner = function() {
+ return this.topSuite;
+ };
+
+ jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
+ if (a.source != b.source)
+ mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
+
+ if (a.ignoreCase != b.ignoreCase)
+ mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
+
+ if (a.global != b.global)
+ mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
+
+ if (a.multiline != b.multiline)
+ mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
+
+ if (a.sticky != b.sticky)
+ mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
+
+ return (mismatchValues.length === 0);
+ };
+
+ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
+ if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
+ return true;
+ }
+
+ a.__Jasmine_been_here_before__ = b;
+ b.__Jasmine_been_here_before__ = a;
+
+ var hasKey = function(obj, keyName) {
+ return obj !== null && obj[keyName] !== this.undefined;
+ };
+
+ for (var property in b) {
+ if (!hasKey(a, property) && hasKey(b, property)) {
+ mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+ }
+ }
+ for (property in a) {
+ if (!hasKey(b, property) && hasKey(a, property)) {
+ mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
+ }
+ }
+ for (property in b) {
+ if (property == '__Jasmine_been_here_before__') continue;
+ if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
+ mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
+ }
+ }
+
+ if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
+ mismatchValues.push("arrays were not the same length");
+ }
+
+ delete a.__Jasmine_been_here_before__;
+ delete b.__Jasmine_been_here_before__;
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+ };
+
+ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
+ mismatchKeys = mismatchKeys || [];
+ mismatchValues = mismatchValues || [];
+
+ for (var i = 0; i < this.equalityTesters_.length; i++) {
+ var equalityTester = this.equalityTesters_[i];
+ var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
+ if (result !== this.undefined) return result;
+ }
+
+ if (a === b) return true;
+
+ if (a === this.undefined || a === null || b === this.undefined || b === null) {
+ return (a == this.undefined && b == this.undefined);
+ }
+
+ if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
+ return a === b;
+ }
+
+ if (a instanceof Date && b instanceof Date) {
+ return a.getTime() == b.getTime();
+ }
+
+ if (a.jasmineMatches) {
+ return a.jasmineMatches(b);
+ }
+
+ if (b.jasmineMatches) {
+ return b.jasmineMatches(a);
+ }
+
+ if (a instanceof jasmine.Matchers.ObjectContaining) {
+ return a.matches(b);
+ }
+
+ if (b instanceof jasmine.Matchers.ObjectContaining) {
+ return b.matches(a);
+ }
+
+ if (jasmine.isString_(a) && jasmine.isString_(b)) {
+ return (a == b);
+ }
+
+ if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
+ return (a == b);
+ }
+
+ if (a instanceof RegExp && b instanceof RegExp) {
+ return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
+ }
+
+ if (typeof a === "object" && typeof b === "object") {
+ return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
+ }
+
+ //Straight check
+ return (a === b);
+ };
+
+ jasmine.Env.prototype.contains_ = function(haystack, needle) {
+ if (jasmine.isArray_(haystack)) {
+ for (var i = 0; i < haystack.length; i++) {
+ if (this.equals_(haystack[i], needle)) return true;
+ }
+ return false;
+ }
+ return haystack.indexOf(needle) >= 0;
+ };
+
+ jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
+ this.equalityTesters_.push(equalityTester);
+ };
+}());
+jasmine.JsApiReporter = function(jasmine) {
+ this.jasmine = jasmine || {};
this.started = false;
this.finished = false;
this.suites_ = [];
this.results_ = {};
-};
-jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
- this.started = true;
- var suites = runner.topLevelSuites();
- for (var i = 0; i < suites.length; i++) {
- var suite = suites[i];
- this.suites_.push(this.summarize_(suite));
- }
-};
+ var status = 'loaded';
-jasmine.JsApiReporter.prototype.suites = function() {
- return this.suites_;
-};
-
-jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
- var isSuite = suiteOrSpec instanceof jasmine.Suite;
- var summary = {
- id: suiteOrSpec.id,
- name: suiteOrSpec.description,
- type: isSuite ? 'suite' : 'spec',
- children: []
+ this.jasmineStarted = function() {
+ this.started = true;
+ status = 'started';
};
-
- if (isSuite) {
- var children = suiteOrSpec.children();
- for (var i = 0; i < children.length; i++) {
- summary.children.push(this.summarize_(children[i]));
- }
- }
- return summary;
-};
-jasmine.JsApiReporter.prototype.results = function() {
- return this.results_;
-};
-
-jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
- return this.results_[specId];
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
- this.finished = true;
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
- this.results_[spec.id] = {
- messages: spec.results().getItems(),
- result: spec.results().failedCount > 0 ? "failed" : "passed"
+ this.jasmineDone = function() {
+ this.finished = true;
+ status = 'done';
};
-};
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.log = function(str) {
-};
-
-jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
- var results = {};
- for (var i = 0; i < specIds.length; i++) {
- var specId = specIds[i];
- results[specId] = this.summarizeResult_(this.results_[specId]);
- }
- return results;
-};
-
-jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
- var summaryMessages = [];
- var messagesLength = result.messages.length;
- for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
- var resultMessage = result.messages[messageIndex];
- summaryMessages.push({
- text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
- passed: resultMessage.passed ? resultMessage.passed() : true,
- type: resultMessage.type,
- message: resultMessage.message,
- trace: {
- stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
- }
- });
- }
-
- return {
- result : result.result,
- messages : summaryMessages
+ this.status = function() {
+ return status;
};
-};
-/**
+ var suites = {};
+
+ this.suiteStarted = function(result) {
+ storeSuite(result);
+ };
+
+ this.suiteDone = function(result) {
+ storeSuite(result);
+ };
+
+ function storeSuite(result) {
+ suites[result.id] = result;
+ }
+
+ this.suites = function() {
+ return suites;
+ };
+
+ var specs = {};
+
+ this.specStarted = function(result) {
+ storeSpec(result);
+ };
+
+ this.specDone = function(result) {
+ storeSpec(result);
+ };
+
+ function storeSpec(result) {
+ specs[result.id] = result;
+ }
+
+ this.specs = function() {
+ return specs;
+ };
+
+};/**
* @constructor
* @param {jasmine.Env} env
* @param actual
* @param {jasmine.Spec} spec
*/
jasmine.Matchers = function(env, actual, spec, opt_isNot) {
+ //TODO: true dependency: equals, contains
this.env = env;
this.actual = actual;
this.spec = spec;
this.isNot = opt_isNot || false;
- this.reportWasCalled_ = false;
};
// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
@@ -1189,14 +1012,9 @@ jasmine.Matchers.pp = function(str) {
throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
};
-// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
-jasmine.Matchers.prototype.report = function(result, failing_message, details) {
- throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
-};
jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
for (var methodName in prototype) {
- if (methodName == 'report') continue;
var orig = prototype[methodName];
matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
}
@@ -1211,8 +1029,6 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
result = !result;
}
- if (this.reportWasCalled_) return result;
-
var message;
if (!result) {
if (this.message) {
@@ -1232,14 +1048,14 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
message += ".";
}
}
- var expectationResult = new jasmine.ExpectationResult({
+ var expectationResult = jasmine.buildExpectationResult({
matcherName: matcherName,
passed: result,
expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
actual: this.actual,
message: message
});
- this.spec.addMatcherResult(expectationResult);
+ this.spec.addExpectationResult(result, expectationResult);
return jasmine.undefined;
};
};
@@ -1574,304 +1390,6 @@ jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mis
jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
return "jasmine.log in production code.
- */
-jasmine.Spec.prototype.log = function() {
- return this.results_.log(arguments);
-};
-
-jasmine.Spec.prototype.runs = function (func) {
- var block = new jasmine.Block(this.env, func, this);
- this.addToQueue(block);
- return this;
-};
-
-jasmine.Spec.prototype.addToQueue = function (block) {
- if (this.queue.isRunning()) {
- this.queue.insertNext(block);
- } else {
- this.queue.add(block);
- }
-};
-
-/**
- * @param {jasmine.ExpectationResult} result
- */
-jasmine.Spec.prototype.addMatcherResult = function(result) {
- this.results_.addResult(result);
-};
-
-jasmine.Spec.prototype.expect = function(actual) {
- var positive = new (this.getMatchersClass_())(this.env, actual, this);
- positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
- return positive;
-};
-
-/**
- * Waits a fixed time period before moving to the next block.
- *
- * @deprecated Use waitsFor() instead
- * @param {Number} timeout milliseconds to wait
- */
-jasmine.Spec.prototype.waits = function(timeout) {
- var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
- this.addToQueue(waitsFunc);
- return this;
-};
-
-/**
- * Waits for the latchFunction to return true before proceeding to the next block.
- *
- * @param {Function} latchFunction
- * @param {String} optional_timeoutMessage
- * @param {Number} optional_timeout
- */
-jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
- var latchFunction_ = null;
- var optional_timeoutMessage_ = null;
- var optional_timeout_ = null;
-
- for (var i = 0; i < arguments.length; i++) {
- var arg = arguments[i];
- switch (typeof arg) {
- case 'function':
- latchFunction_ = arg;
- break;
- case 'string':
- optional_timeoutMessage_ = arg;
- break;
- case 'number':
- optional_timeout_ = arg;
- break;
- }
- }
-
- var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
- this.addToQueue(waitsForFunc);
- return this;
-};
-
-jasmine.Spec.prototype.fail = function (e) {
- var expectationResult = new jasmine.ExpectationResult({
- passed: false,
- message: e ? jasmine.util.formatException(e) : 'Exception',
- trace: { stack: e.stack }
- });
- this.results_.addResult(expectationResult);
-};
-
-jasmine.Spec.prototype.getMatchersClass_ = function() {
- return this.matchersClass || this.env.matchersClass;
-};
-
-jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
- var parent = this.getMatchersClass_();
- var newMatchersClass = function() {
- parent.apply(this, arguments);
- };
- jasmine.util.inherit(newMatchersClass, parent);
- jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
- this.matchersClass = newMatchersClass;
-};
-
-jasmine.Spec.prototype.finishCallback = function() {
- this.env.reporter.reportSpecResults(this);
-};
-
-jasmine.Spec.prototype.finish = function(onComplete) {
- this.removeAllSpies();
- this.finishCallback();
- if (onComplete) {
- onComplete();
- }
-};
-
-jasmine.Spec.prototype.after = function(doAfter) {
- if (this.queue.isRunning()) {
- this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
- } else {
- this.afterCallbacks.unshift(doAfter);
- }
-};
-
-jasmine.Spec.prototype.execute = function(onComplete) {
- var spec = this;
- if (!spec.env.specFilter(spec)) {
- spec.results_.skipped = true;
- spec.finish(onComplete);
+jasmine.QueueRunner.prototype.run = function(fns, index) {
+ if (index >= fns.length) {
+ this.encourageGC(this.onComplete);
return;
}
- this.env.reporter.reportSpecStarting(this);
-
- spec.env.currentSpec = spec;
-
- spec.addBeforesAndAftersToQueue();
-
- spec.queue.start(function () {
- spec.finish(onComplete);
- });
-};
-
-jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
- var runner = this.env.currentRunner();
- var i;
-
- for (var suite = this.suite; suite; suite = suite.parentSuite) {
- for (i = 0; i < suite.before_.length; i++) {
- this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
- }
- }
- for (i = 0; i < runner.before_.length; i++) {
- this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
- }
- for (i = 0; i < this.afterCallbacks.length; i++) {
- this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
- }
- for (suite = this.suite; suite; suite = suite.parentSuite) {
- for (i = 0; i < suite.after_.length; i++) {
- this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
- }
- }
- for (i = 0; i < runner.after_.length; i++) {
- this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
- }
-};
-
-jasmine.Spec.prototype.explodes = function() {
- throw 'explodes function should not have been called';
-};
-
-jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
- if (obj == jasmine.undefined) {
- throw "spyOn could not find an object to spy upon for " + methodName + "()";
- }
-
- if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
- throw methodName + '() method does not exist';
- }
-
- if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
- throw new Error(methodName + ' has already been spied upon');
- }
-
- var spyObj = jasmine.createSpy(methodName);
-
- this.spies_.push(spyObj);
- spyObj.baseObj = obj;
- spyObj.methodName = methodName;
- spyObj.originalValue = obj[methodName];
-
- obj[methodName] = spyObj;
-
- return spyObj;
-};
-
-jasmine.Spec.prototype.removeAllSpies = function() {
- for (var i = 0; i < this.spies_.length; i++) {
- var spy = this.spies_[i];
- spy.baseObj[spy.methodName] = spy.originalValue;
- }
- this.spies_ = [];
-};
-
-/**
- * Internal representation of a Jasmine suite.
- *
- * @constructor
- * @param {jasmine.Env} env
- * @param {String} description
- * @param {Function} specDefinitions
- * @param {jasmine.Suite} parentSuite
- */
-jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
+ var fn = fns[index];
var self = this;
- self.id = env.nextSuiteId ? env.nextSuiteId() : null;
- self.description = description;
- self.queue = new jasmine.Queue(env);
- self.parentSuite = parentSuite;
- self.env = env;
- self.before_ = [];
- self.after_ = [];
- self.children_ = [];
- self.suites_ = [];
- self.specs_ = [];
+ if (fn.length > 0) {
+ attempt(function() { fn.call(self, function() { self.run(fns, index + 1) }) });
+ } else {
+ attempt(function() { fn.call(self); });
+ self.run(fns, index + 1);
+ }
+
+ function attempt(fn) {
+ try {
+ fn();
+ } catch (e) {
+ self.onException(e);
+ if (!self.catchingExceptions()) {
+ //TODO: set a var when we catch an exception and
+ //use a finally block to close the loop in a nice way..
+ throw e;
+ }
+ }
+ }
+};
+jasmine.Spec = function(attrs) {
+ this.encounteredExpectations = false;
+ this.expectationFactory = attrs.expectationFactory;
+ this.resultCallback = attrs.resultCallback || function() {};
+ this.id = attrs.id;
+ this.description = attrs.description || '';
+ this.fn = attrs.fn;
+ this.beforeFns = attrs.beforeFns || function() {};
+ this.afterFns = attrs.afterFns || function() {};
+ this.catchingExceptions = attrs.catchingExceptions;
+ this.onStart = attrs.onStart || function() {};
+ this.exceptionFormatter = attrs.exceptionFormatter || function() {};
+ this.getSpecName = attrs.getSpecName || function() { return ''; };
+ this.expectationResultFactory = attrs.expectationResultFactory || function() {};
+ this.queueRunner = attrs.queueRunner || { execute: function() {}};
+ this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
+
+ this.result = {
+ id: this.id,
+ description: this.description,
+ fullName: this.getFullName(),
+ status: this.status(),
+ failedExpectations: []
+ };
+};
+
+jasmine.Spec.prototype.addExpectationResult = function(passed, data) {
+ this.encounteredExpectations = true;
+ if (!passed) {
+ this.result.failedExpectations.push(data);
+ }
+};
+
+jasmine.Spec.prototype.expect = function(actual) {
+ return this.expectationFactory(actual, this);
+};
+
+jasmine.Spec.prototype.execute = function(onComplete) {
+ var self = this;
+
+ if (this.disabled) {
+ complete();
+ return;
+ }
+
+ var befores = this.beforeFns() || [],
+ afters = this.afterFns() || [];
+ var allFns = befores.concat(this.fn).concat(afters);
+
+ this.onStart(this);
+ this.queueRunner({
+ fns: allFns,
+ onException: function(e) {
+ self.addExpectationResult(false, self.expectationResultFactory({
+ matcherName: "",
+ passed: false,
+ expected: "",
+ actual: "",
+ message: self.exceptionFormatter(e),
+ trace: e
+ }));
+ },
+ onComplete: complete
+ });
+
+ function complete() {
+ self.result.status = self.status();
+ self.resultCallback(self.result);
+
+ if (onComplete) {
+ onComplete();
+ }
+ }
+};
+
+jasmine.Spec.prototype.disable = function() {
+ this.disabled = true;
+};
+
+jasmine.Spec.prototype.status = function() {
+ if (this.disabled) {
+ return 'disabled';
+ }
+
+ if (!this.encounteredExpectations) {
+ return null;
+ }
+
+ if (this.result.failedExpectations.length > 0) {
+ return 'failed';
+ } else {
+ return 'passed';
+ }
+};
+
+jasmine.Spec.prototype.getFullName = function() {
+ return this.getSpecName(this);
+}
+jasmine.Suite = function(attrs) {
+ this.env = attrs.env;
+ this.id = attrs.id;
+ this.parentSuite = attrs.parentSuite;
+ this.description = attrs.description;
+ this.onStart = attrs.onStart || function() {};
+ this.completeCallback = attrs.completeCallback || function() {};
+ this.resultCallback = attrs.resultCallback || function() {};
+ this.encourageGC = attrs.encourageGC || function(fn) {fn();};
+
+ this.beforeFns = [];
+ this.afterFns = [];
+ this.queueRunner = attrs.queueRunner || function() {};
+ this.disabled = false;
+
+ this.children_ = []; // TODO: rename
+ this.suites = []; // TODO: needed?
+ this.specs = []; // TODO: needed?
+
+ this.result = {
+ id: this.id,
+ status: this.disabled ? 'disabled' : '',
+ description: this.description,
+ fullName: this.getFullName()
+ };
};
jasmine.Suite.prototype.getFullName = function() {
var fullName = this.description;
for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
- fullName = parentSuite.description + ' ' + fullName;
+ if (parentSuite.parentSuite) {
+ fullName = parentSuite.description + ' ' + fullName;
+ }
}
return fullName;
};
-jasmine.Suite.prototype.finish = function(onComplete) {
- this.env.reporter.reportSuiteResults(this);
- this.finished = true;
- if (typeof(onComplete) == 'function') {
- onComplete();
- }
+jasmine.Suite.prototype.disable = function() {
+ this.disabled = true;
};
-jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
- beforeEachFunction.typeName = 'beforeEach';
- this.before_.unshift(beforeEachFunction);
+jasmine.Suite.prototype.beforeEach = function(fn) {
+ this.beforeFns.unshift(fn);
};
-jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
- afterEachFunction.typeName = 'afterEach';
- this.after_.unshift(afterEachFunction);
+jasmine.Suite.prototype.afterEach = function(fn) {
+ this.afterFns.unshift(fn);
};
-jasmine.Suite.prototype.results = function() {
- return this.queue.results();
+jasmine.Suite.prototype.addSpec = function(spec) {
+ this.children_.push(spec);
+ this.specs.push(spec); // TODO: needed?
};
-jasmine.Suite.prototype.add = function(suiteOrSpec) {
- this.children_.push(suiteOrSpec);
- if (suiteOrSpec instanceof jasmine.Suite) {
- this.suites_.push(suiteOrSpec);
- this.env.currentRunner().addSuite(suiteOrSpec);
- } else {
- this.specs_.push(suiteOrSpec);
- }
- this.queue.add(suiteOrSpec);
-};
-
-jasmine.Suite.prototype.specs = function() {
- return this.specs_;
-};
-
-jasmine.Suite.prototype.suites = function() {
- return this.suites_;
+jasmine.Suite.prototype.addSuite = function(suite) {
+ suite.parentSuite = this;
+ this.children_.push(suite);
+ this.suites.push(suite); // TODO: needed?
};
jasmine.Suite.prototype.children = function() {
@@ -2518,80 +1724,264 @@ jasmine.Suite.prototype.children = function() {
jasmine.Suite.prototype.execute = function(onComplete) {
var self = this;
- this.queue.start(function () {
- self.finish(onComplete);
- });
-};
-jasmine.WaitsBlock = function(env, timeout, spec) {
- this.timeout = timeout;
- jasmine.Block.call(this, env, null, spec);
-};
-
-jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
-
-jasmine.WaitsBlock.prototype.execute = function (onComplete) {
- if (jasmine.VERBOSE) {
- this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
- }
- this.env.setTimeout(function () {
- onComplete();
- }, this.timeout);
-};
-/**
- * A block which waits for some condition to become true, with timeout.
- *
- * @constructor
- * @extends jasmine.Block
- * @param {jasmine.Env} env The Jasmine environment.
- * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
- * @param {Function} latchFunction A function which returns true when the desired condition has been met.
- * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
- * @param {jasmine.Spec} spec The Jasmine spec.
- */
-jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
- this.timeout = timeout || env.defaultTimeoutInterval;
- this.latchFunction = latchFunction;
- this.message = message;
- this.totalTimeSpentWaitingForLatch = 0;
- jasmine.Block.call(this, env, null, spec);
-};
-jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
-
-jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
-
-jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
- if (jasmine.VERBOSE) {
- this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
- }
- var latchFunctionResult;
- try {
- latchFunctionResult = this.latchFunction.apply(this.spec);
- } catch (e) {
- this.spec.fail(e);
- onComplete();
+ if (this.disabled) {
+ complete();
return;
}
- if (latchFunctionResult) {
- onComplete();
- } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
- var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
- this.spec.fail({
- name: 'timeout',
- message: message
- });
+ var allFns = [],
+ children = this.children_;
- this.abort = true;
- onComplete();
- } else {
- this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
- var self = this;
- this.env.setTimeout(function() {
- self.execute(onComplete);
- }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
+ for (var i = 0; i < children.length; i++) {
+ allFns.push(wrapChild(children[i]));
+
+ function wrapChild(child) {
+ return function(done) {
+ child.execute(done);
+ }
+ }
+ }
+
+ this.onStart(this);
+
+ this.queueRunner({
+ fns: allFns,
+ onComplete: complete
+ });
+
+ function complete() {
+ self.resultCallback(self.result);
+
+ if (onComplete) {
+ onComplete();
+ }
}
};
+jasmine.Clock = function(global, delayedFunctionScheduler) {
+ var self = this,
+ realTimingFunctions = {
+ setTimeout: global.setTimeout,
+ clearTimeout: global.clearTimeout,
+ setInterval: global.setInterval,
+ clearInterval: global.clearInterval
+ },
+ fakeTimingFunctions = {
+ setTimeout: setTimeout,
+ clearTimeout: clearTimeout,
+ setInterval: setInterval,
+ clearInterval: clearInterval
+ },
+ timer = realTimingFunctions,
+ installed = false;
+ self.install = function() {
+ installed = true;
+ timer = fakeTimingFunctions;
+ };
+
+ self.uninstall = function() {
+ delayedFunctionScheduler.reset();
+ installed = false;
+ timer = realTimingFunctions;
+ };
+
+ self.setTimeout = function(fn, delay, params) {
+ if (legacyIE()) {
+ if (arguments.length > 2) {
+ throw new Error("IE < 9 cannot support extra params to setTimeout without a polyfill");
+ }
+ return timer.setTimeout(fn, delay);
+ }
+ return timer.setTimeout.apply(null, arguments);
+ };
+
+ self.setInterval = function(fn, delay, params) {
+ if (legacyIE()) {
+ if (arguments.length > 2) {
+ throw new Error("IE < 9 cannot support extra params to setInterval without a polyfill");
+ }
+ return timer.setInterval(fn, delay);
+ }
+ return timer.setInterval.apply(null, arguments);
+ };
+
+ self.clearTimeout = function(id) {
+ return timer.clearTimeout(id);
+ };
+
+ self.clearInterval = function(id) {
+ return timer.clearInterval(id);
+ };
+
+ self.tick = function(millis) {
+ if (installed) {
+ delayedFunctionScheduler.tick(millis)
+ } else {
+ throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
+ }
+ };
+
+ return self;
+
+ function legacyIE() {
+ //if these methods are polyfilled, apply will be present
+ //TODO: it may be difficult to load the polyfill before jasmine loads
+ //(env should be new-ed inside of onload)
+ return !(global.setTimeout || global.setInterval).apply;
+ }
+
+ function setTimeout(fn, delay) {
+ return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
+ }
+
+ function clearTimeout(id) {
+ return delayedFunctionScheduler.removeFunctionWithId(id);
+ }
+
+ function setInterval(fn, interval) {
+ return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
+ }
+
+ function clearInterval(id) {
+ return delayedFunctionScheduler.removeFunctionWithId(id);
+ }
+
+ function argSlice(argsObj, n) {
+ return Array.prototype.slice.call(argsObj, 2);
+ }
+};
+jasmine.DelayedFunctionScheduler = function() {
+ var self = this;
+ var scheduledFunctions = {};
+ var currentTime = 0;
+ var delayedFnCount = 0;
+
+ self.tick = function(millis) {
+ runFunctionsWithinRange(currentTime, currentTime + millis);
+ currentTime = currentTime + millis;
+ };
+
+ self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
+ timeoutKey = timeoutKey || ++delayedFnCount;
+ runAtMillis = runAtMillis || (currentTime + millis);
+ scheduledFunctions[timeoutKey] = {
+ runAtMillis: runAtMillis,
+ funcToCall: funcToCall,
+ recurring: recurring,
+ params: params,
+ timeoutKey: timeoutKey,
+ millis: millis
+ };
+ return timeoutKey;
+ };
+
+ self.removeFunctionWithId = function(timeoutKey) {
+ delete scheduledFunctions[timeoutKey];
+ };
+
+ self.reset = function() {
+ currentTime = 0;
+ scheduledFunctions = {};
+ delayedFnCount = 0;
+ };
+
+ return self;
+
+
+ //finds/dupes functions within range and removes them.
+ function functionsWithinRange(startMillis, endMillis) {
+ var fnsToRun = [];
+ for (var timeoutKey in scheduledFunctions) {
+ var scheduledFunc = scheduledFunctions[timeoutKey];
+ if (scheduledFunc &&
+ scheduledFunc.runAtMillis >= startMillis &&
+ scheduledFunc.runAtMillis <= endMillis) {
+ //remove fn -- we'll reschedule later if it is recurring.
+ self.removeFunctionWithId(timeoutKey);
+ if (!scheduledFunc.recurring) {
+ fnsToRun.push(scheduledFunc); // schedules each function only once
+ } else {
+ fnsToRun.push(buildNthInstanceOf(scheduledFunc, 0));
+ var additionalTimesFnRunsInRange =
+ Math.floor((endMillis - scheduledFunc.runAtMillis) / scheduledFunc.millis);
+ for (var i = 0; i < additionalTimesFnRunsInRange; i++) {
+ fnsToRun.push(buildNthInstanceOf(scheduledFunc, i + 1));
+ }
+ reschedule(buildNthInstanceOf(scheduledFunc, additionalTimesFnRunsInRange));
+ }
+ }
+ }
+
+ return fnsToRun;
+ }
+
+ function buildNthInstanceOf(scheduledFunc, n) {
+ return {
+ runAtMillis: scheduledFunc.runAtMillis + (scheduledFunc.millis * n),
+ funcToCall: scheduledFunc.funcToCall,
+ params: scheduledFunc.params,
+ millis: scheduledFunc.millis,
+ recurring: scheduledFunc.recurring,
+ timeoutKey: scheduledFunc.timeoutKey
+ };
+ }
+
+ function reschedule(scheduledFn) {
+ self.scheduleFunction(scheduledFn.funcToCall,
+ scheduledFn.millis,
+ scheduledFn.params,
+ true,
+ scheduledFn.timeoutKey,
+ scheduledFn.runAtMillis + scheduledFn.millis);
+ }
+
+
+ function runFunctionsWithinRange(startMillis, endMillis) {
+ var funcsToRun = functionsWithinRange(startMillis, endMillis);
+ if (funcsToRun.length === 0) {
+ return;
+ }
+
+ funcsToRun.sort(function(a, b) {
+ return a.runAtMillis - b.runAtMillis;
+ });
+
+ for (var i = 0; i < funcsToRun.length; ++i) {
+ var funcToRun = funcsToRun[i];
+ funcToRun.funcToCall.apply(null, funcToRun.params);
+ }
+ }
+};
+jasmine.ReportDispatcher = function(methods) {
+
+ var dispatchedMethods = methods || [];
+
+ for (var i = 0; i < dispatchedMethods.length; i++) {
+ var method = dispatchedMethods[i];
+ this[method] = function(m) {
+ return function() {
+ dispatch(m, arguments);
+ };
+ }(method);
+ }
+
+ var reporters = [];
+
+ this.addReporter = function(reporter) {
+ reporters.push(reporter);
+ };
+
+ return this;
+
+ function dispatch(method, args) {
+ for (var i = 0; i < reporters.length; i++) {
+ var reporter = reporters[i];
+ if (reporter[method]) {
+ reporter[method].apply(reporter, args);
+ }
+ }
+ }
+};
jasmine.version_= {
"major": 1,
"minor": 3,
diff --git a/pages b/pages
deleted file mode 160000
index dae7b20e..00000000
--- a/pages
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit dae7b20e1c018830aead62fec77da88d1affe91f
diff --git a/spec/console/ConsoleReporterSpec.js b/spec/console/ConsoleReporterSpec.js
index 3dddc413..07ca1427 100644
--- a/spec/console/ConsoleReporterSpec.js
+++ b/spec/console/ConsoleReporterSpec.js
@@ -1,451 +1,207 @@
describe("ConsoleReporter", function() {
- //keep these literal. otherwise the test loses value as a test.
- function green(str) {
- return '\033[32m' + str + '\033[0m';
- }
-
- function red(str) {
- return '\033[31m' + str + '\033[0m';
- }
-
- function yellow(str) {
- return '\033[33m' + str + '\033[0m';
- }
-
- function prefixGreen(str) {
- return '\033[32m' + str;
- }
-
- function prefixRed(str) {
- return '\033[31m' + str;
- }
-
- var newline = "\n";
-
- var passingSpec = {
- results: function() {
- return {
- passed: function() {
- return true;
- }
- };
- }
- },
- failingSpec = {
- results: function() {
- return {
- passed: function() {
- return false;
- }
- };
- }
- },
- skippedSpec = {
- results: function() {
- return {skipped: true};
- }
- },
- passingRun = {
- specs: function() {
- return [null, null, null];
- },
- results: function() {
- return {failedCount: 0, items_: [null, null, null]};
- }
- },
- failingRun = {
- specs: function() {
- return [null, null, null];
- },
- results: function() {
- return {
- failedCount: 7, items_: [null, null, null]};
- }
- };
-
- function repeatedlyInvoke(f, times) {
- for (var i = 0; i < times; i++) f(times + 1);
- }
-
- function repeat(thing, times) {
- var arr = [];
- for (var i = 0; i < times; i++) arr.push(thing);
- return arr;
- }
-
- function simulateRun(reporter, specResults, suiteResults, finalRunner, startTime, endTime) {
- reporter.reportRunnerStarting();
- for (var i = 0; i < specResults.length; i++) {
- reporter.reportSpecResults(specResults[i]);
- }
- for (i = 0; i < suiteResults.length; i++) {
- reporter.reportSuiteResults(suiteResults[i]);
- }
- reporter.runnerStartTime = startTime;
- reporter.now = function() {
- return endTime;
- };
- reporter.reportRunnerResults(finalRunner);
- }
-
- var reporter, out, done;
+ var out;
beforeEach(function() {
out = (function() {
var output = "";
return {
- print:function(str) {
+ print: function(str) {
output += str;
},
- getOutput:function() {
+ getOutput: function() {
return output;
},
clear: function() {
output = "";
}
};
- })();
-
- done = false;
- reporter = new jasmine.ConsoleReporter(out.print, function(runner) {
- done = true
- });
+ }());
});
-
- describe('Integration', function() {
- it("prints the proper output under a pass scenario - small numbers.", function() {
- simulateRun(reporter,
- repeat(passingSpec, 3),
- [],
- {
- specs: function() {
- return [null, null, null];
- },
- results:function() {
- return {
- items_: [null, null, null],
- totalCount: 7,
- failedCount: 0
- };
- }
- },
- 1000,
- 1777
- );
-
- var output = out.getOutput();
- expect(output).toMatch(/^Started/);
- expect(output).toMatch(/\.\.\./);
- expect(output).toMatch(/3 specs, 0 failures/);
+ it("reports that the suite has started to the console", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print
});
- it("prints the proper output under a pass scenario. large numbers.", function() {
- simulateRun(reporter,
- repeat(passingSpec, 57),
- [],
- {
- specs: function() {
- return [null, null, null];
- },
- results:function() {
- return {
- items_: [null, null, null],
- totalCount: 7,
- failedCount: 0
- };
- }
- },
- 1000,
- 1777);
+ reporter.jasmineStarted();
- var output = out.getOutput();
- expect(output).toMatch(/^Started/);
- expect(output).toMatch(/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./);
- expect(output).toMatch(/3 specs, 0 failures/);
- });
-
- it("prints the proper output under a failure scenario.", function() {
- simulateRun(reporter,
- [failingSpec, passingSpec, failingSpec],
- [
- {description:"The oven",
- results:function() {
- return {
- items_:[
- {failedCount:2,
- description:"heats up",
- items_:[
- {trace:{stack:"stack trace one\n second line"}},
- {trace:{stack:"stack trace two"}}
- ]}
- ]
- };
- }},
- {description:"The washing machine",
- results:function() {
- return {
- items_:[
- {failedCount:2,
- description:"washes clothes",
- items_:[
- {trace:{stack:"stack trace one"}}
- ]}
- ]
- };
- }}
- ],
- {
- specs: function() {
- return [null, null, null];
- },
- results:function() {
- return {
- items_: [null, null, null],
- totalCount: 7,
- failedCount: 2
- };
- }
- },
- 1000,
- 1777);
-
- var output = out.getOutput();
- expect(output).toMatch(/^Started/);
- expect(output).toMatch(/F\.F/);
- expect(output).toMatch(/The oven heats up\n stack trace one\n second line\n stack trace two/);
- expect(output).toMatch(/The washing machine washes clothes\n stack trace one/);
- expect(output).toMatch(/3 specs, 2 failures/);
- });
+ expect(out.getOutput()).toEqual("Started\n");
});
- describe('When a Jasmine environment executes', function() {
- beforeEach(function() {
- reporter.reportRunnerStarting();
+ it("reports a passing spec as a dot", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print
});
- it("should print 'Started' to the console", function() {
- expect(out.getOutput()).toEqual("Started" + newline);
+ reporter.specDone({status: "passed"});
+
+ expect(out.getOutput()).toEqual(".");
+ });
+
+ it("does not report a disabled spec", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print
});
- describe('when a spec reports', function() {
- beforeEach(function() {
- out.clear();
- });
+ reporter.specDone({status: "disabled"});
- it("prints a green dot if the spec passes", function() {
- reporter.reportSpecResults(passingSpec);
+ expect(out.getOutput()).toEqual("");
+ });
- expect(out.getOutput()).toMatch(/\./);
- });
-
- it("prints a red dot if the spec fails", function() {
- reporter.reportSpecResults(failingSpec);
-
- expect(out.getOutput()).toMatch(/F/);
- });
-
- it("prints a yellow star if the spec was skipped", function() {
- reporter.reportSpecResults(skippedSpec);
-
- expect(out.getOutput()).toMatch(/\*/);
- });
+ it("reports a failing spec as an 'F'", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print
});
- describe('when a suite reports', function() {
- var emptyResults;
- beforeEach(function() {
- emptyResults = function() {
- return {
- items_:[]
- };
- };
+ reporter.specDone({status: "failed"});
+
+ expect(out.getOutput()).toEqual("F");
+ });
+
+ it("reports a summary when done (singluar spec and time)", function() {
+ var fakeNow = jasmine.createSpy('fake Date.now'),
+ reporter = new jasmine.ConsoleReporter({
+ print: out.print,
+ now: fakeNow
});
- it("remembers suite results", function() {
- reporter.reportSuiteResults({description: "Oven", results: emptyResults});
- reporter.reportSuiteResults({description: "Mixer", results: emptyResults});
+ fakeNow.andReturn(500);
- expect(reporter.suiteResults[0].description).toEqual('Oven');
- expect(reporter.suiteResults[1].description).toEqual('Mixer');
+ reporter.jasmineStarted();
+ reporter.specDone({status: "passed"});
+ fakeNow.andReturn(1500);
+
+ out.clear();
+ reporter.jasmineDone();
+
+ expect(out.getOutput()).toMatch(/1 spec, 0 failures/);
+ expect(out.getOutput()).toMatch("Finished in 1 second\n");
+ });
+
+ it("reports a summary when done (pluralized specs and seconds)", function() {
+ var fakeNow = jasmine.createSpy('fake Date.now'),
+ reporter = new jasmine.ConsoleReporter({
+ print: out.print,
+ now: fakeNow
});
- it("creates a description out of the current suite and any parent suites", function() {
- var grandparentSuite = {
- description: "My house",
- results: emptyResults
- };
- var parentSuite = {
- description: "kitchen",
- parentSuite: grandparentSuite,
- results: emptyResults
- };
- reporter.reportSuiteResults({ description: "oven", parentSuite: parentSuite, results: emptyResults });
-
- expect(reporter.suiteResults[0].description).toEqual("My house kitchen oven");
- });
-
- it("gathers failing spec results from the suite - the spec must have a description.", function() {
- reporter.reportSuiteResults({description:"Oven",
- results: function() {
- return {
- items_:[
- { failedCount: 0, description: "specOne" },
- { failedCount: 99, description: "specTwo" },
- { failedCount: 0, description: "specThree" },
- { failedCount: 88, description: "specFour" },
- { failedCount: 3 }
- ]
- };
- }});
-
- expect(reporter.suiteResults[0].failedSpecResults).
- toEqual([
- { failedCount: 99, description: "specTwo" },
- { failedCount: 88, description: "specFour" }
- ]);
- });
-
- });
-
- describe('and finishes', function() {
-
- describe('when reporting spec failure information', function() {
-
- it("prints suite and spec descriptions together as a sentence", function() {
- reporter.suiteResults = [
- {description:"The oven", failedSpecResults:[
- {description:"heats up", items_:[]},
- {description:"cleans itself", items_:[]}
- ]},
- {description:"The mixer", failedSpecResults:[
- {description:"blends things together", items_:[]}
- ]}
- ];
-
- reporter.reportRunnerResults(failingRun);
-
- expect(out.getOutput()).toContain("The oven heats up");
- expect(out.getOutput()).toContain("The oven cleans itself");
- expect(out.getOutput()).toContain("The mixer blends things together");
- });
-
- it("prints stack trace of spec failure", function() {
- reporter.suiteResults = [
- {description:"The oven", failedSpecResults:[
- {description:"heats up",
- items_:[
- {trace:{stack:"stack trace one"}},
- {trace:{stack:"stack trace two"}}
- ]}
- ]}
- ];
-
- reporter.reportRunnerResults(failingRun);
-
- expect(out.getOutput()).toContain("The oven heats up");
- expect(out.getOutput()).toContain("stack trace one");
- expect(out.getOutput()).toContain("stack trace two");
- });
-
- });
-
- describe('when reporting the execution time', function() {
-
- it("prints the full finished message", function() {
- reporter.now = function() {
- return 1000;
- };
- reporter.reportRunnerStarting();
- reporter.now = function() {
- return 1777;
- };
- reporter.reportRunnerResults(failingRun);
- expect(out.getOutput()).toContain("Finished in 0.777 seconds");
- });
-
- it("prints round time numbers correctly", function() {
- function run(startTime, endTime) {
- out.clear();
- reporter.runnerStartTime = startTime;
- reporter.now = function() {
- return endTime;
- };
- reporter.reportRunnerResults(passingRun);
+ fakeNow.andReturn(500);
+ reporter.jasmineStarted();
+ reporter.specDone({status: "passed"});
+ reporter.specDone({
+ status: "failed",
+ description: "with a failing spec",
+ fullName: "A suite with a failing spec",
+ failedExpectations: [
+ {
+ passed: false,
+ message: "Expected true to be false.",
+ expected: false,
+ actual: true,
+ trace: {
+ stack: "foo\nbar\nbaz"
}
+ }
+ ]
+ });
- run(1000, 11000);
- expect(out.getOutput()).toContain("10 seconds");
+ out.clear();
- run(1000, 2000);
- expect(out.getOutput()).toContain("1 seconds");
+ fakeNow.andReturn(600);
+ reporter.jasmineDone();
- run(1000, 1100);
- expect(out.getOutput()).toContain("0.1 seconds");
+ expect(out.getOutput()).toMatch(/2 specs, 1 failure/);
+ expect(out.getOutput()).toMatch("Finished in 0.1 seconds\n");
+ });
- run(1000, 1010);
- expect(out.getOutput()).toContain("0.01 seconds");
+ it("reports a summary when done that includes stack traces for a failing suite", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print
+ });
- run(1000, 1001);
- expect(out.getOutput()).toContain("0.001 seconds");
- });
+ reporter.jasmineStarted();
+ reporter.specDone({status: "passed"});
+ reporter.specDone({
+ status: "failed",
+ description: "with a failing spec",
+ fullName: "A suite with a failing spec",
+ failedExpectations: [
+ {
+ passed: false,
+ message: "Expected true to be false.",
+ expected: false,
+ actual: true,
+ trace: {
+ stack: "foo bar baz"
+ }
+ }
+ ]
+ });
+
+ out.clear();
+
+ reporter.jasmineDone();
+
+ expect(out.getOutput()).toMatch(/foo bar baz/);
+ });
+
+ it("calls the onComplete callback when the suite is done", function() {
+ var onComplete = jasmine.createSpy('onComplete'),
+ reporter = new jasmine.ConsoleReporter({
+ print: out.print,
+ onComplete: onComplete
});
- describe("when reporting the results summary", function() {
- it("prints statistics in green if there were no failures", function() {
- reporter.reportRunnerResults({
- specs: function() {
- return [null, null, null];
- },
- results:function() {
- return {items_: [null, null, null], totalCount: 7, failedCount: 0};
- }
- });
- expect(out.getOutput()).
- toContain("3 specs, 0 failures");
- });
+ reporter.jasmineDone();
- it("prints statistics in red if there was a failure", function() {
- reporter.reportRunnerResults({
- specs: function() {
- return [null, null, null];
- },
- results:function() {
- return {items_: [null, null, null], totalCount: 7, failedCount: 3};
- }
- });
- expect(out.getOutput()).
- toContain("3 specs, 3 failures");
- });
+ expect(onComplete).toHaveBeenCalled();
+ });
- it("handles pluralization with 1's ones appropriately", function() {
- reporter.reportRunnerResults({
- specs: function() {
- return [null];
- },
- results:function() {
- return {items_: [null], totalCount: 1, failedCount: 1};
- }
- });
- expect(out.getOutput()).
- toContain("1 spec, 1 failure");
- });
+
+ describe("with color", function() {
+
+ it("reports that the suite has started to the console", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print,
+ showColors: true
});
- describe("done callback", function() {
- it("calls back when done", function() {
- expect(done).toBeFalsy();
- reporter.reportRunnerResults({
- specs: function() {
- return [null, null, null];
- },
- results:function() {
- return {items_: [null, null, null], totalCount: 7, failedCount: 0};
- }
- });
- expect(done).toBeTruthy();
- });
+ reporter.jasmineStarted();
+
+ expect(out.getOutput()).toEqual("Started\n");
+ });
+
+ it("reports a passing spec as a dot", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print,
+ showColors: true
});
+
+ reporter.specDone({status: "passed"});
+
+ expect(out.getOutput()).toEqual("\033[32m.\033[0m");
+ });
+
+ it("does not report a disabled spec", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print,
+ showColors: true
+ });
+
+ reporter.specDone({status: 'disabled'});
+
+ expect(out.getOutput()).toEqual("");
+ });
+
+ it("reports a failing spec as an 'F'", function() {
+ var reporter = new jasmine.ConsoleReporter({
+ print: out.print,
+ showColors: true
+ });
+
+ reporter.specDone({status: 'failed'});
+
+ expect(out.getOutput()).toEqual("\033[31mF\033[0m");
});
});
-});
\ No newline at end of file
+});
diff --git a/spec/core/BaseSpec.js b/spec/core/BaseSpec.js
deleted file mode 100644
index 121a8815..00000000
--- a/spec/core/BaseSpec.js
+++ /dev/null
@@ -1,27 +0,0 @@
-describe("base.js", function() {
- describe("jasmine.MessageResult", function() {
- it("#toString should pretty-print and concatenate each part of the message", function() {
- var values = ["log", "message", 123, {key: "value"}, "FTW!"];
- var messageResult = new jasmine.MessageResult(values);
- expect(messageResult.toString()).toEqual("log message 123 { key : 'value' } FTW!");
- });
- });
-
- describe("jasmine.log", function() {
- it("should accept n arguments", function() {
- spyOn(jasmine.getEnv().currentSpec, 'log');
- jasmine.log(1, 2, 3);
- expect(jasmine.getEnv().currentSpec.log).toHaveBeenCalledWith(1, 2, 3);
- });
- });
-
- describe("jasmine.getGlobal", function() {
- it("should return the global object", function() {
- var globalObject = (function() {
- return this;
- })();
-
- expect(jasmine.getGlobal()).toBe(globalObject);
- });
- });
-});
diff --git a/spec/core/ClockSpec.js b/spec/core/ClockSpec.js
new file mode 100644
index 00000000..84cbf0a3
--- /dev/null
+++ b/spec/core/ClockSpec.js
@@ -0,0 +1,294 @@
+describe("Clock", function() {
+
+ it("calls the global setTimeout directly if Clock is not installed", function() {
+ var setTimeout = jasmine.createSpy('setTimeout'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
+ global = { setTimeout: setTimeout },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.setTimeout(delayedFn, 0);
+
+ expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
+ expect(setTimeout).toHaveBeenCalledWith(delayedFn, 0);
+ });
+
+ it("schedules the delayed function with the fake timer", function() {
+ var setTimeout = jasmine.createSpy('setTimeout'),
+ scheduleFunction = jasmine.createSpy('scheduleFunction'),
+ delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
+ global = { setTimeout: setTimeout },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.install();
+ clock.setTimeout(delayedFn, 0, 'a', 'b');
+
+ expect(setTimeout).not.toHaveBeenCalled();
+ expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
+ });
+
+ it("returns an id for the delayed function", function() {
+ var setTimeout = jasmine.createSpy('setTimeout'),
+ scheduleId = 123,
+ scheduleFunction = jasmine.createSpy('scheduleFunction').andReturn(scheduleId),
+ delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
+ global = { setTimeout: setTimeout },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler),
+ timeoutId;
+
+ clock.install();
+ timeoutId = clock.setTimeout(delayedFn, 0);
+
+ expect(timeoutId).toEqual(123);
+ });
+
+ it("calls the global clearTimeout directly if Clock is not installed", function() {
+ var clearTimeout = jasmine.createSpy('clearTimeout'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
+ global = { clearTimeout: clearTimeout },
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.clearTimeout(123);
+
+ expect(clearTimeout).toHaveBeenCalledWith(123);
+ });
+
+ it("clears the scheduled function with the scheduler", function() {
+ var clearTimeout = jasmine.createSpy('clearTimeout'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
+ global = { setTimeout: clearTimeout },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.install();
+ clock.clearTimeout(123);
+
+ expect(clearTimeout).not.toHaveBeenCalled();
+ expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
+ });
+
+ it("calls the global setInterval directly if Clock is not installed", function() {
+ var setInterval = jasmine.createSpy('setInterval'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
+ global = { setInterval: setInterval },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.setInterval(delayedFn, 0);
+
+ expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
+ expect(setInterval).toHaveBeenCalledWith(delayedFn, 0);
+ });
+
+ it("schedules the delayed function with the fake timer", function() {
+ var setInterval = jasmine.createSpy('setInterval'),
+ scheduleFunction = jasmine.createSpy('scheduleFunction'),
+ delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
+ global = { setInterval: setInterval },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.install();
+ clock.setInterval(delayedFn, 0, 'a', 'b');
+
+ expect(setInterval).not.toHaveBeenCalled();
+ expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
+ });
+
+ it("returns an id for the delayed function", function() {
+ var setInterval = jasmine.createSpy('setInterval'),
+ scheduleId = 123,
+ scheduleFunction = jasmine.createSpy('scheduleFunction').andReturn(scheduleId),
+ delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
+ global = { setInterval: setInterval },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler),
+ intervalId;
+
+ clock.install();
+ intervalId = clock.setInterval(delayedFn, 0);
+
+ expect(intervalId).toEqual(123);
+ });
+
+ it("calls the global clearInterval directly if Clock is not installed", function() {
+ var clearInterval = jasmine.createSpy('clearInterval'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearInterval']),
+ global = { clearInterval: clearInterval },
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.clearInterval(123);
+
+ expect(clearInterval).toHaveBeenCalledWith(123);
+ });
+
+ it("clears the scheduled function with the scheduler", function() {
+ var clearInterval = jasmine.createSpy('clearInterval'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
+ global = { setInterval: clearInterval },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.install();
+ clock.clearInterval(123);
+
+ expect(clearInterval).not.toHaveBeenCalled();
+ expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
+ });
+
+ it("gives you a friendly reminder if the Clock is not installed and you tick", function() {
+ var clock = new jasmine.Clock({}, jasmine.createSpyObj('delayedFunctionScheduler', ['tick']));
+ expect(function() {
+ clock.tick(50);
+ }).toThrow();
+ });
+
+ it("can be uninstalled", function() {
+ var setTimeout = jasmine.createSpy('setTimeout'),
+ setInterval = jasmine.createSpy('setInterval'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction', 'tick', 'reset']),
+ global = { setTimeout: setTimeout, setInterval: setInterval },
+ delayedFn = jasmine.createSpy('delayedFn'),
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ clock.install();
+ clock.setTimeout(delayedFn, 0);
+ expect(setTimeout).not.toHaveBeenCalled();
+
+ clock.setInterval(delayedFn, 0);
+ expect(setInterval).not.toHaveBeenCalled();
+
+ expect(function() {
+ clock.tick(0);
+ }).not.toThrow();
+
+ clock.uninstall();
+
+ expect(delayedFunctionScheduler.reset).toHaveBeenCalled();
+
+ clock.setTimeout(delayedFn, 0);
+
+ expect(setTimeout).toHaveBeenCalled();
+
+ clock.setInterval(delayedFn, 0);
+ expect(setInterval).toHaveBeenCalled();
+
+ expect(function() {
+ clock.tick(0);
+ }).toThrow();
+ });
+
+
+ it("on IE < 9, fails if extra args are passed to fake clock", function() {
+ //fail, because this would break in IE9.
+ var setTimeout = jasmine.createSpy('setTimeout'),
+ setInterval = jasmine.createSpy('setInterval'),
+ delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
+ fn = jasmine.createSpy('fn'),
+ global = { setTimeout: setTimeout, setInterval: setInterval },
+ clock = new jasmine.Clock(global, delayedFunctionScheduler);
+
+ setTimeout.apply = null;
+ setInterval.apply = null;
+
+ clock.install();
+
+ clock.setTimeout(fn, 0);
+ expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, []);
+ expect(function() {
+ clock.setTimeout(fn, 0, 'extra');
+ }).toThrow();
+
+ clock.setInterval(fn, 0);
+ expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], true);
+ expect(function() {
+ clock.setInterval(fn, 0, 'extra');
+ }).toThrow();
+ });
+
+});
+
+describe("Clock (acceptance)", function() {
+ it("can run setTimeouts/setIntervals synchronously", function() {
+ var delayedFn1 = jasmine.createSpy('delayedFn1'),
+ delayedFn2 = jasmine.createSpy('delayedFn2'),
+ delayedFn3 = jasmine.createSpy('delayedFn3'),
+ recurring1 = jasmine.createSpy('recurring1'),
+ delayedFunctionScheduler = new jasmine.DelayedFunctionScheduler(),
+ clock = new jasmine.Clock({setTimeout: setTimeout}, delayedFunctionScheduler);
+
+ clock.install();
+
+ clock.setTimeout(delayedFn1, 0, 'some', 'arg');
+ var intervalId = clock.setInterval(recurring1, 50, 'some', 'other', 'args');
+ clock.setTimeout(delayedFn2, 100);
+ clock.setTimeout(delayedFn3, 200);
+
+ expect(delayedFn1).not.toHaveBeenCalled();
+ expect(delayedFn2).not.toHaveBeenCalled();
+ expect(delayedFn3).not.toHaveBeenCalled();
+
+ clock.tick(0);
+
+ expect(delayedFn1).toHaveBeenCalledWith('some', 'arg');
+ expect(delayedFn2).not.toHaveBeenCalled();
+ expect(delayedFn3).not.toHaveBeenCalled();
+
+ clock.tick(50);
+
+ expect(recurring1).toHaveBeenCalledWith('some', 'other', 'args');
+ expect(recurring1.callCount).toBe(1);
+ expect(delayedFn2).not.toHaveBeenCalled();
+ expect(delayedFn3).not.toHaveBeenCalled();
+
+ clock.tick(50);
+
+ expect(recurring1.callCount).toBe(2);
+ expect(delayedFn2).toHaveBeenCalled();
+ expect(delayedFn3).not.toHaveBeenCalled();
+
+ clock.tick(100);
+
+ expect(recurring1.callCount).toBe(4);
+ expect(delayedFn3).toHaveBeenCalled();
+
+ clock.clearInterval(intervalId);
+ clock.tick(50);
+
+ expect(recurring1.callCount).toBe(4);
+ });
+
+ it("can clear a previously set timeout", function() {
+ var clearedFn = jasmine.createSpy('clearedFn'),
+ delayedFunctionScheduler = new jasmine.DelayedFunctionScheduler(),
+ clock = new jasmine.Clock({setTimeout: function() {}}, delayedFunctionScheduler),
+ timeoutId;
+
+ clock.install();
+
+ timeoutId = clock.setTimeout(clearedFn, 100);
+ expect(clearedFn).not.toHaveBeenCalled();
+
+ clock.clearTimeout(timeoutId);
+ clock.tick(100);
+
+ expect(clearedFn).not.toHaveBeenCalled();
+ });
+
+ it("correctly schedules functions after the Clock has advanced", function() {
+ var delayedFn1 = jasmine.createSpy('delayedFn1'),
+ delayedFunctionScheduler = new jasmine.DelayedFunctionScheduler(),
+ clock = new jasmine.Clock({setTimeout: function(){}}, delayedFunctionScheduler);
+
+ clock.install();
+
+ clock.tick(100);
+ clock.setTimeout(delayedFn1, 10, ['some', 'arg']);
+ clock.tick(5);
+ expect(delayedFn1).not.toHaveBeenCalled();
+ clock.tick(5);
+ expect(delayedFn1).toHaveBeenCalled();
+ });
+});
diff --git a/spec/core/CustomMatchersSpec.js b/spec/core/CustomMatchersSpec.js
index 7a724b57..21214b90 100644
--- a/spec/core/CustomMatchersSpec.js
+++ b/spec/core/CustomMatchersSpec.js
@@ -1,97 +1,96 @@
-describe("Custom Matchers", function() {
- var env;
- var fakeTimer;
-
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
- });
-
- it("should be easy to add more matchers local to a spec, suite, etc.", function() {
- var spec1, spec2, spec1Matcher, spec2Matcher;
- var suite = env.describe('some suite', function() {
- env.beforeEach(function() {
- this.addMatchers({
- matcherForSuite: function(expected) {
- this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
- return true;
- }
- });
- });
-
- spec1 = env.it('spec with an expectation').runs(function () {
- this.addMatchers({
- matcherForSpec: function(expected) {
- this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
- return true;
- }
- });
- spec1Matcher = this.expect("xxx");
- });
-
- spec2 = env.it('spec with failing expectation').runs(function () {
- spec2Matcher = this.expect("yyy");
- });
- });
-
- suite.execute();
-
- spec1Matcher.matcherForSuite("expected");
- expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected");
- spec1Matcher.matcherForSpec("expected");
- expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected");
-
- spec2Matcher.matcherForSuite("expected");
- expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected");
- expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
- });
-
- it("should generate messages with the same rules as for regular matchers when this.report() is not called", function() {
- var spec;
- var suite = env.describe('some suite', function() {
- spec = env.it('spec with an expectation').runs(function () {
- this.addMatchers({
- toBeTrue: function() {
- return this.actual === true;
- }
- });
- this.expect(true).toBeTrue();
- this.expect(false).toBeTrue();
- });
- });
-
- suite.execute();
- var passResult = new jasmine.ExpectationResult({passed: true, matcherName: 'toBeTrue',
- actual: true, expected: jasmine.undefined, message: "Passed." });
- var failResult = new jasmine.ExpectationResult({passed: false, matcherName: 'toBeTrue',
- actual: false, expected: jasmine.undefined, message: "Expected false to be true." });
- failResult.trace = jasmine.any(Object);
- expect(spec.results().getItems()).toEqual([passResult, failResult]);
- });
-
- it("should pass args", function() {
- var matcherCallArgs = [];
- var spec;
- var suite = env.describe('some suite', function() {
- spec = env.it('spec with an expectation').runs(function () {
- this.addMatchers({
- toBeTrue: function() {
- matcherCallArgs.push(jasmine.util.argsToArray(arguments));
- return this.actual === true;
- }
- });
- this.expect(true).toBeTrue();
- this.expect(false).toBeTrue('arg');
- this.expect(true).toBeTrue('arg1', 'arg2');
- });
- });
-
- suite.execute();
- var results = spec.results().getItems();
- expect(results[0].expected).toEqual(jasmine.undefined);
- expect(results[1].expected).toEqual('arg');
- expect(results[2].expected).toEqual(['arg1', 'arg2']);
-
- expect(matcherCallArgs).toEqual([[], ['arg'], ['arg1', 'arg2']]);
- });
-});
\ No newline at end of file
+////TODO: matchers should be add-able to the env, not to the spec.
+//describe("Custom Matchers", function() {
+// var env;
+// var fakeTimer;
+//
+// beforeEach(function() {
+// env = new jasmine.Env();
+// env.updateInterval = 0;
+// });
+//
+// it("should be easy to add more matchers local to a spec, suite, etc.", function() {
+// var spec1, spec2, spec1Matcher, spec2Matcher;
+// var suite = env.describe('some suite', function() {
+// env.beforeEach(function() {
+// this.addMatchers({
+// matcherForSuite: function(expected) {
+// this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
+// return true;
+// }
+// });
+// });
+//
+// spec1 = env.it('spec with an expectation').runs(function () {
+// this.addMatchers({
+// matcherForSpec: function(expected) {
+// this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
+// return true;
+// }
+// });
+// spec1Matcher = this.expect("xxx");
+// });
+//
+// spec2 = env.it('spec with failing expectation').runs(function () {
+// spec2Matcher = this.expect("yyy");
+// });
+// });
+//
+// suite.execute();
+//
+// spec1Matcher.matcherForSuite("expected");
+// expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected");
+// spec1Matcher.matcherForSpec("expected");
+// expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected");
+//
+// spec2Matcher.matcherForSuite("expected");
+// expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected");
+// expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
+// });
+//
+// it("should generate messages with the same rules as for regular matchers when this.report() is not called", function() {
+// var spec;
+// var suite = env.describe('some suite', function() {
+// spec = env.it('spec with an expectation').runs(function () {
+// this.addMatchers({
+// toBeTrue: function() {
+// return this.actual === true;
+// }
+// });
+// this.expect(true).toBeTrue();
+// this.expect(false).toBeTrue();
+// });
+// });
+//
+// suite.execute();
+//
+// var results = spec.results().getItems();
+// expect(results[0].message).toEqual("Passed.");
+// expect(results[1].message).toEqual("Expected false to be true.");
+// });
+//
+// it("should pass args", function() {
+// var matcherCallArgs = [];
+// var spec;
+// var suite = env.describe('some suite', function() {
+// spec = env.it('spec with an expectation').runs(function () {
+// this.addMatchers({
+// toBeTrue: function() {
+// matcherCallArgs.push(jasmine.util.argsToArray(arguments));
+// return this.actual === true;
+// }
+// });
+// this.expect(true).toBeTrue();
+// this.expect(false).toBeTrue('arg');
+// this.expect(true).toBeTrue('arg1', 'arg2');
+// });
+// });
+//
+// suite.execute();
+// var results = spec.results().getItems();
+// expect(results[0].expected).toEqual(jasmine.undefined);
+// expect(results[1].expected).toEqual('arg');
+// expect(results[2].expected).toEqual(['arg1', 'arg2']);
+//
+// expect(matcherCallArgs).toEqual([[], ['arg'], ['arg1', 'arg2']]);
+// });
+//});
diff --git a/spec/core/DelayedFunctionSchedulerSpec.js b/spec/core/DelayedFunctionSchedulerSpec.js
new file mode 100644
index 00000000..0615f493
--- /dev/null
+++ b/spec/core/DelayedFunctionSchedulerSpec.js
@@ -0,0 +1,142 @@
+describe("DelayedFunctionScheduler", function() {
+ it("schedules a function for later execution", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler(),
+ fn = jasmine.createSpy('fn');
+
+ scheduler.scheduleFunction(fn, 0);
+
+ expect(fn).not.toHaveBeenCalled();
+
+ scheduler.tick(0);
+
+ expect(fn).toHaveBeenCalled();
+ });
+
+ it("optionally passes params to scheduled functions", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler(),
+ fn = jasmine.createSpy('fn');
+
+ scheduler.scheduleFunction(fn, 0, ['foo', 'bar']);
+
+ expect(fn).not.toHaveBeenCalled();
+
+ scheduler.tick(0);
+
+ expect(fn).toHaveBeenCalledWith('foo', 'bar');
+ });
+
+ it("scheduled fns can optionally reoccur", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler(),
+ fn = jasmine.createSpy('fn');
+
+ scheduler.scheduleFunction(fn, 20, [], true);
+
+ expect(fn).not.toHaveBeenCalled();
+
+ scheduler.tick(20);
+
+ expect(fn.callCount).toBe(1);
+
+ scheduler.tick(40);
+
+ expect(fn.callCount).toBe(3);
+
+ scheduler.tick(21);
+
+ expect(fn.callCount).toBe(4);
+
+ });
+
+ it("increments scheduled fns ids unless one is passed", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler();
+
+ expect(scheduler.scheduleFunction(function() {
+ }, 0)).toBe(1);
+ expect(scheduler.scheduleFunction(function() {
+ }, 0)).toBe(2);
+ expect(scheduler.scheduleFunction(function() {
+ }, 0, [], false, 123)).toBe(123);
+ expect(scheduler.scheduleFunction(function() {
+ }, 0)).toBe(3);
+ });
+
+ it("#removeFunctionWithId removes a previously scheduled function with a given id", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler(),
+ fn = jasmine.createSpy('fn'),
+ timeoutKey;
+
+ timeoutKey = scheduler.scheduleFunction(fn, 0);
+
+ expect(fn).not.toHaveBeenCalled();
+
+ scheduler.removeFunctionWithId(timeoutKey);
+
+ scheduler.tick(0);
+
+ expect(fn).not.toHaveBeenCalled();
+ });
+
+ it("reset removes scheduled functions", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler(),
+ fn = jasmine.createSpy('fn');
+
+ scheduler.scheduleFunction(fn, 0);
+
+ expect(fn).not.toHaveBeenCalled();
+
+ scheduler.reset();
+
+ scheduler.tick(0);
+
+ expect(fn).not.toHaveBeenCalled();
+ });
+
+ it("reset resets the returned ids", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler();
+ expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
+ expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
+
+ scheduler.reset();
+ expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
+ expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
+ });
+
+ it("reset resets the current tick time", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler(),
+ fn = jasmine.createSpy('fn');
+
+ expect(fn).not.toHaveBeenCalled();
+
+ scheduler.tick(15);
+ scheduler.reset();
+
+ scheduler.scheduleFunction(fn, 20, [], false, 1, 20);
+
+ scheduler.tick(5);
+
+ expect(fn).not.toHaveBeenCalled();
+ });
+
+ it("executes recurring functions interleaved with regular functions in the correct order", function() {
+ var scheduler = new jasmine.DelayedFunctionScheduler(),
+ fn = jasmine.createSpy('fn'),
+ recurringCallCount = 0,
+ recurring = jasmine.createSpy('recurring').andCallFake(function() {
+ recurringCallCount++;
+ if (recurringCallCount < 5) {
+ expect(fn).not.toHaveBeenCalled();
+ }
+ });
+
+ scheduler.scheduleFunction(recurring, 10, [], true);
+ scheduler.scheduleFunction(fn, 50);
+
+ scheduler.tick(60);
+
+ expect(recurring).toHaveBeenCalled();
+ expect(recurring.callCount).toBe(6);
+ expect(fn).toHaveBeenCalled();
+ });
+
+});
+
diff --git a/spec/core/EnvSpec.js b/spec/core/EnvSpec.js
index 3bd67031..b9611489 100644
--- a/spec/core/EnvSpec.js
+++ b/spec/core/EnvSpec.js
@@ -1,12 +1,13 @@
-describe("jasmine.Env", function() {
+// TODO: Fix these unit tests!
+describe("Env", function() {
var env;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
});
- describe('ids', function () {
- it('nextSpecId should return consecutive integers, starting at 0', function () {
+ describe('ids', function() {
+ it('nextSpecId should return consecutive integers, starting at 0', function() {
expect(env.nextSpecId()).toEqual(0);
expect(env.nextSpecId()).toEqual(1);
expect(env.nextSpecId()).toEqual(2);
@@ -17,21 +18,21 @@ describe("jasmine.Env", function() {
var fakeReporter;
beforeEach(function() {
- fakeReporter = jasmine.createSpyObj("fakeReporter", ["log"]);
+ fakeReporter = originalJasmine.createSpyObj("fakeReporter", ["jasmineStarted"]);
});
- describe('version', function () {
+ describe('version', function() {
var oldVersion;
- beforeEach(function () {
+ beforeEach(function() {
oldVersion = jasmine.version_;
});
- afterEach(function () {
+ afterEach(function() {
jasmine.version_ = oldVersion;
});
- it('should raise an error if version is not set', function () {
+ it('should raise an error if version is not set', function() {
jasmine.version_ = null;
var exception;
try {
@@ -79,8 +80,8 @@ describe("jasmine.Env", function() {
it("should allow reporters to be registered", function() {
env.addReporter(fakeReporter);
- env.reporter.log("message");
- expect(fakeReporter.log).toHaveBeenCalledWith("message");
+ env.reporter.jasmineStarted();
+ expect(fakeReporter.jasmineStarted).toHaveBeenCalled();
});
});
@@ -138,8 +139,12 @@ describe("jasmine.Env", function() {
describe("even if there are several", function() {
beforeEach(function() {
- env.addEqualityTester(function(a, b) { return jasmine.undefined; });
- env.addEqualityTester(function(a, b) { return jasmine.undefined; });
+ env.addEqualityTester(function(a, b) {
+ return jasmine.undefined;
+ });
+ env.addEqualityTester(function(a, b) {
+ return jasmine.undefined;
+ });
});
it("should use normal equality rules", function() {
@@ -151,9 +156,182 @@ describe("jasmine.Env", function() {
it("should evaluate custom equality testers in the order they are declared", function() {
isEqual = false;
- env.addEqualityTester(function(a, b) { return true; });
+ env.addEqualityTester(function(a, b) {
+ return true;
+ });
expect(env.equals_('abc', 'abc')).toBeFalsy();
});
});
});
});
+
+describe("Env (integration)", function() {
+
+ it("Suites execute as expected (no nesting)", function() {
+ var env = new jasmine.Env(),
+ calls = [];
+
+ env.describe("A Suite", function() {
+ env.it("with a spec", function() {
+ calls.push("with a spec");
+ });
+ env.it("and another spec", function() {
+ calls.push("and another spec");
+ });
+ });
+
+ env.execute();
+
+ expect(calls).toEqual([
+ "with a spec",
+ "and another spec"
+ ]);
+ });
+
+ it("Nested Suites execute as expected", function() {
+ var env = new jasmine.Env(),
+ calls = [];
+
+ env.describe("Outer suite", function() {
+ env.it("an outer spec", function() {
+ calls.push('an outer spec')
+ });
+ env.describe("Inner suite", function() {
+ env.it("an inner spec", function() {
+ calls.push('an inner spec');
+ });
+ env.it("another inner spec", function() {
+ calls.push('another inner spec');
+ });
+ });
+ });
+
+ env.execute();
+
+ expect(calls).toEqual([
+ 'an outer spec',
+ 'an inner spec',
+ 'another inner spec'
+ ]);
+
+ });
+
+ it("Multiple top-level Suites execute as expected", function() {
+ var env = new jasmine.Env(),
+ calls = [];
+
+ env.describe("Outer suite", function() {
+ env.it("an outer spec", function() {
+ calls.push('an outer spec')
+ });
+ env.describe("Inner suite", function() {
+ env.it("an inner spec", function() {
+ calls.push('an inner spec');
+ });
+ env.it("another inner spec", function() {
+ calls.push('another inner spec');
+ });
+ });
+ });
+
+ env.describe("Another outer suite", function() {
+ env.it("a 2nd outer spec", function() {
+ calls.push('a 2nd outer spec')
+ });
+ });
+
+ env.execute();
+
+ expect(calls).toEqual([
+ 'an outer spec',
+ 'an inner spec',
+ 'another inner spec',
+ 'a 2nd outer spec'
+ ]);
+ });
+
+ it("Mock clock can be installed and used in tests", function() {
+ var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
+ delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
+ delayedFunctionForMockClock = jasmine.createSpy('delayedFunctionForMockClock'),
+ env = new jasmine.Env({global: { setTimeout: globalSetTimeout }});
+
+ env.describe("tests", function() {
+ env.it("test with mock clock", function() {
+ env.clock.install();
+ env.clock.setTimeout(delayedFunctionForMockClock, 100);
+ env.clock.tick(100);
+ });
+ env.it("test without mock clock", function() {
+ env.clock.setTimeout(delayedFunctionForGlobalClock, 100);
+ });
+ });
+
+ expect(globalSetTimeout).not.toHaveBeenCalled();
+ expect(delayedFunctionForMockClock).not.toHaveBeenCalled();
+
+ env.execute();
+
+ expect(delayedFunctionForMockClock).toHaveBeenCalled();
+ expect(globalSetTimeout).toHaveBeenCalledWith(delayedFunctionForGlobalClock, 100);
+ });
+
+ it("should report as expected", function() {
+ var env = new jasmine.Env(),
+ reporter = jasmine.createSpyObj('fakeReproter', [
+ "jasmineStarted",
+ "jasmineDone",
+ "suiteStarted",
+ "suiteDone",
+ "specStarted",
+ "specDone"
+ ]);
+
+ env.addReporter(reporter);
+
+ env.describe("A Suite", function() {
+ env.it("with a top level spec", function() {
+ env.expect(true).toBe(true);
+ });
+ env.describe("with a nested suite", function() {
+ env.xit("with a disabled spec", function() {
+ env.expect(true).toBe(true);
+ });
+ env.it("with a spec", function() {
+ env.expect(true).toBe(false);
+ });
+ });
+ });
+
+ env.execute();
+
+ expect(reporter.jasmineStarted).toHaveBeenCalledWith({
+ totalSpecsDefined: 3
+ });
+ var suiteResult = reporter.suiteStarted.calls[0].args[0];
+ expect(suiteResult.description).toEqual("A Suite");
+ expect(reporter.jasmineDone).toHaveBeenCalled();
+ });
+
+ it("should be possible to get full name from a spec", function() {
+ var env = new jasmine.Env({global: { setTimeout: setTimeout }}),
+ topLevelSpec, nestedSpec, doublyNestedSpec;
+
+ env.describe("my tests", function() {
+ topLevelSpec = env.it("are sometimes top level", function() {
+ });
+ env.describe("are sometimes", function() {
+ nestedSpec = env.it("singly nested", function() {
+ });
+ env.describe("even", function() {
+ doublyNestedSpec = env.it("doubly nested", function() {
+ });
+ });
+ });
+ });
+
+ expect(topLevelSpec.getFullName()).toBe("my tests are sometimes top level.");
+ expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested.");
+ expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested.");
+ });
+});
diff --git a/spec/core/ExceptionFormatterSpec.js b/spec/core/ExceptionFormatterSpec.js
new file mode 100644
index 00000000..c3052c8c
--- /dev/null
+++ b/spec/core/ExceptionFormatterSpec.js
@@ -0,0 +1,26 @@
+describe("ExceptionFormatter", function() {
+
+ it('formats Firefox exception messages', function() {
+ var sampleFirefoxException = {
+ fileName: 'foo.js',
+ line: '1978',
+ message: 'you got your foo in my bar',
+ name: 'A Classic Mistake'
+ },
+ message = jasmine.exceptionMessageFor(sampleFirefoxException);
+
+ expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
+ });
+
+ it('formats Webkit exception messages', function() {
+ var sampleWebkitException = {
+ sourceURL: 'foo.js',
+ lineNumber: '1978',
+ message: 'you got your foo in my bar',
+ name: 'A Classic Mistake'
+ },
+ message = jasmine.exceptionMessageFor(sampleWebkitException);
+
+ expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
+ });
+});
\ No newline at end of file
diff --git a/spec/core/ExceptionsSpec.js b/spec/core/ExceptionsSpec.js
index 315aa1bf..e06b1275 100644
--- a/spec/core/ExceptionsSpec.js
+++ b/spec/core/ExceptionsSpec.js
@@ -6,34 +6,9 @@ describe('Exceptions:', function() {
env.updateInterval = 0;
});
- it('jasmine.formatException formats Firefox exception messages as expected', function() {
- var sampleFirefoxException = {
- fileName: 'foo.js',
- line: '1978',
- message: 'you got your foo in my bar',
- name: 'A Classic Mistake'
- };
-
- var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
-
- expect(jasmine.util.formatException(sampleFirefoxException)).toEqual(expected);
- });
-
- it('jasmine.formatException formats Webkit exception messages as expected', function() {
- var sampleWebkitException = {
- sourceURL: 'foo.js',
- lineNumber: '1978',
- message: 'you got your foo in my bar',
- name: 'A Classic Mistake'
- };
-
- var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
-
- expect(jasmine.util.formatException(sampleWebkitException)).toEqual(expected);
- });
-
describe('with break on exception', function() {
it('should not catch the exception', function() {
+ env.catchExceptions(false);
var suite = env.describe('suite for break on exceptions', function() {
env.it('should break when an exception is thrown', function() {
throw new Error('I should hit a breakpoint!');
@@ -42,16 +17,11 @@ describe('Exceptions:', function() {
var runner = env.currentRunner();
var dont_change = 'I will never change!';
- var oldCatch = jasmine.CATCH_EXCEPTIONS;
- jasmine.CATCH_EXCEPTIONS = false;
try {
suite.execute();
dont_change = 'oops I changed';
}
catch (e) {}
- finally {
- jasmine.CATCH_EXCEPTIONS = oldCatch;
- }
expect(dont_change).toEqual('I will never change!');
});
@@ -59,117 +29,36 @@ describe('Exceptions:', function() {
describe("with catch on exception", function() {
it('should handle exceptions thrown, but continue', function() {
- var fakeTimer = new jasmine.FakeTimer();
- env.setTimeout = fakeTimer.setTimeout;
- env.clearTimeout = fakeTimer.clearTimeout;
- env.setInterval = fakeTimer.setInterval;
- env.clearInterval = fakeTimer.clearInterval;
-
- //we run two exception tests to make sure we continue after throwing an exception
- var suite = env.describe('Suite for handles exceptions', function () {
+ var ranSecondTest = false,
+ suite = env.describe('Suite for handles exceptions', function () {
env.it('should be a test that fails because it throws an exception', function() {
- throw new Error('fake error 1');
+ throw new Error();
});
-
- env.it('should be another test that fails because it throws an exception', function() {
- this.runs(function () {
- throw new Error('fake error 2');
- });
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
-
- env.it('should be a passing test that runs after exceptions are thrown', function() {
- this.expect(true).toEqual(true);
- });
-
- env.it('should be another test that fails because it throws an exception after a wait', function() {
- this.runs(function () {
- var foo = 'foo';
- });
- this.waits(250);
- this.runs(function () {
- throw new Error('fake error 3');
- });
- });
-
env.it('should be a passing test that runs after exceptions are thrown from a async test', function() {
- this.expect(true).toEqual(true);
+ ranSecondTest = true;
});
});
- var runner = env.currentRunner();
suite.execute();
- fakeTimer.tick(2500);
-
- var suiteResults = suite.results();
- var specResults = suiteResults.getItems();
-
- expect(suiteResults.passed()).toEqual(false);
- //
- expect(specResults.length).toEqual(5);
- expect(specResults[0].passed()).toMatch(false);
- var blockResults = specResults[0].getItems();
- expect(blockResults[0].passed()).toEqual(false);
- expect(blockResults[0].message).toMatch(/fake error 1/);
-
- expect(specResults[1].passed()).toEqual(false);
- blockResults = specResults[1].getItems();
- expect(blockResults[0].passed()).toEqual(false);
- expect(blockResults[0].message).toMatch(/fake error 2/);
- expect(blockResults[1].passed()).toEqual(true);
-
- expect(specResults[2].passed()).toEqual(true);
-
- expect(specResults[3].passed()).toEqual(false);
- blockResults = specResults[3].getItems();
- expect(blockResults[0].message).toMatch(/fake error 3/);
-
- expect(specResults[4].passed()).toEqual(true);
+ expect(ranSecondTest).toBe(true);
});
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
- var suite = env.describe("a top level describe block that throws an exception", function () {
+ var ranSecondDescribe = false, suite, suite2, runner = env.currentRunner();
+ suite = env.describe("a suite that throws an exception", function () {
env.it("is a test that should pass", function () {
this.expect(true).toEqual(true);
});
throw new Error("top level error");
});
-
- suite.execute();
- var suiteResults = suite.results();
- var specResults = suiteResults.getItems();
-
- expect(suiteResults.passed()).toEqual(false);
- expect(specResults.length).toEqual(2);
-
- expect(specResults[1].description).toMatch(/encountered a declaration exception/);
- });
-
- it("should handle exceptions thrown directly in nested describe blocks and continue", function () {
- var suite = env.describe("a top level describe", function () {
- env.describe("a mid-level describe that throws an exception", function () {
- env.it("is a test that should pass", function () {
- this.expect(true).toEqual(true);
- });
-
- throw new Error("a mid-level error");
- });
+ suite2 = env.describe("a suite that doesn't throw an exception", function () {
+ ranSecondDescribe = true;
});
- suite.execute();
- var suiteResults = suite.results();
- var specResults = suiteResults.getItems();
-
- expect(suiteResults.passed()).toEqual(false);
- expect(specResults.length).toEqual(1);
-
- var nestedSpecResults = specResults[0].getItems();
-
- expect(nestedSpecResults.length).toEqual(2);
- expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/);
+ runner.execute();
+ expect(ranSecondDescribe).toBe(true);
});
});
+
});
diff --git a/spec/core/ExpectationResultSpec.js b/spec/core/ExpectationResultSpec.js
new file mode 100644
index 00000000..36c4e49c
--- /dev/null
+++ b/spec/core/ExpectationResultSpec.js
@@ -0,0 +1,48 @@
+describe("buildExpectationResult", function() {
+
+ it("defaults to passed", function() {
+ var result = jasmine.buildExpectationResult({passed: 'some-value'});
+ expect(result.passed).toBe('some-value');
+ });
+
+ it("has a type of expect", function() {
+ var result = jasmine.buildExpectationResult({});
+ expect(result.type).toBe('expect');
+ });
+
+ it("message defaults to Passed for passing specs", function() {
+ var result = jasmine.buildExpectationResult({passed: true, message: 'some-value'});
+ expect(result.message).toBe('Passed.');
+ });
+
+ it("message returns the message for failing specs", function() {
+ var result = jasmine.buildExpectationResult({passed: false, message: 'some-value'});
+ expect(result.message).toBe('some-value');
+ });
+
+ it("trace passes trace if exists", function() {
+ var result = jasmine.buildExpectationResult({trace: 'some-value'});
+ expect(result.trace).toBe('some-value');
+ });
+
+ it("trace returns a new error if trace is falsy", function() {
+ var result = jasmine.buildExpectationResult({trace: false});
+ expect(result.trace).toEqual(jasmine.any(Error));
+ });
+
+ it("matcherName returns passed matcherName", function() {
+ var result = jasmine.buildExpectationResult({matcherName: 'some-value'});
+ expect(result.matcherName).toBe('some-value');
+ });
+
+ it("expected returns passed expected", function() {
+ var result = jasmine.buildExpectationResult({expected: 'some-value'});
+ expect(result.expected).toBe('some-value');
+ });
+
+ it("actual returns passed actual", function() {
+ var result = jasmine.buildExpectationResult({actual: 'some-value'});
+ expect(result.actual).toBe('some-value');
+ });
+
+});
diff --git a/spec/core/JsApiReporterSpec.js b/spec/core/JsApiReporterSpec.js
index cca70674..bf7f9f5a 100644
--- a/spec/core/JsApiReporterSpec.js
+++ b/spec/core/JsApiReporterSpec.js
@@ -1,6 +1,6 @@
-describe('jasmine.jsApiReporter', function() {
- describe('results', function () {
- var reporter, spec1, spec2, spec3, expectedSpec1Results, expectedSpec2Results;
+xdescribe('JsApiReporter (integration specs)', function() {
+ describe('results', function() {
+ var reporter, spec1, spec2;
var env;
var suite, nestedSuite, nestedSpec;
@@ -24,34 +24,24 @@ describe('jasmine.jsApiReporter', function() {
});
});
- spec3 = env.it("spec 3", function() {
- this.log('some debug message');
- });
});
- reporter = new jasmine.JsApiReporter();
+ reporter = new jasmine.JsApiReporter(jasmine);
env.addReporter(reporter);
env.execute();
- expectedSpec1Results = {
- messages: spec1.results().getItems(),
- result: "passed"
- };
- expectedSpec2Results = {
- messages: spec2.results().getItems(),
- result: "failed"
- };
});
- it('resultForSpec() should return the result for the given spec', function () {
- expect(reporter.resultsForSpec(spec1.id)).toEqual(expectedSpec1Results);
- expect(reporter.resultsForSpec(spec2.id)).toEqual(expectedSpec2Results);
- });
-
- it('results() should return a hash of all results, indexed by spec id', function () {
- expect(reporter.results()[spec1.id]).toEqual(expectedSpec1Results);
- expect(reporter.results()[spec2.id]).toEqual(expectedSpec2Results);
+ it('results() should return a hash of all results, indexed by spec id', function() {
+ var expectedSpec1Results = {
+ result: "passed"
+ },
+ expectedSpec2Results = {
+ result: "failed"
+ };
+ expect(reporter.results()[spec1.id].result).toEqual('passed');
+ expect(reporter.results()[spec2.id].result).toEqual('failed');
});
it("should return nested suites as children of their parents", function() {
@@ -65,7 +55,6 @@ describe('jasmine.jsApiReporter', function() {
{ id: 2, name: 'nested spec', type: 'spec', children: [ ] }
]
},
- { id: 3, name: 'spec 3', type: 'spec', children: [ ] }
]
}
]);
@@ -76,12 +65,7 @@ describe('jasmine.jsApiReporter', function() {
var result = reporter.results()[spec1.id];
var summarizedResult = reporter.summarizeResult_(result);
expect(summarizedResult.result).toEqual('passed');
- expect(summarizedResult.messages.length).toEqual(1);
- expect(summarizedResult.messages[0].message).toEqual(result.messages[0].message);
- expect(summarizedResult.messages[0].passed).toBeTruthy();
- expect(summarizedResult.messages[0].type).toEqual('expect');
- expect(summarizedResult.messages[0].text).toBeUndefined();
- expect(summarizedResult.messages[0].trace.stack).toBeUndefined();
+ expect(summarizedResult.messages.length).toEqual(0);
});
it("should have a stack trace for failing specs", function() {
@@ -91,13 +75,98 @@ describe('jasmine.jsApiReporter', function() {
expect(summarizedResult.messages[0].trace.stack).toEqual(result.messages[0].trace.stack);
});
- it("should have messages for specs with messages", function() {
- var result = reporter.results()[spec3.id];
- var summarizedResult = reporter.summarizeResult_(result);
- expect(summarizedResult.result).toEqual('passed');
- expect(summarizedResult.messages[0].type).toEqual('log');
- expect(summarizedResult.messages[0].text).toEqual('some debug message');
- });
});
});
-});
\ No newline at end of file
+});
+
+
+describe("JsApiReporter", function() {
+
+ it("knows when a full environment is started", function() {
+ var reporter = new jasmine.JsApiReporter();
+
+ expect(reporter.started).toBe(false);
+ expect(reporter.finished).toBe(false);
+
+ reporter.jasmineStarted();
+
+ expect(reporter.started).toBe(true);
+ expect(reporter.finished).toBe(false);
+ });
+
+ it("knows when a full environment is done", function() {
+ var reporter = new jasmine.JsApiReporter();
+
+ expect(reporter.started).toBe(false);
+ expect(reporter.finished).toBe(false);
+
+ reporter.jasmineStarted();
+ reporter.jasmineDone();
+
+ expect(reporter.finished).toBe(true);
+ });
+
+ it("defaults to 'loaded' status", function() {
+ var reporter = new jasmine.JsApiReporter();
+
+ expect(reporter.status()).toEqual('loaded');
+ });
+
+ it("reports 'started' when Jasmine has started", function() {
+ var reporter = new jasmine.JsApiReporter();
+
+ reporter.jasmineStarted();
+
+ expect(reporter.status()).toEqual('started');
+ });
+
+ it("reports 'done' when Jasmine is done", function() {
+ var reporter = new jasmine.JsApiReporter();
+
+ reporter.jasmineDone();
+
+ expect(reporter.status()).toEqual('done');
+ });
+
+ it("tracks a suite", function() {
+ var reporter = new jasmine.JsApiReporter();
+
+ reporter.suiteStarted({
+ id: 123,
+ description: "A suite"
+ });
+
+ var suites = reporter.suites();
+
+ expect(suites).toEqual({123: {id: 123, description: "A suite"}});
+
+ reporter.suiteDone({
+ id: 123,
+ description: "A suite",
+ status: 'passed'
+ });
+
+ expect(suites).toEqual({123: {id: 123, description: "A suite", status: 'passed'}});
+ });
+
+ it("tracks a spec", function() {
+ var reporter = new jasmine.JsApiReporter();
+
+ reporter.specStarted({
+ id: 123,
+ description: "A spec"
+ });
+
+ var specs = reporter.specs();
+
+ expect(specs).toEqual({123: {id: 123, description: "A spec"}});
+
+ reporter.specDone({
+ id: 123,
+ description: "A spec",
+ status: 'passed'
+ });
+
+ expect(specs).toEqual({123: {id: 123, description: "A spec", status: 'passed'}});
+ });
+});
diff --git a/spec/core/MatchersSpec.js b/spec/core/MatchersSpec.js
index 97c3f60d..fe501f7a 100644
--- a/spec/core/MatchersSpec.js
+++ b/spec/core/MatchersSpec.js
@@ -9,14 +9,14 @@ describe("jasmine.Matchers", function() {
spec = env.it("spec", function() {
});
});
- spyOn(spec, 'addMatcherResult');
+ spyOn(spec, 'addExpectationResult');
- this.addMatchers({
+ addMatchers({
toPass: function() {
- return lastResult().passed();
+ return lastResult().passed;
},
toFail: function() {
- return !lastResult().passed();
+ return !lastResult().passed;
}
});
});
@@ -26,7 +26,7 @@ describe("jasmine.Matchers", function() {
}
function lastResult() {
- return spec.addMatcherResult.mostRecentCall.args[0];
+ return spec.addExpectationResult.mostRecentCall.args[1];
}
function catchException(fn) {
@@ -82,7 +82,7 @@ describe("jasmine.Matchers", function() {
expect((match(/[abc]/gm).toNotEqual(/1/i))).toPass();
// only test if the browser supports the sticky option on a regExp see pull #234
- if (typeof RegExp.prototype.sticky !== 'undefined') {
+ if (RegExp.prototype.sticky !== undefined) {
var sticky_regexp = new RegExp("[abc]", "y");
expect((match(sticky_regexp).toEqual(/1/i))).toFail();
expect((match(sticky_regexp).toNotEqual(/1/i))).toPass();
@@ -98,7 +98,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toEqual");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.expected).toEqual(expected);
@@ -113,7 +113,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toNotEqual");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(str));
expect(result.message).toMatch('not');
expect(result.expected).toEqual(str);
@@ -142,7 +142,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBe");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.expected).toEqual(expected);
@@ -157,7 +157,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toNotBe");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(str);
expect(result.expected).toEqual(str);
expect(result.actual).toEqual(str);
@@ -186,7 +186,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toMatch");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch(expected.toString());
expect(result.expected).toEqual(expected);
@@ -202,7 +202,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toMatch");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected 'a' to match 'b'.");
expect(result.expected).toEqual(expected);
expect(result.actual).toEqual(actual);
@@ -217,7 +217,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toNotMatch");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected 'a' to not match /a/.");
expect(result.expected).toEqual(expected);
expect(result.actual).toEqual(actual);
@@ -231,7 +231,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toNotMatch");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected 'a' to not match 'a'.");
expect(result.expected).toEqual(str);
expect(result.actual).toEqual(str);
@@ -249,7 +249,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBeDefined");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toEqual('Expected undefined to be defined.');
expect(result.actual).toEqual(jasmine.undefined);
});
@@ -273,7 +273,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBeNull");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('null');
expect(result.actual).toEqual(actual);
@@ -287,34 +287,34 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBeNull");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('null');
expect(result.actual).toEqual(actual);
});
- it("toBeNaN", function() {
- expect(match(Number.NaN).toBeNaN()).toPass();
- expect(match(0).toBeNaN()).toFail();
- expect(match(1).toBeNaN()).toFail();
- expect(match(null).toBeNaN()).toFail();
- expect(match(Number.POSITIVE_INFINITY).toBeNaN()).toFail();
- expect(match(Number.NEGATIVE_INFINITY).toBeNaN()).toFail();
- expect(match('NaN').toBeNaN()).toFail();
- });
+ it("toBeNaN", function() {
+ expect(match(Number.NaN).toBeNaN()).toPass();
+ expect(match(0).toBeNaN()).toFail();
+ expect(match(1).toBeNaN()).toFail();
+ expect(match(null).toBeNaN()).toFail();
+ expect(match(Number.POSITIVE_INFINITY).toBeNaN()).toFail();
+ expect(match(Number.NEGATIVE_INFINITY).toBeNaN()).toFail();
+ expect(match('NaN').toBeNaN()).toFail();
+ });
- it("toBeNaN to build an ExpectationResult", function() {
- var actual = 'a';
- var matcher = match(actual);
- matcher.toBeNaN();
+ it("toBeNaN to build an ExpectationResult", function() {
+ var actual = 'a';
+ var matcher = match(actual);
+ matcher.toBeNaN();
- var result = lastResult();
+ var result = lastResult();
- expect(result.matcherName).toEqual("toBeNaN");
- expect(result.passed()).toFail();
- expect(result.message).toMatch("Expected 'a' to be NaN.");
- expect(result.actual).toMatch(actual);
- });
+ expect(result.matcherName).toEqual("toBeNaN");
+ expect(result.passed).toBe(false);
+ expect(result.message).toMatch("Expected 'a' to be NaN.");
+ expect(result.actual).toMatch(actual);
+ });
it("toBeFalsy", function() {
expect(match(false).toBeFalsy()).toPass();
@@ -332,7 +332,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBeFalsy");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('falsy');
expect(result.actual).toEqual(actual);
@@ -356,7 +356,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBeTruthy");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected false to be truthy.");
expect(result.actual).toFail();
});
@@ -378,11 +378,11 @@ describe("jasmine.Matchers", function() {
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail();
expect(match(
function() {
- }).toEqual(jasmine.any(Object))).toFail();
+ }).toEqual(jasmine.any(Object))).toFail();
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass();
expect(match(
function() {
- }).toEqual(jasmine.any(Function))).toPass();
+ }).toEqual(jasmine.any(Function))).toPass();
expect(match(["a", function() {
}]).toEqual(["a", jasmine.any(Function)])).toPass();
});
@@ -391,7 +391,7 @@ describe("jasmine.Matchers", function() {
var matcher;
beforeEach(function () {
matcher = {
- jasmineMatches: jasmine.createSpy("jasmineMatches")
+ jasmineMatches: originalJasmine.createSpy("jasmineMatches")
};
});
@@ -459,7 +459,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toContain");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('contain');
expect(result.message).toMatch(jasmine.pp(expected));
@@ -476,7 +476,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toNotContain");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('not contain');
expect(result.message).toMatch(jasmine.pp(expected));
@@ -499,7 +499,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBeLessThan");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual) + ' to be less than');
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual);
@@ -521,7 +521,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toBeGreaterThan");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual) + ' to be greater than');
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual);
@@ -608,13 +608,13 @@ describe("jasmine.Matchers", function() {
it("should match exceptions specified by message", function() {
expect(match(throwingFn).not.toThrow("Fake Error")).toFail();
-// expect(lastResult().message).toMatch(/Expected function not to throw Fake Error./);
+ // expect(lastResult().message).toMatch(/Expected function not to throw Fake Error./);
expect(match(throwingFn).not.toThrow("Other Error")).toPass();
});
it("should match exceptions specified by Error", function() {
expect(match(throwingFn).not.toThrow(new Error("Fake Error"))).toFail();
-// expect(lastResult().message).toMatch("Other Error");
+ // expect(lastResult().message).toMatch("Other Error");
expect(match(throwingFn).not.toThrow(new Error("Other Error"))).toPass();
});
});
@@ -645,7 +645,7 @@ describe("jasmine.Matchers", function() {
it("should fail (or pass when inverted with .not)", function() {
expect(match(
function() {
- }).toThrow()).toFail();
+ }).toThrow()).toFail();
expect(lastResult().message).toEqual('Expected function to throw an exception.');
});
});
@@ -668,7 +668,7 @@ describe("jasmine.Matchers", function() {
});
it("should use the second message when the matcher sets an array of custom messages", function() {
- spec.addMatchers({
+ env.addMatchers({
custom: function() {
this.message = function() {
return ['Expected it was called.', 'Expected it wasn\'t called.'];
@@ -694,7 +694,7 @@ describe("jasmine.Matchers", function() {
TestClass = {
normalFunction: function() {
},
- spyFunction: jasmine.createSpy("My spy")
+ spyFunction: originalJasmine.createSpy("My spy")
};
});
@@ -702,23 +702,23 @@ describe("jasmine.Matchers", function() {
return function() {
expect(
function() {
- match(TestClass.normalFunction)[methodName]();
- }).toThrow('Expected a spy, but got Function.');
+ match(TestClass.normalFunction)[methodName]();
+ }).toThrow('Expected a spy, but got Function.');
expect(
function() {
- match(jasmine.undefined)[methodName]();
- }).toThrow('Expected a spy, but got undefined.');
+ match(jasmine.undefined)[methodName]();
+ }).toThrow('Expected a spy, but got undefined.');
expect(
function() {
- match({some:'object'})[methodName]();
- }).toThrow('Expected a spy, but got { some : \'object\' }.');
+ match({some:'object'})[methodName]();
+ }).toThrow('Expected a spy, but got { some : \'object\' }.');
expect(
function() {
- match("")[methodName]();
- }).toThrow('Expected a spy, but got \'\'.');
+ match("")[methodName]();
+ }).toThrow('Expected a spy, but got \'\'.');
};
}
@@ -733,8 +733,8 @@ describe("jasmine.Matchers", function() {
it("should throw an exception when invoked with any arguments", function() {
expect(
function() {
- match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
- }).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
+ match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
+ }).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
});
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalled'));
@@ -762,8 +762,8 @@ describe("jasmine.Matchers", function() {
it("should throw an exception when invoked with any arguments", function() {
expect(
function() {
- match(TestClass.normalFunction).wasNotCalled("unwanted argument");
- }).toThrow('wasNotCalled does not take arguments');
+ match(TestClass.normalFunction).wasNotCalled("unwanted argument");
+ }).toThrow('wasNotCalled does not take arguments');
});
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalled'));
@@ -780,7 +780,7 @@ describe("jasmine.Matchers", function() {
var expected = match(TestClass.spyFunction);
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
var result = lastResult();
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.expected).toEqual(['c', 'b', 'a']);
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
expect(result.message).toContain(jasmine.pp(result.expected));
@@ -791,7 +791,7 @@ describe("jasmine.Matchers", function() {
var expected = match(TestClass.spyFunction);
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
var result = lastResult();
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.expected).toEqual(['c', 'b', 'a']);
expect(result.actual.argsForCall).toEqual([]);
expect(result.message).toContain(jasmine.pp(result.expected));
@@ -839,7 +839,7 @@ describe("jasmine.Matchers", function() {
}, spec);
TestClass = { someFunction: function(a, b) {
} };
- spec.spyOn(TestClass, 'someFunction');
+ env.spyOn(TestClass, 'someFunction');
});
it("should should handle the case of a spy", function() {
@@ -849,7 +849,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult();
expect(result.matcherName).toEqual("toHaveBeenCalledWith");
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.message).toContain(jasmine.pp(['a', 'b']));
expect(result.message).toContain(jasmine.pp(['a', 'c']));
expect(result.actual).toEqual(TestClass.someFunction);
@@ -879,7 +879,7 @@ describe("jasmine.Matchers", function() {
var expected = match(TestClass.spyFunction);
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
var result = lastResult();
- expect(result.passed()).toFail();
+ expect(result.passed).toBe(false);
expect(result.expected).toEqual(['a', 'b', 'c']);
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
expect(result.message).toContain(jasmine.pp(result.expected));
@@ -910,7 +910,7 @@ describe("jasmine.Matchers", function() {
containing = new jasmine.Matchers.ObjectContaining({});
});
it("matches everything", function () {
- expect(containing.jasmineMatches("foo", [], [])).toBe(true);
+ expect(containing.jasmineMatches("foo", [], [])).toBe(true);
});
it("says it didn't expect to contain anything", function () {
@@ -974,7 +974,7 @@ describe("jasmine.Matchers", function() {
describe("in real life", function () {
var method;
beforeEach(function () {
- method = jasmine.createSpy("method");
+ method = originalJasmine.createSpy("method");
method({a:"b", c:"d"});
});
it("works correctly for positive matches", function () {
diff --git a/spec/core/MockClockSpec.js b/spec/core/MockClockSpec.js
deleted file mode 100644
index be683440..00000000
--- a/spec/core/MockClockSpec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-describe("MockClock", function () {
-
- beforeEach(function() {
- jasmine.Clock.useMock();
- });
-
- describe("setTimeout", function () {
- it("should mock the clock when useMock is in a beforeEach", function() {
- var expected = false;
- setTimeout(function() {
- expected = true;
- }, 30000);
- expect(expected).toBe(false);
- jasmine.Clock.tick(30001);
- expect(expected).toBe(true);
- });
- });
-
- describe("setInterval", function () {
- it("should mock the clock when useMock is in a beforeEach", function() {
- var interval = 0;
- setInterval(function() {
- interval++;
- }, 30000);
- expect(interval).toEqual(0);
- jasmine.Clock.tick(30001);
- expect(interval).toEqual(1);
- jasmine.Clock.tick(30001);
- expect(interval).toEqual(2);
- jasmine.Clock.tick(1);
- expect(interval).toEqual(2);
- });
- });
-
- it("shouldn't complain if you call jasmine.Clock.useMock() more than once", function() {
- jasmine.Clock.useMock();
- });
-});
diff --git a/spec/core/MultiReporterSpec.js b/spec/core/MultiReporterSpec.js
deleted file mode 100644
index f269d682..00000000
--- a/spec/core/MultiReporterSpec.js
+++ /dev/null
@@ -1,45 +0,0 @@
-describe("jasmine.MultiReporter", function() {
- var multiReporter, fakeReporter1, fakeReporter2;
-
- beforeEach(function() {
- multiReporter = new jasmine.MultiReporter();
- fakeReporter1 = jasmine.createSpyObj("fakeReporter1", ["reportSpecResults"]);
- fakeReporter2 = jasmine.createSpyObj("fakeReporter2", ["reportSpecResults", "reportRunnerStarting"]);
- multiReporter.addReporter(fakeReporter1);
- multiReporter.addReporter(fakeReporter2);
- });
-
- it("should support all the method calls that jasmine.Reporter supports", function() {
- var delegate = {};
- multiReporter.addReporter(delegate);
-
- this.addMatchers({
- toDelegateMethod: function(methodName) {
- delegate[methodName] = jasmine.createSpy(methodName);
- this.actual[methodName]("whatever argument");
-
- return delegate[methodName].wasCalled &&
- delegate[methodName].mostRecentCall.args.length == 1 &&
- delegate[methodName].mostRecentCall.args[0] == "whatever argument";
- }
- });
-
- expect(multiReporter).toDelegateMethod('reportRunnerStarting');
- expect(multiReporter).toDelegateMethod('reportRunnerResults');
- expect(multiReporter).toDelegateMethod('reportSuiteResults');
- expect(multiReporter).toDelegateMethod('reportSpecStarting');
- expect(multiReporter).toDelegateMethod('reportSpecResults');
- expect(multiReporter).toDelegateMethod('log');
- });
-
- it("should delegate to any and all subreporters", function() {
- multiReporter.reportSpecResults('blah', 'foo');
- expect(fakeReporter1.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
- expect(fakeReporter2.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
- });
-
- it("should quietly skip delegating to any subreporters which lack the given method", function() {
- multiReporter.reportRunnerStarting('blah', 'foo');
- expect(fakeReporter2.reportRunnerStarting).toHaveBeenCalledWith('blah', 'foo');
- });
-});
\ No newline at end of file
diff --git a/spec/core/NestedResultsSpec.js b/spec/core/NestedResultsSpec.js
deleted file mode 100644
index e4bc9190..00000000
--- a/spec/core/NestedResultsSpec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-describe('jasmine.NestedResults', function() {
- it('#addResult increments counters', function() {
- // Leaf case
- var results = new jasmine.NestedResults();
-
- results.addResult(new jasmine.ExpectationResult({
- matcherName: "foo", passed: true, message: 'Passed.', actual: 'bar', expected: 'bar'}
- ));
-
- expect(results.getItems().length).toEqual(1);
- expect(results.totalCount).toEqual(1);
- expect(results.passedCount).toEqual(1);
- expect(results.failedCount).toEqual(0);
-
- results.addResult(new jasmine.ExpectationResult({
- matcherName: "baz", passed: false, message: 'FAIL.', actual: "corge", expected: "quux"
- }));
-
- expect(results.getItems().length).toEqual(2);
- expect(results.totalCount).toEqual(2);
- expect(results.passedCount).toEqual(1);
- expect(results.failedCount).toEqual(1);
- });
-
- it('should roll up counts for nested results', function() {
- // Branch case
- var leafResultsOne = new jasmine.NestedResults();
- leafResultsOne.addResult(new jasmine.ExpectationResult({
- matcherName: "toSomething", passed: true, message: 'message', actual: '', expected:''
- }));
-
- leafResultsOne.addResult(new jasmine.ExpectationResult({
- matcherName: "toSomethingElse", passed: false, message: 'message', actual: 'a', expected: 'b'
- }));
-
- var leafResultsTwo = new jasmine.NestedResults();
- leafResultsTwo.addResult(new jasmine.ExpectationResult({
- matcherName: "toSomething", passed: true, message: 'message', actual: '', expected: ''
- }));
- leafResultsTwo.addResult(new jasmine.ExpectationResult({
- matcherName: "toSomethineElse", passed: false, message: 'message', actual: 'c', expected: 'd'
- }));
-
- var branchResults = new jasmine.NestedResults();
- branchResults.addResult(leafResultsOne);
- branchResults.addResult(leafResultsTwo);
-
- expect(branchResults.getItems().length).toEqual(2);
- expect(branchResults.totalCount).toEqual(4);
- expect(branchResults.passedCount).toEqual(2);
- expect(branchResults.failedCount).toEqual(2);
- });
-
-});
diff --git a/spec/core/QueueRunnerSpec.js b/spec/core/QueueRunnerSpec.js
new file mode 100644
index 00000000..933f3e67
--- /dev/null
+++ b/spec/core/QueueRunnerSpec.js
@@ -0,0 +1,132 @@
+describe("QueueRunner", function() {
+
+ it("runs all the functions it's passed", function() {
+ var calls = [],
+ fn1 = jasmine.createSpy('fn1'),
+ fn2 = jasmine.createSpy('fn2'),
+ queueRunner = new jasmine.QueueRunner({
+ fns: [fn1, fn2]
+ });
+ fn1.andCallFake(function() {
+ calls.push('fn1');
+ });
+ fn2.andCallFake(function() {
+ calls.push('fn2');
+ });
+
+ queueRunner.execute();
+
+ expect(calls).toEqual(['fn1', 'fn2']);
+ });
+
+ it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
+ //TODO: it would be nice if spy arity could match the fake, so we could do something like:
+ //createSpy('asyncfn').andCallFake(function(done) {});
+
+ var onComplete = originalJasmine.createSpy('onComplete'),
+ beforeCallback = originalJasmine.createSpy('beforeCallback'),
+ fnCallback = originalJasmine.createSpy('fnCallback'),
+ afterCallback = originalJasmine.createSpy('afterCallback'),
+ fn1 = function(done) {
+ beforeCallback();
+ setTimeout(function() {
+ done()
+ }, 100);
+ },
+ fn2 = function(done) {
+ fnCallback();
+ setTimeout(function() {
+ done()
+ }, 100);
+ },
+ fn3 = function(done) {
+ afterCallback();
+ setTimeout(function() {
+ done()
+ }, 100);
+ },
+ queueRunner = new jasmine.QueueRunner({
+ fns: [fn1, fn2, fn3],
+ onComplete: onComplete
+ });
+
+ clock.install();
+
+ queueRunner.execute();
+
+ expect(beforeCallback).toHaveBeenCalled();
+ expect(fnCallback).not.toHaveBeenCalled();
+ expect(afterCallback).not.toHaveBeenCalled();
+ expect(onComplete).not.toHaveBeenCalled();
+
+ clock.tick(100);
+
+ expect(fnCallback).toHaveBeenCalled();
+ expect(afterCallback).not.toHaveBeenCalled();
+ expect(onComplete).not.toHaveBeenCalled();
+
+ clock.tick(100);
+
+ expect(afterCallback).toHaveBeenCalled();
+ expect(onComplete).not.toHaveBeenCalled();
+
+ clock.tick(100);
+
+ expect(onComplete).toHaveBeenCalled();
+ });
+
+ it("calls an exception handler when an exception is thrown in a fn", function() {
+ var fn = function() {
+ throw new Error('fake error');
+ },
+ exceptionCallback = jasmine.createSpy('exception callback'),
+ queueRunner = new jasmine.QueueRunner({
+ fns: [fn],
+ onException: exceptionCallback
+ });
+
+ queueRunner.execute();
+
+ expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
+ });
+
+ it("rethrows an exception if told to", function() {
+ var fn = function() {
+ throw new Error('fake error');
+ },
+ queueRunner = new jasmine.QueueRunner({
+ fns: [fn],
+ catchingExceptions: function() { return false; }
+ });
+
+ expect(function() { queueRunner.execute(); }).toThrow();
+ });
+
+ it("calls a provided complete callback when done", function() {
+ var fn = jasmine.createSpy('fn'),
+ completeCallback = jasmine.createSpy('completeCallback'),
+ queueRunner = new jasmine.QueueRunner({
+ fns: [fn],
+ onComplete: completeCallback
+ });
+
+ queueRunner.execute();
+
+ expect(completeCallback).toHaveBeenCalled();
+ });
+
+ it("calls a provided garbage collection function with the complete callback when done", function() {
+ var fn = jasmine.createSpy('fn'),
+ completeCallback = jasmine.createSpy('completeCallback'),
+ encourageGC = jasmine.createSpy('encourageGC'),
+ queueRunner = new jasmine.QueueRunner({
+ fns: [fn],
+ encourageGC: encourageGC,
+ onComplete: completeCallback
+ });
+
+ queueRunner.execute();
+
+ expect(encourageGC).toHaveBeenCalledWith(completeCallback);
+ });
+});
diff --git a/spec/core/QueueSpec.js b/spec/core/QueueSpec.js
deleted file mode 100644
index 59a70f39..00000000
--- a/spec/core/QueueSpec.js
+++ /dev/null
@@ -1,23 +0,0 @@
-describe("jasmine.Queue", function() {
- it("should not call itself recursively, so we don't get stack overflow errors", function() {
- var queue = new jasmine.Queue(new jasmine.Env());
- queue.add(new jasmine.Block(null, function() {}));
- queue.add(new jasmine.Block(null, function() {}));
- queue.add(new jasmine.Block(null, function() {}));
- queue.add(new jasmine.Block(null, function() {}));
-
- var nestCount = 0;
- var maxNestCount = 0;
- var nextCallCount = 0;
- queue.next_ = function() {
- nestCount++;
- if (nestCount > maxNestCount) maxNestCount = nestCount;
-
- jasmine.Queue.prototype.next_.apply(queue, arguments);
- nestCount--;
- };
-
- queue.start();
- expect(maxNestCount).toEqual(1);
- });
-});
\ No newline at end of file
diff --git a/spec/core/ReportDispatcherSpec.js b/spec/core/ReportDispatcherSpec.js
new file mode 100644
index 00000000..62b0d463
--- /dev/null
+++ b/spec/core/ReportDispatcherSpec.js
@@ -0,0 +1,40 @@
+describe("ReportDispatcher", function() {
+
+ it("builds an interface of requested methods", function() {
+ var dispatcher = new jasmine.ReportDispatcher(['foo', 'bar', 'baz']);
+
+ expect(dispatcher.foo).toBeDefined();
+ expect(dispatcher.bar).toBeDefined();
+ expect(dispatcher.baz).toBeDefined();
+ });
+
+ it("dispatches requested methods to added reporters", function() {
+ var dispatcher = new jasmine.ReportDispatcher(['foo', 'bar']),
+ reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
+ anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
+
+ dispatcher.addReporter(reporter);
+ dispatcher.addReporter(anotherReporter);
+
+ dispatcher.foo(123, 456);
+
+ expect(reporter.foo).toHaveBeenCalledWith(123, 456);
+ expect(anotherReporter.foo).toHaveBeenCalledWith(123, 456);
+
+ dispatcher.bar('a', 'b');
+
+ expect(reporter.bar).toHaveBeenCalledWith('a', 'b');
+ expect(anotherReporter.bar).toHaveBeenCalledWith('a', 'b');
+ });
+
+ it("does not dispatch to a reporter if the reporter doesn't accept the method", function() {
+ var dispatcher = new jasmine.ReportDispatcher(['foo']),
+ reporter = jasmine.createSpyObj('reporter', ['baz']);
+
+ dispatcher.addReporter(reporter);
+
+ expect(function() {
+ dispatcher.foo(123, 456);
+ }).not.toThrow();
+ });
+});
\ No newline at end of file
diff --git a/spec/core/ReporterSpec.js b/spec/core/ReporterSpec.js
deleted file mode 100644
index 26cdd17c..00000000
--- a/spec/core/ReporterSpec.js
+++ /dev/null
@@ -1,56 +0,0 @@
-describe('jasmine.Reporter', function() {
- var env;
-
-
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
- });
-
- it('should get called from the test runner', function() {
- env.describe('Suite for JSON Reporter with Callbacks', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- env.it('should be a failing test', function() {
- this.runs(function () {
- this.expect(false).toEqual(true);
- });
- });
- });
- env.describe('Suite for JSON Reporter with Callbacks 2', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
-
- });
-
- var foo = 0;
- var bar = 0;
- var baz = 0;
-
- env.addReporter({
- reportSpecResults: function() {
- foo++;
- },
- reportSuiteResults: function() {
- bar++;
- },
- reportRunnerResults: function() {
- baz++;
- }
- });
-
- var runner = env.currentRunner();
- runner.execute();
-
- expect(foo).toEqual(3); // 'foo was expected to be 3, was ' + foo);
- expect(bar).toEqual(2); // 'bar was expected to be 2, was ' + bar);
- expect(baz).toEqual(1); // 'baz was expected to be 1, was ' + baz);
- });
-
-});
\ No newline at end of file
diff --git a/spec/core/RunnerSpec.js b/spec/core/RunnerSpec.js
deleted file mode 100644
index 090a15ea..00000000
--- a/spec/core/RunnerSpec.js
+++ /dev/null
@@ -1,280 +0,0 @@
-describe('RunnerTest', function() {
- var fakeTimer;
- var env;
-
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
-
- fakeTimer = new jasmine.FakeTimer();
- env.setTimeout = fakeTimer.setTimeout;
- env.clearTimeout = fakeTimer.clearTimeout;
- env.setInterval = fakeTimer.setInterval;
- env.clearInterval = fakeTimer.clearInterval;
- });
-
- describe('beforeEach', function() {
- it('should run before each spec for all suites', function () {
- var foo;
- env.beforeEach(function () {
- foo = 0;
- });
-
- env.describe('suite 1', function () {
- env.it('test 1-1', function() {
- foo++;
- this.expect(foo).toEqual(1);
- });
- env.it('test 1-2', function() {
- foo++;
- this.expect(foo).toEqual(1);
- });
- });
-
- env.describe('suite 2', function () {
- env.it('test 2-1', function() {
- foo++;
- this.expect(foo).toEqual(1);
- });
- });
-
- env.currentRunner().execute();
-
- var runnerResults = env.currentRunner().results();
- expect(runnerResults.totalCount).toEqual(3);
- expect(runnerResults.passedCount).toEqual(3);
- });
-
-
- it('should provide all specs', function () {
- var foo;
- env.beforeEach(function () {
- foo = 0;
- });
-
- env.describe('suite 1', function () {
- env.it('test 1-1', function() {
- foo++;
- this.expect(foo).toEqual(1);
- });
- env.it('test 1-2', function() {
- foo++;
- this.expect(foo).toEqual(1);
- });
- });
-
- env.describe('suite 2', function () {
- env.it('test 2-1', function() {
- foo++;
- this.expect(foo).toEqual(1);
- });
- });
-
- env.currentRunner().execute();
-
-
- expect(env.currentRunner().specs().length).toEqual(3);
- });
- });
-
- describe('afterEach', function() {
- it('should run after each spec for all suites', function () {
- var foo = 3;
- env.afterEach(function () {
- foo = foo - 1;
- });
-
- env.describe('suite 1', function () {
- env.it('test 1-1', function() {
- this.expect(foo).toEqual(3);
- });
- env.it('test 1-2', function() {
- this.expect(foo).toEqual(2);
- });
- });
-
- env.describe('suite 2', function () {
- env.it('test 2-1', function() {
- this.expect(foo).toEqual(1);
- });
- });
-
- env.currentRunner().execute();
-
- var runnerResults = env.currentRunner().results();
- expect(runnerResults.totalCount).toEqual(3);
- expect(runnerResults.passedCount).toEqual(3);
- });
-
- it('should run after a failing spec', function () {
- var afterEach = jasmine.createSpy();
- env.afterEach(afterEach);
-
- env.describe('suite', function () {
- env.it('fails', function () {
- this.explodes();
- });
- }).execute();
-
- expect(afterEach).toHaveBeenCalled();
- });
- });
-
-
- it('should run child suites and specs and generate results when execute is called', function() {
- env.describe('one suite description', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- });
-
- env.describe('another suite description', function () {
- env.it('should be another test', function() {
- this.runs(function () {
- this.expect(true).toEqual(false);
- });
- });
- });
-
- env.currentRunner().execute();
-
- var runnerResults = env.currentRunner().results();
- expect(runnerResults.totalCount).toEqual(2);
- expect(runnerResults.passedCount).toEqual(1);
- expect(runnerResults.failedCount).toEqual(1);
- });
-
-
- it('should ignore suites that have been x\'d', function() {
- env.xdescribe('one suite description', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- });
-
- env.describe('another suite description', function () {
- env.it('should be another test', function() {
- this.runs(function () {
- this.expect(true).toEqual(false);
- });
- });
- });
-
- env.currentRunner().execute();
-
- var runnerResults = env.currentRunner().results();
- expect(runnerResults.totalCount).toEqual(1);
- expect(runnerResults.passedCount).toEqual(0);
- expect(runnerResults.failedCount).toEqual(1);
- });
-
- it('should roll up results from all specs', function() {
- env.describe('one suite description', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- });
-
- env.describe('another suite description', function () {
- env.it('should be another test', function() {
- this.runs(function () {
- this.expect(true).toEqual(false);
- });
- });
- });
-
- env.currentRunner().execute();
-
- var results = env.currentRunner().results();
- expect(results.totalCount).toEqual(2);
- expect(results.passedCount).toEqual(1);
- expect(results.failedCount).toEqual(1);
- });
-
- describe('reporting', function () {
- var fakeReporter;
- beforeEach(function () {
- fakeReporter = jasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting", "reportRunnerResults"]);
- env.addReporter(fakeReporter);
- });
-
- it('should report runner results when the runner has completed running', function() {
- env.describe('one suite description', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- });
-
- env.describe('another suite description', function () {
- env.it('should be another test', function() {
- this.waits(200);
- this.runs(function () {
- this.expect(true).toEqual(false);
- });
- });
- });
-
- env.currentRunner().execute();
- expect(fakeReporter.reportRunnerResults).not.toHaveBeenCalled();
- fakeTimer.tick(200);
- //This blows up the JSApiReporter.
- //expect(fakeReporter.reportRunnerResults).toHaveBeenCalledWith(env.currentRunner);
- expect(fakeReporter.reportRunnerResults).toHaveBeenCalled();
- expect(fakeReporter.reportRunnerResults.mostRecentCall.args[0].results()).toEqual(env.currentRunner().results());
- });
- });
-
- it("should report when the tests start running", function() {
- var fakeReporter = jasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting"]);
- env.addReporter(fakeReporter);
-
-
- var runner = new jasmine.Runner(env);
- runner.arbitraryVariable = 'foo';
- spyOn(runner.queue, 'start');
- expect(fakeReporter.reportRunnerStarting).not.toHaveBeenCalled();
- runner.execute();
- expect(fakeReporter.reportRunnerStarting).toHaveBeenCalled();
- var reportedRunner = fakeReporter.reportRunnerStarting.mostRecentCall.args[0];
- expect(reportedRunner.arbitraryVariable).toEqual('foo');
- expect(runner.queue.start).toHaveBeenCalled();
- });
-
- describe("when suites are nested", function() {
- var suite1, suite2, suite3;
-
- function suiteNames(suites) {
- var suiteDescriptions = [];
- for (var i = 0; i < suites.length; i++) {
- suiteDescriptions.push(suites[i].getFullName());
- }
- return suiteDescriptions;
- }
-
- beforeEach(function() {
- suite1 = env.describe("suite 1", function() {
- suite2 = env.describe("suite 2", function() {
- });
- });
- suite3 = env.describe("suite 3", function() {});
- });
-
- it("#suites should return a flat array of all suites, including nested suites", function() {
- var suites = env.currentRunner().suites();
- expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite2.getFullName(), suite3.getFullName()]);
- });
-
- it("#topLevelSuites should return a flat array of all top-level suites only", function() {
- var suites = env.currentRunner().topLevelSuites();
- expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite3.getFullName()]);
- });
- });
-});
\ No newline at end of file
diff --git a/spec/core/SpecRunningSpec.js b/spec/core/SpecRunningSpec.js
index a0268224..32e69f7c 100644
--- a/spec/core/SpecRunningSpec.js
+++ b/spec/core/SpecRunningSpec.js
@@ -1,3 +1,4 @@
+// TODO: This should really be part of the Env Integration Spec
describe("jasmine spec running", function () {
var env;
var fakeTimer;
@@ -5,12 +6,6 @@ describe("jasmine spec running", function () {
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
-
- fakeTimer = new jasmine.FakeTimer();
- env.setTimeout = fakeTimer.setTimeout;
- env.clearTimeout = fakeTimer.clearTimeout;
- env.setInterval = fakeTimer.setInterval;
- env.clearInterval = fakeTimer.clearInterval;
});
it('should assign spec ids sequentially', function() {
@@ -37,626 +32,6 @@ describe("jasmine spec running", function () {
expect(it4.id).toEqual(4);
});
- it("should build up some objects with results we can inspect", function() {
-
- var specWithNoBody, specWithExpectation, specWithFailingExpectations, specWithMultipleExpectations;
-
- var suite = env.describe('default current suite', function() {
- specWithNoBody = env.it('new spec');
-
- specWithExpectation = env.it('spec with an expectation').runs(function () {
- var foo = 'bar';
- this.expect(foo).toEqual('bar');
- });
-
- specWithFailingExpectations = env.it('spec with failing expectation').runs(function () {
- var foo = 'bar';
- this.expect(foo).toEqual('baz');
- });
-
- specWithMultipleExpectations = env.it('spec with multiple expectations').runs(function () {
- var foo = 'bar';
- var baz = 'quux';
-
- this.expect(foo).toEqual('bar');
- this.expect(baz).toEqual('quux');
- });
- });
-
- suite.execute();
-
- expect(specWithNoBody.description).toEqual('new spec');
-
- expect(specWithExpectation.results().getItems().length).toEqual(1); // "Results aren't there after a spec was executed"
- expect(specWithExpectation.results().getItems()[0].passed()).toEqual(true); // "Results has a result, but it's true"
- expect(specWithExpectation.results().description).toEqual('spec with an expectation'); // "Spec's results did not get the spec's description"
-
- expect(specWithFailingExpectations.results().getItems()[0].passed()).toEqual(false); // "Expectation that failed, passed"
-
- expect(specWithMultipleExpectations.results().getItems().length).toEqual(2); // "Spec doesn't support multiple expectations"
- });
-
- it("should work without a runs block", function() {
- var another_spec;
- env.describe('default current suite', function() {
- another_spec = env.it('spec with an expectation', function () {
- var foo = 'bar';
- this.expect(foo).toEqual('bar');
- this.expect(foo).toEqual('baz');
- });
- });
-
- another_spec.execute();
- another_spec.done = true;
-
- expect(another_spec.results().getItems().length).toEqual(2);
- expect(another_spec.results().getItems()[0].passed()).toEqual(true); // "In a spec without a run block, expected first expectation result to be true but was false"
- expect(another_spec.results().getItems()[1].passed()).toEqual(false); // "In a spec without a run block, expected second expectation result to be false but was true";
- expect(another_spec.results().description).toEqual('spec with an expectation'); // "In a spec without a run block, results did not include the spec's description";
- });
-
- it('should queue waits and runs that it encounters while executing specs', function() {
- var specWithRunsAndWaits;
- var foo = 0;
- env.describe('test async spec', function() {
- specWithRunsAndWaits = env.it('spec w/ queued statments', function () {
- this.runs(function () {
- foo++;
- });
- this.waits(500);
- this.runs(function () {
- foo++;
- });
- this.waits(500);
- this.runs(function () {
- foo++;
- });
- });
- });
-
- expect(foo).toEqual(0);
- specWithRunsAndWaits.execute();
-
- expect(foo).toEqual(1);
- fakeTimer.tick(500);
- expect(foo).toEqual(2);
- fakeTimer.tick(500);
- expect(foo).toEqual(3);
- });
-
- it("should run asynchronous tests", function () {
- var foo = 0;
-
- var a_spec;
- env.describe('test async spec', function() {
- a_spec = env.it('spec w/ queued statments', function () {
- this.runs(function () {
- foo++;
- });
- this.runs(function () {
- this.expect(foo).toEqual(1);
- });
- });
- });
-
- a_spec.execute();
-
- expect(a_spec.results().getItems().length).toEqual(1); // 'No call to waits(): Spec queue did not run all functions';
- expect(a_spec.results().getItems()[0].passed()).toEqual(true); // 'No call to waits(): Queued expectation failed';
-
- foo = 0;
- env.describe('test async spec', function() {
- a_spec = env.it('spec w/ queued statments', function () {
- this.runs(function () {
- fakeTimer.setTimeout(function() {
- foo++;
- }, 500);
- });
- this.waits(1000);
- this.runs(function() {
- this.expect(foo).toEqual(1);
- });
- });
- });
-
- a_spec.execute();
-
- expect(a_spec.results().getItems().length).toEqual(0);
-
- fakeTimer.tick(500);
- expect(a_spec.results().getItems().length).toEqual(0);
-
- fakeTimer.tick(500);
- expect(a_spec.results().getItems().length).toEqual(1); // 'Calling waits(): Spec queue did not run all functions';
-
- expect(a_spec.results().getItems()[0].passed()).toEqual(true); // 'Calling waits(): Queued expectation failed';
-
- var bar = 0;
- var another_spec;
- env.describe('test async spec', function() {
- another_spec = env.it('spec w/ queued statments', function () {
- this.runs(function () {
- fakeTimer.setTimeout(function() {
- bar++;
- }, 250);
-
- });
- this.waits(500);
- this.runs(function () {
- fakeTimer.setTimeout(function() {
- bar++;
- }, 250);
- });
- this.waits(500);
- this.runs(function () {
- this.expect(bar).toEqual(2);
- });
- });
- });
-
-
- another_spec.execute();
-
- fakeTimer.tick(1000);
-
- expect(another_spec.results().getItems().length).toEqual(1);
- expect(another_spec.results().getItems()[0].passed()).toEqual(true);
-
- var baz = 0;
- var yet_another_spec;
- env.describe('test async spec', function() {
- yet_another_spec = env.it('spec w/ async fail', function () {
- this.runs(function () {
- fakeTimer.setTimeout(function() {
- baz++;
- }, 250);
- });
- this.waits(100);
- this.runs(function() {
- this.expect(baz).toEqual(1);
- });
- });
- });
-
-
- yet_another_spec.execute();
- //tick twice so that second runs gets eval'd first: mockClock bug?
- fakeTimer.tick(100);
- fakeTimer.tick(150);
-
-
- expect(yet_another_spec.results().getItems().length).toEqual(1);
- expect(yet_another_spec.results().getItems()[0].passed()).toEqual(false);
- });
-
- it("testAsyncSpecsWithMockSuite", function () {
- var bar = 0;
- var another_spec;
- env.describe('test async spec', function() {
- another_spec = env.it('spec w/ queued statments', function () {
- this.runs(function () {
- fakeTimer.setTimeout(function() {
- bar++;
- }, 250);
- });
- this.waits(500);
- this.runs(function () {
- fakeTimer.setTimeout(function() {
- bar++;
- }, 250);
- });
- this.waits(1500);
- this.runs(function() {
- this.expect(bar).toEqual(2);
- });
- });
- });
-
- another_spec.execute();
- fakeTimer.tick(2000);
- expect(another_spec.results().getItems().length).toEqual(1);
- expect(another_spec.results().getItems()[0].passed()).toEqual(true);
- });
-
- describe("waitsFor", function() {
- var latchFunction = function() {
- return true;
- };
- var spec;
-
- function makeWaitsForSpec() {
- var args = jasmine.util.argsToArray(arguments);
- env.describe('suite', function() {
- spec = env.it('spec', function() {
- this.waitsFor.apply(this, args);
- });
- });
- env.execute();
- }
-
- it("should accept args (latchFunction, timeoutMessage, timeout)", function() {
- makeWaitsForSpec(latchFunction, "message", 123);
- var block = spec.queue.blocks[1];
- expect(block.latchFunction).toBe(latchFunction);
- expect(block.timeout).toEqual(123);
- expect(block.message).toEqual('message');
- });
-
- it("should accept args (latchFunction, timeout)", function() {
- makeWaitsForSpec(latchFunction, 123);
- var block = spec.queue.blocks[1];
- expect(block.latchFunction).toBe(latchFunction);
- expect(block.timeout).toEqual(123);
- expect(block.message).toEqual(null);
- });
-
- it("should accept args (latchFunction, timeoutMessage)", function() {
- env.defaultTimeoutInterval = 4321;
- makeWaitsForSpec(latchFunction, "message");
- var block = spec.queue.blocks[1];
- expect(block.latchFunction).toBe(latchFunction);
- expect(block.timeout).toEqual(4321);
- expect(block.message).toEqual('message');
- });
-
- it("should accept args (latchFunction)", function() {
- env.defaultTimeoutInterval = 4321;
- makeWaitsForSpec(latchFunction);
- var block = spec.queue.blocks[1];
- expect(block.latchFunction).toBe(latchFunction);
- expect(block.timeout).toEqual(4321);
- expect(block.message).toEqual(null);
- });
-
- it("should accept deprecated args order (timeout, latchFunction, timeoutMessage)", function() {
- makeWaitsForSpec(123, latchFunction, "message");
- var block = spec.queue.blocks[1];
- expect(block.latchFunction).toBe(latchFunction);
- expect(block.timeout).toEqual(123);
- expect(block.message).toEqual('message');
- });
-
- it("testWaitsFor", function() {
- var doneWaiting = false;
- var runsBlockExecuted = false;
-
- var spec;
- env.describe('foo', function() {
- spec = env.it('has a waits for', function() {
- this.runs(function() {
- });
-
- this.waitsFor(500, function() {
- return doneWaiting;
- });
-
- this.runs(function() {
- runsBlockExecuted = true;
- });
- });
- });
-
- spec.execute();
- expect(runsBlockExecuted).toEqual(false); //, 'should not have executed runs block yet');
- fakeTimer.tick(100);
- doneWaiting = true;
- fakeTimer.tick(100);
- expect(runsBlockExecuted).toEqual(true); //, 'should have executed runs block');
- });
-
- it("fails with message", function() {
- var spec;
- env.describe('foo', function() {
- spec = env.it('has a waits for', function() {
- this.runs(function() {
- });
-
- this.waitsFor(500, function() {
- return false; // force a timeout
- }, 'my awesome condition');
-
- this.runs(function() {
- });
- });
- });
-
- spec.execute();
- fakeTimer.tick(1000);
- expect(spec.results().getItems()[0].message).toEqual('timeout: timed out after 500 msec waiting for my awesome condition');
- });
-
- it("fails and skips the rest of the spec if timeout is reached and the latch function hasn't returned true", function() {
- var runsBlockExecuted = false;
- var subsequentSpecRan = false;
-
- var timeoutSpec, subsequentSpec;
- var suite = env.describe('foo', function() {
- timeoutSpec = env.it('has a waits for', function() {
- this.runs(function() {
- });
-
- this.waitsFor(500, function() {
- return false;
- });
-
- this.runs(function() {
- runsBlockExecuted = true;
- });
- });
-
- subsequentSpec = env.it('then carries on to the next test', function() {
- subsequentSpecRan = true;
- });
- });
-
- env.execute();
- expect(runsBlockExecuted).toEqual(false);
- fakeTimer.tick(100);
- expect(runsBlockExecuted).toEqual(false);
- fakeTimer.tick(400);
- expect(runsBlockExecuted).toEqual(false);
- expect(timeoutSpec.results().getItems()[0].message).toEqual('timeout: timed out after 500 msec waiting for something to happen');
- expect(subsequentSpecRan).toEqual(true);
- });
-
- it("runs afterEach after timing out", function() {
- var afterEach = jasmine.createSpy('afterEach');
-
- env.describe('foo', function () {
- env.afterEach(afterEach);
-
- env.it('waitsFor', function () {
- this.waitsFor(100, function() {
- return false;
- });
- });
- }).execute();
-
- fakeTimer.tick(500);
- expect(afterEach).toHaveBeenCalled();
- });
-
- it("runs single-spec after functions after timing out", function() {
- var after = jasmine.createSpy('after');
-
- env.describe('foo', function () {
- env.it('waitsFor', function () {
- this.after(after);
- this.waitsFor(100, function() {
- return false;
- });
- });
- }).execute();
-
- fakeTimer.tick(500);
- expect(after).toHaveBeenCalled();
- });
-
- describe('with consecutive calls', function () {
- var foo;
- beforeEach(function () {
- foo = 0;
- });
-
- it('exits immediately (does not stack) if the latchFunction times out', function () {
- var reachedFirstWaitsFor = false;
- var reachedSecondWaitsFor = false;
- env.describe('suite that waits', function () {
- env.it('should stack timeouts', function() {
- this.waitsFor(500, function () {
- reachedFirstWaitsFor = true;
- return false;
- });
- this.waitsFor(500, function () {
- reachedSecondWaitsFor = true;
- });
- this.runs(function () {
- foo++;
- });
- });
- });
-
- expect(reachedFirstWaitsFor).toEqual(false);
- env.execute();
-
- expect(reachedFirstWaitsFor).toEqual(true);
- expect(foo).toEqual(0);
- expect(reachedSecondWaitsFor).toEqual(false);
- fakeTimer.tick(500);
- expect(reachedSecondWaitsFor).toEqual(false);
- expect(foo).toEqual(0);
- fakeTimer.tick(500);
- expect(reachedSecondWaitsFor).toEqual(false);
- expect(foo).toEqual(0);
- });
-
- it('stacks latchFunctions', function () {
- var firstWaitsResult = false;
- var secondWaitsResult = false;
- var waitsSuite = env.describe('suite that waits', function () {
- env.it('spec with waitsFors', function() {
- this.waitsFor(600, function () {
- fakeTimer.setTimeout(function () {
- firstWaitsResult = true;
- }, 300);
- return firstWaitsResult;
- });
- this.waitsFor(600, function () {
- fakeTimer.setTimeout(function () {
- secondWaitsResult = true;
- }, 300);
- return secondWaitsResult;
- });
- this.runs(function () {
- foo++;
- });
- });
- });
-
- expect(firstWaitsResult).toEqual(false);
- expect(secondWaitsResult).toEqual(false);
- waitsSuite.execute();
-
- expect(firstWaitsResult).toEqual(false);
- expect(secondWaitsResult).toEqual(false);
- expect(foo).toEqual(0);
-
- fakeTimer.tick(300);
-
- expect(firstWaitsResult).toEqual(true);
- expect(secondWaitsResult).toEqual(false);
- expect(foo).toEqual(0);
-
- fakeTimer.tick(300);
-
- expect(firstWaitsResult).toEqual(true);
- expect(secondWaitsResult).toEqual(true);
- expect(foo).toEqual(1);
-
- });
- });
- });
-
- it("testSpecAfter", function() {
- var log = "";
- var spec;
- var suite = env.describe("has after", function() {
- spec = env.it('spec with after', function() {
- this.runs(function() {
- log += "spec";
- });
- });
- });
- spec.after(function() {
- log += "after1";
- });
- spec.after(function() {
- log += "after2";
- });
-
- suite.execute();
-
- expect(log).toEqual("specafter2after1");
- });
-
- describe('test suite declaration', function() {
- var suite;
- var dummyFunction = function() {
- };
-
- it('should give the suite a description', function() {
- suite = env.describe('one suite description', dummyFunction);
- expect(suite.description).toEqual('one suite description');
- });
-
- it('should enqueue functions for multipart tests and support waits, and run any ready runs() blocks', function() {
- var foo = 0;
- var bar = 0;
-
- suite = env.describe('one suite description', function () {
- env.it('should be a test with queuedFunctions', function() {
- this.runs(function() {
- foo++;
- });
- this.waits(100);
- this.runs(function() {
- bar++;
- });
- });
- });
-
- suite.execute();
-
- expect(foo).toEqual(1);
- expect(bar).toEqual(0);
-
- fakeTimer.tick(100);
- expect(bar).toEqual(1);
- });
-
- });
-
- it("testBeforeAndAfterCallbacks", function () {
- var suiteWithBefore = env.describe('one suite with a before', function () {
-
- this.beforeEach(function () {
- this.foo = 1;
- });
-
- env.it('should be a spec', function () {
- this.runs(function() {
- this.foo++;
- this.expect(this.foo).toEqual(2);
- });
- });
-
- env.it('should be another spec', function () {
- this.runs(function() {
- this.foo++;
- this.expect(this.foo).toEqual(2);
- });
- });
- });
-
- suiteWithBefore.execute();
-
- var suite = suiteWithBefore;
-
- expect(suite.results().getItems()[0].passed()).toEqual(true); // "testBeforeAndAfterCallbacks: the first spec's foo should have been 2");
- expect(suite.results().getItems()[1].passed()).toEqual(true); // "testBeforeAndAfterCallbacks: the second spec's this.foo should have been 2");
-
-
- var foo = 1;
- var suiteWithAfter = env.describe('one suite with an after_each', function () {
-
- env.it('should be a spec with an after_each', function () {
- this.expect(foo).toEqual(1);
- foo++;
- this.expect(foo).toEqual(2);
- });
-
- env.it('should be another spec with an after_each', function () {
- this.expect(foo).toEqual(0);
- foo++;
- this.expect(foo).toEqual(1);
- });
-
- this.afterEach(function () {
- foo = 0;
- });
- });
-
- suiteWithAfter.execute();
-
- suite = suiteWithAfter;
- expect(suite.afterEach.length).toEqual(1);
- expect(suite.results().getItems()[0].passed()).toEqual(true);
- expect(suite.results().getItems()[1].passed()).toEqual(true);
- expect(foo).toEqual(0);
-
- });
-
- it('#waits should allow consecutive waits calls', function () {
- var foo = 0;
- var waitsSuite = env.describe('suite that waits', function () {
- env.it('should wait', function() {
- this.waits(500);
- this.waits(500);
- this.runs(function () {
- foo++;
- });
- });
- });
-
- waitsSuite.execute();
- expect(foo).toEqual(0);
- fakeTimer.tick(500);
- expect(foo).toEqual(0);
- fakeTimer.tick(500);
-
- expect(foo).toEqual(1);
- });
-
it('nested suites', function () {
var foo = 0;
@@ -696,271 +71,15 @@ describe("jasmine spec running", function () {
expect(quux).toEqual(1);
});
- it("#beforeEach should be able to eval runs and waits blocks", function () {
- var foo = 0;
- var bar = 0;
- var suiteWithBefore = env.describe('one suite with a before', function () {
- this.beforeEach(function () {
- this.runs(function () {
- foo++;
- });
- this.waits(500);
- this.runs(function () {
- foo++;
- });
- this.waits(500);
- });
-
- env.it('should be a spec', function () {
- bar = 1;
- foo++;
- });
-
- });
-
- expect(foo).toEqual(0);
- expect(bar).toEqual(0);
- suiteWithBefore.execute();
-
- expect(bar).toEqual(0);
- expect(foo).toEqual(1);
- fakeTimer.tick(500);
-
- expect(bar).toEqual(0);
- expect(foo).toEqual(2);
- fakeTimer.tick(500);
- expect(bar).toEqual(1);
- expect(foo).toEqual(3);
- });
-
- it("#afterEach should be able to eval runs and waits blocks", function () {
- var foo = 0;
- var firstSpecHasRun = false;
- var secondSpecHasRun = false;
- var suiteWithAfter = env.describe('one suite with a before', function () {
- this.afterEach(function () {
- this.waits(500);
- this.runs(function () {
- foo++;
- });
- this.waits(500);
- });
-
- env.it('should be the first spec', function () {
- firstSpecHasRun = true;
- });
-
- env.it('should be a spec', function () {
- secondSpecHasRun = true;
- foo++;
- });
-
- });
-
- expect(firstSpecHasRun).toEqual(false);
- expect(secondSpecHasRun).toEqual(false);
- expect(foo).toEqual(0);
-
- suiteWithAfter.execute();
-
-
- expect(firstSpecHasRun).toEqual(true);
- expect(secondSpecHasRun).toEqual(false);
- expect(foo).toEqual(0);
-
- fakeTimer.tick(500);
-
- expect(foo).toEqual(1);
- expect(secondSpecHasRun).toEqual(false);
- fakeTimer.tick(500);
-
- expect(foo).toEqual(2);
- expect(secondSpecHasRun).toEqual(true);
-
- });
-
- it("Spec#after should be able to eval runs and waits blocks", function () {
- var runsBeforeAfter = false;
- var firstSpecHasRun = false;
- var secondSpecHasRun = false;
- var afterHasRun = false;
- var suiteWithAfter = env.describe('one suite with a before', function () {
-
- env.it('should be the first spec', function () {
- firstSpecHasRun = true;
- this.after(function () {
- this.waits(500);
- this.runs(function () {
- afterHasRun = true;
- });
- this.waits(500);
- }, true);
- this.waits(500);
- this.runs(function () {
- runsBeforeAfter = true;
- });
- });
-
- env.it('should be a spec', function () {
- secondSpecHasRun = true;
- });
-
- });
-
- expect(firstSpecHasRun).toEqual(false);
- expect(runsBeforeAfter).toEqual(false);
- expect(afterHasRun).toEqual(false);
- expect(secondSpecHasRun).toEqual(false);
-
- suiteWithAfter.execute();
-
- expect(firstSpecHasRun).toEqual(true);
- expect(runsBeforeAfter).toEqual(false);
- expect(afterHasRun).toEqual(false);
- expect(secondSpecHasRun).toEqual(false);
-
- fakeTimer.tick(500);
-
- expect(firstSpecHasRun).toEqual(true);
- expect(runsBeforeAfter).toEqual(true);
- expect(afterHasRun).toEqual(false);
- expect(secondSpecHasRun).toEqual(false);
-
- fakeTimer.tick(500);
-
- expect(firstSpecHasRun).toEqual(true);
- expect(runsBeforeAfter).toEqual(true);
- expect(afterHasRun).toEqual(true);
- expect(secondSpecHasRun).toEqual(false);
-
- fakeTimer.tick(500);
-
- expect(firstSpecHasRun).toEqual(true);
- expect(runsBeforeAfter).toEqual(true);
- expect(afterHasRun).toEqual(true);
- expect(secondSpecHasRun).toEqual(true);
- });
-
- it("handles waits", function () {
- var firstSpecHasRun = false;
- var secondSpecHasRun = false;
- var suiteWithAfter = env.describe('one suite with a before', function () {
-
- env.it('should be the first spec', function () {
- this.waits(500);
- this.runs(function () {
- firstSpecHasRun = true;
- });
- });
-
- env.it('should be a spec', function () {
- secondSpecHasRun = true;
- });
-
- });
-
- expect(firstSpecHasRun).toEqual(false);
- expect(secondSpecHasRun).toEqual(false);
-
- suiteWithAfter.execute();
-
- expect(firstSpecHasRun).toEqual(false);
- expect(secondSpecHasRun).toEqual(false);
-
- fakeTimer.tick(500);
-
- expect(firstSpecHasRun).toEqual(true);
- expect(secondSpecHasRun).toEqual(true);
- });
-
- it("testBeforeExecutesSafely", function() {
- var report = "";
- var suite = env.describe('before fails on first test, passes on second', function() {
- var counter = 0;
- this.beforeEach(function() {
- counter++;
- if (counter == 1) {
- throw "before failure";
- }
- });
- env.it("first should not run because before fails", function() {
- this.runs(function() {
- report += "first";
- this.expect(true).toEqual(true);
- });
- });
- env.it("second should run and pass because before passes", function() {
- this.runs(function() {
- report += "second";
- this.expect(true).toEqual(true);
- });
- });
- });
-
- suite.execute();
-
- expect(report).toEqual("firstsecond");
- var suiteResults = suite.results();
- expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(false);
- expect(suiteResults.getItems()[1].getItems()[0].passed()).toEqual(true);
- });
-
- it("testAfterExecutesSafely", function() {
- var report = "";
- var suite = env.describe('after fails on first test, then passes', function() {
- var counter = 0;
- this.afterEach(function() {
- counter++;
- if (counter == 1) {
- throw "after failure";
- }
- });
- env.it("first should run, expectation passes, but spec fails because after fails", function() {
- this.runs(function() {
- report += "first";
- this.expect(true).toEqual(true);
- });
- });
- env.it("second should run and pass because after passes", function() {
- this.runs(function() {
- report += "second";
- this.expect(true).toEqual(true);
- });
- });
- env.it("third should run and pass because after passes", function() {
- this.runs(function() {
- report += "third";
- this.expect(true).toEqual(true);
- });
- });
- });
-
- suite.execute();
-
- expect(report).toEqual("firstsecondthird"); // "all tests should run");
- //After each errors should not go in spec results because it confuses the count.
- var suiteResults = suite.results();
- expect(suiteResults.getItems().length).toEqual(3, 'testAfterExecutesSafely should have results for three specs');
-
- expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 1st spec should pass");
- expect(suiteResults.getItems()[1].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 2nd spec should pass");
- expect(suiteResults.getItems()[2].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 3rd spec should pass");
-
- expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 1st result for 1st suite spec should pass");
- expect(suiteResults.getItems()[0].getItems()[1].passed()).toEqual(false, "testAfterExecutesSafely 2nd result for 1st suite spec should fail because afterEach failed");
- expect(suiteResults.getItems()[1].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 2nd suite spec should pass");
- expect(suiteResults.getItems()[2].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 3rd suite spec should pass");
- });
-
it("should permit nested describes", function() {
var actions = [];
env.beforeEach(function () {
- actions.push('runner beforeEach');
+ actions.push('topSuite beforeEach');
});
env.afterEach(function () {
- actions.push('runner afterEach');
+ actions.push('topSuite afterEach');
});
env.describe('Something', function() {
@@ -1013,33 +132,33 @@ describe("jasmine spec running", function () {
var expected = [
- "runner beforeEach",
+ "topSuite beforeEach",
"outer beforeEach",
"outer it 1",
"outer afterEach",
- "runner afterEach",
+ "topSuite afterEach",
- "runner beforeEach",
+ "topSuite beforeEach",
"outer beforeEach",
"inner 1 beforeEach",
"inner 1 it",
"inner 1 afterEach",
"outer afterEach",
- "runner afterEach",
+ "topSuite afterEach",
- "runner beforeEach",
+ "topSuite beforeEach",
"outer beforeEach",
"outer it 2",
"outer afterEach",
- "runner afterEach",
+ "topSuite afterEach",
- "runner beforeEach",
+ "topSuite beforeEach",
"outer beforeEach",
"inner 2 beforeEach",
"inner 2 it",
"inner 2 afterEach",
"outer afterEach",
- "runner afterEach"
+ "topSuite afterEach"
];
expect(actions).toEqual(expected);
});
@@ -1101,146 +220,34 @@ describe("jasmine spec running", function () {
expect(actions).toEqual(expected);
});
- it("builds up nested names", function() {
- var nestedSpec;
- env.describe('Test Subject', function() {
- env.describe('when under circumstance A', function() {
- env.describe('and circumstance B', function() {
- nestedSpec = env.it('behaves thusly', function() {
- });
- });
+ it("shouldn't run disabled suites", function() {
+ var specInADisabledSuite = originalJasmine.createSpy("specInADisabledSuite"),
+ suite = env.describe('A Suite', function() {
+ env.xdescribe('with a disabled suite', function(){
+ env.it('disabled spec', specInADisabledSuite);
});
});
- expect(nestedSpec.getFullName()).toEqual('Test Subject when under circumstance A and circumstance B behaves thusly.'); //, "Spec.fullName was incorrect: " + nestedSpec.getFullName());
- });
-
- it("should skip empty suites", function () {
- env.describe('NonEmptySuite1', function() {
- env.it('should pass', function() {
- this.expect(true).toEqual(true);
- });
- env.describe('NestedEmptySuite', function() {
- });
- env.it('should pass', function() {
- this.expect(true).toEqual(true);
- });
- });
-
- env.describe('EmptySuite', function() {
- });
-
- env.describe('NonEmptySuite2', function() {
- env.it('should pass', function() {
- this.expect(true).toEqual(true);
- });
- });
-
- env.execute();
-
- var runnerResults = env.currentRunner_.results();
- expect(runnerResults.totalCount).toEqual(3);
- expect(runnerResults.passedCount).toEqual(3);
- expect(runnerResults.failedCount).toEqual(0);
- });
-
- it("should bind 'this' to the running spec within the spec body", function() {
- var spec;
- var suite = env.describe('one suite description', function () {
- env.it('should be a test with queuedFunctions', function() {
- spec = this.runs(function() {
- this.foo = 0;
- this.foo++;
- });
-
- this.runs(function() {
- var that = this;
- fakeTimer.setTimeout(function() {
- that.foo++;
- }, 250);
- });
-
- this.runs(function() {
- this.expect(this.foo).toEqual(2);
- });
-
- this.waits(300);
-
- this.runs(function() {
- this.expect(this.foo).toEqual(2);
- });
- });
-
- });
-
suite.execute();
- fakeTimer.tick(600);
- expect(spec.foo).toEqual(2);
- var suiteResults = suite.results();
- expect(suiteResults.getItems()[0].getItems().length).toEqual(2);
- expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(false);
- expect(suiteResults.getItems()[0].getItems()[1].passed()).toEqual(true);
+
+ expect(specInADisabledSuite).not.toHaveBeenCalled();
});
it("shouldn't run disabled tests", function() {
- var xitSpecWasRun = false;
- var suite = env.describe('default current suite', function() {
- env.xit('disabled spec').runs(function () {
- xitSpecWasRun = true;
- });
-
- env.it('enabled spec').runs(function () {
- var foo = 'bar';
- expect(foo).toEqual('bar');
- });
+ var disabledSpec = originalJasmine.createSpy('disabledSpec'),
+ suite = env.describe('default current suite', function() {
+ env.xit('disabled spec', disabledSpec);
});
-
suite.execute();
- expect(xitSpecWasRun).toEqual(false);
+ expect(disabledSpec).not.toHaveBeenCalled();
});
- it('shouldn\'t execute specs in disabled suites', function() {
- var spy = jasmine.createSpy();
- var disabledSuite = env.xdescribe('a disabled suite', function() {
- env.it('enabled spec, but should not be run', function() {
- spy();
- });
- });
-
- disabledSuite.execute();
-
- expect(spy).not.toHaveBeenCalled();
- });
-
- it('#explodes should throw an exception when it is called inside a spec', function() {
- var exceptionMessage = false;
- var anotherSuite = env.describe('Spec', function () {
- env.it('plodes', function() {
- try {
- this.explodes();
- }
- catch (e) {
- exceptionMessage = e;
- }
- expect(exceptionMessage).toNotEqual(false);
- });
- });
-
- anotherSuite.execute();
-
- expect(exceptionMessage).toEqual('explodes function should not have been called');
- });
-
- it("should recover gracefully when there are errors in describe functions", function() {
+ // TODO: is this useful? It doesn't catch syntax errors
+ xit("should recover gracefully when there are errors in describe functions", function() {
var specs = [];
var superSimpleReporter = new jasmine.Reporter();
- superSimpleReporter.reportSpecResults = function(spec) {
- specs.push("Spec: " + spec.getFullName());
- var results = spec.results().getItems();
- for (var i = 0; i < results.length; i++) {
- var result = results[i];
- specs.push("Result: " + result);
- }
+ superSimpleReporter.reportSpecResults = function(result) {
+ specs.push("Spec: " + result.fullName);
};
try {
@@ -1276,16 +283,11 @@ describe("jasmine spec running", function () {
expect(specs.join('')).toMatch(new RegExp(
'Spec: outer1 inner1 should thingy.' +
- 'Result: Passed.' +
- 'Spec: outer1 inner1 encountered a declaration exception.' +
- 'Result: Error: fake error.*' +
- 'Spec: outer1 inner2 should other thingy.' +
- 'Result: Passed.' +
- 'Spec: outer1 encountered a declaration exception.' +
- 'Result: Error: fake error.*' +
- 'Spec: outer2 should xxx.' +
- 'Result: Passed.'
- ));
- });
+ 'Spec: outer1 inner1 encountered a declaration exception.' +
+ 'Spec: outer1 inner2 should other thingy.' +
+ 'Spec: outer1 encountered a declaration exception.' +
+ 'Spec: outer2 should xxx.'
+ ));
-});
+ });
+});
\ No newline at end of file
diff --git a/spec/core/SpecSpec.js b/spec/core/SpecSpec.js
index 1e4a22d4..949b81cb 100644
--- a/spec/core/SpecSpec.js
+++ b/spec/core/SpecSpec.js
@@ -1,124 +1,184 @@
-describe('Spec', function () {
- var env, suite;
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
- suite = new jasmine.Suite(env, 'suite 1');
+describe("Spec", function() {
+
+ it("delegates execution to a QueueRunner", function() {
+ var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
+ spec = new jasmine.Spec({
+ description: 'my test',
+ id: 'some-id',
+ fn: function() {},
+ queueRunner: fakeQueueRunner
+ });
+
+ spec.execute();
+
+ expect(fakeQueueRunner).toHaveBeenCalled();
});
- describe('initialization', function () {
+ it("should call the start callback on execution", function() {
+ var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
+ beforesWereCalled = false,
+ startCallback = originalJasmine.createSpy('startCallback'),
+ spec = new jasmine.Spec({
+ id: 123,
+ description: 'foo bar',
+ fn: function() {},
+ onStart: startCallback,
+ queueRunner: fakeQueueRunner
+ });
- it('should raise an error if an env is not passed', function () {
- try {
- new jasmine.Spec();
- }
- catch (e) {
- expect(e.message).toEqual('jasmine.Env() required');
- }
- });
+ spec.execute();
- it('should raise an error if a suite is not passed', function () {
- try {
- new jasmine.Spec(env);
- }
- catch (e) {
- expect(e.message).toEqual('jasmine.Suite() required');
- }
- });
+ expect(startCallback).toHaveBeenCalledWith(spec);
+ });
- it('should assign sequential ids for specs belonging to the same env', function () {
- var spec1 = new jasmine.Spec(env, suite);
- var spec2 = new jasmine.Spec(env, suite);
- var spec3 = new jasmine.Spec(env, suite);
- expect(spec1.id).toEqual(0);
- expect(spec2.id).toEqual(1);
- expect(spec3.id).toEqual(2);
+ it("should call the start callback on execution but before any befores are called", function() {
+ var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
+ beforesWereCalled = false,
+ startCallback = originalJasmine.createSpy('start-callback').andCallFake(function() {
+ expect(beforesWereCalled).toBe(false);
+ }),
+ spec = new jasmine.Spec({
+ fn: function() {},
+ beforeFns: function() {
+ return [function() {
+ beforesWereCalled = true
+ }]
+ },
+ onStart: startCallback,
+ queueRunner: fakeQueueRunner
+ });
+
+ spec.execute();
+
+ expect(startCallback).toHaveBeenCalled();
+ });
+
+ it("provides all before fns and after fns to be run", function() {
+ var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
+ before = originalJasmine.createSpy('before'),
+ after = originalJasmine.createSpy('after'),
+ fn = originalJasmine.createSpy('test body').andCallFake(function() {
+ expect(before).toHaveBeenCalled();
+ expect(after).not.toHaveBeenCalled();
+ }),
+ spec = new jasmine.Spec({
+ fn: fn,
+ beforeFns: function() {
+ return [before]
+ },
+ afterFns: function() {
+ return [after]
+ },
+ queueRunner: fakeQueueRunner
+ });
+
+ spec.execute();
+
+ var allSpecFns = fakeQueueRunner.mostRecentCall.args[0].fns;
+ expect(allSpecFns).toEqual([before, fn, after]);
+ });
+
+ it("can be disabled, but still calls callbacks", function() {
+ var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
+
+ startCallback = originalJasmine.createSpy('startCallback'),
+ specBody = originalJasmine.createSpy('specBody'),
+ resultCallback = originalJasmine.createSpy('resultCallback'),
+ spec = new jasmine.Spec({
+ onStart:startCallback,
+ fn: specBody,
+ resultCallback: resultCallback,
+ queueRunner: fakeQueueRunner
+ });
+
+ spec.disable();
+
+ expect(spec.status()).toBe('disabled');
+
+ spec.execute();
+
+ expect(startCallback).not.toHaveBeenCalled();
+ expect(fakeQueueRunner).not.toHaveBeenCalled();
+ expect(specBody).not.toHaveBeenCalled();
+
+ expect(resultCallback).toHaveBeenCalled();
+ });
+
+ it("should call the results callback on execution complete", function() {
+ var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
+
+ startCallback = originalJasmine.createSpy('startCallback'),
+ specBody = originalJasmine.createSpy('specBody'),
+ resultCallback = originalJasmine.createSpy('resultCallback'),
+ spec = new jasmine.Spec({
+ onStart:startCallback,
+ fn: specBody,
+ resultCallback: resultCallback,
+ description: "with a spec",
+ getSpecName: function() { return "a suite with a spec"},
+ queueRunner: fakeQueueRunner
+ });
+
+ spec.disable();
+
+ expect(spec.status()).toBe('disabled');
+
+ spec.execute();
+
+ expect(startCallback).not.toHaveBeenCalled();
+ expect(fakeQueueRunner).not.toHaveBeenCalled();
+ expect(specBody).not.toHaveBeenCalled();
+
+ expect(resultCallback).toHaveBeenCalledWith({
+ id: spec.id,
+ status: 'disabled',
+ description: 'with a spec',
+ fullName: 'a suite with a spec',
+ failedExpectations: []
});
});
- it('getFullName returns suite & spec description', function () {
- var spec = new jasmine.Spec(env, suite, 'spec 1');
- expect(spec.getFullName()).toEqual('suite 1 spec 1.');
+ it("should call the done callback on execution complete", function() {
+ var done = originalJasmine.createSpy('done callback'),
+ spec = new jasmine.Spec({
+ fn: function() {},
+ catchExceptions: function() { return false; },
+ resultCallback: function() {},
+ queueRunner: function(attrs) { attrs.onComplete(); }
+ });
+
+ spec.execute(done);
+
+ expect(done).toHaveBeenCalled();
});
- describe('results', function () {
- var spec, results;
- beforeEach(function () {
- spec = new jasmine.Spec(env, suite);
- results = spec.results();
- expect(results.totalCount).toEqual(0);
- spec.runs(function () {
- this.expect(true).toEqual(true);
- this.expect(true).toEqual(true);
- });
- });
-
-
- it('results shows the total number of expectations for each spec after execution', function () {
- expect(results.totalCount).toEqual(0);
- spec.execute();
- expect(results.totalCount).toEqual(2);
- });
-
- it('results shows the number of passed expectations for each spec after execution', function () {
- expect(results.passedCount).toEqual(0);
- spec.execute();
- expect(results.passedCount).toEqual(2);
- });
-
- it('results shows the number of failed expectations for each spec after execution', function () {
- spec.runs(function () {
- this.expect(true).toEqual(false);
- });
- expect(results.failedCount).toEqual(0);
- spec.execute();
- expect(results.failedCount).toEqual(1);
- });
-
- describe('results.passed', function () {
- it('is true if all spec expectations pass', function () {
- spec.runs(function () {
- this.expect(true).toEqual(true);
- });
- spec.execute();
- expect(results.passed()).toEqual(true);
- });
-
- it('is false if one spec expectation fails', function () {
- spec.runs(function () {
- this.expect(true).toEqual(false);
- });
- spec.execute();
- expect(results.passed()).toEqual(false);
- });
-
- it('a spec with no expectations will return true', function () {
- var specWithoutExpectations = new jasmine.Spec(env, suite);
- specWithoutExpectations.runs(function() {
-
- });
- specWithoutExpectations.execute();
- expect(results.passed()).toEqual(true);
- });
-
- it('an unexecuted spec will return true', function () {
- expect(results.passed()).toEqual(true);
- });
- });
-
- it("includes log messages, which may contain arbitary objects", function() {
- spec.runs(function() {
- this.log("here's some log message", {key: 'value'}, 123);
- });
- spec.execute();
- var items = results.getItems();
- expect(items).toEqual([
- jasmine.any(jasmine.ExpectationResult),
- jasmine.any(jasmine.ExpectationResult),
- jasmine.any(jasmine.MessageResult)
- ]);
- var logResult = items[2];
- expect(logResult.values).toEqual(["here's some log message", {key: 'value'}, 123]);
- });
+ it("#status returns null by default", function() {
+ var spec = new jasmine.Spec({});
+ expect(spec.status()).toBeNull();
});
-});
\ No newline at end of file
+
+ it("#status returns passed if all expectations in the spec have passed", function() {
+ var spec = new jasmine.Spec({});
+ spec.addExpectationResult(true);
+ expect(spec.status()).toBe('passed');
+ });
+
+ it("#status returns failed if any expectations in the spec have failed", function() {
+ var spec = new jasmine.Spec({});
+ spec.addExpectationResult(true);
+ spec.addExpectationResult(false);
+ expect(spec.status()).toBe('failed');
+ });
+
+ it("can return its full name", function() {
+ var spec;
+ spec = new jasmine.Spec({
+ getSpecName: function(passedVal) {
+// expect(passedVal).toBe(spec); TODO: a exec time, spec is undefined WTF?
+ return 'expected val';
+ }
+ });
+
+ expect(spec.getFullName()).toBe('expected val');
+ });
+});
diff --git a/spec/core/SpySpec.js b/spec/core/SpySpec.js
index 90439c4e..8d477895 100644
--- a/spec/core/SpySpec.js
+++ b/spec/core/SpySpec.js
@@ -1,4 +1,9 @@
describe('Spies', function () {
+ var env;
+ beforeEach(function() {
+ env = new jasmine.Env();
+ });
+
it('should replace the specified function with a spy object', function() {
var originalFunctionWasCalled = false;
var TestClass = {
@@ -6,11 +11,13 @@ describe('Spies', function () {
originalFunctionWasCalled = true;
}
};
- this.spyOn(TestClass, 'someFunction');
+ env.spyOn(TestClass, 'someFunction');
expect(TestClass.someFunction.wasCalled).toEqual(false);
expect(TestClass.someFunction.callCount).toEqual(0);
+
TestClass.someFunction('foo');
+
expect(TestClass.someFunction.wasCalled).toEqual(true);
expect(TestClass.someFunction.callCount).toEqual(1);
expect(TestClass.someFunction.mostRecentCall.args).toEqual(['foo']);
@@ -29,7 +36,7 @@ describe('Spies', function () {
originalFunctionWasCalled = true;
}
};
- this.spyOn(TestClass, 'someFunction');
+ env.spyOn(TestClass, 'someFunction');
TestClass.someFunction('foo');
TestClass.someFunction('bar');
@@ -51,7 +58,7 @@ describe('Spies', function () {
}
};
- this.spyOn(TestClass, 'someFunction').andCallThrough();
+ env.spyOn(TestClass, 'someFunction').andCallThrough();
var result = TestClass.someFunction('arg1', 'arg2');
expect(result).toEqual("return value from original function");
expect(originalFunctionWasCalled).toEqual(true);
@@ -69,7 +76,7 @@ describe('Spies', function () {
}
};
- this.spyOn(TestClass, 'someFunction').andReturn("some value");
+ env.spyOn(TestClass, 'someFunction').andReturn("some value");
originalFunctionWasCalled = false;
var result = TestClass.someFunction('arg1', 'arg2');
expect(result).toEqual("some value");
@@ -85,7 +92,7 @@ describe('Spies', function () {
}
};
- this.spyOn(TestClass, 'someFunction').andThrow(new Error('fake error'));
+ env.spyOn(TestClass, 'someFunction').andThrow(new Error('fake error'));
var exception;
try {
TestClass.someFunction('arg1', 'arg2');
@@ -108,7 +115,7 @@ describe('Spies', function () {
}
};
- this.spyOn(TestClass, 'someFunction').andCallFake(function() {
+ env.spyOn(TestClass, 'someFunction').andCallFake(function() {
fakeFunctionWasCalled = true;
passedArgs = arguments;
passedObj = this;
@@ -124,65 +131,78 @@ describe('Spies', function () {
expect(TestClass.someFunction.wasCalled).toEqual(true);
});
- it('is torn down when this.removeAllSpies is called', function() {
- var originalFunctionWasCalled = false;
- var TestClass = {
+ it('is torn down when env.removeAllSpies is called', function() {
+ var originalFunctionWasCalled = false,
+ env = new jasmine.Env(),
+ TestClass = {
someFunction: function() {
originalFunctionWasCalled = true;
}
};
- this.spyOn(TestClass, 'someFunction');
+ env.spyOn(TestClass, 'someFunction');
TestClass.someFunction('foo');
expect(originalFunctionWasCalled).toEqual(false);
- this.removeAllSpies();
+ env.removeAllSpies();
TestClass.someFunction('foo');
expect(originalFunctionWasCalled).toEqual(true);
});
it('calls removeAllSpies during spec finish', function() {
- var test = new jasmine.Spec(new jasmine.Env(), {}, 'sample test');
+ var env = new jasmine.Env(),
+ originalFoo = function() {},
+ testObj = {
+ foo: originalFoo
+ },
+ firstSpec = originalJasmine.createSpy('firstSpec').andCallFake(function() {
+ env.spyOn(testObj, 'foo');
+ }),
+ secondSpec = originalJasmine.createSpy('secondSpec').andCallFake(function() {
+ expect(testObj.foo).toBe(originalFoo);
+ });
+ env.describe('test suite', function() {
+ env.it('spec 0', firstSpec);
+ env.it('spec 1', secondSpec);
+ });
- this.spyOn(test, 'removeAllSpies');
-
- test.finish();
-
- expect(test.removeAllSpies).wasCalled();
+ env.execute();
+ expect(firstSpec).toHaveBeenCalled();
+ expect(secondSpec).toHaveBeenCalled();
});
it('throws an exception when some method is spied on twice', function() {
var TestClass = { someFunction: function() {
} };
- this.spyOn(TestClass, 'someFunction');
+ env.spyOn(TestClass, 'someFunction');
var exception;
try {
- this.spyOn(TestClass, 'someFunction');
+ env.spyOn(TestClass, 'someFunction');
} catch (e) {
exception = e;
}
expect(exception).toBeDefined();
});
-
- it('to spy on an undefined method throws exception', function() {
- var TestClass = {
- someFunction : function() {
- }
- };
- function efunc() {
- this.spyOn(TestClass, 'someOtherFunction');
- };
- expect(function() {
- efunc();
- }).toThrow('someOtherFunction() method does not exist');
-
- });
+
+ it('to spy on an undefined method throws exception', function() {
+ var TestClass = {
+ someFunction : function() {
+ }
+ };
+ function efunc() {
+ env.spyOn(TestClass, 'someOtherFunction');
+ };
+ expect(function() {
+ efunc();
+ }).toThrow('someOtherFunction() method does not exist');
+
+ });
it('should be able to reset a spy', function() {
var TestClass = { someFunction: function() {} };
- this.spyOn(TestClass, 'someFunction');
+ env.spyOn(TestClass, 'someFunction');
expect(TestClass.someFunction).not.toHaveBeenCalled();
TestClass.someFunction();
@@ -195,7 +215,7 @@ describe('Spies', function () {
describe("createSpyObj", function() {
it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() {
var spyObj = jasmine.createSpyObj('BaseName', ['method1', 'method2']);
- expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
+ expect(spyObj).toEqual({ method1: originalJasmine.any(Function), method2: originalJasmine.any(Function)});
expect(spyObj.method1.identity).toEqual('BaseName.method1');
expect(spyObj.method2.identity).toEqual('BaseName.method2');
});
diff --git a/spec/core/SuiteSpec.js b/spec/core/SuiteSpec.js
index d48ef39c..b09e4f62 100644
--- a/spec/core/SuiteSpec.js
+++ b/spec/core/SuiteSpec.js
@@ -1,120 +1,230 @@
-describe('Suite', function() {
- var fakeTimer;
- var env;
+describe("Suite", function() {
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
-
- fakeTimer = new jasmine.FakeTimer();
- env.setTimeout = fakeTimer.setTimeout;
- env.clearTimeout = fakeTimer.clearTimeout;
- env.setInterval = fakeTimer.setInterval;
- env.clearInterval = fakeTimer.clearInterval;
- });
-
- describe('Specs', function () {
- var suite;
-
- beforeEach(function() {
- suite = env.describe('Suite 1', function () {
- env.it('Spec 1', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- env.it('Spec 2', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- env.describe('Suite 2', function () {
- env.it('Spec 3', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- });
- env.it('Spec 4', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- });
- });
-
- it('#specs should return all immediate children that are specs.', function () {
- var suiteSpecs = suite.specs();
- expect(suiteSpecs.length).toEqual(3);
- expect(suiteSpecs[0].description).toEqual('Spec 1');
- expect(suiteSpecs[1].description).toEqual('Spec 2');
- expect(suiteSpecs[2].description).toEqual('Spec 4');
- });
-
- it("#suites should return all immediate children that are suites.", function() {
- var nestedSuites = suite.suites();
- expect(nestedSuites.length).toEqual(1);
- expect(nestedSuites[0].description).toEqual('Suite 2');
- });
-
- it("#children should return all immediate children including suites and specs.", function() {
- var children = suite.children();
- expect(children.length).toEqual(4);
- expect(children[0].description).toEqual('Spec 1');
- expect(children[1].description).toEqual('Spec 2');
- expect(children[2].description).toEqual('Suite 2');
- expect(children[3].description).toEqual('Spec 4');
- });
- });
-
- describe('SpecCount', function () {
-
- it('should keep a count of the number of specs that are run', function() {
- var suite = env.describe('one suite description', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- env.it('should be another test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- env.it('should be a third test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
+ it("keeps its id", function() {
+ var env = new jasmine.Env(),
+ suite = new jasmine.Suite({
+ env: env,
+ id: 456,
+ description: "I am a suite"
});
- expect(suite.specs().length).toEqual(3);
- });
+ expect(suite.id).toEqual(456);
+ });
- it('specCount should be correct even with runs/waits blocks', function() {
- var suite = env.describe('one suite description', function () {
- env.it('should be a test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- env.it('should be another test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- this.waits(10);
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
- env.it('should be a third test', function() {
- this.runs(function () {
- this.expect(true).toEqual(true);
- });
- });
+ it("returns its full name", function() {
+ var env = new jasmine.Env(),
+ suite = new jasmine.Suite({
+ env: env,
+ description: "I am a suite"
});
- expect(suite.specs().length).toEqual(3);
+ expect(suite.getFullName()).toEqual("I am a suite");
+ });
+
+ it("returns its full name when it has parent suites", function() {
+ var env = new jasmine.Env(),
+ parentSuite = new jasmine.Suite({
+ env: env,
+ description: "I am a parent suite",
+ parentSuite: jasmine.createSpy('pretend top level suite')
+ }),
+ suite = new jasmine.Suite({
+ env: env,
+ description: "I am a suite",
+ parentSuite: parentSuite
+ });
+
+ expect(suite.getFullName()).toEqual("I am a parent suite I am a suite");
+ });
+
+ it("adds before functions in order of needed execution", function() {
+ var env = new jasmine.Env(),
+ suite = new jasmine.Suite({
+ env: env,
+ description: "I am a suite"
+ }),
+ outerBefore = jasmine.createSpy('outerBeforeEach'),
+ innerBefore = jasmine.createSpy('insideBeforeEach');
+
+ suite.beforeEach(outerBefore);
+ suite.beforeEach(innerBefore);
+
+ expect(suite.beforeFns).toEqual([innerBefore, outerBefore]);
+ });
+
+ it("adds after functions in order of needed execution", function() {
+ var env = new jasmine.Env(),
+ suite = new jasmine.Suite({
+ env: env,
+ description: "I am a suite"
+ }),
+ outerAfter = jasmine.createSpy('outerAfterEach'),
+ innerAfter = jasmine.createSpy('insideAfterEach');
+
+ suite.afterEach(outerAfter);
+ suite.afterEach(innerAfter);
+
+ expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
+ });
+
+ it("adds specs", function() {
+ var env = new jasmine.Env(),
+ fakeQueue = {
+ add: jasmine.createSpy()
+ },
+ suite = new jasmine.Suite({
+ env: env,
+ description: "I am a suite",
+ queueFactory: function() {
+ return fakeQueue
+ }
+ }),
+ fakeSpec = {};
+
+ expect(suite.specs.length).toEqual(0);
+
+ suite.addSpec(fakeSpec);
+
+ expect(suite.specs.length).toEqual(1);
+ });
+
+ it("adds suites", function() {
+ var env = new jasmine.Env(),
+ fakeQueue = {
+ add: jasmine.createSpy()
+ },
+ suite = new jasmine.Suite({
+ env: env,
+ description: "I am a suite",
+ queueFactory: function() {
+ return fakeQueue
+ }
+ }),
+ anotherSuite = new jasmine.Suite({
+ env: env,
+ description: "I am another suite",
+ queueFactory: function() {
+ return fakeQueue
+ }
+ });
+
+ expect(suite.suites.length).toEqual(0);
+
+ suite.addSuite(anotherSuite);
+
+ expect(suite.suites.length).toEqual(1);
+ });
+
+ it("can be disabled", function() {
+ var env = new jasmine.Env(),
+ fakeQueueRunner = jasmine.createSpy('fake queue runner'),
+ suite = new jasmine.Suite({
+ env: env,
+ description: "with a child suite",
+ queueRunner: fakeQueueRunner
+ });
+
+ suite.disable();
+
+ expect(suite.disabled).toBe(true);
+
+ suite.execute();
+
+ expect(fakeQueueRunner).not.toHaveBeenCalled();
+ });
+
+ it("delegates execution of its specs and suites", function() {
+ var env = new jasmine.Env(),
+ parentSuiteDone = jasmine.createSpy('parent suite done'),
+ fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
+ parentSuite = new jasmine.Suite({
+ env: env,
+ description: "I am a parent suite",
+ queueRunner: fakeQueueRunnerForParent
+ }),
+ fakeQueueRunner = jasmine.createSpy('fake queue runner'),
+ suite = new jasmine.Suite({
+ env: env,
+ description: "with a child suite",
+ queueRunner: fakeQueueRunner
+ }),
+ fakeSpec1 = {
+ execute: jasmine.createSpy('fakeSpec1')
+ };
+
+ spyOn(suite, "execute");
+
+ parentSuite.addSpec(fakeSpec1);
+ parentSuite.addSuite(suite);
+
+ parentSuite.execute(parentSuiteDone);
+
+ var parentSuiteFns = fakeQueueRunnerForParent.mostRecentCall.args[0].fns;
+
+ parentSuiteFns[0]();
+ expect(fakeSpec1.execute).toHaveBeenCalled();
+ parentSuiteFns[1]();
+ expect(suite.execute).toHaveBeenCalled();
+ });
+
+ it("calls a provided onStart callback when starting", function() {
+ var env = new jasmine.Env(),
+ suiteStarted = jasmine.createSpy('suiteStarted'),
+ fakeQueueRunner = function(attrs) { attrs.onComplete(); },
+ suite = new jasmine.Suite({
+ env: env,
+ description: "with a child suite",
+ onStart: suiteStarted,
+ queueRunner: fakeQueueRunner
+ }),
+ fakeSpec1 = {
+ execute: jasmine.createSpy('fakeSpec1')
+ };
+
+ suite.execute();
+
+ expect(suiteStarted).toHaveBeenCalledWith(suite);
+ });
+
+ it("calls a provided onComplete callback when done", function() {
+ var env = new jasmine.Env(),
+ suiteCompleted = jasmine.createSpy('parent suite done'),
+ fakeQueueRunner = function(attrs) { attrs.onComplete(); },
+ suite = new jasmine.Suite({
+ env: env,
+ description: "with a child suite",
+ queueRunner: fakeQueueRunner
+ }),
+ fakeSpec1 = {
+ execute: jasmine.createSpy('fakeSpec1')
+ };
+
+ suite.execute(suiteCompleted);
+
+ expect(suiteCompleted).toHaveBeenCalled();
+ });
+
+ it("calls a provided result callback when done", function() {
+ var env = new jasmine.Env(),
+ suiteResultsCallback = jasmine.createSpy('suite result callback'),
+ fakeQueueRunner = function(attrs) { attrs.onComplete(); },
+ suite = new jasmine.Suite({
+ env: env,
+ description: "with a child suite",
+ queueRunner: fakeQueueRunner,
+ resultCallback: suiteResultsCallback
+ }),
+ fakeSpec1 = {
+ execute: jasmine.createSpy('fakeSpec1')
+ };
+
+ suite.execute();
+
+ expect(suiteResultsCallback).toHaveBeenCalledWith({
+ id: suite.id,
+ status: '',
+ description: "with a child suite",
+ fullName: "with a child suite"
});
});
-});
\ No newline at end of file
+});
diff --git a/spec/core/UtilSpec.js b/spec/core/UtilSpec.js
index 551c2872..17694168 100644
--- a/spec/core/UtilSpec.js
+++ b/spec/core/UtilSpec.js
@@ -1,26 +1,4 @@
describe("jasmine.util", function() {
- describe("extend", function () {
- it("should add properies to a destination object ", function() {
- var destination = {baz: 'baz'};
- jasmine.util.extend(destination, {
- foo: 'foo', bar: 'bar'
- });
- expect(destination).toEqual({foo: 'foo', bar: 'bar', baz: 'baz'});
- });
-
- it("should replace properies that already exist on a destination object", function() {
- var destination = {foo: 'foo'};
- jasmine.util.extend(destination, {
- foo: 'bar'
- });
- expect(destination).toEqual({foo: 'bar'});
- jasmine.util.extend(destination, {
- foo: null
- });
- expect(destination).toEqual({foo: null});
- });
- });
-
describe("isArray_", function() {
it("should return true if the argument is an array", function() {
expect(jasmine.isArray_([])).toBe(true);
diff --git a/spec/core/WaitsForBlockSpec.js b/spec/core/WaitsForBlockSpec.js
deleted file mode 100644
index e1807212..00000000
--- a/spec/core/WaitsForBlockSpec.js
+++ /dev/null
@@ -1,118 +0,0 @@
-describe('WaitsForBlock', function () {
- var env, suite, timeout, spec, message, onComplete, fakeTimer;
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
- suite = new jasmine.Suite(env, 'suite 1');
- timeout = 1000;
- spec = new jasmine.Spec(env, suite);
- message = "some error message";
- onComplete = jasmine.createSpy("onComplete");
- });
-
- describe("jasmine.VERBOSE", function() {
- var jasmineVerboseOriginal;
- beforeEach(function() {
- jasmineVerboseOriginal = jasmine.VERBOSE;
- spyOn(env.reporter, 'log');
-
- });
- it('do not show information if jasmine.VERBOSE is set to false', function () {
- jasmine.VERBOSE = false;
- var latchFunction = function() {
- return true;
- };
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- expect(env.reporter.log).not.toHaveBeenCalled();
- block.execute(onComplete);
- expect(env.reporter.log).not.toHaveBeenCalled();
- jasmine.VERBOSE = jasmineVerboseOriginal;
- });
- it('show information if jasmine.VERBOSE is set to true', function () {
- jasmine.VERBOSE = true;
- var latchFunction = function() {
- return true;
- };
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- expect(env.reporter.log).not.toHaveBeenCalled();
- block.execute(onComplete);
- expect(env.reporter.log).toHaveBeenCalled();
- jasmine.VERBOSE = jasmineVerboseOriginal;
- });
- });
-
- it('onComplete should be called if the latchFunction returns true', function () {
- var latchFunction = function() {
- return true;
- };
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- expect(onComplete).not.toHaveBeenCalled();
- block.execute(onComplete);
- expect(onComplete).toHaveBeenCalled();
- });
-
- it('latchFunction should run in same scope as spec', function () {
- var result;
- var latchFunction = function() {
- result = this.scopedValue;
- };
- spec.scopedValue = 'foo';
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- block.execute(onComplete);
- expect(result).toEqual('foo');
- });
-
- it('should fail spec and call onComplete if there is an error in the latchFunction', function() {
- var latchFunction = jasmine.createSpy('latchFunction').andThrow('some error');
- spyOn(spec, 'fail');
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- block.execute(onComplete);
- expect(spec.fail).toHaveBeenCalledWith('some error');
- expect(onComplete).toHaveBeenCalled();
- });
-
- describe("if latchFunction returns false", function() {
- var latchFunction, fakeTimer;
- beforeEach(function() {
- latchFunction = jasmine.createSpy('latchFunction').andReturn(false);
- fakeTimer = new jasmine.FakeTimer();
- env.setTimeout = fakeTimer.setTimeout;
- env.clearTimeout = fakeTimer.clearTimeout;
- env.setInterval = fakeTimer.setInterval;
- env.clearInterval = fakeTimer.clearInterval;
- });
-
- it('latchFunction should be retried after 10 ms', function () {
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- expect(latchFunction).not.toHaveBeenCalled();
- block.execute(onComplete);
- expect(latchFunction.callCount).toEqual(1);
- fakeTimer.tick(5);
- expect(latchFunction.callCount).toEqual(1);
- fakeTimer.tick(5);
- expect(latchFunction.callCount).toEqual(2);
- });
-
- it('onComplete should be called if latchFunction returns true before timeout', function () {
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- expect(onComplete).not.toHaveBeenCalled();
- block.execute(onComplete);
- expect(onComplete).not.toHaveBeenCalled();
- latchFunction.andReturn(true);
- fakeTimer.tick(100);
- expect(onComplete).toHaveBeenCalled();
- });
-
- it('spec should fail with the passed message if the timeout is reached (and not call onComplete)', function () {
- spyOn(spec, 'fail');
- var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
- block.execute(onComplete);
- expect(spec.fail).not.toHaveBeenCalled();
- fakeTimer.tick(timeout);
- expect(spec.fail).toHaveBeenCalled();
- var failMessage = spec.fail.mostRecentCall.args[0].message;
- expect(failMessage).toMatch(message);
- expect(onComplete).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/html/HTMLReporterSpec.js b/spec/html/HTMLReporterSpec.js
deleted file mode 100644
index 3545527b..00000000
--- a/spec/html/HTMLReporterSpec.js
+++ /dev/null
@@ -1,209 +0,0 @@
-describe("HtmlReporter", function() {
- var env;
- var htmlReporter;
- var body;
- var fakeDocument;
-
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
-
- body = document.createElement("body");
- fakeDocument = { body: body, location: { search: "" } };
- htmlReporter = new jasmine.HtmlReporter(fakeDocument);
- });
-
- function fakeSpec(name) {
- return {
- getFullName: function() {
- return name;
- }
- };
- }
-
- function findElements(divs, withClass) {
- var els = [];
- for (var i = 0; i < divs.length; i++) {
- if (divs[i].className == withClass) els.push(divs[i]);
- }
- return els;
- }
-
- function findElement(divs, withClass) {
- var els = findElements(divs, withClass);
- if (els.length > 0) {
- return els[0];
- }
- throw new Error("couldn't find div with class " + withClass);
- }
-
- it("should run only specs beginning with spec parameter", function() {
- fakeDocument.location.search = "?spec=run%20this";
- expect(htmlReporter.specFilter(fakeSpec("run this"))).toBeTruthy();
- expect(htmlReporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy();
- expect(htmlReporter.specFilter(fakeSpec("not run this"))).toBeFalsy();
- });
-
- describe("running without any specs", function() {
- var runner;
- beforeEach(function() {
- runner = env.currentRunner();
- env.addReporter(htmlReporter);
- });
-
- it("should not error", function() {
- var exec = function() {
- runner.execute();
- };
- expect(exec).not.toThrow();
- });
- });
-
- describe('Matcher reporting', function() {
- var getResultMessageDiv = function(body) {
- var divs = body.getElementsByTagName("div");
- for (var i = 0; i < divs.length; i++) {
- if (divs[i].className.match(/resultMessage/)) {
- return divs[i];
- }
- }
- };
-
- var runner, spec, fakeTimer;
- beforeEach(function() {
- fakeTimer = new jasmine.FakeTimer();
- env.setTimeout = fakeTimer.setTimeout;
- env.clearTimeout = fakeTimer.clearTimeout;
- env.setInterval = fakeTimer.setInterval;
- env.clearInterval = fakeTimer.clearInterval;
- runner = env.currentRunner();
- var suite = new jasmine.Suite(env, 'some suite');
- runner.add(suite);
- spec = new jasmine.Spec(env, suite, 'some spec');
- suite.add(spec);
- fakeDocument.location.search = "?";
- env.addReporter(htmlReporter);
- });
-
- describe('toContain', function() {
- it('should show actual and expected', function() {
- spec.runs(function() {
- this.expect('foo').toContain('bar');
- });
- runner.execute();
- fakeTimer.tick(0);
-
- var resultEl = getResultMessageDiv(body);
- expect(resultEl.innerHTML).toMatch(/foo/);
- expect(resultEl.innerHTML).toMatch(/bar/);
- });
- });
- });
-
- describe("failure messages (integration)", function() {
- var spec, results, expectationResult;
-
- it("should add the failure message to the DOM (non-toEquals matchers)", function() {
- env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.expect('a').toBeNull();
- });
- });
-
- env.addReporter(htmlReporter);
- env.execute();
-
- var divs = body.getElementsByTagName("div");
- var errorDiv = findElement(divs, 'resultMessage fail');
- expect(errorDiv.innerHTML).toMatch(/Expected 'a' to be null/);
- });
-
- it("should add the failure message to the DOM (non-toEquals matchers) html escaping", function() {
- env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.expect('1 < 2').toBeNull();
- });
- });
-
- env.addReporter(htmlReporter);
- env.execute();
-
- var divs = body.getElementsByTagName("div");
- var errorDiv = findElement(divs, 'resultMessage fail');
- expect(errorDiv.innerHTML).toMatch(/Expected '1 < 2' to be null/);
- });
- });
-
- describe("log messages", function() {
- it("should appear in the report of a failed spec", function() {
- env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.log("this is a", "multipart log message");
- this.expect(true).toBeFalsy();
- });
- });
-
- env.addReporter(htmlReporter);
- env.execute();
-
- var divs = body.getElementsByTagName("div");
- var errorDiv = findElement(divs, 'specDetail failed');
- expect(errorDiv.innerHTML).toMatch("this is a multipart log message");
- });
-
- xit("should work on IE without console.log.apply", function() {
- });
- });
-
- describe("duplicate example names", function() {
- it("should report failures correctly", function() {
- var suite1 = env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.log("this one fails!");
- this.expect(true).toBeFalsy();
- });
- });
-
- var suite2 = env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.log("this one passes!");
- this.expect(true).toBeTruthy();
- });
- });
-
- env.addReporter(htmlReporter);
- env.execute();
-
- var divs = body.getElementsByTagName("div");
- var failedSpecDiv = findElement(divs, 'specDetail failed');
- expect(failedSpecDiv.className).toEqual('specDetail failed');
- expect(failedSpecDiv.innerHTML).toContain("this one fails!");
- expect(failedSpecDiv.innerHTML).not.toContain("this one passes!");
- });
- });
-
- describe('#reportSpecStarting', function() {
- beforeEach(function() {
- env.describe("suite 1", function() {
- env.it("spec 1", function() {
- });
- });
- spyOn(htmlReporter, 'log').andCallThrough();
- });
-
- it('DOES NOT log running specs by default', function() {
- env.addReporter(htmlReporter);
- env.execute();
-
- expect(htmlReporter.log).not.toHaveBeenCalled();
- });
-
- it('logs running specs when log_running_specs is true', function() {
- htmlReporter.logRunningSpecs = true;
- env.addReporter(htmlReporter);
- env.execute();
-
- expect(htmlReporter.log).toHaveBeenCalledWith('>> Jasmine Running suite 1 spec 1...');
- });
- });
-});
diff --git a/spec/html/HtmlReporterSpec.js b/spec/html/HtmlReporterSpec.js
new file mode 100644
index 00000000..389fa278
--- /dev/null
+++ b/spec/html/HtmlReporterSpec.js
@@ -0,0 +1,571 @@
+describe("New HtmlReporter", function() {
+
+ it("builds the initial DOM elements, including the title banner", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+ reporter.initialize();
+
+ // Main top-level elements
+ var divs = container.getElementsByTagName("div");
+ expect(findElement(divs, "html-reporter")).toBeTruthy();
+ expect(findElement(divs, "banner")).toBeTruthy();
+ expect(findElement(divs, "alert")).toBeTruthy();
+ expect(findElement(divs, "results")).toBeTruthy();
+
+ var uls = container.getElementsByTagName("ul");
+ expect(findElement(uls, "symbol-summary")).toBeTruthy();
+
+ // title banner
+ var banner = container.getElementsByClassName("banner")[0];
+
+ var title = banner.getElementsByClassName("title")[0];
+ expect(title.innerHTML).toMatch(/Jasmine/);
+
+ var version = banner.getElementsByClassName("version")[0];
+ expect(version.innerHTML).toMatch(/\d+\.\d+\.\d+\srevision\s+\d+/);
+ });
+
+ describe("when a spec is done", function() {
+ it("reports the status symbol of a disabled spec", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+ reporter.initialize();
+
+ reporter.specDone({id: 789, status: "disabled"});
+
+ var statuses = container.getElementsByClassName('symbol-summary')[0];
+ var specEl = statuses.getElementsByTagName('li')[0];
+ expect(specEl.getAttribute("class")).toEqual("disabled");
+ expect(specEl.getAttribute("id")).toEqual("spec_789");
+ });
+
+ it("reports the status symbol of a passing spec", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+ reporter.initialize();
+
+ reporter.specDone({id: 123, status: "passed"});
+
+ var statuses = container.getElementsByClassName("symbol-summary")[0];
+ var specEl = statuses.getElementsByTagName("li")[0];
+ expect(specEl.getAttribute("class")).toEqual("passed");
+ expect(specEl.getAttribute("id")).toEqual("spec_123");
+ });
+
+ it("reports the status symbol of a failing spec", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+
+ reporter.initialize();
+
+ reporter.specDone({
+ id: 345,
+ status: "failed",
+ failedExpectations: []
+ });
+
+ var statuses = container.getElementsByClassName('symbol-summary')[0];
+ var specEl = statuses.getElementsByTagName('li')[0];
+ expect(specEl.getAttribute("class")).toEqual("failed");
+ expect(specEl.getAttribute("id")).toEqual("spec_345");
+ });
+ });
+
+ describe("when Jasmine is done", function() {
+ it("reports the run time", function() {
+ var env = new jasmine.Env(),
+ fakeNow = jasmine.createSpy('fake Date.now'),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ now: fakeNow,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+
+ reporter.initialize();
+
+ fakeNow.andReturn(500);
+ reporter.jasmineStarted({});
+ fakeNow.andReturn(600);
+ reporter.jasmineDone();
+
+ var banner = container.getElementsByClassName("banner")[0];
+ var duration = banner.getElementsByClassName("duration")[0];
+ expect(duration.innerHTML).toMatch(/finished in 0.1s/);
+ });
+
+ it("reports the suite and spec names with status", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+ reporter.initialize();
+
+ reporter.jasmineStarted({});
+ reporter.suiteStarted({
+ id: 1,
+ description: "A Suite",
+ fullName: "A Suite"
+ });
+
+ var specResult = {
+ id: 123,
+ description: "with a spec",
+ fullName: "A Suite with a spec",
+ status: "passed"
+ };
+ reporter.specStarted(specResult);
+ reporter.specDone(specResult);
+
+ reporter.suiteStarted({
+ id: 2,
+ description: "inner suite",
+ fullName: "A Suite inner suite"
+ });
+
+ var specResult = {
+ id: 124,
+ description: "with another spec",
+ fullName: "A Suite inner suite with another spec",
+ status: "passed"
+ };
+ reporter.specStarted(specResult);
+ reporter.specDone(specResult);
+
+ reporter.suiteDone({id: 2});
+
+ specResult = {
+ id: 209,
+ description: "with a failing spec",
+ fullName: "A Suite inner with a failing spec",
+ status: "failed",
+ failedExpectations: []
+ };
+ reporter.specStarted(specResult);
+ reporter.specDone(specResult);
+
+ reporter.suiteDone({id: 1});
+
+ reporter.jasmineDone();
+ var summary = container.getElementsByClassName("summary")[0];
+
+ console.error("=============>", summary);
+ expect(summary.childNodes.length).toEqual(1);
+
+ var outerSuite = summary.childNodes[0];
+ expect(outerSuite.childNodes.length).toEqual(4);
+
+ var classes = [];
+ for (var i = 0; i < outerSuite.childNodes.length; i++) {
+ var node = outerSuite.childNodes[i];
+ classes.push(node.getAttribute("class"));
+ }
+ expect(classes).toEqual(["suite-detail", "specs", "suite", "specs"]);
+
+ var suiteDetail = outerSuite.childNodes[0];
+ var suiteLink = suiteDetail.childNodes[0];
+ expect(suiteLink.text).toEqual("A Suite");
+ expect(suiteLink.getAttribute('href')).toEqual("?spec=A%20Suite");
+
+ var specs = outerSuite.childNodes[1];
+ var spec = specs.childNodes[0];
+ expect(spec.getAttribute("class")).toEqual("passed");
+ expect(spec.getAttribute("id")).toEqual("spec-123");
+
+ var specLink = spec.childNodes[0];
+ expect(specLink.text).toEqual("with a spec");
+ expect(specLink.getAttribute("href")).toEqual("?spec=A%20Suite%20with%20a%20spec");
+// expect(specLink.getAttribute("title")).toEqual("A Suite with a spec");
+ });
+
+ describe("UI for raising/catching exceptions", function() {
+ it("should be unchecked if the env is catching", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+
+ reporter.initialize();
+ reporter.jasmineDone();
+
+ var raisingExceptionsUI = container.getElementsByClassName("raise")[0];
+ expect(raisingExceptionsUI.checked).toBe(false);
+ });
+
+ it("should be checked if the env is not catching", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ fakeQueryString = "",
+ fakeWindowLocation = {
+ search: fakeQueryString
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return fakeWindowLocation; }
+ }),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ queryString: queryString,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+
+ reporter.initialize();
+ env.catchExceptions(false);
+ reporter.jasmineDone();
+
+ var raisingExceptionsUI = container.getElementsByClassName("raise")[0];
+ expect(raisingExceptionsUI.checked).toBe(true);
+ });
+
+ it("should affect the query param for catching exceptions", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ fakeQueryString = "",
+ fakeWindowLocation = {
+ search: fakeQueryString
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return fakeWindowLocation; }
+ }),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ queryString: queryString,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+
+ reporter.initialize();
+ reporter.jasmineDone();
+
+ var input = container.getElementsByClassName("raise")[0];
+ input.click();
+ expect(queryString.getParam("catch")).toEqual(false);
+
+ input.click();
+ expect(queryString.getParam("catch")).toEqual(true);
+ });
+ });
+
+ describe("and all specs pass", function() {
+ var env, container, reporter;
+ beforeEach(function() {
+ env = new jasmine.Env();
+ container = document.createElement("div");
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+ reporter.initialize();
+
+ reporter.jasmineStarted({});
+ reporter.specDone({
+ id: 123,
+ description: "with a spec",
+ fullName: "A Suite with a spec",
+ status: "passed"
+ });
+ reporter.specDone({
+ id: 124,
+ description: "with another spec",
+ fullName: "A Suite inner suite with another spec",
+ status: "passed"
+ });
+ reporter.jasmineDone();
+ });
+
+ it("reports the specs counts", function() {
+ var alert = container.getElementsByClassName("alert")[0];
+ var alertBars = alert.getElementsByClassName("bar");
+
+ expect(alertBars.length).toEqual(1);
+ expect(alertBars[0].getAttribute('class')).toMatch(/passed/);
+ expect(alertBars[0].innerHTML).toMatch(/2 specs, 0 failures/);
+ });
+
+ it("reports no failure details", function() {
+ var specFailure = container.getElementsByClassName("failures")[0];
+
+ expect(specFailure.childNodes.length).toEqual(0);
+ });
+ });
+
+ describe("and some tests fail", function() {
+ var env, container, reporter;
+
+ beforeEach(function() {
+ env = new jasmine.Env();
+ container = document.createElement("div");
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+ reporter.initialize();
+
+ reporter.jasmineStarted({});
+
+ var passingResult = {id: 123, status: "passed"};
+ reporter.specStarted(passingResult);
+ reporter.specDone(passingResult);
+
+ var failingResult = {
+ id: 124,
+ status: "failed",
+ description: "a failing spec",
+ fullName: "a suite with a failing spec",
+ failedExpectations: [
+ {
+ message: "a failure message",
+ trace: {
+ stack: "a stack trace"
+ }
+ }
+ ]
+ };
+ reporter.specStarted(failingResult);
+ reporter.specDone(failingResult);
+ reporter.jasmineDone();
+ });
+
+ it("reports the specs counts", function() {
+ var alert = container.getElementsByClassName("alert")[0];
+ var alertBars = alert.getElementsByClassName("bar");
+
+ expect(alertBars[0].getAttribute('class')).toMatch(/failed/);
+ expect(alertBars[0].innerHTML).toMatch(/2 specs, 1 failure/);
+ });
+
+ it("reports failure messages and stack traces", function() {
+ var specFailures = container.getElementsByClassName("failures")[0];
+
+ var failure = specFailures.childNodes[0];
+ expect(failure.getAttribute("class")).toMatch(/failed/);
+ expect(failure.getAttribute("class")).toMatch(/spec-detail/);
+
+ var specLink = failure.childNodes[0];
+ expect(specLink.getAttribute("class")).toEqual("description");
+ expect(specLink.getAttribute("title")).toEqual("a suite with a failing spec");
+ expect(specLink.getAttribute("href")).toEqual("?spec=a%20suite%20with%20a%20failing%20spec");
+
+ var message = failure.childNodes[1].childNodes[0];
+ expect(message.getAttribute("class")).toEqual("result-message");
+ expect(message.innerHTML).toEqual("a failure message");
+
+ var stackTrace = failure.childNodes[1].childNodes[1];
+ expect(stackTrace.getAttribute("class")).toEqual("stack-trace");
+ expect(stackTrace.innerHTML).toEqual("a stack trace");
+ });
+
+ it("allows switching between failure details and the spec summary", function() {
+ var menuBar = container.getElementsByClassName("bar")[1];
+
+ expect(menuBar.getAttribute("class")).not.toMatch(/hidden/);
+
+ var link = menuBar.getElementsByTagName('a')[0];
+ expect(link.text).toEqual("Failures");
+ expect(link.getAttribute("href")).toEqual("#");
+ });
+
+ it("sets the reporter to 'Failures List' mode", function() {
+ var reporterNode = container.getElementsByClassName("html-reporter")[0];
+ expect(reporterNode.getAttribute("class")).toMatch("failure-list");
+ });
+ });
+ });
+
+ describe("specFilter", function() {
+
+ it("always returns true if there is no filter", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ fakeQueryString = "",
+ fakeWindowLocation = {
+ search: fakeQueryString
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return fakeWindowLocation; }
+ }),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ queryString: queryString,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ }),
+ fakeSpec = {
+ getFullName: function() { return "A suite with a spec"}
+ };
+
+ expect(reporter.specFilter(fakeSpec)).toBe(true);
+ });
+
+ it("matches a focused spec name", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ fakeWindowLocation = {
+ search: "?spec=A%20suite%20with%20a%20spec"
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return fakeWindowLocation; }
+ }),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ queryString: queryString,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ }),
+ fakeMatchingSpec = {
+ getFullName: function() { return "A suite with a spec"}
+ },
+ fakeNonMatchingSpec = {
+ getFullName: function() { return "sasquatch"}
+ };
+
+ expect(reporter.specFilter(fakeMatchingSpec)).toBe(true);
+ expect(reporter.specFilter(fakeNonMatchingSpec)).toBe(false);
+ });
+
+ it("matches a substring of a spec name", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ fakeWindowLocation = {
+ search: "?spec=with"
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return fakeWindowLocation; }
+ }),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ queryString: queryString,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ }),
+ fakeMatchingSpec = {
+ getFullName: function() { return "A suite with a spec" }
+ },
+ fakeNonMatchingSpec = {
+ getFullName: function() { return "sasquatch"}
+ };
+
+ expect(reporter.specFilter(fakeMatchingSpec)).toBe(true);
+ expect(reporter.specFilter(fakeNonMatchingSpec)).toBe(false);
+ });
+ });
+
+ describe("when specs are filtered", function() {
+ it("shows the count of run specs and defined specs", function() {
+ var env = new jasmine.Env(),
+ container = document.createElement("div"),
+ getContainer = function() { return container; },
+ reporter = new jasmine.HtmlReporter({
+ env: env,
+ getContainer: getContainer,
+ createElement: function() { return document.createElement.apply(document, arguments); },
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
+ });
+
+ reporter.initialize();
+
+ reporter.jasmineStarted({
+ totalSpecsDefined: 2
+ });
+ reporter.specDone({
+ id: 123,
+ description: "with a spec",
+ fullName: "A Suite with a spec",
+ status: "passed"
+ });
+ reporter.specDone({
+ id: 124,
+ description: "with another spec",
+ fullName: "A Suite inner suite with another spec",
+ status: "disabled"
+ });
+ reporter.jasmineDone();
+
+ var skippedBar = container.getElementsByClassName("bar")[0];
+ expect(skippedBar.getAttribute("class")).toMatch(/skipped/);
+
+ var runAllLink = skippedBar.childNodes[0];
+ expect(runAllLink.getAttribute("href")).toEqual("?");
+ expect(runAllLink.text).toMatch(/Ran \d+ of \d+ specs - run all/);
+ });
+ });
+
+ // try/catch
+
+ // utility functions
+ function findElements(divs, withClass) {
+ var els = [];
+ for (var i = 0; i < divs.length; i++) {
+ if (divs[i].className == withClass) els.push(divs[i]);
+ }
+ return els;
+ }
+
+ function findElement(divs, withClass) {
+ var els = findElements(divs, withClass);
+ if (els.length > 0) {
+ return els[0];
+ }
+ throw new Error("couldn't find div with class " + withClass);
+ }
+});
diff --git a/spec/html/MatchersHtmlSpec.js b/spec/html/MatchersHtmlSpec.js
index b528753a..e21f4abc 100644
--- a/spec/html/MatchersHtmlSpec.js
+++ b/spec/html/MatchersHtmlSpec.js
@@ -9,14 +9,14 @@ describe("MatchersSpec - HTML Dependent", function () {
spec = env.it("spec", function() {
});
});
- spyOn(spec, 'addMatcherResult');
+ spyOn(spec, 'addExpectationResult');
- this.addMatchers({
+ addMatchers({
toPass: function() {
- return lastResult().passed();
+ return lastResult().passed;
},
toFail: function() {
- return !lastResult().passed();
+ return !lastResult().passed;
}
});
});
@@ -26,7 +26,7 @@ describe("MatchersSpec - HTML Dependent", function () {
}
function lastResult() {
- return spec.addMatcherResult.mostRecentCall.args[0];
+ return spec.addExpectationResult.mostRecentCall.args[1];
}
it("toEqual with DOM nodes", function() {
@@ -35,4 +35,4 @@ describe("MatchersSpec - HTML Dependent", function () {
expect((match(nodeA).toEqual(nodeA))).toPass();
expect((match(nodeA).toEqual(nodeB))).toFail();
});
-});
\ No newline at end of file
+});
diff --git a/spec/html/QueryStringSpec.js b/spec/html/QueryStringSpec.js
new file mode 100644
index 00000000..e95d1811
--- /dev/null
+++ b/spec/html/QueryStringSpec.js
@@ -0,0 +1,43 @@
+describe("QueryString", function() {
+
+ describe("#setParam", function() {
+
+ it("sets the query string to include the given key/value pair", function() {
+ var windowLocation = {
+ search: ""
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return windowLocation }
+ });
+
+ queryString.setParam("foo", "bar baz");
+
+ expect(windowLocation.search).toMatch(/foo=bar%20baz/);
+ });
+ });
+
+ describe("#getParam", function() {
+
+ it("returns the value of the requested key", function() {
+ var windowLocation = {
+ search: "?baz=quux%20corge"
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return windowLocation }
+ });
+
+ expect(queryString.getParam("baz")).toEqual("quux corge");
+ });
+
+ it("returns null if the key is not present", function() {
+ var windowLocation = {
+ search: ""
+ },
+ queryString = new jasmine.QueryString({
+ getWindowLocation: function() { return windowLocation }
+ });
+
+ expect(queryString.getParam("baz")).toBeFalsy();
+ });
+ });
+});
\ No newline at end of file
diff --git a/spec/html/ResultsNodeSpec.js b/spec/html/ResultsNodeSpec.js
new file mode 100644
index 00000000..db46bc13
--- /dev/null
+++ b/spec/html/ResultsNodeSpec.js
@@ -0,0 +1,62 @@
+describe("ResultsNode", function() {
+ it("wraps a result", function() {
+ var fakeResult = {
+ id: 123,
+ message: "foo"
+ },
+ node = new jasmine.ResultsNode(fakeResult, "suite", null);
+
+ expect(node.result).toBe(fakeResult);
+ expect(node.type).toEqual("suite");
+ });
+
+ it("can add children with a type", function() {
+ var fakeResult = {
+ id: 123,
+ message: "foo"
+ },
+ fakeChildResult = {
+ id: 456,
+ message: "bar"
+ },
+ node = new jasmine.ResultsNode(fakeResult, "suite", null);
+
+ node.addChild(fakeChildResult, "spec");
+
+ expect(node.children.length).toEqual(1);
+ expect(node.children[0].result).toEqual(fakeChildResult);
+ expect(node.children[0].type).toEqual("spec");
+ });
+
+ it("has a pointer back to its parent ResultNode", function() {
+ var fakeResult = {
+ id: 123,
+ message: "foo"
+ },
+ fakeChildResult = {
+ id: 456,
+ message: "bar"
+ },
+ node = new jasmine.ResultsNode(fakeResult, "suite", null);
+
+ node.addChild(fakeChildResult, "spec");
+
+ expect(node.children[0].parent).toBe(node);
+ });
+
+ it("can provide the most recent child", function() {
+ var fakeResult = {
+ id: 123,
+ message: "foo"
+ },
+ fakeChildResult = {
+ id: 456,
+ message: "bar"
+ },
+ node = new jasmine.ResultsNode(fakeResult, "suite", null);
+
+ node.addChild(fakeChildResult, "spec");
+
+ expect(node.last()).toBe(node.children[node.children.length - 1]);
+ });
+});
\ No newline at end of file
diff --git a/spec/html/TrivialReporterSpec.js b/spec/html/TrivialReporterSpec.js
deleted file mode 100644
index 4e0830da..00000000
--- a/spec/html/TrivialReporterSpec.js
+++ /dev/null
@@ -1,239 +0,0 @@
-describe("TrivialReporter", function() {
- var env;
- var trivialReporter;
- var body;
- var fakeDocument;
-
- beforeEach(function() {
- env = new jasmine.Env();
- env.updateInterval = 0;
-
- body = document.createElement("body");
- fakeDocument = { body: body, location: { search: "" } };
- trivialReporter = new jasmine.TrivialReporter(fakeDocument);
- });
-
- function fakeSpec(name) {
- return {
- getFullName: function() {
- return name;
- }
- };
- }
-
- function findElements(divs, withClass) {
- var els = [];
- for (var i = 0; i < divs.length; i++) {
- if (divs[i].className == withClass) els.push(divs[i]);
- }
- return els;
- }
-
- function findElement(divs, withClass) {
- var els = findElements(divs, withClass);
- if (els.length > 0) {
- return els[0];
- }
- throw new Error("couldn't find div with class " + withClass);
- }
-
- it("should run only specs beginning with spec parameter", function() {
- fakeDocument.location.search = "?spec=run%20this";
- expect(trivialReporter.specFilter(fakeSpec("run this"))).toBeTruthy();
- expect(trivialReporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy();
- expect(trivialReporter.specFilter(fakeSpec("not run this"))).toBeFalsy();
- });
-
- it("should display empty divs for every suite when the runner is starting", function() {
- trivialReporter.reportRunnerStarting({
- env: env,
- suites: function() {
- return [ new jasmine.Suite({}, "suite 1", null, null) ];
- }
- });
-
- var divs = findElements(body.getElementsByTagName("div"), "suite");
- expect(divs.length).toEqual(1);
- expect(divs[0].innerHTML).toContain("suite 1");
- });
-
- describe('Matcher reporting', function () {
- var getResultMessageDiv = function (body) {
- var divs = body.getElementsByTagName("div");
- for (var i = 0; i < divs.length; i++) {
- if (divs[i].className.match(/resultMessage/)) {
- return divs[i];
- }
- }
- };
-
- var runner, spec, fakeTimer;
- beforeEach(function () {
- fakeTimer = new jasmine.FakeTimer();
- env.setTimeout = fakeTimer.setTimeout;
- env.clearTimeout = fakeTimer.clearTimeout;
- env.setInterval = fakeTimer.setInterval;
- env.clearInterval = fakeTimer.clearInterval;
- runner = env.currentRunner();
- var suite = new jasmine.Suite(env, 'some suite');
- runner.add(suite);
- spec = new jasmine.Spec(env, suite, 'some spec');
- suite.add(spec);
- fakeDocument.location.search = "?";
- env.addReporter(trivialReporter);
- });
-
- describe('toContain', function () {
- it('should show actual and expected', function () {
- spec.runs(function () {
- this.expect('foo').toContain('bar');
- });
- runner.execute();
- fakeTimer.tick(0);
-
- var resultEl = getResultMessageDiv(body);
- expect(resultEl.innerHTML).toMatch(/foo/);
- expect(resultEl.innerHTML).toMatch(/bar/);
- });
- });
- });
-
- describe("failure messages (integration)", function () {
- var spec, results, expectationResult;
-
- beforeEach(function() {
- results = {
- passed: function() {
- return false;
- },
- getItems: function() {
- }};
-
- var suite1 = new jasmine.Suite(env, "suite 1", null, null);
-
- spec = {
- suite: suite1,
- getFullName: function() {
- return "foo";
- },
- results: function() {
- return results;
- }
- };
-
- trivialReporter.reportRunnerStarting({
- env: env,
- suites: function() {
- return [ suite1 ];
- }
- });
- });
-
- it("should add the failure message to the DOM (non-toEquals matchers)", function() {
- expectationResult = new jasmine.ExpectationResult({
- matcherName: "toBeNull", passed: false, message: "Expected 'a' to be null, but it was not"
- });
-
- spyOn(results, 'getItems').andReturn([expectationResult]);
-
- trivialReporter.reportSpecResults(spec);
-
- var divs = body.getElementsByTagName("div");
- var errorDiv = findElement(divs, 'resultMessage fail');
- expect(errorDiv.innerHTML).toEqual("Expected 'a' to be null, but it was not");
- });
-
- it("should add the failure message to the DOM (non-toEquals matchers) html escaping", function() {
- expectationResult = new jasmine.ExpectationResult({
- matcherName: "toBeNull", passed: false, message: "Expected '1 < 2' to e null, & it was not"
- });
-
- spyOn(results, 'getItems').andReturn([expectationResult]);
-
- trivialReporter.reportSpecResults(spec);
-
- var divs = body.getElementsByTagName("div");
- var errorDiv = findElement(divs, 'resultMessage fail');
- expect(errorDiv.innerHTML).toEqual("Expected '1 < 2' to <b>e null, & it was not");
- });
- });
-
- describe("log messages", function() {
- it("should appear in the report", function() {
- env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.log("this is a", "multipart log message");
- });
- });
-
- env.addReporter(trivialReporter);
- env.execute();
-
- var divs = body.getElementsByTagName("div");
- var errorDiv = findElement(divs, 'resultMessage log');
- expect(errorDiv.innerHTML).toEqual("this is a multipart log message");
- });
-
- xit("should work on IE without console.log.apply", function() {
- });
- });
-
- describe("duplicate example names", function() {
- it("should report failures correctly", function() {
- var suite1 = env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.log("this one fails!");
- this.expect(true).toBeFalsy();
- });
- });
-
- var suite2 = env.describe("suite", function() {
- env.it("will have log messages", function() {
- this.log("this one passes!");
- this.expect(true).toBeTruthy();
- });
- });
-
- env.addReporter(trivialReporter);
- env.execute();
-
- var divs = body.getElementsByTagName("div");
- var passedSpecDiv = findElement(divs, 'suite passed');
- expect(passedSpecDiv.className).toEqual('suite passed');
- expect(passedSpecDiv.innerHTML).toContain("this one passes!");
- expect(passedSpecDiv.innerHTML).not.toContain("this one fails!");
-
- var failedSpecDiv = findElement(divs, 'suite failed');
- expect(failedSpecDiv.className).toEqual('suite failed');
- expect(failedSpecDiv.innerHTML).toContain("this one fails!");
- expect(failedSpecDiv.innerHTML).not.toContain("this one passes!");
- });
- });
-
- describe('#reportSpecStarting', function() {
- var spec1;
- beforeEach(function () {
- env.describe("suite 1", function() {
- spec1 = env.it("spec 1", function() {
- });
- });
- });
-
- it('DOES NOT log running specs by default', function() {
- spyOn(trivialReporter, 'log');
-
- trivialReporter.reportSpecStarting(spec1);
-
- expect(trivialReporter.log).not.toHaveBeenCalled();
- });
-
- it('logs running specs when log_running_specs is true', function() {
- trivialReporter.logRunningSpecs = true;
- spyOn(trivialReporter, 'log');
-
- trivialReporter.reportSpecStarting(spec1);
-
- expect(trivialReporter.log).toHaveBeenCalledWith('>> Jasmine Running suite 1 spec 1...');
- });
- });
-});
diff --git a/spec/jasmine-performance.yml b/spec/jasmine-performance.yml
new file mode 100644
index 00000000..27a329e4
--- /dev/null
+++ b/spec/jasmine-performance.yml
@@ -0,0 +1,21 @@
+jasmine_dir:
+ - 'src'
+jasmine_files:
+ - 'core/base.js'
+ - 'core/util.js'
+ - 'core/Reporter.js'
+ - 'html/HtmlReporterHelpers.js'
+ - 'core/ExpectationResult.js'
+ - '**/*.js'
+jasmine_css_files:
+ - 'html/jasmine.css'
+src_files:
+stylesheets:
+helpers:
+spec_files:
+ - 'smoke/performance_test.js'
+src_dir:
+spec_dir:
+ - 'spec'
+
+
diff --git a/spec/jasmine.yml b/spec/jasmine.yml
index bd25c368..3561922e 100644
--- a/spec/jasmine.yml
+++ b/spec/jasmine.yml
@@ -1,38 +1,28 @@
-jasmine_dir:
- - 'src'
#This 'magic' inclusion order allows the travis build to pass.
#TODO: search for the correct files to include to prevent
-jasmine_files:
+src_dir:
+ - 'src'
+src_files:
- 'core/base.js'
- 'core/util.js'
- - 'core/Reporter.js'
#end of known dependencies
+ - 'core/Spec.js'
- 'core/Env.js'
- - 'core/Block.js'
- 'core/JsApiReporter.js'
- 'core/Matchers.js'
- - 'core/mock-timeout.js'
- - 'core/MultiReporter.js'
- - 'core/NestedResults.js'
- 'core/PrettyPrinter.js'
- - 'core/Queue.js'
- - 'core/Runner.js'
- - 'core/Spec.js'
- 'core/Suite.js'
- - 'core/WaitsBlock.js'
- - 'core/WaitsForBlock.js'
- - 'html/HtmlReporterHelpers.js'
- - 'html/HtmlReporter.js'
+ - 'html/**.js'
- '**/*.js'
-jasmine_css_files:
- - 'html/jasmine.css'
-src_files:
stylesheets:
+boot_dir: 'spec/support'
+boot_files:
+ - 'boot.js'
+ - 'dev_boot.js'
helpers:
- 'helpers/**/*.js'
spec_files:
- '**/*[Ss]pec.js'
-src_dir:
spec_dir:
- 'spec'
diff --git a/spec/node_performance_suite.js b/spec/node_performance_suite.js
new file mode 100644
index 00000000..15678385
--- /dev/null
+++ b/spec/node_performance_suite.js
@@ -0,0 +1,180 @@
+var fs = require('fs');
+var util = require('util');
+var path = require('path');
+
+// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
+// undefined = "diz be undefined yo";
+
+
+var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
+for (var k in jasmineGlobals) {
+ global[k] = jasmineGlobals[k];
+}
+var env = jasmine.getEnv();
+
+var jasmineInterface = {
+ describe: function(description, specDefinitions) {
+ return env.describe(description, specDefinitions);
+ },
+
+ xdescribe: function(description, specDefinitions) {
+ return env.xdescribe(description, specDefinitions);
+ },
+
+ it: function(desc, func) {
+ return env.it(desc, func);
+ },
+
+ xit: function(desc, func) {
+ return env.xit(desc, func);
+ },
+
+ beforeEach: function(beforeEachFunction) {
+ return env.beforeEach(beforeEachFunction);
+ },
+
+ afterEach: function(afterEachFunction) {
+ return env.afterEach(afterEachFunction);
+ },
+
+ expect: function(actual) {
+ return env.expect(actual);
+ },
+
+ addMatchers: function(matchers) {
+ return env.addMatchers(matchers);
+ },
+
+ spyOn: function(obj, methodName) {
+ return env.spyOn(obj, methodName);
+ },
+
+
+ jsApiReporter: new jasmine.JsApiReporter(jasmine)
+};
+
+for (var k in jasmineInterface) {
+ global[k] = jasmineInterface[k];
+}
+
+require('../src/console/ConsoleReporter.js');
+
+/*
+ Pulling in code from jasmine-node.
+
+ We can't just depend on jasmine-node because it has its own jasmine that it uses.
+ */
+
+global.window = {
+ setTimeout: setTimeout,
+ clearTimeout: clearTimeout,
+ setInterval: setInterval,
+ clearInterval: clearInterval
+};
+
+delete global.window;
+
+function noop() {
+}
+
+jasmine.executeSpecs = function(specs, done, isVerbose, showColors) {
+ global.originalJasmine = jasmine;
+
+ for (var i = 0, len = specs.length; i < len; ++i) {
+ var filename = specs[i];
+ require(filename.replace(/\.\w+$/, ""));
+ }
+
+ var jasmineEnv = jasmine.getEnv();
+ var consoleReporter = new jasmine.ConsoleReporter({
+ print: util.print,
+ onComplete: done,
+ showColors: showColors
+ });
+
+ jasmineEnv.addReporter(consoleReporter);
+ jasmineEnv.execute();
+};
+
+jasmine.getAllSpecFiles = function(dir, matcher) {
+ var specs = [];
+
+ if (fs.statSync(dir).isFile() && dir.match(matcher)) {
+ specs.push(dir);
+ } else {
+ var files = fs.readdirSync(dir);
+ for (var i = 0, len = files.length; i < len; ++i) {
+ var filename = dir + '/' + files[i];
+ if (fs.statSync(filename).isFile() && filename.match(matcher)) {
+ specs.push(filename);
+ } else if (fs.statSync(filename).isDirectory()) {
+ var subfiles = this.getAllSpecFiles(filename, matcher);
+ subfiles.forEach(function(result) {
+ specs.push(result);
+ });
+ }
+ }
+ }
+
+ return specs;
+};
+
+function now() {
+ return new Date().getTime();
+}
+
+jasmine.asyncSpecWait = function() {
+ var wait = jasmine.asyncSpecWait;
+ wait.start = now();
+ wait.done = false;
+ (function innerWait() {
+ waits(10);
+ runs(function() {
+ if (wait.start + wait.timeout < now()) {
+ expect('timeout waiting for spec').toBeNull();
+ } else if (wait.done) {
+ wait.done = false;
+ } else {
+ innerWait();
+ }
+ });
+ })();
+};
+jasmine.asyncSpecWait.timeout = 4 * 1000;
+jasmine.asyncSpecDone = function() {
+ jasmine.asyncSpecWait.done = true;
+};
+
+for (var key in jasmine) {
+ exports[key] = jasmine[key];
+}
+
+/*
+ End jasmine-node runner
+ */
+
+var isVerbose = false;
+var showColors = true;
+process.argv.forEach(function(arg) {
+ switch (arg) {
+ case '--color': showColors = true; break;
+ case '--noColor': showColors = false; break;
+ case '--verbose': isVerbose = true; break;
+ }
+});
+
+var specs = jasmine.getAllSpecFiles(__dirname + '/smoke/', new RegExp("test.js$"));
+var domIndependentSpecs = [];
+for (var i = 0; i < specs.length; i++) {
+ if (fs.readFileSync(specs[i], "utf8").indexOf("document.createElement") < 0) {
+ domIndependentSpecs.push(specs[i]);
+ }
+}
+
+jasmine.executeSpecs(domIndependentSpecs, function(passed) {
+ if (passed) {
+ process.exit(0);
+ } else {
+ process.exit(1);
+ }
+}, isVerbose, showColors);
diff --git a/spec/node_suite.js b/spec/node_suite.js
index bd2867b3..569f03c6 100644
--- a/spec/node_suite.js
+++ b/spec/node_suite.js
@@ -10,6 +10,58 @@ var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
for (var k in jasmineGlobals) {
global[k] = jasmineGlobals[k];
}
+var env = jasmine.getEnv();
+
+var jasmineInterface = {
+ describe: function(description, specDefinitions) {
+ return env.describe(description, specDefinitions);
+ },
+
+ xdescribe: function(description, specDefinitions) {
+ return env.xdescribe(description, specDefinitions);
+ },
+
+ it: function(desc, func) {
+ return env.it(desc, func);
+ },
+
+ xit: function(desc, func) {
+ return env.xit(desc, func);
+ },
+
+ beforeEach: function(beforeEachFunction) {
+ return env.beforeEach(beforeEachFunction);
+ },
+
+ afterEach: function(afterEachFunction) {
+ return env.afterEach(afterEachFunction);
+ },
+
+ expect: function(actual) {
+ return env.expect(actual);
+ },
+
+ addMatchers: function(matchers) {
+ return env.addMatchers(matchers);
+ },
+
+ spyOn: function(obj, methodName) {
+ return env.spyOn(obj, methodName);
+ },
+
+ clock: env.clock,
+ setTimeout: env.clock.setTimeout,
+ clearTimeout: env.clock.clearTimeout,
+ setInterval: env.clock.setInterval,
+ clearInterval: env.clock.clearInterval,
+
+ jsApiReporter: new jasmine.JsApiReporter(jasmine)
+};
+
+for (var k in jasmineInterface) {
+ global[k] = jasmineInterface[k];
+}
+
require('../src/console/ConsoleReporter.js');
/*
@@ -31,13 +83,19 @@ function noop() {
}
jasmine.executeSpecs = function(specs, done, isVerbose, showColors) {
+ global.originalJasmine = jasmine;
+
for (var i = 0, len = specs.length; i < len; ++i) {
var filename = specs[i];
require(filename.replace(/\.\w+$/, ""));
}
var jasmineEnv = jasmine.getEnv();
- var consoleReporter = new jasmine.ConsoleReporter(util.print, done, showColors);
+ var consoleReporter = new jasmine.ConsoleReporter({
+ print: util.print,
+ onComplete: done,
+ showColors: showColors
+ });
jasmineEnv.addReporter(consoleReporter);
jasmineEnv.execute();
@@ -110,16 +168,17 @@ process.argv.forEach(function(arg) {
}
});
-var specs = jasmine.getAllSpecFiles(__dirname, new RegExp(".js$"));
+// var specs = jasmine.getAllSpecFiles(__dirname + '/smoke', new RegExp("test.js$"));
+var specs = jasmine.getAllSpecFiles(__dirname, new RegExp("Spec.js$"));
var domIndependentSpecs = [];
for (var i = 0; i < specs.length; i++) {
- if (fs.readFileSync(specs[i], "utf8").indexOf("document.createElement") < 0) {
+ if (!specs[i].match('html')) {
domIndependentSpecs.push(specs[i]);
}
}
-jasmine.executeSpecs(domIndependentSpecs, function(runner, log) {
- if (runner.results().failedCount === 0) {
+jasmine.executeSpecs(domIndependentSpecs, function(passed) {
+ if (passed) {
process.exit(0);
} else {
process.exit(1);
diff --git a/spec/runner.html b/spec/runner.html
index 0cde61fb..461632ad 100644
--- a/spec/runner.html
+++ b/spec/runner.html
@@ -1,5 +1,5 @@
+ "http://www.w3.org/TR/html4/loose.dtd">