felixge / node-sandboxed-module

A sandboxed node.js module loader that lets you inject dependencies into your modules.
MIT License
342 stars 42 forks source link

nyc builtin source transformer #63

Open skeggse opened 7 years ago

skeggse commented 7 years ago

Related to https://github.com/felixge/node-sandboxed-module/issues/25.

It'd be nice if the istanbul transformer also supported nyc, which in turn supports subprocesses. I got this working with the following voodoo, but I wasn't sure whether this was the supported mechanism per https://github.com/istanbuljs/nyc. Thoughts? Is this in scope?

function maybeCoverage() {
  return Object.keys(require.cache).some((path) => /node_modules\/nyc/.test(path));
}

SandboxedModule.require('.../index.js', {
  // Voodoo magic to support nyc.
  sourceTransformers: maybeCoverage() ? {
    nyc(source) {
      const Instrumenter = require('nyc/lib/instrumenters/istanbul'),
        instrumenter = Instrumenter(process.cwd(), {}),
        instrumentMethod = instrumenter.instrumentSync.bind(instrumenter);
      return instrumentMethod(source, this.filename);
    }
  } : {}
});
NathanGRomano commented 6 years ago

Where should I put this snippet?

skeggse commented 6 years ago

In a test fixture or mock where you have access to SandboxedModule.

mariecl commented 6 years ago

The way I use the above snippet is the following:

nycTransformer.js (placed at the root of my test folder)

'use strict';

function maybeCoverage() {
  return Object.keys(require.cache).some((path) => (/node_modules\/nyc/).test(path));
}

module.exports = maybeCoverage() ? {
  nyc(source) {
    const Instrumenter = require('nyc/lib/instrumenters/istanbul');
    const instrumenter = Instrumenter(process.cwd(), {});
    const instrumentMethod = instrumenter.instrumentSync.bind(instrumenter);
    return instrumentMethod(source, this.filename);
  },
} : {};

Then in test.js

'use strict';

const assert = require('assert');
const nycTransformer = require('../nycTransformer');
const sandbox = require('sandboxed-module');

it('should do something', function onTest() {
  const sandboxedFile = sandbox.require('path', {
     singleOnly: true,
     requires: { /* */},
     sourceTransformers: nycTransformer,
  });
  assert('something');
});

I hope that helps!

NathanGRomano commented 6 years ago

Thank you

On Wed, Feb 7, 2018 at 10:27 AM, Marie notifications@github.com wrote:

The way I use the above snippet is the following:

nycTransformer.js (placed at the root of my test folder)

'use strict'; function maybeCoverage() { return Object.keys(require.cache).some((path) => (/node_modules\/nyc/).test(path)); } module.exports = maybeCoverage() ? { nyc(source) { const Instrumenter = require('nyc/lib/instrumenters/istanbul'); const instrumenter = Instrumenter(process.cwd(), {}); const instrumentMethod = instrumenter.instrumentSync.bind(instrumenter); return instrumentMethod(source, this.filename); }, } : {};

Then in test.js

'use strict'; const assert = require('assert');const nycTransformer = require('../nycTransformer');const sandbox = require('sandboxed-module'); it('should do something', function onTest() { const sandboxedFile = sandbox.require('path', { singleOnly: true, requires: { / /}, sourceTransformers: nycTransformer, }); assert('something'); });

I hope that helps!

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/felixge/node-sandboxed-module/issues/63#issuecomment-363804202, or mute the thread https://github.com/notifications/unsubscribe-auth/AAlKm5qqfOM-8b_N33kYUMqUEXtMmbBpks5tScDFgaJpZM4OjSy- .