UNPKG

get-es-imports-exports

Version:

Recursively get imports and exports for files using ES import/export syntax

287 lines (247 loc) 7.77 kB
import test from 'ava'; import { join } from 'path'; import getEsImports from '../src'; /* files demonstrate the following cases import name from 'import'; import { name } from 'import'; import { name as otherName } from 'import'; import ... from './local-file' import ... from 'node_module' */ const baseDir = join(__dirname, 'cases'); const singleFile = join(baseDir, 'single-file'); const localImports = join(baseDir, 'local-imports'); const importNothing = join(baseDir, 'import-nothing'); const importJson = join(baseDir, 'import-json'); const namespaceImports = join(baseDir, 'namespace-imports'); const externalImports = join(baseDir, 'external-imports'); const duplicatedImports = join(baseDir, 'duplicated-imports'); const genericExports = join(baseDir, 'exports'); const exportFrom = join(baseDir, 'export-from'); const exportFromNamespace = join(baseDir, 'export-from-namespace'); const nestedFiles = join(baseDir, 'nested-files'); const babelFile = join(baseDir, 'babel-file'); const invalidFile = join(baseDir, 'invalid-files'); const nodeModules = join(__dirname, '../node_modules'); test('a single parses and loads recursively via a single entry point', t => { t.plan(2); const inputFile = join(singleFile, 'index.js'); return getEsImports({ files: [inputFile], }).then(({ imports, exports }) => { t.deepEqual(imports, {}); t.deepEqual(exports, { [inputFile]: ['default', 'test'], }); }); }); test('a single parses and loads non-recursively via a single entry point', t => { t.plan(2); const inputFile = join(singleFile, 'index.js'); return getEsImports({ files: [join(singleFile, 'index.js')], recurse: false, }).then(({ imports, exports }) => { t.deepEqual(imports, {}); t.deepEqual(exports, { [inputFile]: ['default', 'test'], }); }); }); test('multiple local imports parse and load recursively via a single entry point', t => { t.plan(2); return getEsImports({ files: [join(localImports, 'index.js')], }).then(({ imports, exports }) => { t.deepEqual({ [join(localImports, 'import1.js')]: ['default'], [join(localImports, 'import2.js')]: ['test'], }, imports); t.deepEqual({ [join(localImports, 'index.js')]: [], [join(localImports, 'import1.js')]: ['default'], [join(localImports, 'import2.js')]: ['test'], }, exports); }); }); test('multiple local imports parse and load non-recursively from index', t => { t.plan(2); return getEsImports({ files: [join(localImports, 'index.js')], recurse: false, }).then(({ imports, exports }) => { t.deepEqual({ [join(localImports, 'import1.js')]: ['default'], [join(localImports, 'import2.js')]: ['test'], }, imports); t.deepEqual({ [join(localImports, 'index.js')]: [], }, exports); }); }); test('multiple local imports parse and load non-recursively from import1', t => { t.plan(2); return getEsImports({ files: [join(localImports, 'import1.js')], recurse: false, }).then(({ imports, exports }) => { t.deepEqual({ [join(localImports, 'import2.js')]: ['test'], }, imports); t.deepEqual({ [join(localImports, 'import1.js')]: ['default'], }, exports); }); }); test('recognises imports that do not import variables (import "src";)', t => { t.plan(2); return getEsImports({ files: [join(importNothing, 'index.js')], }).then(({ imports, exports }) => { t.deepEqual({ [join(importNothing, 'import1.js')]: [], }, imports); t.deepEqual({ [join(importNothing, 'index.js')]: [], [join(importNothing, 'import1.js')]: [], }, exports); }); }); test('import json', t => { t.plan(2); return getEsImports({ files: [join(importJson, 'index.js')], resolveOptions: { extensions: ['.js', '.json'], }, }).then(({ imports, exports }) => { t.deepEqual({ [join(importJson, 'import1.json')]: [], }, imports); t.deepEqual({ [join(importJson, 'index.js')]: [], [join(importJson, 'import1.json')]: [], }, exports); }); }); test('it recognises namespace imports', t => { t.plan(1); return getEsImports({ files: [join(namespaceImports, 'index.js')], }).then(({ imports }) => { t.deepEqual({ [join(namespaceImports, 'import1.js')]: ['*'], }, imports); }); }); test('external imports parse and loads recursively, excluding the external import', t => { t.plan(1); return getEsImports({ files: [join(externalImports, 'index.js')], }).then(({ imports }) => { t.deepEqual({ [join(externalImports, 'import1.js')]: ['default'], [join(externalImports, 'import2.js')]: ['default'], [join(nodeModules, 'lodash/lodash.js')]: ['filter', 'map', 'reduce'], }, imports); }); }); test('duplicated imports are only added once to the import object', t => { t.plan(1); return getEsImports({ files: [join(duplicatedImports, 'index.js')], }).then(({ imports }) => { t.deepEqual({ [join(nodeModules, 'lodash/lodash.js')]: ['filter', 'map'], }, imports); }); }); test('export statements work for default, class, variable, and function declarations', t => { t.plan(2); return getEsImports({ files: [join(genericExports, 'index.js')], }).then(({ imports, exports }) => { t.deepEqual({}, imports); t.deepEqual({ [join(genericExports, 'index.js')]: ['CONSTANT', 'Class', 'constant', 'default', 'fn'], }, exports); }); }); test('export from statements without a namespace work', t => { t.plan(2); return getEsImports({ files: [join(exportFrom, 'index.js')], }).then(({ imports, exports }) => { t.deepEqual({ [join(nodeModules, 'lodash/lodash.js')]: ['filter', 'map'], }, imports); t.deepEqual({ [join(exportFrom, 'index.js')]: ['filt', 'map'], }, exports); }); }); test('export from statements with a namespace work', t => { t.plan(2); return getEsImports({ files: [join(exportFromNamespace, 'index.js')], }).then(({ imports, exports }) => { t.deepEqual({ [join(nodeModules, 'lodash/lodash.js')]: ['*'], }, imports); t.deepEqual({ [join(exportFromNamespace, 'index.js')]: ['*'], }, exports); }); }); test('nested files are parsed and load recursively', t => { t.plan(1); return getEsImports({ files: [join(nestedFiles, 'index.js')], }).then(({ imports }) => { t.deepEqual({ [join(nestedFiles, 'import1/index.js')]: ['default'], [join(nestedFiles, 'import2/import2.js')]: ['test'], [join(nestedFiles, 'import3/import3.js')]: ['default'], }, imports); }); }); test('will not read files in the exclude string', t => { t.plan(1); return getEsImports({ files: [join(nestedFiles, 'index.js')], exclude: join(nestedFiles, 'import1/**/*.js'), }).then(({ imports }) => { t.deepEqual({ [join(nestedFiles, 'import1/index.js')]: ['default'], [join(nestedFiles, 'import2/import2.js')]: ['test'], }, imports); }); }); test('a file that requires babel does not by default parse', t => { // If this fails, you need to change the case file t.plan(1); return getEsImports({ files: [join(babelFile, 'index.js')], }).catch(() => { t.pass(); }); }); test('a file that requires babel parses with babel-eslint', t => { t.plan(1); return getEsImports({ files: [join(babelFile, 'index.js')], parser: 'babel-eslint', }).then(() => { t.pass(); }).catch(t.fail); }); test('a file that imports scss can exclude correctly', t => { t.plan(1); return getEsImports({ files: [join(invalidFile, 'index.js')], exclude: ['*.scss'], parser: 'babel-eslint', }).then(() => { t.pass(); }).catch(t.fail); });