@@ -12,95 +12,36 @@ use std::fmt;
1212use crate :: reflection;
1313use crate :: Predicate ;
1414
15- #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
16- enum DistanceOp {
17- Similar ,
18- Different ,
19- }
20-
21- impl DistanceOp {
22- fn eval ( self , limit : i32 , distance : i32 ) -> bool {
23- match self {
24- DistanceOp :: Similar => distance <= limit,
25- DistanceOp :: Different => limit < distance,
26- }
27- }
28- }
29-
3015/// Predicate that diffs two strings.
3116///
32- /// This is created by the `predicate::str::similar `.
17+ /// This is created by the `predicate::str::diff `.
3318#[ derive( Debug , Clone , PartialEq , Eq ) ]
3419pub struct DifferencePredicate {
3520 orig : borrow:: Cow < ' static , str > ,
36- split : borrow:: Cow < ' static , str > ,
37- distance : i32 ,
38- op : DistanceOp ,
39- }
40-
41- impl DifferencePredicate {
42- /// The split used when identifying changes.
43- ///
44- /// Common splits include:
45- /// - `""` for char-level.
46- /// - `" "` for word-level.
47- /// - `"\n"` for line-level.
48- ///
49- /// Default: `"\n"`
50- ///
51- /// # Examples
52- ///
53- /// ```
54- /// use predicates::prelude::*;
55- ///
56- /// let predicate_fn = predicate::str::similar("Hello World").split(" ");
57- /// assert_eq!(true, predicate_fn.eval("Hello World"));
58- /// ```
59- pub fn split < S > ( mut self , split : S ) -> Self
60- where
61- S : Into < borrow:: Cow < ' static , str > > ,
62- {
63- self . split = split. into ( ) ;
64- self
65- }
66-
67- /// The maximum allowed edit distance.
68- ///
69- /// Default: `0`
70- ///
71- /// # Examples
72- ///
73- /// ```
74- /// use predicates::prelude::*;
75- ///
76- /// let predicate_fn = predicate::str::similar("Hello World!").split("").distance(1);
77- /// assert_eq!(true, predicate_fn.eval("Hello World!"));
78- /// assert_eq!(true, predicate_fn.eval("Hello World"));
79- /// assert_eq!(false, predicate_fn.eval("Hello World?"));
80- /// ```
81- pub fn distance ( mut self , distance : i32 ) -> Self {
82- self . distance = distance;
83- self
84- }
8521}
8622
8723impl Predicate < str > for DifferencePredicate {
8824 fn eval ( & self , edit : & str ) -> bool {
89- let change = difference:: Changeset :: new ( & self . orig , edit, & self . split ) ;
90- self . op . eval ( self . distance , change. distance )
25+ edit == self . orig
9126 }
9227
9328 fn find_case < ' a > ( & ' a self , expected : bool , variable : & str ) -> Option < reflection:: Case < ' a > > {
94- let change = difference:: Changeset :: new ( & self . orig , variable, & self . split ) ;
95- let result = self . op . eval ( self . distance , change. distance ) ;
29+ let result = variable != self . orig ;
9630 if result == expected {
31+ None
32+ } else {
33+ let orig: Vec < _ > = self . orig . lines ( ) . map ( |l| format ! ( "{}\n " , l) ) . collect ( ) ;
34+ let variable: Vec < _ > = variable. lines ( ) . map ( |l| format ! ( "{}\n " , l) ) . collect ( ) ;
35+ let mut diff =
36+ difflib:: unified_diff ( & orig, & variable, "value" , "value" , "expected" , "actual" , 0 ) ;
37+ diff. insert ( 0 , "\n " . to_owned ( ) ) ;
38+
9739 Some (
98- reflection:: Case :: new ( Some ( self ) , result)
99- . add_product ( reflection:: Product :: new ( "actual distance" , change. distance ) )
100- . add_product ( reflection:: Product :: new ( "diff" , change) ) ,
40+ reflection:: Case :: new ( Some ( self ) , result) . add_product ( reflection:: Product :: new (
41+ "diff" ,
42+ itertools:: join ( diff. iter ( ) , "" ) ,
43+ ) ) ,
10144 )
102- } else {
103- None
10445 }
10546 }
10647}
@@ -114,10 +55,7 @@ impl reflection::PredicateReflection for DifferencePredicate {
11455
11556impl fmt:: Display for DifferencePredicate {
11657 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
117- match self . op {
118- DistanceOp :: Similar => write ! ( f, "var - original <= {}" , self . distance) ,
119- DistanceOp :: Different => write ! ( f, "{} < var - original" , self . distance) ,
120- }
58+ write ! ( f, "diff var original" )
12159 }
12260}
12361
@@ -129,40 +67,14 @@ impl fmt::Display for DifferencePredicate {
12967/// use predicates::prelude::*;
13068///
13169/// let predicate_fn = predicate::str::diff("Hello World");
132- /// assert_eq!(false, predicate_fn.eval("Hello World"));
133- /// assert_eq!(true, predicate_fn.eval("Goodbye World"));
134- /// ```
135- pub fn diff < S > ( orig : S ) -> DifferencePredicate
136- where
137- S : Into < borrow:: Cow < ' static , str > > ,
138- {
139- DifferencePredicate {
140- orig : orig. into ( ) ,
141- split : "\n " . into ( ) ,
142- distance : 0 ,
143- op : DistanceOp :: Different ,
144- }
145- }
146-
147- /// Creates a new `Predicate` that checks strings for how similar they are.
148- ///
149- /// # Examples
150- ///
151- /// ```
152- /// use predicates::prelude::*;
153- ///
154- /// let predicate_fn = predicate::str::similar("Hello World");
15570/// assert_eq!(true, predicate_fn.eval("Hello World"));
71+ /// assert!(predicate_fn.find_case(true, "Hello World").is_none());
15672/// assert_eq!(false, predicate_fn.eval("Goodbye World"));
73+ /// assert!(predicate_fn.find_case(true, "Goodbye World").is_some());
15774/// ```
158- pub fn similar < S > ( orig : S ) -> DifferencePredicate
75+ pub fn diff < S > ( orig : S ) -> DifferencePredicate
15976where
16077 S : Into < borrow:: Cow < ' static , str > > ,
16178{
162- DifferencePredicate {
163- orig : orig. into ( ) ,
164- split : "\n " . into ( ) ,
165- distance : 0 ,
166- op : DistanceOp :: Similar ,
167- }
79+ DifferencePredicate { orig : orig. into ( ) }
16880}
0 commit comments