Comparing version 1.1.0 to 1.2.0
75
index.js
@@ -35,3 +35,3 @@ // | ||
var mock = cache | ||
// Find the tests that match ... | ||
// Find the tests that match | ||
.filter(function(mockDef) { | ||
@@ -49,9 +49,10 @@ var test = mockDef.test; | ||
// If there is an alias we check if the string starts | ||
// with the desired test | ||
if( 'alias' === mockDef._type ) | ||
return req.startsWith( mockDef.test ); | ||
// Last case: we simply have no idea | ||
// Thus, we use a strict equal | ||
return test === req; | ||
}) | ||
// ... and grab the mocked value from it | ||
.map( function(mockDef) { | ||
return mockDef.value; | ||
}); | ||
@@ -62,7 +63,21 @@ | ||
// uses `Array.prototype.unshift` we always use the mock added at last. | ||
if( mock.length ) | ||
return mock[0]; | ||
if( mock.length ) { | ||
mock = mock[0]; | ||
value = mock.value; | ||
// Aliases are a bit special | ||
if( 'alias' !== mock._type ) | ||
return value; | ||
// If the alias is a function we let that function do the | ||
// transformation of the path | ||
if( 'function' === typeof value ) | ||
req = value(req); | ||
// If it is not a function we use string replacement | ||
else | ||
req = req.replace(mock.test, value); | ||
} | ||
// No mock; let the load system do its work | ||
return _load.apply(Module, arguments); | ||
return _load.call(Module, req, parent, isMain); | ||
}; | ||
@@ -211,2 +226,46 @@ }; | ||
return prunk; | ||
}, | ||
// ### alias | ||
// Aliases a path that begins with the given | ||
// string or matches the given regex. | ||
// This basically performs a string replacement if | ||
// you provide a simple string or a regex. | ||
// The regular expressions **must contain** at least | ||
// one grouping expression `(...)` so that the replacement | ||
// actually happens. | ||
// `alias` can also be a function that gets the path and | ||
// returns an updated one. | ||
// You can only provide a predicate function for `test` | ||
// if `alias` is also a function returning a modified path. | ||
// This method will throw if arguments are invalid. | ||
alias: function(test, alias) { | ||
if( 'undefined' === typeof alias ) | ||
throw new Error('prunk.alias needs a second argument'); | ||
if( 'function' === typeof test && 'function' !== typeof alias ) | ||
throw new Error('prunk.alias has been passed a function as test but not as alias'); | ||
if( test instanceof RegExp && ! test.toString().includes('(') ) | ||
throw new Error('prunk.alias has been passed a RegExp without a grouping expression'); | ||
createMock(test, alias, 'alias'); | ||
return prunk; | ||
}, | ||
// ### unalias | ||
// Removes the alias for the given test | ||
// It returns the prunk object so that you can chain calls. | ||
unalias: function(test) { | ||
remove(test, 'alias'); | ||
return prunk; | ||
}, | ||
// ### unaliasAll | ||
// Removes all aliases | ||
// It returns the prunk object so that you can chain calls. | ||
unaliasAll: function() { | ||
removeAll('alias'); | ||
return prunk; | ||
} | ||
@@ -213,0 +272,0 @@ |
{ | ||
"name": "prunk", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "A mocking utility for node.js require", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -13,4 +13,9 @@ # prunk | ||
Given you have a React component you want to test. However, since | ||
this component imports a SCSS file you cannot the import component directly. | ||
The great thing about testing React components is that you do not need | ||
a web browser but can run tests and render components directly in node. | ||
This can be a bit tricky if you use a development environment that allows | ||
you to import non-JavaScript resources (e.g. templates or stylesheets) in your code. | ||
Given you have a React component you want to test. This component imports a | ||
SCSS files so that the import in node would fail. | ||
At this point, you either can introduce a pre-compiler, loader or whatever | ||
@@ -42,7 +47,9 @@ your test framework supports or you can simply mock the import. | ||
In the test `require()` is used instead of `import` because some pre-compilers | ||
In the test, `require()` is used instead of `import` because some pre-compilers | ||
move all imports to the top of the file and that would make the mocking impossible. | ||
If you use mocha you can use [compiler](https://mochajs.org/#usage) for that. | ||
If you use mocha you can leverage it's [compiler](https://mochajs.org/#usage) configuration for that. | ||
(You might also check out [this](https://65535th.com/testing-react-components/) post with an example). | ||
If you just and to make sure some things don't get imported you can suppress them. | ||
The example above uses `.mock()` to replace the required module contents. | ||
If you just want to make sure some things don't get imported in the first place you can suppress them. | ||
Then, they will always return `undefined`; | ||
@@ -68,12 +75,11 @@ | ||
Mocks the given import with the given value. | ||
`test` can be a **function** that is used to compare | ||
whatever is required and returns `true` or `false`. | ||
`test` can be a predicate **function** that is used to compare | ||
whatever is required and returns either `true` or `false`. | ||
If the return value is truthy the import will be | ||
mocked with the given value. | ||
The function's arguments are the same as with `Module._load`. | ||
Most of the time you will look at the first argument, a `string`. | ||
The function gets the required path as an argument. | ||
```javascript | ||
var mockStyles = (req) => 'style.css' === req; | ||
var mockStyles = req => 'style.css' === req; | ||
prunk.mock( mockStyles, 'no css, dude.'); | ||
@@ -114,3 +120,3 @@ ``` | ||
Suppresses all imports that matches the given `test`. | ||
Suppresses all imports that match the given `test`. | ||
`test` can be a **function** that is used to compare | ||
@@ -121,4 +127,3 @@ whatever is required and returns `true` or `false`. | ||
The function's arguments are the same as with `Module._load`. | ||
Most of the time you will look at the first argument, a `string`. | ||
The function gets the required path as an argument. | ||
@@ -130,3 +135,3 @@ ```javascript | ||
`test` can also be a `RegExp` that is matched agains the name | ||
`test` can also be a `RegExp` that is matched against the name | ||
of the import or a string or something else. | ||
@@ -153,4 +158,61 @@ | ||
### prunk.alias(test, alias) | ||
This function provides a simple way to alias paths when required. As the | ||
other functions, it takes a test that can either be a string, a regular | ||
expression or predicate function. Some special rules apply here, though. | ||
If you pass a **string** as the first argument the required path will | ||
match if it begins or equals your string. The `alias` parameter is meant | ||
to be a string, too and simple string manipulation will be performed. | ||
It will only replace the first occurrence of the search pattern. | ||
```javascript | ||
prunk.alias('foo', 'bar'); | ||
require('foo'); // aliased to require('bar') | ||
require('foo/foofoo'); // aliased to require('bar/foofoo'); | ||
``` | ||
It is also possible to provide a **regular expression**. It has to contain a grouping | ||
expression `( )` so that the replacement of the tested value works. `prunk.alias` will | ||
**throw an error** if the regex does not contain a group. | ||
```javascript | ||
prunk.alias(/^(foo)/, 'bar'); | ||
require('foo'); // aliased to require('bar') | ||
require('foo/foofoo'); // aliased to require('bar/foofoo'); | ||
``` | ||
Both, string and regexes also accept a **function** as the second argument. This function | ||
gets the required path and is supposed to return a path which is then required. | ||
```javascript | ||
prunk.alias('foo', path => `my-foo-dir/${path}` ); | ||
require('foo'); // aliased to require('my-foo-dir/foo') | ||
require('foo/foofoo'); // aliased to require('my-foo-dir/foo/foofoo'); | ||
``` | ||
The third possibility is to provide a predicate **function as test**. Since prunk cannot know | ||
how to alias a path matched with a predicate you have to provide a function as second argument, too. | ||
`prunk.alias` will throw if you don't. | ||
```javascript | ||
prunk.alias( path => path.startsWith('bar'), 'test' ); // will throw! | ||
prunk.alias( path => path.startsWith('foo'), () => 'bar' ); | ||
require('foo'); // aliased to require('bar') | ||
``` | ||
### prunk.unalias(test) | ||
Removes the alias for the given test. | ||
This function returns the prunk object so that you can chain calls. | ||
### prunk.unaliasAll() | ||
Removes all aliases. | ||
This function returns the prunk object so that you can chain calls. | ||
## Documentation | ||
[Documented source](https://dak0rn.github.io/prunk/). |
@@ -43,2 +43,14 @@ /** | ||
it('should have an alias() function', function() { | ||
expect( prunk.alias ).to.be.a('function'); | ||
}); | ||
it('should have an unalias() function', function() { | ||
expect( prunk.unalias ).to.be.a('function'); | ||
}); | ||
it('should have a unaliasAll() function', function() { | ||
expect( prunk.unaliasAll ).to.be.a('function'); | ||
}); | ||
}); | ||
@@ -382,2 +394,187 @@ | ||
}); | ||
}); | ||
// alias() function | ||
describe('alias()', function() { | ||
beforeEach(function() { | ||
// Reset the require cache | ||
require.cache = {}; | ||
prunk = require('..'); | ||
// Make sure, the internal cache is empty | ||
prunk._cache = []; | ||
}); | ||
it('should take two arguments', function() { | ||
expect(prunk.alias.length).to.equal(2); | ||
}); | ||
it('should alias correctly when using a string', function() { | ||
prunk.alias('a', './b'); | ||
var imp = require('a'); | ||
expect( imp ).to.equal('b'); | ||
}); | ||
it('should alias correctly when unsing a regex', function() { | ||
prunk.alias(/^(b)/, './a'); | ||
var imp = require('b'); | ||
expect( imp ).to.equal('a'); | ||
imp = require('bb'); | ||
expect( imp ).to.equal('ab'); | ||
}); | ||
it('should alias correctly using a string and a callback', function() { | ||
var aliaser = function() { return './b'; }; | ||
prunk.alias( 'a', aliaser ); | ||
var imp = require('a'); | ||
expect( imp ).to.equal('b'); | ||
}); | ||
it('should alias correctly using a regex and a callback', function() { | ||
var aliaser = function() { return './b'; }; | ||
prunk.alias( /^(a)/, aliaser ); | ||
var imp = require('a'); | ||
expect( imp ).to.equal('b'); | ||
}); | ||
it('should alias correctly using callbacks', function() { | ||
var matcher = function(path) { return null !== path.match(/^a/); }; | ||
var aliaser = function() { return './b'; }; | ||
prunk.alias( matcher, aliaser ); | ||
var imp = require('a'); | ||
expect( imp ).to.equal('b'); | ||
}); | ||
it('should only alias at the beginning of a path', function() { | ||
prunk.alias('b', 'a'); | ||
var wrapper = function() { | ||
require('b/a/b/c'); | ||
}; | ||
expect( wrapper ).to.throw('a/a/b/c'); | ||
}); | ||
it('should return the prunk object again', function() { | ||
expect( prunk.alias('a', 'b') ).to.equal( prunk ); | ||
}); | ||
it('should throw if only one argument is given', function() { | ||
var wrapper = function() { | ||
prunk.alias('b'); | ||
}; | ||
expect( wrapper ).to.throw(); | ||
}) | ||
it('should throw if the regex does not contain a grouping', function() { | ||
var wrapper = function() { | ||
prunk.alias(/^abc/, 'abc'); | ||
}; | ||
expect( wrapper ).to.throw(); | ||
}); | ||
it('should throw if passed a function as first but not as second argument', function() { | ||
var wrapper = function() { | ||
prunk.alias(function() {}, 42); | ||
}; | ||
expect(wrapper).to.throw(); | ||
}); | ||
}); | ||
describe('unalias', function() { | ||
beforeEach(function() { | ||
// Reset the require cache | ||
require.cache = {}; | ||
prunk = require('..'); | ||
prunk._cache = []; | ||
}); | ||
it('should take one argument', function() { | ||
expect(prunk.unalias.length).to.equal(1); | ||
}); | ||
it('should unalias correctly when using a string', function() { | ||
prunk.alias('./a', './b'); | ||
prunk.unalias('./a'); | ||
var imp = require('./a'); | ||
expect( imp ).to.equal('a'); | ||
}); | ||
it('should unalias correctly when unsing a regex', function() { | ||
prunk.alias(/^(a)/, 'b'); | ||
prunk.unalias(/^(a)/); | ||
var imp = require('./a'); | ||
expect( imp ).to.equal('a'); | ||
}); | ||
it('should unalias correctly using callbacks', function() { | ||
var matcher = function(path) { return null !== path.match(/^a/); }; | ||
prunk.alias(matcher, matcher); | ||
prunk.unalias( matcher ); | ||
var imp = require('./a'); | ||
expect( imp ).to.equal('a'); | ||
}); | ||
it('should return the prunk object again', function() { | ||
expect( prunk.unalias() ).to.equal( prunk ); | ||
}); | ||
}); | ||
// unaliasAll function | ||
describe('unaliasAll()', function() { | ||
beforeEach(function() { | ||
// Reset the require cache | ||
require.cache = {}; | ||
prunk = require('..'); | ||
prunk._cache = []; | ||
}); | ||
it('should take no arguments', function() { | ||
expect(prunk.unaliasAll.length).to.equal(0); | ||
}); | ||
it('should unaliasAll correctly when using a string', function() { | ||
prunk.alias('./a', './b'); | ||
prunk.unaliasAll(); | ||
var imp = require('./a'); | ||
expect( imp ).to.equal('a'); | ||
}); | ||
it('should unaliasAll correctly when unsing a regex', function() { | ||
prunk.alias(/^(a)/, 'b'); | ||
prunk.unaliasAll(); | ||
var imp = require('./a'); | ||
expect( imp ).to.equal('a'); | ||
}); | ||
it('should unaliasAll correctly using callbacks', function() { | ||
var matcher = function(path) { return null !== path.match(/^a/); }; | ||
prunk.alias(matcher, matcher); | ||
prunk.unaliasAll(); | ||
var imp = require('./a'); | ||
expect( imp ).to.equal('a'); | ||
}); | ||
it('should return the prunk object again', function() { | ||
expect( prunk.unaliasAll() ).to.equal( prunk ); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43653
9
673
211