Skip to content

Commit 376bdf4

Browse files
chalinmhevery
authored andcommitted
fix(bootstrap): report error on bootstrapping non-Component directive
Fixes angular#951. Test case added to exercise new error reporting. Also added extra test for when Template is missing. Closes angular#961
1 parent a35cc27 commit 376bdf4

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

modules/angular2/src/core/application.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Injector, bind, OpaqueToken} from 'angular2/di';
2-
import {Type, isBlank, isPresent, BaseException, assertionsEnabled, print} from 'angular2/src/facade/lang';
2+
import {Type, isBlank, isPresent, BaseException, assertionsEnabled, print, stringify} from 'angular2/src/facade/lang';
33
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
44
import {DOM} from 'angular2/src/dom/dom_adapter';
55
import {Compiler, CompilerCache} from './compiler/compiler';
@@ -25,6 +25,7 @@ import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
2525
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
2626
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
2727
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
28+
import {Component} from 'angular2/src/core/annotations/annotations';
2829

2930
var _rootInjector: Injector;
3031

@@ -58,6 +59,12 @@ function _injectorBindings(appComponentType): List<Binding> {
5859

5960
bind(appViewToken).toAsyncFactory((changeDetection, compiler, injector, appElement,
6061
appComponentAnnotatedType, strategy, eventManager) => {
62+
var annotation = appComponentAnnotatedType.annotation;
63+
if(!isBlank(annotation) && !(annotation instanceof Component)) {
64+
var type = appComponentAnnotatedType.type;
65+
throw new BaseException(`Only Components can be bootstrapped; ` +
66+
`Directive of ${stringify(type)} is not a Component`);
67+
}
6168
return compiler.compile(appComponentAnnotatedType.type).then(
6269
(protoView) => {
6370
var appProtoView = ProtoView.createRootProtoView(protoView, appElement,

modules/angular2/test/core/application_spec.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from 'angular2/test_lib';
1313
import {bootstrap, appDocumentToken, appElementToken}
1414
from 'angular2/src/core/application';
15-
import {Component} from 'angular2/src/core/annotations/annotations';
15+
import {Component, Decorator} from 'angular2/src/core/annotations/annotations';
1616
import {DOM} from 'angular2/src/dom/dom_adapter';
1717
import {ListWrapper} from 'angular2/src/facade/collection';
1818
import {PromiseWrapper} from 'angular2/src/facade/async';
@@ -64,6 +64,12 @@ class HelloRootCmp4 {
6464
}
6565
}
6666

67+
@Component({selector: 'hello-app'})
68+
class HelloRootMissingTemplate { }
69+
70+
@Decorator({selector: 'hello-app'})
71+
class HelloRootDirectiveIsNotCmp { }
72+
6773
export function main() {
6874
var fakeDoc, el, el2, testBindings, lightDom;
6975

@@ -80,6 +86,23 @@ export function main() {
8086
});
8187

8288
describe('bootstrap factory method', () => {
89+
it('should throw if no Template found', inject([AsyncTestCompleter], (async) => {
90+
var injectorPromise = bootstrap(HelloRootMissingTemplate, testBindings, (e,t) => {throw e;});
91+
PromiseWrapper.then(injectorPromise, null, (reason) => {
92+
expect(reason.message).toContain('No template found for HelloRootMissingTemplate');
93+
async.done();
94+
});
95+
}));
96+
97+
it('should throw if bootstrapped Directive is not a Component', inject([AsyncTestCompleter], (async) => {
98+
var injectorPromise = bootstrap(HelloRootDirectiveIsNotCmp, testBindings, (e,t) => {throw e;});
99+
PromiseWrapper.then(injectorPromise, null, (reason) => {
100+
expect(reason.message).toContain('Only Components can be bootstrapped; ' +
101+
'Directive of HelloRootDirectiveIsNotCmp is not a Component');
102+
async.done();
103+
});
104+
}));
105+
83106
it('should throw if no element is found', inject([AsyncTestCompleter], (async) => {
84107
var injectorPromise = bootstrap(HelloRootCmp, [], (e,t) => {throw e;});
85108
PromiseWrapper.then(injectorPromise, null, (reason) => {

0 commit comments

Comments
 (0)