Skip to main content

property

Macro property 

Source
macro_rules! property {
    ($($t:tt)*) => { ... };
}
Expand description

Matches an object which, upon calling the given method on it with the given arguments, produces a value matched by the given inner matcher.

This is particularly useful as a nested matcher when the desired property cannot be accessed through a field and must instead be extracted through a method call. For example:

#[derive(Debug)]
pub struct MyStruct {
    a_field: u32,
}

impl MyStruct {
    pub fn get_a_field(&self) -> u32 { self.a_field }
}

let value = vec![MyStruct { a_field: 100 }];
verify_that!(value, contains(property!(&MyStruct.get_a_field(), eq(100))))

If the inner matcher is eq(...), it can be omitted:

#[derive(Debug)]
pub struct MyStruct {
    a_field: u32,
}

impl MyStruct {
    pub fn get_a_field(&self) -> u32 { self.a_field }
}

let value = vec![MyStruct { a_field: 100 }];
verify_that!(value, contains(property!(&MyStruct.get_a_field(), 100)))

Important: The method should be pure function with a deterministic output and no side effects. In particular, in the event of an assertion failure, it will be invoked a second time, with the assertion failure output reflecting the second invocation.

The method may also take additional litteral arguments:

impl MyStruct {
    pub fn add_to_a_field(&self, a: u32) -> u32 { self.a_field + a }
}

verify_that!(value, contains(property!(&MyStruct.add_to_a_field(50), eq(150))))

The arguments must be litteral as property! is not able to capture them.

ยงSpecification of the property pattern

The specification of the field follow the syntax: (ref)? (&)? $TYPE.$PROPERTY\($ARGUMENT\).

The & allows to specify whether this matcher matches against an actual of type $TYPE ($TYPE must implement Copy) or a &$TYPE.

For instance:

#[derive(Debug)]
pub struct AStruct;

impl AStruct {
  fn a_property(&self) -> i32 {32}
}
verify_that!(AStruct, property!(&AStruct.a_property(), eq(32)))?;
#[derive(Debug, Clone, Copy)]
pub struct AStruct;

impl AStruct {
  fn a_property(self) -> i32 {32}
}
verify_that!(AStruct, property!(AStruct.a_property(), eq(32)))?;

The ref allows to bind the property returned value by reference, which is required if the field type does not implement Copy.

For instance:

#[derive(Debug)]
pub struct AStruct;

impl AStruct {
  fn a_property(&self) -> i32 {32}
}
verify_that!(AStruct, property!(&AStruct.a_property(), eq(32)))?;

If property! is qualified by both & and ref, they can both be omitted.

#[derive(Debug)]
pub struct AStruct;

impl AStruct {
  fn a_property(&self) -> String {"32".into()}
}
verify_that!(AStruct, property!(&AStruct.a_property(), ref eq("32")))?;
verify_that!(AStruct, property!(AStruct.a_property(), eq("32")))?;

This macro is analogous to field, except that it extracts the datum to be matched from the given object by invoking a method rather than accessing a field.

The list of arguments may optionally have a trailing comma.