bit-bin
Version:
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b
696 lines (594 loc) • 21.6 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
function _sinon() {
const data = _interopRequireDefault(require("sinon"));
_sinon = function () {
return data;
};
return data;
}
function _rewire() {
const data = _interopRequireDefault(require("rewire"));
_rewire = function () {
return data;
};
return data;
}
function _mockFs() {
const data = _interopRequireDefault(require("mock-fs"));
_mockFs = function () {
return data;
};
return data;
}
const cabinetNonDefault = (0, _rewire().default)('./');
const cabinet = cabinetNonDefault.default;
const fixtures = `${__dirname}/../../../../../../fixtures/filing-cabinet`; // eslint-disable-next-line import/no-dynamic-require, global-require
const mockedFiles = require(`${fixtures}/mockedJSFiles`); // eslint-disable-next-line import/no-dynamic-require, global-require
const mockAST = require(`${fixtures}/ast`);
const mockRootDir = _path().default.join(__dirname, '..', '..', '..', '..', '..', '..'); // needed for the lazy loading
require('resolve-dependency-path');
require('sass-lookup');
require('app-module-path');
require('module-definition');
try {
// eslint-disable-next-line global-require
require('module-lookup-amd');
} catch (err) {
// eslint-disable-next-line no-console
console.log(`mocha suppresses the error, so console.error is needed to show the error on the screen.
the problem is with module-lookup-amd that calls requirejs package and uses rewire package.
see https://github.com/jhnns/rewire/issues/178 for more details.
the error occurs since node v12.16.0. for the time being, to run the tests, use an earlier version.
`); // eslint-disable-next-line no-console
console.error(err);
throw err;
}
describe('filing-cabinet', () => {
describe('JavaScript', () => {
beforeEach(() => {
(0, _mockFs().default)(mockedFiles);
});
afterEach(() => {
_mockFs().default.restore();
});
it('dangles off its supported file extensions', () => {
_assert().default.deepEqual(cabinetNonDefault.supportedFileExtensions, ['.js', '.jsx', '.ts', '.tsx', '.scss', '.sass', '.styl', '.less', '.vue']);
});
it('uses a generic resolve for unsupported file extensions', () => {
const resolvedFile = cabinet({
dependency: './bar',
filename: 'js/commonjs/foo.baz',
directory: 'js/commonjs/'
});
_assert().default.ok(resolvedFile.endsWith('bar.baz'));
});
describe('when given an ast for a JS file', () => {
it('reuses the ast when trying to determine the module type', () => {
const ast = {};
const result = cabinet({
dependency: './bar',
filename: 'js/es6/foo.js',
directory: 'js/es6/',
ast
});
_assert().default.ok(result.endsWith('es6/bar.js'));
});
it('resolves the dependency successfully', () => {
const result = cabinet({
dependency: './bar',
filename: 'js/es6/foo.js',
directory: 'js/es6/',
ast: mockAST
});
_assert().default.equal(result, _path().default.join(mockRootDir, 'js/es6/bar.js'));
});
});
describe('when not given an ast', () => {
it('uses the filename to look for the module type', () => {
const options = {
dependency: './bar',
filename: 'js/es6/foo.js',
directory: 'js/es6/'
};
const result = cabinet(options);
_assert().default.equal(result, _path().default.join(mockRootDir, 'js/es6/bar.js'));
});
});
describe('es6', () => {
it('assumes commonjs for es6 modules with no requirejs/webpack config', () => {
const stub = _sinon().default.stub();
const revert = cabinetNonDefault.__set__('commonJSLookup', stub);
cabinet({
dependency: './bar',
filename: 'js/es6/foo.js',
directory: 'js/es6/'
});
_assert().default.ok(stub.called);
revert();
});
});
describe('jsx', () => {
it('resolves files with the .jsx extension', () => {
const result = cabinet({
dependency: './bar',
filename: 'js/es6/foo.jsx',
directory: 'js/es6/'
});
_assert().default.equal(result, `${_path().default.join(mockRootDir, 'js/es6/bar.js')}`);
});
});
describe('amd', () => {
it('uses the amd resolver', () => {
const resolvedFile = cabinet({
dependency: './bar',
filename: 'js/amd/foo.js',
directory: 'js/amd/'
});
_assert().default.ok(resolvedFile.endsWith('amd/bar.js'));
}); // skipped as part of lazy loading fix. not seems to be super helpful test
it.skip('passes along arguments', () => {
const stub = _sinon().default.stub();
const revert = cabinet.__set__('amdLookup', stub);
const config = {
baseUrl: 'js'
};
cabinet({
dependency: 'bar',
config,
configPath: 'config.js',
filename: 'js/amd/foo.js',
directory: 'js/amd/'
});
const args = stub.getCall(0).args[0];
_assert().default.equal(args.dependency, 'bar');
_assert().default.equal(args.config, config);
_assert().default.equal(args.configPath, 'config.js');
_assert().default.equal(args.filename, 'js/amd/foo.js');
_assert().default.equal(args.directory, 'js/amd/');
_assert().default.ok(stub.called);
revert();
});
});
describe('commonjs', () => {
it("uses require's resolver", () => {
const stub = _sinon().default.stub();
const revert = cabinetNonDefault.__set__('commonJSLookup', stub);
cabinet({
dependency: './bar',
filename: 'js/commonjs/foo.js',
directory: 'js/commonjs/'
});
_assert().default.ok(stub.called);
revert();
});
it('returns an empty string for an unresolved module', () => {
const result = cabinet({
dependency: 'foobar',
filename: 'js/commonjs/foo.js',
directory: 'js/commonjs/'
});
_assert().default.equal(result, '');
});
it('adds the directory to the require resolution paths', () => {
const directory = 'js/commonjs/';
cabinet({
dependency: 'foobar',
filename: 'js/commonjs/foo.js',
directory
});
_assert().default.ok( // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
require.main.paths.some(function (p) {
return p.indexOf(_path().default.normalize(directory)) !== -1;
}));
});
it('resolves a relative dependency about the filename', () => {
const directory = 'js/commonjs/';
const filename = `${directory}foo.js`;
const result = cabinet({
dependency: './bar',
filename,
directory
});
_assert().default.equal(result, _path().default.join(_path().default.resolve(directory), 'bar.js'));
});
it("resolves a .. dependency to its parent directory's index.js file", () => {
const directory = 'js/commonjs/';
const filename = `${directory}subdir/module.js`;
const result = cabinet({
dependency: '../',
filename,
directory
});
_assert().default.equal(result, _path().default.join(_path().default.resolve(directory), 'index.js'));
}); // @todo: fix
it.skip('resolves a dependency within a directory outside of the given file', () => {
const directory = 'js/commonjs/';
const filename = `${directory}test/index.spec.js`;
const result = cabinet({
dependency: 'subdir',
filename,
directory
});
_assert().default.equal(result, _path().default.join(_path().default.resolve(directory), 'subdir/index.js'));
}); // @todo: fix
it.skip('resolves a node module with module entry in package.json', () => {
const directory = 'js/commonjs/';
const filename = `${directory}module.entry.js`;
const result = cabinet({
dependency: 'module.entry',
filename,
directory,
nodeModulesConfig: {
entry: 'module'
}
});
_assert().default.equal(result, _path().default.join(_path().default.resolve(directory), '..', 'node_modules', 'module.entry', 'index.module.js'));
});
it('resolves a nested module', () => {
const directory = 'js/node_modules/nested/';
const filename = `${directory}index.js`;
const result = cabinet({
dependency: 'lodash.assign',
filename,
directory
});
_assert().default.equal(result, _path().default.join(_path().default.resolve(directory), 'node_modules', 'lodash.assign', 'index.js'));
});
it('resolves to the index.js file of a directory', () => {
const directory = 'js/withIndex';
const filename = `${directory}/index.js`;
const result = cabinet({
dependency: './subdir',
filename,
directory
});
_assert().default.equal(result, _path().default.normalize(`${_path().default.resolve(directory)}/subdir/index.js`));
});
it('resolves implicit .jsx requires', () => {
const result = cabinet({
dependency: './bar',
filename: 'js/cjs/foo.js',
directory: 'js/cjs/'
});
_assert().default.equal(result, `${_path().default.join(mockRootDir, 'js/cjs/bar.jsx')}`);
});
it('resolves implicit .scss requires', () => {
const result = cabinet({
dependency: './baz',
filename: 'js/cjs/foo.js',
directory: 'js/cjs/'
});
_assert().default.equal(result, `${_path().default.join(mockRootDir, 'js/cjs/baz.scss')}`);
});
it('resolves implicit .json requires', () => {
const result = cabinet({
dependency: './pkg',
filename: 'js/cjs/foo.js',
directory: 'js/cjs/'
});
_assert().default.equal(result, `${_path().default.join(mockRootDir, 'js/cjs/pkg.json')}`);
});
});
describe('typescript', () => {
it('resolves an import', () => {
const directory = 'js/ts';
const filename = `${directory}/index.ts`;
const result = cabinet({
dependency: './foo',
filename,
directory
});
_assert().default.equal(result, _path().default.join(_path().default.resolve(directory), 'foo.ts'));
});
describe('when a dependency does not exist', () => {
it('returns an empty result', () => {
const directory = 'js/ts';
const filename = `${directory}/index.ts`;
const result = cabinet({
dependency: './barbar',
filename,
directory
});
_assert().default.equal(result, '');
});
});
});
});
describe('CSS', () => {
beforeEach(() => {
(0, _mockFs().default)({
stylus: {
'foo.styl': '',
'bar.styl': ''
},
sass: {
'foo.scss': '',
'bar.scss': '',
'foo.sass': '',
'bar.sass': ''
},
less: {
'foo.less': '',
'bar.less': '',
'bar.css': ''
}
}); // mockJSDir = path.resolve(__dirname, '../');
});
afterEach(() => {
_mockFs().default.restore();
});
describe('sass', () => {
it('uses the sass resolver for .scss files', () => {
const result = cabinet({
dependency: 'bar',
filename: 'sass/foo.scss',
directory: 'sass/'
});
_assert().default.equal(result, _path().default.normalize(`${mockRootDir}/sass/bar.scss`));
});
it('uses the sass resolver for .sass files', () => {
const result = cabinet({
dependency: 'bar',
filename: 'sass/foo.sass',
directory: 'sass/'
});
_assert().default.equal(result, _path().default.normalize(`${mockRootDir}/sass/bar.sass`));
});
});
describe('stylus', () => {
it('uses the stylus resolver', () => {
const result = cabinet({
dependency: 'bar',
filename: 'stylus/foo.styl',
directory: 'stylus/'
});
_assert().default.equal(result, _path().default.normalize(`${mockRootDir}/stylus/bar.styl`));
});
});
describe('less', () => {
it('resolves extensionless dependencies', () => {
const result = cabinet({
dependency: 'bar',
filename: 'less/foo.less',
directory: 'less/'
});
_assert().default.equal(result, _path().default.normalize(`${mockRootDir}/less/bar.less`));
});
it('resolves dependencies with a less extension', () => {
const result = cabinet({
dependency: 'bar.less',
filename: 'less/foo.less',
directory: 'less/'
});
_assert().default.equal(result, _path().default.normalize(`${mockRootDir}/less/bar.less`));
});
it('resolves dependencies with a css extension', () => {
const result = cabinet({
dependency: 'bar.css',
filename: 'less/foo.less',
directory: 'less/'
});
_assert().default.equal(result, _path().default.normalize(`${mockRootDir}/less/bar.css`));
});
});
});
describe('unrecognized extension', () => {
it('uses a generic resolve for unsupported file extensions', () => {
const result = cabinet({
dependency: './bar',
filename: 'barbazim/foo.baz',
directory: 'barbazim/'
});
_assert().default.equal(result, _path().default.normalize(`${mockRootDir}/barbazim/bar.baz`));
});
});
describe('.register', () => {
it('registers a custom resolver for a given extension', () => {
const stub = _sinon().default.stub().returns('foo.foobar');
cabinetNonDefault.register('.foobar', stub);
const pathResult = cabinet({
dependency: './bar',
filename: 'js/amd/foo.foobar',
directory: 'js/amd/'
});
_assert().default.ok(stub.called);
_assert().default.equal(pathResult, 'foo.foobar');
});
it('allows does not break default resolvers', () => {
(0, _mockFs().default)({
stylus: {
'foo.styl': '',
'bar.styl': ''
}
});
const stub = _sinon().default.stub().returns('foo');
cabinetNonDefault.register('.foobar', stub);
cabinet({
dependency: './bar',
filename: 'js/amd/foo.foobar',
directory: 'js/amd/'
});
const result = cabinet({
dependency: './bar',
filename: 'stylus/foo.styl',
directory: 'stylus/'
});
_assert().default.ok(stub.called);
_assert().default.ok(result);
_mockFs().default.restore();
});
it('can be called multiple times', () => {
const stub = _sinon().default.stub().returns('foo');
const stub2 = _sinon().default.stub().returns('foo');
cabinetNonDefault.register('.foobar', stub);
cabinetNonDefault.register('.barbar', stub2);
cabinet({
dependency: './bar',
filename: 'js/amd/foo.foobar',
directory: 'js/amd/'
});
cabinet({
dependency: './bar',
filename: 'js/amd/foo.barbar',
directory: 'js/amd/'
});
_assert().default.ok(stub.called);
_assert().default.ok(stub2.called);
});
it('does not add redundant extensions to supportedFileExtensions', () => {
const stub = _sinon().default.stub;
const newExt = '.foobar';
cabinetNonDefault.register(newExt, stub);
cabinetNonDefault.register(newExt, stub);
const {
supportedFileExtensions
} = cabinetNonDefault;
_assert().default.equal(supportedFileExtensions.indexOf(newExt), supportedFileExtensions.lastIndexOf(newExt));
});
});
describe('.scss with a dependency prefix with a tilda', () => {
it('should resolve the dependency to a node_module package (using webpack under the hood)', () => {
const result = cabinet({
dependency: '~bootstrap/index',
filename: `${fixtures}/foo.scss`,
directory: fixtures
});
_assert().default.equal(result, _path().default.resolve(`${fixtures}/node_modules/bootstrap/index.scss`));
});
});
describe('.scss with a dependency prefix with a tilda and resolve config', () => {
describe('when the alias in resolve-config is resolved to an existing file', () => {
it('should resolve the dependency according to the resolve-config', () => {
const resolveConfig = {
aliases: {
'~bootstrap': _path().default.normalize(fixtures)
}
};
const result = cabinet({
resolveConfig,
dependency: '~bootstrap/foo2',
filename: `${fixtures}/foo.scss`,
directory: fixtures
});
_assert().default.equal(result, _path().default.resolve(`${fixtures}/foo2.scss`));
});
});
describe('when the alias in resolve-config does not match the dependency', () => {
it('should fallback to the node-module resolution', () => {
const resolveConfig = {
aliases: {
'~non-exist': 'some-dir'
}
};
const result = cabinet({
resolveConfig,
dependency: '~bootstrap/index',
filename: `${fixtures}/foo.scss`,
directory: fixtures
});
_assert().default.equal(result, _path().default.resolve(`${fixtures}/node_modules/bootstrap/index.scss`));
});
});
}); // @todo: fix.
describe.skip('webpack', () => {
let directory;
beforeEach(() => {
directory = _path().default.resolve(__dirname, '../../../');
});
function testResolution(dependency, expected) {
const resolved = cabinet({
dependency,
filename: `${__dirname}/index.js`,
directory,
webpackConfig: `${fixtures}/webpack.config.js`
});
_assert().default.equal(resolved, _path().default.normalize(expected));
}
it('resolves an aliased path', () => {
testResolution('R', `${directory}/node_modules/resolve/index.js`);
});
it('resolves a non-aliased path', () => {
testResolution('resolve', `${directory}/node_modules/resolve/index.js`);
});
it('resolves a relative path', () => {
testResolution('./test/ast', `${fixtures}/test/ast.js`);
});
it('resolves an absolute path from a file within a subdirectory', () => {
const resolved = cabinet({
dependency: 'R',
filename: `${fixtures}/test/ast.js`,
directory,
webpackConfig: `${fixtures}/webpack.config.js`
});
_assert().default.equal(resolved, `${directory}/node_modules/resolve/index.js`);
});
it('resolves a path using resolve.root', () => {
const resolved = cabinet({
dependency: 'mod1',
filename: `${directory}/index.js`,
directory,
webpackConfig: `${directory}/webpack-root.config.js`
});
_assert().default.equal(resolved, `${directory}/test/root1/mod1.js`);
});
it('resolves NPM module when using resolve.root', () => {
const resolved = cabinet({
dependency: 'resolve',
filename: `${directory}/index.js`,
directory,
webpackConfig: `${directory}/webpack-root.config.js`
});
_assert().default.equal(resolved, `${directory}/node_modules/resolve/index.js`);
});
it('resolves NPM module when using resolve.modulesDirectories', () => {
const resolved = cabinet({
dependency: 'resolve',
filename: `${directory}/index.js`,
directory,
webpackConfig: `${directory}/webpack-root.config.js`
});
_assert().default.equal(resolved, `${directory}/node_modules/resolve/index.js`);
});
it('resolves a path using resolve.modulesDirectories', () => {
const resolved = cabinet({
dependency: 'mod2',
filename: `${directory}/index.js`,
directory,
webpackConfig: `${directory}/webpack-root.config.js`
});
_assert().default.equal(resolved, `${directory}/test/root2/mod2.js`);
});
it('resolves a path using webpack config that exports a function', () => {
const resolved = cabinet({
dependency: 'R',
filename: `${directory}/index.js`,
directory,
webpackConfig: `${directory}/webpack-env.config.js`
});
_assert().default.equal(resolved, `${directory}/node_modules/resolve/index.js`);
});
it('resolves files with a .jsx extension', () => {
testResolution('./test/foo.jsx', `${directory}/test/foo.jsx`);
});
describe('when the dependency contains a loader', () => {
it('still works', () => {
testResolution('hgn!resolve', `${directory}/node_modules/resolve/index.js`);
});
});
});
});
;