Compare commits

..

1 Commits

Author SHA1 Message Date
Omar Abdulla 9676fca3fe Support compiler-version aware exceptions 2025-07-25 17:06:14 +03:00
5 changed files with 22 additions and 97 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
edition = "2024" edition = "2024"
repository = "https://github.com/paritytech/revive-differential-testing.git" repository = "https://github.com/paritytech/revive-differential-testing.git"
rust-version = "1.88.0" rust-version = "1.85.0"
[workspace.dependencies] [workspace.dependencies]
revive-dt-common = { version = "0.1.0", path = "crates/common" } revive-dt-common = { version = "0.1.0", path = "crates/common" }
+5 -34
View File
@@ -3,7 +3,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::str::FromStr;
use alloy::json_abi::JsonAbi; use alloy::json_abi::JsonAbi;
use alloy::network::{Ethereum, TransactionBuilder}; use alloy::network::{Ethereum, TransactionBuilder};
@@ -101,30 +100,12 @@ where
anyhow::bail!("unsupported solc version: {:?}", &mode.solc_version); anyhow::bail!("unsupported solc version: {:?}", &mode.solc_version);
}; };
// Note: if the metadata is contained within a solidity file then this is the only file that
// we wish to compile since this is a self-contained test. Otherwise, if it's a JSON file
// then we need to compile all of the contracts that are in the directory since imports are
// allowed in there.
let Some(ref metadata_file_path) = metadata.file_path else {
anyhow::bail!("The metadata file path is not defined");
};
let mut files_to_compile = if metadata_file_path
.extension()
.is_some_and(|extension| extension.eq_ignore_ascii_case("sol"))
{
Box::new(std::iter::once(metadata_file_path.clone())) as Box<dyn Iterator<Item = _>>
} else {
Box::new(
FilesWithExtensionIterator::new(metadata.directory()?)
.with_allowed_extension("sol"),
)
};
let compiler = Compiler::<T::Compiler>::new() let compiler = Compiler::<T::Compiler>::new()
.allow_path(metadata.directory()?) .allow_path(metadata.directory()?)
.solc_optimizer(mode.solc_optimize()); .solc_optimizer(mode.solc_optimize());
let mut compiler = let mut compiler = FilesWithExtensionIterator::new(metadata.directory()?)
files_to_compile.try_fold(compiler, |compiler, path| compiler.with_source(&path))?; .with_allowed_extension("sol")
.try_fold(compiler, |compiler, path| compiler.with_source(&path))?;
for (library_instance, (library_address, _)) in self.deployed_libraries.iter() { for (library_instance, (library_address, _)) in self.deployed_libraries.iter() {
let library_ident = &metadata let library_ident = &metadata
.contracts .contracts
@@ -458,18 +439,8 @@ where
expected_events.iter().zip(execution_receipt.logs()) expected_events.iter().zip(execution_receipt.logs())
{ {
// Handling the emitter assertion. // Handling the emitter assertion.
if let Some(ref expected_address) = expected_event.address { if let Some(expected_address) = expected_event.address {
let expected = if let Some(contract_instance) = expected_address let expected = expected_address;
.strip_suffix(".address")
.map(ContractInstance::new)
{
deployed_contracts
.get(&contract_instance)
.map(|(address, _)| *address)
} else {
Address::from_str(expected_address).ok()
}
.context("Failed to get the address of the event")?;
let actual = actual_event.address(); let actual = actual_event.address();
if actual != expected { if actual != expected {
tracing::error!( tracing::error!(
+14 -11
View File
@@ -28,19 +28,13 @@ impl Corpus {
} }
} }
/// If `path` is a file, try to parse it directly into a [MetadataFile]. /// Recursively walks `path` and parses any JSON or Solidity file into a test
/// Else, recursively walk through the `path` directory and parse any /// definition [Metadata].
/// JSON or Solidity file into a test definition [MetadataFile].
/// ///
/// Found tests are inserted into `tests`. /// Found tests are inserted into `tests`.
///
/// `path` is expected to be a directory.
pub fn collect_metadata(path: &Path, tests: &mut Vec<MetadataFile>) { pub fn collect_metadata(path: &Path, tests: &mut Vec<MetadataFile>) {
if path.is_file()
&& let Some(metadata) = MetadataFile::try_from_file(&path)
{
tests.push(metadata);
return;
}
let dir_entry = match std::fs::read_dir(path) { let dir_entry = match std::fs::read_dir(path) {
Ok(dir_entry) => dir_entry, Ok(dir_entry) => dir_entry,
Err(error) => { Err(error) => {
@@ -59,6 +53,15 @@ pub fn collect_metadata(path: &Path, tests: &mut Vec<MetadataFile>) {
}; };
let path = entry.path(); let path = entry.path();
collect_metadata(&path, tests); if path.is_dir() {
collect_metadata(&path, tests);
continue;
}
if path.is_file() {
if let Some(metadata) = MetadataFile::try_from_file(&path) {
tests.push(metadata)
}
}
} }
} }
+1 -50
View File
@@ -51,7 +51,7 @@ pub struct ExpectedOutput {
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct Event { pub struct Event {
pub address: Option<String>, pub address: Option<Address>,
pub topics: Vec<String>, pub topics: Vec<String>,
pub values: Calldata, pub values: Calldata,
} }
@@ -1010,53 +1010,4 @@ mod tests {
// Assert // Assert
assert!(resolved.is_err()) assert!(resolved.is_err())
} }
#[test]
fn expected_json_can_be_deserialized1() {
// Arrange
let str = r#"
{
"return_data": [
"1"
],
"events": [
{
"topics": [],
"values": []
}
]
}
"#;
// Act
let expected = serde_json::from_str::<Expected>(str);
// Assert
expected.expect("Failed to deserialize");
}
#[test]
fn expected_json_can_be_deserialized2() {
// Arrange
let str = r#"
{
"return_data": [
"1"
],
"events": [
{
"address": "Main.address",
"topics": [],
"values": []
}
]
}
"#;
// Act
let expected = serde_json::from_str::<Expected>(str);
// Assert
expected.expect("Failed to deserialize");
}
} }
+1 -1
View File
@@ -193,7 +193,7 @@ impl Metadata {
metadata.file_path = Some(path.to_path_buf()); metadata.file_path = Some(path.to_path_buf());
metadata.contracts = Some( metadata.contracts = Some(
[( [(
ContractInstance::new("Test"), ContractInstance::new("test"),
ContractPathAndIdent { ContractPathAndIdent {
contract_source_path: path.to_path_buf(), contract_source_path: path.to_path_buf(),
contract_ident: ContractIdent::new("Test"), contract_ident: ContractIdent::new("Test"),