The LocalStore handles data storage via MongoDB.
Core tests run: {"testsCreated":528}
objects created should be an instance of Store:
return new SurrogateStore() instanceof Store;
returns true as expectedshould make sure new operator used: ```javascript SurrogateStore(); // jshint ignore:line ```
Error: new operator required thrown as expectedshould make sure properties are valid: ```javascript new SurrogateStore({food: 'twinkies'}); ```
Error: error creating Store: invalid property: food thrown as expectedobjects created should be an instance of LocalStore: ```javascript return new LocalStore() instanceof LocalStore; ```
returns true as expected#### Store tests are applied #### PROPERTIES #### name name of store can be set in constructor: ```javascript return new SurrogateStore({name: 'punchedCards'}).name; ```
returns punchedCards as expected#### storeType storeType defaults to Store Class Name but can be set to suite the app architecture.
storeType can be set in constructor:
return new SurrogateStore({storeType: 'legacyStorage'}).storeType;
returns legacyStorage as expected#### METHODS getServices() returns an object with interface for the Store.: ```javascript this.log(JSON.stringify(services)); this.shouldBeTrue(services instanceof Object); this.shouldBeTrue(typeof services['isReady'] == 'boolean'); // don't use until this.shouldBeTrue(typeof services['canGetModel'] == 'boolean'); // define all allowed methods... this.shouldBeTrue(typeof services['canPutModel'] == 'boolean'); this.shouldBeTrue(typeof services['canDeleteModel'] == 'boolean'); this.shouldBeTrue(typeof services['canGetList'] == 'boolean'); ```
log: {"isReady":true,"canGetModel":true,"canPutModel":true,"canDeleteModel":true,"canGetList":true}#### toString() should return a description of the Store: ```javascript var cStore = new SurrogateStore(); this.log(cStore.toString()); cStore.name = '7-Eleven'; cStore.storeType = 'ConvenienceStore'; this.log(cStore.toString()); return cStore.toString(); ```
log: a LocalStore#### onConnect() must pass url string: ```javascript new SurrogateStore().onConnect(); ```
log: ConvenienceStore: 7-Eleven
returns ConvenienceStore: 7-Eleven as expected
Error: argument must a url string thrown as expectedmust pass callback function: ```javascript new SurrogateStore().onConnect(""); ```
Error: argument must a callback thrown as expectedreturn store and undefined error upon successful connection to remote store.: ```javascript new SurrogateStore().onConnect('', function (store, err) { if (err) { callback(err); } else { callback(store instanceof Store); } }); ```
returns true as expected#### getModel() must pass valid model: ```javascript new SurrogateStore().getModel(); ```
Error: argument must be a Model thrown as expectedmodel must have no validation errors: ```javascript var m = new Model(); m.attributes = null; new SurrogateStore().getModel(m); ```
Error: model has validation errors thrown as expectedID attribute must have truthy value: ```javascript new SurrogateStore().getModel(new Model()); ```
Error: ID not set thrown as expectedcallback function required: ```javascript var m = new Model(); m.attributes[0].value = 1; new SurrogateStore().getModel(m); ```
Error: callback required thrown as expectedreturns error when model not found: ```javascript var m = new Model(); m.modelType = "Supermodel"; // change type so one not used in tests m.attributes[0].value = 1; new SurrogateStore().getModel(m, function (mod, err) { if (err) { callback(err); } else { callback(mod); } }); ```
returns Error: model not found in store as expected#### putModel(model) must pass valid model: ```javascript new SurrogateStore().putModel(); ```
Error: argument must be a Model thrown as expectedmodel must have no validation errors: ```javascript var m = new Model(); m.attributes = null; new SurrogateStore().putModel(m); ```
Error: model has validation errors thrown as expectedcallback function required: ```javascript var m = new Model(); m.attributes[0].value = 1; new SurrogateStore().putModel(m); ```
Error: callback required thrown as expectedreturns error when model not found: ```javascript var m = new Model(); m.modelType = "Supermodel"; m.attributes[0].value = 1; new SurrogateStore().putModel(m, function (mod, err) { if (err) { callback(err); } else { callback(mod); } }); ```
returns Error: model not found in store as expectedcreates new model when ID is not set: ```javascript // This works but pollutes store with crap var m = new Model(); new SurrogateStore().putModel(m, function (mod, err) { if (err) { callback(err); } else { callback(mod.get('id') ? true : false); } }); ```
returns true as expected#### deleteModel(model) must pass valid model: ```javascript new SurrogateStore().deleteModel(); ```
Error: argument must be a Model thrown as expectedmodel must have no validation errors: ```javascript var m = new Model(); m.attributes = null; new SurrogateStore().deleteModel(m); ```
Error: model has validation errors thrown as expectedcallback function required: ```javascript var m = new Model(); m.attributes[0].value = 1; new SurrogateStore().deleteModel(m); ```
Error: callback required thrown as expectedreturns error when model not found: ```javascript var m = new Model(); m.modelType = 'PeopleAreString!'; m.attributes[0].value = 90210; new SurrogateStore().deleteModel(m, function (mod, err) { if (err) { callback(err); } else { callback(mod); } }); ```
returns Error: model not found in store as expected#### getList(model, filter, order) This method will clear and populate the list with collection from store. The **filter** property can be used to query the store. The **order** property can specify the sort order of the list. _See integration test for more info._
returns a List populated from store:
this.shouldThrowError(Error('argument must be a List'), function () {
new SurrogateStore().getList();
});
this.shouldThrowError(Error('filter argument must be Object'), function () {
new SurrogateStore().getList(new List(new Model()));
});
this.shouldThrowError(Error('callback required'), function () {
new SurrogateStore().getList(new List(new Model()), []);
});
// See integration tests for examples of usage
Exercise all store function for one store.:
var self = this;
spec.integrationStore = new SurrogateStore();
var storeBeingTested = spec.integrationStore.name + ' ' + spec.integrationStore.storeType;
self.log(storeBeingTested);
// If store is not ready then get out...
if (!spec.integrationStore.getServices().isReady) {
self.log('Store is not ready.');
callback(true);
return;
}
// setup stooge class
self.Stooge = function (args) {
Model.call(this, args);
this.modelType = "_tempTest_Stooge";
this.attributes.push(new Attribute('name'));
};
self.Stooge.prototype = inheritPrototype(Model.prototype);
// create initial stooges
self.moe = new self.Stooge();
self.moe.set('name', 'Moe');
self.larry = new self.Stooge();
self.larry.set('name', 'Larry');
self.shemp = new self.Stooge();
self.shemp.set('name', 'Shemp');
// IDs after stored will be here
self.stoogeIDsStored = [];
self.stoogesRetrieved = [];
self.oldStoogesFound = 0;
self.oldStoogesKilled = 0;
// Make sure store starts in known state. Stores such as mongoStore will retain test values.
// So... use getList to get all stooges then delete them from the Store
var useListToCleanStart = spec.integrationStore.getServices().canGetList;
if (useListToCleanStart) {
var list = new List(new self.Stooge());
try {
self.killhim = new self.Stooge();
spec.integrationStore.getList(list, [], function (list, error) {
if (typeof error != 'undefined') {
callback(error);
return;
}
if (list._items.length < 1)
storeStooges();
else
self.oldStoogesFound = list._items.length;
for (var i = 0; i < list._items.length; i++) {
self.killhim.set('id', list._items[i][0]);
/* jshint ignore:start */
spec.integrationStore.deleteModel(self.killhim, function (model, error) {
if (++self.oldStoogesKilled >= self.oldStoogesFound) {
storeStooges();
}
})
/* jshint ignore:end */
}
});
}
catch (err) {
callback(err);
}
} else {
storeStooges();
}
// callback to store new stooges
function storeStooges() {
self.log(self.oldStoogesFound);
self.log(self.oldStoogesKilled);
spec.integrationStore.putModel(self.moe, stoogeStored);
spec.integrationStore.putModel(self.larry, stoogeStored);
spec.integrationStore.putModel(self.shemp, stoogeStored);
}
// callback after storing stooges
function stoogeStored(model, error) {
if (typeof error != 'undefined') {
callback(error);
return;
}
try {
self.stoogeIDsStored.push(model.get('id'));
if (self.stoogeIDsStored.length == 3) {
self.shouldBeTrue(true,'here');
// Now that first 3 stooges are stored lets retrieve and verify
var actors = [];
for (var i = 0; i < 3; i++) {
actors.push(new self.Stooge());
actors[i].set('id', self.stoogeIDsStored[i]);
spec.integrationStore.getModel(actors[i], stoogeRetrieved);
}
}
}
catch (err) {
callback(err);
}
}
// callback after retrieving stored stooges
function stoogeRetrieved(model, error) {
if (typeof error != 'undefined') {
callback(error);
return;
}
self.stoogesRetrieved.push(model);
if (self.stoogesRetrieved.length == 3) {
self.shouldBeTrue(true,'here');
// Now we have stored and retrieved (via IDs into new objects). So verify the stooges made it
self.shouldBeTrue(self.stoogesRetrieved[0] !== self.moe && // Make sure not a reference but a copy
self.stoogesRetrieved[0] !== self.larry && self.stoogesRetrieved[0] !== self.shemp,'copy');
var s = []; // get list of names to see if all stooges made it
for (var i = 0; i < 3; i++) s.push(self.stoogesRetrieved[i].get('name'));
self.log(s);
self.shouldBeTrue(contains(s, 'Moe') && contains(s, 'Larry') && contains(s, 'Shemp'));
// Replace Shemp with Curly
var didPutCurly = false;
for (i = 0; i < 3; i++) {
if (self.stoogesRetrieved[i].get('name') == 'Shemp') {
didPutCurly = true;
self.stoogesRetrieved[i].set('name', 'Curly');
try {
spec.integrationStore.putModel(self.stoogesRetrieved[i], stoogeChanged);
}
catch (err) {
callback(err);
}
}
}
if (!didPutCurly) {
callback(Error("Can't find Shemp!"));
}
}
}
// callback after storing changed stooge
function stoogeChanged(model, error) {
if (typeof error != 'undefined') {
callback(error);
return;
}
self.shouldBeTrue(model.get('name') == 'Curly','Curly');
var curly = new self.Stooge();
curly.set('id', model.get('id'));
try {
spec.integrationStore.getModel(curly, storeChangedShempToCurly);
}
catch (err) {
callback(err);
}
}
// callback after retrieving changed stooge
function storeChangedShempToCurly(model, error) {
if (typeof error != 'undefined') {
callback(error);
return;
}
self.shouldBeTrue(model.get('name') == 'Curly','Curly');
// Now test delete
self.deletedModelId = model.get('id'); // Remember this
spec.integrationStore.deleteModel(model, stoogeDeleted);
}
// callback when Curly is deleted
function stoogeDeleted(model, error) {
if (typeof error != 'undefined') {
callback(error);
return;
}
// model parameter is what was deleted
self.shouldBeTrue(undefined === model.get('id')); // ID removed
self.shouldBeTrue(model.get('name') == 'Curly'); // the rest remains
// Is it really dead?
var curly = new self.Stooge();
curly.set('id', self.deletedModelId);
spec.integrationStore.getModel(curly, hesDeadJim);
}
// callback after lookup of dead stooge
function hesDeadJim(model, error) {
if (typeof error != 'undefined') {
if ((error != 'Error: id not found in store') && (error != 'Error: model not found in store')) {
callback(error);
return;
}
} else {
callback(Error('no error deleting stooge when expected'));
return;
}
// Skip List test if subclass can't do
if (!spec.integrationStore.getServices().canGetList) {
callback(true);
} else {
// Now create a list from the stooge store
var list = new List(new self.Stooge());
try {
spec.integrationStore.getList(list, {}, {name:1}, listReady);
}
catch (err) {
callback(err);
}
}
}
// callback after list created from store
function listReady(list, error) {
// list.sort({name:1});
if (typeof error != 'undefined') {
callback(error);
return;
}
self.shouldBeTrue(list instanceof List,'is list');
self.shouldBeTrue(list.length() == 2,'is 2');
list.moveFirst();
self.shouldBeTrue(list.get('name') == 'Larry','larry');
list.moveNext();
self.shouldBeTrue(list.get('name') == 'Moe','moe');
callback(true);
}
log: a LocalStore LocalStoreTest variations on getList method.: ```javascript var test = this; var storeBeingTested = new SurrogateStore(); test.log('storeBeingTested: ' + storeBeingTested); // Create list of actors test.actorsInfo = [ // Actor Born Male Oscards ['Jack Nicholson', new Date("01/01/1937"), true, 3], ['Meryl Streep', new Date("01/01/1949"), false, 3], ['Marlon Brando', new Date("01/01/1924"), true, 2], ['Cate Blanchett', new Date("01/01/1969"), false, 1], ['Robert De Niro', new Date("01/01/1943"), true, 2], ['Judi Dench', new Date("01/01/1934"), false, 1], ['Al Pacino', new Date("01/01/1940"), true, 1], ['Nicole Kidman', new Date("01/01/1967"), false, null], ['Daniel Day-Lewis', new Date("01/01/1957"), true, null], ['Shirley MacLaine', new Date("01/01/1934"), false, null], ['Dustin Hoffman', new Date("01/01/1937"), true, null], ['Jodie Foster', new Date("01/01/1962"), false, null], ['Tom Hanks', new Date("01/01/1956"), true, null], ['Kate Winslet', new Date("01/01/1975"), false, null], ['Anthony Hopkins', new Date("01/01/1937"), true, null], ['Angelina Jolie', new Date("01/01/1975"), false, null], ['Paul Newman', new Date("01/01/1925"), true, null], ['Sandra Bullock', new Date("01/01/1964"), false, null], ['Denzel Washington', new Date("01/01/1954"), true, null], ['Renée Zellweger', new Date("01/01/1969"), false, null] ]; // Create actor class test.Actor = function (args) { Model.call(this, args); this.modelType = "Actor"; this.attributes.push(new Attribute('name')); this.attributes.push(new Attribute('born', 'Date')); this.attributes.push(new Attribute('isMale', 'Boolean')); this.attributes.push(new Attribute('oscarWs', 'Number')); }; test.Actor.prototype = inheritPrototype(Model.prototype); test.actor = new test.Actor(); // instance to use for stuff // Make sure store starts in known state. Stores such as mongoStore will retain test values. // So... use getList to get all Actors then delete them from the Store test.list = new List(new test.Actor()); test.oldActorsKilled = 0; test.oldActorsFound = 0; try { test.killhim = new test.Actor(); storeBeingTested.getList(test.list, [], function (list, error) { if (typeof error != 'undefined') { callback(error); return; } if (list._items.length < 1) storeActors(); else { test.oldActorsFound = list._items.length; var testakill = function (model, error) { if (++test.oldActorsKilled >= test.oldActorsFound) { storeActors(); } }; for (var i = 0; i < list._items.length; i++) { test.killhim.set('id', list._items[i][0]); storeBeingTested.deleteModel(test.killhim, testakill); } } }); } catch (err) { callback(err); } // callback after model cleaned // now, build List and add to store function storeActors() { test.actorsStored = 0; for (var i = 0; i < test.actorsInfo.length; i++) { test.actor.set('ID', null); test.actor.set('name', test.actorsInfo[i][0]); test.actor.set('born', test.actorsInfo[i][1]); test.actor.set('isMale', test.actorsInfo[i][2]); storeBeingTested.putModel(test.actor, actorStored); } } // callback after actor stored function actorStored(model, error) { if (typeof error != 'undefined') { callback(error); return; } if (++test.actorsStored >= test.actorsInfo.length) { getAllActors(); } } // test getting all 20 function getAllActors() { try { storeBeingTested.getList(test.list, {}, function (list, error) { if (typeof error != 'undefined') { callback(error); return; } test.shouldBeTrue(list._items.length == 20, '20'); getTomHanks(); }); } catch (err) { callback(err); } } // only one Tom Hanks function getTomHanks() { try { storeBeingTested.getList(test.list, {name: "Tom Hanks"}, function (list, error) { if (typeof error != 'undefined') { callback(error); return; } test.shouldBeTrue(list._items.length == 1, ('1 not ' + list._items.length)); getD(); }); } catch (err) { callback(err); } } // 3 names begin with D // test RegExp function getD() { try { storeBeingTested.getList(test.list, {name: /^D/}, function (list, error) { if (typeof error != 'undefined') { callback(error); return; } test.shouldBeTrue(list._items.length == 3, ('3 not ' + list._items.length)); getRZ(); }); } catch (err) { callback(err); } } // Renée Zellweger only female starting name with 'R' // test filter 2 properties (logical AND) function getRZ() { try { storeBeingTested.getList(test.list, {name: /^R/, isMale: false}, function (list, error) { if (typeof error != 'undefined') { callback(error); return; } test.shouldBeTrue(list._items.length == 1, ('1 not ' + list._items.length)); if (list._items.length) test.shouldBeTrue(list.get('name') == 'Renée Zellweger', 'rz'); getAlphabetical(); }); } catch (err) { callback(err); } } // Retrieve list alphabetically by name // test order parameter function getAlphabetical() { try { storeBeingTested.getList(test.list, {}, {name: 1}, function (list, error) { if (typeof error != 'undefined') { callback(error); return; } // Verify each move returns true when move succeeds test.shouldBeTrue(list.moveFirst(), 'moveFirst'); test.shouldBeTrue(!list.movePrevious(), 'movePrevious'); test.shouldBeTrue(list.get('name') == 'Al Pacino', 'AP'); test.shouldBeTrue(list.moveLast(), 'moveLast'); test.shouldBeTrue(!list.moveNext(), 'moveNext'); test.shouldBeTrue(list.get('name') == 'Tom Hanks', 'TH'); callback(true); }); } catch (err) { callback(err); } } ```
log: 0
log: 0
log: Moe,Larry,Shemp
returns true as expected
log: storeBeingTested: a LocalStore## [◀](#-localstorage) [⌘](#constructors) Summary This documentation generated with https://github.com/tgicloud/tgi-spec.
returns true as expected
TODO put testin stats here.