mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-27 01:33:59 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			266 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Reviewed
 | |
| function shouldBe(expected, actual, msg) {
 | |
|     if (msg === void 0)
 | |
|         msg = "";
 | |
|     else
 | |
|         msg = " for " + msg;
 | |
|     if (actual !== expected)
 | |
|         throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
 | |
| }
 | |
| 
 | |
| function shouldBeAsync(expected, run) {
 | |
|     let actual;
 | |
|     var hadError = false;
 | |
|     run().then(function(value) { actual = value; },
 | |
|                function(error) { hadError = true; actual = error; });
 | |
|     drainMicrotasks();
 | |
| 
 | |
|     if (hadError)
 | |
|         throw actual;
 | |
| 
 | |
|     shouldBe(expected, actual);
 | |
| }
 | |
| 
 | |
| class BaseWrongClass {
 | |
|     baseClassValue() {
 | |
|         return "wrong #1";
 | |
|     }
 | |
|     get property() {
 | |
|         return "wrong #2";
 | |
|     }
 | |
| }
 | |
| 
 | |
| function shouldBeAsyncAndStoreBind(expected, run) {
 | |
|     shouldBeAsync(expected, run);
 | |
|     shouldBeAsync(expected, run.bind({}));
 | |
|     shouldBeAsync(expected, run.bind(1));
 | |
|     shouldBeAsync(expected, run.bind(undefined));
 | |
|     const obj = { 
 | |
|         property : 'wrong value #1', 
 | |
|         baseClassValue : () => 'worng value #2'
 | |
|     };
 | |
|     shouldBeAsync(expected, run.bind(obj));
 | |
|     shouldBeAsync(expected, run.bind(new BaseWrongClass()));
 | |
| }
 | |
| 
 | |
| class BaseClass {
 | |
|     baseClassValue() {
 | |
|         return "BaseClassValue";
 | |
|     }
 | |
|     get property() {
 | |
|         return "test!";
 | |
|     }
 | |
| }
 | |
| 
 | |
| function runSomething(callback) {
 | |
|     callback();
 | |
| }
 | |
| 
 | |
| class ChildClass extends BaseClass {
 | |
|     classValue() {
 | |
|         return "classValue";
 | |
|     }
 | |
|     get classProperty() {
 | |
|         return "classProperty";
 | |
|     }
 | |
|     asyncValueExp() {
 | |
|         return async x => 'value';
 | |
|     }
 | |
|     asyncValueBody() {
 | |
|         return async x => { return 'value'; };
 | |
|     }
 | |
|     asyncThisPropExp() {
 | |
|         return async x => this.classProperty;
 | |
|     }
 | |
|     asyncThisPropBody() {
 | |
|         return async x => { return this.classProperty; };
 | |
|     }
 | |
|     asyncThisPropWithAwaitBody() {
 | |
|         return async x => { 
 | |
|             var self = this.classProperty; 
 | |
|             self = await 'abc';  
 | |
|             return this.classProperty; 
 | |
|         };
 | |
|     }
 | |
|     asyncThisPropInEvalExp() {
 | |
|         return async x => eval('this.classProperty');
 | |
|     }
 | |
|     asyncThisPropInEvalBody() {
 | |
|         return async x => { return eval('this.classProperty'); };
 | |
|     }
 | |
|     asyncThisPropInEvalWithAwaitBody() {
 | |
|         return async x => { 
 | |
|             var self = eval('this.classProperty');
 | |
|             await 'abc';
 | |
|             return eval('this.classProperty'); 
 | |
|         };
 | |
|     }
 | |
|     asyncThisValueExp() {
 | |
|         return async x => this.classValue();
 | |
|     }
 | |
|     asyncThisValueBody() {
 | |
|         return async x => { return this.classValue(); };
 | |
|     }
 | |
|     asyncThisValueBodyWithAwait() {
 | |
|         return async x => { 
 | |
|             var self = this.classValue();
 | |
|             await 'self'; 
 | |
|             return this.classValue(); 
 | |
|         };
 | |
|     }
 | |
|     asyncThisValueInEvalExp() {
 | |
|         return async x => eval('this.classValue()');
 | |
|     }
 | |
|     asyncThisValueInEvalBody() {
 | |
|         return async x => { return eval('this.classValue()'); };
 | |
|     }
 | |
|     asyncThisValueInEvalWithAwaitBody() {
 | |
|         return async x => { 
 | |
|             var self = eval('this.classValue()');
 | |
|             await 'self'; 
 | |
|             return eval('this.classValue()'); 
 | |
|         };
 | |
|     }
 | |
| }
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("value", new ChildClass().asyncValueExp());
 | |
| shouldBeAsyncAndStoreBind("value", new ChildClass().asyncValueBody());
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("classProperty", new ChildClass().asyncThisPropExp());
 | |
| shouldBeAsyncAndStoreBind("classProperty", new ChildClass().asyncThisPropBody());
 | |
| shouldBeAsyncAndStoreBind("classProperty", new ChildClass().asyncThisPropWithAwaitBody());
 | |
| shouldBeAsyncAndStoreBind("classProperty", new ChildClass().asyncThisPropWithAwaitBody());
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("classProperty", new ChildClass().asyncThisPropInEvalExp());
 | |
