@@ -12,6 +12,10 @@ pub type Map = serde_json::value::Map<String, SerdeValue>;
12
12
13
13
use super :: { Input , Output } ;
14
14
15
+ #[ cfg( test) ]
16
+ #[ path = "eval_test.rs" ]
17
+ mod test;
18
+
15
19
#[ derive( Debug , Eq , PartialEq ) ]
16
20
pub enum Error {
17
21
TypeError ,
@@ -174,6 +178,50 @@ impl From<Value> for Rule {
174
178
}
175
179
176
180
impl Function {
181
+ pub fn new_muldiv (
182
+ value : impl Into < Rule > ,
183
+ multiplier : impl Into < Rule > ,
184
+ divisor : impl Into < Rule > ,
185
+ ) -> Self {
186
+ Self :: MulDiv (
187
+ Box :: new ( value. into ( ) ) ,
188
+ Box :: new ( multiplier. into ( ) ) ,
189
+ Box :: new ( divisor. into ( ) ) ,
190
+ )
191
+ }
192
+ pub fn new_div ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
193
+ Self :: Div ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
194
+ }
195
+ pub fn new_mul ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
196
+ Self :: Mul ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
197
+ }
198
+ pub fn new_add ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
199
+ Self :: Add ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
200
+ }
201
+ pub fn new_sub ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
202
+ Self :: Sub ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
203
+ }
204
+ pub fn new_mod ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
205
+ Self :: Mod ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
206
+ }
207
+ pub fn new_min ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
208
+ Self :: Min ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
209
+ }
210
+ pub fn new_max ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
211
+ Self :: Max ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
212
+ }
213
+ pub fn new_lt ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
214
+ Self :: Lt ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
215
+ }
216
+ pub fn new_lte ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
217
+ Self :: Lte ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
218
+ }
219
+ pub fn new_gt ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
220
+ Self :: Gt ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
221
+ }
222
+ pub fn new_gte ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
223
+ Self :: Gte ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
224
+ }
177
225
pub fn new_if ( condition : impl Into < Rule > , then : impl Into < Rule > ) -> Self {
178
226
Self :: If ( Box :: new ( condition. into ( ) ) , Box :: new ( then. into ( ) ) )
179
227
}
@@ -234,6 +282,14 @@ impl Function {
234
282
)
235
283
}
236
284
285
+ pub fn new_eq ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
286
+ Self :: Eq ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
287
+ }
288
+
289
+ pub fn new_neq ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
290
+ Self :: Neq ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
291
+ }
292
+
237
293
pub fn new_split ( string : impl Into < Rule > , separator : impl Into < Rule > ) -> Self {
238
294
Self :: Split ( Box :: new ( string. into ( ) ) , Box :: new ( separator. into ( ) ) )
239
295
}
@@ -254,6 +310,10 @@ impl Function {
254
310
Self :: OnlyShowIf ( Box :: new ( condition. into ( ) ) )
255
311
}
256
312
313
+ pub fn new_do ( rule : impl Into < Rule > ) -> Self {
314
+ Self :: Do ( Box :: new ( rule. into ( ) ) )
315
+ }
316
+
257
317
pub fn new_get ( key : & str ) -> Self {
258
318
Self :: Get ( key. to_string ( ) )
259
319
}
@@ -1019,209 +1079,3 @@ fn math_operator(lhs: Number, rhs: Number, ops: MathOperator) -> Result<Number,
1019
1079
} ,
1020
1080
}
1021
1081
}
1022
-
1023
- #[ cfg( test) ]
1024
- mod test {
1025
- use super :: * ;
1026
- use crate :: targeting:: AdSlot ;
1027
-
1028
- #[ test]
1029
- fn deserialize_intersects_with_get_rule ( ) {
1030
- let json = r#"{"intersects": [{ "get": "adSlot.categories" }, ["News", "Bitcoin"]]}"# ;
1031
-
1032
- let parsed_rule = serde_json:: from_str :: < Rule > ( json) . expect ( "Should deserialize" ) ;
1033
-
1034
- let expected = Rule :: Function ( Function :: new_intersects (
1035
- Rule :: Function ( Function :: new_get ( "adSlot.categories" ) ) ,
1036
- Rule :: Value ( Value :: Array ( vec ! [
1037
- Value :: new_string( "News" ) ,
1038
- Value :: new_string( "Bitcoin" ) ,
1039
- ] ) ) ,
1040
- ) ) ;
1041
-
1042
- assert_eq ! ( expected, parsed_rule)
1043
- }
1044
-
1045
- /// ```json
1046
- /// {
1047
- /// "intersects": [
1048
- /// {
1049
- /// "get": "adSlot.categories"
1050
- /// },
1051
- /// [
1052
- /// "News",
1053
- /// "Bitcoin"
1054
- /// ]
1055
- /// ]
1056
- /// }
1057
- /// ```
1058
- #[ test]
1059
- fn test_intersects_eval ( ) {
1060
- let mut input = Input :: default ( ) ;
1061
- input. ad_slot = Some ( AdSlot {
1062
- categories : vec ! [ "Bitcoin" . to_string( ) , "Ethereum" . to_string( ) ] ,
1063
- hostname : Default :: default ( ) ,
1064
- alexa_rank : 0.0 ,
1065
- } ) ;
1066
-
1067
- let mut output = Output {
1068
- show : true ,
1069
- boost : 1.0 ,
1070
- price : Default :: default ( ) ,
1071
- } ;
1072
-
1073
- let categories = vec ! [ Value :: new_string( "News" ) , Value :: new_string( "Bitcoin" ) ] ;
1074
-
1075
- let rules = Rule :: Function ( Function :: new_intersects (
1076
- Function :: new_get ( "adSlot.categories" ) ,
1077
- Value :: Array ( categories) ,
1078
- ) ) ;
1079
-
1080
- let result = rules. eval ( & input, & mut output) . expect ( "Should eval rules" ) ;
1081
-
1082
- assert_eq ! (
1083
- Value :: Bool ( true ) ,
1084
- result. expect( "Should return Non-NULL result!" )
1085
- ) ;
1086
-
1087
- let mut input = Input :: default ( ) ;
1088
- input. ad_slot = Some ( AdSlot {
1089
- categories : vec ! [ "Advertisement" . to_string( ) , "Programming" . to_string( ) ] ,
1090
- hostname : Default :: default ( ) ,
1091
- alexa_rank : 0.0 ,
1092
- } ) ;
1093
-
1094
- let result = rules. eval ( & input, & mut output) . expect ( "Should eval rules" ) ;
1095
-
1096
- assert_eq ! (
1097
- Value :: Bool ( false ) ,
1098
- result. expect( "Should return Non-NULL result!" )
1099
- ) ;
1100
- }
1101
-
1102
- #[ test]
1103
- fn test_and_eval ( ) {
1104
- let input = Input :: default ( ) ;
1105
- let mut output = Output {
1106
- show : true ,
1107
- boost : 1.0 ,
1108
- price : Default :: default ( ) ,
1109
- } ;
1110
-
1111
- let cases = [
1112
- ( true , true , true ) ,
1113
- ( false , false , false ) ,
1114
- ( false , true , false ) ,
1115
- ( true , false , false ) ,
1116
- ] ;
1117
-
1118
- for ( lhs, rhs, expected) in cases. iter ( ) {
1119
- let rule = Rule :: Function ( Function :: new_and ( Value :: Bool ( * lhs) , Value :: Bool ( * rhs) ) ) ;
1120
- let expected = Some ( Value :: Bool ( * expected) ) ;
1121
-
1122
- assert_eq ! ( Ok ( expected) , rule. eval( & input, & mut output) ) ;
1123
- }
1124
- }
1125
-
1126
- #[ test]
1127
- fn test_if_eval ( ) {
1128
- let input = Input :: default ( ) ;
1129
- let mut output = Output {
1130
- show : true ,
1131
- boost : 1.0 ,
1132
- price : Default :: default ( ) ,
1133
- } ;
1134
-
1135
- let then = Value :: String ( "yes" . to_string ( ) ) ;
1136
-
1137
- let rule = Rule :: Function ( Function :: new_if ( Value :: Bool ( true ) , then. clone ( ) ) ) ;
1138
-
1139
- assert_eq ! ( Ok ( Some ( then. clone( ) ) ) , rule. eval( & input, & mut output) ) ;
1140
-
1141
- let rule = Rule :: Function ( Function :: new_if ( Value :: Bool ( false ) , then) ) ;
1142
-
1143
- assert_eq ! ( Ok ( None ) , rule. eval( & input, & mut output) ) ;
1144
- }
1145
-
1146
- #[ test]
1147
- fn test_bn_eval_from_actual_number_value_string_bignum_or_number ( ) {
1148
- let input = Input :: default ( ) ;
1149
- let mut output = Output {
1150
- show : true ,
1151
- boost : 1.0 ,
1152
- price : Default :: default ( ) ,
1153
- } ;
1154
-
1155
- let cases = vec ! [
1156
- ( Value :: new_string( "1000" ) , Value :: BigNum ( 1000 . into( ) ) ) ,
1157
- ( Value :: new_number( 2_000 ) , Value :: BigNum ( 2_000 . into( ) ) ) ,
1158
- ( Value :: BigNum ( 3 . into( ) ) , Value :: BigNum ( 3 . into( ) ) ) ,
1159
- // rounded floats should work!
1160
- (
1161
- Value :: Number ( Number :: from_f64( 40.0 ) . expect( "should create float number" ) ) ,
1162
- Value :: BigNum ( 40 . into( ) ) ,
1163
- ) ,
1164
- ] ;
1165
-
1166
- for ( from, expected) in cases. into_iter ( ) {
1167
- let rule = Rule :: Function ( Function :: new_bn ( from) ) ;
1168
-
1169
- assert_eq ! ( Ok ( Some ( expected) ) , rule. eval( & input, & mut output) ) ;
1170
- }
1171
- }
1172
-
1173
- #[ test]
1174
- fn test_bn_eval_from_actual_incorrect_value ( ) {
1175
- let input = Input :: default ( ) ;
1176
- let mut output = Output {
1177
- show : true ,
1178
- boost : 1.0 ,
1179
- price : Default :: default ( ) ,
1180
- } ;
1181
-
1182
- let error_cases = vec ! [
1183
- Value :: new_string( "text" ) ,
1184
- // BigNums can only be positive
1185
- Value :: new_number( -100 ) ,
1186
- Value :: Bool ( true ) ,
1187
- Value :: Array ( vec![ Value :: Bool ( false ) ] ) ,
1188
- Value :: Number ( Number :: from_f64( 2.5 ) . expect( "should create float number" ) ) ,
1189
- ] ;
1190
-
1191
- for error_case in error_cases. into_iter ( ) {
1192
- let rule = Rule :: Function ( Function :: new_bn ( error_case) ) ;
1193
-
1194
- assert_eq ! ( Err ( Error :: TypeError ) , rule. eval( & input, & mut output) ) ;
1195
- }
1196
- }
1197
-
1198
- #[ test]
1199
- fn test_set_eval ( ) {
1200
- use crate :: channel:: { Pricing , PricingBounds } ;
1201
- use crate :: util:: tests:: prep_db:: DUMMY_CHANNEL ;
1202
-
1203
- let mut channel = DUMMY_CHANNEL . clone ( ) ;
1204
- channel. spec . pricing_bounds = Some ( PricingBounds {
1205
- impression : Some ( Pricing {
1206
- min : 1_000 . into ( ) ,
1207
- max : 2_000 . into ( ) ,
1208
- } ) ,
1209
- click : Some ( Pricing {
1210
- min : 3_000 . into ( ) ,
1211
- max : 4_000 . into ( ) ,
1212
- } ) ,
1213
- } ) ;
1214
-
1215
- let input = Input :: default ( ) ;
1216
- let mut output = Output :: from ( & channel) ;
1217
-
1218
- assert_eq ! ( Some ( & BigNum :: from( 1_000 ) ) , output. price. get( "IMPRESSION" ) ) ;
1219
-
1220
- let set_to = Value :: BigNum ( BigNum :: from ( 20 ) ) ;
1221
- let rule = Rule :: Function ( Function :: new_set ( "price.IMPRESSION" , set_to) ) ;
1222
-
1223
- assert_eq ! ( Ok ( None ) , rule. eval( & input, & mut output) ) ;
1224
-
1225
- assert_eq ! ( Some ( & BigNum :: from( 20 ) ) , output. price. get( "IMPRESSION" ) ) ;
1226
- }
1227
- }
0 commit comments