kojac 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +7 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +158 -0
- data/MIT-LICENSE +20 -0
- data/README.md +69 -0
- data/Rakefile +27 -0
- data/app/assets/javascripts/can_extensions.js +45 -0
- data/app/assets/javascripts/kojac.js +1230 -0
- data/app/assets/javascripts/kojac_canjs.js +191 -0
- data/app/assets/javascripts/kojac_ember.js +463 -0
- data/app/controllers/kojac_controller.rb +70 -0
- data/app/serializers/default_kojac_serializer.rb +10 -0
- data/diagram.odg +0 -0
- data/kojac.gemspec +36 -0
- data/lib/kojac/app_serialize.rb +29 -0
- data/lib/kojac/kojac_rails.rb +432 -0
- data/lib/kojac/ring_strong_parameters.rb +195 -0
- data/lib/kojac/version.rb +3 -0
- data/lib/kojac.rb +8 -0
- data/lib/tasks/kojac_tasks.rake +4 -0
- data/notes.txt +48 -0
- data/spec/.DS_Store +0 -0
- data/spec/can_cache_spec.js +87 -0
- data/spec/can_factory_spec.js +144 -0
- data/spec/can_model_spec.js +127 -0
- data/spec/demo/README.rdoc +261 -0
- data/spec/demo/Rakefile +7 -0
- data/spec/demo/app/assets/javascripts/application.js +15 -0
- data/spec/demo/app/assets/stylesheets/application.css +13 -0
- data/spec/demo/app/controllers/application_controller.rb +3 -0
- data/spec/demo/app/helpers/application_helper.rb +2 -0
- data/spec/demo/app/mailers/.gitkeep +0 -0
- data/spec/demo/app/models/.gitkeep +0 -0
- data/spec/demo/app/views/layouts/application.html.erb +14 -0
- data/spec/demo/config/application.rb +65 -0
- data/spec/demo/config/boot.rb +10 -0
- data/spec/demo/config/database.yml +25 -0
- data/spec/demo/config/environment.rb +5 -0
- data/spec/demo/config/environments/development.rb +37 -0
- data/spec/demo/config/environments/production.rb +67 -0
- data/spec/demo/config/environments/test.rb +37 -0
- data/spec/demo/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/demo/config/initializers/inflections.rb +15 -0
- data/spec/demo/config/initializers/mime_types.rb +5 -0
- data/spec/demo/config/initializers/secret_token.rb +7 -0
- data/spec/demo/config/initializers/session_store.rb +8 -0
- data/spec/demo/config/initializers/wrap_parameters.rb +14 -0
- data/spec/demo/config/locales/en.yml +5 -0
- data/spec/demo/config/routes.rb +58 -0
- data/spec/demo/config.ru +4 -0
- data/spec/demo/lib/assets/.gitkeep +0 -0
- data/spec/demo/log/.gitkeep +0 -0
- data/spec/demo/public/404.html +26 -0
- data/spec/demo/public/422.html +26 -0
- data/spec/demo/public/500.html +25 -0
- data/spec/demo/public/favicon.ico +0 -0
- data/spec/demo/script/rails +6 -0
- data/spec/ember_factory_spec.js +157 -0
- data/spec/ember_model_spec.js +179 -0
- data/spec/external/.DS_Store +0 -0
- data/spec/external/ember/.DS_Store +0 -0
- data/spec/external/ember/ember-1.0.0-rc.6.js +30970 -0
- data/spec/external/ember/handlebars-1.0.0-rc.4.js +2239 -0
- data/spec/external/jasmine/MIT.LICENSE +20 -0
- data/spec/external/jasmine/jasmine-html.js +616 -0
- data/spec/external/jasmine/jasmine.css +81 -0
- data/spec/external/jasmine/jasmine.js +2529 -0
- data/spec/external/jasmine.async.js +51 -0
- data/spec/external/jquery/jquery-1.7.2.js +9404 -0
- data/spec/external/jquery/jquery-1.7.2.min.js +4 -0
- data/spec/external/jquery/jquery-1.9.1.js +9597 -0
- data/spec/external/json2.js +480 -0
- data/spec/external/steal/steal-121115.js +2747 -0
- data/spec/external/steal/steal-3.2.3.js +2098 -0
- data/spec/external/steal/steal-3.2.3.min.js +27 -0
- data/spec/external/steal/steal.js +2466 -0
- data/spec/external/steal/steal.min.js +32 -0
- data/spec/external/steal/stealconfig.js +19 -0
- data/spec/external/underscore.js +1223 -0
- data/spec/external/underscore_plus.js +261 -0
- data/spec/external.zip +0 -0
- data/spec/handler_stack_spec.js +143 -0
- data/spec/helpers/SpecHelper.js +10 -0
- data/spec/kojac_caching_spec.js +105 -0
- data/spec/kojac_mock_spec.js +230 -0
- data/spec/kojac_model_spec.js +126 -0
- data/spec/kojac_object_spec.js +171 -0
- data/spec/kojac_operations_spec.js +41 -0
- data/spec/mockjson/order_item.js +37 -0
- data/spec/mockjson/order_item__49.js +15 -0
- data/spec/mockjson/order_item__50.js +15 -0
- data/spec/mockjson/order_item__51.js +15 -0
- data/spec/mockjson/product.js +82 -0
- data/spec/mockjson/product__3.js +22 -0
- data/spec/model_ring_spec.rb +52 -0
- data/spec/operation_include_spec.js +77 -0
- data/spec/run.html +81 -0
- data/spec/spec.js +2 -0
- data/spec/support/jasmine.yml +86 -0
- metadata +380 -0
@@ -0,0 +1,261 @@
|
|
1
|
+
// underscore_plus.js
|
2
|
+
// (c) 2012 Gary McGhee, Buzzware Solutions
|
3
|
+
// https://github.com/buzzware/underscore_plus
|
4
|
+
// Underscore may be freely distributed under the MIT license.
|
5
|
+
|
6
|
+
(function() {
|
7
|
+
|
8
|
+
//BEGIN copied from underscore
|
9
|
+
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
10
|
+
// Create quick reference variables for speed access to core prototypes.
|
11
|
+
var slice = ArrayProto.slice;
|
12
|
+
//END copied from underscore
|
13
|
+
|
14
|
+
_.stringify = function(aObject) {
|
15
|
+
if (_.isString(aObject))
|
16
|
+
return aObject;
|
17
|
+
if (aObject===null || aObject===undefined)
|
18
|
+
return '';
|
19
|
+
if (aObject.toString)
|
20
|
+
return aObject.toString();
|
21
|
+
return '';
|
22
|
+
};
|
23
|
+
|
24
|
+
//var MAX_DUMP_DEPTH = 10;
|
25
|
+
//
|
26
|
+
// function dumpObj(obj, name, indent, depth) {
|
27
|
+
// if (depth > MAX_DUMP_DEPTH) {
|
28
|
+
// return indent + name + ": <Maximum Depth Reached>\n";
|
29
|
+
// }
|
30
|
+
// if (typeof obj == "object") {
|
31
|
+
// var child = null;
|
32
|
+
// var output = indent + name + "\n";
|
33
|
+
// indent += "\t";
|
34
|
+
// for (var item in obj)
|
35
|
+
// {
|
36
|
+
// try {
|
37
|
+
// child = obj[item];
|
38
|
+
// } catch (e) {
|
39
|
+
// child = "<Unable to Evaluate>";
|
40
|
+
// }
|
41
|
+
// if (typeof child == "object") {
|
42
|
+
// output += dumpObj(child, item, indent, depth + 1);
|
43
|
+
// } else {
|
44
|
+
// output += indent + item + ": " + child + "\n";
|
45
|
+
// }
|
46
|
+
// }
|
47
|
+
// return output;
|
48
|
+
// } else {
|
49
|
+
// return obj;
|
50
|
+
// }
|
51
|
+
// }
|
52
|
+
|
53
|
+
_.concat = function(aArray,aAnotherArray) {
|
54
|
+
var result = [];
|
55
|
+
result.push.apply(result, aArray);
|
56
|
+
result.push.apply(result, aAnotherArray);
|
57
|
+
return result;
|
58
|
+
};
|
59
|
+
|
60
|
+
_.nameValueString = function(aObject) {
|
61
|
+
return _.map(_.keys(aObject),function(k) { return k+'="'+_.stringify(aObject[k])+'"'}).join(' ');
|
62
|
+
};
|
63
|
+
|
64
|
+
_.classEnsure = function(aOrig,aNew) {
|
65
|
+
if (!aOrig)
|
66
|
+
return aNew;
|
67
|
+
if (!aNew)
|
68
|
+
return aOrig;
|
69
|
+
return _.union(aOrig.split(' '),aNew.split(' '));
|
70
|
+
};
|
71
|
+
|
72
|
+
_.getPath = function(aObject,aPath,aDefault) {
|
73
|
+
if ((typeof aObject)=='string') { // allow aObject to be left out and assume this
|
74
|
+
if (arguments.length==1) {
|
75
|
+
aPath = aObject;
|
76
|
+
aObject = window;
|
77
|
+
} else if (arguments.length==2) {
|
78
|
+
aDefault = aPath;
|
79
|
+
aPath = aObject;
|
80
|
+
aObject = window;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
var nodes = aPath.split('.');
|
84
|
+
var curr = aObject;
|
85
|
+
for (var i=0;i<nodes.length;i++) {
|
86
|
+
var name = nodes[i];
|
87
|
+
if ((curr===undefined)||(curr===null))
|
88
|
+
return aDefault;
|
89
|
+
if ((name in curr) || curr[name]) {
|
90
|
+
var val = curr[name];
|
91
|
+
if ((typeof val)=='function')
|
92
|
+
curr = val.call(curr);
|
93
|
+
else
|
94
|
+
curr = val;
|
95
|
+
} else {
|
96
|
+
return aDefault; // name doesn't exist
|
97
|
+
}
|
98
|
+
}
|
99
|
+
return curr;
|
100
|
+
}
|
101
|
+
|
102
|
+
_.moveKeys = function(aDest,aSource,aKeys) {
|
103
|
+
if (!aSource)
|
104
|
+
return aDest;
|
105
|
+
if (!aKeys)
|
106
|
+
aKeys = _.keys(aSource);
|
107
|
+
for (var i=0;i<aKeys.length;i++) {
|
108
|
+
var k = aKeys[i];
|
109
|
+
if (!(k in aSource))
|
110
|
+
continue;
|
111
|
+
aDest[k] = aSource[k];
|
112
|
+
delete aSource[k];
|
113
|
+
}
|
114
|
+
return aDest;
|
115
|
+
};
|
116
|
+
|
117
|
+
_.removeKey = function(aObject,aKey) {
|
118
|
+
var result = aObject[aKey];
|
119
|
+
delete aObject[aKey];
|
120
|
+
return result;
|
121
|
+
};
|
122
|
+
|
123
|
+
// // find all dynamic objects in an array that have matching values for the contents of aAndCriteria
|
124
|
+
// public static function ObjectArrayFind(aArray:Array, aAndCriteria:Object):Array {
|
125
|
+
// return aArray.filter(
|
126
|
+
// function(item:*, index:int, array:Array):Boolean {
|
127
|
+
// // for all items in aAndCriteria, aItem has matching values
|
128
|
+
// for (var i:String in aAndCriteria) {
|
129
|
+
// if (aAndCriteria[i] != item[i])
|
130
|
+
// return false;
|
131
|
+
// }
|
132
|
+
// return true;
|
133
|
+
// }
|
134
|
+
// );
|
135
|
+
// }
|
136
|
+
//
|
137
|
+
// // like ObjectArrayFind except only returns one object. Could be optimised to quit searching when one is found
|
138
|
+
// // adds listener and removes on first occurrence
|
139
|
+
// public static function ObjectArrayFindOne(aArray:Array, aAndCriteria:Object):Object {
|
140
|
+
// var results:Array = ObjectArrayFind(aArray, aAndCriteria);
|
141
|
+
// return results[0];
|
142
|
+
// }
|
143
|
+
//
|
144
|
+
// public static function ObjectArrayLookup(aArray:Array, aAndCriteria:Object, aProperty:String):Object {
|
145
|
+
// var results:Array = ObjectArrayFind(aArray, aAndCriteria);
|
146
|
+
// var item:Object = results[0];
|
147
|
+
// if (!item)
|
148
|
+
// return null;
|
149
|
+
// return item[aProperty];
|
150
|
+
// }
|
151
|
+
|
152
|
+
_.hasMatchingProperties = function(aObject,aCriteria) {
|
153
|
+
for (var p in aCriteria) {
|
154
|
+
if (!(p in aObject) || (aObject[p]!==aCriteria[p]))
|
155
|
+
return false;
|
156
|
+
}
|
157
|
+
return true;
|
158
|
+
};
|
159
|
+
|
160
|
+
// find one item matching object properties
|
161
|
+
_.findByCriteria = function(aArray,aCriteria) {
|
162
|
+
return _.find(aArray,function(obj){
|
163
|
+
return _.hasMatchingProperties(obj,aCriteria);
|
164
|
+
});
|
165
|
+
};
|
166
|
+
|
167
|
+
// find one item matching object properties
|
168
|
+
_.filterByCriteria = function(aArray,aCriteria) {
|
169
|
+
return _.filter(aArray,function(obj){
|
170
|
+
return _.hasMatchingProperties(obj,aCriteria);
|
171
|
+
});
|
172
|
+
};
|
173
|
+
|
174
|
+
_.isObjectStrict = function(aSomething) {
|
175
|
+
return Object.prototype.toString.call(aSomething)==='[object Object]';
|
176
|
+
}
|
177
|
+
|
178
|
+
// create an object using key,value arguments eg. createObject('a',2) returns {a: 2}
|
179
|
+
_.createObject = function() {
|
180
|
+
var result = {};
|
181
|
+
result[arguments[0]] = arguments[1];
|
182
|
+
return result;
|
183
|
+
}
|
184
|
+
|
185
|
+
_.endsWith = function(aString, aSuffix) {
|
186
|
+
var i = aString.lastIndexOf(aSuffix);
|
187
|
+
return (i>=0 && i===aString.length-aSuffix.length);
|
188
|
+
}
|
189
|
+
|
190
|
+
_.beginsWith = function(aString, aPrefix) {
|
191
|
+
var i = aString.indexOf(aPrefix);
|
192
|
+
return (i==0);
|
193
|
+
}
|
194
|
+
|
195
|
+
_.chop = function(aString, aSuffix) {
|
196
|
+
var i = aString.lastIndexOf(aSuffix);
|
197
|
+
return (i===aString.length-aSuffix.length) ? aString.substring(0,i) : aString;
|
198
|
+
}
|
199
|
+
|
200
|
+
_.bite = function(aString, aPrefix) {
|
201
|
+
var i = aString.indexOf(aPrefix);
|
202
|
+
return (i===0) ? aString.substring(aPrefix.length) : aString;
|
203
|
+
}
|
204
|
+
|
205
|
+
_.typeOf = function(aSomething) {
|
206
|
+
if (aSomething===undefined)
|
207
|
+
return 'undefined';
|
208
|
+
if (aSomething===null)
|
209
|
+
return 'null';
|
210
|
+
|
211
|
+
var result = Object.prototype.toString.call(aSomething);
|
212
|
+
result = _.bite(result,'[object ');
|
213
|
+
result = _.chop(result,']');
|
214
|
+
return result.toLowerCase();
|
215
|
+
}
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Clone properties that are objects or arrays, otherwise if aSource and aDestination are different, properties will be copied
|
219
|
+
* @param aDestination
|
220
|
+
* @param aSource (optional, defaults to aSource)
|
221
|
+
* @return aDestination
|
222
|
+
*/
|
223
|
+
_.cloneComplexValues = function (aDestination, aSource) {
|
224
|
+
if (!aSource)
|
225
|
+
aSource = aDestination;
|
226
|
+
for (var p in aSource) {
|
227
|
+
var t = _.typeOf(aSource[p]);
|
228
|
+
if (t==='array' || t==='object')
|
229
|
+
aDestination[p] = _.clone(aSource[p]);
|
230
|
+
else if (aDestination!==aSource)
|
231
|
+
aDestination[p] = aSource[p];
|
232
|
+
}
|
233
|
+
return aDestination;
|
234
|
+
}
|
235
|
+
|
236
|
+
// http://justtalkaboutweb.com/2008/01/06/javascript-object-extension/
|
237
|
+
|
238
|
+
_.originalClone = _.originalClone || _.clone;
|
239
|
+
// Create a copy (shallow or deep) of an object from https://github.com/cederberg/underscore/commits/feature-clone
|
240
|
+
_.clone = function(obj, deep) {
|
241
|
+
if (!deep)
|
242
|
+
return _.originalClone(obj);
|
243
|
+
if (!_.isObject(obj) || _.isFunction(obj)) return obj;
|
244
|
+
if (_.isDate(obj)) return new Date(obj.getTime());
|
245
|
+
if (_.isRegExp(obj)) return new RegExp(obj.source, obj.toString().replace(/.*\//, ""));
|
246
|
+
var isArr = (_.isArray(obj) || _.isArguments(obj));
|
247
|
+
if (deep) {
|
248
|
+
var func = function (memo, value, key) {
|
249
|
+
if (isArr)
|
250
|
+
memo.push(_.clone(value, true));
|
251
|
+
else
|
252
|
+
memo[key] = _.clone(value, true);
|
253
|
+
return memo;
|
254
|
+
};
|
255
|
+
return _.reduce(obj, func, isArr ? [] : {});
|
256
|
+
} else {
|
257
|
+
return isArr ? slice.call(obj) : _.extend({}, obj);
|
258
|
+
}
|
259
|
+
};
|
260
|
+
|
261
|
+
}).call(this);
|
data/spec/external.zip
ADDED
Binary file
|
@@ -0,0 +1,143 @@
|
|
1
|
+
describe("HandlerStack", function() {
|
2
|
+
|
3
|
+
it("simple add", function() {
|
4
|
+
var hs = new HandlerStack();
|
5
|
+
var context = {text: 'A'};
|
6
|
+
|
7
|
+
hs.add(function(aContext) {
|
8
|
+
context.text += 'B';
|
9
|
+
});
|
10
|
+
hs.add(function(aContext) {
|
11
|
+
context.text += 'C';
|
12
|
+
});
|
13
|
+
runs(function() {
|
14
|
+
hs.run(context);
|
15
|
+
});
|
16
|
+
waitsFor(function() { return context.isResolved(); }, "request done", 3000);
|
17
|
+
runs(function() {
|
18
|
+
expect(context.text).toBe('ABC');
|
19
|
+
});
|
20
|
+
});
|
21
|
+
|
22
|
+
it("add, push, then and done", function() {
|
23
|
+
var hs = new HandlerStack();
|
24
|
+
var context = {text: 'A'};
|
25
|
+
|
26
|
+
hs.add(function(aContext) {
|
27
|
+
context.text += 'B';
|
28
|
+
});
|
29
|
+
hs.add(function(aContext) {
|
30
|
+
context.text += 'C';
|
31
|
+
});
|
32
|
+
hs.push(function(aContext) {
|
33
|
+
context.text += 'X';
|
34
|
+
});
|
35
|
+
runs(function() {
|
36
|
+
hs.run(context);
|
37
|
+
context.then(function(aContext){
|
38
|
+
context.text += 'W';
|
39
|
+
});
|
40
|
+
context.done(function(aContext){
|
41
|
+
context.text += 'Z';
|
42
|
+
});
|
43
|
+
});
|
44
|
+
waitsFor(function() { return context.isResolved(); }, "request done", 3000);
|
45
|
+
runs(function() {
|
46
|
+
expect(context.text).toBe('AXBCWZ');
|
47
|
+
});
|
48
|
+
});
|
49
|
+
|
50
|
+
it("error handling - stop processing handlers and set context.error and context.isRejected and call fail handler", function() {
|
51
|
+
var hs = new HandlerStack();
|
52
|
+
var context = {text: 'A'};
|
53
|
+
|
54
|
+
hs.add(function(aContext) {
|
55
|
+
context.text += 'B';
|
56
|
+
});
|
57
|
+
hs.add(function(aContext) {
|
58
|
+
throw new Error();
|
59
|
+
});
|
60
|
+
hs.add(function(aContext) {
|
61
|
+
context.text += 'X';
|
62
|
+
});
|
63
|
+
hs.run(context);
|
64
|
+
context.then(function(aContext){
|
65
|
+
context.text += 'W';
|
66
|
+
});
|
67
|
+
context.done(function(aContext){
|
68
|
+
context.text += 'Z';
|
69
|
+
});
|
70
|
+
context.fail(function(aContext){
|
71
|
+
context.text += 'F';
|
72
|
+
});
|
73
|
+
waitsFor(function() {
|
74
|
+
return context.isRejected();
|
75
|
+
}, "rejected", 3000);
|
76
|
+
runs(function() {
|
77
|
+
expect(context.text).toBe('ABF');
|
78
|
+
expect(context.error).toBeDefined();
|
79
|
+
expect(typeof(context.error)).toBe('object');
|
80
|
+
});
|
81
|
+
});
|
82
|
+
|
83
|
+
it("reset and recall", function() {
|
84
|
+
var hs = new HandlerStack();
|
85
|
+
var context = {text: 'A'};
|
86
|
+
|
87
|
+
hs.add(function(aContext) {
|
88
|
+
context.text += 'B';
|
89
|
+
});
|
90
|
+
runs(function() {
|
91
|
+
hs.run(context);
|
92
|
+
context.then(function(aContext){
|
93
|
+
context.text += 'W';
|
94
|
+
});
|
95
|
+
context.done(function(aContext){
|
96
|
+
context.text += 'Z';
|
97
|
+
});
|
98
|
+
});
|
99
|
+
waitsFor(function() { return context.isResolved(); }, "resolved", 3000);
|
100
|
+
runs(function() {
|
101
|
+
expect(context.text).toBe('ABWZ');
|
102
|
+
expect(context.error).toBeUndefined();
|
103
|
+
hs.reset();
|
104
|
+
});
|
105
|
+
|
106
|
+
runs(function() {
|
107
|
+
context = {text: 'G'};
|
108
|
+
hs.run(context);
|
109
|
+
context.then(function(aContext){
|
110
|
+
context.text += 'W';
|
111
|
+
});
|
112
|
+
context.done(function(aContext){
|
113
|
+
context.text += 'Z';
|
114
|
+
});
|
115
|
+
});
|
116
|
+
waitsFor(function() { return context.isResolved(); }, "resolved", 3000);
|
117
|
+
runs(function() {
|
118
|
+
expect(context.text).toBe('GBWZ');
|
119
|
+
expect(context.error).toBeUndefined();
|
120
|
+
});
|
121
|
+
|
122
|
+
});
|
123
|
+
|
124
|
+
it("handler on an object", function() {
|
125
|
+
var hs = new HandlerStack();
|
126
|
+
var context = {text: 'A'};
|
127
|
+
var TestClass = function() {
|
128
|
+
this.text = 'B';
|
129
|
+
this.go = function(aContext) {
|
130
|
+
aContext.text += this.text;
|
131
|
+
};
|
132
|
+
};
|
133
|
+
var testClass = new TestClass();
|
134
|
+
hs.add(testClass.go,null,testClass); // note: using ability to specify this as third parameter
|
135
|
+
runs(function() {
|
136
|
+
hs.run(context);
|
137
|
+
});
|
138
|
+
waitsFor(function() { return context.isResolved(); }, "resolved", 3000);
|
139
|
+
runs(function() {
|
140
|
+
expect(context.text).toBe('AB');
|
141
|
+
});
|
142
|
+
});
|
143
|
+
});
|
@@ -0,0 +1,105 @@
|
|
1
|
+
describe("Kojac Caching", function() {
|
2
|
+
|
3
|
+
beforeEach(function () {
|
4
|
+
this.cache = new Kojac.Object();
|
5
|
+
this.kojac = new Kojac.Core({
|
6
|
+
cache: this.cache,
|
7
|
+
remoteProvider: new Kojac.RemoteProvider({useMockFileValues: true,mockFilePath: 'mockjson/'})
|
8
|
+
});
|
9
|
+
});
|
10
|
+
|
11
|
+
it("should return extra keys from a cacheRead that were returned from the server",function(){
|
12
|
+
var products_records = { // this is the normal data to return when requesting 'products'
|
13
|
+
products: [1,2,3],
|
14
|
+
products__1: {
|
15
|
+
id: 1,
|
16
|
+
name: "Product One"
|
17
|
+
},
|
18
|
+
products__2: {
|
19
|
+
id: 2,
|
20
|
+
name: "Product Two"
|
21
|
+
},
|
22
|
+
products__3: {
|
23
|
+
id: 3,
|
24
|
+
name: "Product Three"
|
25
|
+
}
|
26
|
+
};
|
27
|
+
var products_server_response = _.clone(products_records); // the contents of this var will be returned by the mock server
|
28
|
+
this.kojac.remoteProvider.mockReadOperationHandler = function(aOp) { // this function acts as the server
|
29
|
+
switch (aOp.key) {
|
30
|
+
case 'products':
|
31
|
+
aOp.result_key = 'products';
|
32
|
+
aOp.results = _.extend(aOp.results,products_server_response);
|
33
|
+
break;
|
34
|
+
}
|
35
|
+
};
|
36
|
+
var readReq = this.kojac.readRequest('products');
|
37
|
+
waitsFor(function() { return readReq.isResolved(); }, "request done", 3000);
|
38
|
+
runs(function() {
|
39
|
+
expect(readReq.results).toEqual(products_records); // should equal normal response
|
40
|
+
products_server_response = {}; // kill server response - non-cache reads should return empty now
|
41
|
+
readReq = this.kojac.readRequest('products',{cacheResults: false}); // read from server to check this, and don't store result in cache
|
42
|
+
});
|
43
|
+
waitsFor(function() { return readReq.isResolved(); }, "request done", 3000);
|
44
|
+
runs(function() {
|
45
|
+
expect(readReq.results).toEqual({}); // indeed, server now returns empty, but lets try cache
|
46
|
+
readReq = this.kojac.cacheReadRequest('products'); // read from cache
|
47
|
+
});
|
48
|
+
waitsFor(function() { return readReq.isResolved(); }, "request done", 3000);
|
49
|
+
runs(function() {
|
50
|
+
expect(readReq.results).toEqual(products_records); // should return original records - must be coming from cache not server
|
51
|
+
});
|
52
|
+
});
|
53
|
+
|
54
|
+
it("should return extra keys from a cacheRead that were returned from the server, using result_key",function(){
|
55
|
+
var products_records = { // this is the normal data to return when requesting 'products'
|
56
|
+
products: [1,2,3],
|
57
|
+
products__1: {
|
58
|
+
id: 1,
|
59
|
+
name: "Product One"
|
60
|
+
},
|
61
|
+
products__2: {
|
62
|
+
id: 2,
|
63
|
+
name: "Product Two"
|
64
|
+
},
|
65
|
+
products__3: {
|
66
|
+
id: 3,
|
67
|
+
name: "Product Three"
|
68
|
+
}
|
69
|
+
};
|
70
|
+
var products_server_response = _.clone(products_records); // the contents of this var will be returned by the mock server
|
71
|
+
this.kojac.remoteProvider.mockReadOperationHandler = function(aOp) { // this function acts as the server
|
72
|
+
switch (aOp.key) {
|
73
|
+
case 'products':
|
74
|
+
if (aOp.result_key!==aOp.key)
|
75
|
+
products_server_response[aOp.result_key] = _.removeKey(products_server_response,aOp.key);
|
76
|
+
aOp.results = _.extend(aOp.results,products_server_response);
|
77
|
+
break;
|
78
|
+
}
|
79
|
+
};
|
80
|
+
expect(_.keys(this.kojac.cache)).toEqual([]);
|
81
|
+
var readReq = this.kojac.readRequest('products',{result_key: 'products_latest'});
|
82
|
+
waitsFor(function() { return readReq.isResolved(); }, "request done", 3000);
|
83
|
+
runs(function() {
|
84
|
+
var expected = _.clone(products_records);
|
85
|
+
expected.products_latest = _.removeKey(expected,'products');
|
86
|
+
expect(readReq.results).toEqual(expected); // should equal normal response
|
87
|
+
expect(_.keys(this.kojac.cache).sort()).toEqual(['products__1','products__2','products__3','products_latest']);
|
88
|
+
products_server_response = {}; // kill server response - non-cache reads should return empty now
|
89
|
+
readReq = this.kojac.readRequest('products',{cacheResults: false, result_key: 'products_latest'}); // read from server to check this, and don't store result in cache
|
90
|
+
});
|
91
|
+
waitsFor(function() { return readReq.isResolved(); }, "request done", 3000);
|
92
|
+
runs(function() {
|
93
|
+
expect(readReq.results).toEqual({}); // indeed, server now returns empty, but lets try cache
|
94
|
+
readReq = this.kojac.cacheReadRequest('products',{result_key: 'products_latest'}); // read from cache
|
95
|
+
});
|
96
|
+
waitsFor(function() { return readReq.isResolved(); }, "request done", 3000);
|
97
|
+
runs(function() {
|
98
|
+
var expected = _.clone(products_records);
|
99
|
+
expected.products_latest = _.removeKey(expected,'products');
|
100
|
+
expect(readReq.results).toEqual(expected); // should return original records - must be coming from cache not server
|
101
|
+
});
|
102
|
+
});
|
103
|
+
|
104
|
+
});
|
105
|
+
|