@@ -2,78 +2,13 @@ import fs from "node:fs";
22import path from "node:path" ;
33import url from "node:url" ;
44import createEsmUtils from "esm-utils" ;
5- import getPrettier from "./get-prettier.js" ;
6- import getCreateParser from "./get-create-parser.js" ;
7- import getVariantCoverage from "./get-variant-coverage.js" ;
8- import getPlugins from "./get-plugins.js" ;
9- import compileContract from "./utils/compile-contract.js" ;
10- import consistentEndOfLine from "./utils/consistent-end-of-line.js" ;
11- import createSnapshot from "./utils/create-snapshot.js" ;
125import { stringifyOptionsForTitle } from "./utils/stringify-options-for-title.js" ;
13- import visualizeEndOfLine from "./utils/visualize-end-of-line.js" ;
14- import {
15- isAntlrMismatch ,
16- isAstUnstable ,
17- isUnstable ,
18- } from "./failed-format-tests.js" ;
19- import { format , parse } from "./run-prettier.js" ;
6+ import { format } from "./run-prettier.js" ;
7+ import { runTest } from "./run-test.js" ;
8+ import { shouldThrowOnFormat } from "./utilities.js" ;
209
2110const { __dirname } = createEsmUtils ( import . meta) ;
2211
23- const { FULL_TEST } = process . env ;
24- const BOM = "\uFEFF" ;
25-
26- const CURSOR_PLACEHOLDER = "<|>" ;
27-
28- const testsWithAstChanges = new Map (
29- [
30- "Parentheses/AddNoParentheses.sol" ,
31- "Parentheses/SubNoParentheses.sol" ,
32- "Parentheses/MulNoParentheses.sol" ,
33- "Parentheses/DivNoParentheses.sol" ,
34- "Parentheses/ModNoParentheses.sol" ,
35- "Parentheses/ExpNoParentheses.sol" ,
36- "Parentheses/ShiftLNoParentheses.sol" ,
37- "Parentheses/ShiftRNoParentheses.sol" ,
38- "Parentheses/BitAndNoParentheses.sol" ,
39- "Parentheses/BitOrNoParentheses.sol" ,
40- "Parentheses/BitXorNoParentheses.sol" ,
41- "Parentheses/LogicNoParentheses.sol" ,
42- "HexLiteral/HexLiteral.sol" ,
43- "ModifierInvocations/ModifierInvocations.sol" ,
44- ] . map ( ( fixture ) => {
45- const [ file , compareBytecode = ( ) => true ] = Array . isArray ( fixture )
46- ? fixture
47- : [ fixture ] ;
48- return [ path . join ( __dirname , "../format/" , file ) , compareBytecode ] ;
49- } ) ,
50- ) ;
51-
52- const shouldCompareBytecode = ( filename , options ) => {
53- const testFunction = testsWithAstChanges . get ( filename ) ;
54-
55- if ( ! testFunction ) {
56- return false ;
57- }
58-
59- return testFunction ( options ) ;
60- } ;
61-
62- const shouldThrowOnFormat = ( filename , options ) => {
63- const { errors = { } } = options ;
64- if ( errors === true ) {
65- return true ;
66- }
67-
68- const files = errors [ options . parser ] ;
69-
70- if ( files === true || ( Array . isArray ( files ) && files . includes ( filename ) ) ) {
71- return true ;
72- }
73-
74- return false ;
75- } ;
76-
7712const isTestDirectory = ( dirname , name ) =>
7813 ( dirname + path . sep ) . startsWith (
7914 path . join ( __dirname , "../format" , name ) + path . sep ,
@@ -203,170 +138,4 @@ function runFormatTest(fixtures, parsers, options) {
203138 }
204139}
205140
206- async function runTest ( {
207- parsers,
208- name,
209- filename,
210- code,
211- output,
212- parser,
213- mainParserFormatResult,
214- mainParserFormatOptions,
215- } ) {
216- let formatOptions = mainParserFormatOptions ;
217- let formatResult = mainParserFormatResult ;
218-
219- // Verify parsers or error tests
220- if (
221- mainParserFormatResult . error ||
222- mainParserFormatOptions . parser !== parser
223- ) {
224- formatOptions = { ...mainParserFormatResult . options , parser } ;
225- const runFormat = ( ) => format ( code , formatOptions ) ;
226-
227- if ( shouldThrowOnFormat ( name , formatOptions ) ) {
228- await expect ( runFormat ( ) ) . rejects . toThrowErrorMatchingSnapshot ( ) ;
229- return ;
230- }
231-
232- // Verify parsers format result should be the same as main parser
233- output = mainParserFormatResult . outputWithCursor ;
234- formatResult = await runFormat ( ) ;
235- }
236-
237- // Make sure output has consistent EOL
238- expect ( formatResult . eolVisualizedOutput ) . toEqual (
239- visualizeEndOfLine ( consistentEndOfLine ( formatResult . outputWithCursor ) ) ,
240- ) ;
241-
242- // The result is assert to equals to `output`
243- if ( typeof output === "string" ) {
244- expect ( formatResult . eolVisualizedOutput ) . toEqual (
245- visualizeEndOfLine ( output ) ,
246- ) ;
247- return ;
248- }
249-
250- // All parsers have the same result, only snapshot the result from main parser
251- expect (
252- createSnapshot ( formatResult , {
253- parsers,
254- formatOptions,
255- CURSOR_PLACEHOLDER ,
256- } ) ,
257- ) . toMatchSnapshot ( ) ;
258-
259- if ( ! FULL_TEST ) {
260- return ;
261- }
262-
263- if ( formatOptions . parser === "slang" ) {
264- const createParser = await getCreateParser ( ) ;
265- const variantCoverage = await getVariantCoverage ( ) ;
266- const { parser, parseOutput } = createParser ( code , formatOptions ) ;
267-
268- // Check coverage
269- variantCoverage ( parseOutput . tree . asNonterminalNode ( ) ) ;
270-
271- if ( ! isAntlrMismatch ( filename , formatOptions ) ) {
272- // Compare with ANTLR's format
273- const prettier = await getPrettier ( ) ;
274- const { formatted : antlrOutput } = await prettier . formatWithCursor ( code , {
275- ...formatOptions ,
276- // Since Slang forces us to decide on a compiler version, we need to do the
277- // same for ANTLR unless it was already given as an option.
278- compiler : formatOptions . compiler || parser . languageVersion ,
279- parser : "antlr" ,
280- plugins : await getPlugins ( ) ,
281- } ) ;
282- expect ( antlrOutput ) . toEqual ( formatResult . output ) ;
283- }
284- }
285-
286- const isUnstableTest = isUnstable ( filename , formatOptions ) ;
287- if (
288- ( formatResult . changed || isUnstableTest ) &&
289- // No range and cursor
290- formatResult . input === code
291- ) {
292- const { eolVisualizedOutput : firstOutput , output } = formatResult ;
293- const { eolVisualizedOutput : secondOutput } = await format (
294- output ,
295- formatOptions ,
296- ) ;
297- if ( isUnstableTest ) {
298- // To keep eye on failed tests, this assert never supposed to pass,
299- // if it fails, just remove the file from `unstableTests`
300- expect ( secondOutput ) . not . toEqual ( firstOutput ) ;
301- } else {
302- expect ( secondOutput ) . toEqual ( firstOutput ) ;
303- }
304- }
305-
306- const isAstUnstableTest = isAstUnstable ( filename , formatOptions ) ;
307- // Some parsers skip parsing empty files
308- if ( formatResult . changed && code . trim ( ) ) {
309- const { input, output } = formatResult ;
310- const originalAst = await parse ( input , formatOptions ) ;
311- const formattedAst = await parse ( output , formatOptions ) ;
312- if ( isAstUnstableTest ) {
313- expect ( formattedAst ) . not . toEqual ( originalAst ) ;
314- } else {
315- expect ( formattedAst ) . toEqual ( originalAst ) ;
316- }
317- }
318-
319- if ( ! shouldSkipEolTest ( code , formatResult . options ) ) {
320- for ( const eol of [ "\r\n" , "\r" ] ) {
321- const { eolVisualizedOutput : output } = await format (
322- code . replace ( / \n / gu, eol ) ,
323- formatOptions ,
324- ) ;
325- // Only if `endOfLine: "auto"` the result will be different
326- const expected =
327- formatOptions . endOfLine === "auto"
328- ? visualizeEndOfLine (
329- // All `code` use `LF`, so the `eol` of result is always `LF`
330- formatResult . outputWithCursor . replace ( / \n / gu, eol ) ,
331- )
332- : formatResult . eolVisualizedOutput ;
333- expect ( output ) . toEqual ( expected ) ;
334- }
335- }
336-
337- if ( code . charAt ( 0 ) !== BOM ) {
338- const { eolVisualizedOutput : output } = await format (
339- BOM + code ,
340- formatOptions ,
341- ) ;
342- const expected = BOM + formatResult . eolVisualizedOutput ;
343- expect ( output ) . toEqual ( expected ) ;
344- }
345-
346- if ( shouldCompareBytecode ( filename , formatOptions ) ) {
347- const output = compileContract ( filename , formatResult . output ) ;
348- const expected = compileContract ( filename , formatResult . input ) ;
349- expect ( output ) . toEqual ( expected ) ;
350- }
351- }
352-
353- function shouldSkipEolTest ( code , options ) {
354- if ( code . includes ( "\r" ) ) {
355- return true ;
356- }
357- const { requirePragma, rangeStart, rangeEnd } = options ;
358- if ( requirePragma ) {
359- return true ;
360- }
361-
362- if (
363- typeof rangeStart === "number" &&
364- typeof rangeEnd === "number" &&
365- rangeStart >= rangeEnd
366- ) {
367- return true ;
368- }
369- return false ;
370- }
371-
372141export default runFormatTest ;
0 commit comments