Skip to content

Commit

Permalink
MockBuilder: extend trait generic support when the generics are thems…
Browse files Browse the repository at this point in the history
…elf generic (#16)

* improve testing

* fix issue
  • Loading branch information
lemunozm committed Dec 14, 2023
1 parent b3d9ed2 commit 1f5eedf
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 51 deletions.
124 changes: 74 additions & 50 deletions mock-builder/src/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,17 @@ impl FunctionLocation {
let (path, name) = self.location.rsplit_once("::").expect("always '::'");
let (path, trait_info) = match path.strip_prefix('<') {
Some(struct_as_trait_path) => {
let struct_path = struct_as_trait_path
let (struct_path, trait_path) = struct_as_trait_path
.split_once(" as")
.expect("always ' as'")
.0;
.expect("always ' as'");

let trait_name = struct_as_trait_path
.rsplit_once("::")
.expect("always '::'")
.1
.strip_suffix('>')
.unwrap();

// Remove generic from trait name
let trait_name = trait_name
let trait_name = trait_path
.split_once('<')
.map(|(fst, _)| fst)
.unwrap_or(trait_name);
.map(|(name, _generics)| name)
.unwrap_or(trait_path.strip_suffix('>').unwrap())
.rsplit_once("::")
.expect("Always '::'")
.1;

(struct_path, Some(trait_name.to_owned()))
}
Expand Down Expand Up @@ -156,12 +150,16 @@ mod tests {
}

trait TraitExampleGen<G1, G2> {
fn foo() -> FunctionLocation;
fn generic() -> FunctionLocation;
}

struct Example;
trait Config {
type Assoc;
}

impl Example {
struct Example<T>(core::marker::PhantomData<T>);

impl<T> Example<T> {
fn mock_method() -> FunctionLocation {
FunctionLocation::from(|| ())
}
Expand All @@ -171,12 +169,17 @@ mod tests {
FunctionLocation::from(|| ())
}

#[allow(non_snake_case)]
fn mock_TraitExampleGen_generic() -> FunctionLocation {
FunctionLocation::from(|| ())
}

fn mock_generic_method<A: Into<i32>>(_: impl Into<u32>) -> FunctionLocation {
FunctionLocation::from(|| ())
}
}

impl TraitExample for Example {
impl<T> TraitExample for Example<T> {
fn method() -> FunctionLocation {
FunctionLocation::from(|| ())
}
Expand All @@ -186,59 +189,68 @@ mod tests {
}
}

impl TraitExampleGen<u32, bool> for Example {
fn foo() -> FunctionLocation {
impl<T: Config> TraitExampleGen<T::Assoc, bool> for Example<T> {
fn generic() -> FunctionLocation {
FunctionLocation::from(|| ())
}
}

struct TestConfig;
impl Config for TestConfig {
type Assoc = u32;
}

#[test]
fn function_location() {
assert_eq!(
Example::mock_method(),
Example::<TestConfig>::mock_method(),
FunctionLocation {
location: format!("{PREFIX}::Example::mock_method"),
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::mock_method"),
trait_info: None,
}
);

assert_eq!(
Example::mock_TraitExample_method(),
Example::<TestConfig>::mock_TraitExample_method(),
FunctionLocation {
location: format!("{PREFIX}::Example::mock_TraitExample_method"),
location: format!(
"{PREFIX}::Example<{PREFIX}::TestConfig>::mock_TraitExample_method"
),
trait_info: None,
}
);

assert_eq!(
Example::mock_generic_method::<i8>(0u8),
Example::<TestConfig>::mock_generic_method::<i8>(0u8),
FunctionLocation {
location: format!("{PREFIX}::Example::mock_generic_method"),
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::mock_generic_method"),
trait_info: None,
}
);

assert_eq!(
Example::method(),
Example::<TestConfig>::method(),
FunctionLocation {
location: format!("<{PREFIX}::Example as {PREFIX}::TraitExample>::method"),
location: format!(
"<{PREFIX}::Example<{PREFIX}::TestConfig> as {PREFIX}::TraitExample>::method"
),
trait_info: None,
}
);

assert_eq!(
Example::generic_method::<i8>(0u8),
Example::<TestConfig>::generic_method::<i8>(0u8),
FunctionLocation {
location: format!("<{PREFIX}::Example as {PREFIX}::TraitExample>::generic_method"),
location: format!("<{PREFIX}::Example<{PREFIX}::TestConfig> as {PREFIX}::TraitExample>::generic_method"),
trait_info: None,
}
);

assert_eq!(
Example::foo(),
Example::<TestConfig>::generic(),
FunctionLocation {
location: format!(
"<{PREFIX}::Example as {PREFIX}::TraitExampleGen<u32, bool>>::foo"
"<{PREFIX}::Example<{PREFIX}::TestConfig> as {PREFIX}::TraitExampleGen<<{PREFIX}::TestConfig as {PREFIX}::Config>::Assoc, bool>>::generic"
),
trait_info: None,
}
Expand All @@ -248,33 +260,35 @@ mod tests {
#[test]
fn normalized() {
assert_eq!(
Example::mock_method().normalize(),
Example::<TestConfig>::mock_method().normalize(),
FunctionLocation {
location: format!("{PREFIX}::Example::mock_method"),
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::mock_method"),
trait_info: None,
}
);

assert_eq!(
Example::mock_TraitExample_method().normalize(),
Example::<TestConfig>::mock_TraitExample_method().normalize(),
FunctionLocation {
location: format!("{PREFIX}::Example::mock_TraitExample_method"),
location: format!(
"{PREFIX}::Example<{PREFIX}::TestConfig>::mock_TraitExample_method"
),
trait_info: None,
}
);

assert_eq!(
Example::method().normalize(),
Example::<TestConfig>::method().normalize(),
FunctionLocation {
location: format!("{PREFIX}::Example::method"),
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::method"),
trait_info: Some("TraitExample".into()),
}
);

assert_eq!(
Example::foo().normalize(),
Example::<TestConfig>::generic().normalize(),
FunctionLocation {
location: format!("{PREFIX}::Example::foo"),
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::generic"),
trait_info: Some("TraitExampleGen".into()),
}
);
Expand All @@ -283,43 +297,53 @@ mod tests {
#[test]
fn striped_name_prefix() {
assert_eq!(
Example::mock_method().strip_name_prefix("mock_"),
Example::<TestConfig>::mock_method().strip_name_prefix("mock_"),
FunctionLocation {
location: format!("{PREFIX}::Example::method"),
trait_info: None
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::method"),
trait_info: None,
}
);
}

#[test]
fn assimilated_trait_prefix() {
assert_eq!(
Example::mock_method()
Example::<TestConfig>::mock_method()
.strip_name_prefix("mock_")
.assimilate_trait_prefix(),
FunctionLocation {
location: format!("{PREFIX}::Example::method"),
trait_info: None
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::method"),
trait_info: None,
}
);

assert_eq!(
Example::mock_TraitExample_method()
Example::<TestConfig>::mock_TraitExample_method()
.strip_name_prefix("mock_")
.assimilate_trait_prefix(),
FunctionLocation {
location: format!("{PREFIX}::Example::method"),
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::method"),
trait_info: Some("TraitExample".into()),
}
);

assert_eq!(
Example::<TestConfig>::mock_TraitExampleGen_generic()
.strip_name_prefix("mock_")
.assimilate_trait_prefix(),
FunctionLocation {
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::generic"),
trait_info: Some("TraitExampleGen".into()),
}
);
}

#[test]
fn appended_type_signature() {
assert_eq!(
Example::mock_method().append_type_signature::<i8, u8>(),
Example::<TestConfig>::mock_method().append_type_signature::<i8, u8>(),
FunctionLocation {
location: format!("{PREFIX}::Example::mock_method:i8->u8"),
location: format!("{PREFIX}::Example<{PREFIX}::TestConfig>::mock_method:i8->u8"),
trait_info: None,
}
);
Expand Down
26 changes: 25 additions & 1 deletion mock-builder/tests/pallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ pub trait TraitB {
fn same_name(p1: i32) -> bool;
}

pub trait TraitGen<A> {
fn generic() -> u32;
}

pub trait Storage {
fn set(value: i32);
fn get() -> i32;
Expand Down Expand Up @@ -73,6 +77,11 @@ pub mod pallet_mock_test {
pub fn mock_TraitB_same_name(f: impl Fn(i32) -> bool + 'static) {
register_call!(f);
}

#[allow(non_snake_case)]
pub fn mock_TraitGen_generic(f: impl Fn() -> u32 + 'static) {
register_call!(move |()| f());
}
}

impl<T: Config> super::TraitA for Pallet<T> {
Expand Down Expand Up @@ -111,6 +120,12 @@ pub mod pallet_mock_test {
}
}

impl<T: Config> super::TraitGen<T::AccountId> for Pallet<T> {
fn generic() -> u32 {
execute_call!(())
}
}

impl<T: Config> super::Storage for Pallet<T> {
fn set(a: i32) {
execute_call!(a)
Expand Down Expand Up @@ -198,7 +213,7 @@ mod mock {
mod test {
use frame_support::assert_ok;

use super::{mock::*, Storage, TraitA, TraitB};
use super::{mock::*, Storage, TraitA, TraitB, TraitGen};

#[test]
fn basic() {
Expand Down Expand Up @@ -332,4 +347,13 @@ mod test {
assert_eq!(<MockTest as TraitB>::same_name(23), true);
});
}

#[test]
fn method_from_generic_trait_long_path() {
new_test_ext().execute_with(|| {
MockTest::mock_TraitGen_generic(|| 23);

assert_eq!(MockTest::generic(), 23);
});
}
}

0 comments on commit 1f5eedf

Please sign in to comment.