Skip to content

Commit

Permalink
Merge pull request #11261 from mitchlloyd/resolver-assertions-no-cont…
Browse files Browse the repository at this point in the history
…roller

Validate Ember object types in resolver
  • Loading branch information
rwjblue committed May 24, 2015
2 parents d9889a2 + a876722 commit d905afa
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 3 deletions.
5 changes: 5 additions & 0 deletions packages/ember-application/lib/system/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import EmberObject from 'ember-runtime/system/object';
import Namespace from 'ember-runtime/system/namespace';
import helpers from 'ember-htmlbars/helpers';
import validateType from 'ember-application/utils/validate-type';

export var Resolver = EmberObject.extend({
/**
Expand Down Expand Up @@ -172,6 +173,10 @@ export default EmberObject.extend({
this._logLookup(resolved, parsedName);
}

if (resolved) {
validateType(resolved, parsedName);
}

return resolved;
},

Expand Down
25 changes: 25 additions & 0 deletions packages/ember-application/lib/utils/validate-type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
@module ember
@submodule ember-application
*/

let VALIDATED_TYPES = {
route: ['isRouteFactory', 'Ember.Route'],
component: ['isComponentFactory', 'Ember.Component'],
view: ['isViewFactory', 'Ember.View'],
service: ['isServiceFactory', 'Ember.Service']
};

export default function validateType(resolvedType, parsedName) {
let validationAttributes = VALIDATED_TYPES[parsedName.type];

if (!validationAttributes) {
return;
}

let [factoryFlag, expectedType] = validationAttributes;

Ember.assert(`Expected ${parsedName.fullName} to resolve to an ${expectedType} but instead it was ${resolvedType}.`, function() {
return resolvedType[factoryFlag];
});
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import Ember from "ember-metal/core"; // Ember.TEMPLATES
import run from "ember-metal/run_loop";
import { forEach } from "ember-metal/enumerable_utils";
import { capitalize } from "ember-runtime/system/string";
import Logger from "ember-metal/logger";
import Controller from "ember-runtime/controllers/controller";
import Route from "ember-routing/system/route";
import Component from "ember-views/views/component";
import View from "ember-views/views/view";
import Service from "ember-runtime/system/service";
import EmberObject from "ember-runtime/system/object";
import Namespace from "ember-runtime/system/namespace";
import Application from "ember-application/system/application";
Expand Down Expand Up @@ -170,3 +176,34 @@ QUnit.test("lookup description", function() {
equal(registry.describe('model:foo'), 'App.Foo', "models don't get appended at the end");

});

QUnit.test("validating resolved objects", function() {
let types = ['route', 'component', 'view', 'service'];

// Valid setup
application.FooRoute = Route.extend();
application.FooComponent = Component.extend();
application.FooView = View.extend();
application.FooService = Service.extend();

forEach(types, function(type) {
// No errors when resolving correct object types
registry.resolve(`${type}:foo`);

// Unregister to clear cache
registry.unregister(`${type}:foo`);
});

// Invalid setup
application.FooRoute = Component.extend();
application.FooComponent = View.extend();
application.FooView = Service.extend();
application.FooService = Route.extend();

forEach(types, function(type) {
let matcher = new RegExp(`to resolve to an Ember.${capitalize(type)}`);
expectAssertion(function() {
registry.resolve(`${type}:foo`);
}, matcher, `Should assert for ${type}`);
});
});
4 changes: 4 additions & 0 deletions packages/ember-routing/lib/system/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,10 @@ var Route = EmberObject.extend(ActionHandler, Evented, {
}
});

Route.reopenClass({
isRouteFactory: true
});

var defaultQPMeta = {
qps: [],
map: {},
Expand Down
8 changes: 7 additions & 1 deletion packages/ember-runtime/lib/system/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ createInjectionHelper('service');
@extends Ember.Object
@since 1.10.0
*/
export default Object.extend();
const Service = Object.extend();

Service.reopenClass({
isServiceFactory: true
});

export default Service;
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ var ViewChildViewsSupport = Mixin.create({
var view;
attrs.renderer = this.renderer;

if (maybeViewClass.isViewClass) {
if (maybeViewClass.isViewFactory) {
attrs.container = this.container;

view = maybeViewClass.create(attrs);
Expand Down
4 changes: 4 additions & 0 deletions packages/ember-views/lib/views/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,4 +390,8 @@ var Component = View.extend(TargetActionSupport, ComponentTemplateDeprecation, {
*/
});

Component.reopenClass({
isComponentFactory: true
});

export default Component;
2 changes: 1 addition & 1 deletion packages/ember-views/lib/views/core_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ var CoreView = EmberObject.extend(Evented, ActionHandler, {
});

CoreView.reopenClass({
isViewClass: true
isViewFactory: true
});

export var DeprecatedCoreView = CoreView.extend({
Expand Down

0 comments on commit d905afa

Please sign in to comment.