import { AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, el, dispatchEvent, expect, iit, inject, IS_DARTIUM, beforeEachBindings, it, xit, containsRegexp, stringifyElement, TestComponentBuilder } from 'angular2/test_lib'; import {DOM} from 'angular2/src/dom/dom_adapter'; import { Type, isPresent, BaseException, assertionsEnabled, isJsObject, global, stringify, CONST, CONST_EXPR } from 'angular2/src/facade/lang'; import {PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async'; import { Injector, bind, Injectable, Binding, forwardRef, OpaqueToken, Inject, Parent, Ancestor, Unbounded, UnboundedMetadata } from 'angular2/di'; import { PipeFactory, Pipes, defaultPipes, ChangeDetection, DynamicChangeDetection, Pipe, ChangeDetectorRef, ON_PUSH } from 'angular2/change_detection'; import {Directive, Component, View, Attribute, Query} from 'angular2/annotations'; import * as viewAnn from 'angular2/src/core/annotations_impl/view'; import {QueryList} from 'angular2/src/core/compiler/query_list'; 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, ViewRef} 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'; const ANCHOR_ELEMENT = CONST_EXPR(new OpaqueToken('AnchorElement')); export function main() { describe('integration tests', function() { beforeEachBindings(() => [bind(ANCHOR_ELEMENT).toValue(el('
'))]); describe('react to record changes', function() { it('should consume text node changes', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({template: '
{{ctxProp}}
'})) .createAsync(MyComp) .then((rootTC) => { rootTC.componentInstance.ctxProp = 'Hello World!'; rootTC.detectChanges(); expect(rootTC.nativeElement).toHaveText('Hello World!'); async.done(); }); })); it('should consume element binding changes', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({template: '
'})) .createAsync(MyComp) .then((rootTC) => { rootTC.componentInstance.ctxProp = 'Hello World!'; rootTC.detectChanges(); expect(rootTC.componentViewChildren[0].nativeElement.id).toEqual('Hello World!'); async.done(); }); })); it('should consume binding to aria-* attributes', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({template: '
'})) .createAsync(MyComp) .then((rootTC) => { rootTC.componentInstance.ctxProp = 'Initial aria label'; rootTC.detectChanges(); expect( DOM.getAttribute(rootTC.componentViewChildren[0].nativeElement, 'aria-label')) .toEqual('Initial aria label'); rootTC.componentInstance.ctxProp = 'Changed aria label'; rootTC.detectChanges(); expect( DOM.getAttribute(rootTC.componentViewChildren[0].nativeElement, '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([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({template: '
'})) .createAsync(MyComp) .then((rootTC) => { rootTC.detectChanges(); expect(rootTC.componentViewChildren[0].nativeElement.tabIndex).toEqual(0); rootTC.componentInstance.ctxNumProp = 5; rootTC.detectChanges(); expect(rootTC.componentViewChildren[0].nativeElement.tabIndex).toEqual(5); async.done(); }); })); it('should consume binding to camel-cased properties using dash-cased syntax in templates', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({template: ''})) .createAsync(MyComp) .then((rootTC) => { rootTC.detectChanges(); expect(rootTC.componentViewChildren[0].nativeElement.readOnly).toBeFalsy(); rootTC.componentInstance.ctxBoolProp = true; rootTC.detectChanges(); expect(rootTC.componentViewChildren[0].nativeElement.readOnly).toBeTruthy(); async.done(); }); })); it('should consume binding to inner-html', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({template: '
'})) .createAsync(MyComp) .then((rootTC) => { rootTC.componentInstance.ctxProp = 'Some HTML'; rootTC.detectChanges(); expect(DOM.getInnerHTML(rootTC.componentViewChildren[0].nativeElement)) .toEqual('Some HTML'); rootTC.componentInstance.ctxProp = 'Some other
HTML
'; rootTC.detectChanges(); expect(DOM.getInnerHTML(rootTC.componentViewChildren[0].nativeElement)) .toEqual('Some other
HTML
'); async.done(); }); })); it('should consume directive watch expression change.', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { var tpl = '
' + '
' + '
' + '
' + '
' + '
'; tcb.overrideView(MyComp, new viewAnn.View({template: tpl, directives: [MyDir]})) .createAsync(MyComp) .then((rootTC) => { rootTC.componentInstance.ctxProp = 'Hello World!'; rootTC.detectChanges(); expect(rootTC.componentViewChildren[0].inject(MyDir).dirProp) .toEqual('Hello World!'); expect(rootTC.componentViewChildren[1].inject(MyDir).dirProp).toEqual('Hi there!'); expect(rootTC.componentViewChildren[2].inject(MyDir).dirProp).toEqual('Hi there!'); expect(rootTC.componentViewChildren[3].inject(MyDir).dirProp) .toEqual('One more Hello World!'); async.done(); }); })); describe('pipes', () => { it("should support pipes in bindings", inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyCompWithPipes, new viewAnn.View({ template: '
', directives: [MyDir] })) .createAsync(MyCompWithPipes) .then((rootTC) => { rootTC.componentInstance.ctxProp = 'a'; rootTC.detectChanges(); var dir = rootTC.componentViewChildren[0].getLocal('dir'); expect(dir.dirProp).toEqual('aa'); async.done(); }); })); }); it('should support nested components.', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView( MyComp, new viewAnn.View({template: '', directives: [ChildComp]})) .createAsync(MyComp) .then((rootTC) => { rootTC.detectChanges(); expect(rootTC.nativeElement).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([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({ template: '', directives: [MyDir, ChildComp] })) .createAsync(MyComp) .then((rootTC) => { rootTC.componentInstance.ctxProp = 'Hello World!'; rootTC.detectChanges(); var tc = rootTC.componentViewChildren[0]; expect(tc.inject(MyDir).dirProp).toEqual('Hello World!'); expect(tc.inject(ChildComp).dirProp).toEqual(null); async.done(); }); })); it('should support directives where a binding attribute is not given', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({ // No attribute "el-prop" specified. template: '

', directives: [MyDir] })) .createAsync(MyComp) .then((rootTC) => { async.done(); }); })); it('should execute a given directive once, even if specified multiple times', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({ template: '

', directives: [ DuplicateDir, DuplicateDir, [DuplicateDir, [DuplicateDir, bind(DuplicateDir).toClass(DuplicateDir)]] ] })) .createAsync(MyComp) .then((rootTC) => { expect(rootTC.nativeElement).toHaveText('noduplicate'); async.done(); }); })); it('should use the last directive binding per directive', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({ template: '

', directives: [ bind(DuplicateDir) .toClass(DuplicateDir), bind(DuplicateDir).toClass(OtherDuplicateDir) ] })) .createAsync(MyComp) .then((rootTC) => { expect(rootTC.nativeElement).toHaveText('othernoduplicate'); async.done(); }); })); it('should support directives where a selector matches property binding', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View( {template: '

', directives: [IdDir]})) .createAsync(MyComp) .then((rootTC) => { var tc = rootTC.componentViewChildren[0]; var idDir = tc.inject(IdDir); rootTC.componentInstance.ctxProp = 'some_id'; rootTC.detectChanges(); expect(idDir.id).toEqual('some_id'); rootTC.componentInstance.ctxProp = 'other_id'; rootTC.detectChanges(); expect(idDir.id).toEqual('other_id'); async.done(); }); })); it('should allow specifying directives as bindings', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({ template: '', directives: [bind(ChildComp).toClass(ChildComp)] })) .createAsync(MyComp) .then((rootTC) => { rootTC.detectChanges(); expect(rootTC.nativeElement).toHaveText('hello'); async.done(); }); })); it('should read directives metadata from their binding token', inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { tcb.overrideView(MyComp, new viewAnn.View({ template: '
', directives: [bind(PublicApi).toClass(PrivateImpl), NeedsPublicApi] })) .createAsync(MyComp) .then((rootTC) => { async.done(); }); })); it('should support template directives via `