Example #1
0
QUnit.test('`objectAt` returns correct object', function() {
  let arr = ['first', 'second', 'third', 'fourth'];
  equal(objectAt(arr, 2), 'third');
  equal(objectAt(arr, 4), undefined);
});

testBoth('should be clear caches for computed properties that have dependent keys on arrays that are changed after object initialization', function(get, set) {
  var obj = EmberObject.extend({
    init() {
      this._super(...arguments);
      set(this, 'resources', emberA());
    },

    common: computed('*****@*****.**', function() {
      return get(objectAt(get(this, 'resources'), 0), 'common');
    })
  }).create();

  get(obj, 'resources').pushObject(EmberObject.create({ common: 'HI!' }));
  equal('HI!', get(obj, 'common'));

  set(objectAt(get(obj, 'resources'), 0), 'common', 'BYE!');
  equal('BYE!', get(obj, 'common'));
});

testBoth('observers that contain @each in the path should fire only once the first time they are accessed', function(get, set) {
  var count = 0;

  var obj = EmberObject.extend({
    init() {
      this._super(...arguments);
Example #2
0
    didCount++;
  });
}

testBoth('unwatching a computed property - regular get/set', function(get, set) {

  var obj = {};
  defineProperty(obj, 'foo', computed(function(keyName, value) {
    if (value !== undefined) {
      this.__foo = value;
    }

    return this.__foo;
  }));
  addListeners(obj, 'foo');

  watch(obj, 'foo');
  set(obj, 'foo', 'bar');
  equal(willCount, 1, 'should have invoked willCount');
  equal(didCount, 1, 'should have invoked didCount');

  unwatch(obj, 'foo');
  willCount = didCount = 0;
  set(obj, 'foo', 'BAZ');
  equal(willCount, 0, 'should NOT have invoked willCount');
  equal(didCount, 0, 'should NOT have invoked didCount');
});


testBoth('unwatching a regular property - regular get/set', function(get, set) {
Example #3
0
import { observer } from 'ember-metal/mixin';
import run from 'ember-metal/run_loop';
import { testBoth } from 'ember-metal/tests/props_helper';
import EmberObject from 'ember-runtime/system/object';

QUnit.module('EmberObject observer');

testBoth('observer on class', function(get, set) {
  var MyClass = EmberObject.extend({

    count: 0,

    foo: observer('bar', function() {
      set(this, 'count', get(this, 'count') + 1);
    })

  });

  var obj = new MyClass();
  equal(get(obj, 'count'), 0, 'should not invoke observer immediately');

  set(obj, 'bar', 'BAZ');
  equal(get(obj, 'count'), 1, 'should invoke observer after change');
});

testBoth('observer on subclass', function(get, set) {
  var MyClass = EmberObject.extend({

    count: 0,

    foo: observer('bar', function() {
import { defineProperty } from 'ember-metal/properties';
import EmberObject from 'ember-runtime/system/object';
import { testBoth } from 'ember-metal/tests/props_helper';

QUnit.module('CP macros');

testBoth('Ember.computed.empty', function (get, set) {
  var obj = EmberObject.extend({
    bestLannister: null,
    lannisters: null,

    bestLannisterUnspecified: empty('bestLannister'),
    noLannistersKnown: empty('lannisters')
  }).create({
    lannisters: Ember.A([])
  });

  equal(get(obj, 'bestLannisterUnspecified'), true, 'bestLannister initially empty');
  equal(get(obj, 'noLannistersKnown'), true, 'lannisters initially empty');

  get(obj, 'lannisters').pushObject('Tyrion');
  set(obj, 'bestLannister', 'Tyrion');

  equal(get(obj, 'bestLannisterUnspecified'), false, 'empty respects strings');
  equal(get(obj, 'noLannistersKnown'), false, 'empty respects array mutations');
});

testBoth('Ember.computed.notEmpty', function(get, set) {
  var obj = EmberObject.extend({
    bestLannister: null,
    lannisters: null,
Example #5
0
    objB.__foo = 'FOO'; // make a copy;
  },

  teardown() {
    objA = objB = null;
  }
});

testBoth('using get() and set()', function(get, set) {
  equal(get(objA, 'foo'), 'FOO', 'should get FOO from A');
  equal(get(objB, 'foo'), 'FOO', 'should get FOO from B');

  set(objA, 'foo', 'BIFF');
  equal(get(objA, 'foo'), 'computed BIFF', 'should change A');
  equal(get(objB, 'foo'), 'FOO', 'should NOT change B');

  set(objB, 'foo', 'bar');
  equal(get(objB, 'foo'), 'computed bar', 'should change B');
  equal(get(objA, 'foo'), 'computed BIFF', 'should NOT change A');

  set(objA, 'foo', 'BAZ');
  equal(get(objA, 'foo'), 'computed BAZ', 'should change A');
  equal(get(objB, 'foo'), 'computed bar', 'should NOT change B');
});

QUnit.module('redefining computed property to normal', {
  setup() {
    objA = { __foo: 'FOO' };
    defineProperty(objA, 'foo', computed({
      get: function(key) {
        return this['__'+key];
      },
import { testBoth } from 'ember-metal/tests/props_helper';
import { A as emberA } from 'ember-runtime/system/native_array';
import isEnabled from 'ember-metal/features';

QUnit.module('CP macros');

testBoth('Ember.computed.empty', function (get, set) {
  let obj = EmberObject.extend({
    bestLannister: null,
    lannisters: null,

    bestLannisterUnspecified: empty('bestLannister'),
    noLannistersKnown: empty('lannisters')
  }).create({
    lannisters: emberA()
  });

  equal(get(obj, 'bestLannisterUnspecified'), true, 'bestLannister initially empty');
  equal(get(obj, 'noLannistersKnown'), true, 'lannisters initially empty');

  get(obj, 'lannisters').pushObject('Tyrion');
  set(obj, 'bestLannister', 'Tyrion');

  equal(get(obj, 'bestLannisterUnspecified'), false, 'empty respects strings');
  equal(get(obj, 'noLannistersKnown'), false, 'empty respects array mutations');
});

testBoth('Ember.computed.notEmpty', function(get, set) {
  let obj = EmberObject.extend({
    bestLannister: null,
    lannisters: null,
  mixin,
  Mixin
} from 'ember-metal/mixin';
import { isWatching } from 'ember-metal/watching';

QUnit.module('Mixin observer');

testBoth('global observer helper', function(get, set) {

  var MyMixin = Mixin.create({

    count: 0,

    foo: observer('bar', function() {
      set(this, 'count', get(this, 'count')+1);
    })

  });

  var obj = mixin({}, MyMixin);
  equal(get(obj, 'count'), 0, 'should not invoke observer immediately');

  set(obj, 'bar', 'BAZ');
  equal(get(obj, 'count'), 1, 'should invoke observer after change');
});

testBoth('global observer helper takes multiple params', function(get, set) {

  var MyMixin = Mixin.create({

    count: 0,
Example #8
0
    objB.__foo = 'FOO'; // make a copy;
  },

  teardown() {
    objA = objB = null;
  }
});

testBoth('using get() and set()', function(get, set) {
  equal(get(objA, 'foo'), 'FOO', 'should get FOO from A');
  equal(get(objB, 'foo'), 'FOO', 'should get FOO from B');

  set(objA, 'foo', 'BIFF');
  equal(get(objA, 'foo'), 'computed BIFF', 'should change A');
  equal(get(objB, 'foo'), 'FOO', 'should NOT change B');

  set(objB, 'foo', 'bar');
  equal(get(objB, 'foo'), 'computed bar', 'should change B');
  equal(get(objA, 'foo'), 'computed BIFF', 'should NOT change A');

  set(objA, 'foo', 'BAZ');
  equal(get(objA, 'foo'), 'computed BAZ', 'should change A');
  equal(get(objB, 'foo'), 'computed bar', 'should NOT change B');
});

QUnit.module('redefining computed property to normal', {
  setup() {
    objA = { __foo: 'FOO' };
    defineProperty(objA, 'foo', computed({
      get: function(key) {
        return this['__' + key];
      },
Example #9
0
  addListener(obj, keyPath + ':change', function() {
    didCount++;
    didKeys.push(keyPath);
  });
}

testBoth('watching a computed property', function(get, set) {
  let obj = {};
  defineProperty(obj, 'foo', computed({
    get() {
      return this.__foo;
    },
    set(keyName, value) {
      if (value !== undefined) {
        this.__foo = value;
      }
      return this.__foo;
    }
  }));
  addListeners(obj, 'foo');

  watch(obj, 'foo');
  set(obj, 'foo', 'bar');
  equal(willCount, 1, 'should have invoked willCount');
  equal(didCount, 1, 'should have invoked didCount');
});

testBoth('watching a regular defined property', function(get, set) {
  let obj = { foo: 'baz' };
  addListeners(obj, 'foo');

  watch(obj, 'foo');
Example #10
0
testBoth('calling setProperties completes safely despite exceptions', function(get, set) {
  var exc = new Error("Something unexpected happened!");
  var obj = EmberObject.createWithMixins({
    firstName: "Steve",
    lastName: "Jobs",
    companyName: computed(function(key, value) {
      if (value !== undefined) {
        throw exc;
      }
      return "Apple, Inc.";
    })
  });

  var firstNameChangedCount = 0;

  addObserver(obj, 'firstName', function() { firstNameChangedCount++; });

  try {
    obj.setProperties({
      firstName: 'Tim',
      lastName: 'Cook',
      companyName: 'Fruit Co., Inc.'
    });
  } catch(err) {
    if (err !== exc) {
      throw err;
    }
  }

  equal(firstNameChangedCount, 1, 'firstName should have fired once');
});
Example #11
0
testBoth('bindings should not sync twice in a single run loop', function(get, set) {
  let a, b, setValue;
  let setCalled = 0;
  let getCalled = 0;

  run(() => {
    a = {};

    defineProperty(a, 'foo', computed({
      get(key) {
        getCalled++;
        return setValue;
      },
      set(key, value) {
        setCalled++;
        propertyWillChange(this, key);
        setValue = value;
        propertyDidChange(this, key);
        return value;
      }
    }).volatile());

    b = {
      a: a
    };

    expectDeprecation(() => bind(b, 'foo', 'a.foo'), /`Ember.Binding` is deprecated/);
  });

  // reset after initial binding synchronization
  getCalled = 0;

  run(() => {
    set(a, 'foo', 'trollface');
  });

  equal(get(b, 'foo'), 'trollface', 'the binding should sync');
  equal(setCalled, 1, 'Set should only be called once');
  equal(getCalled, 1, 'Get should only be called once');
});
});

QUnit.test('updates when array is modified', function() {
  obj.get('array').pushObject(1);

  equal(obj.get('total'), 7, 'recomputed when elements are added');

  obj.get('array').popObject();

  equal(obj.get('total'), 6, 'recomputes when elements are removed');
});

QUnit.module('collect');

testBoth('works', function(get, set) {
  var obj = { one: 'foo', two: 'bar', three: null };
  defineProperty(obj, 'all', collect('one', 'two', 'three', 'four'));

  deepEqual(get(obj, 'all'), ['foo', 'bar', null, null], 'have all of them');

  set(obj, 'four', true);

  deepEqual(get(obj, 'all'), ['foo', 'bar', null, true], 'have all of them');

  var a = [];
  set(obj, 'one', 0);
  set(obj, 'three', a);

  deepEqual(get(obj, 'all'), [0, 'bar', a, true], 'have all of them');
});
Example #13
0
testBoth("bindings should not sync twice in a single run loop", function(get, set) {
  var a, b, setValue;
  var setCalled=0;
  var getCalled=0;

  run(function() {
    a = {};

    defineProperty(a, 'foo', computed({
      get: function(key) {
        getCalled++;
        return setValue;
      },
      set: function(key, value) {
        setCalled++;
        setValue = value;
        return value;
      }
    }).volatile());

    b = {
      a: a
    };
    bind(b, 'foo', 'a.foo');
  });

  // reset after initial binding synchronization
  getCalled = 0;

  run(function() {
    set(a, 'foo', 'trollface');
  });

  equal(get(b, 'foo'), "trollface", "the binding should sync");
  equal(setCalled, 1, "Set should only be called once");
  equal(getCalled, 1, "Get should only be called once");
});
Example #14
0
  beginPropertyChanges,
  endPropertyChanges
} from 'ember-metal/property_events';
import { testBoth } from 'ember-metal/tests/props_helper';
import EmberObject from 'ember-runtime/system/object';

QUnit.module('ember-runtime/system/object/destroy_test');

testBoth('should schedule objects to be destroyed at the end of the run loop', function(get, set) {
  var obj = EmberObject.create();
  var meta;

  run(function() {
    obj.destroy();
    meta = obj['__ember_meta__'];
    ok(meta, 'meta is not destroyed immediately');
    ok(get(obj, 'isDestroying'), 'object is marked as destroying immediately');
    ok(!get(obj, 'isDestroyed'), 'object is not destroyed immediately');
  });

  meta = obj['__ember_meta__'];
  ok(!meta, 'meta is destroyed after run loop finishes');
  ok(get(obj, 'isDestroyed'), 'object is destroyed after run loop finishes');
});

if (isEnabled('mandatory-setter')) {
  // MANDATORY_SETTER moves value to meta.values
  // a destroyed object removes meta but leaves the accessor
  // that looks it up
  QUnit.test('should raise an exception when modifying watched properties on a destroyed object', function() {
    var obj = EmberObject.extend({
      fooDidChange: observer('foo', function() { })
Example #15
0
  beginPropertyChanges,
  endPropertyChanges
} from 'ember-metal/property_events';
import { testBoth } from 'ember-metal/tests/props_helper';
import EmberObject from 'ember-runtime/system/object';
import { peekMeta } from 'ember-metal/meta';
QUnit.module('ember-runtime/system/object/destroy_test');

testBoth('should schedule objects to be destroyed at the end of the run loop', function(get, set) {
  let obj = EmberObject.create();
  let meta;

  run(() => {
    obj.destroy();
    meta = peekMeta(obj);
    ok(meta, 'meta is not destroyed immediately');
    ok(get(obj, 'isDestroying'), 'object is marked as destroying immediately');
    ok(!get(obj, 'isDestroyed'), 'object is not destroyed immediately');
  });

  meta = peekMeta(obj);
  ok(!meta, 'meta is destroyed after run loop finishes');
  ok(get(obj, 'isDestroyed'), 'object is destroyed after run loop finishes');
});

if (isEnabled('mandatory-setter')) {
  // MANDATORY_SETTER moves value to meta.values
  // a destroyed object removes meta but leaves the accessor
  // that looks it up
  QUnit.test('should raise an exception when modifying watched properties on a destroyed object', function() {
    let obj = EmberObject.extend({
      fooDidChange: observer('foo', function() { })
Example #16
0
  };

  get(obj, 'id');

  equal(count, 1);
});

testBoth('should call unknownProperty on watched values if the value is undefined', function(get, set) {
  var obj = {
    count: 0,
    unknownProperty(key) {
      equal(key, 'foo', 'should pass key');
      this.count++;
      return 'FOO';
    }
  };

  var count = 0;
  addObserver(obj, 'foo', function() {
    count++;
  });

  equal(get(obj, 'foo'), 'FOO', 'should return value from unknown');
});

QUnit.test('warn on attemps to call get with no arguments', function() {
  expectAssertion(function() {
    get('aProperty');
  }, /Get must be called with two arguments;/i);
});
Example #17
0
import { testBoth } from "ember-metal/tests/props_helper";

QUnit.module('Function.prototype.observes() helper');

testBoth('global observer helper takes multiple params', function(get, set) {

  if (Ember.EXTEND_PROTOTYPES === false) {
    ok("undefined" === typeof Function.prototype.observes, 'Function.prototype helper disabled');
    return ;
  }

  var MyMixin = Ember.Mixin.create({

    count: 0,

    foo: function() {
      set(this, 'count', get(this, 'count')+1);
    }.observes('bar', 'baz')

  });

  var obj = Ember.mixin({}, MyMixin);
  equal(get(obj, 'count'), 0, 'should not invoke observer immediately');

  set(obj, 'bar', "BAZ");
  set(obj, 'baz', "BAZ");
  equal(get(obj, 'count'), 2, 'should invoke observer after change');
});

QUnit.module('Function.prototype.on() helper');

testBoth('sets up an event listener, and can trigger the function on multiple events', function(get, set) {
Example #18
0
  endPropertyChanges,
  changeProperties
} from 'ember-metal/property_events';

// ..........................................................
// ADD OBSERVER
//

QUnit.module('addObserver');

testBoth('observer should fire when property is modified', function(get, set) {
  var obj = {};
  var count = 0;

  addObserver(obj, 'foo', function() {
    equal(get(obj, 'foo'), 'bar', 'should invoke AFTER value changed');
    count++;
  });

  set(obj, 'foo', 'bar');
  equal(count, 1, 'should have invoked observer');
});

testBoth('observer should fire when dependent property is modified', function(get, set) {
  var obj = { bar: 'bar' };
  defineProperty(obj, 'foo', computed(function() {
    return get(this, 'bar').toUpperCase();
  }).property('bar'));

  get(obj, 'foo');

  var count = 0;
Example #19
0
QUnit.module("Ember.Binding", {
  setup() {
    originalLookup = Ember.lookup;
    Ember.lookup = lookup = {};
  },
  teardown() {
    lookup = null;
    Ember.lookup = originalLookup;
  }
});

testBoth('Connecting a binding between two properties', function(get, set) {
  var a = { foo: 'FOO', bar: 'BAR' };

  // a.bar -> a.foo
  var binding = new Binding('foo', 'bar');

  performTest(binding, a, a, get, set);
});

testBoth('Connecting a binding between two objects', function(get, set) {
  var b = { bar: 'BAR' };
  var a = { foo: 'FOO', b: b };

  // b.bar -> a.foo
  var binding = new Binding('foo', 'b.bar');

  performTest(binding, a, b, get, set);
});

testBoth('Connecting a binding to path', function(get, set) {
Example #20
0
import { computed } from 'ember-metal/computed';
import { isWatching } from 'ember-metal/watching';
import { testBoth } from 'ember-metal/tests/props_helper';
import ObjectProxy from 'ember-runtime/system/object_proxy';

QUnit.module('ObjectProxy');

testBoth('should not proxy properties passed to create', function (get, set) {
  let Proxy = ObjectProxy.extend({
    cp: computed({
      get(key) { return this._cp; },
      set(key, value) {
        this._cp = value;
        return this._cp;
      }
    })
  });
  let proxy = Proxy.create({
    prop: 'Foo',
    cp: 'Bar'
  });

  equal(get(proxy, 'prop'), 'Foo', 'should not have tried to proxy set');
  equal(proxy._cp, 'Bar', 'should use CP setter');
});

testBoth('should proxy properties to content', function(get, set) {
  let content = {
        firstName: 'Tom',
        lastName: 'Dale',
        unknownProperty(key) { return key + ' unknown';}
      };
Example #21
0
} from "ember-metal/computed_macros";
import EmberObject from "ember-runtime/system/object";
import { testBoth } from "ember-metal/tests/props_helper";

QUnit.module('CP macros');

testBoth('Ember.computed.empty', function (get, set) {
  var obj = EmberObject.extend({
    bestLannister: null,
    lannisters: null,

    bestLannisterUnspecified: empty('bestLannister'),
    noLannistersKnown: empty('lannisters')
  }).create({
    lannisters: Ember.A([])
  });

  equal(get(obj, 'bestLannisterUnspecified'), true, "bestLannister initially empty");
  equal(get(obj, 'noLannistersKnown'), true, "lannisters initially empty");

  get(obj, 'lannisters').pushObject('Tyrion');
  set(obj, 'bestLannister', 'Tyrion');

  equal(get(obj, 'bestLannisterUnspecified'), false, "empty respects strings");
  equal(get(obj, 'noLannistersKnown'), false, "empty respects array mutations");
});

testBoth('Ember.computed.notEmpty', function(get, set) {
  var obj = EmberObject.extend({
    bestLannister: null,
    lannisters: null,