| shouldBeAsyncAndStoreBind("classProperty", new ChildClass().asyncThisPropInEvalBody());
 | |
| shouldBeAsyncAndStoreBind("classProperty", new ChildClass().asyncThisPropInEvalWithAwaitBody());
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("classValue", new ChildClass().asyncThisValueExp());
 | |
| shouldBeAsyncAndStoreBind("classValue", new ChildClass().asyncThisValueBody());
 | |
| shouldBeAsyncAndStoreBind("classValue", new ChildClass().asyncThisValueBodyWithAwait());
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("classValue", new ChildClass().asyncThisValueInEvalExp());
 | |
| shouldBeAsyncAndStoreBind("classValue", new ChildClass().asyncThisValueInEvalBody());
 | |
| shouldBeAsyncAndStoreBind("classValue", new ChildClass().asyncThisValueInEvalWithAwaitBody());
 | |
| 
 | |
| class ChildClass2 extends BaseClass {
 | |
|     constructor() {
 | |
|         super();
 | |
|         this.value = 'internalValue';
 | |
|         return async () => this.classValue() + ' ' + this.classProperty;
 | |
|     }
 | |
|     classStaticValue() {
 | |
|         return "classStaticValue";
 | |
|     }
 | |
|     classValue() {
 | |
|         return this.value;
 | |
|     }
 | |
|     get classProperty() {
 | |
|         return "classProperty";
 | |
|     }
 | |
| }
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("internalValue classProperty", new ChildClass2());
 | |
| 
 | |
| class ChildClass3 extends BaseClass {
 | |
|     constructor() {
 | |
|         super();
 | |
|         this.internalValue = 'internalValue';
 | |
|         return async () => {
 | |
|             var self = this.classValue() + ' ' + this.classProperty;
 | |
|             await 'self';
 | |
|             return this.classValue() + ' ' + this.classProperty;
 | |
|         }
 | |
|     }
 | |
|     classValue() {
 | |
|         return "classValue";
 | |
|     }
 | |
|     get classProperty() {
 | |
|         return "classProperty";
 | |
|     }
 | |
| }
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("classValue classProperty", new ChildClass3());
 | |
| 
 | |
| var promiseHolder = {};
 | |
| var promise = new Promise((resolve, reject) => {
 | |
|     promiseHolder.resolve = resolve;
 | |
|     promiseHolder.reject = reject;
 | |
| });
 | |
| 
 | |
| class ChildClass4 extends BaseClass {
 | |
|     constructor() {
 | |
|         var arr = async () => {
 | |
|             var doSomeStaff = () => {};
 | |
|             doSomeStaff();
 | |
|             await promise;
 | |
|             return this.classValue() + ' ' + this.classProperty;
 | |
|         };
 | |
|         arr();
 | |
|         super();
 | |
|         this.internalValue = 'internalValue';
 | |
|         return async () => {
 | |
|             await 'await';
 | |
|             promiseHolder.resolve();
 | |
|             return this.classValue() + ' ' + this.classProperty;;
 | |
|         };
 | |
|     }
 | |
|     classValue() {
 | |
|         return "classValue";
 | |
|     }
 | |
|     get classProperty() {
 | |
|         return "classProperty";
 | |
|     }
 | |
| }
 | |
| 
 | |
| shouldBeAsyncAndStoreBind("classValue classProperty", new ChildClass4());
 | |
| 
 | |
| class ChildClass5 extends BaseClass {
 | |
|     constructor(result) {
 | |
|         const arr = async () => this.id;
 | |
|         arr().then(()=>{}, e => { result.error = e; });
 | |
|     }
 | |
| }
 | |
| 
 | |
| class ChildClass6 extends BaseClass {
 | |
|     constructor(result) {
 | |
|         const arr = async () => { 
 | |
|             let z = this.id;
 | |
|         };
 | |
|         arr().then(()=>{}, e => { result.error = e; });
 | |
|         super();
 | |
|     }
 | |
| }
 | |
| 
 | |
| class ChildClass7 extends BaseClass {
 | |
|     constructor(result) {
 | |
|         const arr = async () => this.id;
 | |
|         arr().then(()=>{}, e => { result.error = e; });
 | |
|         super();
 | |
|     }
 | |
| }
 | |
| 
 | |
| class ChildClass8 extends BaseClass {
 | |
|     constructor(result) {
 | |
|         const arr = async () => { let i  = this.id; super(); };
 | |
|         arr().then(()=>{}, e => { result.error = e; });
 | |
|     }
 | |
| }
 | |
| 
 | |
| function checkTDZDuringCreate(klass) {
 | |
|     let asyncError = {};
 | |
|     try {
 | |
|         var c = new klass(asyncError);
 | |
|     } catch(e) {
 | |
|         // We do not care about this error
 | |
|     }
 | |
|     drainMicrotasks();
 | |
|     const error = asyncError.error instanceof ReferenceError && asyncError.error.toString() === 'ReferenceError: Cannot access uninitialized variable.';
 | |
|     if (!error) throw new Error('TDZ error is expected, but appeared:' + asyncError.error);
 | |
| }
 | |
| 
 | |
| checkTDZDuringCreate(ChildClass5);
 | |
| checkTDZDuringCreate(ChildClass6);
 | |
| checkTDZDuringCreate(ChildClass7);
 | |
| checkTDZDuringCreate(ChildClass8);
 |