@@ -72,16 +72,16 @@ macro_rules! pointwise {
72
72
pub mod internal {
73
73
#[ cfg( not( google3) ) ]
74
74
use crate as googletest;
75
+ #[ cfg( not( google3) ) ]
76
+ use crate :: matchers:: zipped_iterator:: zip;
75
77
#[ cfg( google3) ]
76
78
use description:: Description ;
77
79
use googletest:: matcher:: { MatchExplanation , Matcher , MatcherResult } ;
78
80
#[ cfg( not( google3) ) ]
79
81
use googletest:: matchers:: description:: Description ;
80
- #[ cfg( not( google3) ) ]
81
- use googletest:: matchers:: has_size:: HasSize ;
82
- #[ cfg( google3) ]
83
- use has_size:: HasSize ;
84
82
use std:: fmt:: Debug ;
83
+ #[ cfg( google3) ]
84
+ use zipped_iterator:: zip;
85
85
86
86
/// This struct is meant to be used only through the `pointwise` macro.
87
87
///
@@ -97,48 +97,52 @@ pub mod internal {
97
97
}
98
98
}
99
99
100
- impl < T : Debug , MatcherT : Matcher < T > , ContainerT : ?Sized + HasSize + Debug > Matcher < ContainerT >
100
+ impl < T : Debug , MatcherT : Matcher < T > , ContainerT : ?Sized + Debug > Matcher < ContainerT >
101
101
for PointwiseMatcher < MatcherT >
102
102
where
103
103
for < ' b > & ' b ContainerT : IntoIterator < Item = & ' b T > ,
104
104
{
105
105
fn matches ( & self , actual : & ContainerT ) -> MatcherResult {
106
- if actual. size ( ) != self . matchers . len ( ) {
107
- return MatcherResult :: DoesNotMatch ;
108
- }
109
- for ( element, matcher) in actual. into_iter ( ) . zip ( & self . matchers ) {
106
+ let mut zipped_iterator = zip ( actual. into_iter ( ) , self . matchers . iter ( ) ) ;
107
+ for ( element, matcher) in zipped_iterator. by_ref ( ) {
110
108
if matches ! ( matcher. matches( element) , MatcherResult :: DoesNotMatch ) {
111
109
return MatcherResult :: DoesNotMatch ;
112
110
}
113
111
}
114
- MatcherResult :: Matches
112
+ if zipped_iterator. has_size_mismatch ( ) {
113
+ MatcherResult :: DoesNotMatch
114
+ } else {
115
+ MatcherResult :: Matches
116
+ }
115
117
}
116
118
117
119
fn explain_match ( & self , actual : & ContainerT ) -> MatchExplanation {
118
- if actual. size ( ) != self . matchers . len ( ) {
119
- return MatchExplanation :: create ( format ! (
120
- "which has size {} (expected {})" ,
121
- actual. size( ) ,
122
- self . matchers. len( )
123
- ) ) ;
124
- }
125
-
126
120
// TODO(b/260819741) This code duplicates elements_are_matcher.rs. Consider
127
121
// extract as a separate library. (or implement pointwise! with
128
122
// elements_are)
129
- let mismatches = actual
130
- . into_iter ( )
131
- . zip ( self . matchers . iter ( ) )
132
- . enumerate ( )
133
- . filter ( |& ( _, ( a, e) ) | matches ! ( e. matches( a) , MatcherResult :: DoesNotMatch ) )
134
- . map ( |( idx, ( a, e) ) | format ! ( "element #{idx} is {a:#?}, {}" , e. explain_match( a) ) )
135
- . collect :: < Description > ( ) ;
123
+ let actual_iterator = actual. into_iter ( ) ;
124
+ let mut zipped_iterator = zip ( actual_iterator, self . matchers . iter ( ) ) ;
125
+ let mut mismatches = Vec :: new ( ) ;
126
+ for ( idx, ( a, e) ) in zipped_iterator. by_ref ( ) . enumerate ( ) {
127
+ if matches ! ( e. matches( a) , MatcherResult :: DoesNotMatch ) {
128
+ mismatches. push ( format ! ( "element #{idx} is {a:?}, {}" , e. explain_match( a) ) ) ;
129
+ }
130
+ }
136
131
if mismatches. is_empty ( ) {
137
- MatchExplanation :: create ( "which matches all elements" . to_string ( ) )
132
+ if !zipped_iterator. has_size_mismatch ( ) {
133
+ MatchExplanation :: create ( "which matches all elements" . to_string ( ) )
134
+ } else {
135
+ MatchExplanation :: create ( format ! (
136
+ "which has size {} (expected {})" ,
137
+ zipped_iterator. left_size( ) ,
138
+ self . matchers. len( )
139
+ ) )
140
+ }
138
141
} else if mismatches. len ( ) == 1 {
139
- MatchExplanation :: create ( format ! ( "where {mismatches}" ) )
142
+ MatchExplanation :: create ( format ! ( "where {}" , mismatches [ 0 ] ) )
140
143
} else {
141
- MatchExplanation :: create ( format ! ( "where:\n {}" , mismatches. indent( ) . bullet_list( ) ) )
144
+ let mismatches = mismatches. into_iter ( ) . collect :: < Description > ( ) ;
145
+ MatchExplanation :: create ( format ! ( "where:\n {}" , mismatches. bullet_list( ) . indent( ) ) )
142
146
}
143
147
}
144
148
@@ -185,6 +189,13 @@ mod tests {
185
189
verify_that ! ( value, pointwise!( lt, [ 2 , 3 ] ) )
186
190
}
187
191
192
+ #[ google_test]
193
+ fn pointwise_matches_two_element_slice ( ) -> Result < ( ) > {
194
+ let value = vec ! [ 1 , 2 ] ;
195
+ let slice = value. as_slice ( ) ;
196
+ verify_that ! ( * slice, pointwise!( lt, [ 2 , 3 ] ) )
197
+ }
198
+
188
199
#[ google_test]
189
200
fn pointwise_does_not_match_value_of_wrong_length ( ) -> Result < ( ) > {
190
201
let value = vec ! [ 1 ] ;
0 commit comments