Use jasmine.undefined for all comparisons to the undefined value, since undefined itself may be redefined elsewhere

in app code.  Thanks to Charlie Meyer at UIUC for the suggestion.
This commit is contained in:
Christian Williams 2009-11-26 11:12:06 -05:00
parent 2cb5bf146c
commit 7653107f0c
14 changed files with 100 additions and 59 deletions

View File

@ -34,8 +34,29 @@ namespace :jasmine do
desc 'Prepares for distribution'
task :dist => ['jasmine:build', 'jasmine:doc']
desc 'Check jasmine sources for coding problems'
task :lint do
passed = true
jasmine_sources.each do |src|
lines = File.read(src).split(/\n/)
lines.each_index do |i|
line = lines[i]
undefineds = line.scan(/.?undefined/)
if undefineds.include?(" undefined") || undefineds.include?("\tundefined")
puts "Dangerous undefined at #{src}:#{i}:\n > #{line}"
passed = false
end
end
end
unless passed
puts "Lint failed!"
exit 1
end
end
desc 'Builds lib/jasmine from source'
task :build do
task :build => :lint do
puts 'Building Jasmine from source'
require 'json'

View File

@ -12,6 +12,14 @@ jasmine.unimplementedMethod_ = function() {
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 for event loop yields. Small values here may result in slow test running. Zero means no updates until all tests have completed.
*
@ -759,7 +767,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
b.__Jasmine_been_here_before__ = a;
var hasKey = function(obj, keyName) {
return obj != null && obj[keyName] !== undefined;
return obj != null && obj[keyName] !== jasmine.undefined;
};
for (var property in b) {
@ -794,8 +802,8 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
if (a === b) return true;
if (a === undefined || a === null || b === undefined || b === null) {
return (a == undefined && b == undefined);
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)) {
@ -821,7 +829,7 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, 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 !== undefined) return result;
if (result !== jasmine.undefined) return result;
}
//Straight check
@ -980,7 +988,7 @@ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
type: resultMessage.type,
message: resultMessage.message,
trace: {
stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : undefined
stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
}
});
};
@ -1108,17 +1116,17 @@ jasmine.Matchers.prototype.toNotMatch = function(expected) {
};
/**
* Matcher that compares the actual to undefined.
* Matcher that compares the actual to jasmine.undefined.
*/
jasmine.Matchers.prototype.toBeDefined = function() {
return (this.actual !== undefined);
return (this.actual !== jasmine.undefined);
};
/**
* Matcher that compares the actual to undefined.
* Matcher that compares the actual to jasmine.undefined.
*/
jasmine.Matchers.prototype.toBeUndefined = function() {
return (this.actual === undefined);
return (this.actual === jasmine.undefined);
};
/**
@ -1247,12 +1255,12 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
var result = false;
var exception = getException_(this.actual, expected);
if (exception) {
result = (expected === undefined || this.env.equals_(exception.message || exception, expected.message || expected));
result = (expected === jasmine.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))) {
if (exception && (expected === jasmine.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.";
@ -1417,7 +1425,7 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
this.ppNestLevel_++;
try {
if (value === undefined) {
if (value === jasmine.undefined) {
this.emitScalar('undefined');
} else if (value === null) {
this.emitScalar('null');
@ -1898,11 +1906,11 @@ jasmine.Spec.prototype.explodes = function() {
};
jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
if (obj == undefined) {
if (obj == jasmine.undefined) {
throw "spyOn could not find an object to spy upon for " + methodName + "()";
}
if (!ignoreMethodDoesntExist && obj[methodName] === undefined) {
if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
throw methodName + '() method does not exist';
}
@ -2071,11 +2079,11 @@ jasmine.FakeTimer = function() {
};
self.clearTimeout = function(timeoutKey) {
self.scheduledFunctions[timeoutKey] = undefined;
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
};
self.clearInterval = function(timeoutKey) {
self.scheduledFunctions[timeoutKey] = undefined;
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
};
};
@ -2098,11 +2106,11 @@ jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMil
var funcsToRun = [];
for (var timeoutKey in this.scheduledFunctions) {
scheduledFunc = this.scheduledFunctions[timeoutKey];
if (scheduledFunc != undefined &&
if (scheduledFunc != jasmine.undefined &&
scheduledFunc.runAtMillis >= oldMillis &&
scheduledFunc.runAtMillis <= nowMillis) {
funcsToRun.push(scheduledFunc);
this.scheduledFunctions[timeoutKey] = undefined;
this.scheduledFunctions[timeoutKey] = jasmine.undefined;
}
}
@ -2233,5 +2241,5 @@ jasmine.version_= {
"major": 0,
"minor": 10,
"build": 0,
"revision": 1259250030
"revision": 1259251766
};

View File

@ -4,6 +4,10 @@
<head>
<title>Jasmine Test Runner</title>
<script type="text/javascript">
undefined = "diz be undefined yo";
</script>
<script type="text/javascript" src="../src/base.js"></script>
<script type="text/javascript" src="../src/util.js"></script>
<script type="text/javascript" src="../src/Env.js"></script>

View File

@ -60,8 +60,8 @@ describe('jasmine.jsApiReporter', function() {
expect(summarizedResult.messages[0].message).toEqual(result.messages[0].message);
expect(summarizedResult.messages[0].passed).toBeTruthy();
expect(summarizedResult.messages[0].type).toEqual('ExpectationResult');
expect(summarizedResult.messages[0].text).toEqual(undefined);
expect(summarizedResult.messages[0].trace.stack).toEqual(undefined);
expect(summarizedResult.messages[0].text).toEqual(jasmine.undefined);
expect(summarizedResult.messages[0].trace.stack).toEqual(jasmine.undefined);
});
it("should have a stack trace for failing specs", function() {

View File

@ -43,8 +43,8 @@ describe("jasmine.Matchers", function() {
expect(match(true).toNotEqual(false)).toEqual(true);
expect((match(true).toNotEqual(true))).toEqual(false);
expect((match(['a', 'b']).toEqual(['a', undefined]))).toEqual(false);
expect((match(['a', 'b']).toEqual(['a', 'b', undefined]))).toEqual(false);
expect((match(['a', 'b']).toEqual(['a', jasmine.undefined]))).toEqual(false);
expect((match(['a', 'b']).toEqual(['a', 'b', jasmine.undefined]))).toEqual(false);
});
it("toEqual to build an Expectation Result", function() {
@ -197,11 +197,11 @@ describe("jasmine.Matchers", function() {
it("toBeDefined", function() {
expect(match('foo').toBeDefined()).toEqual(true);
expect(match(undefined).toBeDefined()).toEqual(false);
expect(match(jasmine.undefined).toBeDefined()).toEqual(false);
});
it("toBeDefined to build an ExpectationResult", function() {
var matcher = match(undefined);
var matcher = match(jasmine.undefined);
matcher.toBeDefined();
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
@ -209,17 +209,17 @@ describe("jasmine.Matchers", function() {
expect(result.matcherName).toEqual("toBeDefined");
expect(result.passed()).toEqual(false);
expect(result.message).toEqual('Expected undefined to be defined.');
expect(result.actual).toEqual(undefined);
expect(result.actual).toEqual(jasmine.undefined);
});
it("toBeUndefined", function() {
expect(match('foo').toBeUndefined()).toEqual(false);
expect(match(undefined).toBeUndefined()).toEqual(true);
expect(match(jasmine.undefined).toBeUndefined()).toEqual(true);
});
it("toBeNull", function() {
expect(match(null).toBeNull()).toEqual(true);
expect(match(undefined).toBeNull()).toEqual(false);
expect(match(jasmine.undefined).toBeNull()).toEqual(false);
expect(match("foo").toBeNull()).toEqual(false);
});
@ -254,7 +254,7 @@ describe("jasmine.Matchers", function() {
it("toBeFalsy", function() {
expect(match(false).toBeFalsy()).toEqual(true);
expect(match(true).toBeFalsy()).toEqual(false);
expect(match(undefined).toBeFalsy()).toEqual(true);
expect(match(jasmine.undefined).toBeFalsy()).toEqual(true);
expect(match(0).toBeFalsy()).toEqual(true);
expect(match("").toBeFalsy()).toEqual(true);
});
@ -276,7 +276,7 @@ describe("jasmine.Matchers", function() {
it("toBeTruthy", function() {
expect(match(false).toBeTruthy()).toEqual(false);
expect(match(true).toBeTruthy()).toEqual(true);
expect(match(undefined).toBeTruthy()).toEqual(false);
expect(match(jasmine.undefined).toBeTruthy()).toEqual(false);
expect(match(0).toBeTruthy()).toEqual(false);
expect(match("").toBeTruthy()).toEqual(false);
expect(match("hi").toBeTruthy()).toEqual(true);
@ -297,11 +297,11 @@ describe("jasmine.Matchers", function() {
});
it("toEqual", function() {
expect(match(undefined).toEqual(undefined)).toEqual(true);
expect(match(jasmine.undefined).toEqual(jasmine.undefined)).toEqual(true);
expect(match({foo:'bar'}).toEqual({foo:'bar'})).toEqual(true);
expect(match("foo").toEqual({bar: undefined})).toEqual(false);
expect(match({foo: undefined}).toEqual("goo")).toEqual(false);
expect(match({foo: {bar :undefined}}).toEqual("goo")).toEqual(false);
expect(match("foo").toEqual({bar: jasmine.undefined})).toEqual(false);
expect(match({foo: jasmine.undefined}).toEqual("goo")).toEqual(false);
expect(match({foo: {bar :jasmine.undefined}}).toEqual("goo")).toEqual(false);
});
it("toEqual with jasmine.any()", function() {
@ -321,7 +321,7 @@ describe("jasmine.Matchers", function() {
});
it("toEqual handles circular objects ok", function() {
expect(match({foo: "bar", baz: undefined}).toEqual({foo: "bar", baz: undefined})).toEqual(true);
expect(match({foo: "bar", baz: jasmine.undefined}).toEqual({foo: "bar", baz: jasmine.undefined})).toEqual(true);
expect(match({foo:['bar','baz','quux']}).toEqual({foo:['bar','baz','quux']})).toEqual(true);
expect(match({foo: {bar:'baz'}, quux:'corge'}).toEqual({foo:{bar:'baz'}, quux:'corge'})).toEqual(true);
@ -488,7 +488,7 @@ describe("jasmine.Matchers", function() {
}).toThrow('Expected a spy, but got Function.');
expect(function() {
match(undefined)[methodName]();
match(jasmine.undefined)[methodName]();
}).toThrow('Expected a spy, but got undefined.');
expect(function() {

View File

@ -8,14 +8,14 @@ describe("jasmine.pp", function () {
expect(jasmine.pp(true)).toEqual("true");
expect(jasmine.pp(false)).toEqual("false");
expect(jasmine.pp(null)).toEqual("null");
expect(jasmine.pp(undefined)).toEqual("undefined");
expect(jasmine.pp(jasmine.undefined)).toEqual("undefined");
expect(jasmine.pp(3)).toEqual("3");
expect(jasmine.pp(-3.14)).toEqual("-3.14");
});
it("should stringify arrays properly", function() {
expect(jasmine.pp([1, 2])).toEqual("[ 1, 2 ]");
expect(jasmine.pp([1, 'foo', {}, undefined, null])).toEqual("[ 1, 'foo', { }, undefined, null ]");
expect(jasmine.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', { }, undefined, null ]");
});
it("should indicate circular array references", function() {
@ -27,7 +27,7 @@ describe("jasmine.pp", function () {
it("should stringify objects properly", function() {
expect(jasmine.pp({foo: 'bar'})).toEqual("{ foo : 'bar' }");
expect(jasmine.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
expect(jasmine.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
expect(jasmine.pp({foo: function () {
}, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
});

View File

@ -1111,7 +1111,7 @@ describe("jasmine spec running", function () {
expect(spec1Matcher.matcherForSpec("expected")).toEqual("matcherForSpec: actual: xxx; expected: expected");
expect(spec2Matcher.matcherForSuite("expected")).toEqual("matcherForSuite: actual: yyy; expected: expected");
expect(spec2Matcher.matcherForSpec).toBe(undefined);
expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
});
});

View File

@ -151,7 +151,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
b.__Jasmine_been_here_before__ = a;
var hasKey = function(obj, keyName) {
return obj != null && obj[keyName] !== undefined;
return obj != null && obj[keyName] !== jasmine.undefined;
};
for (var property in b) {
@ -186,8 +186,8 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
if (a === b) return true;
if (a === undefined || a === null || b === undefined || b === null) {
return (a == undefined && b == undefined);
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)) {
@ -213,7 +213,7 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, 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 !== undefined) return result;
if (result !== jasmine.undefined) return result;
}
//Straight check

View File

@ -88,7 +88,7 @@ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
type: resultMessage.type,
message: resultMessage.message,
trace: {
stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : undefined
stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
}
});
};

View File

@ -113,17 +113,17 @@ jasmine.Matchers.prototype.toNotMatch = function(expected) {
};
/**
* Matcher that compares the actual to undefined.
* Matcher that compares the actual to jasmine.undefined.
*/
jasmine.Matchers.prototype.toBeDefined = function() {
return (this.actual !== undefined);
return (this.actual !== jasmine.undefined);
};
/**
* Matcher that compares the actual to undefined.
* Matcher that compares the actual to jasmine.undefined.
*/
jasmine.Matchers.prototype.toBeUndefined = function() {
return (this.actual === undefined);
return (this.actual === jasmine.undefined);
};
/**
@ -252,12 +252,12 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
var result = false;
var exception = getException_(this.actual, expected);
if (exception) {
result = (expected === undefined || this.env.equals_(exception.message || exception, expected.message || expected));
result = (expected === jasmine.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))) {
if (exception && (expected === jasmine.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.";

View File

@ -17,7 +17,7 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
this.ppNestLevel_++;
try {
if (value === undefined) {
if (value === jasmine.undefined) {
this.emitScalar('undefined');
} else if (value === null) {
this.emitScalar('null');

View File

@ -171,11 +171,11 @@ jasmine.Spec.prototype.explodes = function() {
};
jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
if (obj == undefined) {
if (obj == jasmine.undefined) {
throw "spyOn could not find an object to spy upon for " + methodName + "()";
}
if (!ignoreMethodDoesntExist && obj[methodName] === undefined) {
if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
throw methodName + '() method does not exist';
}

View File

@ -12,6 +12,14 @@ jasmine.unimplementedMethod_ = function() {
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 for event loop yields. Small values here may result in slow test running. Zero means no updates until all tests have completed.
*

View File

@ -18,11 +18,11 @@ jasmine.FakeTimer = function() {
};
self.clearTimeout = function(timeoutKey) {
self.scheduledFunctions[timeoutKey] = undefined;
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
};
self.clearInterval = function(timeoutKey) {
self.scheduledFunctions[timeoutKey] = undefined;
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
};
};
@ -45,11 +45,11 @@ jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMil
var funcsToRun = [];
for (var timeoutKey in this.scheduledFunctions) {
scheduledFunc = this.scheduledFunctions[timeoutKey];
if (scheduledFunc != undefined &&
if (scheduledFunc != jasmine.undefined &&
scheduledFunc.runAtMillis >= oldMillis &&
scheduledFunc.runAtMillis <= nowMillis) {
funcsToRun.push(scheduledFunc);
this.scheduledFunctions[timeoutKey] = undefined;
this.scheduledFunctions[timeoutKey] = jasmine.undefined;
}
}