From b8a26ec372b05d51a23a54399788ad0c4785475e Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Fri, 24 Nov 2023 18:54:44 +0000 Subject: [PATCH] Tests WIP 2 --- test/with.test.js | 178 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/test/with.test.js b/test/with.test.js index 525fdc57..a84194e0 100644 --- a/test/with.test.js +++ b/test/with.test.js @@ -68,6 +68,184 @@ describe('with statements', () => { } }); + describe('allows access to `this`', () => { + itSerializes('when `with ()` not included in output', { + in() { + function outer() { + with ({this: 2, a: 3}) { + return () => this; + } + } + return outer.call({x: 1}); + }, + out: '(_a=>function(){return()=>this}.call(_a))({x:1})', + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual({x: 1}); + } + }); + + itSerializes('when `with ()` included in output', { + in() { + const y = 2; + function outer() { + with ({this: 2, a: 3}) { + return () => [this, y]; + } + } + return outer.call({x: 1}); + }, + out: ` + (y=>_a=>function(){ + return a=>{ + with(a)return()=>[this,y] + } + }.call(_a))(2)({x:1})({this:2,a:3}) + `, + validate(fn) { + expect(fn).toBeFunction(); + expect(fn()).toEqual([{x: 1}, 2]); + } + }); + }); + + describe('allows access to `arguments`', () => { + itSerializes('in sloppy mode function', { + in() { + function outer() { + with ({a: 4}) { + return () => arguments; // eslint-disable-line prefer-rest-params + } + } + return outer(1, 2, 3); + }, + out: '(arguments=>a=>{with(a)return()=>arguments})(function(){return arguments}(1,2,3))({a:4})', + validate(fn) { + expect(fn).toBeFunction(); + const args = fn(); + expect(args).toBeArguments(); + expect([...args]).toEqual([1, 2, 3]); + } + }); + + itSerializes('in strict mode function', { + in() { + function outer() { + with ({a: 4}) { + return () => { + 'use strict'; + + return arguments; // eslint-disable-line prefer-rest-params + }; + } + } + return outer(1, 2, 3); + }, + out: ` + (arguments=>a=>{ + with(a)return()=>{"use strict";return arguments} + })(function(){return arguments}(1,2,3))({a:4}) + `, + validate(fn) { + expect(fn).toBeFunction(); + const args = fn(); + expect(args).toBeArguments(); + expect([...args]).toEqual([1, 2, 3]); + } + }); + }); + + describe('allows access to `this` and `arguments` together', () => { + itSerializes('in sloppy mode function', { + in() { + function outer() { + with ({a: 4}) { + return () => [this, arguments]; // eslint-disable-line prefer-rest-params + } + } + return outer.call({x: 1}, 2, 3, 4); + }, + out: ` + ( + (_a,_b)=>function(){ + return a=>{ + with(a)return()=>[this,arguments] + } + }.apply(_a,_b) + )({x:1},function(){return arguments}(2,3,4))({a:4}) + `, + validate(fn) { + expect(fn).toBeFunction(); + const [that, args] = fn(); + expect(that).toEqual({x: 1}); + expect(args).toBeArguments(); + expect([...args]).toEqual([2, 3, 4]); + } + }); + + itSerializes('in strict mode function', { + in() { + function outer() { + with ({a: 4}) { + return () => { + 'use strict'; + + return [this, arguments]; // eslint-disable-line prefer-rest-params + }; + } + } + return outer.call({x: 1}, 2, 3, 4); + }, + out: ` + ( + (_a,_b)=>function(){ + return a=>{ + with(a)return()=>{ + "use strict"; + return[this,arguments] + } + } + }.apply(_a,_b) + )({x:1},function(){return arguments}(2,3,4))({a:4}) + `, + validate(fn) { + expect(fn).toBeFunction(); + const [that, args] = fn(); + expect(that).toEqual({x: 1}); + expect(args).toBeArguments(); + expect([...args]).toEqual([2, 3, 4]); + } + }); + }); + + itSerializes('allows access to `this` when `arguments` also in scope tree', { + in() { + function outer() { + let f; + with ({x: 1}) f = (0, () => [x, this]); // eslint-disable-line no-undef + return [f, () => arguments]; // eslint-disable-line prefer-rest-params + } + return outer.call({y: 2}, 3, 4, 5); + }, + out: `(()=>{ + const a=( + (_a,b)=>function(){ + return[ + ()=>b, + a=>{with(a)return()=>[x,this]} + ] + }.call(_a) + )({y:2},function(){return arguments}(3,4,5));return[a[1]({x:1}),a[0]] + })()`, + validate([fn1, fn2]) { + expect(fn1).toBeFunction(); + expect(fn1()).toEqual([1, {y: 2}]); + const args = fn2(); + expect(args).toBeArguments(); + expect([...args]).toEqual([3, 4, 5]); + } + }); + itSerializes('Alters scope when `with` object property changed', { in() { const obj = {x: 123},