fix(utils): `serializeFunction` fails with certain functions (#8780)

This commit is contained in:
Rafał Chłodnicki 2021-02-08 00:08:13 +01:00 committed by GitHub
parent eed98eb955
commit d343d85985
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 78 deletions

View File

@ -41,7 +41,8 @@ module.exports = {
], ],
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!(@nuxt|nuxt))' 'node_modules/(?!(@nuxt|nuxt))',
'packages/utils/test/serialize\\.test\\.input\\.js'
], ],
transform: { transform: {

View File

@ -44,7 +44,7 @@ export function serializeFunction (func) {
return _ return _
} }
}) })
.replace(`${func.name || 'function'}(`, 'function (') .replace(new RegExp(`${(func.name || 'function').replace('$', '\\$')}\\s*\\(`), 'function(')
.replace('function function', 'function') .replace('function function', 'function')
} }

View File

@ -0,0 +1,41 @@
// NOTE: This file is excluded from being transformed by babel-jest and needs to use the CommonJS syntax.
module.exports = {
arrow: {
// eslint-disable-next-line arrow-parens
fn1: foobar => {},
fn2: foobar => 1,
// eslint-disable-next-line arrow-parens
fn3: foobar => {
return 3
},
// eslint-disable-next-line arrow-parens
fn4: arg1 =>
2 * arg1,
fn5: () => {},
// eslint-disable-next-line arrow-parens
fn6: foobar => (foobar ? 1 : 0)
},
normal: {
fn: function () {} // eslint-disable-line object-shorthand
},
shorthand: {
fn () {},
// eslint-disable-next-line space-before-function-paren
$fn() {},
// eslint-disable-next-line no-unused-vars
fn_arrow () { const _ = rule => rule },
fn_script () {
return 'function xyz(){};a=false?true:xyz();'
},
fn_internal (arg) {
if (arg) {
return {
title () {
return 'test'
}
}
}
}
}
}

View File

@ -1,111 +1,69 @@
import { serializeFunction, normalizeFunctions } from '../src/serialize' import { serializeFunction, normalizeFunctions } from '../src/serialize'
import data from './serialize.test.input'
const RE_LINE_BREAKS = /[\r\n]+/g
describe('util: serialize', () => { describe('util: serialize', () => {
test('should normalize arrow functions', () => { test('should normalize arrow functions', () => {
const obj = { const normalized = normalizeFunctions(Object.assign({}, data.arrow))
// eslint-disable-next-line arrow-parens expect(normalized.fn1.toString()).toEqual('function anonymous(foobar\n) {\n\n}')
fn1: foobar => {}, expect(normalized.fn2.toString()).toEqual('function anonymous(foobar\n) {\nreturn 1\n}')
fn2: foobar => 1, expect(normalized.fn3.toString()).toEqual('function anonymous(foobar\n) {\nreturn 3\n}')
// eslint-disable-next-line arrow-parens expect(normalized.fn4.toString()).toEqual('function anonymous(arg1\n) {\nreturn 2 * arg1\n}')
fn3: foobar => {
return 3
},
// eslint-disable-next-line arrow-parens
fn4: arg1 =>
2 * arg1
}
expect(normalizeFunctions(obj).fn1.toString())
.toEqual('function anonymous(foobar\n) {\n\n}')
expect(normalizeFunctions(obj).fn2.toString())
.toEqual('function anonymous(foobar\n) {\nreturn 1\n}')
expect(normalizeFunctions(obj).fn3.toString())
.toEqual('function anonymous(foobar\n) {\nreturn 3;\n}')
expect(normalizeFunctions(obj).fn4.toString())
.toEqual('function anonymous(arg1\n) {\nreturn 2 * arg1\n}')
}) })
test('should serialize normal function', () => { test('should serialize normal function', () => {
const obj = { const obj = Object.assign({}, data.normal)
fn: function () {} // eslint-disable-line object-shorthand
}
expect(serializeFunction(obj.fn)).toEqual('function () {}') expect(serializeFunction(obj.fn)).toEqual('function () {}')
}) })
test('should serialize shorthand function', () => { test('should serialize shorthand function', () => {
const obj = { const obj = Object.assign({}, data.shorthand)
fn () {}
}
expect(serializeFunction(obj.fn)).toEqual('function() {}') expect(serializeFunction(obj.fn)).toEqual('function() {}')
expect(serializeFunction(obj.$fn)).toEqual('function() {}')
expect(serializeFunction(obj.fn_arrow)).toEqual('function() { const _ = rule => rule }')
}) })
test('should serialize arrow function', () => { test('should serialize arrow function', () => {
const obj = { const obj = Object.assign({}, data.arrow)
fn: () => {} expect(serializeFunction(obj.fn5)).toEqual('() => {}')
}
expect(serializeFunction(obj.fn)).toEqual('() => {}')
}) })
test('should serialize arrow function with ternary in parens', () => { test('should serialize arrow function with ternary in parens', () => {
const obj = { const obj = Object.assign({}, data.arrow)
// eslint-disable-next-line arrow-parens expect(serializeFunction(obj.fn6)).toEqual('foobar => (foobar ? 1 : 0)')
fn: foobar => (foobar ? 1 : 0)
}
expect(serializeFunction(obj.fn)).toEqual('foobar => foobar ? 1 : 0')
}) })
test('should serialize arrow function with single parameter', () => { test('should serialize arrow function with single parameter', () => {
const obj = { const obj = Object.assign({}, data.arrow)
// eslint-disable-next-line arrow-parens
fn1: foobar => {},
fn2: foobar => 1,
// eslint-disable-next-line arrow-parens
fn3: foobar => {
return 3
},
// eslint-disable-next-line arrow-parens
fn4: arg1 =>
2 * arg1
}
expect(serializeFunction(obj.fn1)).toEqual('foobar => {}') expect(serializeFunction(obj.fn1)).toEqual('foobar => {}')
expect(serializeFunction(obj.fn2)).toEqual('foobar => 1') expect(serializeFunction(obj.fn2)).toEqual('foobar => 1')
expect(serializeFunction(obj.fn3)).toEqual('foobar => {\n return 3;\n }') expect(serializeFunction(obj.fn3).replace(RE_LINE_BREAKS, '\n')).toEqual(`foobar => {
expect(serializeFunction(obj.fn4)).toEqual('arg1 => 2 * arg1') return 3
}`)
expect(serializeFunction(obj.fn4).replace(RE_LINE_BREAKS, '\n')).toEqual(`arg1 =>
2 * arg1`)
}) })
test('should not replace custom scripts', () => { test('should not replace custom scripts', () => {
const obj = { const obj = Object.assign({}, data.shorthand)
fn () {
return 'function xyz(){};a=false?true:xyz();'
}
}
expect(serializeFunction(obj.fn)).toEqual(`function () { expect(serializeFunction(obj.fn_script).replace(RE_LINE_BREAKS, '\n')).toEqual(`function() {
return 'function xyz(){};a=false?true:xyz();'; return 'function xyz(){};a=false?true:xyz();'
}`) }`)
}) })
test('should serialize internal function', () => { test('should serialize internal function', () => {
const obj = { const obj = Object.assign({}, data.shorthand)
fn (arg) {
if (arg) { expect(serializeFunction(obj.fn_internal).replace(RE_LINE_BREAKS, '\n')).toEqual(`function(arg) {
return { if (arg) {
title () { return {
return 'test' title: function () {
} return 'test'
} }
} }
} }
} }`)
expect(serializeFunction(obj.fn)).toEqual(`function(arg) {
if (arg) {
return {
title: function () {
return 'test';
}
};
}
}`)
}) })
}) })