blossom
Version:
Modern, Cross-Platform Application Framework
227 lines (168 loc) • 7.5 kB
JavaScript
// ==========================================================================
// Project: SproutCore - JavaScript Application Framework
// Copyright: ©2006-2011 Apple Inc. and contributors.
// License: Licensed under MIT license (see license.js)
// ==========================================================================
/*globals module ok equals same test MyApp */
// This file tests the initial state of the store when it is first created
// either independently or as a chained store.
// ..........................................................
// UTILITIES
//
var TestRecord = SC.Record.extend();
var TestRecord2 = SC.Record.extend();
function queryEquals(q, location, recordType, conditions, extra, desc) {
if (desc===undefined && typeof extra === 'string') {
desc = extra; extra = undefined ;
}
if (!desc) desc = '';
ok(!!q, desc + ': should have a query');
equals(q.get('isFrozen'), true, desc + ": should be frozen");
if (q) {
if (location) {
equals(q.get('location'), location, desc + ": should have location");
}
if (recordType && recordType.isEnumerable) {
same(q.get('recordTypes'), recordType, desc + ': should have recordTypes (plural)');
} else {
equals(q.get('recordType'), recordType, desc + ': should have recordType (singular)');
}
equals(q.get('conditions'), conditions, desc + ': should have conditions');
if (extra) {
for (var key in extra) {
if (!extra.hasOwnProperty(key)) continue;
equals(q.get(key), extra[key], desc + ': should have extra key ' + key);
}
}
}
}
// ..........................................................
// BASIC TESTS
//
// The local() and remote() builder methods are very similar. This will
// perform the same basic tests on both of them. If you add a builder for a
// new type of location, you can just call this function again with your new
// location
function performBasicTests(methodName, loc) {
suite("SC.Query.%@()".fmt(methodName), {
setup: function() {
window.TestRecord = TestRecord;
window.TestRecord2 = TestRecord2;
},
teardown: function() {
window.TestRecord = window.TestRecord2 = null; // cleanup
}
});
function invokeWith() {
return SC.Query[methodName].apply(SC.Query, arguments);
}
test("basic query with just record type", function() {
var q, q1, q2, q3, q4;
// local
q = invokeWith(TestRecord);
queryEquals(q, loc, TestRecord, null, 'first query');
q1 = invokeWith(TestRecord);
equals(q1, q, 'second call should return cached value');
// using string for record type name should work
q2 = invokeWith("TestRecord");
equals(q2, q, 'queryFor with string should return cached value');
// using an array of a single item should be treated as a single item
q3 = invokeWith([TestRecord]);
equals(q3, q, 'queryFor([TestRecord]) should return cached value');
// ditto w/ strings
q4 = invokeWith(['TestRecord']);
equals(q4, q, 'queryFor(["TestRecord"]) with string should return cached value');
});
test("query with multiple recordtypes", function() {
var types = [TestRecord, TestRecord2],
q1, q2, a3, q4, q5, set;
// create first query
q1 = invokeWith(types);
queryEquals(q1, loc, types, null, 'first query');
// try again - should get cache
q2 = invokeWith(types);
equals(q2, q1, 'second queryFor call should return cached value');
// try again - different order
q3 = invokeWith([TestRecord2, TestRecord]);
equals(q3, q1, 'queryFor with different order of record types should return same cached value');
// try again - using a set
set = SC.Set.create().add(TestRecord).add(TestRecord2);
q4 = invokeWith(set);
equals(q4, q1, 'should return cached query even if using an enumerable for types');
// try again using strings
q5 = invokeWith('TestRecord TestRecord2'.w());
equals(q5, q1, 'should return cached query even if string record names are used');
});
test("query with record type and conditions", function() {
var q1, q2, q3, q4, q5, q6, q7;
q1 = invokeWith(TestRecord, 'foobar');
queryEquals(q1, loc, TestRecord, 'foobar', 'first query');
q2 = invokeWith(TestRecord, 'foobar');
equals(q2, q1, 'second call to queryFor(TestRecord, foobar) should return cached instance');
q3 = invokeWith(TestRecord2, 'foobar');
queryEquals(q3, loc, TestRecord2, 'foobar', 'query(TestRecord2, foobar)');
ok(q3 !== q1, 'different recordType same conditions should return new query');
q4 = invokeWith(TestRecord, 'baz');
queryEquals(q4, loc, TestRecord, 'baz', 'query(TestRecord2, baz)');
ok(q4 !== q1, 'different conditions should return new query');
q5 = invokeWith(TestRecord, 'baz');
equals(q5, q4, 'second call for different conditions should return cache');
});
test("query with record types and conditions hash", function() {
var q = invokeWith([TestRecord, TestRecord2], {});
queryEquals(q, loc, [TestRecord, TestRecord2], null, 'first query');
});
test("query with no record type and with conditions", function() {
var q1, q2;
q1 = invokeWith(null, 'foobar');
queryEquals(q1, loc, SC.Record, 'foobar', 'first query');
q2 = invokeWith(null, 'foobar');
equals(q2, q1, 'should return cached value');
});
test("query with recordtype, conditions, and parameters hash", function() {
var opts = { opt1: 'bar', opt2: 'baz' },
q1, q2;
q1 = invokeWith(TestRecord, 'foo', opts);
queryEquals(q1, loc, TestRecord, 'foo', { parameters: opts }, 'first query');
q2 = invokeWith(TestRecord, 'foo', opts);
ok(q1 !== q2, 'second call to queryFor with opts cannot be cached');
queryEquals(q1, loc, TestRecord, 'foo', { parameters: opts }, 'second query');
});
test("query with recordtype, conditions, and parameters array", function() {
var opts = ['foo', 'bar'],
q1, q2;
q1 = invokeWith(TestRecord, 'foo', opts);
queryEquals(q1, loc, TestRecord, 'foo', { parameters: opts }, 'first query should include parameters prop');
q2 = invokeWith(TestRecord, 'foo', opts);
ok(q1 !== q2, 'second call to queryFor with opts cannot be cached');
queryEquals(q1, loc, TestRecord, 'foo', { parameters: opts }, 'second query');
});
test("passing query object", function() {
var local = SC.Query.local(TestRecord),
remote = SC.Query.remote(TestRecord),
q;
q = invokeWith(local);
if (loc === SC.Query.LOCAL) {
equals(q, local, 'invoking with local query should return same query');
} else {
ok(q !== local, 'invoke with local query should return new instance');
}
equals(q.get('location'), loc, 'query should have expected location');
q = invokeWith(remote);
if (loc === SC.Query.REMOTE) {
equals(q, remote, 'invoking with remote query should return same query');
} else {
ok(q !== remote, 'invoke with remote query should return new instance');
}
equals(q.get('location'), loc, 'query should have expected location');
});
test("no options (matches everything)", function() {
var q1, q2;
q1 = invokeWith();
queryEquals(q1, loc, SC.Record, null, 'first query - matches everything');
q2 = invokeWith();
equals(q2, q1, 'should return same cached query');
});
}
performBasicTests('local', SC.Query.LOCAL);
performBasicTests('remote', SC.Query.REMOTE);