Skip to content

Commit 80d1c2a

Browse files
committed
Add tests to ensure native setters are called exactly once when components are instantiated
1 parent e920cb2 commit 80d1c2a

File tree

4 files changed

+94
-4
lines changed

4 files changed

+94
-4
lines changed

Diff for: tests/app/logo.png

4.8 KB
Loading

Diff for: tests/app/tests/renderer-tests.ts

+92-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// make sure you import mocha-config before @angular/core
22
import { assert } from "./test-config";
3-
import { Component, ElementRef, Renderer2, NgZone } from "@angular/core";
3+
import { Component, ElementRef, Renderer2, NgZone, ViewChild } from "@angular/core";
44
import { ProxyViewContainer } from "ui/proxy-view-container";
55
import { Red } from "color/known-colors";
66
import { dumpView } from "./test-utils";
@@ -10,6 +10,9 @@ import { StackLayout } from "ui/layouts/stack-layout";
1010
import { ContentView } from "ui/content-view";
1111
import { Button } from "ui/button";
1212
import { NgView } from "nativescript-angular/element-registry";
13+
import { registerElement } from "nativescript-angular/element-registry";
14+
import * as button from "tns-core-modules/ui/button";
15+
import * as view from "tns-core-modules/ui/core/view";
1316

1417
@Component({
1518
template: `<StackLayout><Label text="Layout"></Label></StackLayout>`
@@ -136,6 +139,61 @@ export class NgIfThenElseComponent {
136139
}
137140
}
138141

142+
export class ButtonCounter extends button.Button {
143+
nativeBackgroundRedraws = 0;
144+
backgroundInternalSetNativeCount = 0;
145+
fontInternalSetNativeCount = 0;
146+
147+
[view.backgroundInternalProperty.setNative](value) {
148+
this.backgroundInternalSetNativeCount++;
149+
return super[view.backgroundInternalProperty.setNative](value);
150+
}
151+
[view.fontInternalProperty.setNative](value) {
152+
this.fontInternalSetNativeCount++;
153+
return super[view.fontInternalProperty.setNative](value);
154+
}
155+
_redrawNativeBackground(value: any): void {
156+
this.nativeBackgroundRedraws++;
157+
super._redrawNativeBackground(value);
158+
}
159+
}
160+
ButtonCounter.prototype.recycleNativeView = false;
161+
registerElement("ButtonCounter", () => ButtonCounter);
162+
163+
@Component({
164+
selector: "ng-control-setters-count",
165+
template: `
166+
<StackLayout>
167+
<ButtonCounter #btn1 id="btn1" borderWidth="1" borderColor="gray" borderRadius="16" fontWeight="bold" fontSize="16"></ButtonCounter>
168+
<ButtonCounter #btn2 id="btn2"></ButtonCounter>
169+
<ButtonCounter #btn3 id="btn3" borderWidth="1" borderColor="gray" borderRadius="16" fontWeight="bold" fontSize="16"></ButtonCounter>
170+
<ButtonCounter #btn4 id="btn4" borderRadius="3" style="background-image: url('~/logo.png'); background-position: center; background-repeat: no-repeat; background-size: cover;"></ButtonCounter>
171+
</StackLayout>
172+
`,
173+
styles: [`
174+
#btn2, #btn3, #btn4 {
175+
border-width: 2;
176+
border-color: teal;
177+
border-radius: 20;
178+
font-weight: 400;
179+
font-size: 32;
180+
}`]
181+
})
182+
export class NgControlSettersCount {
183+
@ViewChild("btn1") btn1: ElementRef;
184+
@ViewChild("btn2") btn2: ElementRef;
185+
@ViewChild("btn3") btn3: ElementRef;
186+
@ViewChild("btn3") btn4: ElementRef;
187+
188+
get buttons(): ElementRef[] { return [this.btn1, this.btn2, this.btn3, this.btn4]; }
189+
190+
isAfterViewInit: boolean = false;
191+
192+
ngAfterViewInit() {
193+
this.isAfterViewInit = true;
194+
}
195+
}
196+
139197
@Component({
140198
selector: "ng-for-label",
141199
template: `<Label *ngFor="let item of items" [text]="item"></Label>`
@@ -409,7 +467,6 @@ describe("Renderer createElement", () => {
409467
});
410468
});
411469

412-
413470
describe("Renderer attach/detach", () => {
414471
let testApp: TestApp = null;
415472
let renderer: Renderer2 = null;
@@ -480,3 +537,36 @@ describe("Renderer attach/detach", () => {
480537
});
481538
});
482539

540+
describe("Renderer lifecycle", () => {
541+
let testApp: TestApp = null;
542+
let renderer: Renderer2 = null;
543+
544+
before(() => {
545+
return TestApp.create([], [NgControlSettersCount]).then((app) => {
546+
testApp = app;
547+
renderer = testApp.renderer;
548+
});
549+
});
550+
551+
after(() => {
552+
testApp.dispose();
553+
});
554+
555+
afterEach(() => {
556+
testApp.disposeComponents();
557+
});
558+
559+
it("view native setters are called once on startup", () => {
560+
return testApp.loadComponent(NgControlSettersCount).then((componentRef) => {
561+
assert.isTrue(componentRef.instance.isAfterViewInit, "Expected the NgControlSettersCount to have passed its ngAfterViewInit.");
562+
componentRef.instance.buttons.map(btn => btn.nativeElement).forEach(btn => {
563+
assert.isTrue(btn.isLoaded, `Expected ${btn.id} to be allready loaded.`);
564+
assert.isFalse(btn.isLayoutValid, `Expected ${btn.id}'s layout to be invalid.`);
565+
566+
assert.equal(btn.backgroundInternalSetNativeCount, 1, `Expected ${btn.id} backgroundInternalSetNativeCount to be called just once.`);
567+
assert.equal(btn.fontInternalSetNativeCount, 1, `Expected ${btn.id} fontInternalSetNativeCount to be called just once.`);
568+
assert.equal(btn.nativeBackgroundRedraws, 0, `Expected ${btn.id} nativeBackgroundRedraws to be called after its layout pass.`);
569+
});
570+
});
571+
});
572+
});

Diff for: tests/app/tests/test-app.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class TestApp {
3030
registerTestApp(TestApp, this, appRef);
3131
}
3232

33-
public loadComponent(componentType: Type<any>): Promise<ComponentRef<any>> {
33+
public loadComponent<T>(componentType: Type<T>): Promise<ComponentRef<T>> {
3434
const factory = this.resolver.resolveComponentFactory(componentType);
3535
const componentRef = this.containerRef.createComponent(
3636
factory, this.containerRef.length, this.containerRef.parentInjector);

Diff for: tests/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"nativescript-angular": "../nativescript-angular",
3939
"nativescript-unit-test-runner": "^0.3.4",
4040
"rxjs": "^5.2.0",
41-
"tns-core-modules": "^3.0.0",
41+
"tns-core-modules": "next",
4242
"zone.js": "^0.8.2"
4343
},
4444
"devDependencies": {

0 commit comments

Comments
 (0)