Skip to content

Commit

Permalink
Fix window so it always references the global object (even in strict …
Browse files Browse the repository at this point in the history
…mode). Fix references to document, navigator, etc. so that they can be undefined. Fix a strict mode error (callee reference). Include node tests in build.
  • Loading branch information
mbest committed Jan 8, 2013
1 parent f84cdba commit 23073cb
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 41 deletions.
3 changes: 3 additions & 0 deletions build/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,7 @@ rm -f output/*.js~
# Run tests in Phantomjs if available
command -v phantomjs >/dev/null && (cd ..; echo; phantomjs spec/runner.phantom.js || handle_fail)

# Run tests in Nodejs if available
command -v node >/dev/null && (cd ..; echo; node spec/runner.node.js || handle_fail)

echo; echo "Build succeeded"
2 changes: 1 addition & 1 deletion build/fragments/extern-post.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
})(window,document,navigator,window["jQuery"]);
}());
7 changes: 6 additions & 1 deletion build/fragments/extern-pre.js
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
(function(window,document,navigator,jQuery,undefined){
(function(undefined){
var window = this || (0,eval)('this'), // Use global 'this'
document = window['document'],
navigator = window['navigator'],
jQuery = window["jQuery"],
JSON = window["JSON"];
56 changes: 23 additions & 33 deletions spec/runner.node.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
console.log("Running Knockout tests in Node.js");

var fs = require('fs');
var jasmine = require('./lib/jasmine-1.2.0/jasmine');

// export jasmine globals
for (var key in jasmine) {
global[key] = jasmine[key];
global[key] = jasmine[key];
}

// add our jasmine extensions to the exported globals
require('./lib/jasmine.extensions');

// export ko globals
if (process.argv.length > 2) {
global.ko = require(process.argv[2]);
} else {
// equivalent of ../build/knockout-raw.js
global.DEBUG = true;
global.ko = global.koExports = {};
global.knockoutDebugCallback = function(sources) {
eval(sources.reduce(function(all, source) {
return all + '\n' + fs.readFileSync(source);
}, ''));
};
require('../build/fragments/source-references');
}
global.ko = require('../build/output/knockout-latest.js');

// reference behaviors that should work out of browser
require('./arrayEditDetectionBehaviors');
Expand All @@ -40,29 +30,29 @@ var env = jasmine.jasmine.getEnv();

// create reporter to return results
function failureFilter(item) {
return !item.passed();
return !item.passed();
}
env.addReporter({
reportRunnerResults:function (runner) {
var results = runner.results();
runner.suites().map(function (suite) {
// hack around suite results not having a description
var suiteResults = suite.results();
suiteResults.description = suite.description;
return suiteResults;
}).filter(failureFilter).forEach(function (suite) {
console.error(suite.description);
suite.getItems().filter(failureFilter).forEach(function (spec) {
console.error('\t' + spec.description);
spec.getItems().filter(failureFilter).forEach(function (expectation) {
console.error('\t\t' + expectation.message);
reportRunnerResults:function (runner) {
var results = runner.results();
runner.suites().map(function (suite) {
// hack around suite results not having a description
var suiteResults = suite.results();
suiteResults.description = suite.description;
return suiteResults;
}).filter(failureFilter).forEach(function (suite) {
console.error(suite.description);
suite.getItems().filter(failureFilter).forEach(function (spec) {
console.error('\t' + spec.description);
spec.getItems().filter(failureFilter).forEach(function (expectation) {
console.error('\t\t' + expectation.message);
});
});
});
});
console.log("Total:" + results.totalCount + " Passed:" + results.passedCount + " Failed:" + results.failedCount);
process.exit(results.failedCount);
}
console.log("Total:" + results.totalCount + " Passed:" + results.passedCount + " Failed:" + results.failedCount);
process.exit(results.failedCount);
}
});

// good to go
env.execute();
env.execute();
3 changes: 3 additions & 0 deletions spec/runner.phantom.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ function waitFor(testFx, onReady, timeOutMillis) {

var page = require('webpage').create();

console.log("Running Knockout tests in Phantom.js");


// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = function(msg) {
console.log(msg);
Expand Down
2 changes: 1 addition & 1 deletion src/subscribables/dependentObservable.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunction
// plus adds a "disposeWhen" callback that, on each evaluation, disposes if the node was removed by some other means.)
if (disposeWhenNodeIsRemoved && isActive()) {
dispose = function() {
ko.utils.domNodeDisposal.removeDisposeCallback(disposeWhenNodeIsRemoved, arguments.callee);
ko.utils.domNodeDisposal.removeDisposeCallback(disposeWhenNodeIsRemoved, dispose);
disposeAllSubscriptionsToDependencies();
};
ko.utils.domNodeDisposal.addDisposeCallback(disposeWhenNodeIsRemoved, dispose);
Expand Down
8 changes: 4 additions & 4 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ko.utils = new (function () {

// Represent the known event types in a compact way, then at runtime transform it into a hash with event name as key (for fast lookup)
var knownEvents = {}, knownEventTypesByEventName = {};
var keyEventTypeName = /Firefox\/2/i.test(navigator.userAgent) ? 'KeyboardEvent' : 'UIEvents';
var keyEventTypeName = (navigator && /Firefox\/2/i.test(navigator.userAgent)) ? 'KeyboardEvent' : 'UIEvents';
knownEvents[keyEventTypeName] = ['keyup', 'keydown', 'keypress'];
knownEvents['MouseEvents'] = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave'];
for (var eventType in knownEvents) {
Expand All @@ -19,7 +19,7 @@ ko.utils = new (function () {
// Note that, since IE 10 does not support conditional comments, the following logic only detects IE < 10.
// Currently this is by design, since IE 10+ behaves correctly when treated as a standard browser.
// If there is a future need to detect specific versions of IE10+, we will amend this.
var ieVersion = (function() {
var ieVersion = document && (function() {
var version = 3, div = document.createElement('div'), iElems = div.getElementsByTagName('i');

// Keep constructing conditional HTML blocks until we hit one that resolves to an empty fragment
Expand Down Expand Up @@ -398,7 +398,7 @@ ko.utils = new (function () {
if (typeof jsonString == "string") {
jsonString = ko.utils.stringTrim(jsonString);
if (jsonString) {
if ((typeof JSON != "undefined") && (typeof JSON.parse != "undefined")) // Use native parsing where available
if (JSON && JSON.parse) // Use native parsing where available
return JSON.parse(jsonString);
return (new Function("return " + jsonString))(); // Fallback on less safe parsing for older browsers
}
Expand All @@ -407,7 +407,7 @@ ko.utils = new (function () {
},

stringifyJson: function (data, replacer, space) { // replacer and space are optional
if ((typeof JSON == "undefined") || (typeof JSON.stringify == "undefined"))
if (!JSON || !JSON.stringify)
throw new Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
return JSON.stringify(ko.utils.unwrapObservable(data), replacer, space);
},
Expand Down
2 changes: 1 addition & 1 deletion src/virtualElements.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// IE 9 cannot reliably read the "nodeValue" property of a comment node (see https://github.com/SteveSanderson/knockout/issues/186)
// but it does give them a nonstandard alternative property called "text" that it can read reliably. Other browsers don't have that property.
// So, use node.text where available, and node.nodeValue elsewhere
var commentNodesHaveTextProperty = document.createComment("test").text === "<!--test-->";
var commentNodesHaveTextProperty = document && document.createComment("test").text === "<!--test-->";

var startCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*-->$/ : /^\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*$/;
var endCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*\/ko\s*-->$/ : /^\s*\/ko\s*$/;
Expand Down

0 comments on commit 23073cb

Please sign in to comment.