Added grunt to project.

Move from embedded "fork" of jsHint to using grunt's jsHint module.
Cleaned ALL jsHint errors.
Added jasmine.util.isUndefined as alternative to extra careful protection against undefined clobbering
This commit is contained in:
Dan Hansen and Davis W. Frank
2013-03-01 14:24:30 -08:00
parent b22bf9a031
commit cf7bb0269b
27 changed files with 146 additions and 6181 deletions
+2 -1
View File
@@ -11,4 +11,5 @@ tags
Gemfile.lock Gemfile.lock
pkg/* pkg/*
.sass-cache/* .sass-cache/*
src/html/.sass-cache/* src/html/.sass-cache/*
node_modules/
-1
View File
@@ -41,5 +41,4 @@ There are Thor tasks to help with getting green - run `thor list` to see them al
* `thor jasmine_dev:execute_specs` outputs the expected number of specs that should be run and attempts to run in browser and Node * `thor jasmine_dev:execute_specs` outputs the expected number of specs that should be run and attempts to run in browser and Node
* `thor jasmine_dev:execute_specs_in_browser` opens `spec/runner.html` in the default browser on MacOS. Please run this in at least Firefox and Chrome before committing * `thor jasmine_dev:execute_specs_in_browser` opens `spec/runner.html` in the default browser on MacOS. Please run this in at least Firefox and Chrome before committing
* `thor jasmine_dev:execute_specs_in_node` runs all the Jasmine specs in Node.js - it will complain if Node is not installed * `thor jasmine_dev:execute_specs_in_node` runs all the Jasmine specs in Node.js - it will complain if Node is not installed
* `thor jasmine_dev:js_hint` runs all the files through JSHint and will complain about potential viable issues with your code. Fix them.
+10
View File
@@ -44,3 +44,13 @@
* Docs * Docs
* JsDoc is a pain to host and RubyMine is pretty good at navigating. I say we kill it officially * 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? * 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?
# Build
* lib -> generated
*
+24
View File
@@ -0,0 +1,24 @@
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
options: {
/* While it's possible that we could be considering unwanted prototype methods, mostly
* we're doing this because the objects are being used as maps.
*/
forin: false,
/* We're fine with functions defined inside loops (setTimeout functions, etc) */
loopfunc: true
},
all: ['src/**/*.js']
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
// Default task(s).
grunt.registerTask('default', ['jshint']);
};
+5
View File
@@ -7,6 +7,11 @@ Jasmine is a Behavior Driven Development testing framework for JavaScript. It do
Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/) Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/)
# DEV GUIDE
Dependencies for this repo
* Ruby > 1.9, Rubygems, Bundler
* Node.js, npm
## Support ## Support
-5919
View File
File diff suppressed because it is too large Load Diff
-99
View File
@@ -1,99 +0,0 @@
var fs = require("fs");
var util = require("util");
var path = require("path");
var JSHINT = require("./jshint").JSHINT;
// DWF TODO: Standardize this?
function isExcluded(fullPath) {
var fileName = path.basename(fullPath);
var excludeFiles = ["json2.js", "jshint.js", "publish.js", "node_suite.js", "jasmine.js", "jasmine-html.js"];
for (var i = 0; i < excludeFiles.length; i++) {
if (fileName == excludeFiles[i]) {
return true;
}
}
return false;
}
// DWF TODO: This function could/should be re-written
function allJasmineJsFiles(rootDir) {
var files = [];
fs.readdirSync(rootDir).filter(function(filename) {
var fullPath = rootDir + "/" + filename;
if (fs.statSync(fullPath).isDirectory() && !fullPath.match(/pages/)) {
var subDirFiles = allJasmineJsFiles(fullPath);
if (subDirFiles.length > 0) {
files = files.concat();
return true;
}
} else {
if (fullPath.match(/\.js$/) && !isExcluded(fullPath)) {
files.push(fullPath);
return true;
}
}
return false;
});
return files;
}
var jasmineJsFiles = allJasmineJsFiles(".");
jasmineJsFiles.reverse(); //cheap way to do the stuff in src stuff first
var jasmineJsHintConfig = {
forin:true, //while it's possible that we could be
//considering unwanted prototype methods, mostly
//we're doing this because the jsobjects are being
//used as maps.
loopfunc:true //we're fine with functions defined inside loops (setTimeout functions, etc)
};
var jasmineGlobals = {};
//jasmine.undefined is a jasmine-ism, let's let it go...
function removeJasmineUndefinedErrors(errors) {
var keepErrors = [];
for (var i = 0; i < errors.length; i++) {
if (!(errors[i] &&
errors[i].raw &&
errors[i].evidence &&
( errors[i].evidence.match(/jasmine\.undefined/) ||
errors[i].evidence.match(/diz be undefined yo/) )
)) {
keepErrors.push(errors[i]);
}
}
return keepErrors;
}
(function() {
var ansi = {
green: '\033[32m',
red: '\033[31m',
yellow: '\033[33m',
none: '\033[0m'
};
for (var i = 0; i < jasmineJsFiles.length; i++) {
var file = jasmineJsFiles[i];
JSHINT(fs.readFileSync(file, "utf8"), jasmineJsHintConfig);
var errors = JSHINT.data().errors || [];
errors = removeJasmineUndefinedErrors(errors);
if (errors.length >= 1) {
console.log(ansi.red + "Jasmine JSHint failure: " + ansi.none);
console.log(file);
console.log(errors);
process.exit(1);
}
}
console.log(ansi.green + "Jasmine JSHint PASSED." + ansi.none);
})();
+44 -46
View File
@@ -8,7 +8,7 @@ var jasmine = {};
// TODO: do we need this now that we have boot.js? // TODO: do we need this now that we have boot.js?
if (typeof window == "undefined" && typeof exports == "object") { if (typeof window == "undefined" && typeof exports == "object") {
exports.jasmine = jasmine exports.jasmine = jasmine;
} }
/** /**
@@ -18,14 +18,6 @@ jasmine.unimplementedMethod_ = function() {
throw new Error("unimplemented method"); throw new Error("unimplemented method");
}; };
/**
* Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
* a plain old variable and may be redefined by somebody else.
*
* @private
*/
jasmine.undefined = jasmine.___undefined___;
/** /**
* Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
* *
@@ -439,18 +431,23 @@ jasmine.util.argsToArray = function(args) {
var arrayOfArgs = []; var arrayOfArgs = [];
for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
return arrayOfArgs; return arrayOfArgs;
};jasmine.ExceptionFormatter = function() { };
jasmine.util.isUndefined = function(obj) {
return obj === void 0;
};
jasmine.ExceptionFormatter = function() {
this.message = function(error) { this.message = function(error) {
var message = error.name var message = error.name +
+ ': ' ': ' +
+ error.message; error.message;
if (error.fileName || error.sourceURL) { if (error.fileName || error.sourceURL) {
message += " in " + (error.fileName || error.sourceURL); message += " in " + (error.fileName || error.sourceURL);
} }
if (error.line || error.lineNumber) { if (error.line || error.lineNumber) {
message += " (line " + (error.line || error.lineNumber) + ")" message += " (line " + (error.line || error.lineNumber) + ")";
} }
return message; return message;
@@ -458,7 +455,7 @@ jasmine.util.argsToArray = function(args) {
this.stack = function(error) { this.stack = function(error) {
return error ? error.stack : null; return error ? error.stack : null;
} };
};//TODO: expectation result may make more sense as a presentation of an expectation. };//TODO: expectation result may make more sense as a presentation of an expectation.
jasmine.buildExpectationResult = function(options) { jasmine.buildExpectationResult = function(options) {
var messageFormatter = options.messageFormatter || function() {}, var messageFormatter = options.messageFormatter || function() {},
@@ -475,13 +472,13 @@ jasmine.buildExpectationResult = function(options) {
function message() { function message() {
if (options.passed) { if (options.passed) {
return "Passed." return "Passed.";
} else if (options.message) { } else if (options.message) {
return options.message return options.message;
} else if (options.error) { } else if (options.error) {
return messageFormatter(options.error); return messageFormatter(options.error);
} }
return "" return "";
} }
function stack() { function stack() {
@@ -514,8 +511,6 @@ jasmine.buildExpectationResult = function(options) {
this.spies_ = []; this.spies_ = [];
this.currentSpec = null; this.currentSpec = null;
this.undefined = jasmine.undefined;
this.reporter = new jasmine.ReportDispatcher([ this.reporter = new jasmine.ReportDispatcher([
"jasmineStarted", "jasmineStarted",
"jasmineDone", "jasmineDone",
@@ -557,20 +552,20 @@ jasmine.buildExpectationResult = function(options) {
return function() { return function() {
var befores = []; var befores = [];
for (var suite = currentSuite; suite; suite = suite.parentSuite) { for (var suite = currentSuite; suite; suite = suite.parentSuite) {
befores = befores.concat(suite.beforeFns) befores = befores.concat(suite.beforeFns);
} }
return befores.reverse(); return befores.reverse();
} };
}; };
var afterFns = function(currentSuite) { var afterFns = function(currentSuite) {
return function() { return function() {
var afters = []; var afters = [];
for (var suite = currentSuite; suite; suite = suite.parentSuite) { for (var suite = currentSuite; suite; suite = suite.parentSuite) {
afters = afters.concat(suite.afterFns) afters = afters.concat(suite.afterFns);
} }
return afters; return afters;
} };
}; };
var specConstructor = jasmine.Spec; var specConstructor = jasmine.Spec;
@@ -635,7 +630,7 @@ jasmine.buildExpectationResult = function(options) {
exceptionFormatter: exceptionFormatter, exceptionFormatter: exceptionFormatter,
resultCallback: specResultCallback, resultCallback: specResultCallback,
getSpecName: function(spec) { getSpecName: function(spec) {
return getSpecName(spec, suite) return getSpecName(spec, suite);
}, },
onStart: specStarted, onStart: specStarted,
description: description, description: description,
@@ -720,11 +715,11 @@ jasmine.buildExpectationResult = function(options) {
}; };
jasmine.Env.prototype.spyOn = function(obj, methodName) { jasmine.Env.prototype.spyOn = function(obj, methodName) {
if (obj == this.undefined) { if (jasmine.util.isUndefined(obj)) {
throw "spyOn could not find an object to spy upon for " + methodName + "()"; throw "spyOn could not find an object to spy upon for " + methodName + "()";
} }
if (obj[methodName] === this.undefined) { if (jasmine.util.isUndefined(obj[methodName])) {
throw methodName + '() method does not exist'; throw methodName + '() method does not exist';
} }
@@ -879,7 +874,7 @@ jasmine.buildExpectationResult = function(options) {
b.__Jasmine_been_here_before__ = a; b.__Jasmine_been_here_before__ = a;
var hasKey = function(obj, keyName) { var hasKey = function(obj, keyName) {
return obj !== null && obj[keyName] !== this.undefined; return obj !== null && !jasmine.util.isUndefined(obj[keyName]);
}; };
for (var property in b) { for (var property in b) {
@@ -915,13 +910,15 @@ jasmine.buildExpectationResult = function(options) {
for (var i = 0; i < this.equalityTesters_.length; i++) { for (var i = 0; i < this.equalityTesters_.length; i++) {
var equalityTester = this.equalityTesters_[i]; var equalityTester = this.equalityTesters_[i];
var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
if (result !== this.undefined) return result; if (!jasmine.util.isUndefined(result)) {
return result;
}
} }
if (a === b) return true; if (a === b) return true;
if (a === this.undefined || a === null || b === this.undefined || b === null) { if (jasmine.util.isUndefined(a) || a === null || jasmine.util.isUndefined(b) || b === null) {
return (a == this.undefined && b == this.undefined); return (jasmine.util.isUndefined(a) && jasmine.util.isUndefined(b));
} }
if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
@@ -1099,7 +1096,7 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
actual: this.actual, actual: this.actual,
message: message message: message
}); });
return jasmine.undefined; return void 0;
}; };
}; };
@@ -1162,14 +1159,14 @@ jasmine.Matchers.prototype.toNotMatch = function(expected) {
* Matcher that compares the actual to jasmine.undefined. * Matcher that compares the actual to jasmine.undefined.
*/ */
jasmine.Matchers.prototype.toBeDefined = function() { jasmine.Matchers.prototype.toBeDefined = function() {
return (this.actual !== jasmine.undefined); return !jasmine.util.isUndefined(this.actual);
}; };
/** /**
* Matcher that compares the actual to jasmine.undefined. * Matcher that compares the actual to jasmine.undefined.
*/ */
jasmine.Matchers.prototype.toBeUndefined = function() { jasmine.Matchers.prototype.toBeUndefined = function() {
return (this.actual === jasmine.undefined); return jasmine.util.isUndefined(this.actual);
}; };
/** /**
@@ -1272,7 +1269,7 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
if (this.actual.callCount === 0) { if (this.actual.callCount === 0) {
positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called."; positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
} else { } else {
positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '') positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '');
} }
return [positiveMessage, invertedMessage]; return [positiveMessage, invertedMessage];
}; };
@@ -1335,7 +1332,7 @@ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
* @param {Number} precision, as number of decimal places * @param {Number} precision, as number of decimal places
*/ */
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
if (!(precision === 0)) { if (precision !== 0) {
precision = precision || 2; precision = precision || 2;
} }
return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2); return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
@@ -1357,14 +1354,15 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
} catch (e) { } catch (e) {
exception = e; exception = e;
} }
if (exception) { if (exception) {
result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); result = (jasmine.util.isUndefined(expected) || this.env.equals_(exception.message || exception, expected.message || expected));
} }
var not = this.isNot ? "not " : ""; var not = this.isNot ? "not " : "";
this.message = function() { this.message = function() {
if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { if (exception && (jasmine.util.isUndefined(expected) || !this.env.equals_(exception.message || exception, expected.message || expected))) {
return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
} else { } else {
return "Expected function to throw an exception."; return "Expected function to throw an exception.";
@@ -1413,7 +1411,7 @@ jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mis
var env = jasmine.getEnv(); var env = jasmine.getEnv();
var hasKey = function(obj, keyName) { var hasKey = function(obj, keyName) {
return obj != null && obj[keyName] !== jasmine.undefined; return obj !== null && !jasmine.util.isUndefined(obj[keyName]);
}; };
for (var property in this.sample) { for (var property in this.sample) {
@@ -1446,7 +1444,7 @@ jasmine.PrettyPrinter = function() {
jasmine.PrettyPrinter.prototype.format = function(value) { jasmine.PrettyPrinter.prototype.format = function(value) {
this.ppNestLevel_++; this.ppNestLevel_++;
try { try {
if (value === jasmine.undefined) { if (jasmine.util.isUndefined(value)) {
this.emitScalar('undefined'); this.emitScalar('undefined');
} else if (value === null) { } else if (value === null) {
this.emitScalar('null'); this.emitScalar('null');
@@ -1488,7 +1486,7 @@ jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
for (var property in obj) { for (var property in obj) {
if (!obj.hasOwnProperty(property)) continue; if (!obj.hasOwnProperty(property)) continue;
if (property == '__Jasmine_been_here_before__') continue; if (property == '__Jasmine_been_here_before__') continue;
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && fn(property, obj.__lookupGetter__ ? (!jasmine.util.isUndefined(obj.__lookupGetter__(property)) &&
obj.__lookupGetter__(property) !== null) : false); obj.__lookupGetter__(property) !== null) : false);
} }
}; };
@@ -1564,13 +1562,13 @@ jasmine.StringPrettyPrinter.prototype.append = function(value) {
jasmine.QueueRunner = function(attrs) { jasmine.QueueRunner = function(attrs) {
this.fns = attrs.fns || []; this.fns = attrs.fns || [];
this.onComplete = attrs.onComplete || function() {}; this.onComplete = attrs.onComplete || function() {};
this.encourageGC = attrs.encourageGC || function(fn) {fn()}; this.encourageGC = attrs.encourageGC || function(fn) {fn();};
this.onException = attrs.onException || function() {}; this.onException = attrs.onException || function() {};
this.catchException = attrs.catchException || function() { return true; }; this.catchException = attrs.catchException || function() { return true; };
}; };
jasmine.QueueRunner.prototype.execute = function() { jasmine.QueueRunner.prototype.execute = function() {
this.run(this.fns, 0) this.run(this.fns, 0);
}; };
jasmine.QueueRunner.prototype.run = function(fns, index) { jasmine.QueueRunner.prototype.run = function(fns, index) {
@@ -1582,7 +1580,7 @@ jasmine.QueueRunner.prototype.run = function(fns, index) {
var fn = fns[index]; var fn = fns[index];
var self = this; var self = this;
if (fn.length > 0) { if (fn.length > 0) {
attempt(function() { fn.call(self, function() { self.run(fns, index + 1) }) }); attempt(function() { fn.call(self, function() { self.run(fns, index + 1); }); });
} else { } else {
attempt(function() { fn.call(self); }); attempt(function() { fn.call(self); });
self.run(fns, index + 1); self.run(fns, index + 1);
@@ -1814,7 +1812,7 @@ jasmine.Suite.prototype.execute = function(onComplete) {
function wrapChild(child) { function wrapChild(child) {
return function (done) { return function (done) {
child.execute(done); child.execute(done);
} };
} }
}; };
jasmine.Clock = function(global, delayedFunctionScheduler) { jasmine.Clock = function(global, delayedFunctionScheduler) {
@@ -1875,7 +1873,7 @@ jasmine.Clock = function(global, delayedFunctionScheduler) {
self.tick = function(millis) { self.tick = function(millis) {
if (installed) { if (installed) {
delayedFunctionScheduler.tick(millis) delayedFunctionScheduler.tick(millis);
} else { } else {
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
} }
+7
View File
@@ -0,0 +1,7 @@
{
"name": "jasmine-core",
"license": "MIT",
"devDependencies": {
"grunt-contrib-jshint": "~0.2.0"
}
}
+11
View File
@@ -14,4 +14,15 @@ describe("jasmine.util", function() {
expect(jasmine.isArray_(null)).toBe(false); expect(jasmine.isArray_(null)).toBe(false);
}); });
}); });
describe("isUndefined", function() {
it("reports if a variable is defined", function() {
var a;
expect(jasmine.util.isUndefined(a)).toBe(true);
expect(jasmine.util.isUndefined(undefined)).toBe(true);
var undefined = "diz be undefined yo";
expect(jasmine.util.isUndefined(undefined)).toBe(false);
});
});
}); });
-4
View File
@@ -2,10 +2,6 @@ var fs = require('fs');
var util = require('util'); var util = require('util');
var path = require('path'); 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'); var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
for (var k in jasmineGlobals) { for (var k in jasmineGlobals) {
global[k] = jasmineGlobals[k]; global[k] = jasmineGlobals[k];
-4
View File
@@ -2,10 +2,6 @@ var fs = require('fs');
var util = require('util'); var util = require('util');
var path = require('path'); 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'); var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
for (var k in jasmineGlobals) { for (var k in jasmineGlobals) {
global[k] = jasmineGlobals[k]; global[k] = jasmineGlobals[k];
-6
View File
@@ -20,12 +20,6 @@
var originalJasmine = jasmine; var originalJasmine = jasmine;
</script> </script>
<script type="text/javascript">
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
undefined = "diz be undefined yo";
</script>
<!-- include spec files here... --> <!-- include spec files here... -->
<script type="text/javascript" src=".././spec/console/ConsoleReporterSpec.js"></script> <script type="text/javascript" src=".././spec/console/ConsoleReporterSpec.js"></script>
<script type="text/javascript" src=".././spec/core/ClockSpec.js"></script> <script type="text/javascript" src=".././spec/core/ClockSpec.js"></script>
-39
View File
@@ -1,39 +0,0 @@
require 'spec_helper.rb'
describe "JSHint task" do
let(:tmp_dir) { "#{Dir.tmpdir}/jasmine_tasks_test" }
let(:jasmine_dev) { JasmineDev.new }
before do
reset_dir tmp_dir
end
describe "when Node is not present" do
before do
jasmine_dev.should_receive(:has_node?).and_return(false)
@output = capture_output { jasmine_dev.js_hint }
end
it "should not tell the user that lint is running" do
@output.should_not match(/Running JSHint/)
end
it "should prompt the user to install Node" do
@output.should match(/Node\.js is required/)
end
end
describe "when Node is present" do
before do
jasmine_dev.should_receive(:has_node?).and_return(true)
@output = capture_output { jasmine_dev.js_hint }
end
it "should tell the user that lint is running" do
@output.should match(/Running JSHint/)
@output.should match(/Jasmine JSHint PASSED/)
end
end
end
+1 -1
View File
@@ -56,7 +56,7 @@ jasmine.Clock = function(global, delayedFunctionScheduler) {
self.tick = function(millis) { self.tick = function(millis) {
if (installed) { if (installed) {
delayedFunctionScheduler.tick(millis) delayedFunctionScheduler.tick(millis);
} else { } else {
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
} }
+13 -13
View File
@@ -12,8 +12,6 @@
this.spies_ = []; this.spies_ = [];
this.currentSpec = null; this.currentSpec = null;
this.undefined = jasmine.undefined;
this.reporter = new jasmine.ReportDispatcher([ this.reporter = new jasmine.ReportDispatcher([
"jasmineStarted", "jasmineStarted",
"jasmineDone", "jasmineDone",
@@ -55,20 +53,20 @@
return function() { return function() {
var befores = []; var befores = [];
for (var suite = currentSuite; suite; suite = suite.parentSuite) { for (var suite = currentSuite; suite; suite = suite.parentSuite) {
befores = befores.concat(suite.beforeFns) befores = befores.concat(suite.beforeFns);
} }
return befores.reverse(); return befores.reverse();
} };
}; };
var afterFns = function(currentSuite) { var afterFns = function(currentSuite) {
return function() { return function() {
var afters = []; var afters = [];
for (var suite = currentSuite; suite; suite = suite.parentSuite) { for (var suite = currentSuite; suite; suite = suite.parentSuite) {
afters = afters.concat(suite.afterFns) afters = afters.concat(suite.afterFns);
} }
return afters; return afters;
} };
}; };
var specConstructor = jasmine.Spec; var specConstructor = jasmine.Spec;
@@ -133,7 +131,7 @@
exceptionFormatter: exceptionFormatter, exceptionFormatter: exceptionFormatter,
resultCallback: specResultCallback, resultCallback: specResultCallback,
getSpecName: function(spec) { getSpecName: function(spec) {
return getSpecName(spec, suite) return getSpecName(spec, suite);
}, },
onStart: specStarted, onStart: specStarted,
description: description, description: description,
@@ -218,11 +216,11 @@
}; };
jasmine.Env.prototype.spyOn = function(obj, methodName) { jasmine.Env.prototype.spyOn = function(obj, methodName) {
if (obj == this.undefined) { if (jasmine.util.isUndefined(obj)) {
throw "spyOn could not find an object to spy upon for " + methodName + "()"; throw "spyOn could not find an object to spy upon for " + methodName + "()";
} }
if (obj[methodName] === this.undefined) { if (jasmine.util.isUndefined(obj[methodName])) {
throw methodName + '() method does not exist'; throw methodName + '() method does not exist';
} }
@@ -377,7 +375,7 @@
b.__Jasmine_been_here_before__ = a; b.__Jasmine_been_here_before__ = a;
var hasKey = function(obj, keyName) { var hasKey = function(obj, keyName) {
return obj !== null && obj[keyName] !== this.undefined; return obj !== null && !jasmine.util.isUndefined(obj[keyName]);
}; };
for (var property in b) { for (var property in b) {
@@ -413,13 +411,15 @@
for (var i = 0; i < this.equalityTesters_.length; i++) { for (var i = 0; i < this.equalityTesters_.length; i++) {
var equalityTester = this.equalityTesters_[i]; var equalityTester = this.equalityTesters_[i];
var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
if (result !== this.undefined) return result; if (!jasmine.util.isUndefined(result)) {
return result;
}
} }
if (a === b) return true; if (a === b) return true;
if (a === this.undefined || a === null || b === this.undefined || b === null) { if (jasmine.util.isUndefined(a) || a === null || jasmine.util.isUndefined(b) || b === null) {
return (a == this.undefined && b == this.undefined); return (jasmine.util.isUndefined(a) && jasmine.util.isUndefined(b));
} }
if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
+5 -5
View File
@@ -1,15 +1,15 @@
jasmine.ExceptionFormatter = function() { jasmine.ExceptionFormatter = function() {
this.message = function(error) { this.message = function(error) {
var message = error.name var message = error.name +
+ ': ' ': ' +
+ error.message; error.message;
if (error.fileName || error.sourceURL) { if (error.fileName || error.sourceURL) {
message += " in " + (error.fileName || error.sourceURL); message += " in " + (error.fileName || error.sourceURL);
} }
if (error.line || error.lineNumber) { if (error.line || error.lineNumber) {
message += " (line " + (error.line || error.lineNumber) + ")" message += " (line " + (error.line || error.lineNumber) + ")";
} }
return message; return message;
@@ -17,5 +17,5 @@ jasmine.ExceptionFormatter = function() {
this.stack = function(error) { this.stack = function(error) {
return error ? error.stack : null; return error ? error.stack : null;
} };
}; };
+3 -3
View File
@@ -14,13 +14,13 @@ jasmine.buildExpectationResult = function(options) {
function message() { function message() {
if (options.passed) { if (options.passed) {
return "Passed." return "Passed.";
} else if (options.message) { } else if (options.message) {
return options.message return options.message;
} else if (options.error) { } else if (options.error) {
return messageFormatter(options.error); return messageFormatter(options.error);
} }
return "" return "";
} }
function stack() { function stack() {
+9 -8
View File
@@ -61,7 +61,7 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
actual: this.actual, actual: this.actual,
message: message message: message
}); });
return jasmine.undefined; return void 0;
}; };
}; };
@@ -124,14 +124,14 @@ jasmine.Matchers.prototype.toNotMatch = function(expected) {
* Matcher that compares the actual to jasmine.undefined. * Matcher that compares the actual to jasmine.undefined.
*/ */
jasmine.Matchers.prototype.toBeDefined = function() { jasmine.Matchers.prototype.toBeDefined = function() {
return (this.actual !== jasmine.undefined); return !jasmine.util.isUndefined(this.actual);
}; };
/** /**
* Matcher that compares the actual to jasmine.undefined. * Matcher that compares the actual to jasmine.undefined.
*/ */
jasmine.Matchers.prototype.toBeUndefined = function() { jasmine.Matchers.prototype.toBeUndefined = function() {
return (this.actual === jasmine.undefined); return jasmine.util.isUndefined(this.actual);
}; };
/** /**
@@ -234,7 +234,7 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
if (this.actual.callCount === 0) { if (this.actual.callCount === 0) {
positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called."; positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
} else { } else {
positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '') positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '');
} }
return [positiveMessage, invertedMessage]; return [positiveMessage, invertedMessage];
}; };
@@ -297,7 +297,7 @@ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
* @param {Number} precision, as number of decimal places * @param {Number} precision, as number of decimal places
*/ */
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
if (!(precision === 0)) { if (precision !== 0) {
precision = precision || 2; precision = precision || 2;
} }
return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2); return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
@@ -319,14 +319,15 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
} catch (e) { } catch (e) {
exception = e; exception = e;
} }
if (exception) { if (exception) {
result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); result = (jasmine.util.isUndefined(expected) || this.env.equals_(exception.message || exception, expected.message || expected));
} }
var not = this.isNot ? "not " : ""; var not = this.isNot ? "not " : "";
this.message = function() { this.message = function() {
if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { if (exception && (jasmine.util.isUndefined(expected) || !this.env.equals_(exception.message || exception, expected.message || expected))) {
return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
} else { } else {
return "Expected function to throw an exception."; return "Expected function to throw an exception.";
@@ -375,7 +376,7 @@ jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mis
var env = jasmine.getEnv(); var env = jasmine.getEnv();
var hasKey = function(obj, keyName) { var hasKey = function(obj, keyName) {
return obj != null && obj[keyName] !== jasmine.undefined; return obj !== null && !jasmine.util.isUndefined(obj[keyName]);
}; };
for (var property in this.sample) { for (var property in this.sample) {
+2 -2
View File
@@ -13,7 +13,7 @@ jasmine.PrettyPrinter = function() {
jasmine.PrettyPrinter.prototype.format = function(value) { jasmine.PrettyPrinter.prototype.format = function(value) {
this.ppNestLevel_++; this.ppNestLevel_++;
try { try {
if (value === jasmine.undefined) { if (jasmine.util.isUndefined(value)) {
this.emitScalar('undefined'); this.emitScalar('undefined');
} else if (value === null) { } else if (value === null) {
this.emitScalar('null'); this.emitScalar('null');
@@ -55,7 +55,7 @@ jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
for (var property in obj) { for (var property in obj) {
if (!obj.hasOwnProperty(property)) continue; if (!obj.hasOwnProperty(property)) continue;
if (property == '__Jasmine_been_here_before__') continue; if (property == '__Jasmine_been_here_before__') continue;
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && fn(property, obj.__lookupGetter__ ? (!jasmine.util.isUndefined(obj.__lookupGetter__(property)) &&
obj.__lookupGetter__(property) !== null) : false); obj.__lookupGetter__(property) !== null) : false);
} }
}; };
+3 -3
View File
@@ -1,13 +1,13 @@
jasmine.QueueRunner = function(attrs) { jasmine.QueueRunner = function(attrs) {
this.fns = attrs.fns || []; this.fns = attrs.fns || [];
this.onComplete = attrs.onComplete || function() {}; this.onComplete = attrs.onComplete || function() {};
this.encourageGC = attrs.encourageGC || function(fn) {fn()}; this.encourageGC = attrs.encourageGC || function(fn) {fn();};
this.onException = attrs.onException || function() {}; this.onException = attrs.onException || function() {};
this.catchException = attrs.catchException || function() { return true; }; this.catchException = attrs.catchException || function() { return true; };
}; };
jasmine.QueueRunner.prototype.execute = function() { jasmine.QueueRunner.prototype.execute = function() {
this.run(this.fns, 0) this.run(this.fns, 0);
}; };
jasmine.QueueRunner.prototype.run = function(fns, index) { jasmine.QueueRunner.prototype.run = function(fns, index) {
@@ -19,7 +19,7 @@ jasmine.QueueRunner.prototype.run = function(fns, index) {
var fn = fns[index]; var fn = fns[index];
var self = this; var self = this;
if (fn.length > 0) { if (fn.length > 0) {
attempt(function() { fn.call(self, function() { self.run(fns, index + 1) }) }); attempt(function() { fn.call(self, function() { self.run(fns, index + 1); }); });
} else { } else {
attempt(function() { fn.call(self); }); attempt(function() { fn.call(self); });
self.run(fns, index + 1); self.run(fns, index + 1);
+1 -1
View File
@@ -94,6 +94,6 @@ jasmine.Suite.prototype.execute = function(onComplete) {
function wrapChild(child) { function wrapChild(child) {
return function (done) { return function (done) {
child.execute(done); child.execute(done);
} };
} }
}; };
+1 -9
View File
@@ -8,7 +8,7 @@ var jasmine = {};
// TODO: do we need this now that we have boot.js? // TODO: do we need this now that we have boot.js?
if (typeof window == "undefined" && typeof exports == "object") { if (typeof window == "undefined" && typeof exports == "object") {
exports.jasmine = jasmine exports.jasmine = jasmine;
} }
/** /**
@@ -18,14 +18,6 @@ jasmine.unimplementedMethod_ = function() {
throw new Error("unimplemented method"); throw new Error("unimplemented method");
}; };
/**
* Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
* a plain old variable and may be redefined by somebody else.
*
* @private
*/
jasmine.undefined = jasmine.___undefined___;
/** /**
* Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
* *
+5 -1
View File
@@ -58,4 +58,8 @@ jasmine.util.argsToArray = function(args) {
var arrayOfArgs = []; var arrayOfArgs = [];
for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
return arrayOfArgs; return arrayOfArgs;
}; };
jasmine.util.isUndefined = function(obj) {
return obj === void 0;
};
-1
View File
@@ -7,7 +7,6 @@ $:.unshift(File.join(File.dirname(__FILE__), "jasmine_dev"))
require "base" require "base"
require "sources" require "sources"
require "js_hint"
require "build_distribution" require "build_distribution"
require "build_github_pages" require "build_github_pages"
require "build_standalone_distribution" require "build_standalone_distribution"
-2
View File
@@ -2,8 +2,6 @@ class JasmineDev < Thor
desc "build_distribution", "Build Jasmine js & css files" desc "build_distribution", "Build Jasmine js & css files"
def build_distribution(directory = "./lib/jasmine-core") def build_distribution(directory = "./lib/jasmine-core")
invoke :js_hint
say JasmineDev.spacer say JasmineDev.spacer
say "Building Jasmine distribution from source into #{directory}", :cyan say "Building Jasmine distribution from source into #{directory}", :cyan
-13
View File
@@ -1,13 +0,0 @@
class JasmineDev < Thor
desc "js_hint", "Run Jasmine source through JSHint"
def js_hint
say JasmineDev.spacer
return unless node_installed?
say "Running JSHint on Jasmine source and specs...", :cyan
run_with_output "node jshint/run.js", :capture => true
end
end