Skip to content
This repository was archived by the owner on Mar 8, 2019. It is now read-only.

Commit ddfbf82

Browse files
authored
fix: multiple exports (#88)
* make structure for exports * make sure all exported members are named * ready for muti mixins experimentation * add multi mixins tests * fix case of unit test fixes #87
1 parent 619f22c commit ddfbf82

24 files changed

+299
-140
lines changed

src/parse-script.ts

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ParserPlugin } from '@babel/parser'
22
import * as bt from '@babel/types'
33
import { NodePath } from 'ast-types'
4+
import Map from 'ts-map'
45
import buildParser from './babel-parser'
56
import { Documentation } from './Documentation'
67
import cacher from './utils/cacher'
@@ -11,13 +12,19 @@ import recast = require('recast')
1112

1213
const ERROR_MISSING_DEFINITION = 'No suitable component definition found'
1314

15+
interface ParseScriptOptions {
16+
lang: 'ts' | 'js'
17+
filePath: string
18+
nameFilter?: string[]
19+
}
20+
1421
export default function parseScript(
1522
source: string,
1623
documentation: Documentation,
1724
handlers: Array<
1825
(doc: Documentation, componentDefinition: NodePath, ast: bt.File, filePath: string) => void
1926
>,
20-
options: { lang: 'ts' | 'js'; filePath: string },
27+
options: ParseScriptOptions,
2128
) {
2229
const plugins: ParserPlugin[] = options.lang === 'ts' ? ['typescript'] : ['flow']
2330

@@ -26,28 +33,27 @@ export default function parseScript(
2633
throw new Error(ERROR_MISSING_DEFINITION)
2734
}
2835

29-
// FIXME: should be a Map<nameOfExport,NodePath>
30-
// then the documentation can become a map itself and we can look at component/mixins
31-
// with multiple items inside
3236
const componentDefinitions = resolveExportedComponent(ast)
3337

34-
if (componentDefinitions.length === 0) {
38+
if (componentDefinitions.size === 0) {
3539
throw new Error(ERROR_MISSING_DEFINITION)
3640
}
3741

38-
executeHandlers(handlers, componentDefinitions, documentation, ast, options.filePath)
42+
executeHandlers(handlers, componentDefinitions, documentation, ast, options)
3943
}
4044

4145
function executeHandlers(
4246
localHandlers: Array<
4347
(doc: Documentation, componentDefinition: NodePath, ast: bt.File, filePath: string) => void
4448
>,
45-
componentDefinitions: NodePath[],
49+
componentDefinitions: Map<string, NodePath>,
4650
documentation: Documentation,
4751
ast: bt.File,
48-
filePath: string,
52+
opt: ParseScriptOptions,
4953
) {
50-
return componentDefinitions.forEach(compDef => {
51-
localHandlers.forEach(handler => handler(documentation, compDef, ast, filePath))
54+
return componentDefinitions.forEach((compDef, name) => {
55+
if (compDef && name && (!opt.nameFilter || opt.nameFilter.indexOf(name) > -1)) {
56+
localHandlers.forEach(handler => handler(documentation, compDef, ast, opt.filePath))
57+
}
5258
})
5359
}

src/parse.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ const ERROR_EMPTY_DOCUMENT = 'The passed source is empty'
1616
* @param {string} filePath path of the current file against whom to resolve the mixins
1717
* @returns {object} documentation object
1818
*/
19-
export function parseFile(filePath: string, documentation: Documentation) {
19+
export function parseFile(filePath: string, documentation: Documentation, nameFilter?: string[]) {
2020
const source = fs.readFileSync(filePath, {
2121
encoding: 'utf-8',
2222
})
23-
return parseSource(source, filePath, documentation)
23+
return parseSource(source, filePath, documentation, nameFilter)
2424
}
2525

2626
/**
@@ -29,7 +29,12 @@ export function parseFile(filePath: string, documentation: Documentation) {
2929
* @param {string} filePath path of the current file against whom to resolve the mixins
3030
* @returns {object} documentation object
3131
*/
32-
export function parseSource(source: string, filePath: string, documentation: Documentation) {
32+
export function parseSource(
33+
source: string,
34+
filePath: string,
35+
documentation: Documentation,
36+
nameFilter?: string[],
37+
) {
3338
const singleFileComponent = /\.vue$/i.test(path.extname(filePath))
3439
let parts: SFCDescriptor | null = null
3540

@@ -48,7 +53,7 @@ export function parseSource(source: string, filePath: string, documentation: Doc
4853
/\.tsx?$/i.test(path.extname(filePath))
4954
? 'ts'
5055
: 'js'
51-
parseScript(scriptSource, documentation, handlers, { lang, filePath })
56+
parseScript(scriptSource, documentation, handlers, { lang, filePath, nameFilter })
5257
}
5358

5459
// get slots from template

src/script-handlers/__tests__/classDisplayNameHandler.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ describe('classDisplayNameHandler', () => {
2323
export default class Decorum extends Vue{
2424
}
2525
`
26-
const def = parse(src)
27-
classDisplayNameHandler(documentation, def[0])
26+
const def = parse(src).get('default')
27+
if (def) {
28+
classDisplayNameHandler(documentation, def)
29+
}
2830
expect(documentation.set).toHaveBeenCalledWith('displayName', 'Decorum')
2931
})
3032

@@ -34,8 +36,10 @@ describe('classDisplayNameHandler', () => {
3436
export default class Test extends Vue{
3537
}
3638
`
37-
const def = parse(src)
38-
classDisplayNameHandler(documentation, def[0])
39+
const def = parse(src).get('default')
40+
if (def) {
41+
classDisplayNameHandler(documentation, def)
42+
}
3943
expect(documentation.set).toHaveBeenCalledWith('displayName', 'decorum')
4044
})
4145
})

src/script-handlers/__tests__/classMethodHandler.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import { NodePath } from 'ast-types'
2+
import Map from 'ts-map'
13
import babylon from '../../babel-parser'
24
import { Documentation, MethodDescriptor } from '../../Documentation'
35
import resolveExportedComponent from '../../utils/resolveExportedComponent'
46
import classMethodHandler from '../classMethodHandler'
57

68
jest.mock('../../Documentation')
79

8-
function parseTS(src: string) {
10+
function parseTS(src: string): Map<string, NodePath> {
911
const ast = babylon({ plugins: ['typescript'] }).parse(src)
1012
return resolveExportedComponent(ast)
1113
}
@@ -26,8 +28,10 @@ describe('classPropHandler', () => {
2628
})
2729

2830
function tester(src: string, matchedObj: any) {
29-
const def = parseTS(src)
30-
classMethodHandler(documentation, def[0])
31+
const def = parseTS(src).get('default')
32+
if (def) {
33+
classMethodHandler(documentation, def)
34+
}
3135
expect(mockMethodDescriptor).toMatchObject(matchedObj)
3236
}
3337

src/script-handlers/__tests__/classPropHandler.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import { NodePath } from 'ast-types'
2+
import Map from 'ts-map'
13
import babylon from '../../babel-parser'
24
import { Documentation, PropDescriptor } from '../../Documentation'
35
import resolveExportedComponent from '../../utils/resolveExportedComponent'
46
import classPropHandler from '../classPropHandler'
57

68
jest.mock('../../Documentation')
79

8-
function parse(src: string) {
10+
function parse(src: string): Map<string, NodePath> {
911
const ast = babylon({ plugins: ['typescript'] }).parse(src)
1012
return resolveExportedComponent(ast)
1113
}
@@ -27,8 +29,8 @@ describe('propHandler', () => {
2729
})
2830

2931
function tester(src: string, matchedObj: any) {
30-
const def = parse(src)
31-
classPropHandler(documentation, def[0] as any)
32+
const def = parse(src).get('default')
33+
classPropHandler(documentation, def as any)
3234
expect(mockPropDescriptor).toMatchObject(matchedObj)
3335
}
3436

src/script-handlers/__tests__/componentHandler.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { ParserPlugin } from '@babel/parser'
2+
import { NodePath } from 'ast-types'
3+
import Map from 'ts-map'
24
import babylon from '../../babel-parser'
35
import { Documentation } from '../../Documentation'
46
import resolveExportedComponent from '../../utils/resolveExportedComponent'
57
import componentHandler from '../componentHandler'
68

79
jest.mock('../../Documentation')
810

9-
function parse(src: string, plugins: ParserPlugin[] = []) {
11+
function parse(src: string, plugins: ParserPlugin[] = []): Map<string, NodePath> {
1012
const ast = babylon({ plugins }).parse(src)
1113
return resolveExportedComponent(ast)
1214
}
@@ -27,8 +29,10 @@ describe('componentHandler', () => {
2729
name: 'name-123',
2830
}
2931
`
30-
const def = parse(src)
31-
componentHandler(documentation, def[0])
32+
const def = parse(src).get('default')
33+
if (def) {
34+
componentHandler(documentation, def)
35+
}
3236
expect(documentation.set).toHaveBeenCalledWith('description', 'An empty component')
3337
})
3438

@@ -43,8 +47,10 @@ describe('componentHandler', () => {
4347
name: 'name-123',
4448
}
4549
`
46-
const def = parse(src)
47-
componentHandler(documentation, def[0])
50+
const def = parse(src).get('default')
51+
if (def) {
52+
componentHandler(documentation, def)
53+
}
4854
expect(documentation.set).toHaveBeenCalledWith('tags', {
4955
author: [{ description: '[Rafael]', title: 'author' }],
5056
version: [{ description: '12.5.7', title: 'version' }],
@@ -62,8 +68,10 @@ describe('componentHandler', () => {
6268
6369
}
6470
`
65-
const def = parse(src, ['typescript'])
66-
componentHandler(documentation, def[0])
71+
const def = parse(src, ['typescript']).get('default')
72+
if (def) {
73+
componentHandler(documentation, def)
74+
}
6775
expect(documentation.set).toHaveBeenCalledWith('tags', {
6876
version: [{ description: '12.5.7', title: 'version' }],
6977
})

src/script-handlers/__tests__/displayNameHandler.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1+
import { NodePath } from 'ast-types'
12
import babylon from '../../babel-parser'
23
import { Documentation } from '../../Documentation'
34
import resolveExportedComponent from '../../utils/resolveExportedComponent'
45
import displayNameHandler from '../displayNameHandler'
56

67
jest.mock('../../Documentation')
78

8-
function parse(src: string) {
9+
function parse(src: string): NodePath | undefined {
910
const ast = babylon().parse(src)
10-
return resolveExportedComponent(ast)
11+
return resolveExportedComponent(ast).get('default')
1112
}
1213

1314
describe('displayNameHandler', () => {
@@ -27,7 +28,9 @@ describe('displayNameHandler', () => {
2728
}
2829
`
2930
const def = parse(src)
30-
displayNameHandler(documentation, def[0])
31+
if (def) {
32+
displayNameHandler(documentation, def)
33+
}
3134
expect(documentation.set).toHaveBeenCalledWith('displayName', 'name-123')
3235
})
3336

@@ -42,7 +45,9 @@ describe('displayNameHandler', () => {
4245
}
4346
`
4447
const def = parse(src)
45-
displayNameHandler(documentation, def[0])
48+
if (def) {
49+
displayNameHandler(documentation, def)
50+
}
4651
expect(documentation.set).toHaveBeenCalledWith('displayName', 'name-123')
4752
})
4853
})

src/script-handlers/__tests__/eventHandler.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import eventHandler from '../eventHandler'
66

77
jest.mock('../../Documentation')
88

9-
function parse(src: string): NodePath[] {
9+
function parse(src: string): NodePath | undefined {
1010
const ast = babylon().parse(src)
11-
return resolveExportedComponent(ast)
11+
return resolveExportedComponent(ast).get('default')
1212
}
1313

1414
describe('eventHandler', () => {
@@ -38,7 +38,9 @@ describe('eventHandler', () => {
3838
}
3939
`
4040
const def = parse(src)
41-
eventHandler(documentation, def[0])
41+
if (def) {
42+
eventHandler(documentation, def)
43+
}
4244
const eventComp: EventDescriptor = {
4345
description: 'Describe the event',
4446
properties: [
@@ -71,7 +73,9 @@ describe('eventHandler', () => {
7173
}
7274
`
7375
const def = parse(src)
74-
eventHandler(documentation, def[0])
76+
if (def) {
77+
eventHandler(documentation, def)
78+
}
7579
const eventComp: EventDescriptor = {
7680
description: '',
7781
type: {

src/script-handlers/__tests__/extendsHandler.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ describe('extendsHandler', () => {
1919
resolveRequiredMock = resolveRequired as jest.Mock<
2020
(ast: bt.File, varNameFilter?: string[]) => { [key: string]: string }
2121
>
22-
resolveRequiredMock.mockReturnValue({ testComponent: './componentPath' })
22+
resolveRequiredMock.mockReturnValue({
23+
testComponent: { filePath: './componentPath', exportName: 'default' },
24+
})
2325

2426
mockResolvePathFrom = resolvePathFrom as jest.Mock<(path: string, from: string) => string>
2527
mockResolvePathFrom.mockReturnValue('./component/full/path')
@@ -30,8 +32,10 @@ describe('extendsHandler', () => {
3032

3133
function parseItExtends(src: string) {
3234
const ast = babylon().parse(src)
33-
const path = resolveExportedComponent(ast)
34-
extendsHandler(doc, path[0], ast, '')
35+
const path = resolveExportedComponent(ast).get('default')
36+
if (path) {
37+
extendsHandler(doc, path, ast, '')
38+
}
3539
}
3640

3741
it('should resolve extended modules variables in import default', () => {
@@ -42,7 +46,7 @@ describe('extendsHandler', () => {
4246
'}',
4347
].join('\n')
4448
parseItExtends(src)
45-
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc)
49+
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc, ['default'])
4650
})
4751

4852
it('should resolve extended modules variables in require', () => {
@@ -53,27 +57,28 @@ describe('extendsHandler', () => {
5357
'}',
5458
].join('\n')
5559
parseItExtends(src)
56-
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc)
60+
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc, ['default'])
5761
})
5862

5963
it('should resolve extended modules variables in import', () => {
6064
const src = [
61-
'import { testComponent, other } from "./testComponent"',
65+
'import { test as testComponent, other } from "./testComponent"',
6266
'export default {',
6367
' extends:testComponent',
6468
'}',
6569
].join('\n')
6670
parseItExtends(src)
67-
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc)
71+
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc, ['default'])
6872
})
6973

7074
it('should resolve extended modules variables in class style components', () => {
7175
const src = [
72-
'import { testComponent} from "./testComponent"',
76+
'import { testComponent } from "./testComponent";',
77+
'@Component',
7378
'export default class Bart extends testComponent {',
7479
'}',
7580
].join('\n')
7681
parseItExtends(src)
77-
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc)
82+
expect(parseFile).toHaveBeenCalledWith('./component/full/path', doc, ['default'])
7883
})
7984
})

0 commit comments

Comments
 (0)