UNPKG

react-docgen

Version:

A CLI and toolkit to extract information from React components for documentation generation.

334 lines (291 loc) 8.48 kB
/* * Copyright (c) 2015, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ /*global jasmine, describe, it, expect, afterEach*/ // NOTE: This test spawns a subprocesses that load the files from dist/, not // src/. Before running this test run `npm run build` or `npm run watch`. const TEST_TIMEOUT = 120000; jasmine.DEFAULT_TIMEOUT_INTERVAL = TEST_TIMEOUT; const fs = require('fs'); const path = require('path'); const rimraf = require('rimraf'); const temp = require('temp'); const spawn = require('cross-spawn'); function run(args, stdin) { return new Promise(resolve => { const docgen = spawn(path.join(__dirname, '../react-docgen.js'), args); let stdout = ''; let stderr = ''; docgen.stdout.on('data', data => (stdout += data)); docgen.stderr.on('data', data => (stderr += data)); docgen.on('close', () => resolve([stdout, stderr])); docgen.on('error', e => { throw e; }); if (stdin) { docgen.stdin.write(stdin); } docgen.stdin.end(); }); } const component = fs.readFileSync( path.join(__dirname, '../../example/components/Component.js'), ); describe('react-docgen CLI', () => { let tempDir; let tempComponents = []; let tempNoComponents = []; function createTempfiles(suffix, dir) { if (!tempDir) { tempDir = temp.mkdirSync(); } if (!dir) { dir = tempDir; } else { dir = path.join(tempDir, dir); try { fs.mkdirSync(dir); } catch (error) { if (error.message.indexOf('EEXIST') === -1) { throw error; } } } if (!suffix) { suffix = 'js'; } const componentPath = path.join(dir, 'Component.' + suffix); const componentFile = fs.openSync(componentPath, 'w'); fs.writeSync(componentFile, component.toString()); fs.closeSync(componentFile); const noComponentPath = path.join(dir, 'NoComponent.' + suffix); const noComponentFile = fs.openSync(noComponentPath, 'w'); fs.writeSync(noComponentFile, '{}'); fs.closeSync(noComponentFile); tempComponents.push(componentPath); tempNoComponents.push(noComponentPath); return dir; } afterEach(() => { if (tempDir) { rimraf.sync(tempDir); } tempDir = null; tempComponents = []; tempNoComponents = []; }); it( 'reads from stdin', () => { return run([], component).then(([stdout, stderr]) => { expect(stdout).not.toBe(''); expect(stderr).toBe(''); }); }, TEST_TIMEOUT, ); it( 'reads files provided as command line arguments', () => { createTempfiles(); return run(tempComponents.concat(tempNoComponents)).then( ([stdout, stderr]) => { expect(stdout).toContain('Component'); expect(stderr).toContain('NoComponent'); }, ); }, TEST_TIMEOUT, ); it( 'reads directories provided as command line arguments', () => { createTempfiles(); return run([tempDir]).then(([stdout, stderr]) => { expect(stdout).toContain('Component'); expect(stderr).toContain('NoComponent'); }); }, TEST_TIMEOUT, ); it( 'considers js and jsx by default', () => { createTempfiles(); createTempfiles('jsx'); createTempfiles('foo'); return run([tempDir]).then(([stdout, stderr]) => { expect(stdout).toContain('Component.js'); expect(stdout).toContain('Component.jsx'); expect(stdout).not.toContain('Component.foo'); expect(stderr).toContain('NoComponent.js'); expect(stderr).toContain('NoComponent.jsx'); expect(stderr).not.toContain('NoComponent.foo'); }); }, TEST_TIMEOUT, ); it( 'considers files with the specified extension', () => { createTempfiles('foo'); createTempfiles('bar'); const verify = ([stdout, stderr]) => { expect(stdout).toContain('Component.foo'); expect(stdout).toContain('Component.bar'); expect(stderr).toContain('NoComponent.foo'); expect(stderr).toContain('NoComponent.bar'); }; return Promise.all([ run(['--extension=foo', '--extension=bar', tempDir]).then(verify), run(['-x', 'foo', '-x', 'bar', tempDir]).then(verify), ]); }, TEST_TIMEOUT, ); it( 'ignores files in node_modules, __tests__ and __mocks__ by default', () => { createTempfiles(null, 'node_modules'); createTempfiles(null, '__tests__'); createTempfiles(null, '__mocks__'); return run([tempDir]).then(([stdout, stderr]) => { expect(stdout).toBe(''); expect(stderr).toBe(''); }); }, TEST_TIMEOUT, ); it( 'ignores specified folders', () => { createTempfiles(null, 'foo'); const verify = ([stdout, stderr]) => { expect(stdout).toBe(''); expect(stderr).toBe(''); }; return Promise.all([ run(['--ignore=foo', tempDir]).then(verify), run(['-i', 'foo', tempDir]).then(verify), ]); }, TEST_TIMEOUT, ); it( 'writes to stdout', () => { return run([], component).then(([stdout, stderr]) => { expect(stdout.length > 0).toBe(true); expect(stderr.length).toBe(0); }); }, TEST_TIMEOUT, ); it( 'writes to stderr', () => { return run([], '{}').then(([stdout, stderr]) => { expect(stderr.length > 0).toBe(true); expect(stdout.length).toBe(0); }); }, TEST_TIMEOUT, ); it( 'writes to a file if provided', () => { const outFile = temp.openSync(); createTempfiles(); const verify = ([stdout]) => { expect(fs.readFileSync(outFile.path)).not.toBe(''); expect(stdout).toBe(''); }; return Promise.all([ run(['--out=' + outFile.path, tempDir]).then(verify), run(['-o', outFile.path, tempDir]).then(verify), ]); }, TEST_TIMEOUT, ); describe('--resolver', () => { it( 'accepts the names of built in resolvers', () => { return Promise.all([ // No option passed: same as --resolver=findExportedComponentDefinition run([ path.join(__dirname, '../../example/components/Component.js'), ]).then(([stdout]) => { expect(stdout).toContain('Component'); }), run([ '--resolver=findExportedComponentDefinition', path.join(__dirname, '../../example/components/Component.js'), ]).then(([stdout]) => { expect(stdout).toContain('Component'); }), run([ '--resolver=findAllComponentDefinitions', path.join(__dirname, './example/MultipleComponents.js'), ]).then(([stdout]) => { expect(stdout).toContain('ComponentA'); expect(stdout).toContain('ComponentB'); }), ]); }, TEST_TIMEOUT, ); it( 'accepts a path to a resolver function', () => { return Promise.all([ run([ '--resolver=' + path.join(__dirname, 'example/customResolver.js'), path.join(__dirname, '../../example/components/Component.js'), ]).then(([stdout]) => { expect(stdout).toContain('Custom'); }), ]); }, TEST_TIMEOUT, ); }); describe('--exclude/-e', () => { it( 'ignores files by name', () => { createTempfiles(null, 'foo'); createTempfiles(null, 'bar'); const verify = ([stdout, stderr]) => { expect(stdout).toBe(''); expect(stderr).toBe(''); }; return run([ '--exclude=Component.js', '--exclude=NoComponent.js', tempDir, ]).then(verify); }, TEST_TIMEOUT, ); it( 'ignores files by regex', () => { createTempfiles(null, 'foo'); createTempfiles(null, 'bar'); const verify = ([stdout, stderr]) => { expect(stdout).toBe(''); expect(stderr).toBe(''); }; return run(['--exclude=/.*Component\\.js/', tempDir]).then(verify); }, TEST_TIMEOUT, ); }); });