/**
* Nested Records and the Data Store(SC.Record) Unit Test * * @author Evin Grano */
/*global ok, equals, test, module */
// .….….….….….….….….….….….….….….. // Basic Set up needs to move to the setup and teardown // var NestedRecord, store, storeKeys;
var initModels = function () {
NestedRecord.Directory = SC.Record.extend({ /** Child Record Namespace */ nestedRecordNamespace: NestedRecord, name: SC.Record.attr(String), contents: SC.Record.toMany('SC.Record', { isNested: true }) }); NestedRecord.File = SC.Record.extend({ name: SC.Record.attr(String) });
};
// .….….….….….….….….….….….….….….. // Basic SC
.Record Stuff // module(“Data Store Tests for Nested Records”, {
setup: function () { SC.RunLoop.begin(); NestedRecord = SC.Object.create({ store: SC.Store.create() }); store = NestedRecord.store; initModels(); storeKeys = store.loadRecords([NestedRecord.Directory, NestedRecord.File], [ { type: 'Directory', name: 'Dir 1', guid: 1, contents: [ { type: 'Directory', name: 'Dir 2', guid: 2, contents: [ { type: 'File', guid: 3, name: 'File 1' }, { type: 'File', guid: 4, name: 'File 2' } ] } ] }, { type: 'File', id: 5, name: 'File 3' } ]); SC.RunLoop.end(); }, teardown: function () { delete NestedRecord.Directory; delete NestedRecord.File; NestedRecord = null; store = null; }
});
test(“Proper Initialization”, function () {
var first, second; equals(storeKeys.get('length'), 2, "number of primary store keys should be 2"); // First SC.run(function() { first = store.materializeRecord(storeKeys[0]); }); ok(SC.kindOf(first, SC.Record), "first record is a kind of a SC.Record Object"); ok(SC.instanceOf(first, NestedRecord.Directory), "first record is a instance of a NestedRecord.Directory Object"); // Second SC.run(function() { second = store.materializeRecord(storeKeys[1]); }); ok(SC.kindOf(second, SC.Record), "second record is a kind of a SC.Record Object"); ok(SC.instanceOf(second, NestedRecord.File), "second record is a instance of a NestedRecord.File Object");
});
test(“Test that reset() clears out the store for re-use”, function () {
var isEmptyObject = function ( obj ) { var name; for (name in obj) { return false; } return true; }; var parent, child; SC.run(function() { parent = store.materializeRecord(storeKeys[0]); }); SC.run(function() { child = parent.get('contents').firstObject(); }); ok(!isEmptyObject(store.parentRecords), "We expect there to be values in store.parentRecords"); ok(!isEmptyObject(store.childRecords), "We expect there to be values in store.childRecords"); store.reset(); ok(isEmptyObject(store.parentRecords), "We expect there to no longer be any values in store.parentRecords"); ok(isEmptyObject(store.childRecords), "We expect there to no longer be any values in store.childRecords");
});
test(“Proper Status”, function () {
var first, second; // First SC.run(function() { first = store.materializeRecord(storeKeys[0]); }); equals(first.get('status'), SC.Record.READY_CLEAN, 'first record has a READY_CLEAN State'); // Second SC.run(function() { second = store.materializeRecord(storeKeys[1]); }); equals(second.get('status'), SC.Record.READY_CLEAN, 'second record has a READY_CLEAN State'); // Shallow property update. SC.run(function() { first.get('contents').objectAt(0).set('name', 'Dir 2 - Updated') }); equals(first.get('status'), SC.Record.READY_DIRTY, 'first record has a READY_DIRTY State');
});
test(“Deep property update”, function () {
var first, second; // First SC.run(function() { first = store.materializeRecord(storeKeys[0]); }); equals(first.get('status'), SC.Record.READY_CLEAN, 'first record has a READY_CLEAN State'); // Deep property update. SC.run(function() { first.get('contents').objectAt(0).get('contents').objectAt(0).set('name', 'Dir 2 - Updated') }); equals(first.get('status'), SC.Record.READY_DIRTY, 'first record has a READY_DIRTY State');
});
test(“Can Push onto child array”, function () {
var first, contents; // First SC.run(function() { first = store.materializeRecord(storeKeys[0]); first = first.get('contents').objectAt(0); contents = first.get('contents'); equals(contents.get('length'), 2, "should have two items"); contents.forEach(function (f) { ok(SC.instanceOf(f, NestedRecord.File), "should be a NestedRecord.File"); ok(f.get('name'), "should have a name property"); }); contents.pushObject({type: 'File', name: 'File 4', id: 12}); equals(contents.get('length'), 3, "should have three items"); contents.forEach(function (f) { ok(SC.instanceOf(f, NestedRecord.File), "should be a NestedRecord.File"); ok(f.get('name'), "should have a name property"); equals(f.get('status'), SC.Record.READY_DIRTY, 'second record has a READY_DIRTY State'); }); });
});
test(“Use in Nested Store”, function () {
var nstore, dir, c, file, pk, id, nFile, nDir; // First, find the first file SC.run(function() { dir = store.find(NestedRecord.Directory, 1); }); ok(dir, "Directory id:1 exists"); equals(dir.get('name'), 'Dir 1', "Directory id:1 has a name of 'Dir 1'"); c = dir.get('contents'); ok(c, "Content of Directory id:1 exists"); SC.run(function() {dir = c.objectAt(0);}); ok(dir, "Directory id:2 exists"); equals(dir.get('name'), 'Dir 2', "Directory id:2 has a name of 'Dir 2'"); c = dir.get('contents'); ok(c, "Content of Directory id:2 exists"); SC.run(function() {file = c.objectAt(0);}); ok(file, "File id:1 exists"); equals(file.get('name'), 'File 1', "File id:1 has a name of 'File 1'"); // Second, create nested store nstore = store.chain(); SC.RunLoop.begin(); pk = file.get('primaryKey'); id = file.get(pk); nFile = nstore.find(NestedRecord.File, id); SC.RunLoop.end(); ok(nFile, "Nested > File id:1 exists"); equals(nFile.get('name'), 'File 1', "Nested > File id:1 has a name of 'File 1'"); // Third, change the name of the nested store and see what happens SC.run(function(){nFile.set('name', 'Change Name');}); equals(nFile.get('name'), 'Change Name', "Nested > File id:1 has changed the name to 'Changed Name'"); equals(file.get('name'), 'File 1', "Base > File id:1 still has the name of 'File 1'"); nDir = nstore.find(NestedRecord.Directory, 1); // Fourth, commit the changes SC.run(function(){ nstore.commitChanges(); nstore.destroy(); }); nstore = null; equals(file.get('name'), 'Change Name', "Base > File id:1 has changed to name of 'Changed Name'"); // Fifth, double check that the change exists dir = store.find(NestedRecord.Directory, 1); SC.run(function() { file = dir.get('contents').objectAt(0).get('contents').objectAt(0); }); equals(dir.get('status'), SC.Record.READY_DIRTY, 'Base > Directory id:1 has a READY_DIRTY State'); equals(file.get('status'), SC.Record.READY_DIRTY, 'Base > File id:1 has a READY_DIRTY State'); equals(file.get('name'), 'Change Name', "Base > File id:1 has actually changed to name of 'Changed Name'");
});
test(“Store#pushRetrieve for parent updates the child records”, function () {
SC.RunLoop.begin() var parent = store.materializeRecord(storeKeys[0]), nr = parent.get('contents').firstObject(), newDataHash = { type: 'Directory', name: 'Dir 1 Changed', guid: 1, contents: [ { type: 'Directory', name: 'Dir 2 Changed', guid: 2, contents: [ { type: 'File', guid: 3, name: 'File 1' }, { type: 'File', guid: 4, name: 'File 2' } ] } ] }; parent = store.materializeRecord(storeKeys[0]); nr = parent.get('contents').get('firstObject'); ok(nr, "Got nested record"); equals(nr.get('name'), 'Dir 2', "Dir id:2 has correct name"); store.pushRetrieve(null, null, newDataHash, storeKeys[0]); store.flush(); SC.RunLoop.end() equals(parent.get('name'), 'Dir 1 Changed', 'Dir id:1 name was changed'); equals(nr.get('name'), 'Dir 2 Changed', "Dir id:2 name was changed");
});
test(“Store#pushRetrieve for parent updates the child records, even on different path”, function () {
SC.RunLoop.begin() var parent = store.materializeRecord(storeKeys[0]), nr = parent.get('contents').firstObject(), newDataHash = { type: 'Directory', name: 'Dir 1 Changed', guid: 1, contents: [ { type: 'Directory', name: 'Dir 3', guid: 5, contents: [ { type: 'File', guid: 6, name: 'File 6' }, { type: 'File', guid: 7, name: 'File 7' } ] }, { type: 'Directory', name: 'Dir 2 Changed', guid: 2, contents: [ { type: 'File', guid: 3, name: 'File 1' }, { type: 'File', guid: 4, name: 'File 2' } ] } ] }; parent = store.materializeRecord(storeKeys[0]); nr = store.find(NestedRecord.Directory,2); ok(nr, "Got nested record"); equals(nr.get('name'), 'Dir 2', "Dir id:2 has correct name"); store.pushRetrieve(null, null, newDataHash, storeKeys[0]); store.flush(); SC.RunLoop.end() equals(parent.get('name'), 'Dir 1 Changed', 'Dir id:1 name was changed'); equals(nr.get('name'), 'Dir 2 Changed', "Dir id:2 name has changed");
});
test(“Store#pushRetrieve for parent updates the child records, works on first object”, function () {
SC.RunLoop.begin() var parent = store.materializeRecord(storeKeys[0]), nr = parent.get('contents').firstObject(), newDataHash = { type: 'Directory', name: 'Dir 1 Changed', guid: 1, contents: [ { type: 'Directory', name: 'Dir 3', guid: 5, contents: [ { type: 'File', guid: 6, name: 'File 6' }, { type: 'File', guid: 7, name: 'File 7' } ] }, { type: 'Directory', name: 'Dir 2 Changed', guid: 2, contents: [ { type: 'File', guid: 3, name: 'File 1' }, { type: 'File', guid: 4, name: 'File 2' } ] } ] }; parent = store.materializeRecord(storeKeys[0]); nr = parent.get('contents').firstObject(); ok(nr, "Got nested record"); equals(nr.get('name'), 'Dir 2', "Dir id:2 has correct name"); store.pushRetrieve(null, null, newDataHash, storeKeys[0]); store.flush(); SC.RunLoop.end() equals(parent.get('name'), 'Dir 1 Changed', 'Dir id:1 name was changed'); equals(nr.get('name'), 'Dir 2 Changed', "First object name has changed");
});
test(“Store#pushRetrieve for parent updates the child records, on paths nested more than 2 levels”, function () {
SC.RunLoop.begin() var parent = store.materializeRecord(storeKeys[0]), nr = parent.get('contents').firstObject().get('contents').firstObject(), newDataHash = { type: 'Directory', name: 'Dir 1 Changed', guid: 1, contents: [ { type: 'Directory', name: 'Dir 3', guid: 5, contents: [ { type: 'File', guid: 6, name: 'File 6' }, { type: 'File', guid: 7, name: 'File 7' } ] }, { type: 'Directory', name: 'Dir 2 Changed', guid: 2, contents: [ { type: 'File', guid: 3, name: 'File 1 Changed' }, { type: 'File', guid: 4, name: 'File 2' } ] } ] }; ok(nr, "(deep walk) Got nested record"); equals(nr.get('name'), 'File 1', "(deep walk) File id:3 has correct name"); parent = store.materializeRecord(storeKeys[0]); nr = store.find(NestedRecord.File,3); ok(nr, "Got nested record"); equals(nr.get('name'), 'File 1', "File id:3 has correct name"); store.pushRetrieve(null, null, newDataHash, storeKeys[0]); store.flush(); SC.RunLoop.end() equals(parent.get('name'), 'Dir 1 Changed', 'Dir id:1 name was changed'); equals(nr.get('name'), 'File 1 Changed', "File id:3 name has changed");
});