Skip to content

Commit

Permalink
Merge pull request #60 from audunhalland/fix-generic-answer-fn-bound
Browse files Browse the repository at this point in the history
fix: Don't expose private type in the with_types RPIT
  • Loading branch information
audunhalland authored Jul 27, 2024
2 parents 1dabcfb + 53458a8 commit f166b36
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Fixed
- Leaked private type for generic-argument mocks in `with_types` signature ([#58](https://github.com/audunhalland/unimock/issues/58)).

## [0.6.6] - 2024-05-08
### Fixed
Expand Down
2 changes: 2 additions & 0 deletions tests/it/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,8 @@ mod eval_name_clash {
}

mod fn_cfg_attrs {
#![allow(unexpected_cfgs)]

use super::*;

#[unimock(api = TraitMock)]
Expand Down
23 changes: 23 additions & 0 deletions tests/it/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,29 @@ mod param {

deps.generic_param_debug(42_i32);
}

mod cross_mod {
use super::*;

#[unimock(api=CrossModGenericMock)]
pub trait CrossModGeneric<T> {
fn cross_mod(&self, param: T) -> &'static str;
}
}

/// https://github.com/audunhalland/unimock/issues/58
#[test]
fn cross_mod_setup() {
let deps = Unimock::new(
cross_mod::CrossModGenericMock::cross_mod
.with_types::<&'static str>()
.each_call(matching!("foobar"))
.returns("a string"),
);

use cross_mod::CrossModGeneric;
assert_eq!("a string", deps.cross_mod("foobar"));
}
}

mod combined {
Expand Down
8 changes: 4 additions & 4 deletions unimock_macros/src/unimock/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub enum InputsSyntax {

pub enum ArgClass<'t> {
Receiver,
MutImpossible(&'t syn::PatIdent, &'t syn::Type),
MutImpossible(&'t syn::PatIdent),
Other(&'t syn::PatIdent, &'t syn::Type),
Unprocessable(&'t syn::PatType),
}
Expand All @@ -70,7 +70,7 @@ impl<'t> MockMethod<'t> {
if self.method.sig.asyncness.is_some()
|| matches!(
self.output_structure.wrapping,
output::OutputWrapping::AssociatedFuture(_) | output::OutputWrapping::RpitFuture(_)
output::OutputWrapping::AssociatedFuture(_) | output::OutputWrapping::RpitFuture
)
{
Some(DotAwait)
Expand Down Expand Up @@ -202,7 +202,7 @@ impl<'t> MockMethod<'t> {
syn::FnArg::Typed(pat_type) => match (index, pat_type.pat.as_ref()) {
(_, syn::Pat::Ident(pat_ident)) => {
if Self::is_mutable_reference_with_lifetimes_in_type(pat_type.ty.as_ref()) {
ArgClass::MutImpossible(pat_ident, &pat_type.ty)
ArgClass::MutImpossible(pat_ident)
} else {
ArgClass::Other(pat_ident, &pat_type.ty)
}
Expand Down Expand Up @@ -450,7 +450,7 @@ impl<'t> quote::ToTokens for InputsDestructuring<'t> {
ArgClass::Receiver => {
continue;
}
ArgClass::MutImpossible(pat_ident, _) => match self.syntax {
ArgClass::MutImpossible(pat_ident) => match self.syntax {
InputsSyntax::FnPattern
| InputsSyntax::FnParams
| InputsSyntax::EvalPatternAll => pat_ident.to_tokens(tokens),
Expand Down
7 changes: 4 additions & 3 deletions unimock_macros/src/unimock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ fn def_mock_fn(
MockApi::MockMod(ident) => Some(quote_spanned! { span=> #ident:: }),
_ => None,
};
let answer_fn_assoc_type = make_answer_fn(method, trait_info, attr);

MockFnDef {
mock_fn_struct_item: gen_mock_fn_struct_item(non_generic_ident),
Expand All @@ -324,7 +325,7 @@ fn def_mock_fn(
) -> impl for<#input_lifetime> #prefix::MockFn<
Inputs<#input_lifetime> = #input_types_tuple,
OutputKind = #output_kind_assoc_type,
AnswerFn = <#mock_fn_ident #generic_args as #prefix::MockFn>::AnswerFn,
AnswerFn = #answer_fn_assoc_type,
>
#where_clause
{
Expand Down Expand Up @@ -382,7 +383,7 @@ fn def_method_impl(

let must_async_wrap = matches!(
method.output_structure.wrapping,
output::OutputWrapping::RpitFuture(_) | output::OutputWrapping::AssociatedFuture(_)
output::OutputWrapping::RpitFuture | output::OutputWrapping::AssociatedFuture(_)
);

let trait_path = &trait_info.trait_path;
Expand All @@ -401,7 +402,7 @@ fn def_method_impl(

if matches!(
method.output_structure.wrapping,
output::OutputWrapping::RpitFuture(_)
output::OutputWrapping::RpitFuture
) {
lints.push(quote! { manual_async_fn });
}
Expand Down
4 changes: 2 additions & 2 deletions unimock_macros/src/unimock/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl OutputStructure {

pub enum OutputWrapping {
None,
RpitFuture(syn::Type),
RpitFuture,
AssociatedFuture(syn::TraitItemType),
}

Expand Down Expand Up @@ -134,7 +134,7 @@ pub fn determine_output_structure(
let mut output_structure =
determine_owned_or_deep_output_structure(sig, &rpit_future.output.ty, attr);

output_structure.wrapping = OutputWrapping::RpitFuture(rpit_future.output.ty);
output_structure.wrapping = OutputWrapping::RpitFuture;
output_structure
} else {
determine_owned_or_deep_output_structure(sig, output_ty, attr)
Expand Down
2 changes: 0 additions & 2 deletions unimock_macros/src/unimock/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,6 @@ pub fn replace_self_ty_with_path(mut ty: syn::Type, replacement_path: &syn::Path
}

pub struct FutureBound<'s> {
pub future_ident: &'s syn::Ident,
pub output: &'s syn::AssocType,
}

Expand Down Expand Up @@ -642,7 +641,6 @@ pub fn find_future_bound<'s>(
.next()?;

Some(FutureBound {
future_ident: &last_segment.ident,
output: output_assoc,
})
}
Expand Down

0 comments on commit f166b36

Please sign in to comment.