Skip to content

Commit

Permalink
better mock obj validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ruyadorno committed Dec 17, 2020
1 parent 8af0892 commit 6c5cb81
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 3 deletions.
7 changes: 6 additions & 1 deletion lib/mock.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
const Module = require('module')
const { isAbsolute } = require('path')

const isPlainObject = obj => obj
&& typeof obj === 'object'
&& (Object.getPrototypeOf(obj) === null
|| Object.getPrototypeOf(obj) === Object.prototype)

class Mock {
constructor(parentFilename, filename, mocks = {}) {
this.filename = filename
Expand All @@ -14,7 +19,7 @@ class Mock {
throw new TypeError('t.mock() first argument should be a string')
}

if (typeof mocks !== 'object') {
if (!isPlainObject(mocks)) {
throw new TypeError(`mocks should be a a key/value object in which keys
are the same used in ${filename} require calls`)
}
Expand Down
34 changes: 32 additions & 2 deletions test/mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,43 @@ t.throws(
)

t.throws(
() => Mock.get(resolve(__filename)),
() => Mock.get(__filename),
/first argument should be a string/,
'should throw on invalid filename',
)

t.throws(
() => Mock.get(resolve(__filename), './foo.js', ''),
() => Mock.get(__filename, './foo.js', ''),
/mocks should be a a key\/value object in which keys/,
'should throw on invalid mock-defining object',
)

t.throws(
() => Mock.get(__filename, './foo.js', [1]),
/mocks should be a a key\/value object in which keys/,
'should throw on invalid mock-defining object',
)

t.throws(
() => Mock.get(__filename, './foo.js', null),
/mocks should be a a key\/value object in which keys/,
'should throw on invalid mock-defining object',
)

t.throws(
() => Mock.get(__filename, './foo.js', /foo/),
/mocks should be a a key\/value object in which keys/,
'should throw on invalid mock-defining object',
)

t.throws(
() => Mock.get(__filename, './foo.js', 1),
/mocks should be a a key\/value object in which keys/,
'should throw on invalid mock-defining object',
)

t.throws(
() => Mock.get(__filename, './foo.js', new Map()),
/mocks should be a a key\/value object in which keys/,
'should throw on invalid mock-defining object',
)
Expand Down
26 changes: 26 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1517,5 +1517,31 @@ t.test('require defining mocks', t => {
)
})

t.test('should support mocking builtin modules within nested deps', t => {
const f = t.testdir({
lib: {
'a.js':
`module.exports = require('./b.js')`,
'b.js':
`module.exports = require('./c.js')`,
'c.js':
`module.exports = () => require('fs')`,
},
'test.js':
`const t = require('../..'); // tap
t.test('mocking builtin modules in nested modules', t => {
const fs = {}
const a = t.mock('./lib/a.js', { fs })
t.equal(a(), fs, 'should get mocked fs result')
t.end()
})`,
})
return t.spawn(
process.execPath,
[ path.resolve(f, 'test.js') ],
{ cwd: f },
)
})

t.end()
})

0 comments on commit 6c5cb81

Please sign in to comment.