11import fs from "node:fs" ;
22import path from "node:path" ;
33import url from "node:url" ;
4-
54import createEsmUtils from "esm-utils" ;
6-
75import getPrettier from "./get-prettier.js" ;
86import getPlugins from "./get-plugins.js" ;
97import compileContract from "./utils/compile-contract.js" ;
108import consistentEndOfLine from "./utils/consistent-end-of-line.js" ;
119import createSnapshot from "./utils/create-snapshot.js" ;
1210import stringifyOptionsForTitle from "./utils/stringify-options-for-title.js" ;
1311import visualizeEndOfLine from "./utils/visualize-end-of-line.js" ;
12+ import { createParser } from "../../src/slang-utils/create-parser.js" ;
1413
1514const { __dirname } = createEsmUtils ( import . meta) ;
1615
@@ -65,6 +64,22 @@ const testsWithAstChanges = new Map(
6564 } ) ,
6665) ;
6766
67+ const unstableAntlrTests = new Map (
68+ [
69+ // Better placement of comments in Slang.
70+ "BasicIterator/BasicIterator.sol" ,
71+ "Comments/Comments.sol" ,
72+ "IndexOf/IndexOf.sol" ,
73+ // Syntax for `pragma solidity 0.5.0 - 0.6.0;` not supported by ANTLR
74+ "Pragma/Pragma.sol" ,
75+ ] . map ( ( fixture ) => {
76+ const [ file , compareBytecode = ( ) => true ] = Array . isArray ( fixture )
77+ ? fixture
78+ : [ fixture ] ;
79+ return [ path . join ( __dirname , "../format/" , file ) , compareBytecode ] ;
80+ } ) ,
81+ ) ;
82+
6883const isUnstable = ( filename , options ) => {
6984 const testFunction = unstableTests . get ( filename ) ;
7085
@@ -85,6 +100,16 @@ const isAstUnstable = (filename, options) => {
85100 return testFunction ( options ) ;
86101} ;
87102
103+ const isAntlrUnstable = ( filename , options ) => {
104+ const testFunction = unstableAntlrTests . get ( filename ) ;
105+
106+ if ( ! testFunction ) {
107+ return false ;
108+ }
109+
110+ return testFunction ( options ) ;
111+ } ;
112+
88113const shouldCompareBytecode = ( filename , options ) => {
89114 const testFunction = testsWithAstChanges . get ( filename ) ;
90115
@@ -119,6 +144,12 @@ function runFormatTest(fixtures, parsers, options) {
119144 let { importMeta, snippets = [ ] } = fixtures . importMeta
120145 ? fixtures
121146 : { importMeta : fixtures } ;
147+
148+ const filename = path . basename ( new URL ( importMeta . url ) . pathname ) ;
149+ if ( filename !== "format.test.js" ) {
150+ throw new Error ( `Format test should run in file named 'format.test.js'.` ) ;
151+ }
152+
122153 const dirname = path . dirname ( url . fileURLToPath ( importMeta . url ) ) ;
123154
124155 // `IS_PARSER_INFERENCE_TESTS` mean to test `inferParser` on `standalone`
@@ -290,6 +321,25 @@ async function runTest({
290321 return ;
291322 }
292323
324+ if (
325+ formatOptions . parser === "slang-solidity" &&
326+ ! isAntlrUnstable ( filename , formatOptions )
327+ ) {
328+ // Compare with ANTLR's format
329+ const prettier = await getPrettier ( ) ;
330+ const { formatted : antlrOutput } = await prettier . formatWithCursor ( code , {
331+ ...formatOptions ,
332+ // Since Slang forces us to decide on a compiler version, we need to do the
333+ // same for ANTLR unless it was already given as an option.
334+ compiler :
335+ formatOptions . compiler ||
336+ createParser ( code , formatOptions ) [ 0 ] . languageVersion ,
337+ parser : "solidity-parse" ,
338+ plugins : await getPlugins ( ) ,
339+ } ) ;
340+ expect ( antlrOutput ) . toEqual ( formatResult . output ) ;
341+ }
342+
293343 const isUnstableTest = isUnstable ( filename , formatOptions ) ;
294344 if (
295345 ( formatResult . changed || isUnstableTest ) &&
0 commit comments