diff --git a/common/test/src/test-helpers/cas11.ts b/common/test/src/test-helpers/cas11.ts index 73f4babd..279182b9 100644 --- a/common/test/src/test-helpers/cas11.ts +++ b/common/test/src/test-helpers/cas11.ts @@ -33,6 +33,12 @@ import { inspect } from 'util'; const { CommandExpression } = NodeType; const { Between, Equal, Greater } = ComparisonType; +export type ForEachCase = { + message?: string; + value: V; + expected?: E; + title: string; +}; export type Case = [string, any, string?]; export type InterpreterCase = [Node, any, string?]; @@ -40,10 +46,10 @@ export type InterpreterCase = [Node, any, string?]; export const deepConsoleLog = (thing: any): void => console.log(inspect(thing, false, null, true)); -export const runParser = ( +export function runParser( parser: Parser, value: string, -): any => { +): any { const res = withData(parser)( createParserState(), ).run(value); @@ -53,7 +59,18 @@ export const runParser = ( } return res.result; -}; +} + +export function runParserError(parser: NodeParser, text: string): string { + const parserState = createParserState(); + const res = withData(parser)(parserState).run( + text, + ); + + expect(res.isError, 'error not thrown').to.be.true; + + return (res as Err).error; +} export const runCases = ( caseOrCases: Case | Case[], diff --git a/core/evmcrispr/src/parsers/array.ts b/core/evmcrispr/src/parsers/array.ts index a4fe5645..565f3063 100644 --- a/core/evmcrispr/src/parsers/array.ts +++ b/core/evmcrispr/src/parsers/array.ts @@ -14,7 +14,7 @@ import { openingCharParser, } from './utils'; -export const ARRAY_PARSER_ERROR = 'ArrayParserError'; +const ARRAY_PARSER_ERROR = 'ArrayParserError'; export const arrayExpressionParser: NodeParser = recursiveParser(() => diff --git a/core/evmcrispr/src/parsers/command.ts b/core/evmcrispr/src/parsers/command.ts index 8e5a61cd..d8b4fc96 100644 --- a/core/evmcrispr/src/parsers/command.ts +++ b/core/evmcrispr/src/parsers/command.ts @@ -138,7 +138,7 @@ const commandArgsParser = coroutine(function* () { return commandArgOrOpt; }); -export const COMMAND_PARSER_ERROR = 'CommandParserError'; +const COMMAND_PARSER_ERROR = 'CommandParserError'; export const endOfCommandParser = choice([endLine, lookAhead(endOfInput)]); diff --git a/core/evmcrispr/src/parsers/helper.ts b/core/evmcrispr/src/parsers/helper.ts index 778bb705..8237c4a8 100644 --- a/core/evmcrispr/src/parsers/helper.ts +++ b/core/evmcrispr/src/parsers/helper.ts @@ -25,7 +25,7 @@ import { openingCharParser, } from './utils'; -export const HELPER_PARSER_ERROR = 'HelperParserError'; +const HELPER_PARSER_ERROR = 'HelperParserError'; const helperNameParser = recursiveParser(() => takeLeft(regex(/^(?!-|\.)[a-zA-Z\-.]+(? = ( enclosingParsers = [], diff --git a/core/evmcrispr/src/parsers/primaries/literals/boolean.ts b/core/evmcrispr/src/parsers/primaries/literals/boolean.ts index 65384693..22f7b404 100644 --- a/core/evmcrispr/src/parsers/primaries/literals/boolean.ts +++ b/core/evmcrispr/src/parsers/primaries/literals/boolean.ts @@ -9,7 +9,7 @@ import { locate, } from '../../utils'; -export const BOOLEAN_PARSER_ERROR = 'BooleanParserError'; +const BOOLEAN_PARSER_ERROR = 'BooleanParserError'; export const booleanParser: EnclosingNodeParser = ( enclosingParsers = [], diff --git a/core/evmcrispr/src/parsers/primaries/literals/hexadecimal.ts b/core/evmcrispr/src/parsers/primaries/literals/hexadecimal.ts index 65a05e48..ad0ef2c2 100644 --- a/core/evmcrispr/src/parsers/primaries/literals/hexadecimal.ts +++ b/core/evmcrispr/src/parsers/primaries/literals/hexadecimal.ts @@ -9,7 +9,7 @@ import { locate, } from '../../utils'; -export const HEXADECIMAL_PARSER_ERROR = 'HexadecimalParserError'; +const HEXADECIMAL_PARSER_ERROR = 'HexadecimalParserError'; export const hexadecimalParser: EnclosingNodeParser = ( enclosingParsers = [], diff --git a/core/evmcrispr/src/parsers/primaries/literals/string.ts b/core/evmcrispr/src/parsers/primaries/literals/string.ts index 132e95c6..834af58e 100644 --- a/core/evmcrispr/src/parsers/primaries/literals/string.ts +++ b/core/evmcrispr/src/parsers/primaries/literals/string.ts @@ -9,7 +9,7 @@ import { locate, } from '../../utils'; -export const STRING_PARSER_ERROR = 'StringParserError'; +const STRING_PARSER_ERROR = 'StringParserError'; export const stringParser: EnclosingNodeParser = ( enclosingParsers = [], diff --git a/core/evmcrispr/test/cas11ast.test.ts b/core/evmcrispr/test/cas11ast.test.ts deleted file mode 100644 index 2a17445a..00000000 --- a/core/evmcrispr/test/cas11ast.test.ts +++ /dev/null @@ -1,824 +0,0 @@ -import { DAO, DAO2, DAO3 } from '@1hive/evmcrispr-test-common'; - -import type { Cas11AST } from '../src/Cas11AST'; -import { parseScript } from '../src/parsers/script'; - -describe('Cas11AST', () => { - const script = ` - load aragonos as ar - load giveth as giv - - ar:connect ${DAO.kernel} ( - set $dao1Variable agent - connect ${DAO2.kernel} ( - set $dao2Variable vault - install vault:new - ) - ) - - ar:connect ${DAO3} ( - revoke voting token-manager MINT_ROLE - ) - - set $globalScopeVariable "test" - `; - let ast: Cas11AST; - - beforeEach(() => { - ast = parseScript(script).ast; - }); - - describe('when fetching a command at a specific line', () => { - it('should fetch it correctly', () => { - expect(ast.getCommandAtLine(9)).to.eql({ - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'vault:new', - loc: { start: { line: 9, col: 16 }, end: { line: 9, col: 25 } }, - }, - ], - opts: [], - loc: { start: { line: 9, col: 8 }, end: { line: 9, col: 25 } }, - }); - }); - - it('should return nothing when given a line higher than the maximum script line', () => { - expect(ast.getCommandAtLine(30)).to.be.undefined; - }); - - it('should return nothing when given an empty line', () => { - expect(ast.getCommandAtLine(4)).to.be.undefined; - }); - - it('should return nothing when given a line without a command', () => { - expect(ast.getCommandAtLine(10)).to.be.undefined; - }); - }); - - describe('when fetching commands until a specific line', () => { - it('should fetch them correctly', () => { - expect(ast.getCommandsUntilLine(12)).to.eql([ - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'aragonos', - loc: { start: { line: 2, col: 9 }, end: { line: 2, col: 17 } }, - }, - right: { - type: 'ProbableIdentifier', - value: 'ar', - loc: { start: { line: 2, col: 21 }, end: { line: 2, col: 23 } }, - }, - loc: { start: { line: 2, col: 9 }, end: { line: 2, col: 23 } }, - }, - ], - opts: [], - loc: { start: { line: 2, col: 4 }, end: { line: 2, col: 23 } }, - }, - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'giveth', - loc: { start: { line: 3, col: 9 }, end: { line: 3, col: 15 } }, - }, - right: { - type: 'ProbableIdentifier', - value: 'giv', - loc: { start: { line: 3, col: 19 }, end: { line: 3, col: 22 } }, - }, - loc: { start: { line: 3, col: 9 }, end: { line: 3, col: 22 } }, - }, - ], - opts: [], - loc: { start: { line: 3, col: 4 }, end: { line: 3, col: 22 } }, - }, - { - type: 'CommandExpression', - module: 'ar', - name: 'connect', - args: [ - { - type: 'AddressLiteral', - value: '0x1fc7e8d8e4bbbef77a4d035aec189373b52125a8', - loc: { start: { line: 5, col: 15 }, end: { line: 5, col: 57 } }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao1Variable', - loc: { - start: { line: 6, col: 10 }, - end: { line: 6, col: 23 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { - start: { line: 6, col: 24 }, - end: { line: 6, col: 29 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 6, col: 6 }, - end: { line: 6, col: 29 }, - }, - }, - { - type: 'CommandExpression', - name: 'connect', - args: [ - { - type: 'AddressLiteral', - value: '0x8ccbeab14b5ac4a431fffc39f4bec4089020a155', - loc: { - start: { line: 7, col: 14 }, - end: { line: 7, col: 56 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao2Variable', - loc: { - start: { line: 8, col: 12 }, - end: { line: 8, col: 25 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'vault', - loc: { - start: { line: 8, col: 26 }, - end: { line: 8, col: 31 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 8, col: 8 }, - end: { line: 8, col: 31 }, - }, - }, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'vault:new', - loc: { - start: { line: 9, col: 16 }, - end: { line: 9, col: 25 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 9, col: 8 }, - end: { line: 9, col: 25 }, - }, - }, - ], - loc: { - start: { line: 7, col: 57 }, - end: { line: 10, col: 7 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 7, col: 6 }, - end: { line: 10, col: 7 }, - }, - }, - ], - loc: { start: { line: 5, col: 58 }, end: { line: 11, col: 5 } }, - }, - ], - opts: [], - loc: { start: { line: 5, col: 4 }, end: { line: 11, col: 5 } }, - }, - ]); - }); - describe('when given a set of global scope command names', () => { - it('should fetch them correctly', () => { - expect(ast.getCommandsUntilLine(9, ['load', 'set'])).to.eql([ - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'aragonos', - loc: { - start: { line: 2, col: 9 }, - end: { line: 2, col: 17 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'ar', - loc: { - start: { line: 2, col: 21 }, - end: { line: 2, col: 23 }, - }, - }, - loc: { start: { line: 2, col: 9 }, end: { line: 2, col: 23 } }, - }, - ], - opts: [], - loc: { start: { line: 2, col: 4 }, end: { line: 2, col: 23 } }, - }, - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'giveth', - loc: { - start: { line: 3, col: 9 }, - end: { line: 3, col: 15 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'giv', - loc: { - start: { line: 3, col: 19 }, - end: { line: 3, col: 22 }, - }, - }, - loc: { start: { line: 3, col: 9 }, end: { line: 3, col: 22 } }, - }, - ], - opts: [], - loc: { start: { line: 3, col: 4 }, end: { line: 3, col: 22 } }, - }, - { - type: 'CommandExpression', - module: 'ar', - name: 'connect', - args: [ - { - type: 'AddressLiteral', - value: '0x1fc7e8d8e4bbbef77a4d035aec189373b52125a8', - loc: { start: { line: 5, col: 15 }, end: { line: 5, col: 57 } }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao1Variable', - loc: { - start: { line: 6, col: 10 }, - end: { line: 6, col: 23 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { - start: { line: 6, col: 24 }, - end: { line: 6, col: 29 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 6, col: 6 }, - end: { line: 6, col: 29 }, - }, - }, - { - type: 'CommandExpression', - name: 'connect', - args: [ - { - type: 'AddressLiteral', - value: '0x8ccbeab14b5ac4a431fffc39f4bec4089020a155', - loc: { - start: { line: 7, col: 14 }, - end: { line: 7, col: 56 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao2Variable', - loc: { - start: { line: 8, col: 12 }, - end: { line: 8, col: 25 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'vault', - loc: { - start: { line: 8, col: 26 }, - end: { line: 8, col: 31 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 8, col: 8 }, - end: { line: 8, col: 31 }, - }, - }, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'vault:new', - loc: { - start: { line: 9, col: 16 }, - end: { line: 9, col: 25 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 9, col: 8 }, - end: { line: 9, col: 25 }, - }, - }, - ], - loc: { - start: { line: 7, col: 57 }, - end: { line: 10, col: 7 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 7, col: 6 }, - end: { line: 10, col: 7 }, - }, - }, - ], - loc: { start: { line: 5, col: 58 }, end: { line: 11, col: 5 } }, - }, - ], - opts: [], - loc: { start: { line: 5, col: 4 }, end: { line: 11, col: 5 } }, - }, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao1Variable', - loc: { start: { line: 6, col: 10 }, end: { line: 6, col: 23 } }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { start: { line: 6, col: 24 }, end: { line: 6, col: 29 } }, - }, - ], - opts: [], - loc: { start: { line: 6, col: 6 }, end: { line: 6, col: 29 } }, - }, - { - type: 'CommandExpression', - name: 'connect', - args: [ - { - type: 'AddressLiteral', - value: '0x8ccbeab14b5ac4a431fffc39f4bec4089020a155', - loc: { start: { line: 7, col: 14 }, end: { line: 7, col: 56 } }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao2Variable', - loc: { - start: { line: 8, col: 12 }, - end: { line: 8, col: 25 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'vault', - loc: { - start: { line: 8, col: 26 }, - end: { line: 8, col: 31 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 8, col: 8 }, - end: { line: 8, col: 31 }, - }, - }, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'vault:new', - loc: { - start: { line: 9, col: 16 }, - end: { line: 9, col: 25 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 9, col: 8 }, - end: { line: 9, col: 25 }, - }, - }, - ], - loc: { start: { line: 7, col: 57 }, end: { line: 10, col: 7 } }, - }, - ], - opts: [], - loc: { start: { line: 7, col: 6 }, end: { line: 10, col: 7 } }, - }, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao2Variable', - loc: { start: { line: 8, col: 12 }, end: { line: 8, col: 25 } }, - }, - { - type: 'ProbableIdentifier', - value: 'vault', - loc: { start: { line: 8, col: 26 }, end: { line: 8, col: 31 } }, - }, - ], - opts: [], - loc: { start: { line: 8, col: 8 }, end: { line: 8, col: 31 } }, - }, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'vault:new', - loc: { start: { line: 9, col: 16 }, end: { line: 9, col: 25 } }, - }, - ], - opts: [], - loc: { start: { line: 9, col: 8 }, end: { line: 9, col: 25 } }, - }, - ]); - }); - - it('should fetch them correctly when giving a line higher than the maximum script line', () => { - expect(ast.getCommandsUntilLine(200, ['load', 'set'])).to.eql([ - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'aragonos', - loc: { - start: { line: 2, col: 9 }, - end: { line: 2, col: 17 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'ar', - loc: { - start: { line: 2, col: 21 }, - end: { line: 2, col: 23 }, - }, - }, - loc: { start: { line: 2, col: 9 }, end: { line: 2, col: 23 } }, - }, - ], - opts: [], - loc: { start: { line: 2, col: 4 }, end: { line: 2, col: 23 } }, - }, - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'giveth', - loc: { - start: { line: 3, col: 9 }, - end: { line: 3, col: 15 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'giv', - loc: { - start: { line: 3, col: 19 }, - end: { line: 3, col: 22 }, - }, - }, - loc: { start: { line: 3, col: 9 }, end: { line: 3, col: 22 } }, - }, - ], - opts: [], - loc: { start: { line: 3, col: 4 }, end: { line: 3, col: 22 } }, - }, - { - type: 'CommandExpression', - module: 'ar', - name: 'connect', - args: [ - { - type: 'AddressLiteral', - value: '0x1fc7e8d8e4bbbef77a4d035aec189373b52125a8', - loc: { start: { line: 5, col: 15 }, end: { line: 5, col: 57 } }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao1Variable', - loc: { - start: { line: 6, col: 10 }, - end: { line: 6, col: 23 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { - start: { line: 6, col: 24 }, - end: { line: 6, col: 29 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 6, col: 6 }, - end: { line: 6, col: 29 }, - }, - }, - { - type: 'CommandExpression', - name: 'connect', - args: [ - { - type: 'AddressLiteral', - value: '0x8ccbeab14b5ac4a431fffc39f4bec4089020a155', - loc: { - start: { line: 7, col: 14 }, - end: { line: 7, col: 56 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao2Variable', - loc: { - start: { line: 8, col: 12 }, - end: { line: 8, col: 25 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'vault', - loc: { - start: { line: 8, col: 26 }, - end: { line: 8, col: 31 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 8, col: 8 }, - end: { line: 8, col: 31 }, - }, - }, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'vault:new', - loc: { - start: { line: 9, col: 16 }, - end: { line: 9, col: 25 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 9, col: 8 }, - end: { line: 9, col: 25 }, - }, - }, - ], - loc: { - start: { line: 7, col: 57 }, - end: { line: 10, col: 7 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 7, col: 6 }, - end: { line: 10, col: 7 }, - }, - }, - ], - loc: { start: { line: 5, col: 58 }, end: { line: 11, col: 5 } }, - }, - ], - opts: [], - loc: { start: { line: 5, col: 4 }, end: { line: 11, col: 5 } }, - }, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao1Variable', - loc: { start: { line: 6, col: 10 }, end: { line: 6, col: 23 } }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { start: { line: 6, col: 24 }, end: { line: 6, col: 29 } }, - }, - ], - opts: [], - loc: { start: { line: 6, col: 6 }, end: { line: 6, col: 29 } }, - }, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$dao2Variable', - loc: { start: { line: 8, col: 12 }, end: { line: 8, col: 25 } }, - }, - { - type: 'ProbableIdentifier', - value: 'vault', - loc: { start: { line: 8, col: 26 }, end: { line: 8, col: 31 } }, - }, - ], - opts: [], - loc: { start: { line: 8, col: 8 }, end: { line: 8, col: 31 } }, - }, - { - type: 'CommandExpression', - module: 'ar', - name: 'connect', - args: [ - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'revoke', - args: [ - { - type: 'ProbableIdentifier', - value: 'voting', - loc: { - start: { line: 14, col: 13 }, - end: { line: 14, col: 19 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'token-manager', - loc: { - start: { line: 14, col: 20 }, - end: { line: 14, col: 33 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'MINT_ROLE', - loc: { - start: { line: 14, col: 34 }, - end: { line: 14, col: 43 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 14, col: 6 }, - end: { line: 14, col: 43 }, - }, - }, - ], - loc: { - start: { line: 13, col: 31 }, - end: { line: 15, col: 5 }, - }, - }, - ], - opts: [], - loc: { start: { line: 13, col: 4 }, end: { line: 15, col: 5 } }, - }, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$globalScopeVariable', - loc: { - start: { line: 17, col: 8 }, - end: { line: 17, col: 28 }, - }, - }, - { - type: 'StringLiteral', - value: 'test', - loc: { - start: { line: 17, col: 29 }, - end: { line: 17, col: 35 }, - }, - }, - ], - opts: [], - loc: { start: { line: 17, col: 4 }, end: { line: 17, col: 35 } }, - }, - ]); - }); - }); - }); -}); diff --git a/core/evmcrispr/test/cas11ast/__snapshots__/cas11ast.test.ts.snap b/core/evmcrispr/test/cas11ast/__snapshots__/cas11ast.test.ts.snap new file mode 100644 index 00000000..b7c46209 --- /dev/null +++ b/core/evmcrispr/test/cas11ast/__snapshots__/cas11ast.test.ts.snap @@ -0,0 +1,1510 @@ +// Vitest Snapshot v1 + +exports[`Cas11AST > when fetching a command at a specific line > should fetch it correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 16, + "line": 9, + }, + }, + "type": "ProbableIdentifier", + "value": "vault:new", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 8, + "line": 9, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Cas11AST > when fetching commands until a specific line > should fetch them correctly 1`] = ` +[ + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 17, + "line": 2, + }, + "start": { + "col": 9, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "aragonos", + }, + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 9, + "line": 2, + }, + }, + "right": { + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 21, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "ar", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 4, + "line": 2, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 15, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "giveth", + }, + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "right": { + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 19, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "giv", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 4, + "line": 3, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 57, + "line": 5, + }, + "start": { + "col": 15, + "line": 5, + }, + }, + "type": "AddressLiteral", + "value": "0x1fc7e8d8e4bbbef77a4d035aec189373b52125a8", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 23, + "line": 6, + }, + "start": { + "col": 10, + "line": 6, + }, + }, + "type": "VariableIdentifier", + "value": "$dao1Variable", + }, + { + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 24, + "line": 6, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + ], + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 6, + "line": 6, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 56, + "line": 7, + }, + "start": { + "col": 14, + "line": 7, + }, + }, + "type": "AddressLiteral", + "value": "0x8ccbeab14b5ac4a431fffc39f4bec4089020a155", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 8, + }, + "start": { + "col": 12, + "line": 8, + }, + }, + "type": "VariableIdentifier", + "value": "$dao2Variable", + }, + { + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 26, + "line": 8, + }, + }, + "type": "ProbableIdentifier", + "value": "vault", + }, + ], + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 8, + "line": 8, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 16, + "line": 9, + }, + }, + "type": "ProbableIdentifier", + "value": "vault:new", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 8, + "line": 9, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 57, + "line": 7, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 6, + "line": 7, + }, + }, + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 11, + }, + "start": { + "col": 58, + "line": 5, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 11, + }, + "start": { + "col": 4, + "line": 5, + }, + }, + "module": "ar", + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, +] +`; + +exports[`Cas11AST > when fetching commands until a specific line > when given a set of global scope command names > should fetch them correctly 1`] = ` +[ + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 17, + "line": 2, + }, + "start": { + "col": 9, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "aragonos", + }, + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 9, + "line": 2, + }, + }, + "right": { + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 21, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "ar", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 4, + "line": 2, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 15, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "giveth", + }, + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "right": { + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 19, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "giv", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 4, + "line": 3, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 57, + "line": 5, + }, + "start": { + "col": 15, + "line": 5, + }, + }, + "type": "AddressLiteral", + "value": "0x1fc7e8d8e4bbbef77a4d035aec189373b52125a8", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 23, + "line": 6, + }, + "start": { + "col": 10, + "line": 6, + }, + }, + "type": "VariableIdentifier", + "value": "$dao1Variable", + }, + { + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 24, + "line": 6, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + ], + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 6, + "line": 6, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 56, + "line": 7, + }, + "start": { + "col": 14, + "line": 7, + }, + }, + "type": "AddressLiteral", + "value": "0x8ccbeab14b5ac4a431fffc39f4bec4089020a155", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 8, + }, + "start": { + "col": 12, + "line": 8, + }, + }, + "type": "VariableIdentifier", + "value": "$dao2Variable", + }, + { + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 26, + "line": 8, + }, + }, + "type": "ProbableIdentifier", + "value": "vault", + }, + ], + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 8, + "line": 8, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 16, + "line": 9, + }, + }, + "type": "ProbableIdentifier", + "value": "vault:new", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 8, + "line": 9, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 57, + "line": 7, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 6, + "line": 7, + }, + }, + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 11, + }, + "start": { + "col": 58, + "line": 5, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 11, + }, + "start": { + "col": 4, + "line": 5, + }, + }, + "module": "ar", + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 23, + "line": 6, + }, + "start": { + "col": 10, + "line": 6, + }, + }, + "type": "VariableIdentifier", + "value": "$dao1Variable", + }, + { + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 24, + "line": 6, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + ], + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 6, + "line": 6, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 56, + "line": 7, + }, + "start": { + "col": 14, + "line": 7, + }, + }, + "type": "AddressLiteral", + "value": "0x8ccbeab14b5ac4a431fffc39f4bec4089020a155", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 8, + }, + "start": { + "col": 12, + "line": 8, + }, + }, + "type": "VariableIdentifier", + "value": "$dao2Variable", + }, + { + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 26, + "line": 8, + }, + }, + "type": "ProbableIdentifier", + "value": "vault", + }, + ], + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 8, + "line": 8, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 16, + "line": 9, + }, + }, + "type": "ProbableIdentifier", + "value": "vault:new", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 8, + "line": 9, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 57, + "line": 7, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 6, + "line": 7, + }, + }, + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 8, + }, + "start": { + "col": 12, + "line": 8, + }, + }, + "type": "VariableIdentifier", + "value": "$dao2Variable", + }, + { + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 26, + "line": 8, + }, + }, + "type": "ProbableIdentifier", + "value": "vault", + }, + ], + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 8, + "line": 8, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 16, + "line": 9, + }, + }, + "type": "ProbableIdentifier", + "value": "vault:new", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 8, + "line": 9, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", + }, +] +`; + +exports[`Cas11AST > when fetching commands until a specific line > when given a set of global scope command names > should fetch them correctly when giving a line higher than the maximum script line 1`] = ` +[ + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 17, + "line": 2, + }, + "start": { + "col": 9, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "aragonos", + }, + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 9, + "line": 2, + }, + }, + "right": { + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 21, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "ar", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 23, + "line": 2, + }, + "start": { + "col": 4, + "line": 2, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 15, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "giveth", + }, + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "right": { + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 19, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "giv", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 22, + "line": 3, + }, + "start": { + "col": 4, + "line": 3, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 57, + "line": 5, + }, + "start": { + "col": 15, + "line": 5, + }, + }, + "type": "AddressLiteral", + "value": "0x1fc7e8d8e4bbbef77a4d035aec189373b52125a8", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 23, + "line": 6, + }, + "start": { + "col": 10, + "line": 6, + }, + }, + "type": "VariableIdentifier", + "value": "$dao1Variable", + }, + { + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 24, + "line": 6, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + ], + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 6, + "line": 6, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 56, + "line": 7, + }, + "start": { + "col": 14, + "line": 7, + }, + }, + "type": "AddressLiteral", + "value": "0x8ccbeab14b5ac4a431fffc39f4bec4089020a155", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 8, + }, + "start": { + "col": 12, + "line": 8, + }, + }, + "type": "VariableIdentifier", + "value": "$dao2Variable", + }, + { + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 26, + "line": 8, + }, + }, + "type": "ProbableIdentifier", + "value": "vault", + }, + ], + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 8, + "line": 8, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 16, + "line": 9, + }, + }, + "type": "ProbableIdentifier", + "value": "vault:new", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 9, + }, + "start": { + "col": 8, + "line": 9, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 57, + "line": 7, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 10, + }, + "start": { + "col": 6, + "line": 7, + }, + }, + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 11, + }, + "start": { + "col": 58, + "line": 5, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 11, + }, + "start": { + "col": 4, + "line": 5, + }, + }, + "module": "ar", + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 23, + "line": 6, + }, + "start": { + "col": 10, + "line": 6, + }, + }, + "type": "VariableIdentifier", + "value": "$dao1Variable", + }, + { + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 24, + "line": 6, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + ], + "loc": { + "end": { + "col": 29, + "line": 6, + }, + "start": { + "col": 6, + "line": 6, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 8, + }, + "start": { + "col": 12, + "line": 8, + }, + }, + "type": "VariableIdentifier", + "value": "$dao2Variable", + }, + { + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 26, + "line": 8, + }, + }, + "type": "ProbableIdentifier", + "value": "vault", + }, + ], + "loc": { + "end": { + "col": 31, + "line": 8, + }, + "start": { + "col": 8, + "line": 8, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 19, + "line": 14, + }, + "start": { + "col": 13, + "line": 14, + }, + }, + "type": "ProbableIdentifier", + "value": "voting", + }, + { + "loc": { + "end": { + "col": 33, + "line": 14, + }, + "start": { + "col": 20, + "line": 14, + }, + }, + "type": "ProbableIdentifier", + "value": "token-manager", + }, + { + "loc": { + "end": { + "col": 43, + "line": 14, + }, + "start": { + "col": 34, + "line": 14, + }, + }, + "type": "ProbableIdentifier", + "value": "MINT_ROLE", + }, + ], + "loc": { + "end": { + "col": 43, + "line": 14, + }, + "start": { + "col": 6, + "line": 14, + }, + }, + "name": "revoke", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 15, + }, + "start": { + "col": 31, + "line": 13, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 15, + }, + "start": { + "col": 4, + "line": 13, + }, + }, + "module": "ar", + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 28, + "line": 17, + }, + "start": { + "col": 8, + "line": 17, + }, + }, + "type": "VariableIdentifier", + "value": "$globalScopeVariable", + }, + { + "loc": { + "end": { + "col": 35, + "line": 17, + }, + "start": { + "col": 29, + "line": 17, + }, + }, + "type": "StringLiteral", + "value": "test", + }, + ], + "loc": { + "end": { + "col": 35, + "line": 17, + }, + "start": { + "col": 4, + "line": 17, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, +] +`; diff --git a/core/evmcrispr/test/cas11ast/cas11ast.test.ts b/core/evmcrispr/test/cas11ast/cas11ast.test.ts new file mode 100644 index 00000000..98265cd3 --- /dev/null +++ b/core/evmcrispr/test/cas11ast/cas11ast.test.ts @@ -0,0 +1,73 @@ +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; +import { DAO, DAO2, DAO3 } from '@1hive/evmcrispr-test-common'; + +import type { Cas11AST } from '../../src/Cas11AST'; +import { parseScript } from '../../src/parsers/script'; + +describe('Cas11AST', () => { + const script = ` + load aragonos as ar + load giveth as giv + + ar:connect ${DAO.kernel} ( + set $dao1Variable agent + connect ${DAO2.kernel} ( + set $dao2Variable vault + install vault:new + ) + ) + + ar:connect ${DAO3} ( + revoke voting token-manager MINT_ROLE + ) + + set $globalScopeVariable "test" + `; + let ast: Cas11AST; + + beforeEach(() => { + ast = parseScript(script).ast; + }); + + describe('when fetching a command at a specific line', () => { + it('should fetch it correctly', () => { + expect(ast.getCommandAtLine(9)).toMatchSnapshot(); + }); + + describe.concurrent.each>([ + { + title: 'a line higher than the maximum script line', + value: 30, + }, + { title: 'an empty line', value: 4 }, + { title: 'a line without a command', value: 10 }, + ])('', ({ title, value }) => { + it(`should return nothing when given ${title}`, () => { + expect(ast.getCommandAtLine(value)).to.be.undefined; + }); + }); + }); + + describe.concurrent('when fetching commands until a specific line', () => { + it('should fetch them correctly', () => { + expect(ast.getCommandsUntilLine(12)).toMatchSnapshot(); + }); + + describe.concurrent( + 'when given a set of global scope command names', + () => { + it('should fetch them correctly', () => { + expect( + ast.getCommandsUntilLine(9, ['load', 'set']), + ).toMatchSnapshot(); + }); + + it('should fetch them correctly when giving a line higher than the maximum script line', () => { + expect( + ast.getCommandsUntilLine(200, ['load', 'set']), + ).toMatchSnapshot(); + }); + }, + ); + }); +}); diff --git a/core/evmcrispr/test/interpreter/arithmetic.test.ts b/core/evmcrispr/test/interpreter/arithmetic.test.ts index cf8e327d..09514c1c 100644 --- a/core/evmcrispr/test/interpreter/arithmetic.test.ts +++ b/core/evmcrispr/test/interpreter/arithmetic.test.ts @@ -1,42 +1,40 @@ +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; import { createInterpreter, - expectThrowAsync, preparingExpression, } from '@1hive/evmcrispr-test-common'; import type { Signer } from 'ethers'; import { BigNumber } from 'ethers'; -import { ExpressionError } from '../../src/errors'; import { toDecimals } from '../../src/utils'; -describe('Interpreter - arithmetics', () => { - const name = 'ArithmeticExpressionError'; +describe.concurrent('Interpreter - arithmetics', () => { let signer: Signer; beforeAll(async (ctx) => { [signer] = await ctx.file!.utils.getWallets(); }); - it('should return the correct result of an arithmetic operation', async () => { - const [interpret] = await preparingExpression( - '(120 - 5e22 * 2 ^ 2 + 500e33)', - signer, - ); - const res = await interpret(); + describe.concurrent.each([ + { + title: '', + value: '(120 - 5e22 * 2 ^ 2 + 500e33)', + expected: BigNumber.from(120) + .sub(toDecimals(20, 22)) + .add(toDecimals(500, 33)), + }, + { + title: 'containing priority parentheses', + value: '((121e18 / 4) * (9 - 2) ^ 2 - 55e18)', + expected: toDecimals('1427.25', 18), + }, + ])('', ({ title, value, expected }) => { + it(`should return the correct result of an arithmetic operation ${title}`, async () => { + const [interpret] = await preparingExpression(value, signer); + const res = await interpret(); - expect(res).to.eql( - BigNumber.from(120).sub(toDecimals(20, 22)).add(toDecimals(500, 33)), - ); - }); - - it('should return the correct result of an arithmetic operation containing priority parenthesis', async () => { - const [interpret] = await preparingExpression( - '((121e18 / 4) * (9 - 2) ^ 2 - 55e18)', - signer, - ); - const res = await interpret(); - - expect(res).to.eql(toDecimals('1427.25', 18)); + expect(res).to.eql(expected!); + }); }); it('should fail when one of the operands is not a number', async () => { @@ -49,13 +47,6 @@ describe('Interpreter - arithmetics', () => { `, signer, ); - const leftOperandNode = leftOperandInterpreter.ast.body[1].args[1]; - const leftOperandErr = new ExpressionError( - leftOperandNode, - `invalid left operand. Expected a number but got "${invalidValue}"`, - { name }, - ); - const rightOperandInterpreter = createInterpreter( ` set $var1 "${invalidValue}" @@ -64,34 +55,26 @@ describe('Interpreter - arithmetics', () => { `, signer, ); - const rightOperandNode = rightOperandInterpreter.ast.body[1].args[1]; - const rightOperandErr = new ExpressionError( - rightOperandNode, - `invalid right operand. Expected a number but got "${invalidValue}"`, - { name }, - ); - await expectThrowAsync( - () => leftOperandInterpreter.interpret(), - leftOperandErr, - 'invalid left operand error', + await expect( + leftOperandInterpreter.interpret(), + ).rejects.toMatchInlineSnapshot( + '[ArithmeticExpressionError: ArithmeticExpressionError(4:14,4:-4): invalid left operand. Expected a number but got "a string"]', ); - await expectThrowAsync( - () => rightOperandInterpreter.interpret(), - rightOperandErr, - 'invalid right operand error', + await expect( + rightOperandInterpreter.interpret(), + ).rejects.toMatchInlineSnapshot( + '[ArithmeticExpressionError: ArithmeticExpressionError(4:14,4:-4): invalid right operand. Expected a number but got "a string"]', ); }); it('should fail when trying to perform a division by zero', async () => { - const [interpret, n] = await preparingExpression('(4 / 0)', signer); - const err = new ExpressionError( - n, - `invalid operation. Can't divide by zero`, - { name }, - ); + const [interpret] = await preparingExpression('(4 / 0)', signer); - await expectThrowAsync(() => interpret(), err); + // TODO: fix end column location which is smaller than start column location + await expect(interpret()).rejects.toMatchInlineSnapshot( + "[ArithmeticExpressionError: ArithmeticExpressionError(5:12,5:9): invalid operation. Can't divide by zero]", + ); }); }); diff --git a/core/evmcrispr/test/interpreter/primary.test.ts b/core/evmcrispr/test/interpreter/primary.test.ts index b8578f4b..8dc87f95 100644 --- a/core/evmcrispr/test/interpreter/primary.test.ts +++ b/core/evmcrispr/test/interpreter/primary.test.ts @@ -1,178 +1,197 @@ -import type { InterpreterCase } from '@1hive/evmcrispr-test-common'; -import { runInterpreterCases } from '@1hive/evmcrispr-test-common'; -import type { Signer } from 'ethers'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; +import type { BigNumber, Signer } from 'ethers'; import { constants } from 'ethers'; +import type { Node } from '../../src'; +import { Cas11AST, EVMcrispr } from '../../src'; + import type { NumericLiteralNode } from '../../src/types'; import { NodeType } from '../../src/types'; import { timeUnits, toDecimals } from '../../src/utils'; -describe('Interpreter - primaries', async () => { +function numericNode( + value: number, + power?: number, + timeUnit?: string, +): NumericLiteralNode { + const n: NumericLiteralNode = { + type: NodeType.NumberLiteral, + value: String(value), + }; + if (power) n.power = power; + if (timeUnit) n.timeUnit = timeUnit; + + return n; +} + +describe.concurrent('Interpreter - primaries', async () => { let signer: Signer; const getSigner = async () => signer; + async function expectPrimaryInterpretation( + primaryNode: Node, + expectedPrimaryValue: any, + ): Promise { + const interpretFn = new EVMcrispr( + new Cas11AST([]), + getSigner, + ).interpretNode(primaryNode); + + await expect(interpretFn).resolves.toStrictEqual(expectedPrimaryValue); + } + beforeAll(async (ctx) => { [signer] = await ctx.file!.utils.getWallets(); }); - describe('when interpreting a literal node', () => { + describe.concurrent('when interpreting a literal node', () => { it('should interpret address node correctly', async () => { - const c: InterpreterCase = [ + const primaryValue = '0x83E57888cd55C3ea1cfbf0114C963564d81e318d'; + await expectPrimaryInterpretation( { type: NodeType.AddressLiteral, - value: '0x83E57888cd55C3ea1cfbf0114C963564d81e318d', + value: primaryValue, }, - '0x83E57888cd55C3ea1cfbf0114C963564d81e318d', - ]; - - await runInterpreterCases(c, getSigner); + primaryValue, + ); }); - it('should interpret a boolean node correctly', async () => { - const cases: InterpreterCase[] = [ - [ - { - type: NodeType.BoolLiteral, - value: false, - }, - false, - ], - [{ type: NodeType.BoolLiteral, value: true }, true], - ]; - - await runInterpreterCases(cases, getSigner); + describe.each>([ + { + title: '"true"', + value: { type: NodeType.BoolLiteral, value: true }, + expected: true, + }, + { + title: '"false"', + value: { + type: NodeType.BoolLiteral, + value: false, + }, + expected: false, + }, + ])('when interpreting boolean nodes', ({ title, value, expected }) => { + it(`should interpret ${title} value correctly`, async () => { + await expectPrimaryInterpretation(value as Node, expected); + }); }); it('should intepret a bytes node correctly', async () => { - const cases: InterpreterCase[] = [ - [ - { - type: NodeType.BytesLiteral, - value: - '0x0e80f0b30000000000000000000000008e6cd950ad6ba651f6dd608dc70e5886b1aa6b240000000000000000000000002f00df4f995451e0df337b91744006eb8892bfb10000000000000000000000000000000000000000000000004563918244f40000', - }, - '0x0e80f0b30000000000000000000000008e6cd950ad6ba651f6dd608dc70e5886b1aa6b240000000000000000000000002f00df4f995451e0df337b91744006eb8892bfb10000000000000000000000000000000000000000000000004563918244f40000', - ], - ]; - - await runInterpreterCases(cases, getSigner); + const expectedPrimaryValue = + '0x0e80f0b30000000000000000000000008e6cd950ad6ba651f6dd608dc70e5886b1aa6b240000000000000000000000002f00df4f995451e0df337b91744006eb8892bfb10000000000000000000000000000000000000000000000004563918244f40000'; + await expectPrimaryInterpretation( + { + type: NodeType.BytesLiteral, + value: expectedPrimaryValue, + }, + expectedPrimaryValue, + ); }); - it('should intepret a numeric node correctly', async () => { - const node = ( - value: number, - power?: number, - timeUnit?: string, - ): NumericLiteralNode => { - const n: NumericLiteralNode = { - type: NodeType.NumberLiteral, - value: String(value), - }; - if (power) n.power = power; - if (timeUnit) n.timeUnit = timeUnit; - - return n; - }; - - const cases: InterpreterCase[] = [ - [node(15), toDecimals(15, 0), 'Invalid integer number match'], - [ - node(1500, 18), - toDecimals(1500, 18), - 'Invalid integer number raised to a power match', - ], - [ - node(7854.2345), - toDecimals(7854.2345, 0), - 'Invalid decimal number raised to a power match', - ], - [ - node(0.000123, 14), - toDecimals(0.000123, 14), - 'Invalid zero decimal number raised to a power match ', - ], - [ - node(1200.12, 18, 'mo'), - toDecimals(1200.12, 18).mul(timeUnits['mo']), - 'Invalid decimal number raised to a power followed by time unit match', - ], - [ - node(30, undefined, 's'), - toDecimals(30, 0).mul(timeUnits['s']), - 'Invalid number followed by second time unit match', - ], - [ - node(5, undefined, 'm'), - toDecimals(5, 0).mul(timeUnits['m']), - 'Invalid number followed by minute time unit match', - ], - [ - node(35, undefined, 'h'), - toDecimals(35, 0).mul(timeUnits['h']), - 'Invalid number followed by hour time unit match', - ], - [ - node(463, undefined, 'd'), - toDecimals(463, 0).mul(timeUnits['d']), - 'Invalid number followed by day time unit match', - ], - [ - node(96, undefined, 'w'), - toDecimals(96, 0).mul(timeUnits['w']), - 'Invalid number followed by week time unit match', - ], - [ - node(9, undefined, 'mo'), - toDecimals(9, 0).mul(timeUnits['mo']), - 'Invalid number followed by month time unit match', - ], - [ - node(4.67, undefined, 'y'), - toDecimals(4.67, 0).mul(timeUnits['y']), - 'Invalid number followed by year time unit match', - ], - ]; - - await runInterpreterCases(cases, getSigner); + describe.each>([ + { title: 'integer', value: numericNode(15), expected: toDecimals(15, 0) }, + { + title: 'integer raised to a power', + value: numericNode(1500, 18), + expected: toDecimals(1500, 18), + }, + { + title: 'decimal raised to power', + value: numericNode(7854.2345, 16), + expected: toDecimals(7854.2345, 16), + }, + { + title: 'zero decimal raised to a power', + value: numericNode(0.000123, 14), + expected: toDecimals(0.000123, 14), + }, + { + title: 'decimal raised to a power followed by time unit', + value: numericNode(1200.12, 18, 'mo'), + expected: toDecimals(1200.12, 18).mul(timeUnits['mo']), + }, + { + title: 'number followed by secondly time unit', + value: numericNode(30, undefined, 's'), + expected: toDecimals(30, 0).mul(timeUnits['s']), + }, + { + title: 'number followed by minutely time unit', + value: numericNode(5, undefined, 'm'), + expected: toDecimals(5, 0).mul(timeUnits['m']), + }, + { + title: 'number followed by hourly time unit', + value: numericNode(35, undefined, 'h'), + expected: toDecimals(35, 0).mul(timeUnits['h']), + }, + { + title: 'number followed by daily time unit', + value: numericNode(463, undefined, 'd'), + expected: toDecimals(463, 0).mul(timeUnits['d']), + }, + { + title: 'number followed by weekly time unit', + value: numericNode(96, undefined, 'w'), + expected: toDecimals(96, 0).mul(timeUnits['w']), + }, + { + title: 'number followed by monthly time unit', + value: numericNode(9, undefined, 'mo'), + expected: toDecimals(9, 0).mul(timeUnits['mo']), + }, + { + title: 'number followed by yearly time unit', + value: numericNode(4.67, undefined, 'y'), + expected: toDecimals(4.67, 0).mul(timeUnits['y']), + }, + ])('when interpreting numeric nodes', ({ title, value, expected }) => { + it(`should interpret a ${title} value correctly`, async () => { + await expectPrimaryInterpretation(value, expected); + }); }); it('should intepret a string node correctly', async () => { - const cases: InterpreterCase[] = [ - [ - { - type: NodeType.StringLiteral, - value: 'This is a string node', - }, - 'This is a string node', - ], - ]; - - await runInterpreterCases(cases, getSigner); + const expectedPrimaryValue = 'This is a string node'; + + await expectPrimaryInterpretation( + { + type: NodeType.StringLiteral, + value: expectedPrimaryValue, + }, + expectedPrimaryValue, + ); }); }); - describe('when intepreting an identifier node', () => { - it('should intepret a probable identifier correctly', async () => { - const cases: InterpreterCase[] = [ - [ - { - type: NodeType.ProbableIdentifier, - value: 'token-manager.open#3', - }, - 'token-manager.open#3', - ], - [ - { - type: NodeType.ProbableIdentifier, - value: 'ETH', - }, - constants.AddressZero, - ], - ]; - - await runInterpreterCases(cases, getSigner); - }); - it('should interpret a variable correctly'); - it('should fail when intepreting a non-existent variable'); + describe.concurrent.each>([ + { + title: '', + value: { + type: NodeType.ProbableIdentifier, + value: 'token-manager.open#3', + }, + expected: 'token-manager.open#3', + }, + { + title: 'default native token', + value: { + type: NodeType.ProbableIdentifier, + value: 'ETH', + }, + expected: constants.AddressZero, + }, + ])( + 'when interpreting a probable identifier node', + ({ title, value, expected }) => { + it(`should interpret a ${title} identifier correctly`, async () => { + await expectPrimaryInterpretation(value, expected); + }); + }, + ); + + describe.todo('when intepreting a variable node', () => { + it.todo('should interpret a variable correctly'); + it.todo('should fail when intepreting a non-existent variable'); }); }); diff --git a/core/evmcrispr/test/parsers/__snapshots__/arithmetic.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/arithmetic.test.ts.snap new file mode 100644 index 00000000..31edd7bc --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/arithmetic.test.ts.snap @@ -0,0 +1,834 @@ +// Vitest Snapshot v1 + +exports[`Parsers - arithmetic > should parse an arithmetic operation correctly 1`] = ` +{ + "left": { + "left": { + "loc": { + "end": { + "col": 2, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "9", + }, + "loc": { + "end": { + "col": 6, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "+", + "right": { + "loc": { + "end": { + "col": 6, + "line": 1, + }, + "start": { + "col": 5, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "5", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "-", + "right": { + "left": { + "left": { + "loc": { + "end": { + "col": 10, + "line": 1, + }, + "start": { + "col": 9, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "loc": { + "end": { + "col": 14, + "line": 1, + }, + "start": { + "col": 9, + "line": 1, + }, + }, + "operator": "*", + "right": { + "loc": { + "end": { + "col": 14, + "line": 1, + }, + "start": { + "col": 13, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 9, + "line": 1, + }, + }, + "operator": "/", + "right": { + "left": { + "loc": { + "end": { + "col": 18, + "line": 1, + }, + "start": { + "col": 17, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 17, + "line": 1, + }, + }, + "operator": "^", + "right": { + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 21, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "2", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", +} +`; + +exports[`Parsers - arithmetic > should parse an arithmetic operation containing helper functions and call expressions correctly 1`] = ` +{ + "left": { + "left": { + "loc": { + "end": { + "col": 9, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "90.45", + }, + "loc": { + "end": { + "col": 82, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "+", + "right": { + "left": { + "left": { + "loc": { + "end": { + "col": 20, + "line": 1, + }, + "start": { + "col": 13, + "line": 1, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "5000", + }, + "loc": { + "end": { + "col": 48, + "line": 1, + }, + "start": { + "col": 13, + "line": 1, + }, + }, + "operator": "-", + "right": { + "args": [ + { + "loc": { + "end": { + "col": 42, + "line": 1, + }, + "start": { + "col": 39, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "DAI", + }, + { + "args": [], + "loc": { + "end": { + "col": 47, + "line": 1, + }, + "start": { + "col": 44, + "line": 1, + }, + }, + "name": "me", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 48, + "line": 1, + }, + "start": { + "col": 23, + "line": 1, + }, + }, + "name": "token.balance", + "type": "HelperFunctionExpression", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 82, + "line": 1, + }, + "start": { + "col": 12, + "line": 1, + }, + }, + "operator": "*", + "right": { + "left": { + "args": [], + "loc": { + "end": { + "col": 78, + "line": 1, + }, + "start": { + "col": 53, + "line": 1, + }, + }, + "method": "getAmount", + "target": { + "loc": { + "end": { + "col": 65, + "line": 1, + }, + "start": { + "col": 53, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "someContract", + }, + "type": "CallExpression", + }, + "loc": { + "end": { + "col": 82, + "line": 1, + }, + "start": { + "col": 53, + "line": 1, + }, + }, + "operator": "/", + "right": { + "loc": { + "end": { + "col": 82, + "line": 1, + }, + "start": { + "col": 81, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 104, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "+", + "right": { + "left": { + "loc": { + "end": { + "col": 100, + "line": 1, + }, + "start": { + "col": 86, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$some-Variable", + }, + "loc": { + "end": { + "col": 104, + "line": 1, + }, + "start": { + "col": 86, + "line": 1, + }, + }, + "operator": "^", + "right": { + "loc": { + "end": { + "col": 104, + "line": 1, + }, + "start": { + "col": 103, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "2", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", +} +`; + +exports[`Parsers - arithmetic > should parse an arithmetic operation containing priority parenthenses correctly 1`] = ` +{ + "left": { + "left": { + "loc": { + "end": { + "col": 2, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "9", + }, + "loc": { + "end": { + "col": 5, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "^", + "right": { + "loc": { + "end": { + "col": 5, + "line": 1, + }, + "start": { + "col": 3, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "33", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 24, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "+", + "right": { + "left": { + "left": { + "loc": { + "end": { + "col": 10, + "line": 1, + }, + "start": { + "col": 9, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "5", + }, + "loc": { + "end": { + "col": 14, + "line": 1, + }, + "start": { + "col": 9, + "line": 1, + }, + }, + "operator": "-", + "right": { + "loc": { + "end": { + "col": 14, + "line": 1, + }, + "start": { + "col": 13, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 24, + "line": 1, + }, + "start": { + "col": 8, + "line": 1, + }, + }, + "operator": "*", + "right": { + "left": { + "loc": { + "end": { + "col": 20, + "line": 1, + }, + "start": { + "col": 19, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "loc": { + "end": { + "col": 24, + "line": 1, + }, + "start": { + "col": 19, + "line": 1, + }, + }, + "operator": "/", + "right": { + "loc": { + "end": { + "col": 24, + "line": 1, + }, + "start": { + "col": 23, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", +} +`; + +exports[`Parsers - arithmetic > should parse an arithmetic operation with in-between trailing spaces correctly 1`] = ` +{ + "left": { + "left": { + "loc": { + "end": { + "col": 2, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "9", + }, + "loc": { + "end": { + "col": 9, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "+", + "right": { + "loc": { + "end": { + "col": 9, + "line": 1, + }, + "start": { + "col": 8, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "5", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 36, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "operator": "-", + "right": { + "left": { + "left": { + "loc": { + "end": { + "col": 16, + "line": 1, + }, + "start": { + "col": 15, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "loc": { + "end": { + "col": 27, + "line": 1, + }, + "start": { + "col": 15, + "line": 1, + }, + }, + "operator": "*", + "right": { + "loc": { + "end": { + "col": 27, + "line": 1, + }, + "start": { + "col": 26, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 36, + "line": 1, + }, + "start": { + "col": 15, + "line": 1, + }, + }, + "operator": "/", + "right": { + "loc": { + "end": { + "col": 36, + "line": 1, + }, + "start": { + "col": 35, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", +} +`; + +exports[`Parsers - arithmetic > should parse an arithmetic operation with trailing spaces at both ends correctly 1`] = ` +{ + "left": { + "left": { + "loc": { + "end": { + "col": 5, + "line": 1, + }, + "start": { + "col": 4, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "9", + }, + "loc": { + "end": { + "col": 9, + "line": 1, + }, + "start": { + "col": 4, + "line": 1, + }, + }, + "operator": "+", + "right": { + "loc": { + "end": { + "col": 9, + "line": 1, + }, + "start": { + "col": 8, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "5", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 27, + "line": 1, + }, + "start": { + "col": 4, + "line": 1, + }, + }, + "operator": "-", + "right": { + "left": { + "loc": { + "end": { + "col": 13, + "line": 1, + }, + "start": { + "col": 12, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "loc": { + "end": { + "col": 27, + "line": 1, + }, + "start": { + "col": 12, + "line": 1, + }, + }, + "operator": "*", + "right": { + "left": { + "left": { + "loc": { + "end": { + "col": 18, + "line": 1, + }, + "start": { + "col": 17, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4", + }, + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 17, + "line": 1, + }, + }, + "operator": "/", + "right": { + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 21, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + "type": "BinaryExpression", + }, + "loc": { + "end": { + "col": 27, + "line": 1, + }, + "start": { + "col": 16, + "line": 1, + }, + }, + "operator": "^", + "right": { + "loc": { + "end": { + "col": 27, + "line": 1, + }, + "start": { + "col": 26, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", + }, + "type": "BinaryExpression", +} +`; diff --git a/core/evmcrispr/test/parsers/__snapshots__/array.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/array.test.ts.snap new file mode 100644 index 00000000..7ffbda7f --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/array.test.ts.snap @@ -0,0 +1,349 @@ +// Vitest Snapshot v1 + +exports[`Parsers - array > should fail when parsing an array with empty elements 1`] = `"ArrayParserError(1:9): Expecting a valid expression, got ','"`; + +exports[`Parsers - array > should fail when parsing an array with multiple primary values between commas 1`] = `"ArrayParserError(1:12): Expecting character ']', got 'v'"`; + +exports[`Parsers - array > should fail when parsing an array without closing brackets 1`] = `"ArrayParserError(1:16): Expecting character ']', but got end of input."`; + +exports[`Parsers - array > should parse an array correctly 1`] = ` +{ + "elements": [ + { + "loc": { + "end": { + "col": 3, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "12", + }, + { + "loc": { + "end": { + "col": 15, + "line": 1, + }, + "start": { + "col": 5, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "a string", + }, + ], + "loc": { + "end": { + "col": 16, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ArrayExpression", +} +`; + +exports[`Parsers - array > should parse an array with nested arrays correctly 1`] = ` +{ + "elements": [ + { + "loc": { + "end": { + "col": 8, + "line": 1, + }, + "start": { + "col": 1, + "line": 1, + }, + }, + "power": 18, + "timeUnit": "y", + "type": "NumberLiteral", + "value": "145", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 20, + "line": 1, + }, + "start": { + "col": 17, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "DAI", + }, + ], + "loc": { + "end": { + "col": 21, + "line": 1, + }, + "start": { + "col": 10, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + { + "loc": { + "end": { + "col": 28, + "line": 1, + }, + "start": { + "col": 23, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": false, + }, + { + "elements": [ + { + "loc": { + "end": { + "col": 41, + "line": 1, + }, + "start": { + "col": 31, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "a string", + }, + { + "loc": { + "end": { + "col": 55, + "line": 1, + }, + "start": { + "col": 43, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "anIdentifier", + }, + { + "elements": [ + { + "loc": { + "end": { + "col": 59, + "line": 1, + }, + "start": { + "col": 58, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "1", + }, + { + "loc": { + "end": { + "col": 62, + "line": 1, + }, + "start": { + "col": 61, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "2", + }, + { + "elements": [ + { + "loc": { + "end": { + "col": 89, + "line": 1, + }, + "start": { + "col": 65, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "aDeepDeepIdentifier.open", + }, + ], + "loc": { + "end": { + "col": 90, + "line": 1, + }, + "start": { + "col": 64, + "line": 1, + }, + }, + "type": "ArrayExpression", + }, + ], + "loc": { + "end": { + "col": 91, + "line": 1, + }, + "start": { + "col": 57, + "line": 1, + }, + }, + "type": "ArrayExpression", + }, + { + "loc": { + "end": { + "col": 103, + "line": 1, + }, + "start": { + "col": 94, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$variable", + }, + ], + "loc": { + "end": { + "col": 104, + "line": 1, + }, + "start": { + "col": 30, + "line": 1, + }, + }, + "type": "ArrayExpression", + }, + { + "args": [], + "loc": { + "end": { + "col": 120, + "line": 1, + }, + "start": { + "col": 106, + "line": 1, + }, + }, + "method": "host", + "target": { + "loc": { + "end": { + "col": 112, + "line": 1, + }, + "start": { + "col": 106, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$fDAIx", + }, + "type": "CallExpression", + }, + ], + "loc": { + "end": { + "col": 121, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ArrayExpression", +} +`; + +exports[`Parsers - array > should parse an array with spaces at both ends correctly 1`] = ` +{ + "elements": [ + { + "loc": { + "end": { + "col": 6, + "line": 1, + }, + "start": { + "col": 5, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "1", + }, + { + "loc": { + "end": { + "col": 23, + "line": 1, + }, + "start": { + "col": 8, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "a text string", + }, + { + "loc": { + "end": { + "col": 29, + "line": 1, + }, + "start": { + "col": 28, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + ], + "loc": { + "end": { + "col": 34, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ArrayExpression", +} +`; diff --git a/core/evmcrispr/test/parsers/__snapshots__/call.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/call.test.ts.snap new file mode 100644 index 00000000..635785ad --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/call.test.ts.snap @@ -0,0 +1,489 @@ +// Vitest Snapshot v1 + +exports[`Parsers - call expression > should parse a call expression containing nested call expression correctly 1`] = ` +{ + "args": [ + { + "args": [ + { + "loc": { + "end": { + "col": 37, + "line": 1, + }, + "start": { + "col": 31, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "DAIx", + }, + ], + "loc": { + "end": { + "col": 38, + "line": 1, + }, + "start": { + "col": 24, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + { + "args": [ + { + "elements": [ + { + "loc": { + "end": { + "col": 58, + "line": 1, + }, + "start": { + "col": 57, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "1", + }, + { + "loc": { + "end": { + "col": 60, + "line": 1, + }, + "start": { + "col": 59, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "2", + }, + { + "loc": { + "end": { + "col": 62, + "line": 1, + }, + "start": { + "col": 61, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "3", + }, + ], + "loc": { + "end": { + "col": 63, + "line": 1, + }, + "start": { + "col": 56, + "line": 1, + }, + }, + "type": "ArrayExpression", + }, + ], + "loc": { + "end": { + "col": 64, + "line": 1, + }, + "start": { + "col": 40, + "line": 1, + }, + }, + "method": "vault", + "target": { + "loc": { + "end": { + "col": 48, + "line": 1, + }, + "start": { + "col": 40, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$finance", + }, + "type": "CallExpression", + }, + { + "args": [], + "loc": { + "end": { + "col": 85, + "line": 1, + }, + "start": { + "col": 66, + "line": 1, + }, + }, + "method": "method", + "target": { + "loc": { + "end": { + "col": 75, + "line": 1, + }, + "start": { + "col": 66, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$contract", + }, + "type": "CallExpression", + }, + { + "loc": { + "end": { + "col": 93, + "line": 1, + }, + "start": { + "col": 87, + "line": 1, + }, + }, + "power": 18, + "timeUnit": "m", + "type": "NumberLiteral", + "value": "10", + }, + { + "loc": { + "end": { + "col": 123, + "line": 1, + }, + "start": { + "col": 95, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "this is a nice description", + }, + ], + "loc": { + "end": { + "col": 124, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "method": "createFlow", + "target": { + "loc": { + "end": { + "col": 11, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$superfluid", + }, + "type": "CallExpression", +} +`; + +exports[`Parsers - call expression > should parse a call expression made from a helper function correctly 1`] = ` +{ + "args": [ + { + "args": [ + { + "loc": { + "end": { + "col": 32, + "line": 1, + }, + "start": { + "col": 29, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "DAI", + }, + ], + "loc": { + "end": { + "col": 33, + "line": 1, + }, + "start": { + "col": 22, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + { + "loc": { + "end": { + "col": 42, + "line": 1, + }, + "start": { + "col": 35, + "line": 1, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "1800", + }, + ], + "loc": { + "end": { + "col": 43, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "method": "upgrade", + "target": { + "args": [ + { + "loc": { + "end": { + "col": 11, + "line": 1, + }, + "start": { + "col": 7, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "DAIx", + }, + ], + "loc": { + "end": { + "col": 12, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + "type": "CallExpression", +} +`; + +exports[`Parsers - call expression > should parse a call expression made from a literal address correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 54, + "line": 1, + }, + "start": { + "col": 53, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "0", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 67, + "line": 1, + }, + "start": { + "col": 63, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "WETH", + }, + ], + "loc": { + "end": { + "col": 68, + "line": 1, + }, + "start": { + "col": 56, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 69, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "method": "getEntry", + "target": { + "loc": { + "end": { + "col": 42, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "AddressLiteral", + "value": "0x14FA5C16Af56190239B997485656F5c8b4f86c4b", + }, + "type": "CallExpression", +} +`; + +exports[`Parsers - call expression > should parse a call expression with following chained call expressions correctly 1`] = ` +{ + "args": [], + "loc": { + "end": { + "col": 66, + "line": 1, + }, + "start": { + "col": 57, + "line": 1, + }, + }, + "method": "another", + "target": { + "args": [ + { + "args": [], + "loc": { + "end": { + "col": 43, + "line": 1, + }, + "start": { + "col": 40, + "line": 1, + }, + }, + "name": "me", + "type": "HelperFunctionExpression", + }, + { + "loc": { + "end": { + "col": 54, + "line": 1, + }, + "start": { + "col": 45, + "line": 1, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "560.25", + }, + ], + "loc": { + "end": { + "col": 55, + "line": 1, + }, + "start": { + "col": 32, + "line": 1, + }, + }, + "method": "approve", + "target": { + "args": [ + { + "loc": { + "end": { + "col": 29, + "line": 1, + }, + "start": { + "col": 28, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "1", + }, + ], + "loc": { + "end": { + "col": 30, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "method": "getToken", + "target": { + "loc": { + "end": { + "col": 17, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$registryContract", + }, + "type": "CallExpression", + }, + "type": "CallExpression", + }, + "type": "CallExpression", +} +`; diff --git a/core/evmcrispr/test/parsers/__snapshots__/command.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/command.test.ts.snap new file mode 100644 index 00000000..8a084c28 --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/command.test.ts.snap @@ -0,0 +1,1311 @@ +// Vitest Snapshot v1 + +exports[`Parsers - command expression > should fail when parsing an incomplete command name 1`] = `"CommandParserError(1:10): Expecting a valid command name, got ':...'"`; + +exports[`Parsers - command expression > should fail when parsing an invalid command name 1`] = `"CommandParserError(1:14): Expecting a valid command name, got '234...'"`; + +exports[`Parsers - command expression > should fail when parsing an invalid module name 1`] = `"CommandParserError(1:4): Expecting a valid command name, got '2345:...'"`; + +exports[`Parsers - command expression > should fail when parsing an invalid opt name 1`] = `"CommandParserError(1:5): Expecting a valid option name, got '$ asd...'"`; + +exports[`Parsers - command expression > should parse a command followed by block experssions correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 21, + "line": 1, + }, + "start": { + "col": 8, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "token-manager", + }, + { + "loc": { + "end": { + "col": 28, + "line": 1, + }, + "start": { + "col": 22, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "voting", + }, + { + "loc": { + "end": { + "col": 34, + "line": 1, + }, + "start": { + "col": 29, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 16, + "line": 2, + }, + "start": { + "col": 10, + "line": 2, + }, + }, + "type": "VariableIdentifier", + "value": "$agent", + }, + { + "args": [], + "loc": { + "end": { + "col": 34, + "line": 2, + }, + "start": { + "col": 17, + "line": 2, + }, + }, + "method": "vault", + "target": { + "loc": { + "end": { + "col": 25, + "line": 2, + }, + "start": { + "col": 17, + "line": 2, + }, + }, + "type": "VariableIdentifier", + "value": "$finance", + }, + "type": "CallExpression", + }, + ], + "loc": { + "end": { + "col": 34, + "line": 2, + }, + "start": { + "col": 6, + "line": 2, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 42, + "line": 3, + }, + "start": { + "col": 14, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "wrappable-token-manager.open", + }, + { + "loc": { + "end": { + "col": 65, + "line": 3, + }, + "start": { + "col": 43, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "disputable-voting.open", + }, + { + "loc": { + "end": { + "col": 71, + "line": 3, + }, + "start": { + "col": 66, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + { + "body": [ + { + "args": [ + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 21, + "line": 5, + }, + "start": { + "col": 15, + "line": 5, + }, + }, + "type": "ProbableIdentifier", + "value": "create", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 34, + "line": 5, + }, + "start": { + "col": 29, + "line": 5, + }, + }, + "type": "ProbableIdentifier", + "value": "fDAIx", + }, + ], + "loc": { + "end": { + "col": 35, + "line": 5, + }, + "start": { + "col": 22, + "line": 5, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + { + "loc": { + "end": { + "col": 42, + "line": 5, + }, + "start": { + "col": 36, + "line": 5, + }, + }, + "type": "VariableIdentifier", + "value": "$agent", + }, + { + "loc": { + "end": { + "col": 49, + "line": 5, + }, + "start": { + "col": 43, + "line": 5, + }, + }, + "power": 18, + "timeUnit": "mo", + "type": "NumberLiteral", + "value": "1", + }, + ], + "loc": { + "end": { + "col": 49, + "line": 5, + }, + "start": { + "col": 10, + "line": 5, + }, + }, + "name": "flow", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 9, + "line": 6, + }, + "start": { + "col": 21, + "line": 4, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 9, + "line": 6, + }, + "start": { + "col": 8, + "line": 4, + }, + }, + "module": "sf", + "name": "batchcall", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 7, + }, + "start": { + "col": 72, + "line": 3, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 7, + "line": 7, + }, + "start": { + "col": 6, + "line": 3, + }, + }, + "name": "forward", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 8, + }, + "start": { + "col": 35, + "line": 1, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 8, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "forward", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command load correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 15, + "line": 1, + }, + "start": { + "col": 5, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "superfluid", + }, + ], + "loc": { + "end": { + "col": 15, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command set correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 17, + "line": 1, + }, + "start": { + "col": 4, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$new-variable", + }, + { + "loc": { + "end": { + "col": 30, + "line": 1, + }, + "start": { + "col": 18, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "a variable", + }, + ], + "loc": { + "end": { + "col": 30, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command switch correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 13, + "line": 1, + }, + "start": { + "col": 7, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "gnosis", + }, + ], + "loc": { + "end": { + "col": 13, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "switch", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command with as expression correctly 1`] = ` +{ + "args": [ + { + "left": { + "loc": { + "end": { + "col": 13, + "line": 1, + }, + "start": { + "col": 5, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "aragonos", + }, + "loc": { + "end": { + "col": 19, + "line": 1, + }, + "start": { + "col": 5, + "line": 1, + }, + }, + "right": { + "loc": { + "end": { + "col": 19, + "line": 1, + }, + "start": { + "col": 17, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "ar", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 19, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command with helper function and call expression correctly 1`] = ` +{ + "args": [ + { + "args": [ + { + "loc": { + "end": { + "col": 38, + "line": 1, + }, + "start": { + "col": 17, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "upload this to ipfs", + }, + ], + "loc": { + "end": { + "col": 39, + "line": 1, + }, + "start": { + "col": 11, + "line": 1, + }, + }, + "name": "ipfs", + "type": "HelperFunctionExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 66, + "line": 1, + }, + "start": { + "col": 58, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "param1", + }, + { + "loc": { + "end": { + "col": 73, + "line": 1, + }, + "start": { + "col": 68, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": false, + }, + { + "loc": { + "end": { + "col": 88, + "line": 1, + }, + "start": { + "col": 75, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "an-identifier", + }, + { + "args": [], + "loc": { + "end": { + "col": 93, + "line": 1, + }, + "start": { + "col": 90, + "line": 1, + }, + }, + "name": "me", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 94, + "line": 1, + }, + "start": { + "col": 40, + "line": 1, + }, + }, + "method": "getData", + "target": { + "loc": { + "end": { + "col": 48, + "line": 1, + }, + "start": { + "col": 40, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "contract", + }, + "type": "CallExpression", + }, + { + "loc": { + "end": { + "col": 117, + "line": 1, + }, + "start": { + "col": 95, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "anotherIdentifier.open", + }, + ], + "loc": { + "end": { + "col": 117, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "my-command", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command with in-between optional args correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 47, + "line": 1, + }, + "start": { + "col": 5, + "line": 1, + }, + }, + "type": "AddressLiteral", + "value": "0x9C33eaCc2F50E39940D3AfaF2c7B8246B681A374", + }, + { + "loc": { + "end": { + "col": 77, + "line": 1, + }, + "start": { + "col": 73, + "line": 1, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "1", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 127, + "line": 1, + }, + "start": { + "col": 124, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "DAI", + }, + { + "loc": { + "end": { + "col": 134, + "line": 1, + }, + "start": { + "col": 129, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "see", + }, + ], + "loc": { + "end": { + "col": 135, + "line": 1, + }, + "start": { + "col": 117, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + { + "body": [ + { + "args": [ + { + "args": [], + "loc": { + "end": { + "col": 24, + "line": 2, + }, + "start": { + "col": 21, + "line": 2, + }, + }, + "name": "me", + "type": "HelperFunctionExpression", + }, + { + "loc": { + "end": { + "col": 44, + "line": 2, + }, + "start": { + "col": 39, + "line": 2, + }, + }, + "power": 16, + "type": "NumberLiteral", + "value": "25", + }, + ], + "loc": { + "end": { + "col": 44, + "line": 2, + }, + "start": { + "col": 6, + "line": 2, + }, + }, + "name": "inside-command", + "opts": [ + { + "loc": { + "end": { + "col": 38, + "line": 2, + }, + "start": { + "col": 25, + "line": 2, + }, + }, + "name": "t", + "type": "CommandOpt", + "value": { + "loc": { + "end": { + "col": 38, + "line": 2, + }, + "start": { + "col": 29, + "line": 2, + }, + }, + "type": "StringLiteral", + "value": "testing", + }, + }, + ], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 32, + "line": 3, + }, + "start": { + "col": 17, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "token-manager:0", + }, + { + "loc": { + "end": { + "col": 50, + "line": 3, + }, + "start": { + "col": 33, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "superfluid.open:3", + }, + ], + "loc": { + "end": { + "col": 65, + "line": 3, + }, + "start": { + "col": 6, + "line": 3, + }, + }, + "name": "another-ne", + "opts": [ + { + "loc": { + "end": { + "col": 65, + "line": 3, + }, + "start": { + "col": 51, + "line": 3, + }, + }, + "name": "default", + "type": "CommandOpt", + "value": { + "loc": { + "end": { + "col": 65, + "line": 3, + }, + "start": { + "col": 61, + "line": 3, + }, + }, + "type": "BoolLiteral", + "value": true, + }, + }, + ], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 5, + "line": 4, + }, + "start": { + "col": 136, + "line": 1, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 21, + "line": 4, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "exec", + "opts": [ + { + "loc": { + "end": { + "col": 72, + "line": 1, + }, + "start": { + "col": 48, + "line": 1, + }, + }, + "name": "inBetween", + "type": "CommandOpt", + "value": { + "args": [], + "loc": { + "end": { + "col": 72, + "line": 1, + }, + "start": { + "col": 60, + "line": 1, + }, + }, + "method": "getInfo", + "target": { + "loc": { + "end": { + "col": 61, + "line": 1, + }, + "start": { + "col": 60, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "a", + }, + "type": "CallExpression", + }, + }, + { + "loc": { + "end": { + "col": 116, + "line": 1, + }, + "start": { + "col": 78, + "line": 1, + }, + }, + "name": "another-one", + "type": "CommandOpt", + "value": { + "args": [ + { + "loc": { + "end": { + "col": 110, + "line": 1, + }, + "start": { + "col": 107, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "GIV", + }, + { + "args": [], + "loc": { + "end": { + "col": 115, + "line": 1, + }, + "start": { + "col": 112, + "line": 1, + }, + }, + "name": "me", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 116, + "line": 1, + }, + "start": { + "col": 92, + "line": 1, + }, + }, + "name": "token.balance", + "type": "HelperFunctionExpression", + }, + }, + { + "loc": { + "end": { + "col": 21, + "line": 4, + }, + "start": { + "col": 6, + "line": 4, + }, + }, + "name": "lastOne", + "type": "CommandOpt", + "value": { + "loc": { + "end": { + "col": 21, + "line": 4, + }, + "start": { + "col": 16, + "line": 4, + }, + }, + "type": "BoolLiteral", + "value": false, + }, + }, + ], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command with in-between trailing whitespaces correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 43, + "line": 1, + }, + "start": { + "col": 15, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "wrapper-hooked-token-manager", + }, + { + "loc": { + "end": { + "col": 86, + "line": 1, + }, + "start": { + "col": 44, + "line": 1, + }, + }, + "type": "AddressLiteral", + "value": "0x83E57888cd55C3ea1cfbf0114C963564d81e318d", + }, + { + "loc": { + "end": { + "col": 92, + "line": 1, + }, + "start": { + "col": 87, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": false, + }, + { + "loc": { + "end": { + "col": 94, + "line": 1, + }, + "start": { + "col": 93, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "0", + }, + ], + "loc": { + "end": { + "col": 94, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command with left trailing whitespaces correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 39, + "line": 1, + }, + "start": { + "col": 11, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "wrapper-hooked-token-manager", + }, + { + "loc": { + "end": { + "col": 82, + "line": 1, + }, + "start": { + "col": 40, + "line": 1, + }, + }, + "type": "AddressLiteral", + "value": "0x83E57888cd55C3ea1cfbf0114C963564d81e318d", + }, + { + "loc": { + "end": { + "col": 88, + "line": 1, + }, + "start": { + "col": 83, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": false, + }, + { + "loc": { + "end": { + "col": 90, + "line": 1, + }, + "start": { + "col": 89, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "0", + }, + ], + "loc": { + "end": { + "col": 90, + "line": 1, + }, + "start": { + "col": 3, + "line": 1, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command with optional args correctly 1`] = `"CommandParserError(1:0): Expecting a valid command name, got ''exam...'"`; + +exports[`Parsers - command expression > should parse a command with right trailing whitespaces correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 36, + "line": 1, + }, + "start": { + "col": 8, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "wrapper-hooked-token-manager", + }, + { + "loc": { + "end": { + "col": 79, + "line": 1, + }, + "start": { + "col": 37, + "line": 1, + }, + }, + "type": "AddressLiteral", + "value": "0x83E57888cd55C3ea1cfbf0114C963564d81e318d", + }, + { + "loc": { + "end": { + "col": 85, + "line": 1, + }, + "start": { + "col": 80, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": false, + }, + { + "loc": { + "end": { + "col": 87, + "line": 1, + }, + "start": { + "col": 86, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "0", + }, + ], + "loc": { + "end": { + "col": 87, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", +} +`; + +exports[`Parsers - command expression > should parse a command without args correctly 1`] = ` +{ + "args": [], + "loc": { + "end": { + "col": 18, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "module": "mod", + "name": "no-arg-command", + "opts": [], + "type": "CommandExpression", +} +`; diff --git a/core/evmcrispr/test/parsers/__snapshots__/comment.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/comment.test.ts.snap new file mode 100644 index 00000000..6a884f16 --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/comment.test.ts.snap @@ -0,0 +1,225 @@ +// Vitest Snapshot v1 + +exports[`Parsers - comment > should parse a inline comment correctly 1`] = ` +Cas11AST { + "body": [ + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 19, + "line": 2, + }, + "start": { + "col": 11, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "aragonos", + }, + "loc": { + "end": { + "col": 25, + "line": 2, + }, + "start": { + "col": 11, + "line": 2, + }, + }, + "right": { + "loc": { + "end": { + "col": 25, + "line": 2, + }, + "start": { + "col": 23, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "ar", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 2, + }, + "start": { + "col": 6, + "line": 2, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 15, + "line": 3, + }, + "start": { + "col": 10, + "line": 3, + }, + }, + "type": "VariableIdentifier", + "value": "$var1", + }, + { + "loc": { + "end": { + "col": 20, + "line": 3, + }, + "start": { + "col": 16, + "line": 3, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "1", + }, + ], + "loc": { + "end": { + "col": 20, + "line": 3, + }, + "start": { + "col": 6, + "line": 3, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + ], + "type": "Program", +} +`; + +exports[`Parsers - comment > should parse a normal comment correctly 1`] = ` +Cas11AST { + "body": [ + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 17, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "aragonos", + }, + "loc": { + "end": { + "col": 23, + "line": 3, + }, + "start": { + "col": 9, + "line": 3, + }, + }, + "right": { + "loc": { + "end": { + "col": 23, + "line": 3, + }, + "start": { + "col": 21, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "ar", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 23, + "line": 3, + }, + "start": { + "col": 4, + "line": 3, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 13, + "line": 6, + }, + "start": { + "col": 8, + "line": 6, + }, + }, + "type": "VariableIdentifier", + "value": "$var1", + }, + { + "loc": { + "end": { + "col": 18, + "line": 6, + }, + "start": { + "col": 14, + "line": 6, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "1", + }, + ], + "loc": { + "end": { + "col": 18, + "line": 6, + }, + "start": { + "col": 4, + "line": 6, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + ], + "type": "Program", +} +`; diff --git a/core/evmcrispr/test/parsers/__snapshots__/helper.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/helper.test.ts.snap new file mode 100644 index 00000000..64e716fd --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/helper.test.ts.snap @@ -0,0 +1,230 @@ +// Vitest Snapshot v1 + +exports[`Parsers - helper functions > should fail when parsing a helper with an invalid name 1`] = `"HelperParserError(1:4): Expecting a helper name, got '&$6...'"`; + +exports[`Parsers - helper functions > should fail when parsing a helper with empty arguments 1`] = `"HelperParserError(1:20): Expecting a valid expression, got ','"`; + +exports[`Parsers - helper functions > should fail when parsing a helper with no closing parenthesis 1`] = `"HelperParserError(1:17): Expecting character ')', but got end of input."`; + +exports[`Parsers - helper functions > should fail when parsing a helper with no opening parenthesis 1`] = `"HelperParserError(1:10): Expecting a helper name, got '1, 1e...'"`; + +exports[`Parsers - helper functions > should parse helper correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 11, + "line": 1, + }, + "start": { + "col": 7, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "WETH", + }, + ], + "loc": { + "end": { + "col": 12, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", +} +`; + +exports[`Parsers - helper functions > should parse helper with call expression correctly 1`] = ` +{ + "args": [ + { + "args": [], + "loc": { + "end": { + "col": 38, + "line": 1, + }, + "start": { + "col": 16, + "line": 1, + }, + }, + "method": "symbol", + "target": { + "loc": { + "end": { + "col": 28, + "line": 1, + }, + "start": { + "col": 16, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "anotherToken", + }, + "type": "CallExpression", + }, + { + "loc": { + "end": { + "col": 64, + "line": 1, + }, + "start": { + "col": 40, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "this is a string param", + }, + { + "loc": { + "end": { + "col": 71, + "line": 1, + }, + "start": { + "col": 66, + "line": 1, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "10", + }, + ], + "loc": { + "end": { + "col": 72, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "helperFunction", + "type": "HelperFunctionExpression", +} +`; + +exports[`Parsers - helper functions > should parse helper with nested helpers correctly 1`] = ` +{ + "args": [ + { + "loc": { + "end": { + "col": 12, + "line": 1, + }, + "start": { + "col": 7, + "line": 1, + }, + }, + "type": "StringLiteral", + "value": "DAI", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 20, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "34", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 41, + "line": 1, + }, + "start": { + "col": 37, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": true, + }, + ], + "loc": { + "end": { + "col": 42, + "line": 1, + }, + "start": { + "col": 24, + "line": 1, + }, + }, + "name": "innerHelper", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 43, + "line": 1, + }, + "start": { + "col": 14, + "line": 1, + }, + }, + "name": "calc", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 44, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", +} +`; + +exports[`Parsers - helper functions > should parse helper with no arguments correctly 1`] = ` +{ + "args": [], + "loc": { + "end": { + "col": 4, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "name": "now", + "type": "HelperFunctionExpression", +} +`; diff --git a/core/evmcrispr/test/parsers/__snapshots__/primary.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/primary.test.ts.snap new file mode 100644 index 00000000..c4a7eff6 --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/primary.test.ts.snap @@ -0,0 +1,557 @@ +// Vitest Snapshot v1 + +exports[`Parsers - primaries > when parsing literal values > should fail when parsing an invalid string 1`] = `"StringParserError(1:12): Expecting a quoted string, got end of input."`; + +exports[`Parsers - primaries > when parsing literal values > when parsing address values > should fail when parsing an invalid one 1`] = `"AddressParserError(1:0): Expecting an address, got '0xasd...'"`; + +exports[`Parsers - primaries > when parsing literal values > when parsing address values > should parse them correctly 1`] = ` +{ + "loc": { + "end": { + "col": 42, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "AddressLiteral", + "value": "0x3aD736904E9e65189c3000c7DD2c8AC8bB7cD4e3", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing boolean values > should fail when parsing an invalid value 1`] = `"BooleanParserError(1:0): Expecting \\"true\\" or \\"false\\", got 'fals...'"`; + +exports[`Parsers - primaries > when parsing literal values > when parsing boolean values > should parse "true" value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 4, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": true, +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing boolean values > should parse "value" value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 5, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "BoolLiteral", + "value": false, +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing hexadecimal values > should fail when parsing an invalid value 1`] = `"HexadecimalParserError(1:3): Expecting a hexadecimal value, got 'sdadq...'"`; + +exports[`Parsers - primaries > when parsing literal values > when parsing hexadecimal values > should parse a long value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 202, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "BytesLiteral", + "value": "0x0e80f0b30000000000000000000000008e6cd950ad6ba651f6dd608dc70e5886b1aa6b240000000000000000000000002f00df4f995451e0df337b91744006eb8892bfb10000000000000000000000000000000000000000000000004563918244f40000", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing hexadecimal values > should parse a value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 15, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "BytesLiteral", + "value": "0xa3432da4567be", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should fail when parsing an incomplete decimal 1`] = `"NumberParserError(1:4): Invalid decimal. Expecting digits"`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should fail when parsing an incomplete exponent 1`] = `"NumberParserError(1:6): Invalid exponent. Expecting digits"`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should fail when parsing an invalid time unit 1`] = `"NumberParserError(1:10): Invalid time unit. Expected \\"s\\", \\"m\\", \\"h\\", \\"d\\", \\"w\\", \\"mo\\" or \\"y\\", got '34...'"`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a exponent value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 7, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "9200", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a integer value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 2, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "15", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with a decimal and exponent correctly 1`] = ` +{ + "loc": { + "end": { + "col": 6, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "power": 14, + "type": "NumberLiteral", + "value": "0.5", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with a decimal correctly 1`] = ` +{ + "loc": { + "end": { + "col": 7, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "NumberLiteral", + "value": "4500.32", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with a decimal, exponent and temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 12, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "power": 18, + "timeUnit": "mo", + "type": "NumberLiteral", + "value": "20.3245", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with a minutely temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 2, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "timeUnit": "m", + "type": "NumberLiteral", + "value": "5", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with a secondly temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 3, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "timeUnit": "s", + "type": "NumberLiteral", + "value": "50", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with an daily temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 4, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "timeUnit": "d", + "type": "NumberLiteral", + "value": "365", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with an hourly temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 3, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "timeUnit": "h", + "type": "NumberLiteral", + "value": "35", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with an monthly temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 5, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "timeUnit": "mo", + "type": "NumberLiteral", + "value": "6.5", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with an weekly temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 3, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "timeUnit": "w", + "type": "NumberLiteral", + "value": "72", +} +`; + +exports[`Parsers - primaries > when parsing literal values > when parsing numeric values > should parse a value with an yearly temporal unit correctly 1`] = ` +{ + "loc": { + "end": { + "col": 4, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "timeUnit": "y", + "type": "NumberLiteral", + "value": "2.5", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > fail when parsing an invalid identifier 1`] = `"IdentifierParserError(1:3): Expecting an identifier, got '([[))...'"`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 3, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "new", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a camel case value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 9, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "aNewAgent", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a date-like value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 10, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "2015-20-09", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a dots and numbers value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 12, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "agent.open.0", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a kebab case value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 11, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "create-flow", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a kebab case with colon value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 28, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "superfluid-app.other-open:20", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a kebab case with dot value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 15, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "my-ens-name.eth", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a long kebab case value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 27, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "create-super-flow-xtreme-aa", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a no-params-signature-like value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 18, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "noParamSignature()", +} +`; + +exports[`Parsers - primaries > when parsing probable identifiers > should parse a signature-like value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 28, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "ProbableIdentifier", + "value": "aSIgnature(with,some,params)", +} +`; + +exports[`Parsers - primaries > when parsing variable identifiers > should fail when parsing invalid variables 1`] = `"VariableParserError(1:5): Expecting a variable, got '()...'"`; + +exports[`Parsers - primaries > when parsing variable identifiers > when parsing variable values > should parse a value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 9, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$variable", +} +`; + +exports[`Parsers - primaries > when parsing variable identifiers > when parsing variable values > should parse a camel case value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 19, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$aCamelCaseVariable", +} +`; + +exports[`Parsers - primaries > when parsing variable identifiers > when parsing variable values > should parse a snake case value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 22, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$a-snake-case-variable", +} +`; + +exports[`Parsers - primaries > when parsing variable identifiers > when parsing variable values > should parse a snake case with colon and number value correctly 1`] = ` +{ + "loc": { + "end": { + "col": 21, + "line": 1, + }, + "start": { + "col": 0, + "line": 1, + }, + }, + "type": "VariableIdentifier", + "value": "$token-manager.open:0", +} +`; diff --git a/core/evmcrispr/test/parsers/__snapshots__/script.test.ts.snap b/core/evmcrispr/test/parsers/__snapshots__/script.test.ts.snap new file mode 100644 index 00000000..7c109ee8 --- /dev/null +++ b/core/evmcrispr/test/parsers/__snapshots__/script.test.ts.snap @@ -0,0 +1,895 @@ +// Vitest Snapshot v1 + +exports[`Parsers - script > should parse an script correctly 1`] = ` +Cas11AST { + "body": [ + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 19, + "line": 2, + }, + "start": { + "col": 11, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "aragonos", + }, + "loc": { + "end": { + "col": 25, + "line": 2, + }, + "start": { + "col": 11, + "line": 2, + }, + }, + "right": { + "loc": { + "end": { + "col": 25, + "line": 2, + }, + "start": { + "col": 23, + "line": 2, + }, + }, + "type": "ProbableIdentifier", + "value": "ar", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 25, + "line": 2, + }, + "start": { + "col": 6, + "line": 2, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "left": { + "loc": { + "end": { + "col": 21, + "line": 3, + }, + "start": { + "col": 11, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "superfluid", + }, + "loc": { + "end": { + "col": 27, + "line": 3, + }, + "start": { + "col": 11, + "line": 3, + }, + }, + "right": { + "loc": { + "end": { + "col": 27, + "line": 3, + }, + "start": { + "col": 25, + "line": 3, + }, + }, + "type": "ProbableIdentifier", + "value": "sf", + }, + "type": "AsExpression", + }, + ], + "loc": { + "end": { + "col": 27, + "line": 3, + }, + "start": { + "col": 6, + "line": 3, + }, + }, + "name": "load", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 27, + "line": 6, + }, + "start": { + "col": 17, + "line": 6, + }, + }, + "type": "ProbableIdentifier", + "value": "my-dao-ens", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 29, + "line": 7, + }, + "start": { + "col": 16, + "line": 7, + }, + }, + "type": "ProbableIdentifier", + "value": "token-manager", + }, + { + "loc": { + "end": { + "col": 36, + "line": 7, + }, + "start": { + "col": 30, + "line": 7, + }, + }, + "type": "ProbableIdentifier", + "value": "voting", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 51, + "line": 8, + }, + "start": { + "col": 18, + "line": 8, + }, + }, + "type": "ProbableIdentifier", + "value": "wrapper-hooked-token-manager.open", + }, + { + "loc": { + "end": { + "col": 94, + "line": 8, + }, + "start": { + "col": 52, + "line": 8, + }, + }, + "type": "AddressLiteral", + "value": "0x83E57888cd55C3ea1cfbf0114C963564d81e318d", + }, + { + "loc": { + "end": { + "col": 100, + "line": 8, + }, + "start": { + "col": 95, + "line": 8, + }, + }, + "type": "BoolLiteral", + "value": false, + }, + { + "loc": { + "end": { + "col": 102, + "line": 8, + }, + "start": { + "col": 101, + "line": 8, + }, + }, + "type": "NumberLiteral", + "value": "0", + }, + ], + "loc": { + "end": { + "col": 102, + "line": 8, + }, + "start": { + "col": 10, + "line": 8, + }, + }, + "name": "install", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 9, + "line": 11, + }, + "start": { + "col": 42, + "line": 7, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 9, + "line": 11, + }, + "start": { + "col": 8, + "line": 7, + }, + }, + "name": "forward", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 29, + "line": 16, + }, + "start": { + "col": 16, + "line": 16, + }, + }, + "type": "ProbableIdentifier", + "value": "token-manager", + }, + { + "loc": { + "end": { + "col": 36, + "line": 16, + }, + "start": { + "col": 30, + "line": 16, + }, + }, + "type": "ProbableIdentifier", + "value": "voting", + }, + { + "loc": { + "end": { + "col": 42, + "line": 16, + }, + "start": { + "col": 37, + "line": 16, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 20, + "line": 18, + }, + "start": { + "col": 14, + "line": 18, + }, + }, + "type": "VariableIdentifier", + "value": "$agent", + }, + { + "args": [], + "loc": { + "end": { + "col": 37, + "line": 18, + }, + "start": { + "col": 21, + "line": 18, + }, + }, + "method": "vault", + "target": { + "loc": { + "end": { + "col": 28, + "line": 18, + }, + "start": { + "col": 21, + "line": 18, + }, + }, + "type": "ProbableIdentifier", + "value": "finance", + }, + "type": "CallExpression", + }, + ], + "loc": { + "end": { + "col": 37, + "line": 18, + }, + "start": { + "col": 10, + "line": 18, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 46, + "line": 20, + }, + "start": { + "col": 18, + "line": 20, + }, + }, + "type": "ProbableIdentifier", + "value": "wrappable-token-manager.open", + }, + { + "loc": { + "end": { + "col": 69, + "line": 20, + }, + "start": { + "col": 47, + "line": 20, + }, + }, + "type": "ProbableIdentifier", + "value": "disputable-voting.open", + }, + { + "loc": { + "end": { + "col": 75, + "line": 20, + }, + "start": { + "col": 70, + "line": 20, + }, + }, + "type": "ProbableIdentifier", + "value": "agent", + }, + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 21, + "line": 21, + }, + "start": { + "col": 16, + "line": 21, + }, + }, + "type": "VariableIdentifier", + "value": "$daix", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 36, + "line": 21, + }, + "start": { + "col": 29, + "line": 21, + }, + }, + "type": "StringLiteral", + "value": "fDAIx", + }, + ], + "loc": { + "end": { + "col": 37, + "line": 21, + }, + "start": { + "col": 22, + "line": 21, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 37, + "line": 21, + }, + "start": { + "col": 12, + "line": 21, + }, + }, + "name": "set", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 28, + "line": 30, + }, + "start": { + "col": 21, + "line": 30, + }, + }, + "type": "ProbableIdentifier", + "value": "approve", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 41, + "line": 30, + }, + "start": { + "col": 36, + "line": 30, + }, + }, + "type": "StringLiteral", + "value": "DAI", + }, + ], + "loc": { + "end": { + "col": 42, + "line": 30, + }, + "start": { + "col": 29, + "line": 30, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + { + "args": [], + "loc": { + "end": { + "col": 46, + "line": 30, + }, + "start": { + "col": 43, + "line": 30, + }, + }, + "name": "me", + "type": "HelperFunctionExpression", + }, + { + "loc": { + "end": { + "col": 55, + "line": 30, + }, + "start": { + "col": 47, + "line": 30, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "15.45", + }, + ], + "loc": { + "end": { + "col": 55, + "line": 30, + }, + "start": { + "col": 12, + "line": 30, + }, + }, + "module": "sf", + "name": "token", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "body": [ + { + "args": [ + { + "loc": { + "end": { + "col": 27, + "line": 34, + }, + "start": { + "col": 20, + "line": 34, + }, + }, + "type": "ProbableIdentifier", + "value": "upgrade", + }, + { + "loc": { + "end": { + "col": 33, + "line": 34, + }, + "start": { + "col": 28, + "line": 34, + }, + }, + "type": "VariableIdentifier", + "value": "$daix", + }, + { + "loc": { + "end": { + "col": 44, + "line": 34, + }, + "start": { + "col": 34, + "line": 34, + }, + }, + "power": 18, + "type": "NumberLiteral", + "value": "4500.43", + }, + ], + "loc": { + "end": { + "col": 44, + "line": 34, + }, + "start": { + "col": 14, + "line": 34, + }, + }, + "name": "token", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 25, + "line": 35, + }, + "start": { + "col": 19, + "line": 35, + }, + }, + "type": "ProbableIdentifier", + "value": "create", + }, + { + "loc": { + "end": { + "col": 31, + "line": 35, + }, + "start": { + "col": 26, + "line": 35, + }, + }, + "type": "VariableIdentifier", + "value": "$daix", + }, + { + "loc": { + "end": { + "col": 38, + "line": 35, + }, + "start": { + "col": 32, + "line": 35, + }, + }, + "type": "VariableIdentifier", + "value": "$agent", + }, + { + "loc": { + "end": { + "col": 45, + "line": 35, + }, + "start": { + "col": 39, + "line": 35, + }, + }, + "power": 18, + "timeUnit": "mo", + "type": "NumberLiteral", + "value": "1", + }, + ], + "loc": { + "end": { + "col": 45, + "line": 35, + }, + "start": { + "col": 14, + "line": 35, + }, + }, + "name": "flow", + "opts": [], + "type": "CommandExpression", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 29, + "line": 36, + }, + "start": { + "col": 20, + "line": 36, + }, + }, + "type": "ProbableIdentifier", + "value": "downgrade", + }, + { + "args": [ + { + "loc": { + "end": { + "col": 44, + "line": 36, + }, + "start": { + "col": 37, + "line": 36, + }, + }, + "type": "StringLiteral", + "value": "USDCx", + }, + ], + "loc": { + "end": { + "col": 45, + "line": 36, + }, + "start": { + "col": 30, + "line": 36, + }, + }, + "name": "token", + "type": "HelperFunctionExpression", + }, + ], + "loc": { + "end": { + "col": 45, + "line": 36, + }, + "start": { + "col": 14, + "line": 36, + }, + }, + "name": "token", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 13, + "line": 37, + }, + "start": { + "col": 25, + "line": 33, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 13, + "line": 37, + }, + "start": { + "col": 12, + "line": 33, + }, + }, + "module": "sf", + "name": "batchcall", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 11, + "line": 40, + }, + "start": { + "col": 76, + "line": 20, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 11, + "line": 40, + }, + "start": { + "col": 10, + "line": 20, + }, + }, + "name": "forward", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 9, + "line": 43, + }, + "start": { + "col": 43, + "line": 16, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 9, + "line": 43, + }, + "start": { + "col": 8, + "line": 16, + }, + }, + "name": "forward", + "opts": [], + "type": "CommandExpression", + }, + ], + "loc": { + "end": { + "col": 27, + "line": 46, + }, + "start": { + "col": 28, + "line": 6, + }, + }, + "type": "BlockExpression", + }, + ], + "loc": { + "end": { + "col": 27, + "line": 46, + }, + "start": { + "col": 6, + "line": 6, + }, + }, + "module": "ar", + "name": "connect", + "opts": [], + "type": "CommandExpression", + }, + ], + "type": "Program", +} +`; diff --git a/core/evmcrispr/test/parsers/arithmetic.test.ts b/core/evmcrispr/test/parsers/arithmetic.test.ts index cd1e1e00..6e12ddd4 100644 --- a/core/evmcrispr/test/parsers/arithmetic.test.ts +++ b/core/evmcrispr/test/parsers/arithmetic.test.ts @@ -1,788 +1,33 @@ -import type { Case } from '@1hive/evmcrispr-test-common'; -import { runCases } from '@1hive/evmcrispr-test-common'; +import { runParser } from '@1hive/evmcrispr-test-common'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; import { arithmeticParser } from '../../src/parsers/arithmetic'; -describe('Parsers - arithmetic', () => { - it('should parse an arithmetic operation correctly', () => { - const c: Case = [ - '(9 + 5 - 4 * 4 / 3 ^ 2)', - { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'NumberLiteral', - value: '9', - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 2, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '5', - loc: { - start: { - line: 1, - col: 5, - }, - end: { - line: 1, - col: 6, - }, - }, - }, - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 6, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { - line: 1, - col: 9, - }, - end: { - line: 1, - col: 10, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { - line: 1, - col: 13, - }, - end: { - line: 1, - col: 14, - }, - }, - }, - loc: { - start: { - line: 1, - col: 9, - }, - end: { - line: 1, - col: 14, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'NumberLiteral', - value: '3', - loc: { - start: { - line: 1, - col: 17, - }, - end: { - line: 1, - col: 18, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '2', - loc: { - start: { - line: 1, - col: 21, - }, - end: { - line: 1, - col: 22, - }, - }, - }, - loc: { - start: { - line: 1, - col: 17, - }, - end: { - line: 1, - col: 22, - }, - }, - }, - loc: { - start: { - line: 1, - col: 9, - }, - end: { - line: 1, - col: 22, - }, - }, - }, - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 22, - }, - }, - }, - ]; - - runCases(c, arithmeticParser); - }); - - it('should parse an arithmetic operation with trailing spaces correctly', () => { - const cases: Case[] = [ - [ - '( 9 + 5 - 4 * (4 / 3) ^ 3 )', - { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'NumberLiteral', - value: '9', - loc: { - start: { - line: 1, - col: 4, - }, - end: { - line: 1, - col: 5, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '5', - loc: { - start: { - line: 1, - col: 8, - }, - end: { - line: 1, - col: 9, - }, - }, - }, - loc: { - start: { - line: 1, - col: 4, - }, - end: { - line: 1, - col: 9, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { - line: 1, - col: 12, - }, - end: { - line: 1, - col: 13, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { - line: 1, - col: 17, - }, - end: { - line: 1, - col: 18, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '3', - loc: { - start: { - line: 1, - col: 21, - }, - end: { - line: 1, - col: 22, - }, - }, - }, - loc: { - start: { - line: 1, - col: 17, - }, - end: { - line: 1, - col: 22, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '3', - loc: { - start: { - line: 1, - col: 26, - }, - end: { - line: 1, - col: 27, - }, - }, - }, - loc: { - start: { - line: 1, - col: 16, - }, - end: { - line: 1, - col: 27, - }, - }, - }, - loc: { - start: { - line: 1, - col: 12, - }, - end: { - line: 1, - col: 27, - }, - }, - }, - loc: { - start: { - line: 1, - col: 4, - }, - end: { - line: 1, - col: 27, - }, - }, - }, - 'inner left and right trailing spaces mismatch', - ], - [ - '(9 + 5 - 4 * 4 / 3)', - { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'NumberLiteral', - value: '9', - loc: { start: { line: 1, col: 1 }, end: { line: 1, col: 2 } }, - }, - right: { - type: 'NumberLiteral', - value: '5', - loc: { start: { line: 1, col: 8 }, end: { line: 1, col: 9 } }, - }, - loc: { start: { line: 1, col: 1 }, end: { line: 1, col: 9 } }, - }, - right: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { line: 1, col: 15 }, - end: { line: 1, col: 16 }, - }, - }, - right: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { line: 1, col: 26 }, - end: { line: 1, col: 27 }, - }, - }, - loc: { start: { line: 1, col: 15 }, end: { line: 1, col: 27 } }, - }, - right: { - type: 'NumberLiteral', - value: '3', - loc: { start: { line: 1, col: 35 }, end: { line: 1, col: 36 } }, - }, - loc: { start: { line: 1, col: 15 }, end: { line: 1, col: 36 } }, - }, - loc: { start: { line: 1, col: 1 }, end: { line: 1, col: 36 } }, - }, - 'in-between trailing spaces mismatch ', - ], - ]; - - runCases(cases, arithmeticParser); - }); - - it('should parse an arithmetic operation containing priority parentheses correctly', () => { - const c: Case = [ - '(9^33 + (5 - 4) * (4 / 3))', - { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'NumberLiteral', - value: '9', - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 2, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '33', - loc: { - start: { - line: 1, - col: 3, - }, - end: { - line: 1, - col: 5, - }, - }, - }, - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 5, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'NumberLiteral', - value: '5', - loc: { - start: { - line: 1, - col: 9, - }, - end: { - line: 1, - col: 10, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { - line: 1, - col: 13, - }, - end: { - line: 1, - col: 14, - }, - }, - }, - loc: { - start: { - line: 1, - col: 9, - }, - end: { - line: 1, - col: 14, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'NumberLiteral', - value: '4', - loc: { - start: { - line: 1, - col: 19, - }, - end: { - line: 1, - col: 20, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '3', - loc: { - start: { - line: 1, - col: 23, - }, - end: { - line: 1, - col: 24, - }, - }, - }, - loc: { - start: { - line: 1, - col: 19, - }, - end: { - line: 1, - col: 24, - }, - }, - }, - loc: { - start: { - line: 1, - col: 8, - }, - end: { - line: 1, - col: 24, - }, - }, - }, - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 24, - }, - }, - }, - ]; - - runCases(c, arithmeticParser); - }); - - it('should parse an arithmetic operation containing variable helpers and call expressions correctly', () => { - const c: Case = [ - '(90.45e18 + (5000e18 - @token.balance( DAI, @me)) * (someContract::getAmount() / 3) + $some-Variable ^ 2)', - { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'NumberLiteral', - value: '90.45', - power: 18, - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 9, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'NumberLiteral', - value: '5000', - power: 18, - loc: { - start: { - line: 1, - col: 13, - }, - end: { - line: 1, - col: 20, - }, - }, - }, - right: { - type: 'HelperFunctionExpression', - name: 'token.balance', - args: [ - { - type: 'ProbableIdentifier', - value: 'DAI', - loc: { - start: { - line: 1, - col: 39, - }, - end: { - line: 1, - col: 42, - }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'me', - args: [], - loc: { - start: { - line: 1, - col: 44, - }, - end: { - line: 1, - col: 47, - }, - }, - }, - ], - loc: { - start: { - line: 1, - col: 23, - }, - end: { - line: 1, - col: 48, - }, - }, - }, - loc: { - start: { - line: 1, - col: 13, - }, - end: { - line: 1, - col: 48, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'CallExpression', - target: { - type: 'ProbableIdentifier', - value: 'someContract', - loc: { - start: { - line: 1, - col: 53, - }, - end: { - line: 1, - col: 65, - }, - }, - }, - method: 'getAmount', - args: [], - loc: { - start: { - line: 1, - col: 53, - }, - end: { - line: 1, - col: 78, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '3', - loc: { - start: { - line: 1, - col: 81, - }, - end: { - line: 1, - col: 82, - }, - }, - }, - loc: { - start: { - line: 1, - col: 53, - }, - end: { - line: 1, - col: 82, - }, - }, - }, - loc: { - start: { - line: 1, - col: 12, - }, - end: { - line: 1, - col: 82, - }, - }, - }, - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 82, - }, - }, - }, - right: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'VariableIdentifier', - value: '$some-Variable', - loc: { - start: { - line: 1, - col: 86, - }, - end: { - line: 1, - col: 100, - }, - }, - }, - right: { - type: 'NumberLiteral', - value: '2', - loc: { - start: { - line: 1, - col: 103, - }, - end: { - line: 1, - col: 104, - }, - }, - }, - loc: { - start: { - line: 1, - col: 86, - }, - end: { - line: 1, - col: 104, - }, - }, - }, - loc: { - start: { - line: 1, - col: 1, - }, - end: { - line: 1, - col: 104, - }, - }, - }, - ]; - - runCases(c, arithmeticParser); +describe.concurrent('Parsers - arithmetic', () => { + describe.each([ + { title: '', value: '(9 + 5 - 4 * 4 / 3 ^ 2)' }, + { + title: 'with trailing spaces at both ends', + value: '( 9 + 5 - 4 * (4 / 3) ^ 3 )', + }, + { + title: 'with in-between trailing spaces', + value: '(9 + 5 - 4 * 4 / 3)', + }, + { + title: 'containing priority parenthenses', + value: '(9^33 + (5 - 4) * (4 / 3))', + }, + { + title: 'containing helper functions and call expressions', + value: + '(90.45e18 + (5000e18 - @token.balance( DAI, @me)) * (someContract::getAmount() / 3) + $some-Variable ^ 2)', + }, + ])('', ({ title, value }) => { + it(`should parse an arithmetic operation ${title} correctly`, () => { + const parsedValue = runParser(arithmeticParser, value); + + expect(parsedValue).toMatchSnapshot(); + }); }); }); diff --git a/core/evmcrispr/test/parsers/array.test.ts b/core/evmcrispr/test/parsers/array.test.ts index ede6e032..d4e8351f 100644 --- a/core/evmcrispr/test/parsers/array.test.ts +++ b/core/evmcrispr/test/parsers/array.test.ts @@ -1,203 +1,40 @@ -import type { Case } from '@1hive/evmcrispr-test-common'; -import { runCases, runErrorCase } from '@1hive/evmcrispr-test-common'; -import type { Err } from 'arcsecond'; -import { withData } from 'arcsecond'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; +import { runParser, runParserError } from '@1hive/evmcrispr-test-common'; -import { - ARRAY_PARSER_ERROR, - arrayExpressionParser, -} from '../../src/parsers/array'; -import { createParserState } from '../../src/parsers/utils'; -import type { ArrayExpressionNode, NodeParserState } from '../../src/types'; +import { arrayExpressionParser } from '../../src/parsers/array'; -describe('Parsers - array', () => { - it('should parse an array correctly', () => { - const cases: Case[] = [ - [ - '[ 1, "a text string", 3 ]', - { - type: 'ArrayExpression', - elements: [ - { - type: 'NumberLiteral', - value: '1', - loc: { start: { line: 1, col: 5 }, end: { line: 1, col: 6 } }, - }, - { - type: 'StringLiteral', - value: 'a text string', - loc: { start: { line: 1, col: 8 }, end: { line: 1, col: 23 } }, - }, - { - type: 'NumberLiteral', - value: '3', - loc: { start: { line: 1, col: 28 }, end: { line: 1, col: 29 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 34 } }, - }, - 'Invalid array match', - ], - [ +describe.concurrent('Parsers - array', () => { + describe.concurrent.each([ + { title: '', value: '[12, "a string"]' }, + { + title: 'with spaces at both ends', + value: '[ 1, "a text string", 3 ]', + }, + { + title: 'with nested arrays', + value: '[145e18y, @token(DAI), false, ["a string", anIdentifier, [1, 2, [aDeepDeepIdentifier.open]], $variable], $fDAIx::host()]', - { - type: 'ArrayExpression', - elements: [ - { - type: 'NumberLiteral', - value: '145', - power: 18, - timeUnit: 'y', - loc: { start: { line: 1, col: 1 }, end: { line: 1, col: 8 } }, - }, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'DAI', - loc: { - start: { line: 1, col: 17 }, - end: { line: 1, col: 20 }, - }, - }, - ], - loc: { start: { line: 1, col: 10 }, end: { line: 1, col: 21 } }, - }, - { - type: 'BoolLiteral', - value: false, - loc: { start: { line: 1, col: 23 }, end: { line: 1, col: 28 } }, - }, - { - type: 'ArrayExpression', - elements: [ - { - type: 'StringLiteral', - value: 'a string', - loc: { - start: { line: 1, col: 31 }, - end: { line: 1, col: 41 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'anIdentifier', - loc: { - start: { line: 1, col: 43 }, - end: { line: 1, col: 55 }, - }, - }, - { - type: 'ArrayExpression', - elements: [ - { - type: 'NumberLiteral', - value: '1', - loc: { - start: { line: 1, col: 58 }, - end: { line: 1, col: 59 }, - }, - }, - { - type: 'NumberLiteral', - value: '2', - loc: { - start: { line: 1, col: 61 }, - end: { line: 1, col: 62 }, - }, - }, - { - type: 'ArrayExpression', - elements: [ - { - type: 'ProbableIdentifier', - value: 'aDeepDeepIdentifier.open', - loc: { - start: { line: 1, col: 65 }, - end: { line: 1, col: 89 }, - }, - }, - ], - loc: { - start: { line: 1, col: 64 }, - end: { line: 1, col: 90 }, - }, - }, - ], - loc: { - start: { line: 1, col: 57 }, - end: { line: 1, col: 91 }, - }, - }, - { - type: 'VariableIdentifier', - value: '$variable', - loc: { - start: { line: 1, col: 94 }, - end: { line: 1, col: 103 }, - }, - }, - ], - loc: { - start: { line: 1, col: 30 }, - end: { line: 1, col: 104 }, - }, - }, - { - type: 'CallExpression', - target: { - type: 'VariableIdentifier', - value: '$fDAIx', - loc: { - start: { line: 1, col: 106 }, - end: { line: 1, col: 112 }, - }, - }, - method: 'host', - args: [], - loc: { - start: { line: 1, col: 106 }, - end: { line: 1, col: 120 }, - }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 121 } }, - }, - 'Invalid nested array match', - ], - ]; + }, + ])('', ({ title, value }) => { + it(`should parse an array ${title} correctly`, () => { + const parsedValue = runParser(arrayExpressionParser, value); - runCases(cases, arrayExpressionParser); + expect(parsedValue).toMatchSnapshot(); + }); }); - it('should fail when parsing an array with multiple primary values between commas', () => { - runErrorCase( - arrayExpressionParser, - '[1,multiple values between commas, false]', - ARRAY_PARSER_ERROR, - `Expecting character ']'`, - ); - }); - - it('should fail when parsing an array with empty elements', () => { - runErrorCase( - arrayExpressionParser, - '[12e14w, ,,]', - ARRAY_PARSER_ERROR, - 'Expecting a valid expression', - ); - }); - - it('should fail when parsing an array without closing bracket', () => { - const res = withData( - arrayExpressionParser, - )(createParserState()).run('[12e14w, "asdas"'); + describe.concurrent.each([ + { + title: 'with multiple primary values between commas', + value: '[1,multiple values between commas, false]', + }, + { title: 'with empty elements', value: '[12e14w, ,,]' }, + { title: 'without closing brackets', value: '[12e14w, "asdas"' }, + ])('', ({ title, value }) => { + it(`should fail when parsing an array ${title}`, () => { + const error = runParserError(arrayExpressionParser, value); - expect(res.isError).to.be.true; - expect((res as Err).error).to.equals( - `ArrayParserError(1:16): Expecting character ']', but got end of input.`, - ); + expect(error).toMatchSnapshot(); + }); }); }); diff --git a/core/evmcrispr/test/parsers/call.test.ts b/core/evmcrispr/test/parsers/call.test.ts index 538eccd7..4f2e8f64 100644 --- a/core/evmcrispr/test/parsers/call.test.ts +++ b/core/evmcrispr/test/parsers/call.test.ts @@ -1,261 +1,31 @@ -import type { Case } from '@1hive/evmcrispr-test-common'; -import { runCases } from '@1hive/evmcrispr-test-common'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; +import { runParser } from '@1hive/evmcrispr-test-common'; import { callExpressionParser } from '../../src/parsers/call'; describe('Parsers - call expression', () => { - it('should parse call expressions correctly', () => { - const cases: Case[] = [ - [ - `0x14FA5C16Af56190239B997485656F5c8b4f86c4b::getEntry(0, @token(WETH))`, - { - type: 'CallExpression', - target: { - type: 'AddressLiteral', - value: '0x14FA5C16Af56190239B997485656F5c8b4f86c4b', - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 42 } }, - }, - method: 'getEntry', - args: [ - { - type: 'NumberLiteral', - value: '0', - loc: { start: { line: 1, col: 53 }, end: { line: 1, col: 54 } }, - }, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'WETH', - loc: { - start: { line: 1, col: 63 }, - end: { line: 1, col: 67 }, - }, - }, - ], - loc: { start: { line: 1, col: 56 }, end: { line: 1, col: 68 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 69 } }, - }, - ], - [ - `$superfluid::createFlow(@token("DAIx"), $finance::vault([1,2,3]), $contract::method(), 10e18m, 'this is a nice description')`, - { - type: 'CallExpression', - target: { - type: 'VariableIdentifier', - value: '$superfluid', - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 11 } }, - }, - method: 'createFlow', - args: [ - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'StringLiteral', - value: 'DAIx', - loc: { - start: { line: 1, col: 31 }, - end: { line: 1, col: 37 }, - }, - }, - ], - loc: { start: { line: 1, col: 24 }, end: { line: 1, col: 38 } }, - }, - { - type: 'CallExpression', - target: { - type: 'VariableIdentifier', - value: '$finance', - loc: { - start: { line: 1, col: 40 }, - end: { line: 1, col: 48 }, - }, - }, - method: 'vault', - args: [ - { - type: 'ArrayExpression', - elements: [ - { - type: 'NumberLiteral', - value: '1', - loc: { - start: { line: 1, col: 57 }, - end: { line: 1, col: 58 }, - }, - }, - { - type: 'NumberLiteral', - value: '2', - loc: { - start: { line: 1, col: 59 }, - end: { line: 1, col: 60 }, - }, - }, - { - type: 'NumberLiteral', - value: '3', - loc: { - start: { line: 1, col: 61 }, - end: { line: 1, col: 62 }, - }, - }, - ], - loc: { - start: { line: 1, col: 56 }, - end: { line: 1, col: 63 }, - }, - }, - ], - loc: { start: { line: 1, col: 40 }, end: { line: 1, col: 64 } }, - }, - { - type: 'CallExpression', - target: { - type: 'VariableIdentifier', - value: '$contract', - loc: { - start: { line: 1, col: 66 }, - end: { line: 1, col: 75 }, - }, - }, - method: 'method', - args: [], - loc: { start: { line: 1, col: 66 }, end: { line: 1, col: 85 } }, - }, - { - type: 'NumberLiteral', - value: '10', - power: 18, - timeUnit: 'm', - loc: { start: { line: 1, col: 87 }, end: { line: 1, col: 93 } }, - }, - { - type: 'StringLiteral', - value: 'this is a nice description', - loc: { - start: { line: 1, col: 95 }, - end: { line: 1, col: 123 }, - }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 124 } }, - }, - 'invalid nested call expression', - ], - [ - `@token(DAIx)::upgrade(@token(DAI), 1800e18)`, - { - type: 'CallExpression', - target: { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'DAIx', - loc: { - start: { line: 1, col: 7 }, - end: { line: 1, col: 11 }, - }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 12 } }, - }, - method: 'upgrade', - args: [ - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'DAI', - loc: { - start: { line: 1, col: 29 }, - end: { line: 1, col: 32 }, - }, - }, - ], - loc: { start: { line: 1, col: 22 }, end: { line: 1, col: 33 } }, - }, - { - type: 'NumberLiteral', - value: '1800', - power: 18, - loc: { start: { line: 1, col: 35 }, end: { line: 1, col: 42 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 43 } }, - }, - 'invalid helper call expression', - ], - [ - `$registryContract::getToken(1)::approve(@me, 560.25e18)::another()`, - { - type: 'CallExpression', - target: { - type: 'CallExpression', - target: { - type: 'CallExpression', - target: { - type: 'VariableIdentifier', - value: '$registryContract', - loc: { - start: { line: 1, col: 0 }, - end: { line: 1, col: 17 }, - }, - }, - method: 'getToken', - args: [ - { - type: 'NumberLiteral', - value: '1', - loc: { - start: { line: 1, col: 28 }, - end: { line: 1, col: 29 }, - }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 30 } }, - }, - method: 'approve', - args: [ - { - type: 'HelperFunctionExpression', - name: 'me', - args: [], - loc: { - start: { line: 1, col: 40 }, - end: { line: 1, col: 43 }, - }, - }, - { - type: 'NumberLiteral', - value: '560.25', - power: 18, - loc: { - start: { line: 1, col: 45 }, - end: { line: 1, col: 54 }, - }, - }, - ], - loc: { start: { line: 1, col: 32 }, end: { line: 1, col: 55 } }, - }, - method: 'another', - args: [], - loc: { start: { line: 1, col: 57 }, end: { line: 1, col: 66 } }, - }, - 'invalid recursive call expression', - ], - ]; + describe.concurrent.each([ + { + title: 'made from a literal address', + value: `0x14FA5C16Af56190239B997485656F5c8b4f86c4b::getEntry(0, @token(WETH))`, + }, + { + title: 'containing nested call expression', + value: `$superfluid::createFlow(@token("DAIx"), $finance::vault([1,2,3]), $contract::method(), 10e18m, 'this is a nice description')`, + }, + { + title: 'made from a helper function', + value: `@token(DAIx)::upgrade(@token(DAI), 1800e18)`, + }, + { + title: 'with following chained call expressions', + value: `$registryContract::getToken(1)::approve(@me, 560.25e18)::another()`, + }, + ])('', ({ title, value }) => { + it(`should parse a call expression ${title} correctly`, () => { + const parsedValue = runParser(callExpressionParser, value); - runCases(cases, callExpressionParser); + expect(parsedValue).toMatchSnapshot(); + }); }); }); diff --git a/core/evmcrispr/test/parsers/command.test.ts b/core/evmcrispr/test/parsers/command.test.ts index f8758eba..a01d88f4 100644 --- a/core/evmcrispr/test/parsers/command.test.ts +++ b/core/evmcrispr/test/parsers/command.test.ts @@ -1,860 +1,88 @@ -import type { Case } from '@1hive/evmcrispr-test-common'; -import { runCases, runErrorCase } from '@1hive/evmcrispr-test-common'; +import { runParser, runParserError } from '@1hive/evmcrispr-test-common'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; import { - COMMAND_PARSER_ERROR, commandExpressionParser, commandOptParser, } from '../../src/parsers/command'; -describe('Parsers - command expression', () => { - it('should parse a command correctly', () => { - const cases: Case[] = [ - [ - 'my-command @ipfs("upload this to ipfs") contract::getData("param1", false, an-identifier, @me) anotherIdentifier.open', - { - type: 'CommandExpression', - name: 'my-command', - args: [ - { - type: 'HelperFunctionExpression', - name: 'ipfs', - args: [ - { - type: 'StringLiteral', - value: 'upload this to ipfs', - loc: { - start: { line: 1, col: 17 }, - end: { line: 1, col: 38 }, - }, - }, - ], - loc: { start: { line: 1, col: 11 }, end: { line: 1, col: 39 } }, - }, - { - type: 'CallExpression', - target: { - type: 'ProbableIdentifier', - value: 'contract', - loc: { - start: { line: 1, col: 40 }, - end: { line: 1, col: 48 }, - }, - }, - method: 'getData', - args: [ - { - type: 'StringLiteral', - value: 'param1', - loc: { - start: { line: 1, col: 58 }, - end: { line: 1, col: 66 }, - }, - }, - { - type: 'BoolLiteral', - value: false, - loc: { - start: { line: 1, col: 68 }, - end: { line: 1, col: 73 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'an-identifier', - loc: { - start: { line: 1, col: 75 }, - end: { line: 1, col: 88 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'me', - args: [], - loc: { - start: { line: 1, col: 90 }, - end: { line: 1, col: 93 }, - }, - }, - ], - loc: { start: { line: 1, col: 40 }, end: { line: 1, col: 94 } }, - }, - { - type: 'ProbableIdentifier', - value: 'anotherIdentifier.open', - loc: { - start: { line: 1, col: 95 }, - end: { line: 1, col: 117 }, - }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 117 } }, - }, - ], - [ - 'load superfluid', - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'ProbableIdentifier', - value: 'superfluid', - loc: { start: { line: 1, col: 5 }, end: { line: 1, col: 15 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 15 } }, - }, - 'invalid `load` command match', - ], - [ - 'load aragonos as ar', - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'aragonos', - loc: { - start: { line: 1, col: 5 }, - end: { line: 1, col: 13 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'ar', - loc: { - start: { line: 1, col: 17 }, - end: { line: 1, col: 19 }, - }, - }, - loc: { start: { line: 1, col: 5 }, end: { line: 1, col: 19 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 19 } }, - }, - ], - [ - `switch gnosis`, - { - type: 'CommandExpression', - name: 'switch', - args: [ - { - type: 'ProbableIdentifier', - value: 'gnosis', - loc: { start: { line: 1, col: 7 }, end: { line: 1, col: 13 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 13 } }, - }, - 'invalid `switch` command match', - ], - [ - `set $new-variable 'a variable'`, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$new-variable', - loc: { start: { line: 1, col: 4 }, end: { line: 1, col: 17 } }, - }, - { - type: 'StringLiteral', - value: 'a variable', - loc: { start: { line: 1, col: 18 }, end: { line: 1, col: 30 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 30 } }, - }, - 'invalid `set` command match', - ], - [ - `mod:no-arg-command`, - { - type: 'CommandExpression', - module: 'mod', - name: 'no-arg-command', - args: [], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 18 } }, - }, - 'invalid command without args match', - ], - ]; - - runCases(cases, commandExpressionParser); - }); - - it('should parse a command with opt args correctly', async () => { - const c: Case = [ - 'example-command myArg1 125.23e18 @aHelper(contract::getSomething(), false) "text" --option1 optionValue --something-else @token(DAI) --anotherOne 1e18', - { - type: 'CommandExpression', - name: 'example-command', - args: [ - { - type: 'ProbableIdentifier', - value: 'myArg1', - loc: { start: { line: 1, col: 16 }, end: { line: 1, col: 22 } }, - }, - { - type: 'NumberLiteral', - value: '125.23', - power: 18, - loc: { start: { line: 1, col: 23 }, end: { line: 1, col: 32 } }, - }, - { - type: 'HelperFunctionExpression', - name: 'aHelper', - args: [ - { - type: 'CallExpression', - target: { - type: 'ProbableIdentifier', - value: 'contract', - loc: { - start: { line: 1, col: 42 }, - end: { line: 1, col: 50 }, - }, - }, - method: 'getSomething', - args: [], - loc: { - start: { line: 1, col: 42 }, - end: { line: 1, col: 66 }, - }, - }, - { - type: 'BoolLiteral', - value: false, - loc: { - start: { line: 1, col: 68 }, - end: { line: 1, col: 73 }, - }, - }, - ], - loc: { start: { line: 1, col: 33 }, end: { line: 1, col: 74 } }, - }, - { - type: 'StringLiteral', - value: 'text', - loc: { start: { line: 1, col: 75 }, end: { line: 1, col: 81 } }, - }, - ], - opts: [ - { - type: 'CommandOpt', - name: 'option1', - value: { - type: 'ProbableIdentifier', - value: 'optionValue', - loc: { - start: { line: 1, col: 92 }, - end: { line: 1, col: 103 }, - }, - }, - loc: { start: { line: 1, col: 82 }, end: { line: 1, col: 103 } }, - }, - { - type: 'CommandOpt', - name: 'something-else', - value: { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'DAI', - loc: { - start: { line: 1, col: 128 }, - end: { line: 1, col: 131 }, - }, - }, - ], - loc: { - start: { line: 1, col: 121 }, - end: { line: 1, col: 132 }, - }, - }, - loc: { start: { line: 1, col: 104 }, end: { line: 1, col: 132 } }, - }, - { - type: 'CommandOpt', - name: 'anotherOne', - value: { - type: 'NumberLiteral', - value: '1', - power: 18, - loc: { - start: { line: 1, col: 146 }, - end: { line: 1, col: 150 }, - }, - }, - loc: { start: { line: 1, col: 133 }, end: { line: 1, col: 150 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 150 } }, - }, - ]; - - runCases(c, commandExpressionParser); - }); - - it('should parse a command with in-between opt args', () => { - const c: Case = [ - `exec 0x9C33eaCc2F50E39940D3AfaF2c7B8246B681A374 --inBetween a::getInfo() 1e18 --another-one @token.balance(GIV, @me) @token(DAI, "see") ( - inside-command @me --t "testing" 25e16 - another-ne token-manager:0 superfluid.open:3 --default true - ) --lastOne false`, - { - type: 'CommandExpression', - name: 'exec', - args: [ - { - type: 'AddressLiteral', - value: '0x9C33eaCc2F50E39940D3AfaF2c7B8246B681A374', - loc: { start: { line: 1, col: 5 }, end: { line: 1, col: 47 } }, - }, - { - type: 'NumberLiteral', - value: '1', - power: 18, - loc: { start: { line: 1, col: 73 }, end: { line: 1, col: 77 } }, - }, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'DAI', - loc: { - start: { line: 1, col: 124 }, - end: { line: 1, col: 127 }, - }, - }, - { - type: 'StringLiteral', - value: 'see', - loc: { - start: { line: 1, col: 129 }, - end: { line: 1, col: 134 }, - }, - }, - ], - loc: { start: { line: 1, col: 117 }, end: { line: 1, col: 135 } }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'inside-command', - args: [ - { - type: 'HelperFunctionExpression', - name: 'me', - args: [], - loc: { - start: { line: 2, col: 25 }, - end: { line: 2, col: 28 }, - }, - }, - { - type: 'NumberLiteral', - value: '25', - power: 16, - loc: { - start: { line: 2, col: 43 }, - end: { line: 2, col: 48 }, - }, - }, - ], - opts: [ - { - type: 'CommandOpt', - name: 't', - value: { - type: 'StringLiteral', - value: 'testing', - loc: { - start: { line: 2, col: 33 }, - end: { line: 2, col: 42 }, - }, - }, - loc: { - start: { line: 2, col: 29 }, - end: { line: 2, col: 42 }, - }, - }, - ], - loc: { - start: { line: 2, col: 10 }, - end: { line: 2, col: 48 }, - }, - }, - { - type: 'CommandExpression', - name: 'another-ne', - args: [ - { - type: 'ProbableIdentifier', - value: 'token-manager:0', - loc: { - start: { line: 3, col: 21 }, - end: { line: 3, col: 36 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'superfluid.open:3', - loc: { - start: { line: 3, col: 37 }, - end: { line: 3, col: 54 }, - }, - }, - ], - opts: [ - { - type: 'CommandOpt', - name: 'default', - value: { - type: 'BoolLiteral', - value: true, - loc: { - start: { line: 3, col: 65 }, - end: { line: 3, col: 69 }, - }, - }, - loc: { - start: { line: 3, col: 55 }, - end: { line: 3, col: 69 }, - }, - }, - ], - loc: { - start: { line: 3, col: 10 }, - end: { line: 3, col: 69 }, - }, - }, - ], - loc: { start: { line: 1, col: 136 }, end: { line: 4, col: 9 } }, - }, - ], - opts: [ - { - type: 'CommandOpt', - name: 'inBetween', - value: { - type: 'CallExpression', - target: { - type: 'ProbableIdentifier', - value: 'a', - loc: { - start: { line: 1, col: 60 }, - end: { line: 1, col: 61 }, - }, - }, - method: 'getInfo', - args: [], - loc: { start: { line: 1, col: 60 }, end: { line: 1, col: 72 } }, - }, - loc: { start: { line: 1, col: 48 }, end: { line: 1, col: 72 } }, - }, - { - type: 'CommandOpt', - name: 'another-one', - value: { - type: 'HelperFunctionExpression', - name: 'token.balance', - args: [ - { - type: 'ProbableIdentifier', - value: 'GIV', - loc: { - start: { line: 1, col: 107 }, - end: { line: 1, col: 110 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'me', - args: [], - loc: { - start: { line: 1, col: 112 }, - end: { line: 1, col: 115 }, - }, - }, - ], - loc: { - start: { line: 1, col: 92 }, - end: { line: 1, col: 116 }, - }, - }, - loc: { start: { line: 1, col: 78 }, end: { line: 1, col: 116 } }, - }, - { - type: 'CommandOpt', - name: 'lastOne', - value: { - type: 'BoolLiteral', - value: false, - loc: { start: { line: 4, col: 20 }, end: { line: 4, col: 25 } }, - }, - loc: { start: { line: 4, col: 10 }, end: { line: 4, col: 25 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 4, col: 25 } }, - }, - ]; - - runCases(c, commandExpressionParser); - }); - - it('should parse a command with trailing whitespaces', () => { - const command = `install wrapper-hooked-token-manager 0x83E57888cd55C3ea1cfbf0114C963564d81e318d false 0`; +describe.concurrent('Parsers - command expression', () => { + const trailingWhitspacesCommand = `install wrapper-hooked-token-manager 0x83E57888cd55C3ea1cfbf0114C963564d81e318d false 0`; - const cases: Case[] = [ - [ - `${command} `, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'wrapper-hooked-token-manager', - loc: { start: { line: 1, col: 8 }, end: { line: 1, col: 36 } }, - }, - { - type: 'AddressLiteral', - value: '0x83E57888cd55C3ea1cfbf0114C963564d81e318d', - loc: { start: { line: 1, col: 37 }, end: { line: 1, col: 79 } }, - }, - { - type: 'BoolLiteral', - value: false, - loc: { start: { line: 1, col: 80 }, end: { line: 1, col: 85 } }, - }, - { - type: 'NumberLiteral', - value: '0', - loc: { start: { line: 1, col: 86 }, end: { line: 1, col: 87 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 87 } }, - }, - 'invalid command match with right whitespaces', - ], - [ - ` ${command}`, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'wrapper-hooked-token-manager', - loc: { start: { line: 1, col: 11 }, end: { line: 1, col: 39 } }, - }, - { - type: 'AddressLiteral', - value: '0x83E57888cd55C3ea1cfbf0114C963564d81e318d', - loc: { start: { line: 1, col: 40 }, end: { line: 1, col: 82 } }, - }, - { - type: 'BoolLiteral', - value: false, - loc: { start: { line: 1, col: 83 }, end: { line: 1, col: 88 } }, - }, - { - type: 'NumberLiteral', - value: '0', - loc: { start: { line: 1, col: 89 }, end: { line: 1, col: 90 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 3 }, end: { line: 1, col: 90 } }, - }, - 'invalid command match with left whitespaces', - ], - [ - `${command.slice(0, 7)} ${command.slice(7, command.length)}`, - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'wrapper-hooked-token-manager', - loc: { start: { line: 1, col: 15 }, end: { line: 1, col: 43 } }, - }, - { - type: 'AddressLiteral', - value: '0x83E57888cd55C3ea1cfbf0114C963564d81e318d', - loc: { start: { line: 1, col: 44 }, end: { line: 1, col: 86 } }, - }, - { - type: 'BoolLiteral', - value: false, - loc: { start: { line: 1, col: 87 }, end: { line: 1, col: 92 } }, - }, - { - type: 'NumberLiteral', - value: '0', - loc: { start: { line: 1, col: 93 }, end: { line: 1, col: 94 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 94 } }, - }, - 'invalid command match with in-between whitespaces', - ], - ]; - - runCases(cases, commandExpressionParser); - }); - - it('should parse commands followed by block expressions', () => { - const c: Case = [ - `forward token-manager voting agent ( - set $agent $finance::vault() - forward wrappable-token-manager.open disputable-voting.open agent ( - sf:batchcall ( - flow create @token(fDAIx) $agent 1e18mo - ) - ) - )`, - { - type: 'CommandExpression', - name: 'forward', - args: [ - { - type: 'ProbableIdentifier', - value: 'token-manager', - loc: { start: { line: 1, col: 8 }, end: { line: 1, col: 21 } }, - }, - { - type: 'ProbableIdentifier', - value: 'voting', - loc: { start: { line: 1, col: 22 }, end: { line: 1, col: 28 } }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { start: { line: 1, col: 29 }, end: { line: 1, col: 34 } }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$agent', - loc: { - start: { line: 2, col: 14 }, - end: { line: 2, col: 20 }, - }, - }, - { - type: 'CallExpression', - target: { - type: 'VariableIdentifier', - value: '$finance', - loc: { - start: { line: 2, col: 21 }, - end: { line: 2, col: 29 }, - }, - }, - method: 'vault', - args: [], - loc: { - start: { line: 2, col: 21 }, - end: { line: 2, col: 38 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 2, col: 10 }, - end: { line: 2, col: 38 }, - }, - }, - { - type: 'CommandExpression', - name: 'forward', - args: [ - { - type: 'ProbableIdentifier', - value: 'wrappable-token-manager.open', - loc: { - start: { line: 3, col: 18 }, - end: { line: 3, col: 46 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'disputable-voting.open', - loc: { - start: { line: 3, col: 47 }, - end: { line: 3, col: 69 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { - start: { line: 3, col: 70 }, - end: { line: 3, col: 75 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - module: 'sf', - name: 'batchcall', - args: [ - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'flow', - args: [ - { - type: 'ProbableIdentifier', - value: 'create', - loc: { - start: { line: 5, col: 19 }, - end: { line: 5, col: 25 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'fDAIx', - loc: { - start: { line: 5, col: 33 }, - end: { line: 5, col: 38 }, - }, - }, - ], - loc: { - start: { line: 5, col: 26 }, - end: { line: 5, col: 39 }, - }, - }, - { - type: 'VariableIdentifier', - value: '$agent', - loc: { - start: { line: 5, col: 40 }, - end: { line: 5, col: 46 }, - }, - }, - { - type: 'NumberLiteral', - value: '1', - power: 18, - timeUnit: 'mo', - loc: { - start: { line: 5, col: 47 }, - end: { line: 5, col: 53 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 5, col: 14 }, - end: { line: 5, col: 53 }, - }, - }, - ], - loc: { - start: { line: 4, col: 25 }, - end: { line: 6, col: 13 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 4, col: 12 }, - end: { line: 6, col: 13 }, - }, - }, - ], - loc: { - start: { line: 3, col: 76 }, - end: { line: 7, col: 11 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 3, col: 10 }, - end: { line: 7, col: 11 }, - }, - }, - ], - loc: { start: { line: 1, col: 35 }, end: { line: 8, col: 9 } }, - }, - ], - opts: [], - loc: { start: { line: 1, col: 0 }, end: { line: 8, col: 9 } }, - }, - ]; - - runCases(c, commandExpressionParser); - }); - - it('should fail when parsing an invalid module name', () => { - runErrorCase(commandExpressionParser, 'asda2345:asd', COMMAND_PARSER_ERROR); + describe.concurrent.each([ + { + title: 'with helper function and call expression', + value: + 'my-command @ipfs("upload this to ipfs") contract::getData("param1", false, an-identifier, @me) anotherIdentifier.open', + }, + { title: 'load', value: 'load superfluid' }, + { title: 'with as expression', value: 'load aragonos as ar' }, + { title: 'switch', value: 'switch gnosis' }, + { title: 'set', value: `set $new-variable 'a variable'` }, + { title: 'without args', value: `mod:no-arg-command` }, + { + title: 'with optional args', + value: `'example-command myArg1 125.23e18 @aHelper(contract::getSomething(), false) "text" --option1 optionValue --something-else @token(DAI) --anotherOne 1e18'`, + }, + { + title: 'with in-between optional args', + value: `exec 0x9C33eaCc2F50E39940D3AfaF2c7B8246B681A374 --inBetween a::getInfo() 1e18 --another-one @token.balance(GIV, @me) @token(DAI, "see") ( + inside-command @me --t "testing" 25e16 + another-ne token-manager:0 superfluid.open:3 --default true + ) --lastOne false`, + }, + { + title: 'with right trailing whitespaces', + value: `${trailingWhitspacesCommand} `, + }, + { + title: 'with left trailing whitespaces', + value: ` ${trailingWhitspacesCommand}`, + }, + { + title: 'with in-between trailing whitespaces', + value: `${trailingWhitspacesCommand.slice( + 0, + 7, + )} ${trailingWhitspacesCommand.slice( + 7, + trailingWhitspacesCommand.length, + )}`, + }, + { + title: 'followed by block experssions', + value: `forward token-manager voting agent ( + set $agent $finance::vault() + forward wrappable-token-manager.open disputable-voting.open agent ( + sf:batchcall ( + flow create @token(fDAIx) $agent 1e18mo + ) + ) + )`, + }, + ])('', ({ title, value }) => { + it(`should parse a command ${title} correctly`, () => { + const parsedValue = runParser(commandExpressionParser, value); + + expect(parsedValue).toMatchSnapshot(); + }); }); - it('should fail when parsing an incomplete command name', () => { - runErrorCase( - commandExpressionParser, - 'my-command:', - COMMAND_PARSER_ERROR, - 'Expecting a valid command name', - ); - }); + describe.concurrent.each([ + { title: 'invalid module name', value: 'asda2345:asd' }, + { title: 'invalid command name', value: 'my-command:wer234' }, + { title: 'incomplete command name', value: 'my-command:' }, + ])('', ({ title, value }) => { + it(`should fail when parsing an ${title}`, () => { + const error = runParserError(commandExpressionParser, value); - it('should fail when parsing an invalid command name', () => { - runErrorCase( - commandExpressionParser, - 'my-command:wer234', - COMMAND_PARSER_ERROR, - 'Expecting a valid command name', - ); + expect(error).toMatchSnapshot(); + }); }); it('should fail when parsing an invalid opt name', () => { - runErrorCase( - commandOptParser, - '--asd$ asd', - COMMAND_PARSER_ERROR, - 'Expecting a valid option name', - ); + const error = runParserError(commandOptParser, '--asd$ asd'); + + expect(error).toMatchSnapshot(); }); }); diff --git a/core/evmcrispr/test/parsers/comment.test.ts b/core/evmcrispr/test/parsers/comment.test.ts index 362be969..18b2d9dc 100644 --- a/core/evmcrispr/test/parsers/comment.test.ts +++ b/core/evmcrispr/test/parsers/comment.test.ts @@ -1,155 +1,34 @@ -import type { Case } from '@1hive/evmcrispr-test-common'; -import { runCases } from '@1hive/evmcrispr-test-common'; +import { runParser } from '@1hive/evmcrispr-test-common'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; import { scriptParser } from '../../src'; describe('Parsers - comment', () => { - it('should parse a comment correctly', () => { - const c: Case = [ - ` - # a comment here - load aragonos as ar + describe.concurrent.each([ + { + title: 'normal', + value: ` + # a comment here + load aragonos as ar - #another one here - set $var1 1e18 + #another one here + set $var1 1e18 - #one at the end - `, - { - type: 'Program', - body: [ - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'aragonos', - loc: { - start: { line: 3, col: 13 }, - end: { line: 3, col: 21 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'ar', - loc: { - start: { line: 3, col: 25 }, - end: { line: 3, col: 27 }, - }, - }, - loc: { - start: { line: 3, col: 13 }, - end: { line: 3, col: 27 }, - }, - }, - ], - opts: [], - loc: { start: { line: 3, col: 8 }, end: { line: 3, col: 27 } }, - }, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$var1', - loc: { - start: { line: 6, col: 12 }, - end: { line: 6, col: 17 }, - }, - }, - { - type: 'NumberLiteral', - value: '1', - power: 18, - loc: { - start: { line: 6, col: 18 }, - end: { line: 6, col: 22 }, - }, - }, - ], - opts: [], - loc: { start: { line: 6, col: 8 }, end: { line: 6, col: 22 } }, - }, - ], - }, - ]; + #one at the end + `, + }, + { + title: 'inline', + value: ` + load aragonos as ar # this is an inline comment + set $var1 1e18 #another one + `, + }, + ])('', ({ title, value }) => { + it(`should parse a ${title} comment correctly`, () => { + const parsedValue = runParser(scriptParser, value); - runCases(c, scriptParser); - }); - - it('should parse an inline comment', () => { - const c: Case = [ - ` - load aragonos as ar # this is an inline comment - set $var1 1e18 #another one - `, - { - type: 'Program', - body: [ - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'aragonos', - loc: { - start: { line: 2, col: 15 }, - end: { line: 2, col: 23 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'ar', - loc: { - start: { line: 2, col: 27 }, - end: { line: 2, col: 29 }, - }, - }, - loc: { - start: { line: 2, col: 15 }, - end: { line: 2, col: 29 }, - }, - }, - ], - opts: [], - loc: { start: { line: 2, col: 10 }, end: { line: 2, col: 29 } }, - }, - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$var1', - loc: { - start: { line: 3, col: 14 }, - end: { line: 3, col: 19 }, - }, - }, - { - type: 'NumberLiteral', - value: '1', - power: 18, - loc: { - start: { line: 3, col: 20 }, - end: { line: 3, col: 24 }, - }, - }, - ], - opts: [], - loc: { start: { line: 3, col: 10 }, end: { line: 3, col: 24 } }, - }, - ], - }, - ]; - - runCases(c, scriptParser); + expect(parsedValue).toMatchSnapshot(); + }); }); }); diff --git a/core/evmcrispr/test/parsers/helper.test.ts b/core/evmcrispr/test/parsers/helper.test.ts index e16071d0..6a6acd8b 100644 --- a/core/evmcrispr/test/parsers/helper.test.ts +++ b/core/evmcrispr/test/parsers/helper.test.ts @@ -1,152 +1,45 @@ -import { runCases, runErrorCase } from '@1hive/evmcrispr-test-common'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; +import { runParser, runParserError } from '@1hive/evmcrispr-test-common'; -import { - HELPER_PARSER_ERROR, - helperFunctionParser, -} from '../../src/parsers/helper'; +import { helperFunctionParser } from '../../src/parsers/helper'; -describe('Parsers - helper function', () => { - it('should parse helpers correctly', () => { - const cases: [string, any, string?][] = [ - [ +describe.concurrent('Parsers - helper functions', () => { + describe.each([ + { + title: '', + value: '@token(WETH)', + }, + { + title: 'with call expression', + value: '@helperFunction(anotherToken::symbol(), "this is a string param", 10e18)', - { - type: 'HelperFunctionExpression', - name: 'helperFunction', - args: [ - { - type: 'CallExpression', - target: { - type: 'ProbableIdentifier', - value: 'anotherToken', - loc: { - start: { line: 1, col: 16 }, - end: { line: 1, col: 28 }, - }, - }, - method: 'symbol', - args: [], - loc: { start: { line: 1, col: 16 }, end: { line: 1, col: 38 } }, - }, - { - type: 'StringLiteral', - value: 'this is a string param', - loc: { start: { line: 1, col: 40 }, end: { line: 1, col: 64 } }, - }, - { - type: 'NumberLiteral', - value: '10', - power: 18, - loc: { start: { line: 1, col: 66 }, end: { line: 1, col: 71 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 72 } }, - }, - 'invalid helper with call expression match', - ], - [ - `@token(WETH)`, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'WETH', - loc: { start: { line: 1, col: 7 }, end: { line: 1, col: 11 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 12 } }, - }, - 'invalid helper match', - ], - [ - `@now`, - { - type: 'HelperFunctionExpression', - name: 'now', - args: [], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 4 } }, - }, - 'invalid helper without args match', - ], - [ - `@token('DAI', @calc(34, @innerHelper(true)))`, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'StringLiteral', - value: 'DAI', - loc: { start: { line: 1, col: 7 }, end: { line: 1, col: 12 } }, - }, - { - type: 'HelperFunctionExpression', - name: 'calc', - args: [ - { - type: 'NumberLiteral', - value: '34', - loc: { - start: { line: 1, col: 20 }, - end: { line: 1, col: 22 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'innerHelper', - args: [ - { - type: 'BoolLiteral', - value: true, - loc: { - start: { line: 1, col: 37 }, - end: { line: 1, col: 41 }, - }, - }, - ], - loc: { - start: { line: 1, col: 24 }, - end: { line: 1, col: 42 }, - }, - }, - ], - loc: { start: { line: 1, col: 14 }, end: { line: 1, col: 43 } }, - }, - ], - loc: { start: { line: 1, col: 0 }, end: { line: 1, col: 44 } }, - }, - 'invalid nested helper match', - ], - ]; + }, + { + title: 'with no arguments', + value: '@now', + }, + { + title: 'with nested helpers', + value: `@token('DAI', @calc(34, @innerHelper(true)))`, + }, + ])('', ({ title, value }) => { + it(`should parse helper ${title} correctly`, () => { + const parsedValue = runParser(helperFunctionParser, value); - runCases(cases, helperFunctionParser); + expect(parsedValue).toMatchSnapshot(); + }); }); - it('should fail when parsing a helper with an invalid name', () => { - runErrorCase( - helperFunctionParser, - '@asd&$6', - HELPER_PARSER_ERROR, - 'Expecting a helper name', - ); - }); - - it.only('should fail when parsing a helper without a closing parenthesis', () => { - runErrorCase( - helperFunctionParser, - '@helper(asda,1e18', - HELPER_PARSER_ERROR, - ); - }); + describe.each([ + { title: 'an invalid name', value: '@asd&$6' }, + { title: 'no closing parenthesis', value: '@helper(asda,1e18' }, + { title: 'no opening parenthesis', value: '@helperarg1, 1e18, ,)' }, + { title: 'empty arguments', value: '@helper(arg1, 1e18, ,)' }, + ])('', ({ title, value }) => { + it(`should fail when parsing a helper with ${title}`, () => { + const error = runParserError(helperFunctionParser, value); - it('should fail when parsing a helper with empty arguments', () => { - runErrorCase( - helperFunctionParser, - '@helper(arg1, 1e18, ,)', - HELPER_PARSER_ERROR, - 'Expecting a valid expression', - ); + expect(error).toMatchSnapshot(); + }); }); }); diff --git a/core/evmcrispr/test/parsers/primary.test.ts b/core/evmcrispr/test/parsers/primary.test.ts index 37712f44..c9bcd108 100644 --- a/core/evmcrispr/test/parsers/primary.test.ts +++ b/core/evmcrispr/test/parsers/primary.test.ts @@ -1,16 +1,7 @@ -import type { Case } from '@1hive/evmcrispr-test-common'; -import { - runCases, - runErrorCase, - runParser, -} from '@1hive/evmcrispr-test-common'; +import type { ForEachCase } from '@1hive/evmcrispr-test-common'; +import { runParser, runParserError } from '@1hive/evmcrispr-test-common'; import { - ADDRESS_PARSER_ERROR, - BOOLEAN_PARSER_ERROR, - PROBABLE_IDENTIFIER_PARSER_ERROR, - STRING_PARSER_ERROR, - VARIABLE_PARSER_ERROR, addressParser, booleanParser, hexadecimalParser, @@ -19,30 +10,8 @@ import { stringParser, variableIdentifierParser, } from '../../src/parsers/primaries'; -import { HEXADECIMAL_PARSER_ERROR } from '../../src/parsers/primaries/literals/hexadecimal'; -import type { - BooleanLiteralNode, - BytesLiteralNode, - Location, - NumericLiteralNode, - ProbableIdentifierNode, - StringLiteralNode, - VariableIdentifierNode, -} from '../../src/types'; -import { NodeType } from '../../src/types'; - -const buildLocation = (value: string): Location => ({ - start: { - line: 1, - col: 0, - }, - end: { - line: 1, - col: value.length, - }, -}); -describe('Parsers - primary', () => { +describe.concurrent('Parsers - primaries', () => { describe('when parsing literal values', () => { describe('when parsing address values', () => { it('should parse them correctly', () => { @@ -51,262 +20,182 @@ describe('Parsers - primary', () => { addressParser(), '0x3aD736904E9e65189c3000c7DD2c8AC8bB7cD4e3', ), - ).to.deep.equal({ - type: 'AddressLiteral', - value: '0x3aD736904E9e65189c3000c7DD2c8AC8bB7cD4e3', - loc: buildLocation('0x3aD736904E9e65189c3000c7DD2c8AC8bB7cD4e3'), - }); + ).to.toMatchSnapshot(); }); it('should fail when parsing an invalid one', () => { - runErrorCase( + const error = runParserError( addressParser(), '0xasdabmtbrtbrtgsdfsvbrty', - ADDRESS_PARSER_ERROR, - 'Expecting an address', ); + + expect(error).toMatchSnapshot(); }); }); describe('when parsing hexadecimal values', () => { - const n = (value: string): BytesLiteralNode => ({ - type: NodeType.BytesLiteral, - value, - loc: buildLocation(value), - }); - it('should parse them correctly', () => { - const cases: Case[] = [ - ['0xa3432da4567be', n('0xa3432da4567be')], - [ + describe.each([ + { + title: 'value', + value: '0xa3432da4567be', + }, + { + title: 'long value', + value: '0x0e80f0b30000000000000000000000008e6cd950ad6ba651f6dd608dc70e5886b1aa6b240000000000000000000000002f00df4f995451e0df337b91744006eb8892bfb10000000000000000000000000000000000000000000000004563918244f40000', - n( - '0x0e80f0b30000000000000000000000008e6cd950ad6ba651f6dd608dc70e5886b1aa6b240000000000000000000000002f00df4f995451e0df337b91744006eb8892bfb10000000000000000000000000000000000000000000000004563918244f40000', - ), - ], - ]; - - runCases(cases, hexadecimalParser()); + }, + ])('', ({ title, value }) => { + it(`should parse a ${title} correctly`, () => { + const parsedValue = runParser(hexadecimalParser(), value); + expect(parsedValue).to.matchSnapshot(); + }); }); - it('should fail when parsing an invalid one', () => { - runErrorCase( + it('should fail when parsing an invalid value', () => { + const error = runParserError( hexadecimalParser(), '0xasdadqlkerrtrtnrn', - HEXADECIMAL_PARSER_ERROR, - 'Expecting a hexadecimal value', ); + + expect(error).toMatchSnapshot(); }); }); describe('when parsing boolean values', () => { - it('should parse them correctly', () => { - const n = (value: boolean): BooleanLiteralNode => ({ - type: NodeType.BoolLiteral, - value, - loc: buildLocation(value ? 'true' : 'false'), + describe.each([ + { title: '"true" value', value: 'true' }, + { title: '"value" value', value: 'false' }, + ])('', ({ title, value }) => { + it(`should parse ${title} correctly`, () => { + const parsedValue = runParser(booleanParser(), value); + + expect(parsedValue).toMatchSnapshot(); }); - - const cases: Case[] = [ - ['true', n(true)], - ['false', n(false)], - ]; - - runCases(cases, booleanParser()); }); - it('should fail when parsing an invalid one', () => { - runErrorCase( - booleanParser(), - 'fals', - BOOLEAN_PARSER_ERROR, - 'Expecting "true" or "false"', - ); + it('should fail when parsing an invalid value', () => { + const error = runParserError(booleanParser(), 'fals'); + + expect(error).toMatchSnapshot(); }); }); describe('when parsing numeric values', () => { - const errorType = 'NumberParserError'; - - it('should parse them correctly', () => { - const node = ( - value: number, - power?: number, - timeUnit?: string, - ): NumericLiteralNode => { - const n: NumericLiteralNode = { - type: NodeType.NumberLiteral, - value: String(value), - loc: buildLocation( - value.toString() + - (power ? power?.toString() + 'e' : '') + - (timeUnit ?? ''), - ), - }; - if (power) n.power = power; - if (timeUnit) n.timeUnit = timeUnit; - - return n; - }; - const cases: Case[] = [ - ['15', node(15)], - ['9200e18', node(9200, 18)], - ['4500.32', node(4500.32)], - ['0.5e14', node(0.5, 14)], - ['20.3245e18mo', node(20.3245, 18, 'mo')], - ['50s', node(50, undefined, 's')], - ['5m', node(5, undefined, 'm')], - ['35h', node(35, undefined, 'h')], - ['365d', node(365, undefined, 'd')], - ['72w', node(72, undefined, 'w')], - ['6.5mo', node(6.5, undefined, 'mo')], - ['2.5y', node(2.5, undefined, 'y')], - ]; - - runCases(cases, numberParser()); - }); - - it('should fail when parsing an incomplete decimal', () => { - runErrorCase( - numberParser(), - '123.e18', - errorType, - 'Invalid decimal. Expecting digits', - ); + describe.each([ + { title: 'integer value', value: '15' }, + { title: 'exponent value', value: '9200e18' }, + { title: 'value with a decimal', value: '4500.32' }, + { title: 'value with a decimal and exponent', value: '0.5e14' }, + { + title: 'value with a decimal, exponent and temporal unit', + value: '20.3245e18mo', + }, + { title: 'value with a secondly temporal unit', value: '50s' }, + { title: 'value with a minutely temporal unit', value: '5m' }, + { title: 'value with an hourly temporal unit', value: '35h' }, + { title: 'value with an daily temporal unit', value: '365d' }, + { title: 'value with an weekly temporal unit', value: '72w' }, + { title: 'value with an monthly temporal unit', value: '6.5mo' }, + { title: 'value with an yearly temporal unit', value: '2.5y' }, + ])('', ({ title, value }) => { + it(`should parse a ${title} correctly`, () => { + const parsedValue = runParser(numberParser(), value); + + expect(parsedValue).toMatchSnapshot(); + }); }); - it('should fail when parsing an incomplete exponent', () => { - () => { - runErrorCase( - numberParser(), - '123.2ew', - errorType, - 'Invalid exponent. Expecting digits', - ); - }; - }); + describe.each([ + { title: 'incomplete decimal', value: '123.e18' }, + { title: 'incomplete exponent', value: '123.2ew' }, + { title: 'invalid time unit', value: '123.45e13w34' }, + ])('', ({ title, value }) => { + it(`should fail when parsing an ${title}`, () => { + const error = runParserError(numberParser(), value); - it('should fail when parsing an invalid time unit', () => { - runErrorCase( - numberParser(), - '123.45e13w34', - errorType, - `Invalid time unit. Expected "s", "m", "h", "d", "w", "mo" or "y"`, - ); + expect(error).toMatchSnapshot(); + }); }); }); describe('when parsing string values', () => { - it('should parse quoted strings', () => { - const node = (value: string): StringLiteralNode => { - const n: StringLiteralNode = { - type: NodeType.StringLiteral, - value, - loc: { - start: { - line: 1, - col: 0, - }, - end: { - line: 1, - col: value.length + 2, - }, - }, - }; - return n; - }; - - const cases: Case[] = [ - [`'a test single quote string'`, node('a test single quote string')], - [`"a test double quote string"`, node('a test double quote string')], - [`'alpha (with beta) ? --'`, node('alpha (with beta) ? --')], - ]; - - runCases(cases, stringParser()); + describe.each([ + { + title: 'a single quote value', + value: `'a test single quote string'`, + }, + { + title: 'a double quote value', + value: `"a test double quote string"`, + }, + { + title: 'a value with special characters', + value: `'alpha (with beta) ? --'`, + }, + ])('', ({ title, value }) => { + it(`should parse a ${title} correctly`, () => { + const parsedValue = runParser(stringParser(), value); + + expect(parsedValue).toMatchSnapshot; + }); }); }); it('should fail when parsing an invalid string', () => { - runErrorCase( - stringParser(), - '"asdadasdasd', - STRING_PARSER_ERROR, - 'Expecting a quoted string', - ); + const error = runParserError(stringParser(), '"asdadasdasd'); + + expect(error).toMatchSnapshot(); }); }); - describe('when parsing identifiers', () => { - it('should parse probable identifier values', () => { - const node = (value: string): ProbableIdentifierNode => { - const n: ProbableIdentifierNode = { - type: NodeType.ProbableIdentifier, - value, - loc: { - start: { - line: 1, - col: 0, - }, - end: { - line: 1, - col: value.length, - }, - }, - }; - - return n; - }; - - [ - 'new', - 'install', - 'aNewAgent', - 'create-flow', - 'create-super-flow-xtreme-aa', - 'my-ens-name.eth', - 'agent.open.0', - 'superfluid-app.other-open:20', - '2015-20-09', - 'aSIgnature(with,some,params)', - 'noParamSignature()', - ].forEach((value) => - expect(runParser(probableIdentifierParser(), value)).to.eql( - node(value), - ), - ); + describe('when parsing probable identifiers', () => { + describe.each([ + { title: '', value: 'new' }, + { title: 'camel case', value: 'aNewAgent' }, + { title: 'kebab case ', value: 'create-flow' }, + { title: 'long kebab case', value: 'create-super-flow-xtreme-aa' }, + { title: 'kebab case with dot', value: 'my-ens-name.eth' }, + { title: 'dots and numbers', value: 'agent.open.0' }, + { title: 'kebab case with colon', value: 'superfluid-app.other-open:20' }, + { title: 'date-like', value: '2015-20-09' }, + { title: 'signature-like', value: 'aSIgnature(with,some,params)' }, + { title: 'no-params-signature-like', value: 'noParamSignature()' }, + ])('', ({ title, value }) => { + it(`should parse a ${title} value correctly`, () => { + const parsedValue = runParser(probableIdentifierParser(), value); + + expect(parsedValue).toMatchSnapshot(); + }); }); it('fail when parsing an invalid identifier', () => { - runErrorCase( - probableIdentifierParser(), - 'asd([[))', - PROBABLE_IDENTIFIER_PARSER_ERROR, - 'Expecting an identifier', - ); + const error = runParserError(probableIdentifierParser(), 'asd([[))'); + + expect(error).toMatchSnapshot(); }); + }); - it('should parse variable values', () => { - const n = (value: string): VariableIdentifierNode => ({ - type: NodeType.VariableIdentifier, - value, - loc: buildLocation(value), + describe('when parsing variable identifiers', () => { + describe.each([ + { title: '', value: '$variable' }, + { title: 'camel case', value: '$aCamelCaseVariable' }, + { title: 'snake case', value: '$a-snake-case-variable' }, + { + title: 'snake case with colon and number', + value: '$token-manager.open:0', + }, + ])('when parsing variable values', ({ title, value }) => { + it(`should parse a ${title} value correctly`, () => { + const parsedValue = runParser(variableIdentifierParser(), value); + + expect(parsedValue).toMatchSnapshot(); }); - const cases: Case[] = [ - ['$variable', n('$variable')], - ['$aCamelCaseVariable', n('$aCamelCaseVariable')], - ['$a-snake-case-variable', n('$a-snake-case-variable')], - ['$token-manager.open:0', n('$token-manager.open:0')], - ]; - - runCases(cases, variableIdentifierParser()); }); it('should fail when parsing invalid variables', () => { - runErrorCase( - variableIdentifierParser(), - '$asd/()', - VARIABLE_PARSER_ERROR, - 'Expecting a variable', - ); + const error = runParserError(variableIdentifierParser(), '$asd/()'); + + expect(error).toMatchSnapshot(); }); }); }); diff --git a/core/evmcrispr/test/parsers/script.test.ts b/core/evmcrispr/test/parsers/script.test.ts index d4cb303a..1ea1bc98 100644 --- a/core/evmcrispr/test/parsers/script.test.ts +++ b/core/evmcrispr/test/parsers/script.test.ts @@ -1,5 +1,4 @@ -import type { Case } from '@1hive/evmcrispr-test-common'; -import { runCases } from '@1hive/evmcrispr-test-common'; +import { runParser } from '@1hive/evmcrispr-test-common'; import { scriptParser } from '../../src/parsers/script'; @@ -54,572 +53,8 @@ describe('Parsers - script', () => { `; + const parsedScript = runParser(scriptParser, script); - const c: Case = [ - script, - { - type: 'Program', - body: [ - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'aragonos', - loc: { - start: { line: 2, col: 11 }, - end: { line: 2, col: 19 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'ar', - loc: { - start: { line: 2, col: 23 }, - end: { line: 2, col: 25 }, - }, - }, - loc: { - start: { line: 2, col: 11 }, - end: { line: 2, col: 25 }, - }, - }, - ], - opts: [], - loc: { start: { line: 2, col: 6 }, end: { line: 2, col: 25 } }, - }, - { - type: 'CommandExpression', - name: 'load', - args: [ - { - type: 'AsExpression', - left: { - type: 'ProbableIdentifier', - value: 'superfluid', - loc: { - start: { line: 3, col: 11 }, - end: { line: 3, col: 21 }, - }, - }, - right: { - type: 'ProbableIdentifier', - value: 'sf', - loc: { - start: { line: 3, col: 25 }, - end: { line: 3, col: 27 }, - }, - }, - loc: { - start: { line: 3, col: 11 }, - end: { line: 3, col: 27 }, - }, - }, - ], - opts: [], - loc: { start: { line: 3, col: 6 }, end: { line: 3, col: 27 } }, - }, - { - type: 'CommandExpression', - module: 'ar', - name: 'connect', - args: [ - { - type: 'ProbableIdentifier', - value: 'my-dao-ens', - loc: { - start: { line: 6, col: 17 }, - end: { line: 6, col: 27 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'forward', - args: [ - { - type: 'ProbableIdentifier', - value: 'token-manager', - loc: { - start: { line: 7, col: 16 }, - end: { line: 7, col: 29 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'voting', - loc: { - start: { line: 7, col: 30 }, - end: { line: 7, col: 36 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'install', - args: [ - { - type: 'ProbableIdentifier', - value: 'wrapper-hooked-token-manager.open', - loc: { - start: { line: 8, col: 18 }, - end: { line: 8, col: 51 }, - }, - }, - { - type: 'AddressLiteral', - value: - '0x83E57888cd55C3ea1cfbf0114C963564d81e318d', - loc: { - start: { line: 8, col: 52 }, - end: { line: 8, col: 94 }, - }, - }, - { - type: 'BoolLiteral', - value: false, - loc: { - start: { line: 8, col: 95 }, - end: { line: 8, col: 100 }, - }, - }, - { - type: 'NumberLiteral', - value: '0', - loc: { - start: { line: 8, col: 101 }, - end: { line: 8, col: 102 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 8, col: 10 }, - end: { line: 8, col: 102 }, - }, - }, - ], - loc: { - start: { line: 7, col: 42 }, - end: { line: 11, col: 9 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 7, col: 8 }, - end: { line: 11, col: 9 }, - }, - }, - { - type: 'CommandExpression', - name: 'forward', - args: [ - { - type: 'ProbableIdentifier', - value: 'token-manager', - loc: { - start: { line: 16, col: 16 }, - end: { line: 16, col: 29 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'voting', - loc: { - start: { line: 16, col: 30 }, - end: { line: 16, col: 36 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { - start: { line: 16, col: 37 }, - end: { line: 16, col: 42 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$agent', - loc: { - start: { line: 18, col: 14 }, - end: { line: 18, col: 20 }, - }, - }, - { - type: 'CallExpression', - target: { - type: 'ProbableIdentifier', - value: 'finance', - loc: { - start: { line: 18, col: 21 }, - end: { line: 18, col: 28 }, - }, - }, - method: 'vault', - args: [], - loc: { - start: { line: 18, col: 21 }, - end: { line: 18, col: 37 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 18, col: 10 }, - end: { line: 18, col: 37 }, - }, - }, - { - type: 'CommandExpression', - name: 'forward', - args: [ - { - type: 'ProbableIdentifier', - value: 'wrappable-token-manager.open', - loc: { - start: { line: 20, col: 18 }, - end: { line: 20, col: 46 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'disputable-voting.open', - loc: { - start: { line: 20, col: 47 }, - end: { line: 20, col: 69 }, - }, - }, - { - type: 'ProbableIdentifier', - value: 'agent', - loc: { - start: { line: 20, col: 70 }, - end: { line: 20, col: 75 }, - }, - }, - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'set', - args: [ - { - type: 'VariableIdentifier', - value: '$daix', - loc: { - start: { line: 21, col: 16 }, - end: { line: 21, col: 21 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'StringLiteral', - value: 'fDAIx', - loc: { - start: { line: 21, col: 29 }, - end: { line: 21, col: 36 }, - }, - }, - ], - loc: { - start: { line: 21, col: 22 }, - end: { line: 21, col: 37 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 21, col: 12 }, - end: { line: 21, col: 37 }, - }, - }, - { - type: 'CommandExpression', - module: 'sf', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'approve', - loc: { - start: { line: 30, col: 21 }, - end: { line: 30, col: 28 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'StringLiteral', - value: 'DAI', - loc: { - start: { line: 30, col: 36 }, - end: { line: 30, col: 41 }, - }, - }, - ], - loc: { - start: { line: 30, col: 29 }, - end: { line: 30, col: 42 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'me', - args: [], - loc: { - start: { line: 30, col: 43 }, - end: { line: 30, col: 46 }, - }, - }, - { - type: 'NumberLiteral', - value: '15.45', - power: 18, - loc: { - start: { line: 30, col: 47 }, - end: { line: 30, col: 55 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 30, col: 12 }, - end: { line: 30, col: 55 }, - }, - }, - { - type: 'CommandExpression', - module: 'sf', - name: 'batchcall', - args: [ - { - type: 'BlockExpression', - body: [ - { - type: 'CommandExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'upgrade', - loc: { - start: { - line: 34, - col: 20, - }, - end: { line: 34, col: 27 }, - }, - }, - { - type: 'VariableIdentifier', - value: '$daix', - loc: { - start: { - line: 34, - col: 28, - }, - end: { line: 34, col: 33 }, - }, - }, - { - type: 'NumberLiteral', - value: '4500.43', - power: 18, - loc: { - start: { - line: 34, - col: 34, - }, - end: { line: 34, col: 44 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 34, col: 14 }, - end: { line: 34, col: 44 }, - }, - }, - { - type: 'CommandExpression', - name: 'flow', - args: [ - { - type: 'ProbableIdentifier', - value: 'create', - loc: { - start: { - line: 35, - col: 19, - }, - end: { line: 35, col: 25 }, - }, - }, - { - type: 'VariableIdentifier', - value: '$daix', - loc: { - start: { - line: 35, - col: 26, - }, - end: { line: 35, col: 31 }, - }, - }, - { - type: 'VariableIdentifier', - value: '$agent', - loc: { - start: { - line: 35, - col: 32, - }, - end: { line: 35, col: 38 }, - }, - }, - { - type: 'NumberLiteral', - value: '1', - power: 18, - timeUnit: 'mo', - loc: { - start: { - line: 35, - col: 39, - }, - end: { line: 35, col: 45 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 35, col: 14 }, - end: { line: 35, col: 45 }, - }, - }, - { - type: 'CommandExpression', - name: 'token', - args: [ - { - type: 'ProbableIdentifier', - value: 'downgrade', - loc: { - start: { - line: 36, - col: 20, - }, - end: { line: 36, col: 29 }, - }, - }, - { - type: 'HelperFunctionExpression', - name: 'token', - args: [ - { - type: 'StringLiteral', - value: 'USDCx', - loc: { - start: { - line: 36, - col: 37, - }, - end: { - line: 36, - col: 44, - }, - }, - }, - ], - loc: { - start: { - line: 36, - col: 30, - }, - end: { line: 36, col: 45 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 36, col: 14 }, - end: { line: 36, col: 45 }, - }, - }, - ], - loc: { - start: { line: 33, col: 25 }, - end: { line: 37, col: 13 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 33, col: 12 }, - end: { line: 37, col: 13 }, - }, - }, - ], - loc: { - start: { line: 20, col: 76 }, - end: { line: 40, col: 11 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 20, col: 10 }, - end: { line: 40, col: 11 }, - }, - }, - ], - loc: { - start: { line: 16, col: 43 }, - end: { line: 43, col: 9 }, - }, - }, - ], - opts: [], - loc: { - start: { line: 16, col: 8 }, - end: { line: 43, col: 9 }, - }, - }, - ], - loc: { - start: { line: 6, col: 28 }, - end: { line: 46, col: 27 }, - }, - }, - ], - opts: [], - loc: { start: { line: 6, col: 6 }, end: { line: 46, col: 27 } }, - }, - ], - }, - ]; - runCases(c, scriptParser); + expect(parsedScript).to.matchSnapshot(); }); });