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
+ // Define a custom "Symbol" constructor to attach missing built-in symbols without
22
+ // modifying the global "Symbol" constructor
23
+ // tslint:disable-next-line:variable-name
24
+ const FakeSymbol : SymbolConstructor = ( ( description ?: string ) => Symbol ( description ) ) as any ;
25
+ ( < any > FakeSymbol ) . prototype = Symbol . prototype ;
26
+ for ( const key of Object . getOwnPropertyNames ( Symbol ) ) {
27
+ Object . defineProperty ( FakeSymbol , key , Object . getOwnPropertyDescriptor ( Symbol , key ) ! ) ;
28
+ }
29
+
30
+ // Add "asyncIterator" if missing
31
+ if ( ! hasProperty ( FakeSymbol , "asyncIterator" ) ) Object . defineProperty ( FakeSymbol , "asyncIterator" , { value : Symbol . for ( "Symbol.asyncIterator" ) , configurable : true } ) ;
32
+
33
+ function evaluate ( result : compiler . CompilationResult ) {
34
+ const output = result . getOutput ( sourceFile , "js" ) ! ;
35
+ assert . isDefined ( output ) ;
36
+
37
+ const evaluateText = `(function (module, exports, require, __dirname, __filename, Symbol) { ${ output . text } })` ;
38
+ const evaluateThunk = eval ( evaluateText ) as ( module : any , exports : any , require : ( id : string ) => any , dirname : string , filename : string , symbolConstructor : SymbolConstructor ) => void ;
39
+ const module : { exports : any ; } = { exports : { } } ;
40
+ evaluateThunk ( module , module . exports , noRequire , vpath . dirname ( output . file ) , output . file , FakeSymbol ) ;
41
+ return module ;
42
+ }
43
+
44
+ it ( "sync (es5)" , async ( ) => {
45
+ const module = evaluate ( compile ( `
46
+ let i = 0;
47
+ const iterator = {
48
+ [Symbol.iterator]() { return this; },
49
+ next() {
50
+ switch (i++) {
51
+ case 0: return { value: 1, done: false };
52
+ case 1: return { value: Promise.resolve(2), done: false };
53
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
54
+ default: return { value: undefined: done: true };
55
+ }
56
+ }
57
+ };
58
+ export const output: any[] = [];
59
+ export async function main() {
60
+ for await (const item of iterator) {
61
+ output.push(item);
62
+ }
63
+ }` ) ) ;
64
+ await module . exports . main ( ) ;
65
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
66
+ assert . strictEqual ( module . exports . output [ 1 ] , 2 ) ;
67
+ assert . strictEqual ( module . exports . output [ 2 ] , 3 ) ;
68
+ } ) ;
69
+
70
+ it ( "sync (es2015)" , async ( ) => {
71
+ const module = evaluate ( compile ( `
72
+ let i = 0;
73
+ const iterator = {
74
+ [Symbol.iterator]() { return this; },
75
+ next() {
76
+ switch (i++) {
77
+ case 0: return { value: 1, done: false };
78
+ case 1: return { value: Promise.resolve(2), done: false };
79
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
80
+ default: return { value: undefined: done: true };
81
+ }
82
+ }
83
+ };
84
+ export const output: any[] = [];
85
+ export async function main() {
86
+ for await (const item of iterator) {
87
+ output.push(item);
88
+ }
89
+ }` , { target : ScriptTarget . ES2015 } ) ) ;
90
+ await module . exports . main ( ) ;
91
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
92
+ assert . strictEqual ( module . exports . output [ 1 ] , 2 ) ;
93
+ assert . strictEqual ( module . exports . output [ 2 ] , 3 ) ;
94
+ } ) ;
95
+
96
+ it ( "async (es5)" , async ( ) => {
97
+ const module = evaluate ( compile ( `
98
+ let i = 0;
99
+ const iterator = {
100
+ [Symbol.asyncIterator]() { return this; },
101
+ async next() {
102
+ switch (i++) {
103
+ case 0: return { value: 1, done: false };
104
+ case 1: return { value: Promise.resolve(2), done: false };
105
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
106
+ default: return { value: undefined: done: true };
107
+ }
108
+ }
109
+ };
110
+ export const output: any[] = [];
111
+ export async function main() {
112
+ for await (const item of iterator) {
113
+ output.push(item);
114
+ }
115
+ }` ) ) ;
116
+ await module . exports . main ( ) ;
117
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
118
+ assert . instanceOf ( module . exports . output [ 1 ] , Promise ) ;
119
+ assert . instanceOf ( module . exports . output [ 2 ] , Promise ) ;
120
+ } ) ;
121
+
122
+ it ( "async (es2015)" , async ( ) => {
123
+ const module = evaluate ( compile ( `
124
+ let i = 0;
125
+ const iterator = {
126
+ [Symbol.asyncIterator]() { return this; },
127
+ async next() {
128
+ switch (i++) {
129
+ case 0: return { value: 1, done: false };
130
+ case 1: return { value: Promise.resolve(2), done: false };
131
+ case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
132
+ default: return { value: undefined: done: true };
133
+ }
134
+ }
135
+ };
136
+ export const output: any[] = [];
137
+ export async function main() {
138
+ for await (const item of iterator) {
139
+ output.push(item);
140
+ }
141
+ }` , { target : ScriptTarget . ES2015 } ) ) ;
142
+ await module . exports . main ( ) ;
143
+ assert . strictEqual ( module . exports . output [ 0 ] , 1 ) ;
144
+ assert . instanceOf ( module . exports . output [ 1 ] , Promise ) ;
145
+ assert . instanceOf ( module . exports . output [ 2 ] , Promise ) ;
146
+ } ) ;
147
+ } ) ;
148
+ }
0 commit comments