11/****************************************************************************
2- * Copyright 2019, Optimizely, Inc. and contributors *
2+ * Copyright 2019-2020 , Optimizely, Inc. and contributors *
33* *
44* Licensed under the Apache License, Version 2.0 (the "License"); *
55* you may not use this file except in compliance with the License. *
@@ -113,16 +113,17 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
113113
114114extension AttributeValue {
115115
116- func isExactMatch( with target: Any ) throws -> Bool {
117- guard let targetValue = AttributeValue ( value: target) else {
118- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function, target: target) )
116+ func isExactMatch( with target: Any , condition: String = " " , name: String = " " ) throws -> Bool {
117+
118+ if !self . isValidForExactMatcher ( ) || ( self . doubleValue? . isInfinite ?? false ) {
119+ throw OptimizelyError . evaluateAttributeInvalidCondition ( condition)
119120 }
120121
121- guard self . isComparable ( with: targetValue) else {
122- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function , target: target ) )
122+ guard let targetValue = AttributeValue ( value : target ) , self . isComparable ( with: targetValue) else {
123+ throw OptimizelyError . evaluateAttributeInvalidType ( condition , target, name )
123124 }
124125
125- try checkValidAttributeNumber ( target)
126+ try checkValidAttributeNumber ( target, condition : condition , name : name )
126127
127128 // same type and same value
128129 if self == targetValue {
@@ -136,45 +137,47 @@ extension AttributeValue {
136137
137138 return false
138139 }
139-
140- func isSubstring( of target: Any ) throws -> Bool {
140+
141+ func isSubstring( of target: Any , condition: String = " " , name: String = " " ) throws -> Bool {
142+
141143 guard case . string( let value) = self else {
142- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function , target : target ) )
144+ throw OptimizelyError . evaluateAttributeInvalidCondition ( condition )
143145 }
144146
145147 guard let targetStr = target as? String else {
146- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function , target: target ) )
148+ throw OptimizelyError . evaluateAttributeInvalidType ( condition , target, name )
147149 }
148150
149151 return targetStr. contains ( value)
150152 }
151153
152- func isGreater( than target: Any ) throws -> Bool {
153- guard let targetValue = AttributeValue ( value: target) else {
154- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function, target: target) )
154+ func isGreater( than target: Any , condition: String = " " , name: String = " " ) throws -> Bool {
155+
156+ guard let currentDouble = self . doubleValue, currentDouble. isFinite else {
157+ throw OptimizelyError . evaluateAttributeInvalidCondition ( condition)
155158 }
156159
157- guard let currentDouble = self . doubleValue ,
160+ guard let targetValue = AttributeValue ( value : target ) ,
158161 let targetDouble = targetValue. doubleValue else {
159- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function , target: target ) )
162+ throw OptimizelyError . evaluateAttributeInvalidType ( condition , target, name )
160163 }
161164
162- try checkValidAttributeNumber ( target)
163-
165+ try checkValidAttributeNumber ( target, condition : condition , name : name )
166+
164167 return currentDouble > targetDouble
165168 }
166169
167- func isLess( than target: Any ) throws -> Bool {
168- guard let targetValue = AttributeValue ( value: target) else {
169- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function, target: target) )
170+ func isLess( than target: Any , condition: String = " " , name: String = " " ) throws -> Bool {
171+
172+ guard let currentDouble = self . doubleValue, currentDouble. isFinite else {
173+ throw OptimizelyError . evaluateAttributeInvalidCondition ( condition)
170174 }
171175
172- guard let currentDouble = self . doubleValue ,
176+ guard let targetValue = AttributeValue ( value : target ) ,
173177 let targetDouble = targetValue. doubleValue else {
174- throw OptimizelyError . evaluateAttributeInvalidType ( prettySrc ( #function , target: target ) )
178+ throw OptimizelyError . evaluateAttributeInvalidType ( condition , target, name )
175179 }
176-
177- try checkValidAttributeNumber ( target)
180+ try checkValidAttributeNumber ( target, condition: condition, name: name)
178181
179182 return currentDouble < targetDouble
180183 }
@@ -214,7 +217,7 @@ extension AttributeValue {
214217 }
215218 }
216219
217- func checkValidAttributeNumber( _ number: Any ? , caller: String = #function) throws {
220+ func checkValidAttributeNumber( _ number: Any ? , condition : String , name : String , caller: String = #function) throws {
218221 // check range for any value types (Int, Int64, Double, Float...)
219222 // do not check value range for string types
220223
@@ -231,7 +234,17 @@ extension AttributeValue {
231234
232235 // valid range: [-2^53, 2^53]
233236 if abs ( num) > pow ( 2 , 53 ) {
234- throw OptimizelyError . evaluateAttributeValueOutOfRange ( prettySrc ( caller, target: number) )
237+ throw OptimizelyError . evaluateAttributeValueOutOfRange ( condition, name)
238+ }
239+ }
240+
241+ func isValidForExactMatcher( ) -> Bool {
242+ switch ( self ) {
243+ case ( . string) : return true
244+ case ( . int) : return true
245+ case ( . double) : return true
246+ case ( . bool) : return true
247+ default : return false
235248 }
236249 }
237250
0 commit comments