diff --git a/src/lex_4_25.rs b/src/lex_4_25.rs index b525f46..2a359f5 100644 --- a/src/lex_4_25.rs +++ b/src/lex_4_25.rs @@ -493,6 +493,10 @@ pub fn to_identifier(string: &str) -> Token { return Token::Identifier(string.to_string()); } +pub fn to_version(string: &str) -> Token { + return Token::Version(string.to_string()); +} + pub fn to_string_literal(string: &str) -> Token { return Token::StringLiteral(string.to_string()); } diff --git a/src/lib.rs b/src/lib.rs index 09cf08d..fa1561a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ pub mod lex_4_25; pub mod parse_4_25; +pub mod utils; \ No newline at end of file diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..fa4ef00 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,102 @@ +use std::fmt::Debug; +use super::lex_4_25; +use super::parse_4_25; + +pub mod test_utils { + use super::*; + + /** + * Fail a test, panicing and printing expected and actual values + */ + pub fn fail_test(expect: T, actual: T) { + panic!("\nExpected: {:#?} \nActual: {:#?}\n", expect, actual) + } + + pub mod lexer { + use super::lex_4_25; + + /** + * Advance cur in string using next_token, and check that the return matches + * the expected Token. If not, the test fails. + */ + pub fn expect_next_token(string: &Vec, cur: &mut usize, token: lex_4_25::Token) { + match lex_4_25::next_token(&string, cur) { + ref next if *next == token => (), + actual => super::fail_test(token, actual) + }; + } + } + + pub mod parser { + use super::lex_4_25; + use super::parse_4_25; + + /** + * Returns a Token as a ParseNode with no children + */ + pub fn as_leaf(token: lex_4_25::Token) -> Box { + Box::new(token.to_leaf()) + } + + /** + * Returns a ParseNode with the given Token serving as the node, and + * a passed-in array of children as the node's children. + */ + pub fn as_node(node: lex_4_25::Token, children: Vec>) -> Box { + Box::new(parse_4_25::ParseNode { + node, + children + }) + } + + /** + * Returns a ParseNode with the given Token and children, but does + * not wrap the ParseNode in a Box + */ + pub fn as_node_raw(node: lex_4_25::Token, children: Vec>) -> parse_4_25::ParseNode { + parse_4_25::ParseNode { + node, + children + } + } + + /** + * Given an array of children, returns their ParseTree + */ + pub fn as_tree(children: Vec) -> parse_4_25::ParseTree { + parse_4_25::ParseTree { + children + } + } + + /** + * Shorthand for parse(String::from("str-input")). Calls + * parse_4_25::parse and returns the resulting ParseTree + */ + pub fn parse_str(string: &str) -> parse_4_25::ParseTree { + parse_4_25::parse(String::from(string)) + } + + /** + * Given two ParseTrees, checks for equality. If unequal, + * panics and prints the prettified trees. + */ + pub fn expect_tree_eq(expect: parse_4_25::ParseTree, actual: parse_4_25::ParseTree) { + match expect == actual { + true => (), + false => super::fail_test(expect, actual) + } + } + + /** + * Given two ParseNodes, checks for equality. If unequal, + * panics and prints the prettified nodes. + */ + pub fn expect_node_eq(expect: parse_4_25::ParseNode, actual: parse_4_25::ParseNode) { + match expect == actual { + true => (), + false => super::fail_test(expect, actual) + } + } + } +} \ No newline at end of file diff --git a/tests/lex_tests.rs b/tests/lex_tests.rs index 2add4e0..3b61c73 100644 --- a/tests/lex_tests.rs +++ b/tests/lex_tests.rs @@ -3,17 +3,7 @@ extern crate solfix; #[cfg(test)] mod lexer_tests { use solfix::lex_4_25; - - fn fail_test(expect: lex_4_25::Token, actual: lex_4_25::Token) { - panic!("Expected: {:?} | Actual: {:?}", expect, actual); - } - - fn expect_next_token(s: &Vec, cur: &mut usize, t: lex_4_25::Token) { - match lex_4_25::next_token(&s, cur) { - ref next if *next == t => (), - actual => fail_test(t, actual) - }; - } + use solfix::utils::test_utils::lexer::*; #[test] fn recognition_test1() { diff --git a/tests/parse_expression_tests.rs b/tests/parse_expression_tests.rs index fac4bb3..888b4d6 100644 --- a/tests/parse_expression_tests.rs +++ b/tests/parse_expression_tests.rs @@ -4,328 +4,150 @@ extern crate solfix; mod parse_expression_tests { use solfix::lex_4_25; use solfix::parse_4_25::parse_expression; + use solfix::utils::test_utils::parser::*; /*** Arithmetic ***/ #[test] fn addition_parsing_test() { - let addition = String::from("1500 + 0x000").chars().collect::>(); + let s = lex_4_25::to_chars("1500 + 0x000"); let cur = &mut 0; - let node = parse_expression(&addition, cur); - match node.node { - lex_4_25::Token::Plus => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - assert_eq!(node.children.len(), 2); - let left = String::from("1500"); - let right = String::from("0x000"); - match &node.children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(left), actual) - } - match &node.children[1].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(right), actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Plus, vec![ + as_leaf(lex_4_25::to_decimal_number("1500")), + as_leaf(lex_4_25::to_hex_number("0x000")) + ]); + expect_node_eq(expect, actual); } #[test] fn multiplication_parsing_test() { - let multiplication = String::from("1500 * 0x000").chars().collect::>(); + let s = lex_4_25::to_chars("1500 * 0x000"); let cur = &mut 0; - let node = parse_expression(&multiplication, cur); - match node.node { - lex_4_25::Token::Multiply => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } - assert_eq!(node.children.len(), 2); - assert_eq!(node.children[0].children.len(), 0); - assert_eq!(node.children[1].children.len(), 0); - let left = String::from("1500"); - let right = String::from("0x000"); - match &node.children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(left), actual) - } - match &node.children[1].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(right), actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Multiply, vec![ + as_leaf(lex_4_25::to_decimal_number("1500")), + as_leaf(lex_4_25::to_hex_number("0x000")) + ]); + expect_node_eq(expect, actual); } #[test] fn arithmetic_parsing_test1() { - let multiplication = String::from("(800 + 1500) * 0x000").chars().collect::>(); + let s = lex_4_25::to_chars("(800 + 1500) * 0x000"); let cur = &mut 0; - let node = parse_expression(&multiplication, cur); - match node.node { - lex_4_25::Token::Multiply => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } - assert_eq!(node.children.len(), 2); - assert_eq!(node.children[0].children.len(), 2); - assert_eq!(node.children[1].children.len(), 0); - let inner_left = String::from("800"); - let inner_right = String::from("1500"); - let right = String::from("0x000"); - match &node.children[0].node { - lex_4_25::Token::Plus => { - match &node.children[0].children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(inner_left), actual) - } - match &node.children[0].children[1].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(inner_right), actual) - } - } - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - match &node.children[1].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(right), actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Multiply, vec![ + as_node(lex_4_25::Token::Plus, vec![ + as_leaf(lex_4_25::to_decimal_number("800")), + as_leaf(lex_4_25::to_decimal_number("1500")) + ]), + as_leaf(lex_4_25::to_hex_number("0x000")) + ]); + expect_node_eq(expect, actual); } #[test] fn arithmetic_parsing_test2() { - let multiplication = String::from("800 + 1500 * 0x000").chars().collect::>(); + let s = lex_4_25::to_chars("800 + 1500 * 0x000"); let cur = &mut 0; - let node = parse_expression(&multiplication, cur); - match node.node { - lex_4_25::Token::Plus => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - assert_eq!(node.children.len(), 2); - assert_eq!(node.children[0].children.len(), 0); - assert_eq!(node.children[1].children.len(), 2); - let left = String::from("800"); - let inner_left = String::from("1500"); - let inner_right = String::from("0x000"); - match &node.children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(left), actual) - } - match &node.children[1].node { - lex_4_25::Token::Multiply => { - match &node.children[1].children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(inner_left), actual) - } - match &node.children[1].children[1].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(inner_right), actual) - } - } - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Plus, vec![ + as_leaf(lex_4_25::to_decimal_number("800")), + as_node(lex_4_25::Token::Multiply, vec![ + as_leaf(lex_4_25::to_decimal_number("1500")), + as_leaf(lex_4_25::to_hex_number("0x000")) + ]) + ]); + expect_node_eq(expect, actual); } #[test] fn arithmetic_parsing_test3() { - let arithmetic = String::from("800 * 1500 + 0x000").chars().collect::>(); + let s = lex_4_25::to_chars("800 * 1500 + 0x000"); let cur = &mut 0; - let node = parse_expression(&arithmetic, cur); - match node.node { - lex_4_25::Token::Plus => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - assert_eq!(node.children.len(), 2); - assert_eq!(node.children[0].children.len(), 2); - assert_eq!(node.children[1].children.len(), 0); - let inner_left = String::from("800"); - let inner_right = String::from("1500"); - let right = String::from("0x000"); - match &node.children[0].node { - lex_4_25::Token::Multiply => { - match &node.children[0].children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(inner_left), actual) - } - match &node.children[0].children[1].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(inner_right), actual) - } - } - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } - match &node.children[1].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(right), actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Plus, vec![ + as_node(lex_4_25::Token::Multiply, vec![ + as_leaf(lex_4_25::to_decimal_number("800")), + as_leaf(lex_4_25::to_decimal_number("1500")) + ]), + as_leaf(lex_4_25::to_hex_number("0x000")) + ]); + expect_node_eq(expect, actual); } #[test] fn arithmetic_parsing_test4() { - let arithmetic = String::from("800 * 1500 + 0x000 * 0x800").chars().collect::>(); + let s = lex_4_25::to_chars("800 * 1500 + 0x000 * 0x800"); let cur = &mut 0; - let node = parse_expression(&arithmetic, cur); - match node.node { - lex_4_25::Token::Plus => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - assert_eq!(node.children.len(), 2); - assert_eq!(node.children[0].children.len(), 2); - assert_eq!(node.children[1].children.len(), 2); - let left_left = String::from("800"); - let left_right = String::from("1500"); - let right_left = String::from("0x000"); - let right_right = String::from("0x800"); - match &node.children[0].node { - lex_4_25::Token::Multiply => { - match &node.children[0].children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(left_left), actual) - } - match &node.children[0].children[1].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(left_right), actual) - } - } - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } - match &node.children[1].node { - lex_4_25::Token::Multiply => { - match &node.children[1].children[0].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(right_left), actual) - } - match &node.children[1].children[1].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(right_right), actual) - } - } - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Plus, vec![ + as_node(lex_4_25::Token::Multiply, vec![ + as_leaf(lex_4_25::to_decimal_number("800")), + as_leaf(lex_4_25::to_decimal_number("1500")) + ]), + as_node(lex_4_25::Token::Multiply, vec![ + as_leaf(lex_4_25::to_hex_number("0x000")), + as_leaf(lex_4_25::to_hex_number("0x800")) + ]) + ]); + expect_node_eq(expect, actual); } #[test] fn arithmetic_parsing_test5() { - let arithmetic = String::from("1 - 800 * 1500 + 0x000 * 0x800 / 5 ** 1800").chars().collect::>(); + let s = lex_4_25::to_chars("1 - 800 * 1500 + 0x000 * 0x800 / 5 ** 1800"); let cur = &mut 0; - let node = parse_expression(&arithmetic, cur); - match node.node { - lex_4_25::Token::Plus => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - assert_eq!(node.children.len(), 2); - assert_eq!(node.children[0].children.len(), 2); - assert_eq!(node.children[1].children.len(), 2); - match &node.children[0].node { - lex_4_25::Token::Minus => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } - match &node.children[1].node { - lex_4_25::Token::Divide => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Divide, actual) - } - let one = String::from("1"); - match &node.children[0].children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(one), actual) - } - match &node.children[0].children[1].node { - lex_4_25::Token::Multiply => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } - match &node.children[1].children[0].node { - lex_4_25::Token::Multiply => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Multiply, actual) - } - match &node.children[1].children[1].node { - lex_4_25::Token::Power => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Power, actual) - } - assert_eq!(node.children[0].children[0].children.len(), 0); - assert_eq!(node.children[0].children[1].children.len(), 2); - assert_eq!(node.children[1].children[0].children.len(), 2); - assert_eq!(node.children[1].children[1].children.len(), 2); - let eight_hundred = String::from("800"); - match &node.children[0].children[1].children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(eight_hundred), actual) - } - let one_thousand_five_hundred = String::from("1500"); - match &node.children[0].children[1].children[1].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(one_thousand_five_hundred), actual) - } - let zero = String::from("0x000"); - match &node.children[1].children[0].children[0].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(zero), actual) - } - let two_thousand_forty_eight = String::from("0x800"); - match &node.children[1].children[0].children[1].node { - lex_4_25::Token::HexNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::HexNumber(two_thousand_forty_eight), actual) - } - let five = String::from("5"); - match &node.children[1].children[1].children[0].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(five), actual) - } - let one_thousand_eight_hundred = String::from("1800"); - match &node.children[1].children[1].children[1].node { - lex_4_25::Token::DecimalNumber(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber(one_thousand_eight_hundred), actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Plus, vec![ + as_node(lex_4_25::Token::Minus, vec![ + as_leaf(lex_4_25::to_decimal_number("1")), + as_node(lex_4_25::Token::Multiply, vec![ + as_leaf(lex_4_25::to_decimal_number("800")), + as_leaf(lex_4_25::to_decimal_number("1500")) + ]) + ]), + as_node(lex_4_25::Token::Divide, vec![ + as_node(lex_4_25::Token::Multiply, vec![ + as_leaf(lex_4_25::to_hex_number("0x000")), + as_leaf(lex_4_25::to_hex_number("0x800")) + ]), + as_node(lex_4_25::Token::Power, vec![ + as_leaf(lex_4_25::to_decimal_number("5")), + as_leaf(lex_4_25::to_decimal_number("1800")) + ]) + ]) + ]); + expect_node_eq(expect, actual); } /*** Function call ***/ #[test] fn function_call_test1() { - let function_call = "Identifier()"; - let chars = function_call.chars().collect::>(); + let s = lex_4_25::to_chars("Identifier()"); let cur = &mut 0; - let result = parse_expression(&chars, cur); - match result.node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - assert_eq!(result.children.len(), 2); - match &result.children[0].node { - lex_4_25::Token::Identifier(..) => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Identifier("Identifier".to_string()), actual) - } - match &result.children[1].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - assert_eq!(result.children[0].children.len(), 0); - assert_eq!(result.children[1].children.len(), 0); + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::to_identifier("Identifier")), + as_leaf(lex_4_25::Token::OpenParenthesis) + ]); + expect_node_eq(expect, actual); } #[test] fn function_call_test2() { - let function_call = "add(1, 2)"; - let chars = function_call.chars().collect::>(); + let s = lex_4_25::to_chars("add(1, 2)"); let cur = &mut 0; - let result = parse_expression(&chars, cur); - match result.node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - println!("{:?}", result); - assert_eq!(result.children.len(), 2); - match &result.children[0].node { - lex_4_25::Token::Identifier(id) => assert_eq!(&id.to_string(), &"add"), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Identifier("add".to_string()), actual) - } - match &result.children[1].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - assert_eq!(result.children[0].children.len(), 0); - assert_eq!(result.children[1].children.len(), 2); - match &result.children[1].children[0].node { - lex_4_25::Token::DecimalNumber(num) => assert_eq!(&num.to_string(), &"1"), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber("1".to_string()), actual) - } - match &result.children[1].children[1].node { - lex_4_25::Token::DecimalNumber(num) => assert_eq!(&num.to_string(), &"2"), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::DecimalNumber("2".to_string()), actual) - } + let actual = parse_expression(&s, cur); + let expect = as_node_raw(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::to_identifier("add")), + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::to_decimal_number("1")), + as_leaf(lex_4_25::to_decimal_number("2")) + ]) + ]); + expect_node_eq(expect, actual); } } diff --git a/tests/parse_tests.rs b/tests/parse_tests.rs index b0b3665..7ea213d 100644 --- a/tests/parse_tests.rs +++ b/tests/parse_tests.rs @@ -4,414 +4,254 @@ extern crate solfix; mod parse_tests { use solfix::lex_4_25; use solfix::parse_4_25::{ parse, ParseNode, ParseTree }; + use solfix::utils::test_utils::parser::*; /*** Pragma ***/ #[test] fn solidity_4_25_pragma_test1() { - let actual_tree = parse(String::from("pragma solidity 0.4.25;")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Pragma, - children: vec![ - Box::new(lex_4_25::Token::Identifier("solidity".to_string()).to_leaf()), - Box::new(lex_4_25::Token::Version("0.4.25".to_string()).to_leaf()) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("pragma solidity 0.4.25;"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Pragma, vec![ + as_leaf(lex_4_25::to_identifier("solidity")), + as_leaf(lex_4_25::to_version("0.4.25")) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn solidity_4_25_pragma_test2() { - let actual_tree = parse(String::from("pragma solidity ^0.4.25;")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Pragma, - children: vec![ - Box::new(lex_4_25::Token::Identifier("solidity".to_string()).to_leaf()), - Box::new(lex_4_25::Token::BitwiseXor.to_leaf()), - Box::new(lex_4_25::Token::Version("0.4.25".to_string()).to_leaf()) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("pragma solidity ^0.4.25;"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Pragma, vec![ + as_leaf(lex_4_25::to_identifier("solidity")), + as_leaf(lex_4_25::Token::BitwiseXor), + as_leaf(lex_4_25::to_version("0.4.25")) + ]) + ]); + expect_tree_eq(expect, actual); } /*** Contract ***/ #[test] fn contract_test1() { - let actual_tree = parse(String::from("contract A {}")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("A".to_string()).to_leaf()), - Box::new(lex_4_25::Token::OpenBrace.to_leaf()) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract A {}"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("A")), + as_leaf(lex_4_25::Token::OpenBrace) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_test2() { - let actual_tree = parse(String::from("contract B is A {}")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("B".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::Is, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::UserDefinedTypeName, - children: vec![ - Box::new(lex_4_25::Token::Identifier("A".to_string()).to_leaf()) - ] - }) - ] - }) - ] - }), - Box::new(lex_4_25::Token::OpenBrace.to_leaf()) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract B is A {}"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("B")), + as_node(lex_4_25::Token::Is, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_node(lex_4_25::Token::UserDefinedTypeName, vec![ + as_leaf(lex_4_25::to_identifier("A")) + ]) + ]) + ]), + as_leaf(lex_4_25::Token::OpenBrace) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_enum_test1() { - let actual_tree = parse(String::from("contract Enum { enum Foo { } }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Enum".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Enum, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Foo".to_string()).to_leaf()), - Box::new(lex_4_25::Token::OpenBrace.to_leaf()) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Enum { enum Foo { } }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Enum")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Enum, vec![ + as_leaf(lex_4_25::to_identifier("Foo")), + as_leaf(lex_4_25::Token::OpenBrace) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_enum_test2() { - let actual_tree = parse(String::from("contract Enum { enum Foo { Bar, Baz } }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Enum".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Enum, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Foo".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Bar".to_string()).to_leaf()), - Box::new(lex_4_25::Token::Identifier("Baz".to_string()).to_leaf()) - ] - }) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Enum { enum Foo { Bar, Baz } }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Enum")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Enum, vec![ + as_leaf(lex_4_25::to_identifier("Foo")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_leaf(lex_4_25::to_identifier("Bar")), + as_leaf(lex_4_25::to_identifier("Baz")) + ]) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_event_test1() { - let actual_tree = parse(String::from("contract Event { event emptyEvent(); }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Event".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Event, - children: vec![ - Box::new(lex_4_25::Token::Identifier("emptyEvent".to_string()).to_leaf()), - Box::new(lex_4_25::Token::OpenParenthesis.to_leaf()) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Event { event emptyEvent(); }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Event")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Event, vec![ + as_leaf(lex_4_25::to_identifier("emptyEvent")), + as_leaf(lex_4_25::Token::OpenParenthesis) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_event_test2() { - let actual_tree = parse(String::from("contract Event { event Transfer(address indexed from, address indexed to, uint256 indexed value); }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Event".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Event, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Transfer".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::EventParameter, - children: vec![ - Box::new(lex_4_25::Token::Address.to_leaf()), - Box::new(lex_4_25::Token::Indexed.to_leaf()), - Box::new(lex_4_25::Token::Identifier("from".to_string()).to_leaf()) - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::EventParameter, - children: vec![ - Box::new(lex_4_25::Token::Address.to_leaf()), - Box::new(lex_4_25::Token::Indexed.to_leaf()), - Box::new(lex_4_25::Token::Identifier("to".to_string()).to_leaf()) - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::EventParameter, - children: vec![ - Box::new(lex_4_25::Token::Uint256.to_leaf()), - Box::new(lex_4_25::Token::Indexed.to_leaf()), - Box::new(lex_4_25::Token::Identifier("value".to_string()).to_leaf()) - ] - }) - ] - }) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Event { event Transfer(address indexed from, address indexed to, uint256 indexed value); }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Event")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Event, vec![ + as_leaf(lex_4_25::to_identifier("Transfer")), + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_node(lex_4_25::Token::EventParameter, vec![ + as_leaf(lex_4_25::Token::Address), + as_leaf(lex_4_25::Token::Indexed), + as_leaf(lex_4_25::to_identifier("from")) + ]), + as_node(lex_4_25::Token::EventParameter, vec![ + as_leaf(lex_4_25::Token::Address), + as_leaf(lex_4_25::Token::Indexed), + as_leaf(lex_4_25::to_identifier("to")) + ]), + as_node(lex_4_25::Token::EventParameter, vec![ + as_leaf(lex_4_25::Token::Uint256), + as_leaf(lex_4_25::Token::Indexed), + as_leaf(lex_4_25::to_identifier("value")) + ]) + ]) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_function_test1() { - let actual_tree = parse(String::from("contract Function { function doNothing() internal pure { } }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Function".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Function, - children: vec![ - Box::new(lex_4_25::Token::Identifier("doNothing".to_string()).to_leaf()), - Box::new(lex_4_25::Token::OpenParenthesis.to_leaf()), - Box::new(lex_4_25::Token::Internal.to_leaf()), - Box::new(lex_4_25::Token::Pure.to_leaf()), - Box::new(lex_4_25::Token::OpenBrace.to_leaf()) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Function { function doNothing() internal pure { } }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Function")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Function, vec![ + as_leaf(lex_4_25::to_identifier("doNothing")), + as_leaf(lex_4_25::Token::OpenParenthesis), + as_leaf(lex_4_25::Token::Internal), + as_leaf(lex_4_25::Token::Pure), + as_leaf(lex_4_25::Token::OpenBrace) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_function_test2() { - let actual_tree = parse(String::from("contract Function { function emitEvent() internal { emit someEvent(1 + 1); } }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Function".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Function, - children: vec![ - Box::new(lex_4_25::Token::Identifier("emitEvent".to_string()).to_leaf()), - Box::new(lex_4_25::Token::OpenParenthesis.to_leaf()), - Box::new(lex_4_25::Token::Internal.to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Emit, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(lex_4_25::Token::Identifier("someEvent".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Plus, - children: vec![ - Box::new(lex_4_25::Token::DecimalNumber("1".to_string()).to_leaf()), - Box::new(lex_4_25::Token::DecimalNumber("1".to_string()).to_leaf()) - ] - }) - ] - }) - ] - }) - ] - }), - ] - }) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Function { function emitEvent() internal { emit someEvent(1 + 1); } }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Function")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Function, vec![ + as_leaf(lex_4_25::to_identifier("emitEvent")), + as_leaf(lex_4_25::Token::OpenParenthesis), + as_leaf(lex_4_25::Token::Internal), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Emit, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::to_identifier("someEvent")), + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_node(lex_4_25::Token::Plus, vec![ + as_leaf(lex_4_25::to_decimal_number("1")), + as_leaf(lex_4_25::to_decimal_number("1")) + ]) + ]) + ]) + ]) + ]) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_modifier_test1() { - let actual_tree = parse(String::from("contract Modifier { modifier doNothing { _;} }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Modifier".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Modifier, - children: vec![ - Box::new(lex_4_25::Token::Identifier("doNothing".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ Box::new(lex_4_25::Token::Placeholder.to_leaf()) ] - }) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Modifier { modifier doNothing { _;} }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Modifier")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Modifier, vec![ + as_leaf(lex_4_25::to_identifier("doNothing")), + as_node(lex_4_25::Token::OpenBrace, vec![ as_leaf(lex_4_25::Token::Placeholder) ]) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_using_for_test1() { - let actual_tree = parse(String::from("contract Using { using SafeMath for uint256; }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Using".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Using, - children: vec![ - Box::new(lex_4_25::Token::Identifier("SafeMath".to_string()).to_leaf()), - Box::new(lex_4_25::Token::Uint256.to_leaf()) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Using { using SafeMath for uint256; }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Using")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Using, vec![ + as_leaf(lex_4_25::to_identifier("SafeMath")), + as_leaf(lex_4_25::Token::Uint256) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } #[test] fn contract_using_for_test2() { - let actual_tree = parse(String::from("contract Using { using SafeMath for *; }")); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Using".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Using, - children: vec![ - Box::new(lex_4_25::Token::Identifier("SafeMath".to_string()).to_leaf()), - Box::new(lex_4_25::Token::Multiply.to_leaf()) - ] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse_str("contract Using { using SafeMath for *; }"); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Using")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::Using, vec![ + as_leaf(lex_4_25::to_identifier("SafeMath")), + as_leaf(lex_4_25::Token::Multiply) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } } diff --git a/tests/parse_types_tests.rs b/tests/parse_types_tests.rs index 10aaadd..3ec9580 100644 --- a/tests/parse_types_tests.rs +++ b/tests/parse_types_tests.rs @@ -4,283 +4,134 @@ extern crate solfix; mod types_tests { use solfix::lex_4_25; use solfix::parse_4_25::parse_type_name; + use solfix::utils::test_utils::parser::*; #[test] fn elementary_type_test1() { + let s = lex_4_25::to_chars("address"); let cur = &mut 0; - let chars = &String::from("address").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::Address => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Address, actual) - } - assert_eq!(type_node.children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Address, vec![]); + expect_node_eq(expect, actual); } #[test] fn user_defined_type_test1() { + let s = lex_4_25::to_chars("Address.Enum"); let cur = &mut 0; - let chars = &String::from("Address.Enum").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::UserDefinedTypeName => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::UserDefinedTypeName, actual) - } - assert_eq!(type_node.children.len(), 2); - match &type_node.children[0].node { - lex_4_25::Token::Identifier(name) => assert_eq!(name, &"Address"), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Identifier("Address".to_string()), actual) - } - match &type_node.children[1].node { - lex_4_25::Token::Identifier(name) => assert_eq!(name, &"Enum"), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Identifier("Enum".to_string()), actual) - } - assert_eq!(type_node.children[0].children.len(), 0); - assert_eq!(type_node.children[1].children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::UserDefinedTypeName, vec![ + as_leaf(lex_4_25::to_identifier("Address")), + as_leaf(lex_4_25::to_identifier("Enum")) + ]); + expect_node_eq(expect, actual); } #[test] fn mapping_test1() { + let s = lex_4_25::to_chars("mapping (uint256 => uint256)"); let cur = &mut 0; - let chars = &String::from("mapping (uint256 => uint256)").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::Mapping => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Mapping, actual) - } - assert_eq!(type_node.children.len(), 2); - match &type_node.children[0].node { - lex_4_25::Token::Uint256 => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Uint256, actual) - } - match &type_node.children[1].node { - lex_4_25::Token::Uint256 => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Uint256, actual) - } - assert_eq!(type_node.children[0].children.len(), 0); - assert_eq!(type_node.children[1].children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Mapping, vec![ + as_leaf(lex_4_25::Token::Uint256), + as_leaf(lex_4_25::Token::Uint256) + ]); + expect_node_eq(expect, actual); } #[test] fn array_type_name_test1() { + let s = lex_4_25::to_chars("uint256[1 + 1]"); let cur = &mut 0; - let chars = &String::from("uint256[1 + 1]").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::OpenBracket => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenBracket, actual) - } - assert_eq!(type_node.children.len(), 2); - match &type_node.children[0].node { - lex_4_25::Token::Uint256 => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Uint256, actual) - } - match &type_node.children[1].node { - lex_4_25::Token::Plus => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - assert_eq!(type_node.children[0].children.len(), 0); - assert_eq!(type_node.children[1].children.len(), 2); - match &type_node.children[1].children[0].node { - lex_4_25::Token::DecimalNumber(num) => assert_eq!(num, &"1"), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - match &type_node.children[1].children[1].node { - lex_4_25::Token::DecimalNumber(num) => assert_eq!(num, &"1"), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Plus, actual) - } - assert_eq!(type_node.children[1].children[0].children.len(), 0); - assert_eq!(type_node.children[1].children[1].children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::OpenBracket, vec![ + as_leaf(lex_4_25::Token::Uint256), + as_node(lex_4_25::Token::Plus, vec![ + as_leaf(lex_4_25::to_decimal_number("1")), + as_leaf(lex_4_25::to_decimal_number("1")) + ]) + ]); + expect_node_eq(expect, actual); } #[test] fn function_type_name_test1() { + let s = lex_4_25::to_chars("function () internal"); let cur = &mut 0; - let chars = &String::from("function () internal").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::Function => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - assert_eq!(type_node.children.len(), 2); - match &type_node.children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - match &type_node.children[1].node { - lex_4_25::Token::Internal => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Internal, actual) - } - assert_eq!(type_node.children[0].children.len(), 0); - assert_eq!(type_node.children[1].children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Function, vec![ + as_leaf(lex_4_25::Token::OpenParenthesis), + as_leaf(lex_4_25::Token::Internal) + ]); + expect_node_eq(expect, actual); } #[test] fn function_type_name_test2() { + let s = lex_4_25::to_chars("function () internal pure"); let cur = &mut 0; - let chars = &String::from("function () internal pure").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::Function => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - assert_eq!(type_node.children.len(), 3); - match &type_node.children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - match &type_node.children[1].node { - lex_4_25::Token::Internal => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Internal, actual) - } - match &type_node.children[2].node { - lex_4_25::Token::Pure => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Pure, actual) - } - assert_eq!(type_node.children[0].children.len(), 0); - assert_eq!(type_node.children[1].children.len(), 0); - assert_eq!(type_node.children[2].children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Function, vec![ + as_leaf(lex_4_25::Token::OpenParenthesis), + as_leaf(lex_4_25::Token::Internal), + as_leaf(lex_4_25::Token::Pure) + ]); + expect_node_eq(expect, actual); } #[test] fn function_type_name_test3() { + let s = lex_4_25::to_chars("function (uint256, bytes32) internal pure returns (bool) "); let cur = &mut 0; - let chars = &String::from("function (uint256, bytes32) internal pure returns (bool) ").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::Function => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - assert_eq!(type_node.children.len(), 4); - match &type_node.children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - match &type_node.children[1].node { - lex_4_25::Token::Internal => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Internal, actual) - } - match &type_node.children[2].node { - lex_4_25::Token::Pure => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Pure, actual) - } - match &type_node.children[3].node { - lex_4_25::Token::Returns => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Returns, actual) - } - assert_eq!(type_node.children[0].children.len(), 2); - assert_eq!(type_node.children[1].children.len(), 0); - assert_eq!(type_node.children[2].children.len(), 0); - assert_eq!(type_node.children[3].children.len(), 1); - match &type_node.children[0].children[0].node { - lex_4_25::Token::Uint256 => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Uint256, actual) - } - match &type_node.children[0].children[1].node { - lex_4_25::Token::Bytes32 => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Bytes32, actual) - } - match &type_node.children[3].children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - assert_eq!(type_node.children[0].children[0].children.len(), 0); - assert_eq!(type_node.children[0].children[1].children.len(), 0); - assert_eq!(type_node.children[3].children[0].children.len(), 1); - match &type_node.children[3].children[0].children[0].node { - lex_4_25::Token::Bool => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Bool, actual) - } - assert_eq!(type_node.children[3].children[0].children[0].children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Function, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::Token::Uint256), + as_leaf(lex_4_25::Token::Bytes32) + ]), + as_leaf(lex_4_25::Token::Internal), + as_leaf(lex_4_25::Token::Pure), + as_node(lex_4_25::Token::Returns, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::Token::Bool) + ]) + ]) + ]); + expect_node_eq(expect, actual); } #[test] fn function_type_name_test4() { + let s = lex_4_25::to_chars("function (function (uint256) internal) external payable returns (function (bool) external returns (uint256)) "); let cur = &mut 0; - let chars = &String::from("function (function (uint256) internal) external payable returns (function (bool) external returns (uint256)) ").chars().collect::>(); - let type_node = parse_type_name(chars, cur); - match type_node.node { - lex_4_25::Token::Function => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - assert_eq!(type_node.children.len(), 4); - match &type_node.children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - match &type_node.children[1].node { - lex_4_25::Token::External => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::External, actual) - } - match &type_node.children[2].node { - lex_4_25::Token::Payable => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Payable, actual) - } - match &type_node.children[3].node { - lex_4_25::Token::Returns => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Returns, actual) - } - assert_eq!(type_node.children[0].children.len(), 1); - assert_eq!(type_node.children[1].children.len(), 0); - assert_eq!(type_node.children[2].children.len(), 0); - assert_eq!(type_node.children[3].children.len(), 1); - match &type_node.children[0].children[0].node { - lex_4_25::Token::Function => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - match &type_node.children[3].children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - assert_eq!(type_node.children[0].children[0].children.len(), 2); - assert_eq!(type_node.children[3].children[0].children.len(), 1); - match &type_node.children[0].children[0].children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - match &type_node.children[0].children[0].children[1].node { - lex_4_25::Token::Internal => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Internal, actual) - } - match &type_node.children[3].children[0].children[0].node { - lex_4_25::Token::Function => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - assert_eq!(type_node.children[0].children[0].children[0].children.len(), 1); - assert_eq!(type_node.children[0].children[0].children[1].children.len(), 0); - assert_eq!(type_node.children[3].children[0].children[0].children.len(), 3); - match &type_node.children[0].children[0].children[0].children[0].node { - lex_4_25::Token::Uint256 => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Uint256, actual) - } - match &type_node.children[3].children[0].children[0].children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Function, actual) - } - match &type_node.children[3].children[0].children[0].children[1].node { - lex_4_25::Token::External => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::External, actual) - } - match &type_node.children[3].children[0].children[0].children[2].node { - lex_4_25::Token::Returns => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Returns, actual) - } - assert_eq!(type_node.children[3].children[0].children[0].children[0].children.len(), 1); - assert_eq!(type_node.children[3].children[0].children[0].children[1].children.len(), 0); - assert_eq!(type_node.children[3].children[0].children[0].children[2].children.len(), 1); - match &type_node.children[3].children[0].children[0].children[0].children[0].node { - lex_4_25::Token::Bool => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Bool, actual) - } - match &type_node.children[3].children[0].children[0].children[2].children[0].node { - lex_4_25::Token::OpenParenthesis => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::OpenParenthesis, actual) - } - assert_eq!(type_node.children[3].children[0].children[0].children[2].children[0].children.len(), 1); - match &type_node.children[3].children[0].children[0].children[2].children[0].children[0].node { - lex_4_25::Token::Uint256 => (), - actual => panic!("Expected: {:?} | Actual: {:?}", lex_4_25::Token::Uint256, actual) - } - assert_eq!(type_node.children[3].children[0].children[0].children[2].children[0].children[0].children.len(), 0); + let actual = parse_type_name(&s, cur); + let expect = as_node_raw(lex_4_25::Token::Function, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_node(lex_4_25::Token::Function, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::Token::Uint256) + ]), + as_leaf(lex_4_25::Token::Internal) + ]) + ]), + as_leaf(lex_4_25::Token::External), + as_leaf(lex_4_25::Token::Payable), + as_node(lex_4_25::Token::Returns, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_node(lex_4_25::Token::Function, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::Token::Bool) + ]), + as_leaf(lex_4_25::Token::External), + as_node(lex_4_25::Token::Returns, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::Token::Uint256) + ]) + ]) + ]) + ]) + ]) + ]); + expect_node_eq(expect, actual); } } diff --git a/tests/parser_integration_tests.rs b/tests/parser_integration_tests.rs index 7149090..57a09c9 100644 --- a/tests/parser_integration_tests.rs +++ b/tests/parser_integration_tests.rs @@ -4,195 +4,49 @@ extern crate solfix; mod parser_integration_tests { use solfix::lex_4_25; use solfix::parse_4_25::{ parse, ParseNode, ParseTree }; + use solfix::utils::test_utils::parser::*; use std::fs; #[test] fn ownable_test() { let input = fs::read_to_string("./contracts/Ownable.sol") .expect("Test file not found: ./contracts/Ownable.sol"); - let actual_tree = parse(input); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Pragma, - children: vec![ - Box::new(lex_4_25::Token::Identifier("solidity".to_string()).to_leaf()), - Box::new(lex_4_25::Token::BitwiseXor.to_leaf()), - Box::new(lex_4_25::Token::Version("0.4.25".to_string()).to_leaf()) - ] - }, - ParseNode { - node: lex_4_25::Token::Contract, - children: vec![ - Box::new(lex_4_25::Token::Identifier("Ownable".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::StateVariable, - children: vec![ - Box::new(lex_4_25::Token::Address.to_leaf()), - Box::new(lex_4_25::Token::Public.to_leaf()), - Box::new(lex_4_25::Token::Identifier("owner".to_string()).to_leaf()) - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::Modifier, - children: vec![ - Box::new(lex_4_25::Token::Identifier("onlyOwner".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(lex_4_25::Token::Identifier("require".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Equals, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Dot, - children: vec![ - Box::new(lex_4_25::Token::Identifier("msg".to_string()).to_leaf()), - Box::new(lex_4_25::Token::Identifier("sender".to_string()).to_leaf()) - ] - }), - Box::new(lex_4_25::Token::Identifier("owner".to_string()).to_leaf()) - ] - }) - ] - }) - ] - }), - Box::new(lex_4_25::Token::Placeholder.to_leaf()) - ] - }) - ] - }), - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); + let actual = parse(input); + let expect = as_tree(vec![ + as_node_raw(lex_4_25::Token::Pragma, vec![ + as_leaf(lex_4_25::to_identifier("solidity")), + as_leaf(lex_4_25::Token::BitwiseXor), + as_leaf(lex_4_25::to_version("0.4.25")) + ]), + as_node_raw(lex_4_25::Token::Contract, vec![ + as_leaf(lex_4_25::to_identifier("Ownable")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::StateVariable, vec![ + as_leaf(lex_4_25::Token::Address), + as_leaf(lex_4_25::Token::Public), + as_leaf(lex_4_25::to_identifier("owner")) + ]), + as_node(lex_4_25::Token::Modifier, vec![ + as_leaf(lex_4_25::to_identifier("onlyOwner")), + as_node(lex_4_25::Token::OpenBrace, vec![ + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_leaf(lex_4_25::to_identifier("require")), + as_node(lex_4_25::Token::OpenParenthesis, vec![ + as_node(lex_4_25::Token::Equals, vec![ + as_node(lex_4_25::Token::Dot, vec![ + as_leaf(lex_4_25::to_identifier("msg")), + as_leaf(lex_4_25::to_identifier("sender")) + ]), + as_leaf(lex_4_25::to_identifier("owner")) + ]) + ]) + ]), + as_leaf(lex_4_25::Token::Placeholder) + ]) + ]) + ]) + ]) + ]); + expect_tree_eq(expect, actual); } - - /* - #[test] - fn safe_math_test() { - let input = fs::read_to_string("./contracts/SafeMath.sol") - .expect("Test file not found: ./contracts/SafeMath.sol"); - let actual_tree = parse(input); - let expected_tree = ParseTree { - children: vec![ - ParseNode { - node: lex_4_25::Token::Pragma, - children: vec![ - Box::new(lex_4_25::Token::Identifier("solidity".to_string()).to_leaf()), - Box::new(lex_4_25::Token::Version("^0.4.25".to_string()).to_leaf()) - ] - }, - ParseNode { - node: lex_4_25::Token::Library, - children: vec![ - Box::new(lex_4_25::Token::Identifier("SafeMath".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Function, - children: vec![ - Box::new(lex_4_25::Token::Identifier("add".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Parameter, - children: vec![ - Box::new(lex_4_25::Token::Uint256.to_leaf()), - Box::new(lex_4_25::Token::Identifier("a".to_string()).to_leaf()) - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::Parameter, - children: vec![ - Box::new(lex_4_25::Token::Uint256.to_leaf()), - Box::new(lex_4_25::Token::Identifier("b".to_string()).to_leaf()) - ] - }) - ] - }), - Box::new(lex_4_25::Token::Internal.to_leaf()), - Box::new(lex_4_25::Token::Pure.to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::Returns, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(lex_4_25::Token::Uint256.to_leaf()) - ] - }) - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::OpenBrace, - children: vec![ - Box::new(ParseNode { - node: lex_4_25::Token::Assignment, - children: vec![ - - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - Box::new(lex_4_25::Token::Identifier("require".to_string()).to_leaf()), - Box::new(ParseNode { - node: lex_4_25::Token::OpenParenthesis, - children: vec![ - - ] - }) - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::Return, - children: vec![ - Box::new(lex_4_25::Token::Identifier("c".to_string()).to_leaf()) - ] - }) - ] - }) - ] - }), - Box::new(ParseNode { - node: lex_4_25::Token::Function, - children: vec![] - }), - Box::new(ParseNode { - node: lex_4_25::Token::Function, - children: vec![] - }), - Box::new(ParseNode { - node: lex_4_25::Token::Function, - children: vec![] - }), - Box::new(ParseNode { - node: lex_4_25::Token::Function, - children: vec![] - }) - ] - }) - ] - } - ] - }; - assert_eq!(expected_tree, actual_tree); - } - */ }