GithubHelp home page GithubHelp logo

injectr's Introduction

injectr

Finally, a solution to node.js dependency injection

Install it

npm install injectr. Boom.

Use it

var injectr = require('injectr');
var myScript = injectr('../lib/myScript.js', {
    fs : mockFs,
    crypto : mockCrypto
});

Now when you require('fs') or require('crypto') in myScript.js, what you get is mockFs or mockCrypto.

Treat injectr like require for your tests, with a second argument to pass in your mocks.

Paths are now relative to the current file, just like require. Please update your tests if you are upgrading from v0.4 or below.

Context

injectr gives you access to the context of the injectr'd file via an optional third argument. Provide an object, and injectr will modify it as necessary and use that as the context.

var myScript = injectr('../lib/myScript.js', {}, {
    Date : mockDate,
    setTimeout : mockSetTimeout
});

As of version 0.4, injectr doesn't create a full node.js context for you to use. Instead, it isolates your script in its own sandbox, allowing you to include mocks of only the bits that your script needs.

CoffeeScript

injectr compiles any *.coffee files for you, so you can test your CoffeeScript too. The default settings can be changed by overwriting the injectr.onload function. It takes the filename and file contents as arguments, and returns the compiled script.

Share it

injectr is under the MIT License. Fork it. Modify it. Pass it around.

injectr's People

Contributors

jhnns avatar nathanmacinnes avatar philtoms avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

injectr's Issues

conflict when there are folder and file with the same name

/app
app.js

this doesn't work:

var injectr = require('injectr');

var path = require('path');
var app_path = __dirname + '/../app';
app_path = path.normalize(app_path);

global.app = injectr(app_path, {
  'some_module: {}
  }
});

but this does

var injectr = require('injectr');

var path = require('path');
var app_path = __dirname + '/../app.js';
app_path = path.normalize(app_path);

global.app = injectr(app_path, {
  'some_module: {}
  }
});

Using injectr with babel

I have injectr.onload set up to run files through babel like so:

injectr.onload = (file, content) => {
  return require('babel').transform(content, {
    filename: file,
    optional: ['runtime', 'es7.classProperties', 'es7.objectRestSpread']
  }).code;
};

This works but it seems like the polyfilled methods such as [1, 2, 3].includes(2) have to be written as Array.includes([1, 2, 3], 2) instead. Even if I prepend the file content with require('babel/polyfill') I get the same result.

Do you know why the polyfilled methods wouldn't be usable with an injected module?

Can't handle require statements that begin with "../"

It only works if you insert "./../", this does not follow the spec for require, and is not explained in the readme.
If you do not implement support for "../", it would be cool if you at least write about it in the readme.

Should use caching

Should cache the contents of an injectr'd file so that we can inexpensively run it in setup to reload the environment every time, rather than once at the beginning.

Should allow context variable injection

I want to be able to inject objects into the current context. Implementation would be pretty straightforward; it's the interface which is difficult. The interface I've got in my head at the moment is something like this:

injectr(file, {
    deps : {
        fs : mockFs
    },
    context : {
        varName : obj
    }
});

This would of course be an alternative to the existing interface, so injectr would need to check if the object has deps and context properties, and if it does, go with this structure.

This would allow injectr to become more than just a dependency injector for testing.

Sync to NPM

I don't suppose you could do a new release to npm? Coffeescript support in particular isn't in the published version yet.

require.resolve

require.resolve should be implemented.

This is a bit more tricky than the other node globals, as it needs to resolve relative to the injectr'd file.

No useful errors

When injectr'd files throw errors, they aren't recorded anywhere. This is possibly linked to #3, as when console is defined, the errors might be written to it.

Using module.require

According to the node.js manual:

The module.require method provides a way to load a module as if require() was called from the original module.

Note that in order to do this, you must get a reference to the module object. Since require() returns the exports, and the module is typically only available within a specific module's code, it must be explicitly exported in order to be used.

injectr doesn't support this. This isn't a commonly used feature, so implementing it is low priority.

works only with absolute path

var injectr = require('injectr');
var app_path = './../app.js';
global.app = injectr(app_path, {
  'some_module: {}
  }
});

doesn't work, but

var injectr = require('injectr');

var path = require('path');
var app_path = __dirname + '/../app.js';
app_path = path.normalize(app_path);

global.app = injectr(app_path, {
  'some_module: {}
  }
});

does work

__dirname undefined

inside app.js

var application_root = __dirname;

Additionally require.main and __filename undefined too

context.module overwritten on setup

I want to be able to add module.parent to my context but this object is overwritten during the setup. Changing the context.module code to the following allows this:

context.module = context.module || {}; 
context.module.exports = {};

module alias urls not working

injectr is not working when I use npm aliases as the module path.

injectr( '../../components/this-component/index.js',
   {
       '#/components/some-component': MockComponent,
   }).default;

Inside the this-component I am importing SomeComponent from '#/components/some-component'. Inside the injectr I am unable to do it though. I am able to use relative path to make it work, but the components loaded through injectr is not found inside my ThisComponent. Any work-arounds or fixes?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.