[Pkg-javascript-commits] [backbone] 12/34: Adding the beginnings of a speed suite to the Test page.
Jonas Smedegaard
js at moszumanska.debian.org
Sat May 3 16:58:44 UTC 2014
This is an automated email from the git hooks/post-receive script.
js pushed a commit to tag 0.1.2
in repository backbone.
commit e7ce57cc1dbb2b5d3048428333153453baf3817a
Author: Jeremy Ashkenas <jashkenas at gmail.com>
Date: Thu Oct 14 14:46:53 2010 -0400
Adding the beginnings of a speed suite to the Test page.
---
backbone.js | 2 +-
test/collection.js | 22 +-
test/{bindable.js => events.js} | 8 +-
test/model.js | 22 +-
test/speed.js | 25 ++
test/test.html | 7 +-
test/vendor/jslitmus.js | 649 ++++++++++++++++++++++++++++++++++++++++
test/view.js | 15 +-
8 files changed, 715 insertions(+), 35 deletions(-)
diff --git a/backbone.js b/backbone.js
index 58b6bdd..d0a1acc 100644
--- a/backbone.js
+++ b/backbone.js
@@ -82,7 +82,7 @@
if (!(calls = this._callbacks)) return this;
if (list = calls[ev]) {
for (i = 0, l = list.length; i < l; i++) {
- list[i].apply(this, _.rest(arguments));
+ list[i].apply(this, Array.prototype.slice.call(arguments, 1));
}
}
if (list = calls['all']) {
diff --git a/test/collection.js b/test/collection.js
index fb9cec8..de5c974 100644
--- a/test/collection.js
+++ b/test/collection.js
@@ -1,6 +1,6 @@
$(document).ready(function() {
- module("Backbone collections");
+ module("Backbone.Collection");
window.lastRequest = null;
@@ -15,7 +15,7 @@ $(document).ready(function() {
var e = null;
var col = window.col = new Backbone.Collection([a,b,c,d]);
- test("collections: new and sort", function() {
+ test("Collection: new and sort", function() {
equals(col.first(), a, "a should be first");
equals(col.last(), d, "d should be last");
col.comparator = function(model) { return model.id; };
@@ -25,21 +25,21 @@ $(document).ready(function() {
equals(col.length, 4);
});
- test("collections: get, getByCid", function() {
+ test("Collection: get, getByCid", function() {
equals(col.get(1), d);
equals(col.get(3), b);
equals(col.getByCid(col.first().cid), col.first());
});
- test("collections: at", function() {
+ test("Collection: at", function() {
equals(col.at(2), b);
});
- test("collections: pluck", function() {
+ test("Collection: pluck", function() {
equals(col.pluck('label').join(' '), 'd c b a');
});
- test("collections: add", function() {
+ test("Collection: add", function() {
var added = null;
col.bind('add', function(model){ added = model.get('label'); });
e = new Backbone.Model({id: 0, label : 'e'});
@@ -49,7 +49,7 @@ $(document).ready(function() {
equals(col.first(), e);
});
- test("collections: remove", function() {
+ test("Collection: remove", function() {
var removed = null;
col.bind('remove', function(model){ removed = model.get('label'); });
col.remove(e);
@@ -58,13 +58,13 @@ $(document).ready(function() {
equals(col.first(), d);
});
- test("collections: fetch", function() {
+ test("Collection: fetch", function() {
col.fetch();
equals(lastRequest[0], 'read');
equals(lastRequest[1], col);
});
- test("collections: create", function() {
+ test("Collection: create", function() {
var model = col.create({label: 'f'});
equals(lastRequest[0], 'create');
equals(lastRequest[1], model);
@@ -82,7 +82,7 @@ $(document).ready(function() {
equals(coll.one, 1);
});
- test("collections: Underscore methods", function() {
+ test("Collection: Underscore methods", function() {
equals(col.map(function(model){ return model.get('label'); }).join(' '), 'd c b a');
equals(col.any(function(model){ return model.id === 100; }), false);
equals(col.any(function(model){ return model.id === 1; }), true);
@@ -97,7 +97,7 @@ $(document).ready(function() {
equals(col.min(function(model){ return model.id; }).id, 1);
});
- test("collections: refresh", function() {
+ test("Collection: refresh", function() {
var refreshed = 0;
var models = col.models;
col.bind('refresh', function() { refreshed += 1; });
diff --git a/test/bindable.js b/test/events.js
similarity index 84%
rename from test/bindable.js
rename to test/events.js
index 1d92bfa..8380842 100644
--- a/test/bindable.js
+++ b/test/events.js
@@ -1,8 +1,8 @@
$(document).ready(function() {
- module("Backbone bindable");
+ module("Backbone.Events");
- test("bindable: bind and trigger", function() {
+ test("Events: bind and trigger", function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
obj.bind('event', function() { obj.counter += 1; });
@@ -15,7 +15,7 @@ $(document).ready(function() {
equals(obj.counter, 5, 'counter should be incremented five times.');
});
- test("bindable: bind, then unbind all functions", function() {
+ test("Events: bind, then unbind all functions", function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counter += 1; };
@@ -26,7 +26,7 @@ $(document).ready(function() {
equals(obj.counter, 1, 'counter should have only been incremented once.');
});
- test("bindable: bind two callbacks, unbind only one", function() {
+ test("Events: bind two callbacks, unbind only one", function() {
var obj = { counterA: 0, counterB: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counterA += 1; };
diff --git a/test/model.js b/test/model.js
index f10e914..cedb005 100644
--- a/test/model.js
+++ b/test/model.js
@@ -1,6 +1,6 @@
$(document).ready(function() {
- module("Backbone model");
+ module("Backbone.Model");
// Variable to catch the last request.
window.lastRequest = null;
@@ -26,7 +26,7 @@ $(document).ready(function() {
var collection = new klass();
collection.add(doc);
- test("model: initialize", function() {
+ test("Model: initialize", function() {
var Model = Backbone.Model.extend({
initialize: function() {
this.one = 1;
@@ -36,11 +36,11 @@ $(document).ready(function() {
equals(model.one, 1);
});
- test("model: url", function() {
+ test("Model: url", function() {
equals(doc.url(), '/collection/1-the-tempest');
});
- test("model: clone", function() {
+ test("Model: clone", function() {
attrs = { 'foo': 1, 'bar': 2, 'baz': 3};
a = new Backbone.Model(attrs);
b = a.clone();
@@ -55,7 +55,7 @@ $(document).ready(function() {
equals(b.get('foo'), 1, "Changing a parent attribute does not change the clone.");
});
- test("model: isNew", function() {
+ test("Model: isNew", function() {
attrs = { 'foo': 1, 'bar': 2, 'baz': 3};
a = new Backbone.Model(attrs);
ok(a.isNew(), "it should be new");
@@ -63,12 +63,12 @@ $(document).ready(function() {
ok(a.isNew(), "any defined ID is legal, negative or positive");
});
- test("model: get", function() {
+ test("Model: get", function() {
equals(doc.get('title'), 'The Tempest');
equals(doc.get('author'), 'Bill Shakespeare');
});
- test("model: set and unset", function() {
+ test("Model: set and unset", function() {
attrs = { 'foo': 1, 'bar': 2, 'baz': 3};
a = new Backbone.Model(attrs);
var changeCount = 0;
@@ -85,7 +85,7 @@ $(document).ready(function() {
ok(changeCount == 2, "Change count should have incremented for unset.");
});
- test("model: changed, hasChanged, changedAttributes, previous, previousAttributes", function() {
+ test("Model: changed, hasChanged, changedAttributes, previous, previousAttributes", function() {
var model = new Backbone.Model({name : "Tim", age : 10});
model.bind('change', function() {
ok(model.hasChanged('name'), 'name changed');
@@ -99,19 +99,19 @@ $(document).ready(function() {
equals(model.get('name'), 'Rob');
});
- test("model: save", function() {
+ test("Model: save", function() {
doc.save({title : "Henry V"});
equals(lastRequest[0], 'update');
ok(_.isEqual(lastRequest[1], doc));
});
- test("model: destroy", function() {
+ test("Model: destroy", function() {
doc.destroy();
equals(lastRequest[0], 'delete');
ok(_.isEqual(lastRequest[1], doc));
});
- test("model: validate", function() {
+ test("Model: validate", function() {
var lastError;
var model = new Backbone.Model();
model.validate = function(attrs) {
diff --git a/test/speed.js b/test/speed.js
new file mode 100644
index 0000000..0f29d47
--- /dev/null
+++ b/test/speed.js
@@ -0,0 +1,25 @@
+(function(){
+
+ var object = {};
+ _.extend(object, Backbone.Events);
+ var fn = function(){};
+
+ JSLitmus.test('Events: bind + unbind', function() {
+ object.bind("event", fn);
+ object.unbind("event", fn);
+ });
+
+ object.bind('test:trigger', fn);
+
+ JSLitmus.test('Events: trigger', function() {
+ object.trigger('test:trigger');
+ });
+
+ object.bind('test:trigger2', fn);
+ object.bind('test:trigger2', fn);
+
+ JSLitmus.test('Events: trigger 2 functions, passing 5 arguments', function() {
+ object.trigger('test:trigger2', 1, 2, 3, 4, 5);
+ });
+
+})();
\ No newline at end of file
diff --git a/test/test.html b/test/test.html
index 4ecd386..22d16f0 100644
--- a/test/test.html
+++ b/test/test.html
@@ -5,18 +5,23 @@
<link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="vendor/jquery-1.4.2.js"></script>
<script type="text/javascript" src="vendor/qunit.js"></script>
+ <script type="text/javascript" src="vendor/jslitmus.js"></script>
<script type="text/javascript" src="vendor/underscore-1.1.0.js"></script>
<script type="text/javascript" src="../backbone.js"></script>
- <script type="text/javascript" src="bindable.js"></script>
+ <script type="text/javascript" src="events.js"></script>
<script type="text/javascript" src="model.js"></script>
<script type="text/javascript" src="collection.js"></script>
<script type="text/javascript" src="view.js"></script>
+ <script type="text/javascript" src="speed.js"></script>
</head>
<body>
<h1 id="qunit-header">Backbone Test Suite</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
+ <br /><br />
+ <h1 id="qunit-header">Backbone Speed Suite</h1>
+ <div id="jslitmus_container" style="margin: 20px 10px;"></div>
</body>
</html>
diff --git a/test/vendor/jslitmus.js b/test/vendor/jslitmus.js
new file mode 100644
index 0000000..a411179
--- /dev/null
+++ b/test/vendor/jslitmus.js
@@ -0,0 +1,649 @@
+// JSLitmus.js
+//
+// Copyright (c) 2010, Robert Kieffer, http://broofa.com
+// Available under MIT license (http://en.wikipedia.org/wiki/MIT_License)
+
+(function() {
+ // Private methods and state
+
+ // Get platform info but don't go crazy trying to recognize everything
+ // that's out there. This is just for the major platforms and OSes.
+ var platform = 'unknown platform', ua = navigator.userAgent;
+
+ // Detect OS
+ var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|');
+ var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null;
+ if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null;
+
+ // Detect browser
+ var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null;
+
+ // Detect version
+ var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)');
+ var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null;
+ var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform';
+
+ /**
+ * A smattering of methods that are needed to implement the JSLitmus testbed.
+ */
+ var jsl = {
+ /**
+ * Enhanced version of escape()
+ */
+ escape: function(s) {
+ s = s.replace(/,/g, '\\,');
+ s = escape(s);
+ s = s.replace(/\+/g, '%2b');
+ s = s.replace(/ /g, '+');
+ return s;
+ },
+
+ /**
+ * Get an element by ID.
+ */
+ $: function(id) {
+ return document.getElementById(id);
+ },
+
+ /**
+ * Null function
+ */
+ F: function() {},
+
+ /**
+ * Set the status shown in the UI
+ */
+ status: function(msg) {
+ var el = jsl.$('jsl_status');
+ if (el) el.innerHTML = msg || '';
+ },
+
+ /**
+ * Convert a number to an abbreviated string like, "15K" or "10M"
+ */
+ toLabel: function(n) {
+ if (n == Infinity) {
+ return 'Infinity';
+ } else if (n > 1e9) {
+ n = Math.round(n/1e8);
+ return n/10 + 'B';
+ } else if (n > 1e6) {
+ n = Math.round(n/1e5);
+ return n/10 + 'M';
+ } else if (n > 1e3) {
+ n = Math.round(n/1e2);
+ return n/10 + 'K';
+ }
+ return n;
+ },
+
+ /**
+ * Copy properties from src to dst
+ */
+ extend: function(dst, src) {
+ for (var k in src) dst[k] = src[k]; return dst;
+ },
+
+ /**
+ * Like Array.join(), but for the key-value pairs in an object
+ */
+ join: function(o, delimit1, delimit2) {
+ if (o.join) return o.join(delimit1); // If it's an array
+ var pairs = [];
+ for (var k in o) pairs.push(k + delimit1 + o[k]);
+ return pairs.join(delimit2);
+ },
+
+ /**
+ * Array#indexOf isn't supported in IE, so we use this as a cross-browser solution
+ */
+ indexOf: function(arr, o) {
+ if (arr.indexOf) return arr.indexOf(o);
+ for (var i = 0; i < this.length; i++) if (arr[i] === o) return i;
+ return -1;
+ }
+ };
+
+ /**
+ * Test manages a single test (created with
+ * JSLitmus.test())
+ *
+ * @private
+ */
+ var Test = function (name, f) {
+ if (!f) throw new Error('Undefined test function');
+ if (!/function[^\(]*\(([^,\)]*)/.test(f.toString())) {
+ throw new Error('"' + name + '" test: Test is not a valid Function object');
+ }
+ this.loopArg = RegExp.$1;
+ this.name = name;
+ this.f = f;
+ };
+
+ jsl.extend(Test, /** @lends Test */ {
+ /** Calibration tests for establishing iteration loop overhead */
+ CALIBRATIONS: [
+ new Test('calibrating loop', function(count) {while (count--);}),
+ new Test('calibrating function', jsl.F)
+ ],
+
+ /**
+ * Run calibration tests. Returns true if calibrations are not yet
+ * complete (in which case calling code should run the tests yet again).
+ * onCalibrated - Callback to invoke when calibrations have finished
+ */
+ calibrate: function(onCalibrated) {
+ for (var i = 0; i < Test.CALIBRATIONS.length; i++) {
+ var cal = Test.CALIBRATIONS[i];
+ if (cal.running) return true;
+ if (!cal.count) {
+ cal.isCalibration = true;
+ cal.onStop = onCalibrated;
+ //cal.MIN_TIME = .1; // Do calibrations quickly
+ cal.run(2e4);
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+
+ jsl.extend(Test.prototype, {/** @lends Test.prototype */
+ /** Initial number of iterations */
+ INIT_COUNT: 10,
+ /** Max iterations allowed (i.e. used to detect bad looping functions) */
+ MAX_COUNT: 1e9,
+ /** Minimum time a test should take to get valid results (secs) */
+ MIN_TIME: .5,
+
+ /** Callback invoked when test state changes */
+ onChange: jsl.F,
+
+ /** Callback invoked when test is finished */
+ onStop: jsl.F,
+
+ /**
+ * Reset test state
+ */
+ reset: function() {
+ delete this.count;
+ delete this.time;
+ delete this.running;
+ delete this.error;
+ },
+
+ /**
+ * Run the test (in a timeout). We use a timeout to make sure the browser
+ * has a chance to finish rendering any UI changes we've made, like
+ * updating the status message.
+ */
+ run: function(count) {
+ count = count || this.INIT_COUNT;
+ jsl.status(this.name + ' x ' + count);
+ this.running = true;
+ var me = this;
+ setTimeout(function() {me._run(count);}, 200);
+ },
+
+ /**
+ * The nuts and bolts code that actually runs a test
+ */
+ _run: function(count) {
+ var me = this;
+
+ // Make sure calibration tests have run
+ if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return;
+ this.error = null;
+
+ try {
+ var start, f = this.f, now, i = count;
+
+ // Start the timer
+ start = new Date();
+
+ // Now for the money shot. If this is a looping function ...
+ if (this.loopArg) {
+ // ... let it do the iteration itself
+ f(count);
+ } else {
+ // ... otherwise do the iteration for it
+ while (i--) f();
+ }
+
+ // Get time test took (in secs)
+ this.time = Math.max(1,new Date() - start)/1000;
+
+ // Store iteration count and per-operation time taken
+ this.count = count;
+ this.period = this.time/count;
+
+ // Do we need to do another run?
+ this.running = this.time <= this.MIN_TIME;
+
+ // ... if so, compute how many times we should iterate
+ if (this.running) {
+ // Bump the count to the nearest power of 2
+ var x = this.MIN_TIME/this.time;
+ var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2))));
+ count *= pow;
+ if (count > this.MAX_COUNT) {
+ throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.');
+ }
+ }
+ } catch (e) {
+ // Exceptions are caught and displayed in the test UI
+ this.reset();
+ this.error = e;
+ }
+
+ // Figure out what to do next
+ if (this.running) {
+ me.run(count);
+ } else {
+ jsl.status('');
+ me.onStop(me);
+ }
+
+ // Finish up
+ this.onChange(this);
+ },
+
+ /**
+ * Get the number of operations per second for this test.
+ *
+ * @param normalize if true, iteration loop overhead taken into account
+ */
+ getHz: function(/**Boolean*/ normalize) {
+ var p = this.period;
+
+ // Adjust period based on the calibration test time
+ if (normalize && !this.isCalibration) {
+ var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1];
+
+ // If the period is within 20% of the calibration time, then zero the
+ // it out
+ p = p < cal.period*1.2 ? 0 : p - cal.period;
+ }
+
+ return Math.round(1/p);
+ },
+
+ /**
+ * Get a friendly string describing the test
+ */
+ toString: function() {
+ return this.name + ' - ' + this.time/this.count + ' secs';
+ }
+ });
+
+ // CSS we need for the UI
+ var STYLESHEET = '<style> \
+ #jslitmus {font-family:sans-serif; font-size: 12px;} \
+ #jslitmus a {text-decoration: none;} \
+ #jslitmus a:hover {text-decoration: underline;} \
+ #jsl_status { \
+ margin-top: 10px; \
+ font-size: 10px; \
+ color: #888; \
+ } \
+ A IMG {border:none} \
+ #test_results { \
+ margin-top: 10px; \
+ font-size: 12px; \
+ font-family: sans-serif; \
+ border-collapse: collapse; \
+ border-spacing: 0px; \
+ } \
+ #test_results th, #test_results td { \
+ border: solid 1px #ccc; \
+ vertical-align: top; \
+ padding: 3px; \
+ } \
+ #test_results th { \
+ vertical-align: bottom; \
+ background-color: #ccc; \
+ padding: 1px; \
+ font-size: 10px; \
+ } \
+ #test_results #test_platform { \
+ color: #444; \
+ text-align:center; \
+ } \
+ #test_results .test_row { \
+ color: #006; \
+ cursor: pointer; \
+ } \
+ #test_results .test_nonlooping { \
+ border-left-style: dotted; \
+ border-left-width: 2px; \
+ } \
+ #test_results .test_looping { \
+ border-left-style: solid; \
+ border-left-width: 2px; \
+ } \
+ #test_results .test_name {white-space: nowrap;} \
+ #test_results .test_pending { \
+ } \
+ #test_results .test_running { \
+ font-style: italic; \
+ } \
+ #test_results .test_done {} \
+ #test_results .test_done { \
+ text-align: right; \
+ font-family: monospace; \
+ } \
+ #test_results .test_error {color: #600;} \
+ #test_results .test_error .error_head {font-weight:bold;} \
+ #test_results .test_error .error_body {font-size:85%;} \
+ #test_results .test_row:hover td { \
+ background-color: #ffc; \
+ text-decoration: underline; \
+ } \
+ #chart { \
+ margin: 10px 0px; \
+ width: 250px; \
+ } \
+ #chart img { \
+ border: solid 1px #ccc; \
+ margin-bottom: 5px; \
+ } \
+ #chart #tiny_url { \
+ height: 40px; \
+ width: 250px; \
+ } \
+ #jslitmus_credit { \
+ font-size: 10px; \
+ color: #888; \
+ margin-top: 8px; \
+ } \
+ </style>';
+
+ // HTML markup for the UI
+ var MARKUP = '<div id="jslitmus"> \
+ <button onclick="JSLitmus.runAll(event)">Run Tests</button> \
+ <button id="stop_button" disabled="disabled" onclick="JSLitmus.stop()">Stop Tests</button> \
+ <br \> \
+ <br \> \
+ <input type="checkbox" style="vertical-align: middle" id="test_normalize" checked="checked" onchange="JSLitmus.renderAll()""> Normalize results \
+ <table id="test_results"> \
+ <colgroup> \
+ <col /> \
+ <col width="100" /> \
+ </colgroup> \
+ <tr><th id="test_platform" colspan="2">' + platform + '</th></tr> \
+ <tr><th>Test</th><th>Ops/sec</th></tr> \
+ <tr id="test_row_template" class="test_row" style="display:none"> \
+ <td class="test_name"></td> \
+ <td class="test_result">Ready</td> \
+ </tr> \
+ </table> \
+ <div id="jsl_status"></div> \
+ <div id="chart" style="display:none"> \
+ <a id="chart_link" target="_blank"><img id="chart_image"></a> \
+ TinyURL (for chart): \
+ <iframe id="tiny_url" frameBorder="0" scrolling="no" src=""></iframe> \
+ </div> \
+ <a id="jslitmus_credit" title="JSLitmus home page" href="http://code.google.com/p/jslitmus" target="_blank">Powered by JSLitmus</a> \
+ </div>';
+
+ /**
+ * The public API for creating and running tests
+ */
+ window.JSLitmus = {
+ /** The list of all tests that have been registered with JSLitmus.test */
+ _tests: [],
+ /** The queue of tests that need to be run */
+ _queue: [],
+
+ /**
+ * The parsed query parameters the current page URL. This is provided as a
+ * convenience for test functions - it's not used by JSLitmus proper
+ */
+ params: {},
+
+ /**
+ * Initialize
+ */
+ _init: function() {
+ // Parse query params into JSLitmus.params[] hash
+ var match = (location + '').match(/([^?#]*)(#.*)?$/);
+ if (match) {
+ var pairs = match[1].split('&');
+ for (var i = 0; i < pairs.length; i++) {
+ var pair = pairs[i].split('=');
+ if (pair.length > 1) {
+ var key = pair.shift();
+ var value = pair.length > 1 ? pair.join('=') : pair[0];
+ this.params[key] = value;
+ }
+ }
+ }
+
+ // Write out the stylesheet. We have to do this here because IE
+ // doesn't honor sheets written after the document has loaded.
+ document.write(STYLESHEET);
+
+ // Setup the rest of the UI once the document is loaded
+ if (window.addEventListener) {
+ window.addEventListener('load', this._setup, false);
+ } else if (document.addEventListener) {
+ document.addEventListener('load', this._setup, false);
+ } else if (window.attachEvent) {
+ window.attachEvent('onload', this._setup);
+ }
+
+ return this;
+ },
+
+ /**
+ * Set up the UI
+ */
+ _setup: function() {
+ var el = jsl.$('jslitmus_container');
+ if (!el) document.body.appendChild(el = document.createElement('div'));
+
+ el.innerHTML = MARKUP;
+
+ // Render the UI for all our tests
+ for (var i=0; i < JSLitmus._tests.length; i++)
+ JSLitmus.renderTest(JSLitmus._tests[i]);
+ },
+
+ /**
+ * (Re)render all the test results
+ */
+ renderAll: function() {
+ for (var i = 0; i < JSLitmus._tests.length; i++)
+ JSLitmus.renderTest(JSLitmus._tests[i]);
+ JSLitmus.renderChart();
+ },
+
+ /**
+ * (Re)render the chart graphics
+ */
+ renderChart: function() {
+ var url = JSLitmus.chartUrl();
+ jsl.$('chart_link').href = url;
+ jsl.$('chart_image').src = url;
+ jsl.$('chart').style.display = '';
+
+ // Update the tiny URL
+ jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url);
+ },
+
+ /**
+ * (Re)render the results for a specific test
+ */
+ renderTest: function(test) {
+ // Make a new row if needed
+ if (!test._row) {
+ var trow = jsl.$('test_row_template');
+ if (!trow) return;
+
+ test._row = trow.cloneNode(true);
+ test._row.style.display = '';
+ test._row.id = '';
+ test._row.onclick = function() {JSLitmus._queueTest(test);};
+ test._row.title = 'Run ' + test.name + ' test';
+ trow.parentNode.appendChild(test._row);
+ test._row.cells[0].innerHTML = test.name;
+ }
+
+ var cell = test._row.cells[1];
+ var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping'];
+
+ if (test.error) {
+ cns.push('test_error');
+ cell.innerHTML =
+ '<div class="error_head">' + test.error + '</div>' +
+ '<ul class="error_body"><li>' +
+ jsl.join(test.error, ': ', '</li><li>') +
+ '</li></ul>';
+ } else {
+ if (test.running) {
+ cns.push('test_running');
+ cell.innerHTML = 'running';
+ } else if (jsl.indexOf(JSLitmus._queue, test) >= 0) {
+ cns.push('test_pending');
+ cell.innerHTML = 'pending';
+ } else if (test.count) {
+ cns.push('test_done');
+ var hz = test.getHz(jsl.$('test_normalize').checked);
+ cell.innerHTML = hz != Infinity ? hz : '∞';
+ cell.title = 'Looped ' + test.count + ' times in ' + test.time + ' seconds';
+ } else {
+ cell.innerHTML = 'ready';
+ }
+ }
+ cell.className = cns.join(' ');
+ },
+
+ /**
+ * Create a new test
+ */
+ test: function(name, f) {
+ // Create the Test object
+ var test = new Test(name, f);
+ JSLitmus._tests.push(test);
+
+ // Re-render if the test state changes
+ test.onChange = JSLitmus.renderTest;
+
+ // Run the next test if this one finished
+ test.onStop = function(test) {
+ if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test);
+ JSLitmus.currentTest = null;
+ JSLitmus._nextTest();
+ };
+
+ // Render the new test
+ this.renderTest(test);
+ },
+
+ /**
+ * Add all tests to the run queue
+ */
+ runAll: function(e) {
+ e = e || window.event;
+ var reverse = e && e.shiftKey, len = JSLitmus._tests.length;
+ for (var i = 0; i < len; i++) {
+ JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]);
+ }
+ },
+
+ /**
+ * Remove all tests from the run queue. The current test has to finish on
+ * it's own though
+ */
+ stop: function() {
+ while (JSLitmus._queue.length) {
+ var test = JSLitmus._queue.shift();
+ JSLitmus.renderTest(test);
+ }
+ },
+
+ /**
+ * Run the next test in the run queue
+ */
+ _nextTest: function() {
+ if (!JSLitmus.currentTest) {
+ var test = JSLitmus._queue.shift();
+ if (test) {
+ jsl.$('stop_button').disabled = false;
+ JSLitmus.currentTest = test;
+ test.run();
+ JSLitmus.renderTest(test);
+ if (JSLitmus.onTestStart) JSLitmus.onTestStart(test);
+ } else {
+ jsl.$('stop_button').disabled = true;
+ JSLitmus.renderChart();
+ }
+ }
+ },
+
+ /**
+ * Add a test to the run queue
+ */
+ _queueTest: function(test) {
+ if (jsl.indexOf(JSLitmus._queue, test) >= 0) return;
+ JSLitmus._queue.push(test);
+ JSLitmus.renderTest(test);
+ JSLitmus._nextTest();
+ },
+
+ /**
+ * Generate a Google Chart URL that shows the data for all tests
+ */
+ chartUrl: function() {
+ var n = JSLitmus._tests.length, markers = [], data = [];
+ var d, min = 0, max = -1e10;
+ var normalize = jsl.$('test_normalize').checked;
+
+ // Gather test data
+ for (var i=0; i < JSLitmus._tests.length; i++) {
+ var test = JSLitmus._tests[i];
+ if (test.count) {
+ var hz = test.getHz(normalize);
+ var v = hz != Infinity ? hz : 0;
+ data.push(v);
+ markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' +
+ markers.length + ',10');
+ max = Math.max(v, max);
+ }
+ }
+ if (markers.length <= 0) return null;
+
+ // Build chart title
+ var title = document.getElementsByTagName('title');
+ title = (title && title.length) ? title[0].innerHTML : null;
+ var chart_title = [];
+ if (title) chart_title.push(title);
+ chart_title.push('Ops/sec (' + platform + ')');
+
+ // Build labels
+ var labels = [jsl.toLabel(min), jsl.toLabel(max)];
+
+ var w = 250, bw = 15;
+ var bs = 5;
+ var h = markers.length*(bw + bs) + 30 + chart_title.length*20;
+
+ var params = {
+ chtt: escape(chart_title.join('|')),
+ chts: '000000,10',
+ cht: 'bhg', // chart type
+ chd: 't:' + data.join(','), // data set
+ chds: min + ',' + max, // max/min of data
+ chxt: 'x', // label axes
+ chxl: '0:|' + labels.join('|'), // labels
+ chsp: '0,1',
+ chm: markers.join('|'), // test names
+ chbh: [bw, 0, bs].join(','), // bar widths
+ // chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient
+ chs: w + 'x' + h
+ };
+ return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&');
+ }
+ };
+
+ JSLitmus._init();
+})();
\ No newline at end of file
diff --git a/test/view.js b/test/view.js
index e05b2bd..bf7302c 100644
--- a/test/view.js
+++ b/test/view.js
@@ -1,32 +1,33 @@
$(document).ready(function() {
- module("Backbone View");
+ module("Backbone.View");
var view = new Backbone.View({
id : 'test-view',
className : 'test-view'
});
- test("view: constructor", function() {
+ test("View: constructor", function() {
equals(view.el.id, 'test-view');
equals(view.el.className, 'test-view');
equals(view.options.id, 'test-view');
equals(view.options.className, 'test-view');
});
- test("view: jQuery", function() {
+ test("View: jQuery", function() {
view.el = document.body;
- equals(view.$('#qunit-header').text(), 'Backbone Test Suite');
+ equals(view.$('#qunit-header')[0].innerHTML, 'Backbone Test Suite');
+ equals(view.$('#qunit-header')[1].innerHTML, 'Backbone Speed Suite');
});
- test("view: make", function() {
+ test("View: make", function() {
var div = view.make('div', {id: 'test-div'}, "one two three");
equals(div.tagName.toLowerCase(), 'div');
equals(div.id, 'test-div');
equals($(div).text(), 'one two three');
});
- test("view: initialize", function() {
+ test("View: initialize", function() {
var View = Backbone.View.extend({
initialize: function() {
this.one = 1;
@@ -36,7 +37,7 @@ $(document).ready(function() {
equals(view.one, 1);
});
- test("view: handleEvents", function() {
+ test("View: handleEvents", function() {
var counter = 0;
view.el = document.body;
view.increment = function() {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/backbone.git
More information about the Pkg-javascript-commits
mailing list