Skip to content

Commit

Permalink
Get Array tests running again and fix duplicate notifications.
Browse files Browse the repository at this point in the history
  • Loading branch information
wagenet committed May 3, 2012
1 parent 74f574e commit 09d7ad6
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 163 deletions.
3 changes: 2 additions & 1 deletion packages/ember-runtime/lib/system/array_proxy.js
Expand Up @@ -125,7 +125,8 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
length: Ember.computed(function() {
var content = get(this, 'content');
return content ? get(content, 'length') : 0;
}).property('content.length').cacheable(),
// No dependencies since Enumerable notifies length of change
}).property().cacheable(),

/** @private (nodoc) */
replace: function(idx, amt, objects) {
Expand Down
17 changes: 14 additions & 3 deletions packages/ember-runtime/tests/suites/enumerable.js
Expand Up @@ -23,8 +23,9 @@ var ObserverClass = Ember.Object.extend({
later analysis.
*/
propertyDidChange: function(target, key, value) {
this._keys[key] = true;
this._values[key] = value;
if (this._keys[key] === undefined) { this._keys[key] = 0; }
this._keys[key]++;
this._values[key] = value;
},

/**
Expand All @@ -50,7 +51,7 @@ var ObserverClass = Ember.Object.extend({
@returns {Object} receiver
*/
observe: function(obj) {
if (Ember.Observer && Ember.Observer.detect(obj)) {
if (obj.addObserver) {
var keys = Array.prototype.slice.call(arguments, 1),
loc = keys.length;
while(--loc>=0) obj.addObserver(keys[loc], this, 'propertyDidChange');
Expand Down Expand Up @@ -79,6 +80,16 @@ var ObserverClass = Ember.Object.extend({
else return true;
},

/**
Returns times the observer as invoked.
@param {String} key
Key to check
*/
timesCalled: function(key) {
return this._keys[key] || 0;
},

/**
begins acting as an enumerable observer.
*/
Expand Down
58 changes: 58 additions & 0 deletions packages/ember-runtime/tests/suites/mutable_array/addObject.js
@@ -0,0 +1,58 @@
// ==========================================================================
// Project: Ember Runtime
// Copyright: ©2011 Strobe Inc. and contributors.
// License: Licensed under MIT license (see license.js)
// ==========================================================================

require('ember-runtime/~tests/suites/mutable_array');

var suite = Ember.MutableArrayTests;

suite.module('addObject');

suite.test("should return receiver", function() {
var before, obj;
before = this.newFixture(3);
obj = this.newObject(before);
equal(obj.addObject(before[1]), obj, 'should return receiver');
});

suite.test("[A,B].addObject(C) => [A,B,C] + notify", function() {
var obj, before, after, observer, item;

before = this.newFixture(2);
item = this.newFixture(1)[0];
after = [before[0], before[1], item];
obj = this.newObject(before);
observer = this.newObserver(obj, '@each', 'length');

obj.addObject(item);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
}
});

suite.test("[A,B,C].addObject(A) => [A,B,C] + NO notify", function() {
var obj, before, after, observer, item;

before = this.newFixture(3);
after = before;
item = before[0];
obj = this.newObject(before);
observer = this.newObserver(obj, '@each', 'length');

obj.addObject(item); // note: item in set

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('@each'), false, 'should NOT have notified @each');
equal(observer.validate('length'), false, 'should NOT have notified length');
}
});
16 changes: 6 additions & 10 deletions packages/ember-runtime/tests/suites/mutable_array/clear.js
Expand Up @@ -17,17 +17,15 @@ suite.test("[].clear() => [] + notify", function () {
before = [];
after = [];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

equal(obj.clear(), obj, 'return self');

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.validate('@each'), false, 'should NOT have notified @each once');
equal(observer.validate('length'), false, 'should NOT have notified length once');
});

suite.test("[X].clear() => [] + notify", function () {
Expand All @@ -36,16 +34,14 @@ suite.test("[X].clear() => [] + notify", function () {
before = this.newFixture(1);
after = [];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

equal(obj.clear(), obj, 'return self');

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');

});
50 changes: 19 additions & 31 deletions packages/ember-runtime/tests/suites/mutable_array/insertAt.js
Expand Up @@ -16,17 +16,15 @@ suite.test("[].insertAt(0, X) => [X] + notify", function() {

after = this.newFixture(1);
obj = this.newObject([]);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.insertAt(0, after[0]);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});

suite.test("[].insertAt(200,X) => OUT_OF_RANGE_EXCEPTION exception", function() {
Expand All @@ -43,17 +41,15 @@ suite.test("[A].insertAt(0, X) => [X,A] + notify", function() {
before = this.newFixture(1);
after = [item, before[0]];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.insertAt(0, item);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});

suite.test("[A].insertAt(1, X) => [A,X] + notify", function() {
Expand All @@ -63,17 +59,15 @@ suite.test("[A].insertAt(1, X) => [A,X] + notify", function() {
before = this.newFixture(1);
after = [before[0], item];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.insertAt(1, item);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});

suite.test("[A].insertAt(200,X) => OUT_OF_RANGE exception", function() {
Expand All @@ -90,17 +84,15 @@ suite.test("[A,B,C].insertAt(0,X) => [X,A,B,C] + notify", function() {
before = this.newFixture(3);
after = [item, before[0], before[1], before[2]];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.insertAt(0, item);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});

suite.test("[A,B,C].insertAt(1,X) => [A,X,B,C] + notify", function() {
Expand All @@ -110,17 +102,15 @@ suite.test("[A,B,C].insertAt(1,X) => [A,X,B,C] + notify", function() {
before = this.newFixture(3);
after = [before[0], item, before[1], before[2]];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.insertAt(1, item);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});

suite.test("[A,B,C].insertAt(3,X) => [A,B,C,X] + notify", function() {
Expand All @@ -130,15 +120,13 @@ suite.test("[A,B,C].insertAt(3,X) => [A,B,C,X] + notify", function() {
before = this.newFixture(3);
after = [before[0], before[1], before[2], item];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.insertAt(3, item);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
});
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});
26 changes: 10 additions & 16 deletions packages/ember-runtime/tests/suites/mutable_array/popObject.js
Expand Up @@ -14,15 +14,13 @@ suite.test("[].popObject() => [] + returns undefined + NO notify", function() {
var obj, observer;

obj = this.newObject([]);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

equal(obj.popObject(), undefined, 'popObject results');

deepEqual(this.toArray(obj), [], 'post item results');
if (observer.isEnabled) {
equal(observer.validate('[]'), false, 'should NOT have notified []');
equal(observer.validate('length'), false, 'should NOT have notified length');
}
equal(observer.validate('@each'), false, 'should NOT have notified @each');
equal(observer.validate('length'), false, 'should NOT have notified length');
});

suite.test("[X].popObject() => [] + notify", function() {
Expand All @@ -31,17 +29,15 @@ suite.test("[X].popObject() => [] + notify", function() {
before = this.newFixture(1);
after = [];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

ret = obj.popObject();

equal(ret, before[0], 'return object');
deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');
if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should NOT have notified []');
equal(observer.validate('length'), true, 'should NOT have notified length');
}
equal(observer.validate('@each'), true, 'should NOT have notified @each');
equal(observer.validate('length'), true, 'should NOT have notified length');
});

suite.test("[A,B,C].popObject() => [A,B] + notify", function() {
Expand All @@ -50,16 +46,14 @@ suite.test("[A,B,C].popObject() => [A,B] + notify", function() {
before = this.newFixture(3);
after = [before[0], before[1]];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

ret = obj.popObject();

equal(ret, before[2], 'return object');
deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should NOT have notified []');
equal(observer.validate('length'), true, 'should NOT have notified length');
}
});
equal(observer.validate('@each'), true, 'should NOT have notified @each');
equal(observer.validate('length'), true, 'should NOT have notified length');
});
16 changes: 6 additions & 10 deletions packages/ember-runtime/tests/suites/mutable_array/pushObject.js
Expand Up @@ -22,17 +22,15 @@ suite.test("[].pushObject(X) => [X] + notify", function() {
before = [];
after = this.newFixture(1);
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.pushObject(after[0]);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});

suite.test("[A,B,C].pushObject(X) => [A,B,C,X] + notify", function() {
Expand All @@ -42,15 +40,13 @@ suite.test("[A,B,C].pushObject(X) => [A,B,C,X] + notify", function() {
item = this.newFixture(1)[0];
after = [before[0], before[1], before[2], item];
obj = this.newObject(before);
observer = this.newObserver(obj, '[]', 'length');
observer = this.newObserver(obj, '@each', 'length');

obj.pushObject(item);

deepEqual(this.toArray(obj), after, 'post item results');
equal(Ember.get(obj, 'length'), after.length, 'length');

if (observer.isEnabled) {
equal(observer.validate('[]'), true, 'should have notified []');
equal(observer.validate('length'), true, 'should have notified length');
}
equal(observer.timesCalled('@each'), 1, 'should have notified @each once');
equal(observer.timesCalled('length'), 1, 'should have notified length once');
});

0 comments on commit 09d7ad6

Please sign in to comment.