diff --git a/modules/angular2/src/core/annotations/decorators.dart b/modules/angular2/src/core/annotations/decorators.dart index 676088c9e7..38168fafe7 100644 --- a/modules/angular2/src/core/annotations/decorators.dart +++ b/modules/angular2/src/core/annotations/decorators.dart @@ -2,5 +2,5 @@ library angular2.core.decorators; export '../annotations_impl/annotations.dart'; export '../annotations_impl/visibility.dart'; - -/* This file is empty because, Dart does not have decorators. */ +export '../annotations_impl/view.dart'; +export '../annotations_impl/di.dart'; diff --git a/modules/angular2/src/core/annotations_impl/view.ts b/modules/angular2/src/core/annotations_impl/view.ts index 3bc6d4c2f1..cd8c910c4f 100644 --- a/modules/angular2/src/core/annotations_impl/view.ts +++ b/modules/angular2/src/core/annotations_impl/view.ts @@ -73,7 +73,10 @@ export class View { * } * ``` */ - directives: List; + // TODO(tbosch): use Type | Binding | List when Dart supports union types, + // as otherwise we would need to import Binding type and Dart would warn + // for an unused import. + directives: List>; /** * Specify a custom renderer for this View. @@ -89,7 +92,7 @@ export class View { }: { templateUrl?: string, template?: string, - directives?: List, + directives?: List>, renderer?: string } = {}) { diff --git a/modules/angular2/src/test_lib/test_lib.ts b/modules/angular2/src/test_lib/test_lib.ts index 00e015b832..67e6b9b375 100644 --- a/modules/angular2/src/test_lib/test_lib.ts +++ b/modules/angular2/src/test_lib/test_lib.ts @@ -17,7 +17,18 @@ export function proxy() { var _global: jasmine.GlobalPolluter = (typeof window === 'undefined' ? global : window); export var afterEach = _global.afterEach; -export var expect = _global.expect; + +export interface NgMatchers extends jasmine.Matchers { + toBe(expected: any): boolean; + toEqual(expected: any): boolean; + toBePromise(expected: any): boolean; + toBeAnInstanceOf(expected: any): boolean; + toHaveText(expected: any): boolean; + toImplement(expected: any): boolean; + not: NgMatchers; +} + +export var expect: (actual: any) => NgMatchers = _global.expect; export var IS_DARTIUM = false; diff --git a/modules/angular2/test/core/compiler/integration_spec.js b/modules/angular2/test/core/compiler/integration_spec.js deleted file mode 100644 index bd3e44279e..0000000000 --- a/modules/angular2/test/core/compiler/integration_spec.js +++ /dev/null @@ -1,1595 +0,0 @@ -import { - AsyncTestCompleter, - beforeEach, - ddescribe, - xdescribe, - describe, - el, - dispatchEvent, - expect, - iit, - inject, - IS_DARTIUM, - beforeEachBindings, - it, - xit -} from 'angular2/test_lib'; - - -import {TestBed} from 'angular2/src/test_lib/test_bed'; - -import {DOM} from 'angular2/src/dom/dom_adapter'; -import {Type, isPresent, BaseException, assertionsEnabled, isJsObject, global} from 'angular2/src/facade/lang'; -import {PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async'; - -import {Injector, bind} from 'angular2/di'; -import {PipeRegistry, defaultPipeRegistry, - ChangeDetection, DynamicChangeDetection, Pipe, ChangeDetectorRef, ON_PUSH} from 'angular2/change_detection'; - -import {Directive, Component} from 'angular2/src/core/annotations_impl/annotations'; -import {QueryList} from 'angular2/src/core/compiler/query_list'; -import {View} from 'angular2/src/core/annotations_impl/view'; -import {Parent, Ancestor, Unbounded} from 'angular2/src/core/annotations_impl/visibility'; -import {Attribute, Query} from 'angular2/src/core/annotations_impl/di'; - -import {NgIf} from 'angular2/src/directives/ng_if'; -import {NgFor} from 'angular2/src/directives/ng_for'; - -import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; -import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref'; -import {Compiler} from 'angular2/src/core/compiler/compiler'; -import {ElementRef} from 'angular2/src/core/compiler/element_ref'; - -import {DomRenderer} from 'angular2/src/render/dom/dom_renderer'; -import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; - -export function main() { - describe('integration tests', function() { - var ctx; - - beforeEach( () => { - ctx = new MyComp(); - }); - - - describe('react to record changes', function() { - it('should consume text node changes', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({template: '
{{ctxProp}}
'})); - tb.createView(MyComp, {context: ctx}).then((view) => { - ctx.ctxProp = 'Hello World!'; - - view.detectChanges(); - expect(DOM.getInnerHTML(view.rootNodes[0])).toEqual('Hello World!'); - async.done(); - }); - })); - - it('should consume element binding changes', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({template: '
'})); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - ctx.ctxProp = 'Hello World!'; - view.detectChanges(); - - expect(view.rootNodes[0].id).toEqual('Hello World!'); - async.done(); - }); - })); - - it('should consume binding to aria-* attributes', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({template: '
'})); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - ctx.ctxProp = 'Initial aria label'; - view.detectChanges(); - expect(DOM.getAttribute(view.rootNodes[0], 'aria-label')).toEqual('Initial aria label'); - - ctx.ctxProp = 'Changed aria label'; - view.detectChanges(); - expect(DOM.getAttribute(view.rootNodes[0], 'aria-label')).toEqual('Changed aria label'); - - async.done(); - }); - })); - - it('should consume binding to property names where attr name and property name do not match', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({template: '
'})); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - view.detectChanges(); - expect(view.rootNodes[0].tabIndex).toEqual(0); - - ctx.ctxNumProp = 5; - view.detectChanges(); - expect(view.rootNodes[0].tabIndex).toEqual(5); - - async.done(); - }); - })); - - it('should consume binding to camel-cased properties using dash-cased syntax in templates', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({template: ''})); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - view.detectChanges(); - expect(view.rootNodes[0].readOnly).toBeFalsy(); - - ctx.ctxBoolProp = true; - view.detectChanges(); - expect(view.rootNodes[0].readOnly).toBeTruthy(); - - async.done(); - }); - })); - - it('should consume binding to inner-html', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({template: '
'})); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - ctx.ctxProp = 'Some HTML'; - view.detectChanges(); - expect(DOM.getInnerHTML(view.rootNodes[0])).toEqual('Some HTML'); - - ctx.ctxProp = 'Some other
HTML
'; - view.detectChanges(); - expect(DOM.getInnerHTML(view.rootNodes[0])).toEqual('Some other
HTML
'); - - async.done(); - }); - })); - - it('should ignore bindings to unknown properties', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({template: '
'})); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - ctx.ctxProp = 'Some value'; - view.detectChanges(); - expect(DOM.hasProperty(view.rootNodes[0], 'unknown')).toBeFalsy(); - - async.done(); - }); - })); - - it('should consume directive watch expression change.', inject([TestBed, AsyncTestCompleter], (tb, async) => { - var tpl = - '
' + - '
' + - '
' + - '
' + - '
' + - '
' - tb.overrideView(MyComp, new View({template: tpl, directives: [MyDir]})); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - ctx.ctxProp = 'Hello World!'; - view.detectChanges(); - - expect(view.rawView.elementInjectors[0].get(MyDir).dirProp).toEqual('Hello World!'); - expect(view.rawView.elementInjectors[1].get(MyDir).dirProp).toEqual('Hi there!'); - expect(view.rawView.elementInjectors[2].get(MyDir).dirProp).toEqual('Hi there!'); - expect(view.rawView.elementInjectors[3].get(MyDir).dirProp).toEqual('One more Hello World!'); - async.done(); - }); - })); - - describe('pipes', () => { - beforeEachBindings(() => { - return [bind(ChangeDetection).toFactory( - () => new DynamicChangeDetection(new PipeRegistry({ - "double" : [new DoublePipeFactory()] - })), - [] - )]; - }); - - it("should support pipes in bindings and bind config", inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, - new View({ - template: '', - directives: [ComponentWithPipes] - })); - - tb.createView(MyComp, {context: ctx}).then((view) => { - ctx.ctxProp = 'a'; - view.detectChanges(); - - var comp = view.rawView.locals.get("comp"); - - // it is doubled twice: once in the binding, second time in the bind config - expect(comp.prop).toEqual('aaaa'); - async.done(); - }); - })); - }); - - it('should support nested components.', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({ - template: '', - directives: [ChildComp] - })); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - view.detectChanges(); - - expect(view.rootNodes).toHaveText('hello'); - async.done(); - }); - })); - - // GH issue 328 - https://github.com/angular/angular/issues/328 - it('should support different directive types on a single node', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, - new View({ - template: '', - directives: [MyDir, ChildComp] - })); - - tb.createView(MyComp, {context: ctx}).then((view) => { - - ctx.ctxProp = 'Hello World!'; - view.detectChanges(); - - var elInj = view.rawView.elementInjectors[0]; - expect(elInj.get(MyDir).dirProp).toEqual('Hello World!'); - expect(elInj.get(ChildComp).dirProp).toEqual(null); - - async.done(); - }); - })); - - it('should support directives where a binding attribute is not given', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, - new View({ - // No attribute "el-prop" specified. - template: '

', - directives: [MyDir] - })); - - tb.createView(MyComp, {context: ctx}).then((view) => { - async.done(); - }); - })); - - it('should support directives where a selector matches property binding', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, - new View({ - template: '

', - directives: [IdDir] - })); - - tb.createView(MyComp, {context: ctx}).then((view) => { - var idDir = view.rawView.elementInjectors[0].get(IdDir); - - ctx.ctxProp = 'some_id'; - view.detectChanges(); - expect(idDir.id).toEqual('some_id'); - - ctx.ctxProp = 'other_id'; - view.detectChanges(); - expect(idDir.id).toEqual('other_id'); - - async.done(); - }); - })); - - it('should allow specifying directives as bindings', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({ - template: '', - directives: [bind(ChildComp).toClass(ChildComp)] - })); - - tb.createView(MyComp, {context: ctx}).then((view) => { - view.detectChanges(); - - expect(view.rootNodes).toHaveText('hello'); - async.done(); - }); - })); - - it('should read directives metadata from their binding token', inject([TestBed, AsyncTestCompleter], (tb, async) => { - tb.overrideView(MyComp, new View({ - template: '
', - directives: [bind(PublicApi).toClass(PrivateImpl), NeedsPublicApi] - })); - - tb.createView(MyComp, {context: ctx}).then((view) => { - async.done(); - }); - })); - - it('should support template directives via `