lib/jazrb/jasmine/jasmine.js in smparkes-jazrb-0.0.10 vs lib/jazrb/jasmine/jasmine.js in smparkes-jazrb-0.0.11

- old
+ new

@@ -17,11 +17,11 @@ * */ jasmine.DEFAULT_UPDATE_INTERVAL = 250; /** - * Allows for bound functions to be comapred. Internal use only. + * Allows for bound functions to be compared. Internal use only. * * @ignore * @private * @param base {Object} bound 'this' for the function * @param name {Function} function to find @@ -324,10 +324,20 @@ return spyObj; }; /** + * Determines whether an object is a spy. + * + * @param {jasmine.Spy|Object} putativeSpy + * @returns {Boolean} + */ +jasmine.isSpy = function(putativeSpy) { + return putativeSpy && putativeSpy.isSpy; +}; + +/** * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something * large in one call. * * @param {String} baseName name of spy class * @param {Array} methodNames array of names of methods to make spies @@ -390,10 +400,19 @@ */ var xit = function(desc, func) { return jasmine.getEnv().xit(desc, func); }; +jasmine.pending_ = function(){ + Error.call(this,"Pending"); +}; +jasmine.pending_.prototype = new Error; + +var pending = function() { + throw new jasmine.pending_; +}; + /** * 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. @@ -550,11 +569,11 @@ jasmine.version_= { "major": 0, "minor": 10, "build": 0, - "revision": 1258603168 + "revision": 1259177226 }; /** * @namespace */ jasmine.util = {}; @@ -631,19 +650,30 @@ this.currentSuite = null; this.currentRunner_ = new jasmine.Runner(this); this.reporter = new jasmine.MultiReporter(); - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL + this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; 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); + + for (var methodName in jasmine.Matchers.prototype) { + var orig = jasmine.Matchers.prototype[methodName]; + this.matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); + } }; jasmine.Env.prototype.setTimeout = jasmine.setTimeout; jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; @@ -736,24 +766,25 @@ jasmine.Env.prototype.it = function(description, func) { var spec = new jasmine.Spec(this, this.currentSuite, description); this.currentSuite.add(spec); this.currentSpec = spec; + spec.pending = false; if (func) { spec.runs(func); + } else { + spec.pending = true; } return spec; }; -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; +jasmine.Env.prototype.xit = function(description, func) { + var spec = this.it(description, func); + spec.pending = -1; + return spec; }; jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { return true; @@ -886,13 +917,19 @@ this.spec = spec; }; jasmine.Block.prototype.execute = function(onComplete) { try { - this.func.apply(this.spec); + if(!this.spec.pending){ + this.func.apply(this.spec); + } } catch (e) { - this.spec.fail(e); + if(e instanceof jasmine.pending_){ + this.spec.pending = true; + } else { + this.spec && this.spec.fail(e); + } } onComplete(); }; /** JavaScript API reporter. * @@ -973,11 +1010,12 @@ return results; }; jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ var summaryMessages = []; - for (var messageIndex in result.messages) { + var messagesLength = result.messages.length + for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { var resultMessage = result.messages[messageIndex]; summaryMessages.push({ text: resultMessage.text, passed: resultMessage.passed ? resultMessage.passed() : true, type: resultMessage.type, @@ -1020,19 +1058,29 @@ }); this.spec.addMatcherResult(expectationResult); return result; }; -jasmine.Matchers.matcherFn_ = function(matcherName, options) { - return function () { - jasmine.util.extend(this, options); +jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { + return function() { var matcherArgs = jasmine.util.argsToArray(arguments); - var args = [this.actual].concat(matcherArgs); - var result = options.test.apply(this, args); + var result = matcherFunction.apply(this, arguments); var message; if (!result) { - message = options.message.apply(this, args); + if (this.message) { + message = this.message.apply(this, arguments); + } else { + var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + message = "Expected " + jasmine.pp(this.actual) + " " + englishyPredicate; + if (matcherArgs.length > 0) { + for (var i = 0; i < matcherArgs.length; i++) { + if (i > 0) message += ","; + message += " " + jasmine.pp(matcherArgs[i]); + } + } + message += "."; + } } var expectationResult = new jasmine.ExpectationResult({ matcherName: matcherName, passed: result, expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], @@ -1050,317 +1098,213 @@ /** * toBe: compares the actual to the expected using === * @param expected */ -jasmine.Matchers.prototype.toBe = jasmine.Matchers.matcherFn_('toBe', { - test: function (actual, expected) { - return actual === expected; - }, - message: function(actual, expected) { - return "Expected " + jasmine.pp(actual) + " to be " + jasmine.pp(expected); - } -}); +jasmine.Matchers.prototype.toBe = function(expected) { + return this.actual === expected; +}; /** * toNotBe: compares the actual to the expected using !== * @param expected */ -jasmine.Matchers.prototype.toNotBe = jasmine.Matchers.matcherFn_('toNotBe', { - test: function (actual, expected) { - return actual !== expected; - }, - message: function(actual, expected) { - return "Expected " + jasmine.pp(actual) + " to not be " + jasmine.pp(expected); - } -}); +jasmine.Matchers.prototype.toNotBe = function(expected) { + return this.actual !== expected; +}; /** * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. * * @param expected */ -jasmine.Matchers.prototype.toEqual = jasmine.Matchers.matcherFn_('toEqual', { - test: function (actual, expected) { - return this.env.equals_(actual, expected); - }, - message: function(actual, expected) { - return "Expected " + jasmine.pp(actual) + " to equal " + jasmine.pp(expected); - } -}); +jasmine.Matchers.prototype.toEqual = function(expected) { + return this.env.equals_(this.actual, expected); +}; /** * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual * @param expected */ -jasmine.Matchers.prototype.toNotEqual = jasmine.Matchers.matcherFn_('toNotEqual', { - test: function (actual, expected) { - return !this.env.equals_(actual, expected); - }, - message: function(actual, expected) { - return "Expected " + jasmine.pp(actual) + " to not equal " + jasmine.pp(expected); - } -}); +jasmine.Matchers.prototype.toNotEqual = function(expected) { + return !this.env.equals_(this.actual, expected); +}; /** * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes * a pattern or a String. * * @param reg_exp */ -jasmine.Matchers.prototype.toMatch = jasmine.Matchers.matcherFn_('toMatch', { - test: function(actual, expected) { - return new RegExp(expected).test(actual); - }, - message: function(actual, expected) { - return jasmine.pp(actual) + " does not match the regular expression " + new RegExp(expected).toString(); - } -}); +jasmine.Matchers.prototype.toMatch = function(expected) { + return new RegExp(expected).test(this.actual); +}; /** * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch * @param reg_exp */ +jasmine.Matchers.prototype.toNotMatch = function(expected) { + return !(new RegExp(expected).test(this.actual)); +}; -jasmine.Matchers.prototype.toNotMatch = jasmine.Matchers.matcherFn_('toNotMatch', { - test: function(actual, expected) { - return !(new RegExp(expected).test(actual)); - }, - message: function(actual, expected) { - return jasmine.pp(actual) + " should not match " + new RegExp(expected).toString(); - } -}); - /** - * Matcher that compares the acutal to undefined. + * Matcher that compares the actual to undefined. */ +jasmine.Matchers.prototype.toBeDefined = function() { + return (this.actual !== undefined); +}; -jasmine.Matchers.prototype.toBeDefined = jasmine.Matchers.matcherFn_('toBeDefined', { - test: function(actual) { - return (actual !== undefined); - }, - message: function() { - return 'Expected actual to not be undefined.'; - } -}); - /** - * Matcher that compares the acutal to undefined. + * Matcher that compares the actual to undefined. */ +jasmine.Matchers.prototype.toBeUndefined = function() { + return (this.actual === undefined); +}; -jasmine.Matchers.prototype.toBeUndefined = jasmine.Matchers.matcherFn_('toBeUndefined', { - test: function(actual) { - return (actual === undefined); - }, - message: function(actual) { - return 'Expected ' + jasmine.pp(actual) + ' to be undefined.'; - } -}); - /** * Matcher that compares the actual to null. - * */ -jasmine.Matchers.prototype.toBeNull = jasmine.Matchers.matcherFn_('toBeNull', { - test: function(actual) { - return (actual === null); - }, - message: function(actual) { - return 'Expected ' + jasmine.pp(actual) + ' to be null.'; - } -}); +jasmine.Matchers.prototype.toBeNull = function() { + return (this.actual === null); +}; /** * Matcher that boolean not-nots the actual. */ -jasmine.Matchers.prototype.toBeTruthy = jasmine.Matchers.matcherFn_('toBeTruthy', { - test: function(actual) { - return !!actual; - }, - message: function() { - return 'Expected actual to be truthy'; - } -}); +jasmine.Matchers.prototype.toBeTruthy = function() { + return !!this.actual; +}; /** * Matcher that boolean nots the actual. */ -jasmine.Matchers.prototype.toBeFalsy = jasmine.Matchers.matcherFn_('toBeFalsy', { - test: function(actual) { - return !actual; - }, - message: function(actual) { - return 'Expected ' + jasmine.pp(actual) + ' to be falsy'; - } -}); +jasmine.Matchers.prototype.toBeFalsy = function() { + return !this.actual; +}; /** - * Matcher that checks to see if the acutal, a Jasmine spy, was called. + * Matcher that checks to see if the actual, a Jasmine spy, was called. */ +jasmine.Matchers.prototype.wasCalled = function() { + if (arguments.length > 0) { + throw new Error('wasCalled does not take arguments, use wasCalledWith'); + } -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.matcherFn_('wasCalled', { - getActual_: function() { - var args = jasmine.util.argsToArray(arguments); - if (args.length > 1) { - throw(new Error('wasCalled does not take arguments, use wasCalledWith')); - } - return args.splice(0, 1)[0]; - }, - test: function() { - var actual = this.getActual_.apply(this, arguments); - if (!actual || !actual.isSpy) { - return false; - } - return actual.wasCalled; - }, - message: function() { - var actual = this.getActual_.apply(this, arguments); - if (!actual || !actual.isSpy) { - return 'Actual is not a spy.'; - } - return "Expected spy " + actual.identity + " to have been called."; + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.'); } -}); + this.message = function() { + return "Expected spy " + this.actual.identity + " to have been called."; + }; + + return this.actual.wasCalled; +}; + /** - * Matcher that checks to see if the acutal, a Jasmine spy, was not called. + * Matcher that checks to see if the actual, a Jasmine spy, was not called. */ -jasmine.Matchers.prototype.wasNotCalled = jasmine.Matchers.matcherFn_('wasNotCalled', { - getActual_: function() { - var args = jasmine.util.argsToArray(arguments); - return args.splice(0, 1)[0]; - }, - test: function() { - var actual = this.getActual_.apply(this, arguments); - if (!actual || !actual.isSpy) { - return false; - } - return !actual.wasCalled; - }, - message: function() { - var actual = this.getActual_.apply(this, arguments); - if (!actual || !actual.isSpy) { - return 'Actual is not a spy.'; - } - return "Expected spy " + actual.identity + " to not have been called."; +jasmine.Matchers.prototype.wasNotCalled = function() { + if (arguments.length > 0) { + throw new Error('wasNotCalled does not take arguments'); } -}); -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.matcherFn_('wasCalledWith', { - test: function() { - var args = jasmine.util.argsToArray(arguments); - var actual = args.splice(0, 1)[0]; - if (!actual || !actual.isSpy) { - return false; - } - return this.env.contains_(actual.argsForCall, args); - }, - message: function() { - var args = jasmine.util.argsToArray(arguments); - var actual = args.splice(0, 1)[0]; - var message; - if (!actual || !actual.isSpy) { - message = 'Actual is not a spy'; - } else { - message = "Expected spy to have been called with " + jasmine.pp(args) + " but was called with " + actual.argsForCall; - } - return message; + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.'); } -}); + this.message = function() { + return "Expected spy " + this.actual.identity + " to not have been called."; + }; + + return !this.actual.wasCalled; +}; + /** - * Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters. + * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. * * @example * */ +jasmine.Matchers.prototype.wasCalledWith = function() { + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.'); + } + this.message = function() { + return "Expected spy to have been called with " + jasmine.pp(arguments) + " but was called with " + jasmine.pp(this.actual.argsForCall); + }; + + return this.env.contains_(this.actual.argsForCall, jasmine.util.argsToArray(arguments)); +}; + /** * Matcher that checks that the expected item is an element in the actual Array. * * @param {Object} item */ +jasmine.Matchers.prototype.toContain = function(expected) { + return this.env.contains_(this.actual, expected); +}; -jasmine.Matchers.prototype.toContain = jasmine.Matchers.matcherFn_('toContain', { - test: function(actual, expected) { - return this.env.contains_(actual, expected); - }, - message: function(actual, expected) { - return 'Expected ' + jasmine.pp(actual) + ' to contain ' + jasmine.pp(expected); - } -}); - /** * Matcher that checks that the expected item is NOT an element in the actual Array. * * @param {Object} item */ -jasmine.Matchers.prototype.toNotContain = jasmine.Matchers.matcherFn_('toNotContain', { - test: function(actual, expected) { - return !this.env.contains_(actual, expected); - }, - message: function(actual, expected) { - return 'Expected ' + jasmine.pp(actual) + ' to not contain ' + jasmine.pp(expected); - } -}); +jasmine.Matchers.prototype.toNotContain = function(expected) { + return !this.env.contains_(this.actual, expected); +}; -jasmine.Matchers.prototype.toBeLessThan = jasmine.Matchers.matcherFn_('toBeLessThan', { - test: function(actual, expected) { - return actual < expected; - }, - message: function(actual, expected) { - return 'Expected ' + jasmine.pp(actual) + ' to be less than ' + jasmine.pp(expected); - } -}); +jasmine.Matchers.prototype.toBeLessThan = function(expected) { + return this.actual < expected; +}; -jasmine.Matchers.prototype.toBeGreaterThan = jasmine.Matchers.matcherFn_('toBeGreaterThan', { - test: function(actual, expected) { - return actual > expected; - }, - message: function(actual, expected) { - return 'Expected ' + jasmine.pp(actual) + ' to be greater than ' + jasmine.pp(expected); - } -}); +jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { + return this.actual > expected; +}; /** * Matcher that checks that the expected exception was thrown by the actual. * * @param {String} expectedException */ -jasmine.Matchers.prototype.toThrow = jasmine.Matchers.matcherFn_('toThrow', { - getException_: function(actual, expected) { +jasmine.Matchers.prototype.toThrow = function(expected) { + function getException_(actual, expected) { var exception; if (typeof actual != 'function') { throw new Error('Actual is not a function'); } try { actual(); } catch (e) { exception = e; } return exception; - }, - test: function(actual, expected) { - var result = false; - var exception = this.getException_(actual, expected); - if (exception) { - result = (expected === undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - return result; - }, - message: function(actual, expected) { - var exception = this.getException_(actual, expected); + } + + var result = false; + var exception = getException_(this.actual, expected); + if (exception) { + result = (expected === undefined || this.env.equals_(exception.message || exception, expected.message || expected)); + } + + this.message = function(expected) { + var exception = getException_(this.actual, expected); if (exception && (expected === undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { return ["Expected function to throw", expected.message || expected, ", but it threw", exception.message || exception ].join(' '); } else { return "Expected function to throw an exception."; } - } -}); + }; + return result; +}; + jasmine.Matchers.Any = function(expectedClass) { this.expectedClass = expectedClass; }; jasmine.Matchers.Any.prototype.matches = function(other) { @@ -1504,15 +1448,13 @@ /** * Formats a value in a nice, human-readable string. * * @param value - * @returns {String} */ jasmine.PrettyPrinter.prototype.format = function(value) { if (this.ppNestLevel_ > 40) { - // return '(jasmine.pp nested too deeply!)'; throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); } this.ppNestLevel_++; try { @@ -1524,16 +1466,20 @@ this.emitScalar('<window>'); } else if (value instanceof jasmine.Matchers.Any) { this.emitScalar(value.toString()); } else if (typeof value === 'string') { this.emitString(value); + } else if (jasmine.isSpy(value)) { + this.emitScalar("spy on " + value.identity); } else if (typeof value === 'function') { this.emitScalar('Function'); } else if (typeof value.nodeType === 'number') { this.emitScalar('HTMLNode'); } else if (value instanceof Date) { this.emitScalar('Date(' + value + ')'); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); } else if (value.__Jasmine_been_here_before__) { this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>'); } else if (jasmine.isArray_(value) || typeof value == 'object') { value.__Jasmine_been_here_before__ = true; if (jasmine.isArray_(value)) { @@ -1847,15 +1793,13 @@ */ jasmine.Spec = function(env, suite, description) { if (!env) { throw new Error('jasmine.Env() required'); } - ; if (!suite) { throw new Error('jasmine.Suite() required'); } - ; var spec = this; spec.id = env.nextSpecId ? env.nextSpecId() : null; spec.env = env; spec.suite = suite; spec.description = description; @@ -1888,10 +1832,11 @@ }; jasmine.Spec.prototype.runs = function (func) { var block = new jasmine.Block(this.env, func, this); this.addToQueue(block); + ( this.pending != -1 ) && ( this.pending = false ); return this; }; jasmine.Spec.prototype.addToQueue = function (block) { if (this.queue.isRunning()) { @@ -1941,10 +1886,10 @@ }); this.results_.addResult(expectationResult); }; jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || jasmine.Matchers; + return this.matchersClass || this.env.matchersClass; }; jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { var parent = this.getMatchersClass_(); var newMatchersClass = function() {