Skip to content

Commit

Permalink
[#2648] Update ckan.sandbox() and unit tests
Browse files Browse the repository at this point in the history
Sandbox now has nothing but helper functions.
  • Loading branch information
aron committed Jul 11, 2012
1 parent 1bae4d9 commit 0e41c65
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 34 deletions.
68 changes: 45 additions & 23 deletions ckan/public/base/javascript/sandbox.js
Expand Up @@ -34,49 +34,43 @@ this.ckan = this.ckan || {};
*
*/
(function (ckan, $) {
var callbacks = [];

/* Creates a new instance of Sandbox.
*
* element - An element that the sandbox is bound to.
* options - An object of key/value pairs.
*
* Examples
*
* new Sandbox(element, {a: 1, b: 2, c: 3});
* new Sandbox();
*
* Returns a new instance of Sandbox.
*/
function Sandbox(element, options) {
this.el = element instanceof $ ? element : $(element);
this.options = options || {};
function Sandbox(callbacks) {
var index = 0;
var length = callbacks ? callbacks.length : 0;

// Allow libraries to add objects/arrays to the sandbox object as they
// cannot be added to the prototype without being shared.
for (; index < length; index += 1) {
callbacks[index](this);
}
}

$.extend(Sandbox.prototype, {
/* The jQuery element for the current module */
el: null,

/* The options object passed into the module either via data-* attributes
* or the default settings.
*/
options: null,

/* A scoped find function restricted to the current scope. */
$: function (selector) {
return this.el.find(selector);
},
jQuery: $,

/* An alias for jQuery.ajax() */
ajax: $.ajax,
ajax: $.ajax
});

/* Factory function for creating new sandbox instances. This should be
* used in preference to the Sandbox constructor.
*
* Returns a new Sandbox instance.
*/
ckan.sandbox = function (element, options) {
return new Sandbox(element, options);
};
function sandbox(element, options) {
return new sandbox.Sandbox(ckan.sandbox.callbacks);
}

/* Allows the extension of the Sandbox prototype by other core libraries.
*
Expand All @@ -92,12 +86,40 @@ this.ckan = this.ckan || {};
*
* Returns the ckan object.
*/
ckan.sandbox.extend = function (props) {
sandbox.extend = function (props) {
$.extend(Sandbox.prototype, props || {});
return ckan;
};

/* Allows the extension of the Sandbox with objects and arrays. These
* cannot be added to the prototype without them being shared across
* all instances.
*
* fn - A callback that receives the sandbox object.
*
* Examples
*
* ckan.sandbox.setup(function (sandbox) {
* sandbox.myObject = {};
* sandbox.myArray = [];
* });
*
* Returns the ckan object.
*/
sandbox.setup = function setup(fn) {
var callbacks = ckan.sandbox.callbacks = ckan.sandbox.callbacks || [];

if (typeof fn === 'function') {
callbacks.push(fn);
} else {
throw new Error('ckan.sandbox.setup() must be passed a function');
}

return ckan;
};

// Export Sandbox for testing.
ckan.sandbox = sandbox;
ckan.sandbox.Sandbox = Sandbox;

})(this.ckan, this.jQuery);
67 changes: 56 additions & 11 deletions ckan/public/base/test/spec/sandbox.spec.js
@@ -1,30 +1,75 @@
/*globals describe beforeEach afterEach it assert sinon ckan jQuery */
describe('ckan.sandbox()', function () {
it('should create an instance of Sandbox', function () {
var target = sinon.stub(ckan.sandbox, 'Sandbox');
ckan.sandbox();
sinon.assert.called(target);
target.restore();
});

it('should pass in sandbox.callbacks', function () {
var target = sinon.stub(ckan.sandbox, 'Sandbox');
ckan.sandbox();
sinon.assert.calledWith(target, ckan.sandbox.callbacks);
target.restore();
});

describe('Sandbox()', function () {
var Sandbox = ckan.sandbox.Sandbox;

beforeEach(function () {
this.el = document.createElement('div');
this.options = {prop1: 1, prop2: 2, prop3: 3};
});

describe('.options', function () {
it('should be a reference to the options passed into Sandbox');
});
it('should call each callback provided with itself', function () {
var callbacks = [sinon.spy(), sinon.spy(), sinon.spy()];

describe('.el', function () {
it('should the element passed into Sandbox wrapped in jQuery');
});
var target = new Sandbox(callbacks);

describe('.$()', function () {
it('should find elements within the .el property');
jQuery.each(callbacks, function () {
sinon.assert.called(this);
sinon.assert.calledWith(this, target);
});
});

describe('.ajax()', function () {
it('should be an alias for the jQuery.ajax() method', function () {
var target = new Sandbox(this.el, this.options);
var target = new Sandbox();
assert.strictEqual(target.ajax, jQuery.ajax);
});
});

describe('.jQuery()', function () {
it('should be a reference to jQuery', function () {
var target = new Sandbox();
assert.strictEqual(target.jQuery, jQuery);
});
});
});

describe('sandbox.extend()', function () {
it('should extend the Sandbox.prototype with properties', function () {
var method = sinon.spy();

ckan.sandbox.extend({method: method});

assert.equal(ckan.sandbox().method, method);
});
});

describe('sandbox.setup()', function () {
it('should register a function to be called when the sandbox is initialized', function () {
var target = sinon.spy();

ckan.sandbox.setup(target);
ckan.sandbox();

sinon.assert.called(target);
});

it('should throw an error if a non function is provided', function () {
assert.throws(function () {
ckan.sandbox.setup('not a function');
});
});
});
});

0 comments on commit 0e41c65

Please sign in to comment.