X Tutup
Skip to content

Commit c72ed99

Browse files
committed
fix(testing): remove test zone for now and rely on returned promises
Adds tests for public Dart and TS frameworks to make sure that components with templateUrl can be created by the TestComponentBuilder. Closes angular#6359 Closes angular#6601
1 parent 78bfdf7 commit c72ed99

File tree

5 files changed

+72
-72
lines changed

5 files changed

+72
-72
lines changed

modules/angular2/src/testing/testing.ts

Lines changed: 18 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -126,77 +126,23 @@ function _isPromiseLike(input): boolean {
126126
return input && !!(input.then);
127127
}
128128

129-
function runInTestZone(fnToExecute, finishCallback, failCallback): any {
130-
var pendingMicrotasks = 0;
131-
var pendingTimeouts = [];
132-
133-
var ngTestZone = (<Zone>global.zone)
134-
.fork({
135-
onError: function(e) { failCallback(e); },
136-
'$run': function(parentRun) {
137-
return function() {
138-
try {
139-
return parentRun.apply(this, arguments);
140-
} finally {
141-
if (pendingMicrotasks == 0 && pendingTimeouts.length == 0) {
142-
finishCallback();
143-
}
144-
}
145-
};
146-
},
147-
'$scheduleMicrotask': function(parentScheduleMicrotask) {
148-
return function(fn) {
149-
pendingMicrotasks++;
150-
var microtask = function() {
151-
try {
152-
fn();
153-
} finally {
154-
pendingMicrotasks--;
155-
}
156-
};
157-
parentScheduleMicrotask.call(this, microtask);
158-
};
159-
},
160-
'$setTimeout': function(parentSetTimeout) {
161-
return function(fn: Function, delay: number, ...args) {
162-
var id;
163-
var cb = function() {
164-
fn();
165-
ListWrapper.remove(pendingTimeouts, id);
166-
};
167-
id = parentSetTimeout(cb, delay, args);
168-
pendingTimeouts.push(id);
169-
return id;
170-
};
171-
},
172-
'$clearTimeout': function(parentClearTimeout) {
173-
return function(id: number) {
174-
parentClearTimeout(id);
175-
ListWrapper.remove(pendingTimeouts, id);
176-
};
177-
},
178-
});
179-
180-
return ngTestZone.run(fnToExecute);
181-
}
182-
183129
function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | AnyTestFn,
184130
testTimeOut: number): void {
185131
var timeOut = testTimeOut;
186132

187133
if (testFn instanceof FunctionWithParamTokens) {
188134
jsmFn(name, (done) => {
189-
var finishCallback = () => {
190-
// Wait one more event loop to make sure we catch unreturned promises and
191-
// promise rejections.
192-
setTimeout(done, 0);
193-
};
194-
var returnedTestValue =
195-
runInTestZone(() => testInjector.execute(testFn), finishCallback, done.fail);
135+
var returnedTestValue;
136+
try {
137+
returnedTestValue = testInjector.execute(testFn);
138+
} catch (err) {
139+
done.fail(err);
140+
return;
141+
}
196142

197143
if (testFn.isAsync) {
198144
if (_isPromiseLike(returnedTestValue)) {
199-
(<Promise<any>>returnedTestValue).then(null, (err) => { done.fail(err); });
145+
(<Promise<any>>returnedTestValue).then(() => { done(); }, (err) => { done.fail(err); });
200146
} else {
201147
done.fail('Error: injectAsync was expected to return a promise, but the ' +
202148
' returned value was: ' + returnedTestValue);
@@ -206,6 +152,7 @@ function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | An
206152
done.fail('Error: inject returned a value. Did you mean to use injectAsync? Returned ' +
207153
'value was: ' + returnedTestValue);
208154
}
155+
done();
209156
}
210157
}, timeOut);
211158
} else {
@@ -232,17 +179,17 @@ export function beforeEach(fn: FunctionWithParamTokens | AnyTestFn): void {
232179
// The test case uses inject(). ie `beforeEach(inject([ClassA], (a) => { ...
233180
// }));`
234181
jsmBeforeEach((done) => {
235-
var finishCallback = () => {
236-
// Wait one more event loop to make sure we catch unreturned promises and
237-
// promise rejections.
238-
setTimeout(done, 0);
239-
};
240182

241-
var returnedTestValue =
242-
runInTestZone(() => testInjector.execute(fn), finishCallback, done.fail);
183+
var returnedTestValue;
184+
try {
185+
returnedTestValue = testInjector.execute(fn);
186+
} catch (err) {
187+
done.fail(err);
188+
return;
189+
}
243190
if (fn.isAsync) {
244191
if (_isPromiseLike(returnedTestValue)) {
245-
(<Promise<any>>returnedTestValue).then(null, (err) => { done.fail(err); });
192+
(<Promise<any>>returnedTestValue).then(() => { done(); }, (err) => { done.fail(err); });
246193
} else {
247194
done.fail('Error: injectAsync was expected to return a promise, but the ' +
248195
' returned value was: ' + returnedTestValue);
@@ -252,6 +199,7 @@ export function beforeEach(fn: FunctionWithParamTokens | AnyTestFn): void {
252199
done.fail('Error: inject returned a value. Did you mean to use injectAsync? Returned ' +
253200
'value was: ' + returnedTestValue);
254201
}
202+
done();
255203
}
256204
});
257205
} else {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<span>from external template</span>

modules/angular2/test/testing/testing_public_spec.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ class TestViewProvidersComp {
9494
constructor(private fancyService: FancyService) {}
9595
}
9696

97+
@Component({selector: 'external-template-comp'})
98+
@View({templateUrl: '/base/modules/angular2/test/testing/static_assets/test.html'})
99+
class ExternalTemplateComp {
100+
}
101+
102+
@Component({selector: 'bad-template-comp'})
103+
@View({templateUrl: 'non-existant.html'})
104+
class BadTemplateUrl {
105+
}
97106

98107
export function main() {
99108
describe('angular2 jasmine matchers', () => {
@@ -273,11 +282,12 @@ export function main() {
273282
restoreJasmineIt();
274283
});
275284

276-
it('should fail when an asynchronous error is thrown', (done) => {
285+
// TODO(juliemr): reenable this test when we are using a test zone and can capture this error.
286+
xit('should fail when an asynchronous error is thrown', (done) => {
277287
var itPromise = patchJasmineIt();
278288

279289
it('throws an async error',
280-
inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); }));
290+
injectAsync([], () => { setTimeout(() => { throw new Error('bar'); }, 0); }));
281291

282292
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
283293
expect(err.message).toEqual('bar');
@@ -304,6 +314,19 @@ export function main() {
304314
restoreJasmineIt();
305315
});
306316

317+
it('should fail when an XHR fails', (done) => {
318+
var itPromise = patchJasmineIt();
319+
320+
it('should fail with an error from a promise',
321+
injectAsync([TestComponentBuilder], (tcb) => { return tcb.createAsync(BadTemplateUrl); }));
322+
323+
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
324+
expect(err).toEqual('Failed to load non-existant.html');
325+
done();
326+
});
327+
restoreJasmineIt();
328+
});
329+
307330
describe('using beforeEachProviders', () => {
308331
beforeEachProviders(() => [bind(FancyService).toValue(new FancyService())]);
309332

@@ -428,5 +451,16 @@ export function main() {
428451
.toHaveText('injected value: mocked out value');
429452
});
430453
}));
454+
455+
it('should allow an external templateUrl',
456+
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
457+
458+
return tcb.createAsync(ExternalTemplateComp)
459+
.then((componentFixture) => {
460+
componentFixture.detectChanges();
461+
expect(componentFixture.debugElement.nativeElement)
462+
.toHaveText('from external template\n');
463+
});
464+
}));
431465
});
432466
}

modules_dart/angular2_testing/test/angular2_testing_test.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ class TestService {
2626
}
2727
}
2828

29+
@Component(selector: 'external-template-cmp')
30+
@View(templateUrl: 'test_template.html')
31+
class ExternalTemplateComponent {
32+
ExternalTemplateComponent() {
33+
}
34+
}
35+
2936
class MyToken {}
3037

3138
const TEMPLATE =
@@ -79,6 +86,15 @@ void main() {
7986
expect(rootTC.debugElement.nativeElement.text, equals('1;2;3;'));
8087
});
8188

89+
ngTest('should allow a component using a templateUrl', (TestComponentBuilder tcb) async {
90+
var rootTC = await tcb
91+
.createAsync(ExternalTemplateComponent);
92+
93+
rootTC.detectChanges();
94+
95+
expect(rootTC.debugElement.nativeElement.text, equals('from external template\n'));
96+
});
97+
8298
group('expected failures', () {
8399
ngTest('no type in param list', (notTyped) {
84100
expect(1, equals(2));
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<span>from external template</span>

0 commit comments

Comments
 (0)
X Tutup