From 85e037cebdc70b2be21d5ef979b75c010cdf04a2 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Thu, 27 Apr 2023 16:44:59 +0200 Subject: [PATCH] test: add some basic tests 1. Test that checks if deserialization works 2. Test for a visitor that collects all function names 3. Test for a visitor that collects all variable names --- src/lib.rs | 15 --- tests/ast-json/Counter.json | 244 ++++++++++++++++++++++++++++++++++++ tests/basic.rs | 66 ++++++++++ 3 files changed, 310 insertions(+), 15 deletions(-) create mode 100644 tests/ast-json/Counter.json create mode 100644 tests/basic.rs diff --git a/src/lib.rs b/src/lib.rs index d026194..16a8173 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,2 @@ pub mod ast; pub mod visitor; - -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/tests/ast-json/Counter.json b/tests/ast-json/Counter.json new file mode 100644 index 0000000..7669cfd --- /dev/null +++ b/tests/ast-json/Counter.json @@ -0,0 +1,244 @@ +{ + "absolutePath": "Counter.sol", + "exportedSymbols": { + "Counter": [ + 21 + ] + }, + "id": 22, + "license": "UNLICENSED", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + "^", + "0.8", + ".13" + ], + "nodeType": "PragmaDirective", + "src": "39:24:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "Counter", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 21, + "linearizedBaseContracts": [ + 21 + ], + "name": "Counter", + "nameLocation": "74:7:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "functionSelector": "8381f58a", + "id": 3, + "mutability": "mutable", + "name": "number", + "nameLocation": "103:6:0", + "nodeType": "VariableDeclaration", + "scope": 21, + "src": "88:21:0", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "88:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "public" + }, + { + "body": { + "id": 12, + "nodeType": "Block", + "src": "161:35:0", + "statements": [ + { + "expression": { + "id": 10, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 8, + "name": "number", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "171:6:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 9, + "name": "newNumber", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "180:9:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "171:18:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 11, + "nodeType": "ExpressionStatement", + "src": "171:18:0" + } + ] + }, + "functionSelector": "3fb5c1cb", + "id": 13, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "setNumber", + "nameLocation": "125:9:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 6, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 5, + "mutability": "mutable", + "name": "newNumber", + "nameLocation": "143:9:0", + "nodeType": "VariableDeclaration", + "scope": 13, + "src": "135:17:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 4, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "135:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "134:19:0" + }, + "returnParameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "161:0:0" + }, + "scope": 21, + "src": "116:80:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": { + "id": 19, + "nodeType": "Block", + "src": "230:25:0", + "statements": [ + { + "expression": { + "id": 17, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "240:8:0", + "subExpression": { + "id": 16, + "name": "number", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "240:6:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 18, + "nodeType": "ExpressionStatement", + "src": "240:8:0" + } + ] + }, + "functionSelector": "d09de08a", + "id": 20, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "increment", + "nameLocation": "211:9:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 14, + "nodeType": "ParameterList", + "parameters": [], + "src": "220:2:0" + }, + "returnParameters": { + "id": 15, + "nodeType": "ParameterList", + "parameters": [], + "src": "230:0:0" + }, + "scope": 21, + "src": "202:53:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 22, + "src": "65:192:0", + "usedErrors": [] + } + ], + "src": "39:219:0" +} diff --git a/tests/basic.rs b/tests/basic.rs new file mode 100644 index 0000000..fbff529 --- /dev/null +++ b/tests/basic.rs @@ -0,0 +1,66 @@ +#[cfg(test)] +mod tests { + use eyre::Result; + use solc_ast::{ast::*, visitor::ast_visitor::*}; + + fn read_counter() -> Result { + Ok(serde_json::from_reader(std::io::BufReader::new( + std::fs::File::open("tests/ast-json/Counter.json")?, + ))?) + } + + #[test] + fn deserialize_counter() -> Result<()> { + let source_unit = read_counter()?; + assert_eq!(source_unit.absolute_path, Some("Counter.sol".into())); + Ok(()) + } + + #[derive(Default, Debug)] + struct FunctionDefinitionCollector { + names: Vec, + } + + impl ASTConstVisitor for FunctionDefinitionCollector { + fn end_visit_function_definition(&mut self, node: &FunctionDefinition) -> Result<()> { + self.names.push(node.name.clone()); + Ok(()) + } + } + + #[test] + fn functions() -> Result<()> { + let source_unit = read_counter()?; + let mut function_definition_collector = FunctionDefinitionCollector::default(); + source_unit.accept(&mut function_definition_collector)?; + assert_eq!( + function_definition_collector.names, + vec![String::from("setNumber"), String::from("increment")] + ); + Ok(()) + } + + #[derive(Default, Debug)] + struct VariableNameCollector { + names: Vec, + } + + impl ASTConstVisitor for VariableNameCollector { + fn end_visit_variable_declaration(&mut self, node: &VariableDeclaration) -> Result<()> { + self.names.push(node.name.clone()); + Ok(()) + } + } + + #[test] + fn variables() -> Result<()> { + let source_unit = read_counter()?; + let mut variable_name_collector = VariableNameCollector::default(); + source_unit.accept(&mut variable_name_collector)?; + assert_eq!( + variable_name_collector.names, + vec![String::from("number"), String::from("newNumber")] + ); + Ok(()) + } +}