ember-source 4.5.0-alpha.5 → 4.6.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +8 -3
  2. package/blueprints-js/-addon-import.js +48 -0
  3. package/blueprints-js/acceptance-test/mocha-files/tests/acceptance/__name__-test.js +24 -0
  4. package/blueprints-js/acceptance-test/mocha-rfc-232-files/tests/acceptance/__name__-test.js +13 -0
  5. package/blueprints-js/acceptance-test/qunit-files/tests/acceptance/__name__-test.js +12 -0
  6. package/blueprints-js/acceptance-test/qunit-rfc-232-files/tests/acceptance/__name__-test.js +13 -0
  7. package/blueprints-js/component/files/__root__/__path__/__name__.js +3 -0
  8. package/blueprints-js/component/files/__root__/__templatepath__/__templatename__.hbs +1 -0
  9. package/blueprints-js/component-addon/files/__root__/__path__/__name__.js +1 -0
  10. package/blueprints-js/component-class/files/__root__/__path__/__name__.js +3 -0
  11. package/blueprints-js/component-class-addon/files/__root__/__path__/__name__.js +1 -0
  12. package/blueprints-js/component-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +34 -0
  13. package/blueprints-js/component-test/mocha-files/__root__/__testType__/__path__/__test__.js +36 -0
  14. package/blueprints-js/component-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +38 -0
  15. package/blueprints-js/component-test/qunit-files/__root__/__testType__/__path__/__test__.js +31 -0
  16. package/blueprints-js/component-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +36 -0
  17. package/blueprints-js/controller/files/__root__/__path__/__name__.js +3 -0
  18. package/blueprints-js/controller-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +16 -0
  19. package/blueprints-js/controller-test/mocha-files/__root__/__testType__/__path__/__test__.js +18 -0
  20. package/blueprints-js/controller-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +13 -0
  21. package/blueprints-js/controller-test/qunit-files/__root__/__testType__/__path__/__test__.js +12 -0
  22. package/blueprints-js/controller-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +12 -0
  23. package/blueprints-js/helper/files/__root__/__collection__/__name__.js +5 -0
  24. package/blueprints-js/helper/mu-files/__root__/__collection__/__name__.js +7 -0
  25. package/blueprints-js/helper-addon/files/__root__/__path__/__name__.js +1 -0
  26. package/blueprints-js/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js +26 -0
  27. package/blueprints-js/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js +28 -0
  28. package/blueprints-js/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +18 -0
  29. package/blueprints-js/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js +15 -0
  30. package/blueprints-js/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +17 -0
  31. package/blueprints-js/initializer/files/__root__/initializers/__name__.js +5 -0
  32. package/blueprints-js/initializer-addon/files/__root__/__path__/__name__.js +1 -0
  33. package/blueprints-js/initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +28 -0
  34. package/blueprints-js/initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +31 -0
  35. package/blueprints-js/initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +25 -0
  36. package/blueprints-js/initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +37 -0
  37. package/blueprints-js/instance-initializer/files/__root__/instance-initializers/__name__.js +5 -0
  38. package/blueprints-js/instance-initializer-addon/files/__root__/__path__/__name__.js +1 -0
  39. package/blueprints-js/instance-initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +30 -0
  40. package/blueprints-js/instance-initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +32 -0
  41. package/blueprints-js/instance-initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +26 -0
  42. package/blueprints-js/instance-initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +39 -0
  43. package/blueprints-js/mixin/files/__root__/mixins/__name__.js +3 -0
  44. package/blueprints-js/mixin-test/mocha-files/__root__/__testType__/__name__-test.js +13 -0
  45. package/blueprints-js/mixin-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +13 -0
  46. package/blueprints-js/mixin-test/qunit-files/__root__/__testType__/__name__-test.js +12 -0
  47. package/blueprints-js/mixin-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +12 -0
  48. package/blueprints-js/route/files/__root__/__path__/__name__.js +9 -0
  49. package/blueprints-js/route/files/__root__/__templatepath__/__templatename__.hbs +2 -0
  50. package/blueprints-js/route-addon/files/__root__/__path__/__name__.js +1 -0
  51. package/blueprints-js/route-addon/files/__root__/__templatepath__/__templatename__.js +1 -0
  52. package/blueprints-js/route-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +15 -0
  53. package/blueprints-js/route-test/mocha-files/__root__/__testType__/__path__/__test__.js +17 -0
  54. package/blueprints-js/route-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +12 -0
  55. package/blueprints-js/route-test/qunit-files/__root__/__testType__/__path__/__test__.js +11 -0
  56. package/blueprints-js/route-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +11 -0
  57. package/blueprints-js/service/files/__root__/__path__/__name__.js +3 -0
  58. package/blueprints-js/service-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +16 -0
  59. package/blueprints-js/service-test/mocha-files/__root__/__testType__/__path__/__test__.js +18 -0
  60. package/blueprints-js/service-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +13 -0
  61. package/blueprints-js/service-test/qunit-files/__root__/__testType__/__path__/__test__.js +12 -0
  62. package/blueprints-js/service-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +12 -0
  63. package/blueprints-js/template/files/__root__/__path__/__name__.hbs +0 -0
  64. package/blueprints-js/test-framework-detector.js +60 -0
  65. package/blueprints-js/util/files/__root__/utils/__name__.js +3 -0
  66. package/blueprints-js/util-test/mocha-files/__root__/__testType__/__name__-test.js +11 -0
  67. package/blueprints-js/util-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +11 -0
  68. package/blueprints-js/util-test/qunit-files/__root__/__testType__/__name__-test.js +10 -0
  69. package/blueprints-js/util-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +10 -0
  70. package/build-metadata.json +3 -3
  71. package/dist/ember-template-compiler.js +2 -2
  72. package/dist/ember-template-compiler.map +1 -1
  73. package/dist/ember-testing.js +3 -8
  74. package/dist/ember-testing.map +1 -1
  75. package/dist/ember.debug.js +119 -419
  76. package/dist/ember.debug.map +1 -1
  77. package/dist/header/license.js +1 -1
  78. package/dist/packages/@ember/-internals/glimmer/index.js +21 -11
  79. package/dist/packages/@ember/-internals/metal/index.js +0 -3
  80. package/dist/packages/@ember/-internals/routing/lib/system/router.js +0 -4
  81. package/dist/packages/@ember/controller/lib/controller_mixin.js +8 -18
  82. package/dist/packages/@ember/object/lib/computed/computed_macros.js +6 -4
  83. package/dist/packages/@ember/object/lib/computed/reduce_computed_macros.js +73 -364
  84. package/dist/packages/ember/version.js +1 -1
  85. package/dist/packages/ember-testing/lib/adapters/adapter.js +2 -7
  86. package/docs/data.json +534 -528
  87. package/package.json +5 -4
