suman icon indicating copy to clipboard operation
suman copied to clipboard

create blocks with isolated scope

Open ORESoftware opened this issue 7 years ago • 3 comments

something like this:

before:

it.cb('sync test', t => {
   t.assert.equal(++count, 2);
   t.assert.equal(t.supply.three, 3);
   t.done()
 });

after:


const v = true;

 it.cb('sync test', isolated(t => {
    // v is not defined
    t.assert.equal(++count, 2);
    t.assert.equal(t.supply.three, 3);
    t.done()
  }));

ORESoftware avatar Jan 02 '18 21:01 ORESoftware

this is done, but an improved way to cover all function types might look like:

function parseArguments(str, offset = 0, depth = 0) {
  const openIndex = str.indexOf('(', offset);
  const closeIndex = str.indexOf(')', offset);

  return (openIndex >= 0 && openIndex < closeIndex)
    ? parseArguments(str, openIndex + 1, depth + 1)
    : (depth > 0)
      ? parseArguments(str, closeIndex + 1, depth - 1)
      : str.slice(0, closeIndex)
}

function isolated (fn) {
  let str = Function.prototype.toString.call(fn);
  let args, body;

  if (/^(?:function\s*\S*\s*)?\(/.test(str)) {
    const offset = str.indexOf('(') + 1;
    args = parseArguments(str.slice(offset));
    str = str.slice(offset + args.length + 1);
  } else {
    const offset = str.indexOf('=');
    args = str.slice(0, offset).trim();
    str = str.slice(offset);
  }

  if (/^\s*(?:=>)?\s*{/.test(str)) {
    body = str.slice(str.indexOf('{') + 1, str.lastIndexOf('}'));
  } else {
    body = 'return ' + str.slice(str.indexOf('>') + 1).trim()
  }

  // 'use strict' directive prevents leaking scope
  return eval(`'use strict';(function(${args}){${body}})`);
}

let processed = [
  isolated(function named ({ h }, i = () => {}) {
    console.log(h);
    return i;
  }),
  isolated(({ h }, i = () => {}) => {
    console.log(h);
    return i;
  }),
  isolated(h => {
    console.log(h);
  }),
  isolated(({ h }, i = () => {}) => (
    console.log(h),
    i
  )),
  isolated(h =>
    console.log(h)
  )
];

processed.forEach((fn) => console.log(fn.toString()))

ORESoftware avatar Jan 03 '18 07:01 ORESoftware

see:

https://stackoverflow.com/questions/48071628/create-helper-function-to-run-a-function-in-an-isolated-scope/48073135

ORESoftware avatar Jan 03 '18 07:01 ORESoftware

or this:

function isolated (fn) {
  return new Function(`
    with (new Proxy({}, {
      has() { return true; },
      get(target, property) {
        if (typeof property !== 'string') return target[property];
        throw new ReferenceError(property + ' accessed from isolated scope');
      }
    })) return ${Function.prototype.toString.call(fn)}
  `).call(new Proxy(function(){}, new Proxy({}, {
    get() { throw new ReferenceError('this accessed from isolated scope'); }
  })));
}

ORESoftware avatar Jan 03 '18 21:01 ORESoftware