1
+ /// <reference path="..\harness.ts" />
2
+
3
+ namespace ts {
4
+ declare var Symbol : SymbolConstructor ;
5
+
6
+ describe ( "forAwaitOfEvaluation" , ( ) => {
7
+ const sourceFile = vpath . combine ( vfs . srcFolder , "source.ts" ) ;
8
+
9
+ function compile ( sourceText : string , options ?: CompilerOptions ) {
10
+ const fs = vfs . createFromFileSystem ( Harness . IO , /*ignoreCase*/ false ) ;
11
+ fs . writeFileSync ( sourceFile , sourceText ) ;
12
+ const compilerOptions : CompilerOptions = { target : ScriptTarget . ES5 , module : ModuleKind . CommonJS , lib : [ "lib.esnext.d.ts" ] , ...options } ;
13
+ const host = new fakes . CompilerHost ( fs , compilerOptions ) ;
14
+ return compiler . compileFiles ( host , [ sourceFile ] , compilerOptions ) ;
15
+ }
16
+
17
+ function noRequire ( id : string ) {
18
+ throw new Error ( `Module '${ id } ' could not be found.` ) ;
19
+ }
20
+
21
+ // tslint:disable-next-line:variable-name
22
+ const FakeSymbol : SymbolConstructor = ( ( description ?: string ) => Symbol ( description ) ) as any ;
23
+ ( < any > FakeSymbol ) . prototype = Symbol . prototype ;
24
+ for ( const key of Object . getOwnPropertyNames ( Symbol ) ) {
25
+ Object . defineProperty ( FakeSymbol , key , Object . getOwnPropertyDescriptor ( Symbol , key ) ! ) ;
26
+ }
27
+ ( < any > FakeSymbol ) . asyncIterator = ( < any > FakeSymbol ) . asyncIterator || Symbol . for ( "Symbol.asyncIterator" ) ;
28
+
29
+ function evaluate ( result : compiler . CompilationResult ) {
30
+ const output = result . getOutput ( sourceFile , "js" ) ! ;
31
+ assert . isDefined ( output ) ;
32
+
33
+ const evaluateText = `(function (module, exports, require, __dirname, __filename, Symbol) { ${ output . text } })` ;
34
+ const evaluateThunk = eval ( evaluateText ) as ( module : any , exports : any , require : ( id : string ) => any , dirname : string , filename : string , symbolConstructor : SymbolConstructor ) => void ;
35
+ const module : { exports : any ; } = { exports : { } } ;
36
+ evaluateThunk ( module , module . exports , noRequire , vpath . dirname ( output . file ) , output . file , FakeSymbol ) ;
37
+ return module ;
38
+ }
39
+
40
+ it ( "sync (es5)" , async ( ) => {
41
+ const module = evaluate ( compile ( `
42
+ let i = 0;
43
+ const iterator = {
44
+ [Symbol.iterator]() { return this; },
45
+ next() {
46
+ switch (i++) {
47
+ case 0: return { value: 1, done: false };
48
+ case 1: return { value: Promise.resolve(2), done: false };
49
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
50
+ default: return { value: undefined: done: true };
51
+ }
52
+ }
53
+ };
54
+ export const output: any[] = [];
55
+ export async function main() {
56
+ for await (const item of iterator) {
57
+ output.push(item);
58
+ }
59
+ }` ) ) ;
60
+ await module . exports . main ( ) ;
61
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
62
+ assert . strictEqual ( module . exports . output [ 1 ] , 2 ) ;
63
+ assert . strictEqual ( module . exports . output [ 2 ] , 3 ) ;
64
+ } ) ;
65
+
66
+ it ( "sync (es2015)" , async ( ) => {
67
+ const module = evaluate ( compile ( `
68
+ let i = 0;
69
+ const iterator = {
70
+ [Symbol.iterator]() { return this; },
71
+ next() {
72
+ switch (i++) {
73
+ case 0: return { value: 1, done: false };
74
+ case 1: return { value: Promise.resolve(2), done: false };
75
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
76
+ default: return { value: undefined: done: true };
77
+ }
78
+ }
79
+ };
80
+ export const output: any[] = [];
81
+ export async function main() {
82
+ for await (const item of iterator) {
83
+ output.push(item);
84
+ }
85
+ }` , { target : ScriptTarget . ES2015 } ) ) ;
86
+ await module . exports . main ( ) ;
87
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
88
+ assert . strictEqual ( module . exports . output [ 1 ] , 2 ) ;
89
+ assert . strictEqual ( module . exports . output [ 2 ] , 3 ) ;
90
+ } ) ;
91
+
92
+ it ( "async (es5)" , async ( ) => {
93
+ const module = evaluate ( compile ( `
94
+ let i = 0;
95
+ const iterator = {
96
+ [Symbol.asyncIterator]() { return this; },
97
+ async next() {
98
+ switch (i++) {
99
+ case 0: return { value: 1, done: false };
100
+ case 1: return { value: Promise.resolve(2), done: false };
101
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
102
+ default: return { value: undefined: done: true };
103
+ }
104
+ }
105
+ };
106
+ export const output: any[] = [];
107
+ export async function main() {
108
+ for await (const item of iterator) {
109
+ output.push(item);
110
+ }
111
+ }` ) ) ;
112
+ await module . exports . main ( ) ;
113
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
114
+ assert . instanceOf ( module . exports . output [ 1 ] , Promise ) ;
115
+ assert . instanceOf ( module . exports . output [ 2 ] , Promise ) ;
116
+ } ) ;
117
+
118
+ it ( "async (es2015)" , async ( ) => {
119
+ const module = evaluate ( compile ( `
120
+ let i = 0;
121
+ const iterator = {
122
+ [Symbol.asyncIterator]() { return this; },
123
+ async next() {
124
+ switch (i++) {
125
+ case 0: return { value: 1, done: false };
126
+ case 1: return { value: Promise.resolve(2), done: false };
127
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
128
+ default: return { value: undefined: done: true };
129
+ }
130
+ }
131
+ };
132
+ export const output: any[] = [];
133
+ export async function main() {
134
+ for await (const item of iterator) {
135
+ output.push(item);
136
+ }
137
+ }` , { target : ScriptTarget . ES2015 } ) ) ;
138
+ await module . exports . main ( ) ;
139
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
140
+ assert . instanceOf ( module . exports . output [ 1 ] , Promise ) ;
141
+ assert . instanceOf ( module . exports . output [ 2 ] , Promise ) ;
142
+ } ) ;
143
+ } ) ;
144
+ }
0 commit comments