@@ -4,7 +4,12 @@
4
4
  import { DEBUG } from '@glimmer/env';
5
5
  import { assert } from '@ember/debug';
6
6
  import { computed, autoComputed, get, isElementDescriptor } from '@ember/-internals/metal';
7
- import { compare, isArray, A as emberA, uniqBy as uniqByArray } from '@ember/-internals/runtime';
7
+ import { compare, A as emberA, uniqBy as uniqByArray } from '@ember/-internals/runtime';
8
+ import EmberArray from '@ember/-internals/runtime/lib/mixins/array';
9
+
10
+ function isNativeOrEmberArray(obj) {
11
+ return Array.isArray(obj) || EmberArray.detect(obj);
12
+ }
8
13
 
9
14
  function reduceMacro(dependentKey, callback, initialValue, name) {
10
15
  assert(`Dependent key passed to \`${name}\` computed macro shouldn't contain brace expanding pattern.`, !/[[\]{}]/g.test(dependentKey));
@@ -33,7 +38,7 @@ function arrayMacro(dependentKey, additionalDependentKeys, callback) {
33
38
  return computed(dependentKey, ...additionalDependentKeys, function () {
34
39
  let value = get(this, propertyName);
35
40
 
36
- if (isArray(value)) {
41
+ if (isNativeOrEmberArray(value)) {
37
42
  return emberA(callback.call(this, value));
38
43
  } else {
39
44
  return emberA();
@@ -203,94 +208,24 @@ export function min(dependentKey) {
203
208
  assert('You attempted to use @min as a decorator directly, but it requires a `dependentKey` parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
204
209
  return reduceMacro(dependentKey, (min, item) => Math.min(min, item), Infinity, 'min');
205
210
  }
206
- /**
207
- Returns an array mapped via the callback
208
-
209
- The callback method you provide should have the following signature:
210
- - `item` is the current item in the iteration.
211
- - `index` is the integer index of the current item in the iteration.
212
-
213
- ```javascript
214
- function mapCallback(item, index);
215
- ```
216
-
217
- Example:
218
-
219
- ```javascript
220
- import { set } from '@ember/object';
221
- import { map } from '@ember/object/computed';
222
-
223
- class Hamster {
224
- constructor(chores) {
225
- set(this, 'chores', chores);
226
- }
227
-
228
- @map('chores', function(chore, index) {
229
- return `${chore.toUpperCase()}!`;
230
- })
231
- excitingChores;
232
- });
233
-
234
- let hamster = new Hamster(['clean', 'write more unit tests']);
235
-
236
- hamster.excitingChores; // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
237
- ```
238
-
239
- You can optionally pass an array of additional dependent keys as the second
240
- parameter to the macro, if your map function relies on any external values:
241
-
242
- ```javascript
243
- import { set } from '@ember/object';
244
- import { map } from '@ember/object/computed';
245
-
246
- class Hamster {
247
- shouldUpperCase = false;
248
-
249
- constructor(chores) {
250
- set(this, 'chores', chores);
251
- }
252
-
253
- @map('chores', ['shouldUpperCase'], function(chore, index) {
254
- if (this.shouldUpperCase) {
255
- return `${chore.toUpperCase()}!`;
256
- } else {
257
- return `${chore}!`;
258
- }
259
- })
260
- excitingChores;
261
- }
262
-
263
- let hamster = new Hamster(['clean', 'write more unit tests']);
264
-
265
- hamster.excitingChores; // ['clean!', 'write more unit tests!']
266
-
267
- set(hamster, 'shouldUpperCase', true);
268
- hamster.excitingChores; // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
269
- ```
270
-
271
- @method map
272
- @for @ember/object/computed
273
- @static
274
- @param {String} dependentKey
275
- @param {Array} [additionalDependentKeys] optional array of additional
276
- dependent keys
277
- @param {Function} callback
278
- @return {ComputedProperty} an array mapped via the callback
279
- @public
280
- */
281
-
282
- export function map(dependentKey, additionalDependentKeys, callback) {
211
+ export function map(dependentKey, additionalDependentKeysOrCallback, callback) {
283
212
  assert('You attempted to use @map as a decorator directly, but it requires atleast `dependentKey` and `callback` parameters', !isElementDescriptor(Array.prototype.slice.call(arguments)));
213
+ assert('The final parameter provided to map must be a callback function', typeof callback === 'function' || callback === undefined && typeof additionalDependentKeysOrCallback === 'function');
214
+ assert('The second parameter provided to map must either be the callback or an array of additional dependent keys', Array.isArray(additionalDependentKeysOrCallback) || typeof additionalDependentKeysOrCallback === 'function');
215
+ let additionalDependentKeys;
284
216
 
285
- if (callback === undefined && typeof additionalDependentKeys === 'function') {
286
- callback = additionalDependentKeys;
217
+ if (typeof additionalDependentKeysOrCallback === 'function') {
218
+ callback = additionalDependentKeysOrCallback;
287
219
  additionalDependentKeys = [];
220
+ } else {
221
+ additionalDependentKeys = additionalDependentKeysOrCallback;
288
222
  }
289
223
 
290
- assert('The final parameter provided to map must be a callback function', typeof callback === 'function');
291
- assert('The second parameter provided to map must either be the callback or an array of additional dependent keys', Array.isArray(additionalDependentKeys));
224
+ const cCallback = callback;
225
+ assert('[BUG] Missing callback', cCallback);
292
226
  return arrayMacro(dependentKey, additionalDependentKeys, function (value) {
293
- return value.map(callback, this);
227
+ // This is so dumb...
228
+ return Array.isArray(value) ? value.map(cCallback, this) : value.map(cCallback, this);
294
229
  });
295
230
  }
296
231
  /**
@@ -348,124 +283,23 @@ export function mapBy(dependentKey, propertyKey) {
348
283
  assert(`Dependent key passed to \`mapBy\` computed macro shouldn't contain brace expanding pattern.`, !/[[\]{}]/g.test(dependentKey));
349
284
  return map(`${dependentKey}.@each.${propertyKey}`, item => get(item, propertyKey));
350
285
  }
351
- /**
352
- Filters the array by the callback.
353
-
354
- The callback method you provide should have the following signature:
355
- - `item` is the current item in the iteration.
356
- - `index` is the integer index of the current item in the iteration.
357
- - `array` is the dependant array itself.
358
-
359
- ```javascript
360
- function filterCallback(item, index, array);
361
- ```
362
-
363
- Example:
364
-
365
- ```javascript
366
- import { set } from '@ember/object';
367
- import { filter } from '@ember/object/computed';
368
-
369
- class Hamster {
370
- constructor(chores) {
371
- set(this, 'chores', chores);
372
- }
373
-
374
- @filter('chores', function(chore, index, array) {
375
- return !chore.done;
376
- })
377
- remainingChores;
378
- }
379
-
380
- let hamster = Hamster.create([
381
- { name: 'cook', done: true },
382
- { name: 'clean', done: true },
383
- { name: 'write more unit tests', done: false }
384
- ]);
385
-
386
- hamster.remainingChores; // [{name: 'write more unit tests', done: false}]
387
- ```
388
-
389
- You can also use `@each.property` in your dependent key, the callback will
390
- still use the underlying array:
391
-
392
- ```javascript
393
- import { set } from '@ember/object';
394
- import { filter } from '@ember/object/computed';
395
-
396
- class Hamster {
397
- constructor(chores) {
398
- set(this, 'chores', chores);
399
- }
400
-
401
- @filter('chores.@each.done', function(chore, index, array) {
402
- return !chore.done;
403
- })
404
- remainingChores;
405
- }
406
-
407
- let hamster = new Hamster([
408
- { name: 'cook', done: true },
409
- { name: 'clean', done: true },
410
- { name: 'write more unit tests', done: false }
411
- ]);
412
- hamster.remainingChores; // [{name: 'write more unit tests', done: false}]
413
-
414
- set(hamster.chores[2], 'done', true);
415
- hamster.remainingChores; // []
416
- ```
417
-
418
- Finally, you can optionally pass an array of additional dependent keys as the
419
- second parameter to the macro, if your filter function relies on any external
420
- values:
421
-
422
- ```javascript
423
- import { filter } from '@ember/object/computed';
424
-
425
- class Hamster {
426
- constructor(chores) {
427
- set(this, 'chores', chores);
428
- }
429
-
430
- doneKey = 'finished';
431
-
432
- @filter('chores', ['doneKey'], function(chore, index, array) {
433
- return !chore[this.doneKey];
434
- })
435
- remainingChores;
436
- }
437
-
438
- let hamster = new Hamster([
439
- { name: 'cook', finished: true },
440
- { name: 'clean', finished: true },
441
- { name: 'write more unit tests', finished: false }
442
- ]);
443
-
444
- hamster.remainingChores; // [{name: 'write more unit tests', finished: false}]
445
- ```
446
-
447
- @method filter
448
- @for @ember/object/computed
449
- @static
450
- @param {String} dependentKey
451
- @param {Array} [additionalDependentKeys] optional array of additional dependent keys
452
- @param {Function} callback
453
- @return {ComputedProperty} the filtered array
454
- @public
455
- */
456
-
457
- export function filter(dependentKey, additionalDependentKeys, callback) {
286
+ export function filter(dependentKey, additionalDependentKeysOrCallback, callback) {
458
287
  assert('You attempted to use @filter as a decorator directly, but it requires atleast `dependentKey` and `callback` parameters', !isElementDescriptor(Array.prototype.slice.call(arguments)));
288
+ assert('The final parameter provided to filter must be a callback function', typeof callback === 'function' || callback === undefined && typeof additionalDependentKeysOrCallback === 'function');
289
+ assert('The second parameter provided to filter must either be the callback or an array of additional dependent keys', Array.isArray(additionalDependentKeysOrCallback) || typeof additionalDependentKeysOrCallback === 'function');
290
+ let additionalDependentKeys;
459
291
 
460
- if (callback === undefined && typeof additionalDependentKeys === 'function') {
461
- callback = additionalDependentKeys;
292
+ if (typeof additionalDependentKeysOrCallback === 'function') {
293
+ callback = additionalDependentKeysOrCallback;
462
294
  additionalDependentKeys = [];
295
+ } else {
296
+ additionalDependentKeys = additionalDependentKeysOrCallback;
463
297
  }
464
298
 
465
- assert('The final parameter provided to filter must be a callback function', typeof callback === 'function');
466
- assert('The second parameter provided to filter must either be the callback or an array of additional dependent keys', Array.isArray(additionalDependentKeys));
299
+ const cCallback = callback;
467
300
  return arrayMacro(dependentKey, additionalDependentKeys, function (value) {
468
- return value.filter(callback, this);
301
+ // This is a really silly way to keep TS happy
302
+ return Array.isArray(value) ? value.filter(cCallback, this) : value.filter(cCallback, this);
469
303
  });
470
304
  }
471
305
  /**
@@ -554,15 +388,16 @@ export function filterBy(dependentKey, propertyKey, value) {
554
388
  @public
555
389
  */
556
390
 
557
- export function uniq(...args) {
391
+ export function uniq(dependentKey, ...additionalDependentKeys) {
558
392
  assert('You attempted to use @uniq/@union as a decorator directly, but it requires atleast one dependent key parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
393
+ let args = [dependentKey, ...additionalDependentKeys];
559
394
  return multiArrayMacro(args, function (dependentKeys) {
560
395
  let uniq = emberA();
561
396
  let seen = new Set();
562
397
  dependentKeys.forEach(dependentKey => {
563
398
  let value = get(this, dependentKey);
564
399
 
565
- if (isArray(value)) {
400
+ if (isNativeOrEmberArray(value)) {
566
401
  value.forEach(item => {
567
402
  if (!seen.has(item)) {
568
403
  seen.add(item);
@@ -617,7 +452,7 @@ export function uniqBy(dependentKey, propertyKey) {
617
452
  assert(`Dependent key passed to \`uniqBy\` computed macro shouldn't contain brace expanding pattern.`, !/[[\]{}]/g.test(dependentKey));
618
453
  return computed(`${dependentKey}.[]`, function () {
619
454
  let list = get(this, dependentKey);
620
- return isArray(list) ? uniqByArray(list, propertyKey) : emberA();
455
+ return isNativeOrEmberArray(list) ? uniqByArray(list, propertyKey) : emberA();
621
456
  }).readOnly();
622
457
  }
623
458
  /**
@@ -703,20 +538,22 @@ export let union = uniq;
703
538
  @public
704
539
  */
705
540
 
706
- export function intersect(...args) {
541
+ export function intersect(dependentKey, ...additionalDependentKeys) {
707
542
  assert('You attempted to use @intersect as a decorator directly, but it requires atleast one dependent key parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
543
+ let args = [dependentKey, ...additionalDependentKeys];
708
544
  return multiArrayMacro(args, function (dependentKeys) {
709
545
  let arrays = dependentKeys.map(dependentKey => {
710
546
  let array = get(this, dependentKey);
711
- return isArray(array) ? array : [];
547
+ return Array.isArray(array) ? array : [];
712
548
  });
713
- let results = arrays.pop().filter(candidate => {
714
- for (let i = 0; i < arrays.length; i++) {
549
+ let firstArray = arrays.pop();
550
+ assert('Attempted to apply multiArrayMacro for intersect without any dependentKeys', firstArray);
551
+ let results = firstArray.filter(candidate => {
552
+ for (let array of arrays) {
715
553
  let found = false;
716
- let array = arrays[i];
717
554
 
718
- for (let j = 0; j < array.length; j++) {
719
- if (array[j] === candidate) {
555
+ for (let item of array) {
556
+ if (item === candidate) {
720
557
  found = true;
721
558
  break;
722
559
  }
@@ -784,11 +621,11 @@ export function setDiff(setAProperty, setBProperty) {
784
621
  let setA = get(this, setAProperty);
785
622
  let setB = get(this, setBProperty);
786
623
 
787
- if (!isArray(setA)) {
624
+ if (!isNativeOrEmberArray(setA)) {
788
625
  return emberA();
789
626
  }
790
627
 
791
- if (!isArray(setB)) {
628
+ if (!isNativeOrEmberArray(setB)) {
792
629
  return emberA(setA);
793
630
  }
794
631
 
@@ -827,8 +664,9 @@ export function setDiff(setAProperty, setBProperty) {
827
664
  @public
828
665
  */
829
666
 
830
- export function collect(...dependentKeys) {
667
+ export function collect(dependentKey, ...additionalDependentKeys) {
831
668
  assert('You attempted to use @collect as a decorator directly, but it requires atleast one dependent key parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
669
+ let dependentKeys = [dependentKey, ...additionalDependentKeys];
832
670
  return multiArrayMacro(dependentKeys, function () {
833
671
  let res = dependentKeys.map(key => {
834
672
  let val = get(this, key);
@@ -837,172 +675,38 @@ export function collect(...dependentKeys) {
837
675
  return emberA(res);
838
676
  }, 'collect');
839
677
  }
840
- /**
841
- A computed property which returns a new array with all the properties from the
842
- first dependent array sorted based on a property or sort function. The sort
843
- macro can be used in two different ways:
844
-
845
- 1. By providing a sort callback function
846
- 2. By providing an array of keys to sort the array
847
-
848
- In the first form, the callback method you provide should have the following
849
- signature:
850
-
851
- ```javascript
852
- function sortCallback(itemA, itemB);
853
- ```
854
-
855
- - `itemA` the first item to compare.
856
- - `itemB` the second item to compare.
857
-
858
- This function should return negative number (e.g. `-1`) when `itemA` should
859
- come before `itemB`. It should return positive number (e.g. `1`) when `itemA`
860
- should come after `itemB`. If the `itemA` and `itemB` are equal this function
861
- should return `0`.
862
-
863
- Therefore, if this function is comparing some numeric values, simple `itemA -
864
- itemB` or `itemA.get( 'foo' ) - itemB.get( 'foo' )` can be used instead of
865
- series of `if`.
866
-
867
- Example:
868
-
869
- ```javascript
870
- import { set } from '@ember/object';
871
- import { sort } from '@ember/object/computed';
872
-
873
- class ToDoList {
874
- constructor(todos) {
875
- set(this, 'todos', todos);
876
- }
877
-
878
- // using a custom sort function
879
- @sort('todos', function(a, b){
880
- if (a.priority > b.priority) {
881
- return 1;
882
- } else if (a.priority < b.priority) {
883
- return -1;
884
- }
885
-
886
- return 0;
887
- })
888
- priorityTodos;
889
- }
890
-
891
- let todoList = new ToDoList([
892
- { name: 'Unit Test', priority: 2 },
893
- { name: 'Documentation', priority: 3 },
894
- { name: 'Release', priority: 1 }
895
- ]);
896
-
897
- todoList.priorityTodos; // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
898
- ```
899
-
900
- You can also optionally pass an array of additional dependent keys as the
901
- second parameter, if your sort function is dependent on additional values that
902
- could changes:
903
-
904
- ```js
905
- import EmberObject, { set } from '@ember/object';
906
- import { sort } from '@ember/object/computed';
907
-
908
- class ToDoList {
909
- sortKey = 'priority';
910
-
911
- constructor(todos) {
912
- set(this, 'todos', todos);
913
- }
914
-
915
- // using a custom sort function
916
- @sort('todos', ['sortKey'], function(a, b){
917
- if (a[this.sortKey] > b[this.sortKey]) {
918
- return 1;
919
- } else if (a[this.sortKey] < b[this.sortKey]) {
920
- return -1;
921
- }
922
-
923
- return 0;
924
- })
925
- sortedTodos;
926
- });
927
-
928
- let todoList = new ToDoList([
929
- { name: 'Unit Test', priority: 2 },
930
- { name: 'Documentation', priority: 3 },
931
- { name: 'Release', priority: 1 }
932
- ]);
933
-
934
- todoList.priorityTodos; // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
935
- ```
936
-
937
- In the second form, you should provide the key of the array of sort values as
938
- the second parameter:
939
-
940
- ```javascript
941
- import { set } from '@ember/object';
942
- import { sort } from '@ember/object/computed';
943
-
944
- class ToDoList {
945
- constructor(todos) {
946
- set(this, 'todos', todos);
947
- }
948
-
949
- // using standard ascending sort
950
- todosSorting = ['name'];
951
- @sort('todos', 'todosSorting') sortedTodos;
952
-
953
- // using descending sort
954
- todosSortingDesc = ['name:desc'];
955
- @sort('todos', 'todosSortingDesc') sortedTodosDesc;
956
- }
957
-
958
- let todoList = new ToDoList([
959
- { name: 'Unit Test', priority: 2 },
960
- { name: 'Documentation', priority: 3 },
961
- { name: 'Release', priority: 1 }
962
- ]);
963
-
964
- todoList.sortedTodos; // [{ name:'Documentation', priority:3 }, { name:'Release', priority:1 }, { name:'Unit Test', priority:2 }]
965
- todoList.sortedTodosDesc; // [{ name:'Unit Test', priority:2 }, { name:'Release', priority:1 }, { name:'Documentation', priority:3 }]
966
- ```
967
-
968
- @method sort
969
- @for @ember/object/computed
970
- @static
971
- @param {String} itemsKey
972
- @param {String|Function|Array} sortDefinitionOrDependentKeys The key of the sort definition (an array of sort properties),
973
- the sort function, or an array of additional dependent keys
974
- @param {Function?} sortDefinition the sort function (when used with additional dependent keys)
975
- @return {ComputedProperty} computes a new sorted array based on the sort
976
- property array or callback function
977
- @public
978
- */
979
-
980
- export function sort(itemsKey, additionalDependentKeys, sortDefinition) {
678
+ export function sort(itemsKey, additionalDependentKeysOrDefinition, sortDefinition) {
981
679
  assert('You attempted to use @sort as a decorator directly, but it requires atleast an `itemsKey` parameter', !isElementDescriptor(Array.prototype.slice.call(arguments)));
982
680
 
983
681
  if (DEBUG) {
984
682
  let argumentsValid = false;
985
683
 
986
684
  if (arguments.length === 2) {
987
- argumentsValid = typeof itemsKey === 'string' && (typeof additionalDependentKeys === 'string' || typeof additionalDependentKeys === 'function');
685
+ argumentsValid = typeof itemsKey === 'string' && (typeof additionalDependentKeysOrDefinition === 'string' || typeof additionalDependentKeysOrDefinition === 'function');
988
686
  }
989
687
 
990
688
  if (arguments.length === 3) {
991
- argumentsValid = typeof itemsKey === 'string' && Array.isArray(additionalDependentKeys) && typeof sortDefinition === 'function';
689
+ argumentsValid = typeof itemsKey === 'string' && Array.isArray(additionalDependentKeysOrDefinition) && typeof sortDefinition === 'function';
992
690
  }
993
691
 
994
692
  assert('The `sort` computed macro can either be used with an array of sort properties or with a sort function. If used with an array of sort properties, it must receive exactly two arguments: the key of the array to sort, and the key of the array of sort properties. If used with a sort function, it may receive up to three arguments: the key of the array to sort, an optional additional array of dependent keys for the computed property, and the sort function.', argumentsValid);
995
693
  }
996
694
 
997
- if (sortDefinition === undefined && !Array.isArray(additionalDependentKeys)) {
998
- sortDefinition = additionalDependentKeys;
695
+ let additionalDependentKeys;
696
+ let sortDefinitionOrString;
697
+
698
+ if (Array.isArray(additionalDependentKeysOrDefinition)) {
699
+ additionalDependentKeys = additionalDependentKeysOrDefinition;
700
+ sortDefinitionOrString = sortDefinition;
701
+ } else {
999
702
  additionalDependentKeys = [];
703
+ sortDefinitionOrString = additionalDependentKeysOrDefinition;
1000
704
  }
1001
705
 
1002
- if (typeof sortDefinition === 'function') {
1003
- return customSort(itemsKey, additionalDependentKeys, sortDefinition);
706
+ if (typeof sortDefinitionOrString === 'function') {
707
+ return customSort(itemsKey, additionalDependentKeys, sortDefinitionOrString);
1004
708
  } else {
1005
- return propertySort(itemsKey, sortDefinition);
709
+ return propertySort(itemsKey, sortDefinitionOrString);
1006
710
  }
1007
711
  }
1008
712
 
@@ -1017,12 +721,14 @@ function customSort(itemsKey, additionalDependentKeys, comparator) {
1017
721
  function propertySort(itemsKey, sortPropertiesKey) {
1018
722
  let cp = autoComputed(function (key) {
1019
723
  let sortProperties = get(this, sortPropertiesKey);
1020
- assert(`The sort definition for '${key}' on ${this} must be a function or an array of strings`, isArray(sortProperties) && sortProperties.every(s => typeof s === 'string'));
724
+ assert(`The sort definition for '${key}' on ${this} must be a function or an array of strings`, function (arr) {
725
+ return isNativeOrEmberArray(arr) && arr.every(s => typeof s === 'string');
726
+ }(sortProperties));
1021
727
  let itemsKeyIsAtThis = itemsKey === '@this';
1022
728
  let normalizedSortProperties = normalizeSortProperties(sortProperties);
1023
729
  let items = itemsKeyIsAtThis ? this : get(this, itemsKey);
1024
730
 
1025
- if (!isArray(items)) {
731
+ if (!isNativeOrEmberArray(items)) {
1026
732
  return emberA();
1027
733
  }
1028
734
 
@@ -1036,17 +742,20 @@ function propertySort(itemsKey, sortPropertiesKey) {
1036
742
  }
1037
743
 
1038
744
  function normalizeSortProperties(sortProperties) {
1039
- return sortProperties.map(p => {
745
+ let callback = p => {
1040
746
  let [prop, direction] = p.split(':');
1041
- direction = direction || 'asc';
747
+ direction = direction || 'asc'; // SAFETY: There will always be at least one value returned by split
748
+
1042
749
  return [prop, direction];
1043
- });
750
+ }; // This nonsense is necessary since technically the two map implementations diverge.
751
+
752
+
753
+ return Array.isArray(sortProperties) ? sortProperties.map(callback) : sortProperties.map(callback);
1044
754
  }
1045
755
 
1046
756
  function sortByNormalizedSortProperties(items, normalizedSortProperties) {
1047
757
  return emberA(items.slice().sort((itemA, itemB) => {
1048
- for (let i = 0; i < normalizedSortProperties.length; i++) {
1049
- let [prop, direction] = normalizedSortProperties[i];
758
+ for (let [prop, direction] of normalizedSortProperties) {
1050
759
  let result = compare(get(itemA, prop), get(itemB, prop));
1051
760
 
1052
761
  if (result !== 0) {
@@ -1 +1 @@
1
- export default "4.5.0-alpha.5";
1
+ export default "4.6.0-alpha.2";
@@ -1,8 +1,4 @@
1
1
  import { Object as EmberObject } from '@ember/-internals/runtime';
2
-
3
- function K() {
4
- return this;
5
- }
6
2
  /**
7
3
  @module @ember/test
8
4
  */
@@ -15,7 +11,6 @@ function K() {
15
11
  @public
16
12
  */
17
13
 
18
-
19
14
  export default EmberObject.extend({
20
15
  /**
21
16
  This callback will be called whenever an async operation is about to start.
@@ -24,14 +19,14 @@ export default EmberObject.extend({
24
19
  @public
25
20
  @method asyncStart
26
21
  */
27
- asyncStart: K,
22
+ asyncStart() {},
28
23
 
29
24
  /**
30
25
  This callback will be called whenever an async operation has completed.
31
26
  @public
32
27
  @method asyncEnd
33
28
  */
34
- asyncEnd: K,
29
+ asyncEnd() {},
35
30
 
36
31
  /**
37
32
  Override this method with your testing framework's false assertion.