documentation/__tests__/lib/flow_doctrine.js
2018-12-17 10:22:53 -08:00

317 lines
6.3 KiB
JavaScript

const flowDoctrine = require('../../src/flow_doctrine.js');
const parse = require('../../src/parsers/javascript');
const FLOW_TYPES = require('@babel/types').FLOW_TYPES;
function toComment(fn, filename) {
return parse(
{
file: filename,
source: fn instanceof Function ? '(' + fn.toString() + ')' : fn
},
{}
)[0];
}
test('flowDoctrine', function() {
const types = FLOW_TYPES.filter(function(type) {
return type.match(/\wTypeAnnotation$/);
});
function toDoctrineType(flowType) {
const annotation = toComment(
'/** add */function add(a: ' + flowType + ' ) { }'
).context.ast.node.params[0].typeAnnotation.typeAnnotation;
if (types.indexOf(annotation.type) !== -1) {
types.splice(types.indexOf(annotation.type), 1);
}
return flowDoctrine(annotation);
}
expect(toDoctrineType('number')).toEqual({
type: 'NameExpression',
name: 'number'
});
expect(toDoctrineType('string')).toEqual({
type: 'NameExpression',
name: 'string'
});
expect(toDoctrineType('any')).toEqual({
type: 'AllLiteral'
});
expect(toDoctrineType('(y:Foo) => Bar')).toEqual({
type: 'FunctionType',
params: [
{
type: 'ParameterType',
name: 'y',
expression: {
type: 'NameExpression',
name: 'Foo'
}
}
],
result: {
type: 'NameExpression',
name: 'Bar'
}
});
expect(toDoctrineType('?number')).toEqual({
type: 'NullableType',
expression: {
type: 'NameExpression',
name: 'number'
}
});
expect(toDoctrineType('number | string')).toEqual({
type: 'UnionType',
elements: [
{
type: 'NameExpression',
name: 'number'
},
{
type: 'NameExpression',
name: 'string'
}
]
});
expect(toDoctrineType('Object')).toEqual({
type: 'NameExpression',
name: 'Object'
});
expect(toDoctrineType('namedType.propertyOfType')).toEqual({
type: 'NameExpression',
name: 'namedType.propertyOfType'
});
expect(toDoctrineType('Array<namedType.propertyOfType>')).toEqual({
applications: [
{
type: 'NameExpression',
name: 'namedType.propertyOfType'
}
],
expression: {
name: 'Array',
type: 'NameExpression'
},
type: 'TypeApplication'
});
expect(toDoctrineType('Array<namedType.propertyOfType<boolean>>')).toEqual({
applications: [
{
applications: [
{
name: 'boolean',
type: 'NameExpression'
}
],
expression: {
type: 'NameExpression',
name: 'namedType.propertyOfType'
},
type: 'TypeApplication'
}
],
expression: {
name: 'Array',
type: 'NameExpression'
},
type: 'TypeApplication'
});
expect(toDoctrineType('{ a: foo.bar }')).toEqual({
fields: [
{
key: 'a',
type: 'FieldType',
value: {
name: 'foo.bar',
type: 'NameExpression'
}
}
],
type: 'RecordType'
});
expect(toDoctrineType('{ a: { b: foo.bar } }')).toEqual({
fields: [
{
key: 'a',
type: 'FieldType',
value: {
type: 'RecordType',
fields: [
{
key: 'b',
type: 'FieldType',
value: {
name: 'foo.bar',
type: 'NameExpression'
}
}
]
}
}
],
type: 'RecordType'
});
expect(toDoctrineType('{ a: 1 }')).toEqual({
type: 'RecordType',
fields: [
{
type: 'FieldType',
key: 'a',
value: {
type: 'NumericLiteralType',
value: 1
}
}
]
});
expect(toDoctrineType('mixed')).toEqual({
type: 'AllLiteral'
});
expect(toDoctrineType('Array')).toEqual({
type: 'NameExpression',
name: 'Array'
});
expect(toDoctrineType('Array<number>')).toEqual({
type: 'TypeApplication',
expression: {
type: 'NameExpression',
name: 'Array'
},
applications: [
{
type: 'NameExpression',
name: 'number'
}
]
});
expect(toDoctrineType('number[]')).toEqual({
type: 'TypeApplication',
expression: {
type: 'NameExpression',
name: 'Array'
},
applications: [
{
type: 'NameExpression',
name: 'number'
}
]
});
expect(toDoctrineType('[]')).toEqual({
type: 'ArrayType',
elements: []
});
expect(toDoctrineType('[number]')).toEqual({
type: 'ArrayType',
elements: [
{
type: 'NameExpression',
name: 'number'
}
]
});
expect(toDoctrineType('[string, boolean]')).toEqual({
type: 'ArrayType',
elements: [
{
type: 'NameExpression',
name: 'string'
},
{
type: 'NameExpression',
name: 'boolean'
}
]
});
expect(toDoctrineType('boolean')).toEqual({
type: 'NameExpression',
name: 'boolean'
});
expect(toDoctrineType('any => any')).toEqual({
type: 'FunctionType',
params: [
{
expression: { type: 'AllLiteral' },
name: '',
type: 'ParameterType'
}
],
result: { type: 'AllLiteral' }
});
expect(toDoctrineType('undefined')).toEqual({
type: 'NameExpression',
name: 'undefined'
});
expect(toDoctrineType('"value"')).toEqual({
type: 'StringLiteralType',
value: 'value'
});
expect(toDoctrineType('1')).toEqual({
type: 'NumericLiteralType',
value: 1
});
expect(toDoctrineType('true')).toEqual({
type: 'BooleanLiteralType',
value: true
});
expect(toDoctrineType('false')).toEqual({
type: 'BooleanLiteralType',
value: false
});
expect(toDoctrineType('null')).toEqual({
type: 'NullLiteral'
});
expect(toDoctrineType('void')).toEqual({
type: 'VoidLiteral'
});
expect(toDoctrineType('this')).toEqual({
type: 'NameExpression',
name: 'this'
});
expect(toDoctrineType('{ ...A }')).toEqual({
fields: [],
type: 'RecordType'
});
// TODO: remove all these types
expect(types).toEqual([
'ExistsTypeAnnotation',
'InterfaceTypeAnnotation',
'IntersectionTypeAnnotation',
'EmptyTypeAnnotation',
'TypeofTypeAnnotation'
]);
});