-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.js
101 lines (92 loc) · 2.69 KB
/
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// @flow
'use strict';
const pluginTester = require('babel-plugin-tester');
const getBabylonOptions = require('babylon-options');
const printAST = require('ast-pretty-print');
const {getFlowBindingsInScope, findFlowBinding} = require('./');
const babelOptions = {
parserOpts: getBabylonOptions({
stage: 0,
plugins: ['flow'],
}),
};
const print = (t, value) => {
let printed = printAST(value) + '\n';
return t.expressionStatement(
t.templateLiteral([
t.templateElement({ raw: printed }, true)
], [])
);
};
const capturePlugin = ({ types: t }) => {
let getOutput = path => {
return print(t, getFlowBindingsInScope(path));
};
return {
name: 'test-capture-plugin',
visitor: {
Program(path) {
path.unshiftContainer('body', getOutput(path));
},
'ClassDeclaration|FunctionDeclaration|InterfaceDeclaration|TypeAlias'(path) {
if (path.parentPath.isExportDeclaration()) {
path.parentPath.insertAfter(getOutput(path));
} else {
path.insertAfter(getOutput(path));
}
},
ClassExpression(path) {
path.find(p => p.isDeclaration()).insertAfter(getOutput(path));
}
},
};
};
pluginTester({
plugin: capturePlugin,
snapshot: true,
babelOptions,
tests: {
'import type': 'import type a from "mod";',
'import {type}': 'import {type a} from "mod";',
'import typeof': 'import typeof {a} from "mod";',
'import {typeof}': 'import {typeof a} from "mod";',
'type alias': 'type a = {};',
'interface declaration': 'interface a {}',
'class declaration': 'class a {}',
'type alias params': 'type a<b> = {}',
'interface params': 'interface a<b> {}',
'class params': 'class a<b> {}',
'function params': 'function a<b>() {}',
'nested': 'function a<b>() {}',
'class expression': 'let a = class b {}',
'export type alias': 'export type a = {}',
'export interface declaration': 'export interface a {}',
'export class declaration': 'export class a {}',
'export default class declaration': 'export default class a {}',
}
});
const searchPlugin = ({ types: t }) => {
let getOutput = path => {
return print(t, findFlowBinding(path, 'END'));
};
return {
name: 'test-search-plugin',
visitor: {
Identifier(path) {
if (path.node.name === 'START') {
path.find(p => p.isStatement()).insertAfter(getOutput(path));
}
}
},
};
};
pluginTester({
plugin: searchPlugin,
snapshot: true,
babelOptions,
tests: {
'current scope': 'type END = 1; START;',
'nested scope': 'type END = 1; function a() { START; }',
'deep nested scope': 'type END = 1; function a() { function b() { START; } }',
}
})