From 0dd53c8526f88fabb7f4361f9886e67172f09417 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:50:18 +0300 Subject: [PATCH 01/13] test: port ethabi/src/contract.rs unit tests --- crates/json-abi/src/abi.rs | 616 +++++++++++++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) diff --git a/crates/json-abi/src/abi.rs b/crates/json-abi/src/abi.rs index 203bb87fb..d22158f88 100644 --- a/crates/json-abi/src/abi.rs +++ b/crates/json-abi/src/abi.rs @@ -452,3 +452,619 @@ impl<'de> Visitor<'de> for ContractAbiObjectVisitor { }) } } + +#[cfg(all(test))] +mod test { + use crate::{Error, Event, EventParam, Fallback, Function, Param, Receive, StateMutability}; + + use super::{Constructor, JsonAbi}; + + use alloc::collections::BTreeMap; + use serde::{Deserialize, Serialize}; + use std::fmt::Debug; + + fn assert_ser_de(canon: &T) + where + T: Serialize + for<'a> Deserialize<'a> + PartialEq + Debug, + { + let ser = serde_json::to_string(canon).unwrap(); + let de = serde_json::from_str(&ser).unwrap(); + assert_eq!(canon, &de); + } + + #[test] + fn empty() { + let json = "[]"; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn constructor() { + let json = r#" + [ + { + "type": "constructor", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: Some(Constructor { + inputs: vec![Param { + name: "a".to_string(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + state_mutability: StateMutability::NonPayable + }), + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn functions() { + let json = r#" + [ + { + "type": "function", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "outputs": [ + { + "name": "res", + "type":"address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "bar", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::from_iter(vec![ + ( + "foo".to_string(), + vec![Function { + name: "foo".to_string(), + inputs: vec![Param { + name: "a".to_string(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + outputs: vec![Param { + name: "res".to_string(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + state_mutability: StateMutability::NonPayable, + }] + ), + ( + "bar".to_string(), + vec![Function { + name: "bar".to_string(), + inputs: vec![], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }] + ), + ]), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn functions_overloads() { + let json = r#" + [ + { + "type": "function", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "outputs": [ + { + "name": "res", + "type":"address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "foo", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Function { + name: "foo".to_string(), + inputs: vec![Param { + name: "a".to_string(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + outputs: vec![Param { + name: "res".to_string(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + state_mutability: StateMutability::NonPayable, + }, + Function { + name: "foo".to_string(), + inputs: vec![], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }, + ] + )]), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn events() { + let json = r#" + [ + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "bar", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": true + } + ], + "anonymous": false + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::from_iter(vec![ + ( + "foo".to_string(), + vec![Event { + name: "foo".to_string(), + inputs: vec![EventParam { + name: "a".to_string(), + indexed: false, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }] + ), + ( + "bar".to_string(), + vec![Event { + name: "bar".to_string(), + inputs: vec![EventParam { + name: "a".to_string(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }] + ), + ]), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn events_overload() { + let json = r#" + [ + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": true + } + ], + "anonymous": false + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Event { + name: "foo".to_string(), + inputs: vec![EventParam { + name: "a".to_string(), + indexed: false, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }, + Event { + name: "foo".to_string(), + inputs: vec![EventParam { + name: "a".to_string(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }, + ] + )]), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn errors() { + let json = r#" + [ + { + "type": "error", + "inputs": [ + { + "name": "available", + "type": "uint256" + }, + { + "name": "required", + "type": "address" + } + ], + "name": "foo" + }, + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "address" + } + ], + "name": "bar" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::from_iter(vec![ + ( + "foo".to_string(), + vec![Error { + name: "foo".into(), + inputs: vec![ + Param { + name: "available".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![] + }, + Param { + name: "required".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + } + ], + }] + ), + ( + "bar".to_string(), + vec![Error { + name: "bar".into(), + inputs: vec![ + Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![] + }, + Param { + name: "b".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ], + }] + ), + ]), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn errors_overload() { + let json = r#" + [ + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + } + ], + "name": "foo" + }, + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "address" + } + ], + "name": "foo" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Error { + name: "foo".into(), + inputs: vec![Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![], + }], + }, + Error { + name: "foo".into(), + inputs: vec![ + Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![], + }, + Param { + name: "b".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + } + ], + }, + ] + ),]), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn receive() { + let json = r#" + [ + { + "type": "receive", + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: Some(Receive { + state_mutability: StateMutability::NonPayable, + }), + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn fallback() { + let json = r#" + [ + { + "type": "fallback", + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: Some(Fallback { + state_mutability: StateMutability::NonPayable, + }), + } + ); + + assert_ser_de(&deserialized); + } +} From defc3c9b7a07a0c5c720d4f89221fb7c22af2bc3 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:36:44 +0300 Subject: [PATCH 02/13] test: port ethabi/src/event_param.rs unit tests --- crates/json-abi/src/param.rs | 282 ++++++++++++++++++++++++++++++++++- 1 file changed, 280 insertions(+), 2 deletions(-) diff --git a/crates/json-abi/src/param.rs b/crates/json-abi/src/param.rs index e97e707a3..1802bb0d5 100644 --- a/crates/json-abi/src/param.rs +++ b/crates/json-abi/src/param.rs @@ -135,7 +135,7 @@ impl Param { pub fn udt_specifier(&self) -> Option> { // UDTs are more annoying to check for, so we reuse logic here. if !self.is_udt() { - return None + return None; } self.internal_type().and_then(|ty| ty.other_specifier()) } @@ -342,7 +342,7 @@ impl EventParam { pub fn udt_specifier(&self) -> Option> { // UDTs are more annoying to check for, so we reuse logic here. if !self.is_udt() { - return None + return None; } self.internal_type().and_then(|ty| ty.other_specifier()) } @@ -442,6 +442,7 @@ struct BorrowedParam<'a> { #[cfg(test)] mod tests { + use serde_json::Value; use super::*; #[test] @@ -453,4 +454,281 @@ mod tests { }"#; let _param = serde_json::from_str::(param).unwrap(); } + + fn assert_json_eq(left: &str, right: &str) { + let left: Value = serde_json::from_str(left).unwrap(); + let right: Value = serde_json::from_str(right).unwrap(); + assert_eq!(left, right); + } + + #[test] + fn event_param_deserialization() { + let s = r#"{ + "name": "foo", + "type": "address", + "indexed": true + }"#; + + let deserialized: EventParam = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + EventParam { + name: "foo".to_owned(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None, + } + ); + + assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn event_param_tuple_deserialization() { + let s = r#"{ + "name": "foo", + "type": "tuple", + "indexed": true, + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "tuple", + "components": [ + { + "name": "c", + "type": "address" + } + ] + } + ] + }"#; + + let deserialized: EventParam = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + EventParam { + name: "foo".to_owned(), + indexed: true, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".into(), + ty: "uint48".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "b".into(), + ty: "tuple".into(), + components: vec![Param { + name: "c".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }], + internal_type: None, + } + ], + internal_type: None, + } + ); + + assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn event_param_tuple_array_deserialization() { + let s = r#"{ + "components": [ + { + "type": "uint256", + "name": "a" + }, + { + "type": "address", + "name": "b" + }, + { + "components": [ + { + "type": "address", + "name": "c" + }, + { + "type": "address", + "name": "d" + } + ], + "type": "tuple", + "name": "e" + }, + { + "type": "uint256", + "name": "f" + }, + { + "components": [ + { + "components": [ + { + "type": "address", + "name": "g" + }, + { + "type": "bytes", + "name": "h" + } + ], + "type": "tuple[]", + "name": "i" + }, + { + "components": [ + { + "type": "address", + "name": "j" + }, + { + "type": "uint256", + "name": "k" + } + ], + "type": "tuple[]", + "name": "l" + }, + { + "type": "uint256", + "name": "m" + } + ], + "type": "tuple[]", + "name": "n" + }, + { + "type": "uint256", + "name": "o" + } + ], + "indexed": false, + "name": "LogTaskSubmitted", + "type": "tuple" + }"#; + + let deserialized: EventParam = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + EventParam { + name: "LogTaskSubmitted".to_owned(), + indexed: false, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "b".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "e".into(), + ty: "tuple".into(), + components: vec![ + Param { + name: "c".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "d".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "f".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "n".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "i".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "g".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "h".into(), + ty: "bytes".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "l".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "j".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "k".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "m".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "o".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None + } + ); + + assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } } From ada50a5378f2e9791c73f1070861430ff2986e2a Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:46:08 +0300 Subject: [PATCH 03/13] test: port ethabi/src/state_mutability.rs unit tests --- crates/json-abi/src/lib.rs | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/crates/json-abi/src/lib.rs b/crates/json-abi/src/lib.rs index dec3cd50b..7836bdfa0 100644 --- a/crates/json-abi/src/lib.rs +++ b/crates/json-abi/src/lib.rs @@ -73,3 +73,42 @@ impl StateMutability { } } } + +#[cfg(all(test))] +mod test { + use serde_json::Value; + + use crate::StateMutability; + + fn assert_json_eq(left: &str, right: &str) { + let left: Value = serde_json::from_str(left).unwrap(); + let right: Value = serde_json::from_str(right).unwrap(); + assert_eq!(left, right); + } + + #[test] + fn state_mutability() { + let json = r#" + [ + "pure", + "view", + "nonpayable", + "payable" + ] + "#; + + let deserialized: Vec = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + vec![ + StateMutability::Pure, + StateMutability::View, + StateMutability::NonPayable, + StateMutability::Payable, + ] + ); + + assert_json_eq(json, &serde_json::to_string(&deserialized).unwrap()); + } +} From 9cf3d2820673430d45403bd069ef148554bc7d0a Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:27:42 +0300 Subject: [PATCH 04/13] change from unit tests into integration tests --- crates/json-abi/src/abi.rs | 616 ---------------------- crates/json-abi/src/param.rs | 283 +--------- crates/json-abi/tests/event_param_test.rs | 282 ++++++++++ crates/json-abi/tests/json_abi_test.rs | 614 +++++++++++++++++++++ 4 files changed, 899 insertions(+), 896 deletions(-) create mode 100644 crates/json-abi/tests/event_param_test.rs create mode 100644 crates/json-abi/tests/json_abi_test.rs diff --git a/crates/json-abi/src/abi.rs b/crates/json-abi/src/abi.rs index d22158f88..203bb87fb 100644 --- a/crates/json-abi/src/abi.rs +++ b/crates/json-abi/src/abi.rs @@ -452,619 +452,3 @@ impl<'de> Visitor<'de> for ContractAbiObjectVisitor { }) } } - -#[cfg(all(test))] -mod test { - use crate::{Error, Event, EventParam, Fallback, Function, Param, Receive, StateMutability}; - - use super::{Constructor, JsonAbi}; - - use alloc::collections::BTreeMap; - use serde::{Deserialize, Serialize}; - use std::fmt::Debug; - - fn assert_ser_de(canon: &T) - where - T: Serialize + for<'a> Deserialize<'a> + PartialEq + Debug, - { - let ser = serde_json::to_string(canon).unwrap(); - let de = serde_json::from_str(&ser).unwrap(); - assert_eq!(canon, &de); - } - - #[test] - fn empty() { - let json = "[]"; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn constructor() { - let json = r#" - [ - { - "type": "constructor", - "inputs": [ - { - "name":"a", - "type":"address" - } - ], - "stateMutability": "nonpayable" - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: Some(Constructor { - inputs: vec![Param { - name: "a".to_string(), - internal_type: None, - ty: "address".into(), - components: vec![], - }], - state_mutability: StateMutability::NonPayable - }), - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn functions() { - let json = r#" - [ - { - "type": "function", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address" - } - ], - "outputs": [ - { - "name": "res", - "type":"address" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "bar", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::from_iter(vec![ - ( - "foo".to_string(), - vec![Function { - name: "foo".to_string(), - inputs: vec![Param { - name: "a".to_string(), - internal_type: None, - ty: "address".into(), - components: vec![] - }], - outputs: vec![Param { - name: "res".to_string(), - internal_type: None, - ty: "address".into(), - components: vec![] - }], - state_mutability: StateMutability::NonPayable, - }] - ), - ( - "bar".to_string(), - vec![Function { - name: "bar".to_string(), - inputs: vec![], - outputs: vec![], - state_mutability: StateMutability::NonPayable, - }] - ), - ]), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn functions_overloads() { - let json = r#" - [ - { - "type": "function", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address" - } - ], - "outputs": [ - { - "name": "res", - "type":"address" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "foo", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::from_iter(vec![( - "foo".to_string(), - vec![ - Function { - name: "foo".to_string(), - inputs: vec![Param { - name: "a".to_string(), - internal_type: None, - ty: "address".into(), - components: vec![], - }], - outputs: vec![Param { - name: "res".to_string(), - internal_type: None, - ty: "address".into(), - components: vec![] - }], - state_mutability: StateMutability::NonPayable, - }, - Function { - name: "foo".to_string(), - inputs: vec![], - outputs: vec![], - state_mutability: StateMutability::NonPayable, - }, - ] - )]), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn events() { - let json = r#" - [ - { - "type": "event", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": false - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "bar", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": true - } - ], - "anonymous": false - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::from_iter(vec![ - ( - "foo".to_string(), - vec![Event { - name: "foo".to_string(), - inputs: vec![EventParam { - name: "a".to_string(), - indexed: false, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }] - ), - ( - "bar".to_string(), - vec![Event { - name: "bar".to_string(), - inputs: vec![EventParam { - name: "a".to_string(), - indexed: true, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }] - ), - ]), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn events_overload() { - let json = r#" - [ - { - "type": "event", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": false - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": true - } - ], - "anonymous": false - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::from_iter(vec![( - "foo".to_string(), - vec![ - Event { - name: "foo".to_string(), - inputs: vec![EventParam { - name: "a".to_string(), - indexed: false, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }, - Event { - name: "foo".to_string(), - inputs: vec![EventParam { - name: "a".to_string(), - indexed: true, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }, - ] - )]), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn errors() { - let json = r#" - [ - { - "type": "error", - "inputs": [ - { - "name": "available", - "type": "uint256" - }, - { - "name": "required", - "type": "address" - } - ], - "name": "foo" - }, - { - "type": "error", - "inputs": [ - { - "name": "a", - "type": "uint256" - }, - { - "name": "b", - "type": "address" - } - ], - "name": "bar" - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::from_iter(vec![ - ( - "foo".to_string(), - vec![Error { - name: "foo".into(), - inputs: vec![ - Param { - name: "available".into(), - internal_type: None, - ty: "uint256".into(), - components: vec![] - }, - Param { - name: "required".into(), - internal_type: None, - ty: "address".into(), - components: vec![], - } - ], - }] - ), - ( - "bar".to_string(), - vec![Error { - name: "bar".into(), - inputs: vec![ - Param { - name: "a".into(), - internal_type: None, - ty: "uint256".into(), - components: vec![] - }, - Param { - name: "b".into(), - internal_type: None, - ty: "address".into(), - components: vec![] - } - ], - }] - ), - ]), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn errors_overload() { - let json = r#" - [ - { - "type": "error", - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "foo" - }, - { - "type": "error", - "inputs": [ - { - "name": "a", - "type": "uint256" - }, - { - "name": "b", - "type": "address" - } - ], - "name": "foo" - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::from_iter(vec![( - "foo".to_string(), - vec![ - Error { - name: "foo".into(), - inputs: vec![Param { - name: "a".into(), - internal_type: None, - ty: "uint256".into(), - components: vec![], - }], - }, - Error { - name: "foo".into(), - inputs: vec![ - Param { - name: "a".into(), - internal_type: None, - ty: "uint256".into(), - components: vec![], - }, - Param { - name: "b".into(), - internal_type: None, - ty: "address".into(), - components: vec![], - } - ], - }, - ] - ),]), - receive: None, - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn receive() { - let json = r#" - [ - { - "type": "receive", - "stateMutability": "nonpayable" - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: Some(Receive { - state_mutability: StateMutability::NonPayable, - }), - fallback: None, - } - ); - - assert_ser_de(&deserialized); - } - - #[test] - fn fallback() { - let json = r#" - [ - { - "type": "fallback", - "stateMutability": "nonpayable" - } - ] - "#; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: Some(Fallback { - state_mutability: StateMutability::NonPayable, - }), - } - ); - - assert_ser_de(&deserialized); - } -} diff --git a/crates/json-abi/src/param.rs b/crates/json-abi/src/param.rs index 1802bb0d5..52ca23e9a 100644 --- a/crates/json-abi/src/param.rs +++ b/crates/json-abi/src/param.rs @@ -135,7 +135,7 @@ impl Param { pub fn udt_specifier(&self) -> Option> { // UDTs are more annoying to check for, so we reuse logic here. if !self.is_udt() { - return None; + return None } self.internal_type().and_then(|ty| ty.other_specifier()) } @@ -342,7 +342,7 @@ impl EventParam { pub fn udt_specifier(&self) -> Option> { // UDTs are more annoying to check for, so we reuse logic here. if !self.is_udt() { - return None; + return None } self.internal_type().and_then(|ty| ty.other_specifier()) } @@ -442,8 +442,8 @@ struct BorrowedParam<'a> { #[cfg(test)] mod tests { - use serde_json::Value; use super::*; + use serde_json::Value; #[test] fn test_complex_param() { @@ -454,281 +454,4 @@ mod tests { }"#; let _param = serde_json::from_str::(param).unwrap(); } - - fn assert_json_eq(left: &str, right: &str) { - let left: Value = serde_json::from_str(left).unwrap(); - let right: Value = serde_json::from_str(right).unwrap(); - assert_eq!(left, right); - } - - #[test] - fn event_param_deserialization() { - let s = r#"{ - "name": "foo", - "type": "address", - "indexed": true - }"#; - - let deserialized: EventParam = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - EventParam { - name: "foo".to_owned(), - indexed: true, - ty: "address".into(), - components: vec![], - internal_type: None, - } - ); - - assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } - - #[test] - fn event_param_tuple_deserialization() { - let s = r#"{ - "name": "foo", - "type": "tuple", - "indexed": true, - "components": [ - { - "name": "a", - "type": "uint48" - }, - { - "name": "b", - "type": "tuple", - "components": [ - { - "name": "c", - "type": "address" - } - ] - } - ] - }"#; - - let deserialized: EventParam = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - EventParam { - name: "foo".to_owned(), - indexed: true, - ty: "tuple".into(), - components: vec![ - Param { - name: "a".into(), - ty: "uint48".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "b".into(), - ty: "tuple".into(), - components: vec![Param { - name: "c".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }], - internal_type: None, - } - ], - internal_type: None, - } - ); - - assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } - - #[test] - fn event_param_tuple_array_deserialization() { - let s = r#"{ - "components": [ - { - "type": "uint256", - "name": "a" - }, - { - "type": "address", - "name": "b" - }, - { - "components": [ - { - "type": "address", - "name": "c" - }, - { - "type": "address", - "name": "d" - } - ], - "type": "tuple", - "name": "e" - }, - { - "type": "uint256", - "name": "f" - }, - { - "components": [ - { - "components": [ - { - "type": "address", - "name": "g" - }, - { - "type": "bytes", - "name": "h" - } - ], - "type": "tuple[]", - "name": "i" - }, - { - "components": [ - { - "type": "address", - "name": "j" - }, - { - "type": "uint256", - "name": "k" - } - ], - "type": "tuple[]", - "name": "l" - }, - { - "type": "uint256", - "name": "m" - } - ], - "type": "tuple[]", - "name": "n" - }, - { - "type": "uint256", - "name": "o" - } - ], - "indexed": false, - "name": "LogTaskSubmitted", - "type": "tuple" - }"#; - - let deserialized: EventParam = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - EventParam { - name: "LogTaskSubmitted".to_owned(), - indexed: false, - ty: "tuple".into(), - components: vec![ - Param { - name: "a".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "b".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "e".into(), - ty: "tuple".into(), - components: vec![ - Param { - name: "c".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "d".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "f".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "n".into(), - ty: "tuple[]".into(), - components: vec![ - Param { - name: "i".into(), - ty: "tuple[]".into(), - components: vec![ - Param { - name: "g".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "h".into(), - ty: "bytes".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "l".into(), - ty: "tuple[]".into(), - components: vec![ - Param { - name: "j".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "k".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "m".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "o".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None - } - ); - - assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } } diff --git a/crates/json-abi/tests/event_param_test.rs b/crates/json-abi/tests/event_param_test.rs new file mode 100644 index 000000000..20b6ab1c8 --- /dev/null +++ b/crates/json-abi/tests/event_param_test.rs @@ -0,0 +1,282 @@ +#[cfg(test)] +mod tests { + use alloy_json_abi::{EventParam, Param}; + use serde_json::Value; + + fn assert_json_eq(left: &str, right: &str) { + let left: Value = serde_json::from_str(left).unwrap(); + let right: Value = serde_json::from_str(right).unwrap(); + assert_eq!(left, right); + } + + #[test] + fn event_param_deserialization() { + let s = r#"{ + "name": "foo", + "type": "address", + "indexed": true + }"#; + + let deserialized: EventParam = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + EventParam { + name: "foo".to_owned(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None, + } + ); + + assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn event_param_tuple_deserialization() { + let s = r#"{ + "name": "foo", + "type": "tuple", + "indexed": true, + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "tuple", + "components": [ + { + "name": "c", + "type": "address" + } + ] + } + ] + }"#; + + let deserialized: EventParam = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + EventParam { + name: "foo".to_owned(), + indexed: true, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".into(), + ty: "uint48".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "b".into(), + ty: "tuple".into(), + components: vec![Param { + name: "c".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }], + internal_type: None, + } + ], + internal_type: None, + } + ); + + assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn event_param_tuple_array_deserialization() { + let s = r#"{ + "components": [ + { + "type": "uint256", + "name": "a" + }, + { + "type": "address", + "name": "b" + }, + { + "components": [ + { + "type": "address", + "name": "c" + }, + { + "type": "address", + "name": "d" + } + ], + "type": "tuple", + "name": "e" + }, + { + "type": "uint256", + "name": "f" + }, + { + "components": [ + { + "components": [ + { + "type": "address", + "name": "g" + }, + { + "type": "bytes", + "name": "h" + } + ], + "type": "tuple[]", + "name": "i" + }, + { + "components": [ + { + "type": "address", + "name": "j" + }, + { + "type": "uint256", + "name": "k" + } + ], + "type": "tuple[]", + "name": "l" + }, + { + "type": "uint256", + "name": "m" + } + ], + "type": "tuple[]", + "name": "n" + }, + { + "type": "uint256", + "name": "o" + } + ], + "indexed": false, + "name": "LogTaskSubmitted", + "type": "tuple" + }"#; + + let deserialized: EventParam = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + EventParam { + name: "LogTaskSubmitted".to_owned(), + indexed: false, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "b".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "e".into(), + ty: "tuple".into(), + components: vec![ + Param { + name: "c".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "d".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "f".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "n".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "i".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "g".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "h".into(), + ty: "bytes".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "l".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "j".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "k".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "m".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "o".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None + } + ); + + assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } +} diff --git a/crates/json-abi/tests/json_abi_test.rs b/crates/json-abi/tests/json_abi_test.rs new file mode 100644 index 000000000..81885968c --- /dev/null +++ b/crates/json-abi/tests/json_abi_test.rs @@ -0,0 +1,614 @@ +#[cfg(all(test))] +mod test { + use alloy_json_abi::{ + Constructor, Error, Event, EventParam, Fallback, Function, JsonAbi, Param, Receive, + StateMutability, + }; + use serde::{Deserialize, Serialize}; + use std::{collections::BTreeMap, fmt::Debug}; + + fn assert_ser_de(canon: &T) + where + T: Serialize + for<'a> Deserialize<'a> + PartialEq + Debug, + { + let ser = serde_json::to_string(canon).unwrap(); + let de = serde_json::from_str(&ser).unwrap(); + assert_eq!(canon, &de); + } + + #[test] + fn empty() { + let json = "[]"; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn constructor() { + let json = r#" + [ + { + "type": "constructor", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: Some(Constructor { + inputs: vec![Param { + name: "a".to_string(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + state_mutability: StateMutability::NonPayable + }), + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn functions() { + let json = r#" + [ + { + "type": "function", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "outputs": [ + { + "name": "res", + "type":"address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "bar", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::from_iter(vec![ + ( + "foo".into(), + vec![Function { + name: "foo".into(), + inputs: vec![Param { + name: "a".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + outputs: vec![Param { + name: "res".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + state_mutability: StateMutability::NonPayable, + }] + ), + ( + "bar".into(), + vec![Function { + name: "bar".into(), + inputs: vec![], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }] + ), + ]), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn functions_overloads() { + let json = r#" + [ + { + "type": "function", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "outputs": [ + { + "name": "res", + "type":"address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "foo", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Function { + name: "foo".into(), + inputs: vec![Param { + name: "a".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + outputs: vec![Param { + name: "res".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + state_mutability: StateMutability::NonPayable, + }, + Function { + name: "foo".into(), + inputs: vec![], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }, + ] + )]), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn events() { + let json = r#" + [ + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "bar", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": true + } + ], + "anonymous": false + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::from_iter(vec![ + ( + "foo".into(), + vec![Event { + name: "foo".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: false, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }] + ), + ( + "bar".to_string(), + vec![Event { + name: "bar".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }] + ), + ]), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn events_overload() { + let json = r#" + [ + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": true + } + ], + "anonymous": false + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Event { + name: "foo".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: false, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }, + Event { + name: "foo".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }, + ] + )]), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn errors() { + let json = r#" + [ + { + "type": "error", + "inputs": [ + { + "name": "available", + "type": "uint256" + }, + { + "name": "required", + "type": "address" + } + ], + "name": "foo" + }, + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "address" + } + ], + "name": "bar" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::from_iter(vec![ + ( + "foo".to_string(), + vec![Error { + name: "foo".into(), + inputs: vec![ + Param { + name: "available".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![] + }, + Param { + name: "required".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + } + ], + }] + ), + ( + "bar".to_string(), + vec![Error { + name: "bar".into(), + inputs: vec![ + Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![] + }, + Param { + name: "b".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ], + }] + ), + ]), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn errors_overload() { + let json = r#" + [ + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + } + ], + "name": "foo" + }, + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "address" + } + ], + "name": "foo" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Error { + name: "foo".into(), + inputs: vec![Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![], + }], + }, + Error { + name: "foo".into(), + inputs: vec![ + Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![], + }, + Param { + name: "b".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + } + ], + }, + ] + ),]), + receive: None, + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn receive() { + let json = r#" + [ + { + "type": "receive", + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: Some(Receive { + state_mutability: StateMutability::NonPayable, + }), + fallback: None, + } + ); + + assert_ser_de(&deserialized); + } + + #[test] + fn fallback() { + let json = r#" + [ + { + "type": "fallback", + "stateMutability": "nonpayable" + } + ] + "#; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: Some(Fallback { + state_mutability: StateMutability::NonPayable, + }), + } + ); + + assert_ser_de(&deserialized); + } +} From 0abfadb77a66019131c7e6e5f9bae72b6e6ad65d Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:31:27 +0300 Subject: [PATCH 05/13] move state mutability tests into tests/ dir --- crates/json-abi/src/lib.rs | 39 ------------------- .../json-abi/tests/state_mutability_test.rs | 38 ++++++++++++++++++ 2 files changed, 38 insertions(+), 39 deletions(-) create mode 100644 crates/json-abi/tests/state_mutability_test.rs diff --git a/crates/json-abi/src/lib.rs b/crates/json-abi/src/lib.rs index 7836bdfa0..dec3cd50b 100644 --- a/crates/json-abi/src/lib.rs +++ b/crates/json-abi/src/lib.rs @@ -73,42 +73,3 @@ impl StateMutability { } } } - -#[cfg(all(test))] -mod test { - use serde_json::Value; - - use crate::StateMutability; - - fn assert_json_eq(left: &str, right: &str) { - let left: Value = serde_json::from_str(left).unwrap(); - let right: Value = serde_json::from_str(right).unwrap(); - assert_eq!(left, right); - } - - #[test] - fn state_mutability() { - let json = r#" - [ - "pure", - "view", - "nonpayable", - "payable" - ] - "#; - - let deserialized: Vec = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - vec![ - StateMutability::Pure, - StateMutability::View, - StateMutability::NonPayable, - StateMutability::Payable, - ] - ); - - assert_json_eq(json, &serde_json::to_string(&deserialized).unwrap()); - } -} diff --git a/crates/json-abi/tests/state_mutability_test.rs b/crates/json-abi/tests/state_mutability_test.rs new file mode 100644 index 000000000..d8bc52280 --- /dev/null +++ b/crates/json-abi/tests/state_mutability_test.rs @@ -0,0 +1,38 @@ +#[cfg(all(test))] +mod test { + use serde_json::Value; + + use crate::StateMutability; + + fn assert_json_eq(left: &str, right: &str) { + let left: Value = serde_json::from_str(left).unwrap(); + let right: Value = serde_json::from_str(right).unwrap(); + assert_eq!(left, right); + } + + #[test] + fn state_mutability() { + let json = r#" + [ + "pure", + "view", + "nonpayable", + "payable" + ] + "#; + + let deserialized: Vec = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + vec![ + StateMutability::Pure, + StateMutability::View, + StateMutability::NonPayable, + StateMutability::Payable, + ] + ); + + assert_json_eq(json, &serde_json::to_string(&deserialized).unwrap()); + } +} From 561d76135a9d1cf236dcd226efad1f704b4a1f83 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Tue, 15 Aug 2023 20:30:14 +0300 Subject: [PATCH 06/13] test: port ethabi/src/operation unit tests --- crates/json-abi/tests/abi_item_test.rs | 220 +++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 crates/json-abi/tests/abi_item_test.rs diff --git a/crates/json-abi/tests/abi_item_test.rs b/crates/json-abi/tests/abi_item_test.rs new file mode 100644 index 000000000..56b907961 --- /dev/null +++ b/crates/json-abi/tests/abi_item_test.rs @@ -0,0 +1,220 @@ +#[cfg(test)] +mod test { + use alloy_json_abi::{ + AbiItem, Event, EventParam, Function, + InternalType::{Other, Struct}, + Param, StateMutability, + }; + use std::borrow::Cow; + + macro_rules! assert_ser_de { + ($value:expr) => {{ + let ser = serde_json::to_string(&$value).unwrap(); + let de: AbiItem<'_> = serde_json::from_str(&ser).unwrap(); + assert_eq!( + &$value, &de, + "Original value and deserialized value do not match." + ); + }}; + } + + #[test] + fn operation() { + let s = r#"{ + "type":"function", + "inputs": [{ + "name":"a", + "type":"address" + }], + "name":"foo", + "outputs": [], + "stateMutability": "nonpayable" + }"#; + + let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); + + #[allow(deprecated)] + let function = Function { + name: "foo".to_owned(), + inputs: vec![Param { + name: "a".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }; + + assert_eq!(deserialized, AbiItem::Function(Cow::Owned(function))); + let ser = serde_json::to_string(&deserialized).unwrap(); + let de: AbiItem<'_> = serde_json::from_str(&ser).unwrap(); + assert_eq!(&deserialized, &de); + assert_ser_de!(deserialized); + } + + #[test] + fn event_operation_with_tuple_array_input() { + let s = r#"{ + "type":"event", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed":true + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct Action[]", + "name": "b", + "type": "tuple[]" + } + ], + "name":"E", + "outputs": [], + "anonymous": false + }"#; + + let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); + + let event = Event { + name: "E".to_owned(), + inputs: vec![ + EventParam { + name: "a".to_owned(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None, + }, + EventParam { + name: "b".to_owned(), + indexed: false, + ty: "tuple[]".into(), + components: vec![ + Param { + name: "to".into(), + ty: "address".into(), + components: vec![], + internal_type: Some(Other { + contract: None, + ty: "address".into(), + }), + }, + Param { + name: "value".into(), + ty: "uint256".into(), + components: vec![], + internal_type: Some(Other { + contract: None, + ty: "uint256".into(), + }), + }, + Param { + name: "data".into(), + ty: "bytes".into(), + components: vec![], + internal_type: Some(Other { + contract: None, + ty: "bytes".into(), + }), + }, + ], + internal_type: Some(Struct { + contract: None, + ty: "Action[]".into(), + }), + }, + ], + anonymous: false, + }; + + assert_eq!(deserialized, AbiItem::Event(Cow::Owned(event))); + assert_ser_de!(deserialized); + } + + // #[test] + // fn sanitize_function_name() { + // fn test_sanitize_function_name(name: &str, expected: &str) { + // let s = format!( + // r#"{{ + // "type":"function", + // "inputs": [{{ + // "name":"a", + // "type":"address" + // }}], + // "name":"{}", + // "outputs": [] + // }}"#, + // name + // ); + + // let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); + // let function = match &deserialized { + // AbiItem::Function(f) => f, + // _ => panic!("expected function"), + // }; + + // assert_eq!(function.name, expected); + + // assert_ser_de!(deserialized); + // } + + // test_sanitize_function_name("foo", "foo"); + // test_sanitize_function_name("foo()", "foo"); + // test_sanitize_function_name("()", ""); + // test_sanitize_function_name("", ""); + // } + + // #[test] + // fn sanitize_event_name() { + // fn test_sanitize_event_name(name: &str, expected: &str) { + // let s = format!( + // r#"{{ + // "type":"event", + // "inputs": [{{ + // "name":"a", + // "type":"address", + // "indexed":true + // }}], + // "name":"{}", + // "outputs": [], + // "anonymous": false + // }}"#, + // name + // ); + + // let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); + // let event = match deserialized { + // AbiItem::Event(e) => e, + // _ => panic!("expected event!"), + // }; + + // assert_eq!(event.name, expected); + + // assert_ser_de!(AbiItem::Event(event.clone())); + // } + + // test_sanitize_event_name("foo", "foo"); + // test_sanitize_event_name("foo()", "foo"); + // test_sanitize_event_name("()", ""); + // test_sanitize_event_name("", ""); + // } +} From 440ce889a93b1f86937c3a267fac8831c0b6aeba Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 16 Aug 2023 14:56:22 +0300 Subject: [PATCH 07/13] move common utils to seperate helper file --- crates/json-abi/tests/abi_item_test.rs | 18 +++------- crates/json-abi/tests/event_param_test.rs | 16 ++++----- crates/json-abi/tests/json_abi_test.rs | 35 ++++++++----------- .../json-abi/tests/state_mutability_test.rs | 15 +++----- crates/json-abi/tests/test_helpers.rs | 24 +++++++++++++ 5 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 crates/json-abi/tests/test_helpers.rs diff --git a/crates/json-abi/tests/abi_item_test.rs b/crates/json-abi/tests/abi_item_test.rs index 56b907961..1403cc78a 100644 --- a/crates/json-abi/tests/abi_item_test.rs +++ b/crates/json-abi/tests/abi_item_test.rs @@ -1,5 +1,8 @@ +mod test_helpers; + #[cfg(test)] mod test { + use crate::assert_ser_de; use alloy_json_abi::{ AbiItem, Event, EventParam, Function, InternalType::{Other, Struct}, @@ -7,17 +10,6 @@ mod test { }; use std::borrow::Cow; - macro_rules! assert_ser_de { - ($value:expr) => {{ - let ser = serde_json::to_string(&$value).unwrap(); - let de: AbiItem<'_> = serde_json::from_str(&ser).unwrap(); - assert_eq!( - &$value, &de, - "Original value and deserialized value do not match." - ); - }}; - } - #[test] fn operation() { let s = r#"{ @@ -50,7 +42,7 @@ mod test { let ser = serde_json::to_string(&deserialized).unwrap(); let de: AbiItem<'_> = serde_json::from_str(&ser).unwrap(); assert_eq!(&deserialized, &de); - assert_ser_de!(deserialized); + assert_ser_de!(AbiItem<'_>, deserialized); } #[test] @@ -147,7 +139,7 @@ mod test { }; assert_eq!(deserialized, AbiItem::Event(Cow::Owned(event))); - assert_ser_de!(deserialized); + assert_ser_de!(AbiItem<'_>, deserialized); } // #[test] diff --git a/crates/json-abi/tests/event_param_test.rs b/crates/json-abi/tests/event_param_test.rs index 20b6ab1c8..a8ce1e57d 100644 --- a/crates/json-abi/tests/event_param_test.rs +++ b/crates/json-abi/tests/event_param_test.rs @@ -1,13 +1,9 @@ +mod test_helpers; + #[cfg(test)] mod tests { + use crate::assert_json_eq; use alloy_json_abi::{EventParam, Param}; - use serde_json::Value; - - fn assert_json_eq(left: &str, right: &str) { - let left: Value = serde_json::from_str(left).unwrap(); - let right: Value = serde_json::from_str(right).unwrap(); - assert_eq!(left, right); - } #[test] fn event_param_deserialization() { @@ -30,7 +26,7 @@ mod tests { } ); - assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); } #[test] @@ -88,7 +84,7 @@ mod tests { } ); - assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); } #[test] @@ -277,6 +273,6 @@ mod tests { } ); - assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str()); + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); } } diff --git a/crates/json-abi/tests/json_abi_test.rs b/crates/json-abi/tests/json_abi_test.rs index 81885968c..dca0d2315 100644 --- a/crates/json-abi/tests/json_abi_test.rs +++ b/crates/json-abi/tests/json_abi_test.rs @@ -1,20 +1,13 @@ +mod test_helpers; + #[cfg(all(test))] mod test { + use crate::assert_ser_de; use alloy_json_abi::{ Constructor, Error, Event, EventParam, Fallback, Function, JsonAbi, Param, Receive, StateMutability, }; - use serde::{Deserialize, Serialize}; - use std::{collections::BTreeMap, fmt::Debug}; - - fn assert_ser_de(canon: &T) - where - T: Serialize + for<'a> Deserialize<'a> + PartialEq + Debug, - { - let ser = serde_json::to_string(canon).unwrap(); - let de = serde_json::from_str(&ser).unwrap(); - assert_eq!(canon, &de); - } + use std::collections::BTreeMap; #[test] fn empty() { @@ -34,7 +27,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -76,7 +69,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -153,7 +146,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -227,7 +220,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -304,7 +297,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -378,7 +371,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -471,7 +464,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -549,7 +542,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -579,7 +572,7 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } #[test] @@ -609,6 +602,6 @@ mod test { } ); - assert_ser_de(&deserialized); + assert_ser_de!(JsonAbi, deserialized); } } diff --git a/crates/json-abi/tests/state_mutability_test.rs b/crates/json-abi/tests/state_mutability_test.rs index d8bc52280..0c7d525e5 100644 --- a/crates/json-abi/tests/state_mutability_test.rs +++ b/crates/json-abi/tests/state_mutability_test.rs @@ -1,14 +1,9 @@ +mod test_helpers; + #[cfg(all(test))] mod test { - use serde_json::Value; - - use crate::StateMutability; - - fn assert_json_eq(left: &str, right: &str) { - let left: Value = serde_json::from_str(left).unwrap(); - let right: Value = serde_json::from_str(right).unwrap(); - assert_eq!(left, right); - } + use crate::assert_json_eq; + use alloy_json_abi::StateMutability; #[test] fn state_mutability() { @@ -33,6 +28,6 @@ mod test { ] ); - assert_json_eq(json, &serde_json::to_string(&deserialized).unwrap()); + assert_json_eq!(json, &serde_json::to_string(&deserialized).unwrap()); } } diff --git a/crates/json-abi/tests/test_helpers.rs b/crates/json-abi/tests/test_helpers.rs new file mode 100644 index 000000000..01d3a0347 --- /dev/null +++ b/crates/json-abi/tests/test_helpers.rs @@ -0,0 +1,24 @@ +#[macro_export] +macro_rules! assert_ser_de { + ($type:ty, $value:expr) => {{ + let ser = serde_json::to_string(&$value).unwrap(); + let de: $type = serde_json::from_str(&ser).unwrap(); + assert_eq!( + &$value, &de, + "Original value and deserialized value do not match." + ); + }}; +} + +#[macro_export] +macro_rules! assert_json_eq { + ($left:expr, $right:expr) => {{ + let left_val: serde_json::Value = serde_json::from_str($left).unwrap(); + let right_val: serde_json::Value = serde_json::from_str($right).unwrap(); + assert_eq!( + left_val, right_val, + "JSON values are not equal: {} != {}", + $left, $right + ); + }}; +} From 1ee82d5197d76699a580b220c142b423e4bed497 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 16 Aug 2023 14:57:03 +0300 Subject: [PATCH 08/13] test: port ethabi/src/param.rs tests --- crates/json-abi/tests/param_tests.rs | 447 +++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 crates/json-abi/tests/param_tests.rs diff --git a/crates/json-abi/tests/param_tests.rs b/crates/json-abi/tests/param_tests.rs new file mode 100644 index 000000000..b854bda0d --- /dev/null +++ b/crates/json-abi/tests/param_tests.rs @@ -0,0 +1,447 @@ +mod test_helpers; + +mod tests { + use crate::{assert_json_eq, assert_ser_de}; + use alloy_json_abi::{InternalType::Struct, Param}; + + #[test] + fn param_simple() { + let s = r#"{ + "name": "foo", + "type": "address" + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn param_simple_internal_type() { + let s = r#"{ + "name": "foo", + "type": "address", + "internalType": "struct Verifier.Proof" + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: Some(Struct { + contract: Some("Verifier".into()), + ty: "Proof".into(), + }), + ty: "address".into(), + components: vec![] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn param_tuple() { + let s = r#"{ + "name": "foo", + "type": "tuple", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "tuple", + "components": [ + { + "type": "address", + "name": "c" + } + ] + } + ] + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![], + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![Param { + name: "c".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![], + },], + }, + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn param_tuple_internal_type() { + let s = r#"{ + "name": "foo", + "type": "tuple", + "internalType": "struct Pairing.G1Point[]", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "tuple", + "components": [ + { + "name": "c", + "type": "address" + } + ] + } + ] + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: Some(Struct { + contract: Some("Pairing".into()), + ty: "G1Point[]".into(), + }), + ty: "tuple".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![Param { + name: "c".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + }] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn param_tuple_named() { + let s = r#"{ + "name": "foo", + "type": "tuple", + "components": [ + { + "name": "amount", + "type": "uint48" + }, + { + "name": "things", + "type": "tuple", + "components": [ + { + "name": "baseTupleParam", + "type": "address" + } + ] + } + ] + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![ + Param { + name: "amount".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "things".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![Param { + name: "baseTupleParam".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + },] + }, + ] + } + ); + + assert_ser_de!(Param, deserialized); + } + + #[test] + fn param_tuple_array() { + let s = r#"{ + "name": "foo", + "type": "tuple[]", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "address" + }, + { + "name": "c", + "type": "address" + } + ] + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple[]".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + }, + Param { + name: "c".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn param_array_of_array_of_tuple() { + let s = r#"{ + "name": "foo", + "type": "tuple[][]", + "components": [ + { + "name": "a", + "type": "uint8" + }, + { + "name": "b", + "type": "uint16" + } + ] + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple[][]".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint8".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "uint16".into(), + components: vec![] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn param_tuple_fixed_array() { + let s = r#"{ + "name": "foo", + "type": "tuple[2]", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "address" + }, + { + "name": "c", + "type": "address" + } + ] + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple[2]".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + }, + Param { + name: "c".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } + + #[test] + fn param_tuple_with_nested_tuple_arrays() { + let s = r#"{ + "name": "foo", + "type": "tuple", + "components": [ + { + "name": "a", + "type": "tuple[]", + "components": [ + { + "name": "b", + "type": "address" + } + ] + }, + { + "name": "c", + "type": "tuple[42]", + "components": [ + { + "name": "d", + "type": "address" + } + ] + } + ] + }"#; + + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "tuple[]".into(), + components: vec![Param { + name: "b".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + },] + }, + Param { + name: "c".to_owned(), + internal_type: None, + ty: "tuple[42]".into(), + components: vec![Param { + name: "d".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + }] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); + } +} From 541678a25e5905f6e64358a9f5511a118326b770 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:39:55 +0300 Subject: [PATCH 09/13] make clippy happy --- crates/json-abi/src/param.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/json-abi/src/param.rs b/crates/json-abi/src/param.rs index 52ca23e9a..e97e707a3 100644 --- a/crates/json-abi/src/param.rs +++ b/crates/json-abi/src/param.rs @@ -443,7 +443,6 @@ struct BorrowedParam<'a> { #[cfg(test)] mod tests { use super::*; - use serde_json::Value; #[test] fn test_complex_param() { From f846e9aaa6b76fc2251f48dac0ea9c4a261e010a Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:43:13 +0300 Subject: [PATCH 10/13] closes #103 --- crates/json-abi/tests/abi_item_test.rs | 314 ++++--- crates/json-abi/tests/event_param_test.rs | 322 ++++--- crates/json-abi/tests/json_abi_test.rs | 788 +++++++++--------- crates/json-abi/tests/param_tests.rs | 563 +++++++------ .../json-abi/tests/state_mutability_test.rs | 34 +- 5 files changed, 1001 insertions(+), 1020 deletions(-) diff --git a/crates/json-abi/tests/abi_item_test.rs b/crates/json-abi/tests/abi_item_test.rs index 1403cc78a..28f0f4612 100644 --- a/crates/json-abi/tests/abi_item_test.rs +++ b/crates/json-abi/tests/abi_item_test.rs @@ -1,18 +1,15 @@ mod test_helpers; -#[cfg(test)] -mod test { - use crate::assert_ser_de; - use alloy_json_abi::{ - AbiItem, Event, EventParam, Function, - InternalType::{Other, Struct}, - Param, StateMutability, - }; - use std::borrow::Cow; - - #[test] - fn operation() { - let s = r#"{ +use alloy_json_abi::{ + AbiItem, Event, EventParam, Function, + InternalType::{Other, Struct}, + Param, StateMutability, +}; +use std::borrow::Cow; + +#[test] +fn operation() { + let s = r#"{ "type":"function", "inputs": [{ "name":"a", @@ -23,31 +20,31 @@ mod test { "stateMutability": "nonpayable" }"#; - let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); + let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); + + #[allow(deprecated)] + let function = Function { + name: "foo".to_owned(), + inputs: vec![Param { + name: "a".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }; - #[allow(deprecated)] - let function = Function { - name: "foo".to_owned(), - inputs: vec![Param { - name: "a".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![], - }], - outputs: vec![], - state_mutability: StateMutability::NonPayable, - }; - - assert_eq!(deserialized, AbiItem::Function(Cow::Owned(function))); - let ser = serde_json::to_string(&deserialized).unwrap(); - let de: AbiItem<'_> = serde_json::from_str(&ser).unwrap(); - assert_eq!(&deserialized, &de); - assert_ser_de!(AbiItem<'_>, deserialized); - } - - #[test] - fn event_operation_with_tuple_array_input() { - let s = r#"{ + assert_eq!(deserialized, AbiItem::Function(Cow::Owned(function))); + let ser = serde_json::to_string(&deserialized).unwrap(); + let de: AbiItem<'_> = serde_json::from_str(&ser).unwrap(); + assert_eq!(&deserialized, &de); + assert_ser_de!(AbiItem<'_>, deserialized); +} + +#[test] +fn event_operation_with_tuple_array_input() { + let s = r#"{ "type":"event", "inputs": [ { @@ -84,129 +81,128 @@ mod test { "anonymous": false }"#; - let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); - - let event = Event { - name: "E".to_owned(), - inputs: vec![ - EventParam { - name: "a".to_owned(), - indexed: true, - ty: "address".into(), - components: vec![], - internal_type: None, - }, - EventParam { - name: "b".to_owned(), - indexed: false, - ty: "tuple[]".into(), - components: vec![ - Param { - name: "to".into(), + let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); + + let event = Event { + name: "E".to_owned(), + inputs: vec![ + EventParam { + name: "a".to_owned(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None, + }, + EventParam { + name: "b".to_owned(), + indexed: false, + ty: "tuple[]".into(), + components: vec![ + Param { + name: "to".into(), + ty: "address".into(), + components: vec![], + internal_type: Some(Other { + contract: None, ty: "address".into(), - components: vec![], - internal_type: Some(Other { - contract: None, - ty: "address".into(), - }), - }, - Param { - name: "value".into(), + }), + }, + Param { + name: "value".into(), + ty: "uint256".into(), + components: vec![], + internal_type: Some(Other { + contract: None, ty: "uint256".into(), - components: vec![], - internal_type: Some(Other { - contract: None, - ty: "uint256".into(), - }), - }, - Param { - name: "data".into(), + }), + }, + Param { + name: "data".into(), + ty: "bytes".into(), + components: vec![], + internal_type: Some(Other { + contract: None, ty: "bytes".into(), - components: vec![], - internal_type: Some(Other { - contract: None, - ty: "bytes".into(), - }), - }, - ], - internal_type: Some(Struct { - contract: None, - ty: "Action[]".into(), - }), - }, - ], - anonymous: false, - }; - - assert_eq!(deserialized, AbiItem::Event(Cow::Owned(event))); - assert_ser_de!(AbiItem<'_>, deserialized); - } - - // #[test] - // fn sanitize_function_name() { - // fn test_sanitize_function_name(name: &str, expected: &str) { - // let s = format!( - // r#"{{ - // "type":"function", - // "inputs": [{{ - // "name":"a", - // "type":"address" - // }}], - // "name":"{}", - // "outputs": [] - // }}"#, - // name - // ); - - // let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); - // let function = match &deserialized { - // AbiItem::Function(f) => f, - // _ => panic!("expected function"), - // }; - - // assert_eq!(function.name, expected); - - // assert_ser_de!(deserialized); - // } - - // test_sanitize_function_name("foo", "foo"); - // test_sanitize_function_name("foo()", "foo"); - // test_sanitize_function_name("()", ""); - // test_sanitize_function_name("", ""); - // } - - // #[test] - // fn sanitize_event_name() { - // fn test_sanitize_event_name(name: &str, expected: &str) { - // let s = format!( - // r#"{{ - // "type":"event", - // "inputs": [{{ - // "name":"a", - // "type":"address", - // "indexed":true - // }}], - // "name":"{}", - // "outputs": [], - // "anonymous": false - // }}"#, - // name - // ); - - // let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); - // let event = match deserialized { - // AbiItem::Event(e) => e, - // _ => panic!("expected event!"), - // }; - - // assert_eq!(event.name, expected); - - // assert_ser_de!(AbiItem::Event(event.clone())); - // } - - // test_sanitize_event_name("foo", "foo"); - // test_sanitize_event_name("foo()", "foo"); - // test_sanitize_event_name("()", ""); - // test_sanitize_event_name("", ""); - // } + }), + }, + ], + internal_type: Some(Struct { + contract: None, + ty: "Action[]".into(), + }), + }, + ], + anonymous: false, + }; + + assert_eq!(deserialized, AbiItem::Event(Cow::Owned(event))); + assert_ser_de!(AbiItem<'_>, deserialized); } + +// #[test] +// fn sanitize_function_name() { +// fn test_sanitize_function_name(name: &str, expected: &str) { +// let s = format!( +// r#"{{ +// "type":"function", +// "inputs": [{{ +// "name":"a", +// "type":"address" +// }}], +// "name":"{}", +// "outputs": [] +// }}"#, +// name +// ); + +// let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); +// let function = match &deserialized { +// AbiItem::Function(f) => f, +// _ => panic!("expected function"), +// }; + +// assert_eq!(function.name, expected); + +// assert_ser_de!(deserialized); +// } + +// test_sanitize_function_name("foo", "foo"); +// test_sanitize_function_name("foo()", "foo"); +// test_sanitize_function_name("()", ""); +// test_sanitize_function_name("", ""); +// } + +// #[test] +// fn sanitize_event_name() { +// fn test_sanitize_event_name(name: &str, expected: &str) { +// let s = format!( +// r#"{{ +// "type":"event", +// "inputs": [{{ +// "name":"a", +// "type":"address", +// "indexed":true +// }}], +// "name":"{}", +// "outputs": [], +// "anonymous": false +// }}"#, +// name +// ); + +// let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); +// let event = match deserialized { +// AbiItem::Event(e) => e, +// _ => panic!("expected event!"), +// }; + +// assert_eq!(event.name, expected); + +// assert_ser_de!(AbiItem::Event(event.clone())); +// } + +// test_sanitize_event_name("foo", "foo"); +// test_sanitize_event_name("foo()", "foo"); +// test_sanitize_event_name("()", ""); +// test_sanitize_event_name("", ""); +// } diff --git a/crates/json-abi/tests/event_param_test.rs b/crates/json-abi/tests/event_param_test.rs index a8ce1e57d..efd2ca89f 100644 --- a/crates/json-abi/tests/event_param_test.rs +++ b/crates/json-abi/tests/event_param_test.rs @@ -1,37 +1,34 @@ mod test_helpers; -#[cfg(test)] -mod tests { - use crate::assert_json_eq; - use alloy_json_abi::{EventParam, Param}; +use alloy_json_abi::{EventParam, Param}; - #[test] - fn event_param_deserialization() { - let s = r#"{ +#[test] +fn event_param_deserialization() { + let s = r#"{ "name": "foo", "type": "address", "indexed": true }"#; - let deserialized: EventParam = serde_json::from_str(s).unwrap(); + let deserialized: EventParam = serde_json::from_str(s).unwrap(); - assert_eq!( - deserialized, - EventParam { - name: "foo".to_owned(), - indexed: true, - ty: "address".into(), - components: vec![], - internal_type: None, - } - ); + assert_eq!( + deserialized, + EventParam { + name: "foo".to_owned(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None, + } + ); - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} - #[test] - fn event_param_tuple_deserialization() { - let s = r#"{ +#[test] +fn event_param_tuple_deserialization() { + let s = r#"{ "name": "foo", "type": "tuple", "indexed": true, @@ -53,43 +50,43 @@ mod tests { ] }"#; - let deserialized: EventParam = serde_json::from_str(s).unwrap(); + let deserialized: EventParam = serde_json::from_str(s).unwrap(); - assert_eq!( - deserialized, - EventParam { - name: "foo".to_owned(), - indexed: true, - ty: "tuple".into(), - components: vec![ - Param { - name: "a".into(), - ty: "uint48".into(), + assert_eq!( + deserialized, + EventParam { + name: "foo".to_owned(), + indexed: true, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".into(), + ty: "uint48".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "b".into(), + ty: "tuple".into(), + components: vec![Param { + name: "c".into(), + ty: "address".into(), components: vec![], internal_type: None, - }, - Param { - name: "b".into(), - ty: "tuple".into(), - components: vec![Param { - name: "c".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }], - internal_type: None, - } - ], - internal_type: None, - } - ); + }], + internal_type: None, + } + ], + internal_type: None, + } + ); - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} - #[test] - fn event_param_tuple_array_deserialization() { - let s = r#"{ +#[test] +fn event_param_tuple_array_deserialization() { + let s = r#"{ "components": [ { "type": "uint256", @@ -165,114 +162,113 @@ mod tests { "type": "tuple" }"#; - let deserialized: EventParam = serde_json::from_str(s).unwrap(); + let deserialized: EventParam = serde_json::from_str(s).unwrap(); - assert_eq!( - deserialized, - EventParam { - name: "LogTaskSubmitted".to_owned(), - indexed: false, - ty: "tuple".into(), - components: vec![ - Param { - name: "a".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "b".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "e".into(), - ty: "tuple".into(), - components: vec![ - Param { - name: "c".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "d".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "f".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "n".into(), - ty: "tuple[]".into(), - components: vec![ - Param { - name: "i".into(), - ty: "tuple[]".into(), - components: vec![ - Param { - name: "g".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "h".into(), - ty: "bytes".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "l".into(), - ty: "tuple[]".into(), - components: vec![ - Param { - name: "j".into(), - ty: "address".into(), - components: vec![], - internal_type: None, - }, - Param { - name: "k".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "m".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None, - }, - Param { - name: "o".into(), - ty: "uint256".into(), - components: vec![], - internal_type: None, - }, - ], - internal_type: None - } - ); + assert_eq!( + deserialized, + EventParam { + name: "LogTaskSubmitted".to_owned(), + indexed: false, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "b".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "e".into(), + ty: "tuple".into(), + components: vec![ + Param { + name: "c".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "d".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "f".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "n".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "i".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "g".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "h".into(), + ty: "bytes".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "l".into(), + ty: "tuple[]".into(), + components: vec![ + Param { + name: "j".into(), + ty: "address".into(), + components: vec![], + internal_type: None, + }, + Param { + name: "k".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "m".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None, + }, + Param { + name: "o".into(), + ty: "uint256".into(), + components: vec![], + internal_type: None, + }, + ], + internal_type: None + } + ); - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); } diff --git a/crates/json-abi/tests/json_abi_test.rs b/crates/json-abi/tests/json_abi_test.rs index dca0d2315..5580fb0ee 100644 --- a/crates/json-abi/tests/json_abi_test.rs +++ b/crates/json-abi/tests/json_abi_test.rs @@ -1,38 +1,35 @@ mod test_helpers; -#[cfg(all(test))] -mod test { - use crate::assert_ser_de; - use alloy_json_abi::{ - Constructor, Error, Event, EventParam, Fallback, Function, JsonAbi, Param, Receive, - StateMutability, - }; - use std::collections::BTreeMap; - - #[test] - fn empty() { - let json = "[]"; - - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn constructor() { - let json = r#" +use alloy_json_abi::{ + Constructor, Error, Event, EventParam, Fallback, Function, JsonAbi, Param, Receive, + StateMutability, +}; +use std::collections::BTreeMap; + +#[test] +fn empty() { + let json = "[]"; + + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} + +#[test] +fn constructor() { + let json = r#" [ { "type": "constructor", @@ -47,34 +44,34 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: Some(Constructor { - inputs: vec![Param { - name: "a".to_string(), - internal_type: None, - ty: "address".into(), - components: vec![], - }], - state_mutability: StateMutability::NonPayable - }), - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn functions() { - let json = r#" + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: Some(Constructor { + inputs: vec![Param { + name: "a".to_string(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + state_mutability: StateMutability::NonPayable + }), + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} + +#[test] +fn functions() { + let json = r#" [ { "type": "function", @@ -103,55 +100,55 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::from_iter(vec![ - ( - "foo".into(), - vec![Function { - name: "foo".into(), - inputs: vec![Param { - name: "a".into(), - internal_type: None, - ty: "address".into(), - components: vec![] - }], - outputs: vec![Param { - name: "res".into(), - internal_type: None, - ty: "address".into(), - components: vec![] - }], - state_mutability: StateMutability::NonPayable, - }] - ), - ( - "bar".into(), - vec![Function { - name: "bar".into(), - inputs: vec![], - outputs: vec![], - state_mutability: StateMutability::NonPayable, - }] - ), - ]), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn functions_overloads() { - let json = r#" + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::from_iter(vec![ + ( + "foo".into(), + vec![Function { + name: "foo".into(), + inputs: vec![Param { + name: "a".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + outputs: vec![Param { + name: "res".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + state_mutability: StateMutability::NonPayable, + }] + ), + ( + "bar".into(), + vec![Function { + name: "bar".into(), + inputs: vec![], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }] + ), + ]), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} + +#[test] +fn functions_overloads() { + let json = r#" [ { "type": "function", @@ -180,52 +177,52 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Function { + name: "foo".into(), + inputs: vec![Param { + name: "a".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + }], + outputs: vec![Param { + name: "res".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + }], + state_mutability: StateMutability::NonPayable, + }, + Function { + name: "foo".into(), + inputs: vec![], + outputs: vec![], + state_mutability: StateMutability::NonPayable, + }, + ] + )]), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::from_iter(vec![( - "foo".to_string(), - vec![ - Function { - name: "foo".into(), - inputs: vec![Param { - name: "a".into(), - internal_type: None, - ty: "address".into(), - components: vec![], - }], - outputs: vec![Param { - name: "res".into(), - internal_type: None, - ty: "address".into(), - components: vec![] - }], - state_mutability: StateMutability::NonPayable, - }, - Function { - name: "foo".into(), - inputs: vec![], - outputs: vec![], - state_mutability: StateMutability::NonPayable, - }, - ] - )]), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn events() { - let json = r#" +#[test] +fn events() { + let json = r#" [ { "type": "event", @@ -254,55 +251,55 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::from_iter(vec![ - ( - "foo".into(), - vec![Event { - name: "foo".into(), - inputs: vec![EventParam { - name: "a".into(), - indexed: false, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }] - ), - ( - "bar".to_string(), - vec![Event { - name: "bar".into(), - inputs: vec![EventParam { - name: "a".into(), - indexed: true, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }] - ), - ]), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn events_overload() { - let json = r#" + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::from_iter(vec![ + ( + "foo".into(), + vec![Event { + name: "foo".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: false, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }] + ), + ( + "bar".to_string(), + vec![Event { + name: "bar".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }] + ), + ]), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} + +#[test] +fn events_overload() { + let json = r#" [ { "type": "event", @@ -331,52 +328,52 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Event { + name: "foo".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: false, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }, + Event { + name: "foo".into(), + inputs: vec![EventParam { + name: "a".into(), + indexed: true, + ty: "address".into(), + components: vec![], + internal_type: None + }], + anonymous: false, + }, + ] + )]), + errors: BTreeMap::new(), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::from_iter(vec![( - "foo".to_string(), - vec![ - Event { - name: "foo".into(), - inputs: vec![EventParam { - name: "a".into(), - indexed: false, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }, - Event { - name: "foo".into(), - inputs: vec![EventParam { - name: "a".into(), - indexed: true, - ty: "address".into(), - components: vec![], - internal_type: None - }], - anonymous: false, - }, - ] - )]), - errors: BTreeMap::new(), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn errors() { - let json = r#" +#[test] +fn errors() { + let json = r#" [ { "type": "error", @@ -409,67 +406,67 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::from_iter(vec![ - ( - "foo".to_string(), - vec![Error { - name: "foo".into(), - inputs: vec![ - Param { - name: "available".into(), - internal_type: None, - ty: "uint256".into(), - components: vec![] - }, - Param { - name: "required".into(), - internal_type: None, - ty: "address".into(), - components: vec![], - } - ], - }] - ), - ( - "bar".to_string(), - vec![Error { - name: "bar".into(), - inputs: vec![ - Param { - name: "a".into(), - internal_type: None, - ty: "uint256".into(), - components: vec![] - }, - Param { - name: "b".into(), - internal_type: None, - ty: "address".into(), - components: vec![] - } - ], - }] - ), - ]), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn errors_overload() { - let json = r#" + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::from_iter(vec![ + ( + "foo".to_string(), + vec![Error { + name: "foo".into(), + inputs: vec![ + Param { + name: "available".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![] + }, + Param { + name: "required".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + } + ], + }] + ), + ( + "bar".to_string(), + vec![Error { + name: "bar".into(), + inputs: vec![ + Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![] + }, + Param { + name: "b".into(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ], + }] + ), + ]), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} + +#[test] +fn errors_overload() { + let json = r#" [ { "type": "error", @@ -498,56 +495,56 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::from_iter(vec![( - "foo".to_string(), - vec![ - Error { - name: "foo".into(), - inputs: vec![Param { + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::from_iter(vec![( + "foo".to_string(), + vec![ + Error { + name: "foo".into(), + inputs: vec![Param { + name: "a".into(), + internal_type: None, + ty: "uint256".into(), + components: vec![], + }], + }, + Error { + name: "foo".into(), + inputs: vec![ + Param { name: "a".into(), internal_type: None, ty: "uint256".into(), components: vec![], - }], - }, - Error { - name: "foo".into(), - inputs: vec![ - Param { - name: "a".into(), - internal_type: None, - ty: "uint256".into(), - components: vec![], - }, - Param { - name: "b".into(), - internal_type: None, - ty: "address".into(), - components: vec![], - } - ], - }, - ] - ),]), - receive: None, - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn receive() { - let json = r#" + }, + Param { + name: "b".into(), + internal_type: None, + ty: "address".into(), + components: vec![], + } + ], + }, + ] + ),]), + receive: None, + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} + +#[test] +fn receive() { + let json = r#" [ { "type": "receive", @@ -556,28 +553,28 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: Some(Receive { - state_mutability: StateMutability::NonPayable, - }), - fallback: None, - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } - - #[test] - fn fallback() { - let json = r#" + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: Some(Receive { + state_mutability: StateMutability::NonPayable, + }), + fallback: None, + } + ); + + assert_ser_de!(JsonAbi, deserialized); +} + +#[test] +fn fallback() { + let json = r#" [ { "type": "fallback", @@ -586,22 +583,21 @@ mod test { ] "#; - let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); - - assert_eq!( - deserialized, - JsonAbi { - constructor: None, - functions: BTreeMap::new(), - events: BTreeMap::new(), - errors: BTreeMap::new(), - receive: None, - fallback: Some(Fallback { - state_mutability: StateMutability::NonPayable, - }), - } - ); - - assert_ser_de!(JsonAbi, deserialized); - } + let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); + + assert_eq!( + deserialized, + JsonAbi { + constructor: None, + functions: BTreeMap::new(), + events: BTreeMap::new(), + errors: BTreeMap::new(), + receive: None, + fallback: Some(Fallback { + state_mutability: StateMutability::NonPayable, + }), + } + ); + + assert_ser_de!(JsonAbi, deserialized); } diff --git a/crates/json-abi/tests/param_tests.rs b/crates/json-abi/tests/param_tests.rs index b854bda0d..ab99249fa 100644 --- a/crates/json-abi/tests/param_tests.rs +++ b/crates/json-abi/tests/param_tests.rs @@ -1,60 +1,58 @@ mod test_helpers; -mod tests { - use crate::{assert_json_eq, assert_ser_de}; - use alloy_json_abi::{InternalType::Struct, Param}; +use alloy_json_abi::{InternalType::Struct, Param}; - #[test] - fn param_simple() { - let s = r#"{ +#[test] +fn param_simple() { + let s = r#"{ "name": "foo", "type": "address" }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); + let deserialized: Param = serde_json::from_str(s).unwrap(); - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - } - ); + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ); - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} - #[test] - fn param_simple_internal_type() { - let s = r#"{ +#[test] +fn param_simple_internal_type() { + let s = r#"{ "name": "foo", "type": "address", "internalType": "struct Verifier.Proof" }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: Some(Struct { - contract: Some("Verifier".into()), - ty: "Proof".into(), - }), - ty: "address".into(), - components: vec![] - } - ); - - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } - - #[test] - fn param_tuple() { - let s = r#"{ + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: Some(Struct { + contract: Some("Verifier".into()), + ty: "Proof".into(), + }), + ty: "address".into(), + components: vec![] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} + +#[test] +fn param_tuple() { + let s = r#"{ "name": "foo", "type": "tuple", "components": [ @@ -75,42 +73,42 @@ mod tests { ] }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: None, - ty: "tuple".into(), - components: vec![ - Param { - name: "a".to_owned(), + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![], + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![Param { + name: "c".to_owned(), internal_type: None, - ty: "uint48".into(), + ty: "address".into(), components: vec![], - }, - Param { - name: "b".to_owned(), - internal_type: None, - ty: "tuple".into(), - components: vec![Param { - name: "c".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![], - },], - }, - ] - } - ); - - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } - - #[test] - fn param_tuple_internal_type() { - let s = r#"{ + },], + }, + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} + +#[test] +fn param_tuple_internal_type() { + let s = r#"{ "name": "foo", "type": "tuple", "internalType": "struct Pairing.G1Point[]", @@ -132,45 +130,45 @@ mod tests { ] }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: Some(Struct { - contract: Some("Pairing".into()), - ty: "G1Point[]".into(), - }), - ty: "tuple".into(), - components: vec![ - Param { - name: "a".to_owned(), + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: Some(Struct { + contract: Some("Pairing".into()), + ty: "G1Point[]".into(), + }), + ty: "tuple".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![Param { + name: "c".to_owned(), internal_type: None, - ty: "uint48".into(), + ty: "address".into(), components: vec![] - }, - Param { - name: "b".to_owned(), - internal_type: None, - ty: "tuple".into(), - components: vec![Param { - name: "c".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - }] - } - ] - } - ); - - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } - - #[test] - fn param_tuple_named() { - let s = r#"{ + }] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} + +#[test] +fn param_tuple_named() { + let s = r#"{ "name": "foo", "type": "tuple", "components": [ @@ -191,42 +189,42 @@ mod tests { ] }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: None, - ty: "tuple".into(), - components: vec![ - Param { - name: "amount".to_owned(), + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![ + Param { + name: "amount".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "things".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![Param { + name: "baseTupleParam".to_owned(), internal_type: None, - ty: "uint48".into(), + ty: "address".into(), components: vec![] - }, - Param { - name: "things".to_owned(), - internal_type: None, - ty: "tuple".into(), - components: vec![Param { - name: "baseTupleParam".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - },] - }, - ] - } - ); - - assert_ser_de!(Param, deserialized); - } - - #[test] - fn param_tuple_array() { - let s = r#"{ + },] + }, + ] + } + ); + + assert_ser_de!(Param, deserialized); +} + +#[test] +fn param_tuple_array() { + let s = r#"{ "name": "foo", "type": "tuple[]", "components": [ @@ -245,43 +243,43 @@ mod tests { ] }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: None, - ty: "tuple[]".into(), - components: vec![ - Param { - name: "a".to_owned(), - internal_type: None, - ty: "uint48".into(), - components: vec![] - }, - Param { - name: "b".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - }, - Param { - name: "c".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - } - ] - } - ); - - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple[]".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + }, + Param { + name: "c".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} - #[test] - fn param_array_of_array_of_tuple() { - let s = r#"{ +#[test] +fn param_array_of_array_of_tuple() { + let s = r#"{ "name": "foo", "type": "tuple[][]", "components": [ @@ -296,36 +294,36 @@ mod tests { ] }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: None, - ty: "tuple[][]".into(), - components: vec![ - Param { - name: "a".to_owned(), - internal_type: None, - ty: "uint8".into(), - components: vec![] - }, - Param { - name: "b".to_owned(), - internal_type: None, - ty: "uint16".into(), - components: vec![] - } - ] - } - ); - - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + let deserialized: Param = serde_json::from_str(s).unwrap(); + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple[][]".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint8".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "uint16".into(), + components: vec![] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} - #[test] - fn param_tuple_fixed_array() { - let s = r#"{ +#[test] +fn param_tuple_fixed_array() { + let s = r#"{ "name": "foo", "type": "tuple[2]", "components": [ @@ -344,43 +342,43 @@ mod tests { ] }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: None, - ty: "tuple[2]".into(), - components: vec![ - Param { - name: "a".to_owned(), - internal_type: None, - ty: "uint48".into(), - components: vec![] - }, - Param { - name: "b".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - }, - Param { - name: "c".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - } - ] - } - ); - - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple[2]".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "uint48".into(), + components: vec![] + }, + Param { + name: "b".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + }, + Param { + name: "c".to_owned(), + internal_type: None, + ty: "address".into(), + components: vec![] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); +} - #[test] - fn param_tuple_with_nested_tuple_arrays() { - let s = r#"{ +#[test] +fn param_tuple_with_nested_tuple_arrays() { + let s = r#"{ "name": "foo", "type": "tuple", "components": [ @@ -407,41 +405,40 @@ mod tests { ] }"#; - let deserialized: Param = serde_json::from_str(s).unwrap(); - - assert_eq!( - deserialized, - Param { - name: "foo".to_owned(), - internal_type: None, - ty: "tuple".into(), - components: vec![ - Param { - name: "a".to_owned(), + let deserialized: Param = serde_json::from_str(s).unwrap(); + + assert_eq!( + deserialized, + Param { + name: "foo".to_owned(), + internal_type: None, + ty: "tuple".into(), + components: vec![ + Param { + name: "a".to_owned(), + internal_type: None, + ty: "tuple[]".into(), + components: vec![Param { + name: "b".to_owned(), internal_type: None, - ty: "tuple[]".into(), - components: vec![Param { - name: "b".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - },] - }, - Param { - name: "c".to_owned(), + ty: "address".into(), + components: vec![] + },] + }, + Param { + name: "c".to_owned(), + internal_type: None, + ty: "tuple[42]".into(), + components: vec![Param { + name: "d".to_owned(), internal_type: None, - ty: "tuple[42]".into(), - components: vec![Param { - name: "d".to_owned(), - internal_type: None, - ty: "address".into(), - components: vec![] - }] - } - ] - } - ); - - assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); - } + ty: "address".into(), + components: vec![] + }] + } + ] + } + ); + + assert_json_eq!(s, serde_json::to_string(&deserialized).unwrap().as_str()); } diff --git a/crates/json-abi/tests/state_mutability_test.rs b/crates/json-abi/tests/state_mutability_test.rs index 0c7d525e5..dd978fb8b 100644 --- a/crates/json-abi/tests/state_mutability_test.rs +++ b/crates/json-abi/tests/state_mutability_test.rs @@ -1,13 +1,10 @@ mod test_helpers; -#[cfg(all(test))] -mod test { - use crate::assert_json_eq; - use alloy_json_abi::StateMutability; +use alloy_json_abi::StateMutability; - #[test] - fn state_mutability() { - let json = r#" +#[test] +fn state_mutability() { + let json = r#" [ "pure", "view", @@ -16,18 +13,17 @@ mod test { ] "#; - let deserialized: Vec = serde_json::from_str(json).unwrap(); + let deserialized: Vec = serde_json::from_str(json).unwrap(); - assert_eq!( - deserialized, - vec![ - StateMutability::Pure, - StateMutability::View, - StateMutability::NonPayable, - StateMutability::Payable, - ] - ); + assert_eq!( + deserialized, + vec![ + StateMutability::Pure, + StateMutability::View, + StateMutability::NonPayable, + StateMutability::Payable, + ] + ); - assert_json_eq!(json, &serde_json::to_string(&deserialized).unwrap()); - } + assert_json_eq!(json, &serde_json::to_string(&deserialized).unwrap()); } From 48264ee49af8abe0aa84022e5e514b27a8311fb9 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 16 Aug 2023 18:47:24 +0300 Subject: [PATCH 11/13] fix indenting issue --- crates/json-abi/tests/abi_item_test.rs | 123 +++---- crates/json-abi/tests/event_param_test.rs | 114 +++---- crates/json-abi/tests/json_abi_test.rs | 306 +++++++++--------- crates/json-abi/tests/param_tests.rs | 274 ++++++++-------- .../json-abi/tests/state_mutability_test.rs | 14 +- 5 files changed, 416 insertions(+), 415 deletions(-) diff --git a/crates/json-abi/tests/abi_item_test.rs b/crates/json-abi/tests/abi_item_test.rs index 28f0f4612..a6be6cfae 100644 --- a/crates/json-abi/tests/abi_item_test.rs +++ b/crates/json-abi/tests/abi_item_test.rs @@ -10,15 +10,15 @@ use std::borrow::Cow; #[test] fn operation() { let s = r#"{ - "type":"function", - "inputs": [{ - "name":"a", - "type":"address" - }], - "name":"foo", - "outputs": [], + "type":"function", + "inputs": [{ + "name":"a", + "type":"address" + }], + "name":"foo", + "outputs": [], "stateMutability": "nonpayable" - }"#; + }"#; let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); @@ -45,41 +45,41 @@ fn operation() { #[test] fn event_operation_with_tuple_array_input() { let s = r#"{ - "type":"event", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed":true - }, - { - "components": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "indexed": false, - "internalType": "struct Action[]", - "name": "b", - "type": "tuple[]" - } - ], - "name":"E", - "outputs": [], - "anonymous": false - }"#; + "type":"event", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed":true + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct Action[]", + "name": "b", + "type": "tuple[]" + } + ], + "name":"E", + "outputs": [], + "anonymous": false + }"#; let deserialized: AbiItem<'static> = serde_json::from_str(s).unwrap(); @@ -144,14 +144,14 @@ fn event_operation_with_tuple_array_input() { // fn test_sanitize_function_name(name: &str, expected: &str) { // let s = format!( // r#"{{ -// "type":"function", -// "inputs": [{{ -// "name":"a", -// "type":"address" -// }}], -// "name":"{}", -// "outputs": [] -// }}"#, +// "type":"function", +// "inputs": [{{ +// "name":"a", +// "type":"address" +// }}], +// "name":"{}", +// "outputs": [] +// }}"#, // name // ); @@ -177,16 +177,16 @@ fn event_operation_with_tuple_array_input() { // fn test_sanitize_event_name(name: &str, expected: &str) { // let s = format!( // r#"{{ -// "type":"event", -// "inputs": [{{ -// "name":"a", -// "type":"address", -// "indexed":true -// }}], -// "name":"{}", -// "outputs": [], -// "anonymous": false -// }}"#, +// "type":"event", +// "inputs": [{{ +// "name":"a", +// "type":"address", +// "indexed":true +// }}], +// "name":"{}", +// "outputs": [], +// "anonymous": false +// }}"#, // name // ); @@ -206,3 +206,4 @@ fn event_operation_with_tuple_array_input() { // test_sanitize_event_name("()", ""); // test_sanitize_event_name("", ""); // } + diff --git a/crates/json-abi/tests/event_param_test.rs b/crates/json-abi/tests/event_param_test.rs index efd2ca89f..0f1def5e1 100644 --- a/crates/json-abi/tests/event_param_test.rs +++ b/crates/json-abi/tests/event_param_test.rs @@ -5,10 +5,10 @@ use alloy_json_abi::{EventParam, Param}; #[test] fn event_param_deserialization() { let s = r#"{ - "name": "foo", - "type": "address", - "indexed": true - }"#; + "name": "foo", + "type": "address", + "indexed": true + }"#; let deserialized: EventParam = serde_json::from_str(s).unwrap(); @@ -29,26 +29,26 @@ fn event_param_deserialization() { #[test] fn event_param_tuple_deserialization() { let s = r#"{ - "name": "foo", - "type": "tuple", - "indexed": true, - "components": [ - { + "name": "foo", + "type": "tuple", + "indexed": true, + "components": [ + { "name": "a", - "type": "uint48" - }, - { + "type": "uint48" + }, + { "name": "b", - "type": "tuple", - "components": [ - { + "type": "tuple", + "components": [ + { "name": "c", - "type": "address" - } - ] - } - ] - }"#; + "type": "address" + } + ] + } + ] + }"#; let deserialized: EventParam = serde_json::from_str(s).unwrap(); @@ -87,79 +87,79 @@ fn event_param_tuple_deserialization() { #[test] fn event_param_tuple_array_deserialization() { let s = r#"{ - "components": [ - { + "components": [ + { "type": "uint256", "name": "a" }, - { + { "type": "address", "name": "b" }, - { - "components": [ - { + { + "components": [ + { "type": "address", "name": "c" }, - { + { "type": "address", "name": "d" } - ], - "type": "tuple", + ], + "type": "tuple", "name": "e" - }, - { + }, + { "type": "uint256", "name": "f" }, - { - "components": [ - { - "components": [ - { + { + "components": [ + { + "components": [ + { "type": "address", "name": "g" }, - { + { "type": "bytes", "name": "h" } - ], - "type": "tuple[]", + ], + "type": "tuple[]", "name": "i" - }, - { - "components": [ - { + }, + { + "components": [ + { "type": "address", "name": "j" }, - { + { "type": "uint256", "name": "k" } - ], - "type": "tuple[]", + ], + "type": "tuple[]", "name": "l" - }, - { + }, + { "type": "uint256", "name": "m" } - ], - "type": "tuple[]", + ], + "type": "tuple[]", "name": "n" - }, - { + }, + { "type": "uint256", "name": "o" } - ], - "indexed": false, - "name": "LogTaskSubmitted", - "type": "tuple" + ], + "indexed": false, + "name": "LogTaskSubmitted", + "type": "tuple" }"#; let deserialized: EventParam = serde_json::from_str(s).unwrap(); diff --git a/crates/json-abi/tests/json_abi_test.rs b/crates/json-abi/tests/json_abi_test.rs index 5580fb0ee..1eeaa799f 100644 --- a/crates/json-abi/tests/json_abi_test.rs +++ b/crates/json-abi/tests/json_abi_test.rs @@ -30,19 +30,19 @@ fn empty() { #[test] fn constructor() { let json = r#" - [ - { - "type": "constructor", - "inputs": [ - { - "name":"a", - "type":"address" - } - ], - "stateMutability": "nonpayable" - } - ] - "#; + [ + { + "type": "constructor", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "stateMutability": "nonpayable" + } + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -72,33 +72,33 @@ fn constructor() { #[test] fn functions() { let json = r#" - [ - { - "type": "function", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address" - } - ], - "outputs": [ - { - "name": "res", - "type":"address" - } - ], + [ + { + "type": "function", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "outputs": [ + { + "name": "res", + "type":"address" + } + ], "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "bar", - "inputs": [], - "outputs": [], + }, + { + "type": "function", + "name": "bar", + "inputs": [], + "outputs": [], "stateMutability": "nonpayable" - } - ] - "#; + } + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -149,33 +149,33 @@ fn functions() { #[test] fn functions_overloads() { let json = r#" - [ - { - "type": "function", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address" - } - ], - "outputs": [ - { - "name": "res", - "type":"address" - } - ], + [ + { + "type": "function", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address" + } + ], + "outputs": [ + { + "name": "res", + "type":"address" + } + ], "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "foo", - "inputs": [], - "outputs": [], + }, + { + "type": "function", + "name": "foo", + "inputs": [], + "outputs": [], "stateMutability": "nonpayable" - } - ] - "#; + } + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -223,33 +223,33 @@ fn functions_overloads() { #[test] fn events() { let json = r#" - [ - { - "type": "event", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": false - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "bar", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": true - } - ], - "anonymous": false - } - ] - "#; + [ + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "bar", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": true + } + ], + "anonymous": false + } + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -300,33 +300,33 @@ fn events() { #[test] fn events_overload() { let json = r#" - [ - { - "type": "event", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": false - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "foo", - "inputs": [ - { - "name":"a", - "type":"address", - "indexed": true - } - ], - "anonymous": false - } - ] - "#; + [ + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "foo", + "inputs": [ + { + "name":"a", + "type":"address", + "indexed": true + } + ], + "anonymous": false + } + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -404,7 +404,7 @@ fn errors() { "name": "bar" } ] - "#; + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -467,33 +467,33 @@ fn errors() { #[test] fn errors_overload() { let json = r#" - [ - { - "type": "error", - "inputs": [ - { - "name": "a", - "type": "uint256" - } - ], - "name": "foo" - }, - { - "type": "error", - "inputs": [ - { - "name": "a", - "type": "uint256" - }, - { - "name": "b", - "type": "address" - } - ], - "name": "foo" - } - ] - "#; + [ + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + } + ], + "name": "foo" + }, + { + "type": "error", + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "address" + } + ], + "name": "foo" + } + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -545,13 +545,13 @@ fn errors_overload() { #[test] fn receive() { let json = r#" - [ - { + [ + { "type": "receive", "stateMutability": "nonpayable" } - ] - "#; + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); @@ -575,13 +575,13 @@ fn receive() { #[test] fn fallback() { let json = r#" - [ - { + [ + { "type": "fallback", "stateMutability": "nonpayable" } - ] - "#; + ] + "#; let deserialized: JsonAbi = serde_json::from_str(json).unwrap(); diff --git a/crates/json-abi/tests/param_tests.rs b/crates/json-abi/tests/param_tests.rs index ab99249fa..6ff171a95 100644 --- a/crates/json-abi/tests/param_tests.rs +++ b/crates/json-abi/tests/param_tests.rs @@ -5,9 +5,9 @@ use alloy_json_abi::{InternalType::Struct, Param}; #[test] fn param_simple() { let s = r#"{ - "name": "foo", - "type": "address" - }"#; + "name": "foo", + "type": "address" + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); @@ -27,10 +27,10 @@ fn param_simple() { #[test] fn param_simple_internal_type() { let s = r#"{ - "name": "foo", - "type": "address", - "internalType": "struct Verifier.Proof" - }"#; + "name": "foo", + "type": "address", + "internalType": "struct Verifier.Proof" + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); @@ -53,25 +53,25 @@ fn param_simple_internal_type() { #[test] fn param_tuple() { let s = r#"{ - "name": "foo", - "type": "tuple", - "components": [ - { - "name": "a", - "type": "uint48" - }, - { - "name": "b", - "type": "tuple", - "components": [ - { - "type": "address", - "name": "c" - } - ] - } - ] - }"#; + "name": "foo", + "type": "tuple", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "tuple", + "components": [ + { + "type": "address", + "name": "c" + } + ] + } + ] + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); @@ -109,26 +109,26 @@ fn param_tuple() { #[test] fn param_tuple_internal_type() { let s = r#"{ - "name": "foo", - "type": "tuple", - "internalType": "struct Pairing.G1Point[]", - "components": [ - { - "name": "a", - "type": "uint48" - }, - { - "name": "b", - "type": "tuple", - "components": [ - { - "name": "c", - "type": "address" - } - ] - } - ] - }"#; + "name": "foo", + "type": "tuple", + "internalType": "struct Pairing.G1Point[]", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "tuple", + "components": [ + { + "name": "c", + "type": "address" + } + ] + } + ] + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); @@ -169,25 +169,25 @@ fn param_tuple_internal_type() { #[test] fn param_tuple_named() { let s = r#"{ - "name": "foo", - "type": "tuple", - "components": [ - { - "name": "amount", - "type": "uint48" - }, - { - "name": "things", - "type": "tuple", - "components": [ - { - "name": "baseTupleParam", - "type": "address" - } - ] - } - ] - }"#; + "name": "foo", + "type": "tuple", + "components": [ + { + "name": "amount", + "type": "uint48" + }, + { + "name": "things", + "type": "tuple", + "components": [ + { + "name": "baseTupleParam", + "type": "address" + } + ] + } + ] + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); @@ -225,23 +225,23 @@ fn param_tuple_named() { #[test] fn param_tuple_array() { let s = r#"{ - "name": "foo", - "type": "tuple[]", - "components": [ - { - "name": "a", - "type": "uint48" - }, - { - "name": "b", - "type": "address" - }, - { - "name": "c", - "type": "address" - } - ] - }"#; + "name": "foo", + "type": "tuple[]", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "address" + }, + { + "name": "c", + "type": "address" + } + ] + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); @@ -280,19 +280,19 @@ fn param_tuple_array() { #[test] fn param_array_of_array_of_tuple() { let s = r#"{ - "name": "foo", - "type": "tuple[][]", - "components": [ - { - "name": "a", - "type": "uint8" - }, - { - "name": "b", - "type": "uint16" - } - ] - }"#; + "name": "foo", + "type": "tuple[][]", + "components": [ + { + "name": "a", + "type": "uint8" + }, + { + "name": "b", + "type": "uint16" + } + ] + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); assert_eq!( @@ -324,23 +324,23 @@ fn param_array_of_array_of_tuple() { #[test] fn param_tuple_fixed_array() { let s = r#"{ - "name": "foo", - "type": "tuple[2]", - "components": [ - { - "name": "a", - "type": "uint48" - }, - { - "name": "b", - "type": "address" - }, - { - "name": "c", - "type": "address" - } - ] - }"#; + "name": "foo", + "type": "tuple[2]", + "components": [ + { + "name": "a", + "type": "uint48" + }, + { + "name": "b", + "type": "address" + }, + { + "name": "c", + "type": "address" + } + ] + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); @@ -379,31 +379,31 @@ fn param_tuple_fixed_array() { #[test] fn param_tuple_with_nested_tuple_arrays() { let s = r#"{ - "name": "foo", - "type": "tuple", - "components": [ - { - "name": "a", - "type": "tuple[]", - "components": [ - { - "name": "b", - "type": "address" - } - ] - }, - { - "name": "c", - "type": "tuple[42]", - "components": [ - { - "name": "d", - "type": "address" - } - ] - } - ] - }"#; + "name": "foo", + "type": "tuple", + "components": [ + { + "name": "a", + "type": "tuple[]", + "components": [ + { + "name": "b", + "type": "address" + } + ] + }, + { + "name": "c", + "type": "tuple[42]", + "components": [ + { + "name": "d", + "type": "address" + } + ] + } + ] + }"#; let deserialized: Param = serde_json::from_str(s).unwrap(); diff --git a/crates/json-abi/tests/state_mutability_test.rs b/crates/json-abi/tests/state_mutability_test.rs index dd978fb8b..3ca406571 100644 --- a/crates/json-abi/tests/state_mutability_test.rs +++ b/crates/json-abi/tests/state_mutability_test.rs @@ -5,13 +5,13 @@ use alloy_json_abi::StateMutability; #[test] fn state_mutability() { let json = r#" - [ - "pure", - "view", - "nonpayable", - "payable" - ] - "#; + [ + "pure", + "view", + "nonpayable", + "payable" + ] + "#; let deserialized: Vec = serde_json::from_str(json).unwrap(); From a3e99e9f6c2a67d19eb31eafd339a32639eb565c Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 16 Aug 2023 19:54:15 +0300 Subject: [PATCH 12/13] apply cargo fmt --- crates/json-abi/tests/abi_item_test.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/json-abi/tests/abi_item_test.rs b/crates/json-abi/tests/abi_item_test.rs index a6be6cfae..1bdd5a258 100644 --- a/crates/json-abi/tests/abi_item_test.rs +++ b/crates/json-abi/tests/abi_item_test.rs @@ -206,4 +206,3 @@ fn event_operation_with_tuple_array_input() { // test_sanitize_event_name("()", ""); // test_sanitize_event_name("", ""); // } - From 04c8e9d0538cb41085fdd0f80b6edf2f46881fea Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 23 Aug 2023 20:30:49 +0300 Subject: [PATCH 13/13] remove sanitize name tests --- crates/json-abi/tests/abi_item_test.rs | 68 -------------------------- 1 file changed, 68 deletions(-) diff --git a/crates/json-abi/tests/abi_item_test.rs b/crates/json-abi/tests/abi_item_test.rs index 1bdd5a258..685d6cda7 100644 --- a/crates/json-abi/tests/abi_item_test.rs +++ b/crates/json-abi/tests/abi_item_test.rs @@ -138,71 +138,3 @@ fn event_operation_with_tuple_array_input() { assert_eq!(deserialized, AbiItem::Event(Cow::Owned(event))); assert_ser_de!(AbiItem<'_>, deserialized); } - -// #[test] -// fn sanitize_function_name() { -// fn test_sanitize_function_name(name: &str, expected: &str) { -// let s = format!( -// r#"{{ -// "type":"function", -// "inputs": [{{ -// "name":"a", -// "type":"address" -// }}], -// "name":"{}", -// "outputs": [] -// }}"#, -// name -// ); - -// let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); -// let function = match &deserialized { -// AbiItem::Function(f) => f, -// _ => panic!("expected function"), -// }; - -// assert_eq!(function.name, expected); - -// assert_ser_de!(deserialized); -// } - -// test_sanitize_function_name("foo", "foo"); -// test_sanitize_function_name("foo()", "foo"); -// test_sanitize_function_name("()", ""); -// test_sanitize_function_name("", ""); -// } - -// #[test] -// fn sanitize_event_name() { -// fn test_sanitize_event_name(name: &str, expected: &str) { -// let s = format!( -// r#"{{ -// "type":"event", -// "inputs": [{{ -// "name":"a", -// "type":"address", -// "indexed":true -// }}], -// "name":"{}", -// "outputs": [], -// "anonymous": false -// }}"#, -// name -// ); - -// let deserialized: AbiItem = serde_json::from_str(&s).unwrap(); -// let event = match deserialized { -// AbiItem::Event(e) => e, -// _ => panic!("expected event!"), -// }; - -// assert_eq!(event.name, expected); - -// assert_ser_de!(AbiItem::Event(event.clone())); -// } - -// test_sanitize_event_name("foo", "foo"); -// test_sanitize_event_name("foo()", "foo"); -// test_sanitize_event_name("()", ""); -// test_sanitize_event_name("", ""); -// }