mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-06-12 03:01:12 +00:00
Add a common crate (#75)
* Add a barebones common crate * Refactor some code into the common crate * Add a `ResolverApi` interface. This commit adds a `ResolverApi` trait to the `format` crate that can be implemented by any type that can act as a resolver. A resolver is able to provide information on the chain state. This chain state could be fresh or it could be cached (which is something that we will do in a future PR). This cleans up our crate graph so that `format` is not depending on the node interactions crate for the `EthereumNode` trait. * Cleanup the blocking executor
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
use std::{borrow::Cow, collections::HashSet, path::PathBuf};
|
||||
|
||||
/// An iterator that finds files of a certain extension in the provided directory. You can think of
|
||||
/// this a glob pattern similar to: `${path}/**/*.md`
|
||||
pub struct FilesWithExtensionIterator {
|
||||
/// The set of allowed extensions that that match the requirement and that should be returned
|
||||
/// when found.
|
||||
allowed_extensions: HashSet<Cow<'static, str>>,
|
||||
|
||||
/// The set of directories to visit next. This iterator does BFS and so these directories will
|
||||
/// only be visited if we can't find any files in our state.
|
||||
directories_to_search: Vec<PathBuf>,
|
||||
|
||||
/// The set of files matching the allowed extensions that were found. If there are entries in
|
||||
/// this vector then they will be returned when the [`Iterator::next`] method is called. If not
|
||||
/// then we visit one of the next directories to visit.
|
||||
files_matching_allowed_extensions: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl FilesWithExtensionIterator {
|
||||
pub fn new(root_directory: PathBuf) -> Self {
|
||||
Self {
|
||||
allowed_extensions: Default::default(),
|
||||
directories_to_search: vec![root_directory],
|
||||
files_matching_allowed_extensions: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_allowed_extension(
|
||||
mut self,
|
||||
allowed_extension: impl Into<Cow<'static, str>>,
|
||||
) -> Self {
|
||||
self.allowed_extensions.insert(allowed_extension.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for FilesWithExtensionIterator {
|
||||
type Item = PathBuf;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(file_path) = self.files_matching_allowed_extensions.pop() {
|
||||
return Some(file_path);
|
||||
};
|
||||
|
||||
let directory_to_search = self.directories_to_search.pop()?;
|
||||
|
||||
// Read all of the entries in the directory. If we failed to read this dir's entires then we
|
||||
// elect to just ignore it and look in the next directory, we do that by calling the next
|
||||
// method again on the iterator, which is an intentional decision that we made here instead
|
||||
// of panicking.
|
||||
let Ok(dir_entries) = std::fs::read_dir(directory_to_search) else {
|
||||
return self.next();
|
||||
};
|
||||
|
||||
for entry in dir_entries.flatten() {
|
||||
let entry_path = entry.path();
|
||||
if entry_path.is_dir() {
|
||||
self.directories_to_search.push(entry_path)
|
||||
} else if entry_path.is_file()
|
||||
&& entry_path.extension().is_some_and(|ext| {
|
||||
self.allowed_extensions
|
||||
.iter()
|
||||
.any(|allowed| ext.eq_ignore_ascii_case(allowed.as_ref()))
|
||||
})
|
||||
{
|
||||
self.files_matching_allowed_extensions.push(entry_path)
|
||||
}
|
||||
}
|
||||
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
//! The test driver handles the compilation and execution of the test cases.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use alloy::json_abi::JsonAbi;
|
||||
@@ -19,6 +20,9 @@ use alloy::{
|
||||
};
|
||||
use anyhow::Context;
|
||||
use indexmap::IndexMap;
|
||||
use serde_json::Value;
|
||||
|
||||
use revive_dt_common::iterators::FilesWithExtensionIterator;
|
||||
use revive_dt_compiler::{Compiler, SolidityCompiler};
|
||||
use revive_dt_config::Arguments;
|
||||
use revive_dt_format::case::CaseIdx;
|
||||
@@ -29,11 +33,8 @@ use revive_dt_node::Node;
|
||||
use revive_dt_node_interaction::EthereumNode;
|
||||
use revive_dt_report::reporter::{CompilationTask, Report, Span};
|
||||
use revive_solc_json_interface::SolcStandardJsonOutput;
|
||||
use serde_json::Value;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::Platform;
|
||||
use crate::common::*;
|
||||
|
||||
pub struct State<'a, T: Platform> {
|
||||
/// The configuration that the framework was started with.
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
|
||||
use revive_dt_compiler::{SolidityCompiler, revive_resolc, solc};
|
||||
use revive_dt_config::TestingPlatform;
|
||||
use revive_dt_format::traits::ResolverApi;
|
||||
use revive_dt_node::{Node, geth, kitchensink::KitchensinkNode};
|
||||
use revive_dt_node_interaction::EthereumNode;
|
||||
|
||||
pub mod common;
|
||||
pub mod driver;
|
||||
|
||||
/// One platform can be tested differentially against another.
|
||||
///
|
||||
/// For this we need a blockchain node implementation and a compiler.
|
||||
pub trait Platform {
|
||||
type Blockchain: EthereumNode + Node;
|
||||
type Blockchain: EthereumNode + Node + ResolverApi;
|
||||
type Compiler: SolidityCompiler;
|
||||
|
||||
/// Returns the matching [TestingPlatform] of the [revive_dt_config::Arguments].
|
||||
|
||||
Reference in New Issue
Block a user