]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | describe("Ext.data.reader.Json", function() {\r |
2 | var reader, data1, data2, result1, result2, result3;\r | |
3 | \r | |
4 | beforeEach(function() {\r | |
5 | Ext.ClassManager.enableNamespaceParseCache = false;\r | |
6 | Ext.data.Model.schema.setNamespace('spec');\r | |
7 | Ext.define('spec.JsonReader', {\r | |
8 | extend: 'Ext.data.Model',\r | |
9 | fields: [\r | |
10 | {name: 'inter', type: 'int'}\r | |
11 | ]\r | |
12 | });\r | |
13 | \r | |
14 | reader = new Ext.data.JsonReader({\r | |
15 | rootProperty: 'data',\r | |
16 | totalProperty: 'totalProp',\r | |
17 | messageProperty: 'messageProp',\r | |
18 | successProperty: 'successProp',\r | |
19 | model: 'spec.JsonReader'\r | |
20 | });\r | |
21 | });\r | |
22 | \r | |
23 | afterEach(function(){\r | |
24 | if (reader) {\r | |
25 | reader.destroy();\r | |
26 | }\r | |
27 | \r | |
28 | reader = null;\r | |
29 | \r | |
30 | Ext.ClassManager.enableNamespaceParseCache = true;\r | |
31 | Ext.undefine('spec.JsonReader');\r | |
32 | Ext.data.Model.schema.clear(true);\r | |
33 | });\r | |
34 | \r | |
35 | describe("raw data", function() {\r | |
36 | var data, rec;\r | |
37 | \r | |
38 | beforeEach(function() {\r | |
39 | data = {\r | |
40 | inter: 1\r | |
41 | };\r | |
42 | });\r | |
43 | \r | |
44 | afterEach(function() {\r | |
45 | rec = null;\r | |
46 | });\r | |
47 | \r | |
48 | it("should not set raw data reference by default", function() {\r | |
49 | rec = reader.readRecords([data]).getRecords()[0];\r | |
50 | \r | |
51 | expect(rec.raw).not.toBeDefined();\r | |
52 | });\r | |
53 | \r | |
54 | it('should set raw data reference for a TreeStore record', function () {\r | |
55 | // Simulate TreeStore node\r | |
56 | spec.JsonReader.prototype.isNode = true;\r | |
57 | \r | |
58 | rec = reader.readRecords([data]).getRecords()[0];\r | |
59 | \r | |
60 | expect(rec.raw).toBe(data);\r | |
61 | });\r | |
62 | });\r | |
63 | \r | |
64 | describe("copyFrom", function() {\r | |
65 | var Model, copy;\r | |
66 | \r | |
67 | beforeEach(function() {\r | |
68 | Model = Ext.define(null, {\r | |
69 | extend: 'Ext.data.Model'\r | |
70 | });\r | |
71 | \r | |
72 | reader.destroy();\r | |
73 | reader = null;\r | |
74 | });\r | |
75 | \r | |
76 | afterEach(function() {\r | |
77 | copy.destroy();\r | |
78 | Model = copy = null;\r | |
79 | });\r | |
80 | \r | |
81 | it("should copy the model", function() {\r | |
82 | reader = new Ext.data.reader.Json({\r | |
83 | model: Model\r | |
84 | });\r | |
85 | copy = new Ext.data.reader.Json();\r | |
86 | copy.copyFrom(reader);\r | |
87 | expect(copy.getModel()).toBe(Model);\r | |
88 | });\r | |
89 | \r | |
90 | it("should copy the record", function() {\r | |
91 | reader = new Ext.data.reader.Json({\r | |
92 | model: Model,\r | |
93 | record: 'foo'\r | |
94 | });\r | |
95 | copy = new Ext.data.reader.Json();\r | |
96 | copy.copyFrom(reader);\r | |
97 | expect(copy.getRecord()).toBe('foo');\r | |
98 | \r | |
99 | var result = reader.read([{\r | |
100 | foo: {\r | |
101 | x: 1\r | |
102 | }\r | |
103 | }]);\r | |
104 | expect(result.getRecords()[0].get('x')).toBe(1);\r | |
105 | });\r | |
106 | \r | |
107 | it("should copy the totalProperty", function() {\r | |
108 | reader = new Ext.data.reader.Json({\r | |
109 | model: Model,\r | |
110 | totalProperty: 'aTotal'\r | |
111 | });\r | |
112 | copy = new Ext.data.reader.Json();\r | |
113 | copy.copyFrom(reader);\r | |
114 | expect(copy.getTotalProperty()).toBe('aTotal');\r | |
115 | \r | |
116 | var result = reader.read({\r | |
117 | aTotal: 1000\r | |
118 | });\r | |
119 | expect(result.getTotal()).toBe(1000);\r | |
120 | });\r | |
121 | \r | |
122 | it("should copy the successProperty", function() {\r | |
123 | reader = new Ext.data.reader.Json({\r | |
124 | model: Model,\r | |
125 | successProperty: 'aSuccess'\r | |
126 | });\r | |
127 | copy = new Ext.data.reader.Json();\r | |
128 | copy.copyFrom(reader);\r | |
129 | expect(copy.getSuccessProperty()).toBe('aSuccess');\r | |
130 | \r | |
131 | var result = reader.read({\r | |
132 | aSuccess: false\r | |
133 | });\r | |
134 | expect(result.getSuccess()).toBe(false);\r | |
135 | });\r | |
136 | \r | |
137 | it("should copy the messageProperty", function() {\r | |
138 | reader = new Ext.data.reader.Json({\r | |
139 | model: Model,\r | |
140 | messageProperty: 'aMessage'\r | |
141 | });\r | |
142 | copy = new Ext.data.reader.Json();\r | |
143 | copy.copyFrom(reader);\r | |
144 | expect(copy.getMessageProperty()).toBe('aMessage');\r | |
145 | \r | |
146 | var result = reader.read({\r | |
147 | aMessage: 'Some Message'\r | |
148 | });\r | |
149 | expect(result.getMessage()).toBe('Some Message');\r | |
150 | });\r | |
151 | \r | |
152 | it("should copy the rootProperty", function() {\r | |
153 | reader = new Ext.data.reader.Json({\r | |
154 | model: Model,\r | |
155 | rootProperty: 'aRoot'\r | |
156 | });\r | |
157 | copy = new Ext.data.reader.Json();\r | |
158 | copy.copyFrom(reader);\r | |
159 | expect(copy.getRootProperty()).toBe('aRoot');\r | |
160 | \r | |
161 | var result = reader.read({\r | |
162 | aRoot: [{}, {}, {}, {}]\r | |
163 | });\r | |
164 | expect(result.getCount()).toBe(4);\r | |
165 | });\r | |
166 | });\r | |
167 | \r | |
168 | describe("preserveRawData", function() {\r | |
169 | it("should not use the raw data object for the model if set to true", function() {\r | |
170 | reader.setPreserveRawData(true);\r | |
171 | var o = {\r | |
172 | inter: 1\r | |
173 | };\r | |
174 | \r | |
175 | var rec = reader.readRecords([o]).getRecords()[0];\r | |
176 | \r | |
177 | rec.set('inter', 2);\r | |
178 | expect(o.inter).toBe(1);\r | |
179 | });\r | |
180 | \r | |
181 | it("should be able to modify the raw data object for the model if set to false", function() {\r | |
182 | reader.setPreserveRawData(false);\r | |
183 | var o = {\r | |
184 | inter: 1\r | |
185 | };\r | |
186 | \r | |
187 | var rec = reader.readRecords([o]).getRecords()[0];\r | |
188 | \r | |
189 | rec.set('inter', 2);\r | |
190 | expect(o.inter).toBe(2);\r | |
191 | });\r | |
192 | });\r | |
193 | \r | |
194 | describe("extractors", function() {\r | |
195 | var createReader;\r | |
196 | \r | |
197 | beforeEach(function(){\r | |
198 | createReader = function(cfg){\r | |
199 | cfg = cfg || {};\r | |
200 | reader = new Ext.data.reader.Json(Ext.applyIf({\r | |
201 | model: 'spec.JsonReader'\r | |
202 | }, cfg));\r | |
203 | reader.buildExtractors(true);\r | |
204 | };\r | |
205 | });\r | |
206 | \r | |
207 | afterEach(function(){\r | |
208 | createReader = null;\r | |
209 | });\r | |
210 | \r | |
211 | it("should run function extractors in the reader scope", function(){\r | |
212 | var actual;\r | |
213 | \r | |
214 | createReader({\r | |
215 | successProperty: function(){\r | |
216 | actual = this;\r | |
217 | return true;\r | |
218 | }\r | |
219 | });\r | |
220 | reader.getSuccess({\r | |
221 | success: true\r | |
222 | });\r | |
223 | expect(actual).toBe(reader);\r | |
224 | });\r | |
225 | \r | |
226 | /**\r | |
227 | * While testing all of these individually is a bit redundant, it's for completeness\r | |
228 | * to ensure that all of them are run through the proper extractors.\r | |
229 | */\r | |
230 | describe("getTotal", function(){\r | |
231 | it("should default to total", function(){\r | |
232 | createReader();\r | |
233 | expect(reader.getTotal({\r | |
234 | total: 5\r | |
235 | })).toBe(5);\r | |
236 | });\r | |
237 | \r | |
238 | it("should have no getTotal method if the totalProperty isn't specified", function(){\r | |
239 | createReader({\r | |
240 | totalProperty: ''\r | |
241 | });\r | |
242 | expect(reader.getTotal).toBeUndefined();\r | |
243 | });\r | |
244 | \r | |
245 | it("should read the specified property name", function(){\r | |
246 | createReader({\r | |
247 | totalProperty: 'foo'\r | |
248 | });\r | |
249 | expect(reader.getTotal({\r | |
250 | foo: 10\r | |
251 | })).toBe(10);\r | |
252 | });\r | |
253 | \r | |
254 | it("should accept a function configuration", function(){\r | |
255 | createReader({\r | |
256 | totalProperty: function(data){\r | |
257 | return data.big.chain.total;\r | |
258 | }\r | |
259 | });\r | |
260 | expect(reader.getTotal({\r | |
261 | big: {\r | |
262 | chain: {\r | |
263 | total: 65\r | |
264 | }\r | |
265 | }\r | |
266 | })).toBe(65);\r | |
267 | });\r | |
268 | \r | |
269 | describe("JSON", function(){\r | |
270 | it("should read dot notation", function(){\r | |
271 | createReader({\r | |
272 | totalProperty: 'big.chain.total'\r | |
273 | });\r | |
274 | expect(reader.getTotal({\r | |
275 | big: {\r | |
276 | chain: {\r | |
277 | total: 43\r | |
278 | }\r | |
279 | }\r | |
280 | })).toBe(43);\r | |
281 | });\r | |
282 | \r | |
283 | it("should read array notation for numeric values", function(){\r | |
284 | createReader({\r | |
285 | totalProperty: 'values[0]'\r | |
286 | });\r | |
287 | expect(reader.getTotal({\r | |
288 | values: [9]\r | |
289 | })).toBe(9);\r | |
290 | });\r | |
291 | \r | |
292 | it("should read array notation for property names", function(){\r | |
293 | createReader({\r | |
294 | totalProperty: '["foo-bar"]'\r | |
295 | });\r | |
296 | expect(reader.getTotal({\r | |
297 | 'foo-bar': 16\r | |
298 | })).toBe(16);\r | |
299 | });\r | |
300 | \r | |
301 | it("should read array/dot notation", function(){\r | |
302 | createReader({\r | |
303 | totalProperty: 'big[0].chain.total'\r | |
304 | });\r | |
305 | expect(reader.getTotal({\r | |
306 | big: [{\r | |
307 | chain: {\r | |
308 | total: 17\r | |
309 | }\r | |
310 | }]\r | |
311 | })).toBe(17);\r | |
312 | });\r | |
313 | \r | |
314 | it("should not read dot chains if simple accessors are used", function(){\r | |
315 | createReader({\r | |
316 | totalProperty: 'some.big.chain',\r | |
317 | useSimpleAccessors: true\r | |
318 | });\r | |
319 | expect(reader.getTotal({\r | |
320 | 'some.big.chain': 88\r | |
321 | })).toBe(88);\r | |
322 | });\r | |
323 | }); \r | |
324 | });\r | |
325 | \r | |
326 | describe("success", function(){\r | |
327 | it("should default to success", function(){\r | |
328 | createReader();\r | |
329 | expect(reader.getSuccess({\r | |
330 | success: true\r | |
331 | })).toBe(true);\r | |
332 | });\r | |
333 | \r | |
334 | it("should have no getSuccess method if the successProperty isn't specified", function(){\r | |
335 | createReader({\r | |
336 | successProperty: ''\r | |
337 | });\r | |
338 | expect(reader.getSuccess).toBeUndefined();\r | |
339 | });\r | |
340 | \r | |
341 | it("should read the specified property name", function(){\r | |
342 | createReader({\r | |
343 | successProperty: 'foo'\r | |
344 | });\r | |
345 | expect(reader.getSuccess({\r | |
346 | foo: false\r | |
347 | })).toBe(false);\r | |
348 | });\r | |
349 | \r | |
350 | it("should accept a function configuration", function(){\r | |
351 | createReader({\r | |
352 | successProperty: function(data){\r | |
353 | return data.big.chain.success;\r | |
354 | }\r | |
355 | });\r | |
356 | expect(reader.getSuccess({\r | |
357 | big: {\r | |
358 | chain: {\r | |
359 | success: true\r | |
360 | }\r | |
361 | }\r | |
362 | })).toBe(true);\r | |
363 | });\r | |
364 | \r | |
365 | describe("JSON", function(){\r | |
366 | it("should read dot notation", function(){\r | |
367 | createReader({\r | |
368 | successProperty: 'big.chain.success'\r | |
369 | });\r | |
370 | expect(reader.getSuccess({\r | |
371 | big: {\r | |
372 | chain: {\r | |
373 | success: true\r | |
374 | }\r | |
375 | }\r | |
376 | })).toBe(true);\r | |
377 | });\r | |
378 | \r | |
379 | it("should read array notation for numeric values", function(){\r | |
380 | createReader({\r | |
381 | successProperty: 'values[0]'\r | |
382 | });\r | |
383 | expect(reader.getSuccess({\r | |
384 | values: [false]\r | |
385 | })).toBe(false);\r | |
386 | });\r | |
387 | \r | |
388 | it("should read array notation for property names", function(){\r | |
389 | createReader({\r | |
390 | successProperty: '["foo-bar"]'\r | |
391 | });\r | |
392 | expect(reader.getSuccess({\r | |
393 | 'foo-bar': false\r | |
394 | })).toBe(false);\r | |
395 | });\r | |
396 | \r | |
397 | it("should read array/dot notation", function(){\r | |
398 | createReader({\r | |
399 | successProperty: 'big[0].chain.success'\r | |
400 | });\r | |
401 | expect(reader.getSuccess({\r | |
402 | big: [{\r | |
403 | chain: {\r | |
404 | success: true\r | |
405 | }\r | |
406 | }]\r | |
407 | })).toBe(true);\r | |
408 | });\r | |
409 | \r | |
410 | it("should not read dot chains if simple accessors are used", function(){\r | |
411 | createReader({\r | |
412 | successProperty: 'some.big.chain',\r | |
413 | useSimpleAccessors: true\r | |
414 | });\r | |
415 | expect(reader.getSuccess({\r | |
416 | 'some.big.chain': true\r | |
417 | })).toBe(true);\r | |
418 | });\r | |
419 | });\r | |
420 | });\r | |
421 | \r | |
422 | describe("message", function(){\r | |
423 | it("should default to undefined", function(){\r | |
424 | createReader();\r | |
425 | expect(reader.getMessage).toBeUndefined();\r | |
426 | });\r | |
427 | \r | |
428 | it("should have no getMessage method if the messageProperty isn't specified", function(){\r | |
429 | createReader({\r | |
430 | successProperty: ''\r | |
431 | });\r | |
432 | expect(reader.getSuccess).toBeUndefined();\r | |
433 | });\r | |
434 | \r | |
435 | it("should read the specified property name", function(){\r | |
436 | createReader({\r | |
437 | messageProperty: 'foo'\r | |
438 | });\r | |
439 | expect(reader.getMessage({\r | |
440 | foo: false\r | |
441 | })).toBe(false);\r | |
442 | });\r | |
443 | \r | |
444 | it("should accept a function configuration", function(){\r | |
445 | createReader({\r | |
446 | messageProperty: function(data){\r | |
447 | return data.big.chain.message;\r | |
448 | }\r | |
449 | });\r | |
450 | expect(reader.getMessage({\r | |
451 | big: {\r | |
452 | chain: {\r | |
453 | message: 'msg'\r | |
454 | }\r | |
455 | }\r | |
456 | })).toBe('msg');\r | |
457 | });\r | |
458 | \r | |
459 | describe("JSON", function(){\r | |
460 | it("should read dot notation", function(){\r | |
461 | createReader({\r | |
462 | messageProperty: 'big.chain.message'\r | |
463 | });\r | |
464 | expect(reader.getMessage({\r | |
465 | big: {\r | |
466 | chain: {\r | |
467 | message: 'some message'\r | |
468 | }\r | |
469 | }\r | |
470 | })).toBe('some message');\r | |
471 | });\r | |
472 | \r | |
473 | it("should read array notation for numeric values", function(){\r | |
474 | createReader({\r | |
475 | messageProperty: 'values[0]'\r | |
476 | });\r | |
477 | expect(reader.getMessage({\r | |
478 | values: ['a message']\r | |
479 | })).toBe('a message');\r | |
480 | });\r | |
481 | \r | |
482 | it("should read array notation for property names", function(){\r | |
483 | createReader({\r | |
484 | messageProperty: '["foo-bar"]'\r | |
485 | });\r | |
486 | expect(reader.getMessage({\r | |
487 | 'foo-bar': 'new msg'\r | |
488 | })).toBe('new msg');\r | |
489 | });\r | |
490 | \r | |
491 | it("should read array/dot notation", function(){\r | |
492 | createReader({\r | |
493 | messageProperty: 'big[0].chain.message'\r | |
494 | });\r | |
495 | expect(reader.getMessage({\r | |
496 | big: [{\r | |
497 | chain: {\r | |
498 | message: 'stuff'\r | |
499 | }\r | |
500 | }]\r | |
501 | })).toBe('stuff');\r | |
502 | });\r | |
503 | \r | |
504 | it("should not read dot chains if simple accessors are used", function(){\r | |
505 | createReader({\r | |
506 | messageProperty: 'some.big.chain',\r | |
507 | useSimpleAccessors: true\r | |
508 | });\r | |
509 | expect(reader.getMessage({\r | |
510 | 'some.big.chain': 'data'\r | |
511 | })).toBe('data');\r | |
512 | });\r | |
513 | });\r | |
514 | });\r | |
515 | \r | |
516 | describe("root", function(){\r | |
517 | it("should default to a function returning the main object", function(){\r | |
518 | var data = [];\r | |
519 | createReader();\r | |
520 | expect(reader.getRoot(data)).toBe(data);\r | |
521 | });\r | |
522 | \r | |
523 | it("default to a function returning the main object root isn't specified", function(){\r | |
524 | var data = [];\r | |
525 | createReader({\r | |
526 | rootProperty: ''\r | |
527 | });\r | |
528 | expect(reader.getRoot(data)).toBe(data);\r | |
529 | });\r | |
530 | \r | |
531 | it("should read the specified property name", function(){\r | |
532 | var data = [];\r | |
533 | createReader({\r | |
534 | rootProperty: 'foo'\r | |
535 | });\r | |
536 | expect(reader.getRoot({\r | |
537 | foo: data\r | |
538 | })).toBe(data);\r | |
539 | });\r | |
540 | \r | |
541 | it("should accept a function configuration", function(){\r | |
542 | var data = [];\r | |
543 | createReader({\r | |
544 | rootProperty: function(data){\r | |
545 | return data.big.chain.root;\r | |
546 | }\r | |
547 | });\r | |
548 | expect(reader.getRoot({\r | |
549 | big: {\r | |
550 | chain: {\r | |
551 | root: data\r | |
552 | }\r | |
553 | }\r | |
554 | })).toBe(data);\r | |
555 | });\r | |
556 | \r | |
557 | describe("JSON", function(){\r | |
558 | it("should read dot notation", function(){\r | |
559 | var data = [];\r | |
560 | createReader({\r | |
561 | rootProperty: 'big.chain.root'\r | |
562 | });\r | |
563 | expect(reader.getRoot({\r | |
564 | big: {\r | |
565 | chain: {\r | |
566 | root: data\r | |
567 | }\r | |
568 | }\r | |
569 | })).toBe(data);\r | |
570 | });\r | |
571 | \r | |
572 | it("should read array notation for numeric values", function(){\r | |
573 | var data = [];\r | |
574 | createReader({\r | |
575 | rootProperty: 'values[0]'\r | |
576 | });\r | |
577 | expect(reader.getRoot({\r | |
578 | values: [data]\r | |
579 | })).toBe(data);\r | |
580 | });\r | |
581 | \r | |
582 | it("should read array notation for property names", function(){\r | |
583 | var data = [];\r | |
584 | createReader({\r | |
585 | rootProperty: '["foo-bar"]'\r | |
586 | });\r | |
587 | expect(reader.getRoot({\r | |
588 | 'foo-bar': data\r | |
589 | })).toBe(data);\r | |
590 | });\r | |
591 | \r | |
592 | it("should read array/dot notation", function(){\r | |
593 | var data = [];\r | |
594 | createReader({\r | |
595 | rootProperty: 'big[0].chain.root'\r | |
596 | });\r | |
597 | expect(reader.getRoot({\r | |
598 | big: [{\r | |
599 | chain: {\r | |
600 | root: data\r | |
601 | }\r | |
602 | }]\r | |
603 | })).toBe(data);\r | |
604 | });\r | |
605 | \r | |
606 | it("should not read dot chains if simple accessors are used", function(){\r | |
607 | var data = [];\r | |
608 | createReader({\r | |
609 | rootProperty: 'some.big.chain',\r | |
610 | useSimpleAccessors: true\r | |
611 | });\r | |
612 | expect(reader.getRoot({\r | |
613 | 'some.big.chain': data\r | |
614 | })).toBe(data);\r | |
615 | });\r | |
616 | });\r | |
617 | });\r | |
618 | \r | |
619 | describe("fields", function(){\r | |
620 | var rawOptions = {\r | |
621 | recordCreator: Ext.identityFn\r | |
622 | };\r | |
623 | \r | |
624 | beforeEach(function(){\r | |
625 | createReader = function(fields, simple){\r | |
626 | Ext.define('spec.JsonFieldTest', {\r | |
627 | extend: 'Ext.data.Model',\r | |
628 | fields: fields\r | |
629 | });\r | |
630 | reader = new Ext.data.reader.Json({\r | |
631 | model: 'spec.JsonFieldTest',\r | |
632 | fields: fields,\r | |
633 | useSimpleAccessors: simple || false\r | |
634 | });\r | |
635 | };\r | |
636 | });\r | |
637 | \r | |
638 | afterEach(function() {\r | |
639 | Ext.undefine('spec.JsonFieldTest');\r | |
640 | });\r | |
641 | \r | |
642 | it("should read the name if no mapping is specified", function(){\r | |
643 | createReader(['field']);\r | |
644 | var result = reader.readRecords([{field: 'val'}], rawOptions).getRecords()[0];\r | |
645 | expect(result.field).toBe('val');\r | |
646 | });\r | |
647 | \r | |
648 | it("should give precedence to the mapping", function(){\r | |
649 | createReader([{\r | |
650 | name: 'field',\r | |
651 | mapping: 'somethingElse'\r | |
652 | }]);\r | |
653 | var result = reader.readRecords([{somethingElse: 'a value'}], rawOptions).getRecords()[0];\r | |
654 | expect(result.field).toEqual('a value');\r | |
655 | });\r | |
656 | \r | |
657 | it("should accept a function", function(){\r | |
658 | createReader([{\r | |
659 | name: 'field',\r | |
660 | mapping: function(o){\r | |
661 | return o.complex.chain.value;\r | |
662 | }\r | |
663 | }]);\r | |
664 | var result = reader.readRecords([{\r | |
665 | complex: {\r | |
666 | chain: {\r | |
667 | value: 2\r | |
668 | }\r | |
669 | }\r | |
670 | }], rawOptions).getRecords()[0];\r | |
671 | expect(result.field).toBe(2);\r | |
672 | });\r | |
673 | \r | |
674 | it("should ignore certain falsy mapping values", function(){\r | |
675 | createReader([{\r | |
676 | name: 'field',\r | |
677 | mapping: undefined\r | |
678 | }, {\r | |
679 | name: 'field2',\r | |
680 | mapping: null\r | |
681 | }, {\r | |
682 | name: 'field3',\r | |
683 | mapping: ''\r | |
684 | }]);\r | |
685 | var result = reader.readRecords([{\r | |
686 | field: 'val',\r | |
687 | field2: 'val2',\r | |
688 | field3: 'val3'\r | |
689 | }], rawOptions).getRecords()[0];\r | |
690 | \r | |
691 | expect(result.field).toBe('val');\r | |
692 | expect(result.field2).toBe('val2');\r | |
693 | expect(result.field3).toBe('val3');\r | |
694 | });\r | |
695 | \r | |
696 | it("should allow zero value for mapping", function(){\r | |
697 | createReader([{\r | |
698 | name: 'field',\r | |
699 | mapping: 0\r | |
700 | }]);\r | |
701 | var result1 = reader.readRecords([{\r | |
702 | 0: 'woo'\r | |
703 | }], rawOptions).getRecords()[0];\r | |
704 | var result2 = reader.readRecords([['T']], rawOptions).getRecords()[0];\r | |
705 | expect(result1.field).toBe('woo');\r | |
706 | expect(result2.field).toBe('T');\r | |
707 | });\r | |
708 | \r | |
709 | it("should not include a mapping where the value doesn't exist", function() {\r | |
710 | createReader([{\r | |
711 | name: 'field',\r | |
712 | mapping: 'foo'\r | |
713 | }]);\r | |
714 | var result = reader.readRecords([{\r | |
715 | notFoo: 'x'\r | |
716 | }], rawOptions).getRecords()[0];\r | |
717 | expect(result).toEqual({\r | |
718 | notFoo: 'x'\r | |
719 | });\r | |
720 | expect(result.hasOwnProperty('field')).toBe(false);\r | |
721 | });\r | |
722 | \r | |
723 | describe("JSON", function(){\r | |
724 | it("should read dot notation", function(){\r | |
725 | createReader([{\r | |
726 | name: 'field',\r | |
727 | mapping: 'some.value'\r | |
728 | }]);\r | |
729 | var result = reader.readRecords([{\r | |
730 | some: {\r | |
731 | value: 'mapped'\r | |
732 | }\r | |
733 | }], rawOptions).getRecords()[0];\r | |
734 | expect(result.field).toBe('mapped');\r | |
735 | });\r | |
736 | \r | |
737 | it("should handle dot notation with an undefined property", function(){\r | |
738 | createReader([{\r | |
739 | name: 'field',\r | |
740 | mapping: 'some.value'\r | |
741 | }]);\r | |
742 | var result = reader.readRecords([{\r | |
743 | some: {\r | |
744 | // 'value' is undefined\r | |
745 | }\r | |
746 | }], rawOptions).getRecords()[0];\r | |
747 | expect(result.field).toBeUndefined(); // default value\r | |
748 | });\r | |
749 | \r | |
750 | it("should handle dot notation with nested undefined properties", function(){\r | |
751 | createReader([{\r | |
752 | name: 'field',\r | |
753 | mapping: 'some.deep.nested.value'\r | |
754 | }]);\r | |
755 | var result = reader.readRecords([{\r | |
756 | some: {\r | |
757 | // 'deep' and children are undefined\r | |
758 | }\r | |
759 | }], rawOptions).getRecords()[0];\r | |
760 | expect(result.field).toBeUndefined(); // default value\r | |
761 | });\r | |
762 | \r | |
763 | it("should read array notation for numeric values", function(){\r | |
764 | createReader([{\r | |
765 | name: 'field',\r | |
766 | mapping: 'values[0]'\r | |
767 | }]);\r | |
768 | var result = reader.readRecords([{\r | |
769 | values: ['a']\r | |
770 | }], rawOptions).getRecords()[0];\r | |
771 | expect(result.field).toBe('a');\r | |
772 | });\r | |
773 | \r | |
774 | it("should read array notation for property names", function(){\r | |
775 | createReader([{\r | |
776 | name: 'field',\r | |
777 | mapping: '["a-prop"]'\r | |
778 | }]);\r | |
779 | var result = reader.readRecords([{\r | |
780 | 'a-prop': 'woo'\r | |
781 | }], rawOptions).getRecords()[0];\r | |
782 | expect(result.field).toBe('woo');\r | |
783 | });\r | |
784 | \r | |
785 | it("should read array/dot notation", function(){\r | |
786 | createReader([{\r | |
787 | name: 'field',\r | |
788 | mapping: 'big[0].chain.value'\r | |
789 | }]);\r | |
790 | var result = reader.readRecords([{\r | |
791 | big: [{\r | |
792 | chain: {\r | |
793 | value: 45\r | |
794 | }\r | |
795 | }]\r | |
796 | }], rawOptions).getRecords()[0];\r | |
797 | expect(result.field).toBe(45);\r | |
798 | });\r | |
799 | \r | |
800 | it("should handle array/dot notation with nested undefined properties", function(){\r | |
801 | createReader([{\r | |
802 | name: 'field',\r | |
803 | mapping: 'big[0].deep.chain.value'\r | |
804 | }]);\r | |
805 | var result = reader.readRecords([{\r | |
806 | big: [{\r | |
807 | deep: {\r | |
808 | // 'chain' and children are undefined\r | |
809 | }\r | |
810 | }]\r | |
811 | }], rawOptions).getRecords()[0];\r | |
812 | expect(result.field).toBeUndefined(); // default value\r | |
813 | });\r | |
814 | \r | |
815 | it("should not read dot chains if simple accessors are used", function(){\r | |
816 | createReader([{\r | |
817 | name: 'field',\r | |
818 | mapping: 'a.long.name'\r | |
819 | }], true);\r | |
820 | var result = reader.readRecords([{\r | |
821 | 'a.long.name': 'sixty'\r | |
822 | }], rawOptions).getRecords()[0];\r | |
823 | \r | |
824 | expect(result.field).toBe('sixty');\r | |
825 | });\r | |
826 | \r | |
827 | it("should handle dot chains with undefined values if simple accessors are used", function(){\r | |
828 | createReader([{\r | |
829 | name: 'field',\r | |
830 | mapping: 'a.long.name'\r | |
831 | }], true);\r | |
832 | var result = reader.readRecords([{\r | |
833 | // 'a.long.name' is undefined\r | |
834 | }], rawOptions).getRecords()[0];\r | |
835 | expect(result.field).toBeUndefined();\r | |
836 | });\r | |
837 | \r | |
838 | it("should read dotted properties inside a bracketed block", function() {\r | |
839 | createReader([{\r | |
840 | name: 'field',\r | |
841 | mapping: '["foo.bar.baz"]'\r | |
842 | }]);\r | |
843 | \r | |
844 | var result = reader.readRecords([{\r | |
845 | 'foo.bar.baz': 'x'\r | |
846 | }], rawOptions).getRecords()[0];\r | |
847 | expect(result.field).toBe('x');\r | |
848 | });\r | |
849 | \r | |
850 | it("should read [arrayIndex].property", function() {\r | |
851 | createReader([{\r | |
852 | name: 'field',\r | |
853 | mapping: '[2].foo'\r | |
854 | }]);\r | |
855 | \r | |
856 | var result = reader.readRecords([\r | |
857 | [1, 2, {\r | |
858 | foo: 'x'\r | |
859 | }]\r | |
860 | ], rawOptions).getRecords()[0];\r | |
861 | expect(result.field).toBe('x');\r | |
862 | });\r | |
863 | \r | |
864 | it("should read [arrayIndex]['property']", function() {\r | |
865 | createReader([{\r | |
866 | name: 'field',\r | |
867 | mapping: '[2]["complex-name"]'\r | |
868 | }]);\r | |
869 | \r | |
870 | var result = reader.readRecords([\r | |
871 | [1, 2, {\r | |
872 | 'complex-name': 'x'\r | |
873 | }]\r | |
874 | ], rawOptions).getRecords()[0];\r | |
875 | expect(result.field).toBe('x');\r | |
876 | });\r | |
877 | \r | |
878 | it("should read [arrayIndex][arrayIndex]", function() {\r | |
879 | createReader([{\r | |
880 | name: 'field',\r | |
881 | mapping: '[2][1]'\r | |
882 | }]);\r | |
883 | \r | |
884 | var result = reader.readRecords([\r | |
885 | [1, 2, [3, 4, 5, 6]]\r | |
886 | ], rawOptions).getRecords()[0];\r | |
887 | expect(result.field).toBe(4);\r | |
888 | });\r | |
889 | \r | |
890 | it("should read property.property", function() {\r | |
891 | createReader([{\r | |
892 | name: 'field',\r | |
893 | mapping: 'foo.bar'\r | |
894 | }]);\r | |
895 | \r | |
896 | var result = reader.readRecords([{\r | |
897 | foo: {\r | |
898 | bar: 'x'\r | |
899 | }\r | |
900 | }], rawOptions).getRecords()[0];\r | |
901 | expect(result.field).toBe('x');\r | |
902 | });\r | |
903 | \r | |
904 | it("should read property['property']", function() {\r | |
905 | createReader([{\r | |
906 | name: 'field',\r | |
907 | mapping: 'foo["complex-name"]'\r | |
908 | }]);\r | |
909 | \r | |
910 | var result = reader.readRecords([{\r | |
911 | foo: {\r | |
912 | 'complex-name': 'x'\r | |
913 | }\r | |
914 | }], rawOptions).getRecords()[0];\r | |
915 | expect(result.field).toBe('x');\r | |
916 | });\r | |
917 | \r | |
918 | it("should read property[arrayIndex]", function() {\r | |
919 | createReader([{\r | |
920 | name: 'field',\r | |
921 | mapping: 'foo[2]'\r | |
922 | }]);\r | |
923 | \r | |
924 | var result = reader.readRecords([{\r | |
925 | foo: [1, 2, 3, 4]\r | |
926 | }], rawOptions).getRecords()[0];\r | |
927 | expect(result.field).toBe(3);\r | |
928 | });\r | |
929 | \r | |
930 | it("should read ['property'].property", function() {\r | |
931 | createReader([{\r | |
932 | name: 'field',\r | |
933 | mapping: '["complex-name"].foo'\r | |
934 | }]);\r | |
935 | \r | |
936 | var result = reader.readRecords([{\r | |
937 | 'complex-name': {\r | |
938 | foo: 'x'\r | |
939 | }\r | |
940 | }], rawOptions).getRecords()[0];\r | |
941 | expect(result.field).toBe('x');\r | |
942 | });\r | |
943 | \r | |
944 | it("should read ['property']['property']", function() {\r | |
945 | createReader([{\r | |
946 | name: 'field',\r | |
947 | mapping: '["complex-name"]["other-prop"]'\r | |
948 | }]);\r | |
949 | \r | |
950 | var result = reader.readRecords([{\r | |
951 | 'complex-name': {\r | |
952 | 'other-prop': 'x'\r | |
953 | }\r | |
954 | }], rawOptions).getRecords()[0];\r | |
955 | expect(result.field).toBe('x');\r | |
956 | });\r | |
957 | \r | |
958 | it("should read ['property'][arrayIndex]", function() {\r | |
959 | createReader([{\r | |
960 | name: 'field',\r | |
961 | mapping: '["complex-name"][1]'\r | |
962 | }]);\r | |
963 | \r | |
964 | var result = reader.readRecords([{\r | |
965 | 'complex-name': [1, 2, 3, 4]\r | |
966 | }], rawOptions).getRecords()[0];\r | |
967 | expect(result.field).toBe(2);\r | |
968 | });\r | |
969 | \r | |
970 | it("should read property['property'][arrayIndex]", function() {\r | |
971 | createReader([{\r | |
972 | name: 'field',\r | |
973 | mapping: 'foo["complex-name"][2]'\r | |
974 | }]);\r | |
975 | \r | |
976 | var result = reader.readRecords([{\r | |
977 | foo: {\r | |
978 | 'complex-name': [1, 2, 3, 4]\r | |
979 | }\r | |
980 | }], rawOptions).getRecords()[0];\r | |
981 | expect(result.field).toBe(3);\r | |
982 | });\r | |
983 | \r | |
984 | it("should handle property[arrayIndex]['property']", function() {\r | |
985 | createReader([{\r | |
986 | name: 'field',\r | |
987 | mapping: 'foo[1]["complex-name"]'\r | |
988 | }]);\r | |
989 | \r | |
990 | var result = reader.readRecords([{\r | |
991 | foo: [1, {\r | |
992 | 'complex-name': 'x'\r | |
993 | }]\r | |
994 | }], rawOptions).getRecords()[0];\r | |
995 | expect(result.field).toBe('x');\r | |
996 | });\r | |
997 | \r | |
998 | it("should handle ['property'].property[arrayIndex]", function() {\r | |
999 | createReader([{\r | |
1000 | name: 'field',\r | |
1001 | mapping: '["complex-name"].foo[1]'\r | |
1002 | }]);\r | |
1003 | \r | |
1004 | var result = reader.readRecords([{\r | |
1005 | 'complex-name': {\r | |
1006 | foo: [1, 2, 3]\r | |
1007 | }\r | |
1008 | }], rawOptions).getRecords()[0];\r | |
1009 | expect(result.field).toBe(2);\r | |
1010 | });\r | |
1011 | \r | |
1012 | it("should handle ['property'][arrayIndex].property", function() {\r | |
1013 | createReader([{\r | |
1014 | name: 'field',\r | |
1015 | mapping: '["complex-name"][1].foo'\r | |
1016 | }]);\r | |
1017 | \r | |
1018 | var result = reader.readRecords([{\r | |
1019 | 'complex-name': [1, {\r | |
1020 | foo: 'x'\r | |
1021 | }]\r | |
1022 | }], rawOptions).getRecords()[0];\r | |
1023 | expect(result.field).toBe('x');\r | |
1024 | });\r | |
1025 | \r | |
1026 | it("should handle [arrayIndex].property['property']", function() {\r | |
1027 | createReader([{\r | |
1028 | name: 'field',\r | |
1029 | mapping: '[1].foo["complex-name"]'\r | |
1030 | }]);\r | |
1031 | \r | |
1032 | var result = reader.readRecords([\r | |
1033 | [1, {\r | |
1034 | foo: {\r | |
1035 | 'complex-name': 'x'\r | |
1036 | }\r | |
1037 | }]\r | |
1038 | ], rawOptions).getRecords()[0];\r | |
1039 | expect(result.field).toBe('x');\r | |
1040 | });\r | |
1041 | \r | |
1042 | it("should handle [arrayIndex]['property'].property", function() {\r | |
1043 | createReader([{\r | |
1044 | name: 'field',\r | |
1045 | mapping: '[1]["complex-name"].foo'\r | |
1046 | }]);\r | |
1047 | \r | |
1048 | var result = reader.readRecords([\r | |
1049 | [1, {\r | |
1050 | 'complex-name': {\r | |
1051 | foo: 'x'\r | |
1052 | }\r | |
1053 | }]\r | |
1054 | ], rawOptions).getRecords()[0];\r | |
1055 | expect(result.field).toBe('x');\r | |
1056 | });\r | |
1057 | });\r | |
1058 | });\r | |
1059 | });\r | |
1060 | \r | |
1061 | describe("reading records", function() {\r | |
1062 | beforeEach(function() {\r | |
1063 | Ext.define("spec.JsonReaderTest", {\r | |
1064 | extend: 'Ext.data.Model',\r | |
1065 | fields: [\r | |
1066 | {name: 'id'},\r | |
1067 | {name: 'floater', type: 'float'},\r | |
1068 | {name: 'bool', type: 'boolean'},\r | |
1069 | {name: 'inter', type: 'integer'},\r | |
1070 | {name: 'class', type: 'string'},\r | |
1071 | {\r | |
1072 | name: 'string', \r | |
1073 | type: 'string', \r | |
1074 | convert: function(v) {\r | |
1075 | return "modified/" + v;\r | |
1076 | }\r | |
1077 | }, {\r | |
1078 | name: 'withMap',\r | |
1079 | mapping: 'someMap'\r | |
1080 | }\r | |
1081 | ]\r | |
1082 | });\r | |
1083 | \r | |
1084 | // Created in global beforeEach\r | |
1085 | reader.destroy();\r | |
1086 | \r | |
1087 | reader = new Ext.data.reader.Json({\r | |
1088 | rootProperty: 'data',\r | |
1089 | idProperty: 'id',\r | |
1090 | successProperty: 'successProp',\r | |
1091 | totalProperty: 'totalProp',\r | |
1092 | messageProperty: 'message',\r | |
1093 | model: "spec.JsonReaderTest"\r | |
1094 | });\r | |
1095 | \r | |
1096 | data1 = {\r | |
1097 | id : 1,\r | |
1098 | bool : true,\r | |
1099 | inter : 8675,\r | |
1100 | floater: 1.23,\r | |
1101 | string : 'Ed',\r | |
1102 | 'class': 'person'\r | |
1103 | };\r | |
1104 | \r | |
1105 | data2 = {\r | |
1106 | id : 2,\r | |
1107 | bool : false,\r | |
1108 | inter : 309,\r | |
1109 | floater: 4.56,\r | |
1110 | string : 'Nick',\r | |
1111 | 'class': 'person'\r | |
1112 | };\r | |
1113 | \r | |
1114 | result1 = reader.readRecords({\r | |
1115 | data : [data1],\r | |
1116 | successProp: true,\r | |
1117 | totalProp : 2\r | |
1118 | });\r | |
1119 | \r | |
1120 | result2 = reader.readRecords({\r | |
1121 | data : [data2],\r | |
1122 | successProp: false,\r | |
1123 | totalProp : 6,\r | |
1124 | message : 'Failed'\r | |
1125 | });\r | |
1126 | \r | |
1127 | result3 = reader.readRecords({\r | |
1128 | data : data2,\r | |
1129 | successProp: true,\r | |
1130 | totalProp : 6\r | |
1131 | });\r | |
1132 | });\r | |
1133 | \r | |
1134 | afterEach(function() {\r | |
1135 | Ext.undefine("spec.JsonReaderTest");\r | |
1136 | });\r | |
1137 | \r | |
1138 | it("should read the success property", function() {\r | |
1139 | expect(result1.getSuccess()).toBe(true);\r | |
1140 | expect(result2.getSuccess()).toBe(false);\r | |
1141 | });\r | |
1142 | \r | |
1143 | it("should read the total record count", function() {\r | |
1144 | expect(result1.getTotal()).toBe(2);\r | |
1145 | expect(result2.getTotal()).toBe(6);\r | |
1146 | });\r | |
1147 | \r | |
1148 | it("should read records correctly", function() {\r | |
1149 | var recData = result1.getRecords()[0].getData();\r | |
1150 | \r | |
1151 | expect(recData.id).toBe(data1.id);\r | |
1152 | expect(recData.floater).toBe(data1.floater);\r | |
1153 | expect(recData.bool).toBe(data1.bool);\r | |
1154 | expect(recData.inter).toBe(data1.inter);\r | |
1155 | });\r | |
1156 | \r | |
1157 | it("should be able to have fields as reserved words", function(){\r | |
1158 | var recData = result1.getRecords()[0].getData();\r | |
1159 | expect(recData['class']).toBe('person'); \r | |
1160 | });\r | |
1161 | \r | |
1162 | it("should read records correctly if there was just a single object instead of an array of data", function() {\r | |
1163 | var recData = result3.getRecords()[0].getData();\r | |
1164 | \r | |
1165 | expect(recData.id).toBe(data2.id);\r | |
1166 | expect(recData.floater).toBe(data2.floater);\r | |
1167 | expect(recData.bool).toBe(data2.bool);\r | |
1168 | expect(recData.inter).toBe(data2.inter);\r | |
1169 | });\r | |
1170 | \r | |
1171 | it("should still read on failure by default", function(){\r | |
1172 | expect(result2.getRecords()[0].getId()).toBe(2);\r | |
1173 | });\r | |
1174 | \r | |
1175 | it("should ignore values records/total when success is false & readRecordsOnFailure is false", function(){\r | |
1176 | reader.setReadRecordsOnFailure(false);\r | |
1177 | result2 = reader.readRecords({\r | |
1178 | data : [data2],\r | |
1179 | successProp: false,\r | |
1180 | totalProp : 6,\r | |
1181 | message : 'Failed'\r | |
1182 | });\r | |
1183 | expect(result2.getRecords()).toEqual([]);\r | |
1184 | expect(result2.getTotal()).toBe(0);\r | |
1185 | expect(result2.getMessage()).toBe('Failed');\r | |
1186 | });\r | |
1187 | \r | |
1188 | it("should respect the field's convert function", function() {\r | |
1189 | var recData = result1.getRecords()[0].getData();\r | |
1190 | \r | |
1191 | expect(recData.string).toBe('modified/Ed');\r | |
1192 | });\r | |
1193 | \r | |
1194 | it("should be able to load a single record", function(){\r | |
1195 | var data = reader.readRecords({\r | |
1196 | data: data1\r | |
1197 | }).getRecords()[0].getData();\r | |
1198 | \r | |
1199 | expect(data.id).toBe(data1.id);\r | |
1200 | expect(data.floater).toBe(data1.floater);\r | |
1201 | expect(data.bool).toBe(data1.bool);\r | |
1202 | expect(data.inter).toBe(data1.inter);\r | |
1203 | });\r | |
1204 | \r | |
1205 | it("should handle record instances being in the data", function(){\r | |
1206 | var data = reader.readRecords({\r | |
1207 | data : [data1, new spec.JsonReaderTest(data2)],\r | |
1208 | successProp: true\r | |
1209 | }).getRecords()[1].getData();\r | |
1210 | \r | |
1211 | expect(data.id).toBe(data2.id);\r | |
1212 | expect(data.floater).toBe(data2.floater);\r | |
1213 | expect(data.bool).toBe(data2.bool);\r | |
1214 | expect(data.inter).toBe(data2.inter);\r | |
1215 | });\r | |
1216 | \r | |
1217 | describe("readOptions", function() {\r | |
1218 | it("should return what we construct when we pass recordCreator", function() {\r | |
1219 | var records = reader.readRecords({\r | |
1220 | data: [data1, data2]\r | |
1221 | }, {\r | |
1222 | recordCreator: function(o) {\r | |
1223 | return o;\r | |
1224 | }\r | |
1225 | }).getRecords();\r | |
1226 | expect(records[0]).toEqual(data1);\r | |
1227 | expect(records[1]).toEqual(data2);\r | |
1228 | }); \r | |
1229 | \r | |
1230 | it("should process mappings", function() {\r | |
1231 | var records = reader.readRecords({\r | |
1232 | data: [{\r | |
1233 | someMap: 'foo'\r | |
1234 | }]\r | |
1235 | }, {\r | |
1236 | recordCreator: function(o) {\r | |
1237 | return o;\r | |
1238 | }\r | |
1239 | }).getRecords();\r | |
1240 | expect(records[0]).toEqual({\r | |
1241 | withMap: 'foo',\r | |
1242 | someMap: 'foo'\r | |
1243 | });\r | |
1244 | });\r | |
1245 | });\r | |
1246 | });\r | |
1247 | \r | |
1248 | describe("loading with a 'record' property", function() {\r | |
1249 | var data, resultSet;\r | |
1250 | \r | |
1251 | beforeEach(function() {\r | |
1252 | Ext.define('spec.User', {\r | |
1253 | extend: 'Ext.data.Model',\r | |
1254 | fields: [\r | |
1255 | 'id', 'name', 'email'\r | |
1256 | ]\r | |
1257 | });\r | |
1258 | \r | |
1259 | // Created in global beforeEach\r | |
1260 | reader.destroy();\r | |
1261 | \r | |
1262 | reader = new Ext.data.reader.Json({\r | |
1263 | model: 'spec.User',\r | |
1264 | rootProperty: 'users',\r | |
1265 | record: 'user'\r | |
1266 | });\r | |
1267 | \r | |
1268 | data = {\r | |
1269 | users: [\r | |
1270 | {\r | |
1271 | user: {\r | |
1272 | id: 1,\r | |
1273 | name: 'Ed Spencer',\r | |
1274 | email: 'ed@sencha.com'\r | |
1275 | }\r | |
1276 | },\r | |
1277 | {\r | |
1278 | user: {\r | |
1279 | id: 2,\r | |
1280 | name: 'Abe Elias',\r | |
1281 | email: 'abe@sencha.com'\r | |
1282 | }\r | |
1283 | }\r | |
1284 | ]\r | |
1285 | };\r | |
1286 | \r | |
1287 | resultSet = reader.readRecords(data);\r | |
1288 | });\r | |
1289 | \r | |
1290 | afterEach(function() {\r | |
1291 | Ext.undefine('spec.User');\r | |
1292 | });\r | |
1293 | \r | |
1294 | it("should parse the correct number of results", function() {\r | |
1295 | expect(resultSet.getCount()).toEqual(2);\r | |
1296 | });\r | |
1297 | \r | |
1298 | it("should parse each record correctly", function() {\r | |
1299 | var records = resultSet.getRecords(),\r | |
1300 | record1 = records[0],\r | |
1301 | record2 = records[1];\r | |
1302 | \r | |
1303 | expect(record1.get('name')).toBe('Ed Spencer');\r | |
1304 | expect(record2.get('name')).toBe('Abe Elias');\r | |
1305 | });\r | |
1306 | });\r | |
1307 | \r | |
1308 | describe("calling model onLoad", function() {\r | |
1309 | beforeEach(function() {\r | |
1310 | Ext.define('spec.User', {\r | |
1311 | extend: 'Ext.data.Model',\r | |
1312 | fields: ['name'],\r | |
1313 | onLoad: function() {}\r | |
1314 | });\r | |
1315 | \r | |
1316 | // Created in global beforeEach\r | |
1317 | reader.destroy();\r | |
1318 | });\r | |
1319 | \r | |
1320 | afterEach(function() {\r | |
1321 | Ext.undefine('spec.User');\r | |
1322 | });\r | |
1323 | \r | |
1324 | it("should call the template method for each record", function() {\r | |
1325 | var spy = spyOn(spec.User.prototype, 'onLoad');\r | |
1326 | reader = new Ext.data.reader.Json({\r | |
1327 | model: 'spec.User'\r | |
1328 | });\r | |
1329 | reader.read([\r | |
1330 | {id: 1},\r | |
1331 | {id: 2},\r | |
1332 | {id: 3},\r | |
1333 | {id: 4},\r | |
1334 | {id: 5},\r | |
1335 | {id: 6},\r | |
1336 | {id: 7}\r | |
1337 | ]);\r | |
1338 | expect(spy.callCount).toBe(7);\r | |
1339 | });\r | |
1340 | \r | |
1341 | it("should call the template method after processing associations", function() {\r | |
1342 | var count;\r | |
1343 | spyOn(spec.User.prototype, 'onLoad').andCallFake(function() {\r | |
1344 | count = this.orders().getCount();\r | |
1345 | });\r | |
1346 | Ext.define('spec.Order', {\r | |
1347 | extend: 'Ext.data.Model',\r | |
1348 | fields: [{\r | |
1349 | name: 'userId',\r | |
1350 | reference: 'User'\r | |
1351 | }]\r | |
1352 | });\r | |
1353 | reader = new Ext.data.reader.Json({\r | |
1354 | model: 'spec.User'\r | |
1355 | });\r | |
1356 | reader.read([{\r | |
1357 | id: 1,\r | |
1358 | orders: [{\r | |
1359 | id: 1\r | |
1360 | }]\r | |
1361 | }]);\r | |
1362 | expect(count).toBe(1);\r | |
1363 | Ext.undefine('spec.Order');\r | |
1364 | });\r | |
1365 | });\r | |
1366 | \r | |
1367 | describe("loading nested data", function() {\r | |
1368 | var nestedLoadData = {\r | |
1369 | "users": [\r | |
1370 | {\r | |
1371 | "id": 123,\r | |
1372 | "name": "Ed",\r | |
1373 | "addresses": [\r | |
1374 | {\r | |
1375 | "line1": "525 University Avenue",\r | |
1376 | "line2": "Suite 23",\r | |
1377 | "town" : "Palo Alto"\r | |
1378 | }\r | |
1379 | ],\r | |
1380 | "orders": [\r | |
1381 | {\r | |
1382 | "id": 50,\r | |
1383 | "total": 100,\r | |
1384 | "order_items": [\r | |
1385 | {\r | |
1386 | "id" : 20,\r | |
1387 | "price" : 40,\r | |
1388 | "quantity": 2,\r | |
1389 | "product" : {\r | |
1390 | "id": 1000,\r | |
1391 | "name": "MacBook Pro"\r | |
1392 | }\r | |
1393 | },\r | |
1394 | {\r | |
1395 | "id" : 21,\r | |
1396 | "price" : 20,\r | |
1397 | "quantity": 1,\r | |
1398 | "product" : {\r | |
1399 | "id": 1001,\r | |
1400 | "name": "iPhone"\r | |
1401 | }\r | |
1402 | }\r | |
1403 | ]\r | |
1404 | },\r | |
1405 | {\r | |
1406 | "id": 51,\r | |
1407 | "total": 10,\r | |
1408 | "order_items": [\r | |
1409 | {\r | |
1410 | "id": 22,\r | |
1411 | "price": 10,\r | |
1412 | "quantity": 1,\r | |
1413 | "product": {\r | |
1414 | "id" : 1002,\r | |
1415 | "name": "iPad"\r | |
1416 | }\r | |
1417 | }\r | |
1418 | ]\r | |
1419 | }\r | |
1420 | ]\r | |
1421 | }\r | |
1422 | ]\r | |
1423 | };\r | |
1424 | \r | |
1425 | beforeEach(function() {\r | |
1426 | //We have five models - User, Address, Order, OrderItem and Product\r | |
1427 | Ext.define("spec.User", {\r | |
1428 | extend: 'Ext.data.Model',\r | |
1429 | fields: [\r | |
1430 | 'id', 'name'\r | |
1431 | ],\r | |
1432 | \r | |
1433 | hasMany: [\r | |
1434 | {model: 'spec.Order', name: 'orders'},\r | |
1435 | {model: 'spec.Address', name: 'addresses'}\r | |
1436 | ],\r | |
1437 | \r | |
1438 | proxy: {\r | |
1439 | type: 'rest',\r | |
1440 | reader: {\r | |
1441 | type: 'json',\r | |
1442 | rootProperty: 'users'\r | |
1443 | }\r | |
1444 | }\r | |
1445 | });\r | |
1446 | \r | |
1447 | spyOn(Ext.log, 'warn');\r | |
1448 | \r | |
1449 | Ext.define('spec.Address', {\r | |
1450 | extend: 'Ext.data.Model',\r | |
1451 | fields: [\r | |
1452 | 'id', 'line1', 'line2', 'town'\r | |
1453 | ],\r | |
1454 | \r | |
1455 | belongsTo: 'spec.User'\r | |
1456 | });\r | |
1457 | \r | |
1458 | Ext.define("spec.Order", {\r | |
1459 | extend: 'Ext.data.Model',\r | |
1460 | fields: [\r | |
1461 | 'id', 'total'\r | |
1462 | ],\r | |
1463 | \r | |
1464 | hasMany : {model: 'spec.OrderItem', name: 'orderItems', associationKey: 'order_items'},\r | |
1465 | belongsTo: 'spec.User'\r | |
1466 | });\r | |
1467 | \r | |
1468 | Ext.define("spec.OrderItem", {\r | |
1469 | extend: 'Ext.data.Model',\r | |
1470 | fields: [\r | |
1471 | 'id', 'price', 'quantity', 'order_id', 'product_id'\r | |
1472 | ],\r | |
1473 | \r | |
1474 | belongsTo: ['spec.Order', {model: 'spec.Product', getterName: 'getProduct', associationKey: 'product'}]\r | |
1475 | });\r | |
1476 | \r | |
1477 | Ext.define("spec.Product", {\r | |
1478 | extend: 'Ext.data.Model',\r | |
1479 | fields: [\r | |
1480 | 'id', 'name'\r | |
1481 | ],\r | |
1482 | \r | |
1483 | hasMany: {model: 'spec.OrderItem', name: 'orderItems'}\r | |
1484 | });\r | |
1485 | \r | |
1486 | // Created in global beforeEach\r | |
1487 | reader.destroy();\r | |
1488 | });\r | |
1489 | \r | |
1490 | afterEach(function() {\r | |
1491 | Ext.undefine('spec.User');\r | |
1492 | Ext.undefine('spec.Address');\r | |
1493 | Ext.undefine('spec.Order');\r | |
1494 | Ext.undefine('spec.OrderItem');\r | |
1495 | Ext.undefine('spec.Product');\r | |
1496 | });\r | |
1497 | \r | |
1498 | function createReader(config) {\r | |
1499 | return new Ext.data.reader.Json(Ext.apply({}, config, {\r | |
1500 | model: "spec.User",\r | |
1501 | rootProperty: "users"\r | |
1502 | }));\r | |
1503 | }\r | |
1504 | \r | |
1505 | it("should set implicitIncludes to true by default", function() {\r | |
1506 | reader = createReader();\r | |
1507 | \r | |
1508 | expect(reader.getImplicitIncludes()).toBe(true);\r | |
1509 | });\r | |
1510 | \r | |
1511 | it("should not parse includes if implicitIncludes is set to false", function() {\r | |
1512 | reader = createReader({implicitIncludes: false});\r | |
1513 | \r | |
1514 | var resultSet = reader.read(Ext.clone(nestedLoadData)),\r | |
1515 | user = resultSet.getRecords()[0],\r | |
1516 | orders = user.orders();\r | |
1517 | \r | |
1518 | expect(orders.getCount()).toBe(0);\r | |
1519 | });\r | |
1520 | \r | |
1521 | describe("when reading nested data", function() {\r | |
1522 | var resultSet, user, orders, orderItems, product, addresses;\r | |
1523 | \r | |
1524 | beforeEach(function() {\r | |
1525 | reader = createReader();\r | |
1526 | resultSet = reader.read(Ext.clone(nestedLoadData));\r | |
1527 | user = resultSet.getRecords()[0];\r | |
1528 | addresses = user.addresses();\r | |
1529 | orders = user.orders();\r | |
1530 | orderItems = orders.first().orderItems();\r | |
1531 | product = orderItems.first().getProduct();\r | |
1532 | });\r | |
1533 | \r | |
1534 | it("should populate first-order associations", function() {\r | |
1535 | expect(orders.getCount()).toBe(2);\r | |
1536 | expect(addresses.getCount()).toBe(1);\r | |
1537 | });\r | |
1538 | \r | |
1539 | it("should populate second-order associations", function() {\r | |
1540 | expect(orderItems.getCount()).toBe(2);\r | |
1541 | });\r | |
1542 | \r | |
1543 | it("should populate belongsTo associations", function() {\r | |
1544 | expect(product.get('name')).toBe('MacBook Pro');\r | |
1545 | });\r | |
1546 | \r | |
1547 | it("should ignore associations where the model isn't yet loaded", function() {\r | |
1548 | Ext.define('spec.Employee', {\r | |
1549 | extend: 'Ext.data.Model',\r | |
1550 | fields: ['id', 'name', {\r | |
1551 | name: 'projectId',\r | |
1552 | reference: 'Project'\r | |
1553 | }]\r | |
1554 | });\r | |
1555 | reader = new Ext.data.reader.Json({\r | |
1556 | model: 'spec.Employee'\r | |
1557 | });\r | |
1558 | expect(function() {\r | |
1559 | reader.read({\r | |
1560 | id: 1,\r | |
1561 | name: 'Foo'\r | |
1562 | });\r | |
1563 | }).not.toThrow();\r | |
1564 | });\r | |
1565 | });\r | |
1566 | });\r | |
1567 | \r | |
1568 | describe("reconfiguring via metadata", function() {\r | |
1569 | \r | |
1570 | it("should call onMetaChange", function() {\r | |
1571 | var meta = {some: 'meta data'};\r | |
1572 | \r | |
1573 | spyOn(reader, 'onMetaChange').andReturn();\r | |
1574 | spyOn(reader, 'getRoot').andReturn([]);\r | |
1575 | \r | |
1576 | reader.readRecords({metaData: meta});\r | |
1577 | expect(reader.onMetaChange).toHaveBeenCalledWith(meta);\r | |
1578 | });\r | |
1579 | \r | |
1580 | it("should accept a custom meta property", function(){\r | |
1581 | reader.setMetaProperty('foo.bar.baz');\r | |
1582 | reader.buildExtractors(true);\r | |
1583 | \r | |
1584 | spyOn(reader, 'onMetaChange').andReturn();\r | |
1585 | spyOn(reader, 'getRoot').andReturn([]);\r | |
1586 | \r | |
1587 | var o = {};\r | |
1588 | var meta = {\r | |
1589 | foo: {\r | |
1590 | bar: {\r | |
1591 | baz: o\r | |
1592 | }\r | |
1593 | }\r | |
1594 | };\r | |
1595 | reader.readRecords(meta);\r | |
1596 | expect(reader.onMetaChange).toHaveBeenCalledWith(o);\r | |
1597 | });\r | |
1598 | \r | |
1599 | });\r | |
1600 | \r | |
1601 | describe("reading xhr", function() {\r | |
1602 | var goodResponse = {\r | |
1603 | responseText: '{ "success": true, "users": [{"name": "Ben", "location": "Boston"}, {"name": "Mike", "location": "Redwood City"}, {"name": "Nick", "location": "Kansas City"}] }'\r | |
1604 | },\r | |
1605 | badResponse = {\r | |
1606 | responseText: 'this is not JSON'\r | |
1607 | };\r | |
1608 | \r | |
1609 | beforeEach(function() {\r | |
1610 | Ext.define('spec.User', {\r | |
1611 | extend: 'Ext.data.Model',\r | |
1612 | fields: ['name', 'location']\r | |
1613 | });\r | |
1614 | \r | |
1615 | // Created in global beforeEach\r | |
1616 | reader.destroy();\r | |
1617 | \r | |
1618 | reader = new Ext.data.reader.Json({\r | |
1619 | rootProperty: 'users',\r | |
1620 | model: 'spec.User',\r | |
1621 | listeners: {\r | |
1622 | exception: function (reader, response, errorMsg, eOpts) {\r | |
1623 | }\r | |
1624 | }\r | |
1625 | });\r | |
1626 | });\r | |
1627 | \r | |
1628 | afterEach(function() {\r | |
1629 | Ext.undefine('spec.User');\r | |
1630 | });\r | |
1631 | \r | |
1632 | function doRead(response) {\r | |
1633 | return reader.read(response);\r | |
1634 | }\r | |
1635 | \r | |
1636 | describe("if there is a responseText property", function() {\r | |
1637 | describe("if there is valid JSON", function() { \r | |
1638 | it("should be successful", function() {\r | |
1639 | expect(doRead(goodResponse).getSuccess()).toBe(true);\r | |
1640 | });\r | |
1641 | \r | |
1642 | it("should return the expected number of records", function() {\r | |
1643 | expect(doRead(goodResponse).getCount()).toBe(3);\r | |
1644 | });\r | |
1645 | \r | |
1646 | it("should not return a non-empty dataset", function() {\r | |
1647 | expect(doRead(goodResponse).getRecords().length).toBe(3);\r | |
1648 | });\r | |
1649 | });\r | |
1650 | \r | |
1651 | describe("if there is invalid JSON", function() {\r | |
1652 | beforeEach(function() {\r | |
1653 | spyOn(Ext, 'log');\r | |
1654 | spyOn(Ext.Logger, 'warn');\r | |
1655 | });\r | |
1656 | \r | |
1657 | it("should not be successful", function() {\r | |
1658 | expect(doRead(badResponse).getSuccess()).toBe(false);\r | |
1659 | });\r | |
1660 | \r | |
1661 | it("should not return any records", function() {\r | |
1662 | expect(doRead(badResponse).getTotal()).toBe(0);\r | |
1663 | });\r | |
1664 | \r | |
1665 | it("should return any empty dataset", function() {\r | |
1666 | expect(doRead(badResponse).getRecords().length).toBe(0);\r | |
1667 | });\r | |
1668 | \r | |
1669 | it("should fire the exception event", function() {\r | |
1670 | var spy = jasmine.createSpy();\r | |
1671 | reader.on('exception', spy);\r | |
1672 | doRead(badResponse);\r | |
1673 | expect(spy.callCount).toBe(1);\r | |
1674 | });\r | |
1675 | });\r | |
1676 | });\r | |
1677 | \r | |
1678 | describe("if there is no responseText property", function() { \r | |
1679 | it("should return an empty dataset", function() {\r | |
1680 | expect(doRead("something").getCount()).toBe(0);\r | |
1681 | });\r | |
1682 | });\r | |
1683 | });\r | |
1684 | });\r |