All files / addon-test-support/properties/collection legacy.js

100% Statements 43/43
83.33% Branches 10/12
100% Functions 13/13
100% Lines 40/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120              1x     871x   641x       181x   181x 175x     181x 145x 725x     181x   181x 181x       181x   181x       230x 230x   230x                         230x   230x       145x 54x       54x 108x     54x         725x 725x 30x           12x 12x 36x   12x       176x   176x               176x 176x   176x       333x 303x 122x   181x            
/* global Symbol */
import { A } from '@ember/array';
import { buildSelector, assign as mergeFunction } from '../../-private/helpers';
import { create } from '../../create';
import { count } from '../count';
import Ceibo from 'ceibo';
 
const arrayDelegateMethods = ['map', 'filter', 'mapBy', 'filterBy', 'forEach'];
 
function merge(target, ...objects) {
  objects.forEach((o) => mergeFunction(target, o));
 
  return target;
}
 
function generateEnumerable(node, definition, item, key) {
  let enumerable = merge({}, definition);
 
  if (typeof (enumerable.count) === 'undefined') {
    enumerable.count = count(item.itemScope);
  }
 
  if (typeof (enumerable.toArray) === 'undefined') {
    enumerable.toArray = toArrayMethod(node, item, key);
    arrayDelegateMethods.forEach((method) => delegateToArray(enumerable, method));
  }
 
  let collection = create(enumerable, { parent: node });
 
  Eif (typeof (Symbol) !== 'undefined' && Symbol.iterator) {
    collection[Symbol.iterator] = iteratorMethod;
  }
 
  // Change the key of the root node
  Ceibo.meta(collection).key = `${key}()`;
 
  return collection;
}
 
function generateItem(node, index, definition, key) {
  let filters = merge({}, { scope: definition.scope, at: index });
  let scope = buildSelector({}, definition.itemScope, filters);
 
  let tree = create(
    merge(
      {
        testContainer: definition.testContainer
      },
      definition.item,
      {
        scope,
        resetScope: definition.resetScope
      }
    ), { parent: node });
 
  // Change the key of the root node
  Ceibo.meta(tree).key = `${key}(${index})`;
 
  return tree;
}
 
function toArrayMethod(node, definition, key) {
  return function() {
    let array = A();
    let index;
    let count;
 
    for (index = 0, count = this.count; index < count; index++) {
      array.push(generateItem(node, index, definition, key));
    }
 
    return array;
  };
}
 
function delegateToArray(enumerable, method) {
  Eif (typeof (enumerable[method]) === 'undefined') {
    enumerable[method] = function(...args) {
      return this.toArray()[method](...args);
    };
  }
}
 
function iteratorMethod() {
  let i = 0;
  let items = this.toArray();
  let next = () => ({ done: i >= items.length, value: items[i++] });
 
  return { next };
}
 
export function collection(definition) {
  definition = mergeFunction({}, definition);
 
  let item = {
    scope: definition.scope,
    itemScope: definition.itemScope,
    resetScope: definition.resetScope,
    item: definition.item,
    testContainer: definition.testContainer
  };
 
  delete definition.item;
  delete definition.itemScope;
 
  return {
    isDescriptor: true,
 
    get(key) {
      return (index) => {
        if (typeof (index) === 'number') {
          return generateItem(this, index, item, key);
        } else {
          return generateEnumerable(this, definition, item, key);
        }
      };
    }
  };
}