Skip to content

Commit

Permalink
Backport warnings and errors for 1.0's Ember.Object.create() behaviour.
Browse files Browse the repository at this point in the history
Closes #2.
  • Loading branch information
Erik Bryn and James A. Rosen authored and ebryn committed Jul 29, 2013
1 parent 73c3882 commit 2047e74
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 33 deletions.
35 changes: 2 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,37 +37,6 @@ non-dotted paths, just as in 1.0.
See [issue #1](https://github.com/zendesk/ember.js/issues/1) for more
information.

## `Ember.Object.create`
## Transitions

This backports the `create` and `createWithMixins` functionality from Ember 1.0
to Ember 0.9. In Ember 0.9.8.1, the following is perfectly valid:

```javascript
Ember.Object.create(Ember.Mixin.create(), {
someProperty: function() { return 'some value'; }.property(),
someFunction: function() { return this._super(); }
});
```

In Ember 1.0, that same code throws three exceptions:

* Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.
* mber.Object.create no longer supports defining computed properties.
* Ember.Object.create no longer supports defining methods that call _super.

This helps those migrating from Ember 0.9 to 1.0 by backporting the new
behavior, conditional on a flag, `ENV.CREATE_WITH_MIXINS`, which
has four possible values:

* `"0.9"` (the default): Ember 0.9.8.1 compatibility; `Ember.Object.create`
accepts `Ember.Mixin`s and `Object`s that contain
`Ember.ComputedProperty`s or `Function`s that call `_super`.
* `"0.9+warn"`: Ember 0.9.8.1 compatibility with warnings.
* `"0.9+deprecate"`: Ember 0.9.8.1 compatibility with deprecation warnings
(errors if `ENV.RAISE_ON_DEPRECATION` is `true`)
* `"1.0"`: Ember 1.0 compatibility; `Ember.Obect.create` will throw an
exception if passed an `Ember.Mixin` or an object that contains an
`Ember.ComputedProperty` or `Function` that calls `_super`.

See [issue #2](https://github.com/zendesk/ember.js/issues/2) for more
information.
* [Ember.Object.create](doc/object_create.md)
32 changes: 32 additions & 0 deletions doc/object_create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# `Ember.Object.create`

This backports the `create` and `createWithMixins` functionality from Ember 1.0
to Ember 0.9. In Ember 0.9.8.1, the following is perfectly valid:

```javascript
Ember.Object.create(Ember.Mixin.create(), {
someProperty: function() { return 'some value'; }.property(),
someFunction: function() { return this._super(); }
});
```

In Ember 1.0, that same code throws three exceptions:

* Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.
* Ember.Object.create no longer supports defining computed properties.
* Ember.Object.create no longer supports defining methods that call _super.

This helps those migrating from Ember 0.9 to 1.0 by backporting the new
behavior, conditional on a flag, `ENV.CREATE_WITH_MIXINS`, which
has four possible values:

* `null` (the default): Ember 0.9.8.1 compatibility; `Ember.Object.create`
accepts `Ember.Mixin`s and `Object`s that contain
`Ember.ComputedProperty`s or `Function`s that call `_super`.
* `"warn"`: Ember 0.9.8.1 compatibility with warnings.
* `"error"`: Ember 1.0 compatibility; `Ember.Object.create` will throw an
exception if passed an `Ember.Mixin` or an object that contains an
`Ember.ComputedProperty` or `Function` that calls `_super`.

See [issue #2](https://github.com/zendesk/ember.js/issues/2) for more
information.
28 changes: 28 additions & 0 deletions packages/ember-runtime/lib/system/core_object.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,26 @@ var o_create = Ember.platform.create,
a_slice = Array.prototype.slice,
meta = Ember.meta;

function checkForDeprecations(initMixins) {
var level = Ember.ENV.CREATE_WITH_MIXINS,
op = {warn: Ember.warn, error: Ember.error}[level];
if (!level || level === '0.9') { return; }

var currentMixin, currentValue;
for (var i = 0, l = initMixins.length; i < l; i++) {
currentMixin = initMixins[i];
op("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(currentMixin instanceof Ember.Mixin));

for (var key in currentMixin) {
currentValue = currentMixin[key];
op("Ember.Object.create no longer supports defining computed properties.", !(currentValue instanceof Ember.ComputedProperty));

var usesSuper = typeof currentValue === 'function' && currentValue.toString().indexOf('._super') !== -1;
op("Ember.Object.create no longer supports defining methods that call _super.", !usesSuper);
}
}
}

/** @private */
function makeCtor() {

Expand All @@ -31,6 +51,8 @@ function makeCtor() {
var Class = function() {
if (!wasApplied) { Class.proto(); } // prepare prototype...
if (initMixins) {
checkForDeprecations(initMixins);

this.reopen.apply(this, initMixins);
initMixins = null;
rewatch(this); // always rewatch just in case
Expand Down Expand Up @@ -191,6 +213,12 @@ var ClassMixin = Ember.Mixin.create({
return new C();
},

createWithMixins: function() {
var C = this;
if (arguments.length>0) { this._initMixins(arguments); }
return new C();
},

reopen: function() {
this.willReopen();
var PrototypeMixin = this.PrototypeMixin;
Expand Down
124 changes: 124 additions & 0 deletions packages/ember-runtime/tests/backports/create_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
module("Ember.Object.createWithMixins");

test("it exists", function() {
ok(Ember.Object.createWithMixins);
});

test("it instantiates objects", function() {
var obj = Ember.Object.createWithMixins({ foo: 'bar' });
ok(obj);
equal(obj.get('foo'), 'bar');
});

test('it works on subclasses', function() {
var Klass = Ember.Object.extend({
foo: 'bar'
});
var obj = Klass.createWithMixins({ foo: 'baz' });
equal(obj.get('foo'), 'baz');
});

var originalFlag, originalWarn, warnings;

module("Backported Ember.Object.create", {
setup: function() {
originalFlag = Ember.ENV.CREATE_WITH_MIXINS;
originalWarn = Ember.Logger.warn;
warnings = [];
Ember.Logger.warn = function(msg) {
warnings.push(msg.replace("WARNING: ", ""));
};
},
teardown: function() {
Ember.ENV.CREATE_WITH_MIXINS = originalFlag;
Ember.Logger.warn = originalWarn;
}
});

test("passing a mixin with warnings off", function() {
Ember.ENV.CREATE_WITH_MIXINS = null;
Ember.Object.create(Ember.Mixin.create());
equal(warnings.length, 0);
});

test("passing a mixin with warnings on", function() {
Ember.ENV.CREATE_WITH_MIXINS = 'warn';

Ember.Object.create(Ember.Mixin.create());
equal(warnings.length, 1);
equal(warnings[0], "Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.");
});

test("passing a mixin with errors on", function() {
Ember.ENV.CREATE_WITH_MIXINS = 'error';
raises(function() {
Ember.Object.create(Ember.Mixin.create());
}, "Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.");
});

test("passing computed properties with warnings off", function() {
Ember.ENV.CREATE_WITH_MIXINS = null;

Ember.Object.create({
aProp: Ember.computed(function() { return 'three'; })
});
equal(warnings.length, 0);
});

test("passing computed properties with warnings on", function() {
Ember.ENV.CREATE_WITH_MIXINS = 'warn';

Ember.Object.create({
aProp: Ember.computed(function() { return 'three'; })
});
equal(warnings.length, 1);
equal(warnings[0], "Ember.Object.create no longer supports defining computed properties.");
});

test("passing a computed property with errors on", function() {
Ember.ENV.CREATE_WITH_MIXINS = 'error';
raises(function() {
Ember.Object.create({
aProp: Ember.computed(function() { return 'three'; })
});
}, "Ember.Object.create no longer supports defining computed properties.");
});

test("passing methods that use _super with warnings off", function() {
Ember.ENV.CREATE_WITH_MIXINS = null;

Ember.Object.create({
aProp: function() { return this._super(); }
});
equal(warnings.length, 0);
});

test("passing methods that use _super with warnings on", function() {
Ember.ENV.CREATE_WITH_MIXINS = 'warn';

Ember.Object.create({
aProp: function() { return this._super(); }
});
equal(warnings.length, 1);
equal(warnings[0], "Ember.Object.create no longer supports defining methods that call _super.");
});

test("passing methods that *don't* use _super with warnings on", function() {
Ember.ENV.CREATE_WITH_MIXINS = 'warn';

Ember.Object.create({
aProp: function() { return this._notSuper(); }
});
equal(warnings.length, 0);
});

test("passing methods that use _super with errors on", function() {
Ember.ENV.CREATE_WITH_MIXINS = 'error';

raises(function() {
Ember.Object.create({
aProp: function() { return this._super(); }
});
});
});

0 comments on commit 2047e74

Please sign in to comment.