diff --git a/tests/config/constants.js b/tests/config/constants.js new file mode 100644 index 000000000..e6c7c16a0 --- /dev/null +++ b/tests/config/constants.js @@ -0,0 +1,11 @@ +import path from "node:path"; +import createEsmUtils from "esm-utils"; +import { normalizeDirectory } from "./utilities.js"; + +const { __dirname } = createEsmUtils(import.meta); + +export const FORMAT_TEST_DIRECTORY = normalizeDirectory( + path.join(__dirname, "../format/"), +); + +export const CURSOR_PLACEHOLDER = "<|>"; diff --git a/tests/config/failed-format-tests.js b/tests/config/failed-format-tests.js new file mode 100644 index 000000000..795dd9e49 --- /dev/null +++ b/tests/config/failed-format-tests.js @@ -0,0 +1,63 @@ +import path from "node:path"; +import { FORMAT_TEST_DIRECTORY } from "./constants.js"; + +// Here we add files that will not be the same when formatting a second time. +const unstableTests = new Map( + [].map((fixture) => { + const [file, isUnstable = () => true] = Array.isArray(fixture) + ? fixture + : [fixture]; + return [path.join(FORMAT_TEST_DIRECTORY, file), isUnstable]; + }), +); + +// Here we add files that will not have the same AST after being formatted. +const unstableAstTests = new Map( + [ + // `: =` and `= :` are syntactically the same as `:=` and `=:`, but the ast + // changes from `YulColonAndEqual` and `YulEqualAndColon` to `ColonEqual` + // and `EqualColon`, which is expected but the workaround to keep the test + // stable is too much, so we just put it in this list. + "AssemblyV0.4.26/Assembly.sol", + ].map((fixture) => { + const [file, isUnstable = () => true] = Array.isArray(fixture) + ? fixture + : [fixture]; + return [path.join(FORMAT_TEST_DIRECTORY, file), isUnstable]; + }), +); + +const antlrMismatchTests = new Map( + [ + // Better placement of comments in Slang. + "BasicIterator/BasicIterator.sol", + "Comments/Comments.sol", + "IndexOf/IndexOf.sol", + // Syntax for `pragma solidity 0.5.0 - 0.6.0;` not supported by ANTLR + "Pragma/Pragma.sol", + // ANTLR doesn't support assembly assignment operators separated by a space + // like `: =` or `= :` + "AssemblyV0.4.26/Assembly.sol", + // ANTLR doesn't support UntypedTupleMember with a storage location, which + // is valid Slang, but not in Solidity. + "AllSolidityFeaturesV0.4.26/AllSolidityFeatures.sol", + // TODO Review how ANTLR is formatting chained assignments + "Assignments/Assignments.sol", + ].map((fixture) => { + const [file, isUnstable = () => true] = Array.isArray(fixture) + ? fixture + : [fixture]; + return [path.join(FORMAT_TEST_DIRECTORY, file), isUnstable]; + }), +); + +const isUnstable = (filepath, options) => + unstableTests.get(filepath)?.(options); + +const isAstUnstable = (filepath, options) => + unstableAstTests.get(filepath)?.(options); + +const isAntlrMismatch = (filepath, options) => + antlrMismatchTests.get(filepath)?.(options); + +export { isAstUnstable, isUnstable, isAntlrMismatch }; diff --git a/tests/config/run-format-test.js b/tests/config/run-format-test.js index 8cadbf577..3d0c5477e 100644 --- a/tests/config/run-format-test.js +++ b/tests/config/run-format-test.js @@ -11,6 +11,11 @@ import consistentEndOfLine from "./utils/consistent-end-of-line.js"; import createSnapshot from "./utils/create-snapshot.js"; import { stringifyOptionsForTitle } from "./utils/stringify-options-for-title.js"; import visualizeEndOfLine from "./utils/visualize-end-of-line.js"; +import { + isAntlrMismatch, + isAstUnstable, + isUnstable, +} from "./failed-format-tests.js"; const { __dirname } = createEsmUtils(import.meta); @@ -21,32 +26,6 @@ const CURSOR_PLACEHOLDER = "<|>"; const RANGE_START_PLACEHOLDER = "<<>>"; const RANGE_END_PLACEHOLDER = "<<>>"; -// Here we add files that will not be the same when formatting a second time. -const unstableTests = new Map( - [].map((fixture) => { - const [file, isUnstable = () => true] = Array.isArray(fixture) - ? fixture - : [fixture]; - return [path.join(__dirname, "../format/", file), isUnstable]; - }), -); - -// Here we add files that will not have the same AST after being formatted. -const unstableAstTests = new Map( - [ - // `: =` and `= :` are syntactically the same as `:=` and `=:`, but the ast - // changes from `YulColonAndEqual` and `YulEqualAndColon` to `ColonEqual` - // and `EqualColon`, which is expected but the workaround to keep the test - // stable is too much, so we just put it in this list. - "AssemblyV0.4.26/Assembly.sol", - ].map((fixture) => { - const [file, isAstUnstable = () => true] = Array.isArray(fixture) - ? fixture - : [fixture]; - return [path.join(__dirname, "../format/", file), isAstUnstable]; - }), -); - const testsWithAstChanges = new Map( [ "Parentheses/AddNoParentheses.sol", @@ -71,60 +50,6 @@ const testsWithAstChanges = new Map( }), ); -const antlrMismatchTests = new Map( - [ - // Better placement of comments in Slang. - "BasicIterator/BasicIterator.sol", - "Comments/Comments.sol", - "IndexOf/IndexOf.sol", - // Syntax for `pragma solidity 0.5.0 - 0.6.0;` not supported by ANTLR - "Pragma/Pragma.sol", - // ANTLR doesn't support assembly assignment operators separated by a space - // like `: =` or `= :` - "AssemblyV0.4.26/Assembly.sol", - // ANTLR doesn't support UntypedTupleMember with a storage location, which - // is valid Slang, but not in Solidity. - "AllSolidityFeaturesV0.4.26/AllSolidityFeatures.sol", - // TODO Review how ANTLR is formatting chained assignments - "Assignments/Assignments.sol", - ].map((fixture) => { - const [file, compareBytecode = () => true] = Array.isArray(fixture) - ? fixture - : [fixture]; - return [path.join(__dirname, "../format/", file), compareBytecode]; - }), -); - -const isUnstable = (filename, options) => { - const testFunction = unstableTests.get(filename); - - if (!testFunction) { - return false; - } - - return testFunction(options); -}; - -const isAstUnstable = (filename, options) => { - const testFunction = unstableAstTests.get(filename); - - if (!testFunction) { - return false; - } - - return testFunction(options); -}; - -const isAntlrMismatch = (filename, options) => { - const testFunction = antlrMismatchTests.get(filename); - - if (!testFunction) { - return false; - } - - return testFunction(options); -}; - const shouldCompareBytecode = (filename, options) => { const testFunction = testsWithAstChanges.get(filename); diff --git a/tests/config/utilities.js b/tests/config/utilities.js new file mode 100644 index 000000000..bed70134e --- /dev/null +++ b/tests/config/utilities.js @@ -0,0 +1,5 @@ +import path from "node:path"; + +const normalizeDirectory = (directory) => path.normalize(directory + path.sep); + +export { normalizeDirectory }; diff --git a/tests/config/utils/create-snapshot.js b/tests/config/utils/create-snapshot.js index aa91625b7..510a30846 100644 --- a/tests/config/utils/create-snapshot.js +++ b/tests/config/utils/create-snapshot.js @@ -1,9 +1,8 @@ import { wrap as raw } from "jest-snapshot-serializer-raw"; +import { CURSOR_PLACEHOLDER } from "../constants.js"; import visualizeEndOfLine from "./visualize-end-of-line.js"; import visualizeRange from "./visualize-range.js"; -const CURSOR_PLACEHOLDER = "<|>"; - const DEFAULT_PRINT_WIDTH = 80; const SEPARATOR_WIDTH = DEFAULT_PRINT_WIDTH; function printSeparator(description = "") {