#[cfg(test)] mod tests { use scilla_parser::parser::parser; macro_rules! check_ok { ($parser:ty, $result:expr) => { let mut errors = vec![]; assert!(<$parser>::new() .parse( &mut errors, scilla_parser::parser::lexer::Lexer::new($result) ) .is_ok()); }; } macro_rules! check_err { ($parser:ty, $result:expr) => { let mut errors = vec![]; assert!(<$parser>::new() .parse( &mut errors, scilla_parser::parser::lexer::Lexer::new($result) ) .is_err()); }; } #[test] fn bytestring_parser() { check_ok!(parser::ByteStringParser, "ByStr1234"); check_ok!(parser::ByteStringParser, "ByStr11"); check_ok!(parser::ByteStringParser, "ByStr0"); check_err!(parser::ByteStringParser, "ByStr 3"); check_err!(parser::ByteStringParser, "ByStr 11"); check_err!(parser::ByteStringParser, "ByStr 0"); check_err!(parser::ByteStringParser, "ByStr"); } #[test] fn type_name_identifier_parser() { check_ok!(parser::TypeNameIdentifierParser, "Event"); check_ok!(parser::TypeNameIdentifierParser, "Foo"); check_ok!(parser::TypeNameIdentifierParser, "ByStr42"); check_err!(parser::TypeNameIdentifierParser, "bystr"); check_err!(parser::TypeNameIdentifierParser, "_foo"); check_err!(parser::TypeNameIdentifierParser, "ByStr 0"); check_err!(parser::TypeNameIdentifierParser, "Type With Spaces"); } #[test] fn imported_name_parser() { check_ok!(parser::ImportedNameParser, "Event"); check_ok!(parser::ImportedNameParser, "Foo"); check_ok!(parser::ImportedNameParser, "ByStr42"); check_ok!(parser::ImportedNameParser, "Event as Alias"); check_ok!(parser::ImportedNameParser, "Foo as Alias"); check_ok!(parser::ImportedNameParser, "ByStr42 as Alias"); check_err!(parser::ImportedNameParser, "foo"); check_err!(parser::ImportedNameParser, "Type With Spaces"); check_err!(parser::ImportedNameParser, "Foo As Alias"); check_err!(parser::ImportedNameParser, "Event as"); } #[test] fn import_declarations() { check_ok!(parser::ImportDeclarationsParser, "import Foo"); check_ok!( parser::ImportDeclarationsParser, "import Event import ByStr42" ); check_ok!(parser::ImportDeclarationsParser, "import Foo as Bar"); check_err!(parser::ImportDeclarationsParser, "foo"); check_err!(parser::ImportDeclarationsParser, "import"); check_err!(parser::ImportDeclarationsParser, "import Foo import"); } #[test] fn meta_identifiers() { check_ok!(parser::MetaIdentifierParser, "Event"); check_ok!(parser::MetaIdentifierParser, "Foo.Bar"); check_ok!(parser::MetaIdentifierParser, "ABCD.Event"); check_ok!(parser::MetaIdentifierParser, "0x1234.Event"); check_ok!(parser::MetaIdentifierParser, "ByStr"); check_err!(parser::MetaIdentifierParser, "_foo"); check_err!(parser::MetaIdentifierParser, "Type With Spaces"); check_err!(parser::MetaIdentifierParser, "Foo .. Bar"); check_err!(parser::MetaIdentifierParser, "0x1234 - Bar"); check_err!(parser::MetaIdentifierParser, "Foo."); check_err!(parser::MetaIdentifierParser, "0x1234.42"); } #[test] fn variable_identifier() { check_ok!(parser::VariableIdentifierParser, "foo"); check_ok!(parser::VariableIdentifierParser, "_bar"); check_ok!(parser::VariableIdentifierParser, "Foo.bar"); check_ok!(parser::VariableIdentifierParser, "ByStr42.baz"); check_ok!(parser::VariableIdentifierParser, "Event.qux"); check_err!(parser::VariableIdentifierParser, "42"); check_err!(parser::VariableIdentifierParser, "_"); check_err!(parser::VariableIdentifierParser, "Type With Spaces.baz"); // check_err!(parser::VariableIdentifierParser, "Bystr.qux"); check_err!(parser::VariableIdentifierParser, "Event42.Bar"); check_err!(parser::VariableIdentifierParser, "Foo."); } #[test] fn builtin_arguments() { check_ok!(parser::BuiltinArgumentsParser, "( )"); check_ok!(parser::BuiltinArgumentsParser, "foo"); check_ok!(parser::BuiltinArgumentsParser, "foo bar baz"); check_ok!(parser::BuiltinArgumentsParser, "Event.qux"); check_err!(parser::BuiltinArgumentsParser, "42"); check_err!(parser::BuiltinArgumentsParser, "_"); check_err!(parser::BuiltinArgumentsParser, "Type With Spaces.baz"); check_err!(parser::BuiltinArgumentsParser, "Event42.Bar"); check_err!(parser::BuiltinArgumentsParser, "Foo."); } #[test] fn scilla_types() { check_ok!(parser::ScillaTypeParser, "Uint32"); check_ok!(parser::ScillaTypeParser, "Foo(Bar)"); check_ok!(parser::ScillaTypeParser, "Map Uint32 String"); check_ok!(parser::ScillaTypeParser, "Uint32 -> Bool"); check_ok!(parser::ScillaTypeParser, "(Uint32)"); check_ok!(parser::ScillaTypeParser, "Address with end"); check_ok!( parser::ScillaTypeParser, "forall 'A. forall 'B. ( 'B -> 'A -> 'B) -> 'B -> List 'A -> 'B" ); check_ok!(parser::ScillaTypeParser, "T"); check_err!(parser::ScillaTypeParser, "Map"); check_err!(parser::ScillaTypeParser, "Uint32 ->"); check_err!(parser::ScillaTypeParser, "-> Bool"); check_err!(parser::ScillaTypeParser, "address with"); check_err!(parser::ScillaTypeParser, "address with Foo end"); check_err!(parser::ScillaTypeParser, "forall T. Map(T, Uint32)"); check_err!(parser::ScillaTypeParser, "Foo(Bar"); } #[test] fn test_address_type() { check_ok!(parser::AddressTypeParser, "Foo with end"); check_ok!(parser::AddressTypeParser, "ByStr42 with end"); check_ok!(parser::AddressTypeParser, "Event with end"); check_ok!( parser::AddressTypeParser, "Foo with contract field field1: Uint32, field field2: Uint32 end" ); check_ok!( parser::AddressTypeParser, "ByStr42 with contract field field1: Uint32 end" ); check_ok!(parser::AddressTypeParser, "Event with contract end"); check_ok!(parser::AddressTypeParser, "Foo with library end"); check_ok!(parser::AddressTypeParser, "ByStr42 with library end"); check_ok!(parser::AddressTypeParser, "Event with library end"); check_ok!(parser::AddressTypeParser, "Foo with _foo end"); check_ok!(parser::AddressTypeParser, "ByStr42 with _foo end"); check_ok!(parser::AddressTypeParser, "Event with _foo end"); check_ok!( parser::AddressTypeParser, "Foo with contract field field1: Uint32 end" ); check_ok!(parser::AddressTypeParser, "ByStr42 with contract field field1: Uint32, field field2: Uint32, field field3: Uint32 end"); check_ok!( parser::AddressTypeParser, "Event with contract field field1: Uint32 end" ); check_err!(parser::AddressTypeParser, "foo with end"); check_err!(parser::AddressTypeParser, "Foo with "); check_err!(parser::AddressTypeParser, "Foo with foo bar: Uint32 end"); check_err!( parser::AddressTypeParser, "Foo with contract field1: Uint32, field2: Uint32" ); check_err!(parser::AddressTypeParser, "Foo with contract, end"); } #[test] fn test_type_map_key() { check_ok!(parser::TypeMapKeyParser, "Foo"); check_ok!(parser::TypeMapKeyParser, "(Foo)"); check_ok!(parser::TypeMapKeyParser, "Foo with end"); check_ok!(parser::TypeMapKeyParser, "(Foo with end)"); check_ok!(parser::TypeMapKeyParser, "(ByStr42 with contract end)"); check_ok!(parser::TypeMapKeyParser, "Foo with library end"); check_err!(parser::TypeMapKeyParser, "foo"); check_err!(parser::TypeMapKeyParser, "Foo()"); check_err!(parser::TypeMapKeyParser, "(Foo with bar end)"); check_err!(parser::TypeMapKeyParser, "(42)"); } #[test] fn type_map_value() { check_ok!(parser::TypeMapValueParser, "Uint32"); check_ok!(parser::TypeMapValueParser, "Map Foo Bar"); check_ok!(parser::TypeMapValueParser, "(Uint32)"); check_ok!(parser::TypeMapValueParser, "Address with end"); check_ok!( parser::TypeMapValueParser, "Foo with contract field field1: Uint32 end" ); check_err!(parser::TypeMapValueParser, "foo"); check_err!(parser::TypeMapValueParser, "bystr1"); check_err!(parser::TypeMapValueParser, "event"); check_err!(parser::TypeMapValueParser, "map(foo, bar)"); check_err!(parser::TypeMapValueParser, "(42)"); check_err!(parser::TypeMapValueParser, "address with"); check_err!(parser::TypeMapValueParser, "foo with foo bar"); } #[test] fn type_map_value_arguments() { check_ok!(parser::TypeMapValueArgumentsParser, "(Uint32)"); check_ok!(parser::TypeMapValueArgumentsParser, "Foo"); check_ok!(parser::TypeMapValueArgumentsParser, "Map Foo Bar"); check_err!(parser::TypeMapValueArgumentsParser, "Foo Bar"); check_err!(parser::TypeMapValueArgumentsParser, "map(foo, bar)"); check_err!(parser::TypeMapValueArgumentsParser, "(42)()"); check_err!(parser::TypeMapValueArgumentsParser, "(Uint32"); check_err!(parser::TypeMapValueArgumentsParser, "Map(Foo)"); check_err!(parser::TypeMapValueArgumentsParser, "Map(Foo, Bar)"); } #[test] fn type_argument() { check_ok!(parser::TypeArgumentParser, "Foo"); check_ok!(parser::TypeArgumentParser, "(Bar)"); check_ok!(parser::TypeArgumentParser, "Uint32"); check_ok!(parser::TypeArgumentParser, "'A"); check_ok!(parser::TypeArgumentParser, "(Uint32)"); check_ok!( parser::TypeArgumentParser, "Address with contract field field1: Uint32, field field2: Uint32 end" ); check_ok!(parser::TypeArgumentParser, "Map Uint32 Bool"); check_err!(parser::TypeArgumentParser, "foo bar"); check_err!(parser::TypeArgumentParser, "123"); check_err!(parser::TypeArgumentParser, "foo.bar"); check_err!(parser::TypeArgumentParser, "mapUint32Uint32"); check_err!(parser::TypeArgumentParser, "'_A"); check_err!(parser::TypeArgumentParser, "(map(Int32, String))"); check_err!(parser::TypeArgumentParser, "Foo.bar"); check_err!(parser::TypeArgumentParser, "Map(Int32, String, Bool)"); } #[test] fn full_expressions() { check_ok!(parser::FullExpressionParser, "let x = Int32 42 in X"); check_ok!(parser::FullExpressionParser, "let x: Int32 = Int32 42 in X"); check_ok!( parser::FullExpressionParser, "let x = Uint128 42 in builtin lt x x" ); check_ok!( parser::FullExpressionParser, "fun (x: Int32) => builtin lt x x" ); check_ok!(parser::FullExpressionParser, "fun (x: Int32) => foo"); check_ok!(parser::FullExpressionParser, "foo"); check_ok!(parser::FullExpressionParser, "foo bar baz"); check_ok!(parser::FullExpressionParser, "UInt32 42"); check_ok!(parser::FullExpressionParser, "true"); check_ok!(parser::FullExpressionParser, "builtin blabla a b"); check_ok!( parser::FullExpressionParser, "{ foo: UInt32 42; bar: Int64 23 }" ); check_ok!( parser::FullExpressionParser, "match foo with \n| False => True \n| _ => False \nend" ); check_ok!(parser::FullExpressionParser, "Foo"); check_ok!(parser::FullExpressionParser, "Foo m n"); check_ok!(parser::FullExpressionParser, "tfun 'T => fun (x: 'T) => x"); check_ok!(parser::FullExpressionParser, "@foo Type"); check_err!(parser::FullExpressionParser, "let 42 = x in x"); check_err!(parser::FullExpressionParser, "let x: = 42 in x"); check_err!(parser::FullExpressionParser, "fun x => x + 1"); check_err!(parser::FullExpressionParser, "42foo"); check_err!(parser::FullExpressionParser, "42.foo"); check_err!(parser::FullExpressionParser, "42.23"); check_err!(parser::FullExpressionParser, "builtin noop"); check_err!(parser::FullExpressionParser, "{ foo = 42; bar: 23 }"); check_err!(parser::FullExpressionParser, "{ foo: 42, bar = 23 }"); check_err!(parser::FullExpressionParser, "{ foo = 42, }"); check_err!( parser::FullExpressionParser, "match foo with | 42 => true end" ); check_err!(parser::FullExpressionParser, "Foo()"); check_err!(parser::FullExpressionParser, "tfun T => Foo"); check_err!(parser::FullExpressionParser, "@foo()"); } #[test] fn atomic_expression() { check_ok!(parser::AtomicExpressionParser, "foo"); check_ok!(parser::AtomicExpressionParser, "Uint32 42"); check_ok!(parser::AtomicExpressionParser, "0x123abc"); check_ok!(parser::AtomicExpressionParser, r#""string""#); check_err!(parser::AtomicExpressionParser, "(foo)"); check_err!(parser::AtomicExpressionParser, "42.0"); check_err!(parser::AtomicExpressionParser, "True"); } #[test] fn value_literal() { check_ok!(parser::AtomicExpressionParser, "foo"); check_ok!(parser::AtomicExpressionParser, "Uint32 42"); check_ok!(parser::AtomicExpressionParser, "0x123abc"); check_ok!(parser::AtomicExpressionParser, r#""string""#); check_err!(parser::AtomicExpressionParser, "(foo)"); check_err!(parser::AtomicExpressionParser, "42.0"); check_err!(parser::AtomicExpressionParser, "True"); } #[test] fn map_access() { check_ok!(parser::MapAccessParser, "[foo]"); check_ok!(parser::MapAccessParser, "[bar123]"); check_ok!(parser::MapAccessParser, "[_result]"); check_err!(parser::MapAccessParser, "[0x0232]"); check_err!(parser::MapAccessParser, r#"["xx"]"#); check_err!(parser::MapAccessParser, "[Foo]"); check_err!(parser::MapAccessParser, "[]"); check_err!(parser::MapAccessParser, "[foo.bar]"); } #[test] fn pattern() { check_ok!(parser::PatternParser, "_"); check_ok!(parser::PatternParser, "foo"); check_ok!(parser::PatternParser, "Bar42"); check_ok!(parser::PatternParser, "Bar42 _"); check_ok!(parser::PatternParser, "Bar42 hello"); check_ok!(parser::PatternParser, "Bar42(_)"); check_ok!(parser::PatternParser, "Bar42(Foo)"); check_ok!(parser::PatternParser, "Bar42(Foo Bar)"); check_ok!(parser::PatternParser, "Bar42(ByStr42 Int32)"); check_ok!(parser::PatternParser, "Bar42(Foo.Bar Bar.Baz)"); check_err!(parser::PatternParser, "_ _"); check_err!(parser::PatternParser, "42Bar"); check_err!(parser::PatternParser, "foo bar"); check_err!(parser::PatternParser, "Foo42(, Bar)"); check_err!(parser::PatternParser, "Foo42(Map, Bar)"); check_err!(parser::PatternParser, "Bar42(Map ByStr42 Int32)"); } #[test] fn argument_pattern() { check_ok!(parser::ArgumentPatternParser, "_"); check_ok!(parser::ArgumentPatternParser, "foo"); check_ok!(parser::ArgumentPatternParser, "MyType"); check_ok!(parser::ArgumentPatternParser, "(baz)"); check_ok!(parser::ArgumentPatternParser, "(Bar42 _)"); check_ok!(parser::ArgumentPatternParser, "my_type"); check_err!(parser::ArgumentPatternParser, "2bar"); check_err!(parser::ArgumentPatternParser, "MyType()"); check_err!(parser::ArgumentPatternParser, "(2bar)"); } #[test] fn pattern_match_expression_clause() { check_ok!( parser::PatternMatchExpressionClauseParser, "| _ => Uint32 42" ); check_ok!( parser::PatternMatchExpressionClauseParser, "| Foo => Uint32 42" ); check_ok!( parser::PatternMatchExpressionClauseParser, "| Foo _ Bar => Uint32 42" ); check_ok!( parser::PatternMatchExpressionClauseParser, "| Bar _ => Uint32 42" ); check_ok!( parser::PatternMatchExpressionClauseParser, "| Bar _ => Int32 -1" ); check_ok!( parser::PatternMatchExpressionClauseParser, "| Foo _ => let x = Uint32 1 in x" ); check_err!(parser::PatternMatchExpressionClauseParser, "| Foo =>"); check_err!(parser::PatternMatchExpressionClauseParser, "| => 42"); check_err!(parser::PatternMatchExpressionClauseParser, "| _ => "); check_err!(parser::PatternMatchExpressionClauseParser, "| () => 42"); check_err!( parser::PatternMatchExpressionClauseParser, "| Foo + Bar => 42" ); } #[test] fn message_entry() { check_ok!(parser::MessageEntryParser, "foo: Uint32 42"); check_ok!(parser::MessageEntryParser, "foo: bar"); check_ok!(parser::MessageEntryParser, "foo: 0x1337"); check_err!(parser::MessageEntryParser, "foo"); check_err!(parser::MessageEntryParser, "foo: bar: baz"); check_err!(parser::MessageEntryParser, ": 42"); } #[test] fn test_type_annotation() { check_ok!(parser::TypeAnnotationParser, ": Int"); check_ok!(parser::TypeAnnotationParser, ": MyTypeOrEnumLikeIdentifier"); check_ok!(parser::TypeAnnotationParser, ": ByStr32"); check_ok!(parser::TypeAnnotationParser, ": (Map ByStr32 Uint32)"); check_ok!( parser::TypeAnnotationParser, ": (Map ByStr32 (Map ByStr32 Uint32))" ); check_ok!( parser::TypeAnnotationParser, ": (List MyTypeOrEnumLikeIdentifier)" ); check_ok!( parser::TypeAnnotationParser, ": (Pair MyTypeOrEnumLikeIdentifier1 MyTypeOrEnumLikeIdentifier2)" ); check_ok!( parser::TypeAnnotationParser, ": (Pair (Pair Int Bool) (List MyTypeOrEnumLikeIdentifier))" ); check_err!( parser::TypeAnnotationParser, ": MyTypeOrEnumLikeIdentifier (" ); check_err!( parser::TypeAnnotationParser, ": (Map MyTypeOrEnumLikeIdentifier)" ); check_err!( parser::TypeAnnotationParser, ": (Pair MyTypeOrEnumLikeIdentifier1 MyTypeOrEnumLikeIdentifier2" ); check_err!(parser::TypeAnnotationParser, "Int"); check_err!(parser::TypeAnnotationParser, ": 42"); } #[test] fn typed_identifier() { check_ok!(parser::TypedIdentifierParser, "foo: Int"); check_ok!(parser::TypedIdentifierParser, "bar: ByStr20"); check_ok!(parser::TypedIdentifierParser, "baz: (Int Bool)"); check_err!(parser::TypedIdentifierParser, "1foo: Int"); check_err!(parser::TypedIdentifierParser, "foo: int"); check_err!(parser::TypedIdentifierParser, "foo: (,)"); } #[test] fn test_statement() { check_ok!(parser::StatementParser, "foo <- bar"); check_ok!(parser::StatementParser, "remoteFetchStatement"); check_ok!(parser::StatementParser, "foo := bar"); check_ok!(parser::StatementParser, "foo = Uint32 42"); check_ok!(parser::StatementParser, "foo <- &Event"); check_ok!(parser::StatementParser, "foo <- qux[baz]"); check_ok!(parser::StatementParser, "foo <- exists baz[bar]"); check_ok!(parser::StatementParser, "foo[bar] := qux"); check_ok!(parser::StatementParser, "delete foo[bar]"); check_ok!(parser::StatementParser, "accept"); check_ok!(parser::StatementParser, "send foo"); check_ok!(parser::StatementParser, "event foo"); check_ok!(parser::StatementParser, "throw"); check_ok!( parser::StatementParser, "match foo with | False => True | _ => False end" ); check_ok!(parser::StatementParser, "match foo with | _ => value end"); check_ok!(parser::StatementParser, "Foo bar baz"); check_ok!(parser::StatementParser, "forall foo Event"); check_err!(parser::StatementParser, "foo < bar"); check_err!(parser::StatementParser, "42 = foo"); check_err!(parser::StatementParser, "&Event"); check_err!(parser::StatementParser, "foo[] <- bar"); check_err!(parser::StatementParser, "foo <- exists"); check_err!(parser::StatementParser, "foo[] := bar"); check_err!(parser::StatementParser, "foo := qux[bar][baz]"); check_err!(parser::StatementParser, "foo.delete[bar]"); check_err!(parser::StatementParser, "send"); check_err!(parser::StatementParser, "event"); check_err!(parser::StatementParser, "match with _ => 42 end"); check_err!(parser::StatementParser, "forall"); } #[test] fn blockchain_fetch_arguments() { check_ok!(parser::BlockchainFetchArgumentsParser, "(foo bar)"); check_ok!(parser::BlockchainFetchArgumentsParser, "(x)"); check_ok!(parser::BlockchainFetchArgumentsParser, "(y z a)"); check_err!(parser::BlockchainFetchArgumentsParser, "()"); check_err!(parser::BlockchainFetchArgumentsParser, "(123)"); check_err!(parser::BlockchainFetchArgumentsParser, "(foo, 123)"); check_err!(parser::BlockchainFetchArgumentsParser, "foo, bar"); check_err!(parser::BlockchainFetchArgumentsParser, "(foo; bar)"); check_err!(parser::BlockchainFetchArgumentsParser, "foo"); } #[test] fn statement_block() { check_ok!(parser::StatementBlockParser, "x <- y; z := a"); check_ok!(parser::StatementBlockParser, "accept"); check_ok!(parser::StatementBlockParser, "send x"); check_ok!(parser::StatementBlockParser, "event myEvent"); check_ok!( parser::StatementBlockParser, "match x with | _ => accept end" ); check_ok!( parser::StatementBlockParser, "match x with | _ => y <- z end" ); check_ok!(parser::StatementBlockParser, "MyComponent y"); check_ok!( parser::StatementBlockParser, "MyComponent y; forall foo Event ; match x with | _ => y <- z end" ); check_err!(parser::StatementBlockParser, "x < y"); check_err!(parser::StatementBlockParser, "x <-"); check_err!(parser::StatementBlockParser, "accept event"); check_err!(parser::StatementBlockParser, "send"); check_err!(parser::StatementBlockParser, "match x with _ => accept end"); check_err!(parser::StatementBlockParser, "MyComponent X"); check_err!(parser::StatementBlockParser, "MyComponent y forall x"); } #[test] fn parameter_pair() { check_ok!(parser::ParameterPairParser, "foo: Uint32"); check_ok!(parser::ParameterPairParser, "bar: Bool"); check_ok!(parser::ParameterPairParser, "baz: Address"); check_ok!(parser::ParameterPairParser, "qux: Map Uint32 Bool"); check_err!(parser::ParameterPairParser, "foo Uint32"); check_err!(parser::ParameterPairParser, "foo"); check_err!(parser::ParameterPairParser, "123: Uint32"); check_err!(parser::ParameterPairParser, "foo: bar: Uint32"); check_err!(parser::ParameterPairParser, "foo: uint32"); check_err!(parser::ParameterPairParser, "foo: mapUint32, Bool"); } #[test] fn component_definition() { check_ok!( parser::ComponentDefinitionParser, "transition myTransition(param1: Uint32, param2: Uint32) end" ); check_ok!( parser::ComponentDefinitionParser, "procedure myProcedure(param: Uint32) end" ); check_ok!( parser::ComponentDefinitionParser, "procedure myProcedure(param: Map ByStr32 ByStr32) param end" ); check_ok!( parser::ComponentDefinitionParser, "transition myTransition(param: Bool) match param with | False => True | _ => False end end" ); check_err!(parser::ComponentDefinitionParser, "transition myTransition"); check_err!( parser::ComponentDefinitionParser, "procedure myProcedure() returns Uint32" ); check_err!( parser::ComponentDefinitionParser, "procedure myProcedure(param: Uint32) returns Uint32 {" ); check_err!( parser::ComponentDefinitionParser, "transition myTransition() { state_1 -> state_2 }" ); check_err!( parser::ComponentDefinitionParser, "transition myTransition(param1: Uint32 param2: Uint32)" ); } #[test] fn procedure_definition() { check_ok!(parser::ProcedureDefinitionParser, "procedure foo() end"); check_ok!( parser::ProcedureDefinitionParser, "procedure bar(x: Int32, y: Uint32) baz x y end" ); check_err!(parser::ProcedureDefinitionParser, "procedure 42() { }"); check_err!(parser::ProcedureDefinitionParser, "procedure foo(x, y) { }"); check_err!( parser::ProcedureDefinitionParser, "procedure foo(x: Int32, y: Uint32)" ); check_err!( parser::ProcedureDefinitionParser, "procedure foo(x: Int32, y: Uint32) foo x y" ); check_err!(parser::ProcedureDefinitionParser, "procedure foo() {}"); } #[test] fn transition_definition() { check_ok!( parser::TransitionDefinitionParser, "transition foo() bar end" ); check_ok!( parser::TransitionDefinitionParser, "transition bar(x: Int32, y: Uint32) foo end" ); check_ok!( parser::TransitionDefinitionParser, "transition qux(bar: Bool) bar end" ); check_ok!(parser::TransitionDefinitionParser, "transition empty() end"); check_err!( parser::TransitionDefinitionParser, "transition 123() { foo() }" ); check_err!( parser::TransitionDefinitionParser, "transition foo(bar) { foo() }" ); check_err!( parser::TransitionDefinitionParser, "transition foo() { foo(); bar() }" ); check_err!( parser::TransitionDefinitionParser, "transaction foo() { bar() }" ); check_err!( parser::TransitionDefinitionParser, "transition foo() { bar }" ); check_err!( parser::TransitionDefinitionParser, "transition foo() { bar( }" ); check_err!( parser::TransitionDefinitionParser, "transition foo() { bar() };" ); check_err!(parser::TransitionDefinitionParser, "transition foo() { ; }"); } #[test] fn component_id() { check_ok!(parser::ComponentIdParser, "MyType"); check_ok!(parser::ComponentIdParser, "Event42"); check_ok!(parser::ComponentIdParser, "Foo_Bar"); check_ok!(parser::ComponentIdParser, "ByStr42"); check_ok!(parser::ComponentIdParser, "regular_id"); check_err!(parser::ComponentIdParser, "42Event"); check_err!(parser::ComponentIdParser, "my type"); check_err!(parser::ComponentIdParser, "event+"); check_err!(parser::ComponentIdParser, "ByStr"); } #[test] fn component_parameters() { check_ok!(parser::ComponentParametersParser, "()"); check_ok!(parser::ComponentParametersParser, "(a: Int32)"); check_ok!(parser::ComponentParametersParser, "(a: Int32, b: Bool)"); check_ok!( parser::ComponentParametersParser, "(a: Int32, b: Bool, c: String)" ); check_ok!( parser::ComponentParametersParser, "(a: ByStr20, b: Map ByStr20 (Uint256))" ); check_err!(parser::ComponentParametersParser, "a: Int32, b: Bool"); check_err!(parser::ComponentParametersParser, "(a: Int32"); check_err!(parser::ComponentParametersParser, "(a: Int32,, b: Bool)"); check_err!(parser::ComponentParametersParser, "(())"); check_err!(parser::ComponentParametersParser, "(a: )"); } #[test] fn component_body() { check_ok!( parser::ComponentBodyParser, " RequireNotPaused; RequireContractOwner; is_paused := true; e = { _eventname: \"Pause\"; is_paused: true }; event e end " ); check_ok!( parser::ComponentBodyParser, " RequirePaused; RequireContractOwner; is_paused := false; e = { _eventname: \"Unpause\"; is_paused: false }; event e end " ); check_ok!(parser::ComponentBodyParser, " current_init <-& init.dApp; xPointsDApp = \"xpoints\"; get_addr <-& current_init.dns[xPointsDApp]; addr = option_bystr20_value get_addr; is_xPoints = builtin eq _sender addr; match is_xPoints with | True => | False => e = { _exception : \"donate.tyron-WrongCaller\" }; throw e end; get_xPoints <- xpoints[_origin]; x_points = option_uint128_value get_xPoints; IsSufficient x_points amount; new_bal = builtin sub x_points amount; xpoints[_origin] := new_bal end "); } #[test] fn contract_fields() { check_ok!(parser::ContractFieldParser, "field foo: Int32 = Int32 42"); check_ok!( parser::ContractFieldParser, "field bar: Map ByStr32 (List Uint32) = Emp ByStr32 (List Uint32)" ); check_ok!(parser::ContractFieldParser, "field baz: Event = Event"); check_err!(parser::ContractFieldParser, "field: Foo = Bar"); check_err!(parser::ContractFieldParser, "field bar = 42"); check_err!(parser::ContractFieldParser, "field baz: Event = 42"); check_err!(parser::ContractFieldParser, "field qux = 'hello world'"); } #[test] fn test_with_constraint() { check_ok!( parser::WithConstraintParser, "with builtin blt end_of_life =>" ); check_ok!( parser::WithConstraintParser, "with builtin add {UInt32} one =>" ); check_ok!(parser::WithConstraintParser, "with true =>"); check_ok!(parser::WithConstraintParser, "with variableIdentifier =>"); check_err!(parser::WithConstraintParser, "foo"); check_err!( parser::WithConstraintParser, "with variableIdentifier => foo" ); check_err!(parser::WithConstraintParser, "with =>"); check_err!(parser::WithConstraintParser, "with"); } #[test] fn contract_definition() { check_ok!(parser::ContractDefinitionParser, "contract MyContract()"); check_ok!( parser::ContractDefinitionParser, "contract MyContract(address: ByStr20)" ); check_ok!( parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true =>" ); check_ok!( parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1: Uint32 = Uint32 1" ); check_ok!(parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1: Uint32 = Uint32 1 transition a() end"); check_ok!(parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1: Uint32 = Uint32 1 procedure a() end"); check_ok!( parser::ContractDefinitionParser, r#"contract MyContract(address: ByStr20) with true => field field1: Uint32 = Uint32 1 procedure RequireNotSelf(address: ByStr20) is_self = builtin eq address _sender; match is_self with | False => | True => error = SelfError; Throw error end end"# ); check_err!(parser::ContractDefinitionParser, "contract MyContract"); check_err!(parser::ContractDefinitionParser, "contract MyContract end"); check_err!(parser::ContractDefinitionParser, "Contract MyContract"); check_err!(parser::ContractDefinitionParser, "contract"); check_err!( parser::ContractDefinitionParser, "contract MyContract(address: ByStr20,) with (true =>)" ); check_err!( parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1 = 1" ); check_err!( parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1: = 1" ); check_err!( parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1: Uint32 = 1 field2: 10" ); check_err!(parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1: Uint32 = 1 transition a(Void) {}"); check_err!(parser::ContractDefinitionParser, "contract MyContract(address: ByStr20) with true => field field1: Uint32 = 1 procedure a(Void) {"); } #[test] fn type_alternative_clause() { check_ok!(parser::TypeAlternativeClauseParser, "| MyType"); check_ok!(parser::TypeAlternativeClauseParser, "| MyType of Int"); check_ok!( parser::TypeAlternativeClauseParser, "| ByStr123 of Map MyType Int" ); check_err!(parser::TypeAlternativeClauseParser, "| MyType of"); check_err!(parser::TypeAlternativeClauseParser, "| 123MyType"); check_err!(parser::TypeAlternativeClauseParser, "| ByStr"); } #[test] fn library_single_definition() { check_ok!(parser::LibrarySingleDefinitionParser, "let foo = Int32 42"); check_ok!( parser::LibrarySingleDefinitionParser, "let foo: Int32 = Int32 42" ); check_ok!(parser::LibrarySingleDefinitionParser, "type Foo"); check_ok!( parser::LibrarySingleDefinitionParser, "type Foo = | Bar | Baz" ); check_err!(parser::LibrarySingleDefinitionParser, "let = Int32 42"); check_err!(parser::LibrarySingleDefinitionParser, "let foo: = 42"); check_err!(parser::LibrarySingleDefinitionParser, "type Int32 42"); check_err!( parser::LibrarySingleDefinitionParser, "type Foo = | Bar Baz" ); } #[test] fn library_definition() { check_ok!(parser::LibraryDefinitionParser, "library Foo"); check_ok!( parser::LibraryDefinitionParser, "library Bar let x = Int32 10" ); check_ok!(parser::LibraryDefinitionParser, "library Baz type Quux"); check_ok!( parser::LibraryDefinitionParser, "library Qux type Quux = | Event" ); check_ok!( parser::LibraryDefinitionParser, "library Quux type Quux = | Event of Uint256" ); check_ok!( parser::LibraryDefinitionParser, "library Quuz type Quux = | Event of Uint256 | AnotherEvent of ByStr20" ); check_ok!( parser::LibraryDefinitionParser, "library Qoorx let x: Int32 = Int32 42" ); check_err!(parser::LibraryDefinitionParser, "library Foo Bar"); check_err!(parser::LibraryDefinitionParser, "library"); check_err!(parser::LibraryDefinitionParser, "library Foo bar"); check_err!(parser::LibraryDefinitionParser, "library Foo type"); check_err!( parser::LibraryDefinitionParser, "library Foo type = | Event" ); check_err!(parser::LibraryDefinitionParser, "library Foo type Quux ="); check_err!(parser::LibraryDefinitionParser, "library Foo type Quux = |"); check_err!( parser::LibraryDefinitionParser, "library Foo type Quux = | Event of" ); check_err!(parser::LibraryDefinitionParser, "library Foo let"); check_err!(parser::LibraryDefinitionParser, "library Foo let x"); check_err!(parser::LibraryDefinitionParser, "library Foo let = 42"); } }