mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-05 22:19:46 -06:00
Decaff helper jscodemods. (#5732)
* Added a file that removes comments that start with #. * Added .eslintrc to silence ts errors in codemods. * Convert switch (false) to if-else. * Add disable-eslint no-empty by default after empty catch. * Reserve comments when converting switch-case. * Added new codemods to bulk-decaffeinate. * Preserve comments. * Ignored lint rules for test fixtures. * Move comments between arrow and block to the top. * Merged tests into one file. * Turned off no-undef for test fixtures. * No-cond-assign * Added jscodemods to decaff config. * Fixed typo. * Make CI test codemods * Added test-no-return. * Revert "Added test-no-return." This reverts commit d610829e957e38a6d56c19ba2219681e3f6c65ec. * fix arrow-comment Co-authored-by: Ben Kucera <14625260+Bkucera@users.noreply.github.com> Co-authored-by: Zach Bloomquist <github@chary.us>
This commit is contained in:
committed by
Zach Bloomquist
parent
4a2636ddd3
commit
994ab326a0
3
scripts/decaff/.eslintrc.json
Normal file
3
scripts/decaff/.eslintrc.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"parser": "espree"
|
||||
}
|
||||
11
scripts/decaff/__testfixtures__/.eslintrc.json
Normal file
11
scripts/decaff/__testfixtures__/.eslintrc.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"parser": "espree",
|
||||
"rules": {
|
||||
"no-empty": "off",
|
||||
"no-undef": "off",
|
||||
"no-cond-assign": "off",
|
||||
"semi": "off",
|
||||
"brace-style": "off",
|
||||
"no-case-declarations": "off"
|
||||
}
|
||||
}
|
||||
10
scripts/decaff/__testfixtures__/arrow-comment.input.js
Normal file
10
scripts/decaff/__testfixtures__/arrow-comment.input.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// Original comment
|
||||
const func = (a, b) =>
|
||||
// Multiline comment
|
||||
// is here
|
||||
{
|
||||
a.works()
|
||||
b.check.thisOut()
|
||||
}
|
||||
|
||||
func()
|
||||
10
scripts/decaff/__testfixtures__/arrow-comment.output.js
Normal file
10
scripts/decaff/__testfixtures__/arrow-comment.output.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// Original comment
|
||||
// Multiline comment
|
||||
// is here
|
||||
const func = (a, b) =>
|
||||
{
|
||||
a.works()
|
||||
b.check.thisOut()
|
||||
};
|
||||
|
||||
func()
|
||||
7
scripts/decaff/__testfixtures__/empty-catch.input.js
Normal file
7
scripts/decaff/__testfixtures__/empty-catch.input.js
Normal file
@@ -0,0 +1,7 @@
|
||||
try {
|
||||
// do something
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
// do something
|
||||
} finally {}
|
||||
7
scripts/decaff/__testfixtures__/empty-catch.output.js
Normal file
7
scripts/decaff/__testfixtures__/empty-catch.output.js
Normal file
@@ -0,0 +1,7 @@
|
||||
try {
|
||||
// do something
|
||||
} catch (e) {} // eslint-disable-line no-empty
|
||||
|
||||
try {
|
||||
// do something
|
||||
} finally {}
|
||||
6
scripts/decaff/__testfixtures__/no-cond-assign.input.js
Normal file
6
scripts/decaff/__testfixtures__/no-cond-assign.input.js
Normal file
@@ -0,0 +1,6 @@
|
||||
let a
|
||||
|
||||
// Comment
|
||||
if (a = c()) {
|
||||
a.fix()
|
||||
}
|
||||
8
scripts/decaff/__testfixtures__/no-cond-assign.output.js
Normal file
8
scripts/decaff/__testfixtures__/no-cond-assign.output.js
Normal file
@@ -0,0 +1,8 @@
|
||||
let a
|
||||
|
||||
// Comment
|
||||
a = c();
|
||||
|
||||
if (a) {
|
||||
a.fix()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
//# Testing this
|
||||
// eslint-disable-next-line
|
||||
console.log('it works') //# Test
|
||||
|
||||
// This # should not be removed.
|
||||
/*# it's not wrong */
|
||||
@@ -0,0 +1,6 @@
|
||||
// Testing this
|
||||
// eslint-disable-next-line
|
||||
console.log('it works') // Test
|
||||
|
||||
// This # should not be removed.
|
||||
/*# it's not wrong */
|
||||
33
scripts/decaff/__testfixtures__/switch-false.input.js
Normal file
33
scripts/decaff/__testfixtures__/switch-false.input.js
Normal file
@@ -0,0 +1,33 @@
|
||||
function f () {
|
||||
switch (false) {
|
||||
// Comment should be reserved
|
||||
case !a.subject(a):
|
||||
let x = 30
|
||||
|
||||
b.doSomething(x)
|
||||
break
|
||||
// Multi line comment
|
||||
// should be reserved
|
||||
case c.isGood:
|
||||
c.checkThisOut()
|
||||
findThings()
|
||||
break
|
||||
case isBad:
|
||||
c.neverCheck()
|
||||
break
|
||||
case !isAwesome:
|
||||
a.subject(a)
|
||||
break
|
||||
case hi:
|
||||
// This should be reserved, too
|
||||
return 3
|
||||
case you:
|
||||
// This comment is preserved
|
||||
break
|
||||
default:
|
||||
b.goToNext()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
f()
|
||||
25
scripts/decaff/__testfixtures__/switch-false.output.js
Normal file
25
scripts/decaff/__testfixtures__/switch-false.output.js
Normal file
@@ -0,0 +1,25 @@
|
||||
function f () {
|
||||
if (a.subject(a)) {
|
||||
// Comment should be reserved
|
||||
let x = 30;
|
||||
|
||||
b.doSomething(x)
|
||||
} else if (!c.isGood) {
|
||||
// Multi line comment
|
||||
// should be reserved
|
||||
c.checkThisOut();
|
||||
findThings()
|
||||
} else if (!isBad) {
|
||||
c.neverCheck();
|
||||
} else if (isAwesome) {
|
||||
a.subject(a);
|
||||
} else if (!hi) {
|
||||
// This should be reserved, too
|
||||
return 3
|
||||
} else if (!you) // This comment is preserved
|
||||
{} else {
|
||||
b.goToNext();
|
||||
}
|
||||
}
|
||||
|
||||
f()
|
||||
10
scripts/decaff/__tests__/decaff.test.js
Normal file
10
scripts/decaff/__tests__/decaff.test.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/* global jest */
|
||||
|
||||
jest.autoMockOff()
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(__dirname, 'switch-false')
|
||||
defineTest(__dirname, 'empty-catch')
|
||||
defineTest(__dirname, 'remove-comment-sharp')
|
||||
defineTest(__dirname, 'arrow-comment')
|
||||
defineTest(__dirname, 'no-cond-assign')
|
||||
28
scripts/decaff/arrow-comment.js
Normal file
28
scripts/decaff/arrow-comment.js
Normal file
@@ -0,0 +1,28 @@
|
||||
module.exports = (fileInfo, api) => {
|
||||
const j = api.jscodeshift
|
||||
|
||||
return j(fileInfo.source)
|
||||
.find(j.VariableDeclaration, {
|
||||
declarations: [{
|
||||
type: 'VariableDeclarator',
|
||||
init: {
|
||||
type: 'ArrowFunctionExpression',
|
||||
body: {
|
||||
type: 'BlockStatement',
|
||||
},
|
||||
},
|
||||
}],
|
||||
})
|
||||
.replaceWith((nodePath) => {
|
||||
const { node } = nodePath
|
||||
const comments = node.declarations[0].init.body.comments
|
||||
|
||||
if (comments && comments.length > 0) {
|
||||
node.comments = [...node.comments, ...comments]
|
||||
node.declarations[0].init.body.comments = null
|
||||
}
|
||||
|
||||
return node
|
||||
})
|
||||
.toSource()
|
||||
}
|
||||
28
scripts/decaff/empty-catch.js
Normal file
28
scripts/decaff/empty-catch.js
Normal file
@@ -0,0 +1,28 @@
|
||||
module.exports = (fileInfo, api) => {
|
||||
const j = api.jscodeshift
|
||||
|
||||
const source = j(fileInfo.source)
|
||||
.find(j.TryStatement)
|
||||
.replaceWith((nodePath) => {
|
||||
const { node } = nodePath
|
||||
|
||||
// Add trailing eslint-disable-line for empty catch block
|
||||
if (node.handler && node.handler.body.body.length === 0) {
|
||||
node.handler.body.comments = [
|
||||
{
|
||||
type: 'Line',
|
||||
value: ' eslint-disable-line no-empty',
|
||||
leading: false,
|
||||
trailing: true,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
return node
|
||||
})
|
||||
.toSource()
|
||||
|
||||
// Generated source above creates {}// eslint-disable-line block.
|
||||
// So, add a space with replace
|
||||
return source.replace(/\{\}\/\/ eslint-disable-line/g, '{} // eslint-disable-line')
|
||||
}
|
||||
29
scripts/decaff/no-cond-assign.js
Normal file
29
scripts/decaff/no-cond-assign.js
Normal file
@@ -0,0 +1,29 @@
|
||||
module.exports = (fileInfo, api) => {
|
||||
const j = api.jscodeshift
|
||||
|
||||
return j(fileInfo.source)
|
||||
.find(j.IfStatement, {
|
||||
test: {
|
||||
type: 'AssignmentExpression',
|
||||
},
|
||||
})
|
||||
.replaceWith((nodePath) => {
|
||||
const { node } = nodePath
|
||||
|
||||
const assign = j.expressionStatement(node.test)
|
||||
|
||||
assign.comments = node.comments
|
||||
|
||||
const ifStatement = j.ifStatement(
|
||||
node.test.left,
|
||||
node.consequent,
|
||||
node.alternate
|
||||
)
|
||||
|
||||
return [
|
||||
assign,
|
||||
ifStatement,
|
||||
]
|
||||
})
|
||||
.toSource()
|
||||
}
|
||||
4
scripts/decaff/remove-comment-sharp.js
Normal file
4
scripts/decaff/remove-comment-sharp.js
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file doesn't use AST because it makes things too complicated.
|
||||
module.exports = (fileInfo) => {
|
||||
return fileInfo.source.replace(/\/\/#/g, '//')
|
||||
}
|
||||
98
scripts/decaff/switch-false.js
Normal file
98
scripts/decaff/switch-false.js
Normal file
@@ -0,0 +1,98 @@
|
||||
module.exports = (fileInfo, api) => {
|
||||
const j = api.jscodeshift
|
||||
|
||||
return j(fileInfo.source)
|
||||
.find(j.SwitchStatement, {
|
||||
discriminant: {
|
||||
type: 'Literal',
|
||||
value: false,
|
||||
},
|
||||
})
|
||||
.replaceWith((nodePath) => {
|
||||
const { node } = nodePath
|
||||
|
||||
const cases = node.cases.map((c) => {
|
||||
const { test, consequent, comments } = c
|
||||
|
||||
return {
|
||||
test: generateTest(j, test),
|
||||
content: generateContent(j, consequent),
|
||||
comments,
|
||||
}
|
||||
})
|
||||
|
||||
const ifStatement = generateIfStatement(j, cases)
|
||||
|
||||
ifStatement.comments = node.comments
|
||||
|
||||
return ifStatement
|
||||
})
|
||||
.toSource()
|
||||
}
|
||||
|
||||
function generateTest (j, test) {
|
||||
if (test) {
|
||||
if (test.type === 'UnaryExpression') {
|
||||
return test.argument
|
||||
}
|
||||
|
||||
return j.unaryExpression('!', test)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function generateContent (j, consequent) {
|
||||
if (consequent.length === 1 && consequent[0].type === 'BreakStatement') {
|
||||
const block = j.blockStatement([])
|
||||
|
||||
block.comments = consequent[0].comments
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
return j.blockStatement(consequent.filter((c) => c.type !== 'BreakStatement'))
|
||||
}
|
||||
|
||||
function generateIfStatement (j, cases) {
|
||||
const nonDefaultCases = cases.filter((c) => c.test !== null)
|
||||
const defaultCase = cases.filter((c) => c.test === null)[0]
|
||||
|
||||
let ifStatement = null
|
||||
|
||||
if (defaultCase) {
|
||||
const content = addComment(defaultCase.content, defaultCase.comments)
|
||||
|
||||
ifStatement = content
|
||||
}
|
||||
|
||||
nonDefaultCases.reverse().forEach((c) => {
|
||||
const content = addComment(c.content, c.comments)
|
||||
|
||||
ifStatement = j.ifStatement(
|
||||
c.test,
|
||||
content,
|
||||
ifStatement
|
||||
)
|
||||
})
|
||||
|
||||
return ifStatement
|
||||
}
|
||||
|
||||
function addComment (content, comments) {
|
||||
if (content.body.length > 0) {
|
||||
content.body[0].comments = [...(comments || []), ...(content.body[0].comments || [])]
|
||||
} else {
|
||||
const newComments = (comments || []).map((co) => {
|
||||
return {
|
||||
...co,
|
||||
leading: false,
|
||||
trailing: false,
|
||||
}
|
||||
})
|
||||
|
||||
content.comments = [...newComments, ...(content.comments || [])]
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
Reference in New Issue
Block a user