Skip to content

Instantly share code, notes, and snippets.

@DomDerrien
Created July 21, 2014 13:56
Show Gist options
  • Save DomDerrien/df586b4b478d3f9613aa to your computer and use it in GitHub Desktop.
Save DomDerrien/df586b4b478d3f9613aa to your computer and use it in GitHub Desktop.
Dojo & Intern: use of `require.undef()` to be able to get a freshly loaded module as parameter for `require()`
/*global define, indexedDB*/
/*jslint white: true*/
/* Source: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB */
define([
'dojo/_base/declare',
'dojo/Deferred',
'dojo/has',
'tests/MockHandler'
], function (declare, Deferred, has, MockHandler) {
'use strict';
var localIndexedDb = typeof indexedDB === 'undefined' ? null : indexedDB, // because `indexedDB` does not exist in the Node.js environment -- part of the test cannot be covered with a unit test :(
mockHandler,
expose;
has.add('IndexedDB', localIndexedDb !== null);
if (has('tests-api')) {
mockHandler = new MockHandler({
Deferred: Deferred,
localIndexedDb: localIndexedDb
});
}
function setMocks(params) {
params = params || {};
Deferred = mockHandler.set('Deferred', params.Deferred);
localIndexedDb = mockHandler.set('localIndexedDb', params.localIndexedDb);
}
expose = declare(null, {
databaseDfd: null,
entityStore: null,
entityName: null,
idProperty: '_id',
version: 1,
constructor: function (params) {
this.databaseDfd = new Deferred();
params = params || {};
if (has('tests-api')) {
setMocks(params.mocks);
}
this.entityName = params.entityName;
this.idProperty = params.idProperty || this.idProperty;
this.version = params.version || this.version;
if (!has('IndexedDB')) {
this.databaseDfd.reject('No support of IndexedDB');
return;
}
var request = localIndexedDb.open(this.entityName, this.version),
self = this;
// Database creation on the fly
request.onupgradeneeded = function (event) {
var database = event.target.result,
objectStore,
idx;
// Generic error handler
database.onerror = function (event) {
self.databaseDfd.reject(event.target.error);
};
// Store and indexes creation
objectStore = database.createObjectStore(self.entityName, {
keyPath: self.idProperty
});
objectStore.createIndex(self.idProperty, self.idProperty, {
unique: true
});
if (params.indexedFields) {
for (idx = 0; idx < params.indexedFields.length; idx += 1) {
objectStore.createIndex(params.indexedFields[idx], params.indexedFields[idx], {
unique: false
});
}
}
};
// Process of the viable database connexion
request.onsuccess = function (event) {
self.databaseDfd.resolve(event.target.result);
};
},
get: function (id) {
var self = this,
dfd = new Deferred();
this.databaseDfd.then(function (database) {
var transaction = database.transaction(self.entityName, 'readonly'),
objectStore = transaction.objectStore(self.entityName),
request = objectStore.get(id);
// Generic error handler
database.onerror = function (event) {
dfd.reject(event.target.error);
};
// Forward the retreived entity
request.onsuccess = function (event) {
dfd.resolve(event.target.result);
};
}, function (error) {
dfd.reject(error);
});
return dfd.promise;
},
query: function () { // query, directives
var self = this,
dfd = new Deferred();
this.databaseDfd.then(function (database) {
var transaction = database.transaction(self.entityName, 'readonly'),
objectStore = transaction.objectStore(self.entityName),
// TODO: Find a way to use the idProperty or secondKEy from the filter, request = filters ? objectStore.index(self.idProperty).openCursor(IDBKeyRange.only(filters)) : objectStore.openCursor();
request = objectStore.openCursor(),
entities = [];
// Generic error handler
database.onerror = function (event) {
dfd.reject(event.target.error);
};
// Accumulate the retreived entities
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
entities.push(cursor.value);
cursor['continue']();
}
else {
dfd.resolve(entities);
}
};
}, function (error) {
dfd.reject(error);
});
return dfd.promise;
},
add: function () {
var dfd = new Deferred();
dfd.reject('Not supported operation');
return dfd.promise;
},
put: function (entity) {
var self = this,
dfd = new Deferred();
this.databaseDfd.then(function (database) {
var transaction = database.transaction(self.entityName, 'readwrite'),
objectStore = transaction.objectStore(self.entityName),
request = objectStore.put(entity);
// Generic error handler
database.onerror = function (event) {
dfd.reject(event.target.error);
};
// Forward the updated entity
request.onsuccess = function (event) {
dfd.resolve(event.target.result);
};
}, function (error) {
dfd.reject(error);
});
return dfd.promise;
},
remove: function (id) {
var self = this,
dfd = new Deferred();
this.databaseDfd.then(function (database) {
var transaction = database.transaction(self.entityName, 'readwrite'),
objectStore = transaction.objectStore(self.entityName),
request = objectStore['delete'](id);
// Generic error handler
database.onerror = function (event) {
dfd.reject(event.target.error);
};
// Forward the deletion acknoledgement
request.onsuccess = function () {
dfd.resolve();
};
}, function (error) {
dfd.reject(error);
});
return dfd.promise;
}
});
return expose;
});
/*global define, require*/
/*jslint nomen: true, white: true, forin: true*/
define([
'intern!object',
'intern/chai!assert',
'intern/node_modules/dojo/has',
'intern/node_modules/dojo/Deferred',
'../IDBStore'
], function (registerSuite, assert, has, Deferred, IDBStore) {
'use strict';
registerSuite({
name: 'IndexedDB store',
setup: function () {},
beforeEach: function () {
has.add('tests-api', true, false, true);
},
afterEach: function () {},
teardown: function () {
require.undef('ubi/utils/IDBStore');
},
'initialization': {
'test configuration': function () {
assert.isNotNull(new IDBStore().databaseDfd);
},
'production configuration': function () {
require.undef('ubi/storage/IDBStore');
has.add('tests-api', false, false, true);
require(['ubi/storage/IDBStore'], this.async(1000).callback(function (IDBStore) {
assert.isNotNull(new IDBStore().databaseDfd);
}));
}
},
// ... More tests ...
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment