From c38883677cda76298332b62c76b4180598c88657 Mon Sep 17 00:00:00 2001 From: Steve Benedick Date: Thu, 24 Sep 2020 10:29:20 -0600 Subject: [PATCH 1/7] add beta language, update spm installation text --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d3decc5..cedfc12 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,36 @@ # AEPRulesEngine +## BETA + +AEPRulesEngine is currently in beta. Use of this code is by invitation only and not otherwise supported by Adobe. Please contact your Adobe Customer Success Manager to learn more. + ## Overview A simple, generic, extensible Rules Engine in Swift. - ## Installation ### Swift Package Manager -Once you have your Swift package set up, adding RuleEngine as a dependency is as easy as adding it to the dependencies value of your Package.swift. +To add the AEPRulesEngine Package to your application, from the Xcode menu select: + +`File > Swift Packages > Add Package Dependency...` + +Enter the URL for the AEPRulesEngine package repository: `https://github.com/adobe/aepsdk-rulesengine-ios.git`. + +When prompted, make sure you change the branch to `main`. + +There are three options for selecting your dependencies as identified by the *suffix* of the library name: + +- "Dynamic" - the library will be linked dynamically +- "Static" - the library will be linked statically +- *(none)* - (default) SPM will determine whether the library will be linked dynamically or statically + +Alternatively, if your project has a `Package.swift` file, you can add AEPRulesEngine directly to your dependencies: -Example: ``` dependencies: [ -.package(url: "https://github.com/adobe/aepsdk-rulesengine-ios.git", from: "0.0.1") + .package(url: "https://github.com/adobe/aepsdk-rulesengine-ios.git", .branch("main")) ] ``` @@ -55,7 +71,6 @@ let matchedRules = rulesEngine.evaluate(data: ["company":"adobe"]) ``` - ## Contributing Contributions are welcomed! Read the [Contributing Guide](./.github/CONTRIBUTING.md) for more information. From 7f2b7ec53048212d3507bcd15b4aa6262143758f Mon Sep 17 00:00:00 2001 From: Yansong Yang Date: Thu, 22 Oct 2020 10:31:15 -0600 Subject: [PATCH 2/7] add Codecov badge to Readme page --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7754586..8443bb3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![codecov](https://codecov.io/gh/yangyansong-adbe/aepsdk-rulesengine-ios/branch/dev/graph/badge.svg?token=T8LRU71KTB)](undefined) + # AEPRulesEngine ## BETA From b2e0247bf57975209997dd9a26fd576b7c420394 Mon Sep 17 00:00:00 2001 From: Jiabin Geng Date: Mon, 26 Oct 2020 10:04:32 -0600 Subject: [PATCH 3/7] tag version 3.0.0-beta.1 (#28) Co-authored-by: jgeng --- AEPRulesEngine.podspec | 2 +- Package.swift | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/AEPRulesEngine.podspec b/AEPRulesEngine.podspec index e7151f2..3dc8952 100644 --- a/AEPRulesEngine.podspec +++ b/AEPRulesEngine.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "AEPRulesEngine" - s.version = "0.0.1" + s.version = "1.0.0-beta.1" s.summary = "AEPRulesEngine" s.description = <<-DESC A simple, generic, extensible Rules Engine in Swift diff --git a/Package.swift b/Package.swift index cdce476..86980c4 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,6 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), -// .package(url: "https://github.com/Realm/SwiftLint", from: "0.28.1") ], targets: [ .target(name: "AEPRulesEngine", dependencies: []), From 42d077db4569b5b9d32248ad004a37a46d197579 Mon Sep 17 00:00:00 2001 From: steve benedick Date: Wed, 6 Jan 2021 16:05:03 -0700 Subject: [PATCH 4/7] -some cleanup in the rules engine --- LICENSE | 2 +- README.md | 44 ++++++++++++++++--- .../AEPRulesEngine/ConditionEvaluator.swift | 18 +++++--- Sources/AEPRulesEngine/Context.swift | 20 +++++++++ Sources/AEPRulesEngine/Evaluating.swift | 2 +- .../Expression/ComparisonExpression.swift | 10 +++-- .../{ => Expression}/Evaluable.swift | 2 +- .../Expression/LogicalExpression.swift | 4 +- .../AEPRulesEngine/Expression/Operand.swift | 6 +-- .../Expression/UnaryExpression.swift | 4 +- .../{RulesEngineLog.swift => Log/Log.swift} | 9 ++-- .../LogLevel.swift} | 28 +++++------- Sources/AEPRulesEngine/Log/Logging.swift | 22 ++++++++++ Sources/AEPRulesEngine/Operand+Literal.swift | 2 +- .../AEPRulesEngine/Result+RulesFailure.swift | 2 +- Sources/AEPRulesEngine/Rule.swift | 2 +- Sources/AEPRulesEngine/RulesEngine.swift | 23 ++-------- Sources/AEPRulesEngine/RulesFailure.swift | 22 ++++++++++ .../Template/MustacheError.swift | 22 ++++++++++ .../Template/MustacheToken.swift | 3 +- .../Template/ParserTagDelimiters.swift | 37 ++++++++++++++++ Sources/AEPRulesEngine/Template/Segment.swift | 11 +---- .../AEPRulesEngine/Template/Template.swift | 2 +- .../Template/TemplateParser.swift | 35 +++++---------- Sources/AEPRulesEngine/Transformer.swift | 32 ++++++++++++++ Sources/AEPRulesEngine/Transforming.swift | 19 +------- Sources/AEPRulesEngine/Traversable.swift | 2 +- .../UnitTests/ExpressionTests.swift | 28 ++++++------ .../UnitTests/OperandTests.swift | 6 +-- .../UnitTests/ParserTests.swift | 14 +++--- .../UnitTests/RulesEngineLogLevelTests.swift | 16 +++---- .../UnitTests/RulesEngineLoggingTests.swift | 24 +++++----- .../UnitTests/RulesEngineTests.swift | 2 +- .../UnitTests/TraverseTests.swift | 2 +- 34 files changed, 308 insertions(+), 169 deletions(-) create mode 100644 Sources/AEPRulesEngine/Context.swift rename Sources/AEPRulesEngine/{ => Expression}/Evaluable.swift (94%) rename Sources/AEPRulesEngine/{RulesEngineLog.swift => Log/Log.swift} (85%) rename Sources/AEPRulesEngine/{RulesEngineLogging.swift => Log/LogLevel.swift} (56%) create mode 100644 Sources/AEPRulesEngine/Log/Logging.swift create mode 100644 Sources/AEPRulesEngine/RulesFailure.swift create mode 100644 Sources/AEPRulesEngine/Template/MustacheError.swift create mode 100644 Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift create mode 100644 Sources/AEPRulesEngine/Transformer.swift diff --git a/LICENSE b/LICENSE index 758d439..f897003 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2020 Adobe + Copyright 2021 Adobe Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 7754586..c9b1297 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,43 @@ AEPRulesEngine is currently in beta. Use of this code is by invitation only and A simple, generic, extensible Rules Engine in Swift. +## Requirements +- Xcode 11.0 (or newer) +- Swift 5.0 (or newer) + ## Installation +### [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) +```ruby +# Podfile +use_frameworks! + +# for app development, include all the following pods +target 'YOUR_TARGET_NAME' do + pod 'AEPRulesEngine', :git => 'https://github.com/adobe/aepsdk-rulesengine-ios.git', :branch => 'main' + pod 'AEPCore', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' + pod 'AEPServices', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' + pod 'AEPLifecycle', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' + pod 'AEPIdentity', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' +end + +# for extension development, include AEPCore and its dependencies +target 'YOUR_TARGET_NAME' do + pod 'AEPRulesEngine', :git => 'https://github.com/adobe/aepsdk-rulesengine-ios.git', :branch => 'main' + pod 'AEPCore', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' + pod 'AEPServices', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' +end +``` + +Replace `YOUR_TARGET_NAME` and then, in the `Podfile` directory, type: + +```bash +$ pod install +``` + ### Swift Package Manager -To add the AEPRulesEngine Package to your application, from the Xcode menu select: +To add the AEPRulesEngine package to your application, from the Xcode menu select: `File > Swift Packages > Add Package Dependency...` @@ -37,9 +69,9 @@ dependencies: [ ## Usage -### Initialize Rules Engine +### Initialize the Rules Engine -To create a `RuleEngine` instance, first define an `Evaluator` and then use it as the parameter for `RuleEngine`. +To create a `RulesEngine` instance, define an `Evaluator` and pass it to the `RulesEngine`'s initializer: ``` let evaluator = ConditionEvaluator(options: .caseInsensitive) let rulesEngine = RulesEngine(evaluator: evaluator) @@ -47,7 +79,7 @@ let rulesEngine = RulesEngine(evaluator: evaluator) ### Define Rules -Any thing that conforms to the `Rule` protocol can be used as rule. +Anything that conforms to the `Rule` protocol can be used as rule: ``` Swift public class MobileRule: Rule { init(condition: Evaluable) { self.condition = condition } @@ -57,7 +89,7 @@ let condition = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: " let rule = MobileRule(condition: condition) rulesEngine.addRules(rules: [rule]) ``` -However, a rule like this doesn't make much sense, without the ability to dynamically fetch a value it will always be true or false. +A rule without the flexibility to dynamically fetch a value will always evaluate to true or false. To fetch the value for a rule at runtime, use a Mustache Token: ``` Swift let mustache = Operand(mustache: "{{company}}") @@ -68,7 +100,7 @@ rulesEngine.addRules(rules: [rule]) ### Evaluate data -Use the method `evaluate` to run rule engine on the input data that is `Traversable`. +Use the `evaluate` method to process `Traversable` data through the `RulesEngine`: ``` let matchedRules = rulesEngine.evaluate(data: ["company":"adobe"]) diff --git a/Sources/AEPRulesEngine/ConditionEvaluator.swift b/Sources/AEPRulesEngine/ConditionEvaluator.swift index d565f0f..cde5a90 100644 --- a/Sources/AEPRulesEngine/ConditionEvaluator.swift +++ b/Sources/AEPRulesEngine/ConditionEvaluator.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -13,11 +13,14 @@ public class ConditionEvaluator: Evaluating { fileprivate let LOG_TAG = "ConditionEvaluator" var operators: [String: Any] = [:] + + // MARK: - Evaluating public func evaluate(operation: String, lhs: A) -> Result { let op = operators[getHash(operation: operation, typeA: A.self)] as? ((A) -> Bool) + guard let op_ = op else { - let message = "Operator not defined for \(getHash(operation: operation, typeA: A.self))" - RulesEngineLog.trace(label: LOG_TAG, message) + let message = "No operator defined for \(getHash(operation: operation, typeA: A.self))" + Log.trace(label: LOG_TAG, message) return Result.failure(RulesFailure.missingOperator(message: message)) } return op_(lhs) ? Result.success(true) : Result.failure(.conditionNotMatched(message: "(\(String(describing: A.self))(\(lhs)) \(operation))")) @@ -27,8 +30,8 @@ public class ConditionEvaluator: Evaluating { let op = operators[getHash(operation: operation, typeA: A.self, typeB: B.self)] as? ((A, B) -> Bool) guard let op_ = op else { - let message = "Operator not defined for \(getHash(operation: operation, typeA: A.self, typeB: B.self))" - RulesEngineLog.trace(label: LOG_TAG, message) + let message = "No operator defined for \(getHash(operation: operation, typeA: A.self, typeB: B.self))" + Log.trace(label: LOG_TAG, message) return Result.failure(RulesFailure.missingOperator(message: message)) } return op_(lhs, rhs) ? Result.success(true) : Result.failure(.conditionNotMatched(message: "\(String(describing: A.self))(\(lhs)) \(operation) \(String(describing: B.self))(\(rhs))")) @@ -78,6 +81,7 @@ public extension ConditionEvaluator { } private func addDefaultOperators() { + addComparisonOperator(operation: "and", type: Bool.self, closure: { $0 && $1 }) addComparisonOperator(operation: "or", type: Bool.self, closure: { $0 || $1 }) @@ -117,9 +121,11 @@ public extension ConditionEvaluator { } private func addCaseInSensitiveOperators() { - addComparisonOperator(operation: "startsWith", type: String.self, closure: { $0.lowercased().starts(with: $1.lowercased()) }) addComparisonOperator(operation: "equals", type: String.self, closure: { $0.lowercased() == $1.lowercased() }) + addComparisonOperator(operation: "notEquals", type: String.self, closure: { $0.lowercased() != $1.lowercased() }) + addComparisonOperator(operation: "startsWith", type: String.self, closure: { $0.lowercased().starts(with: $1.lowercased()) }) addComparisonOperator(operation: "endsWith", type: String.self, closure: { $0.lowercased().hasSuffix($1.lowercased()) }) addComparisonOperator(operation: "contains", type: String.self, closure: { $0.lowercased().contains($1.lowercased()) }) + addComparisonOperator(operation: "notContains", type: String.self, closure: { !$0.lowercased().contains($1.lowercased()) }) } } diff --git a/Sources/AEPRulesEngine/Context.swift b/Sources/AEPRulesEngine/Context.swift new file mode 100644 index 0000000..965b743 --- /dev/null +++ b/Sources/AEPRulesEngine/Context.swift @@ -0,0 +1,20 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +import Foundation + +/// A type that contains all pieces necessary for boolean evaluation +public struct Context { + public let data: Traversable + public let evaluator: Evaluating + public let transformer: Transforming +} diff --git a/Sources/AEPRulesEngine/Evaluating.swift b/Sources/AEPRulesEngine/Evaluating.swift index 18f1bd1..5457451 100644 --- a/Sources/AEPRulesEngine/Evaluating.swift +++ b/Sources/AEPRulesEngine/Evaluating.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift b/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift index 2a74b55..b9e604f 100644 --- a/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift +++ b/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -24,8 +24,10 @@ public struct ComparisonExpression: Evaluable { self.operationName = operationName } + // MARK: - Evaluable + public func evaluate(in context: Context) -> Result { - RulesEngineLog.trace(label: LOG_TAG, "Evaluating \(lhs) - \(operationName) - \(rhs)") + Log.trace(label: LOG_TAG, "Evaluating \(lhs) - \(operationName) - \(rhs)") let resolvedLhs = lhs(context) let resolvedRhs = rhs(context) var result: Result @@ -38,8 +40,8 @@ public struct ComparisonExpression: Evaluable { case .success: return result case let .failure(error): - RulesEngineLog.debug(label: LOG_TAG, "Failed to evaluate \(String(describing: resolvedLhs)) - \(operationName) - \(String(describing: resolvedRhs))") - return Result.failure(.innerFailure(message: "Comparison (\(lhs) \(operationName) \(rhs)) returns false", error: error)) + Log.debug(label: LOG_TAG, "Failed to evaluate \(String(describing: resolvedLhs)) - \(operationName) - \(String(describing: resolvedRhs))") + return Result.failure(.innerFailure(message: "Comparison (\(lhs) \(operationName) \(rhs)) returned false", error: error)) } } } diff --git a/Sources/AEPRulesEngine/Evaluable.swift b/Sources/AEPRulesEngine/Expression/Evaluable.swift similarity index 94% rename from Sources/AEPRulesEngine/Evaluable.swift rename to Sources/AEPRulesEngine/Expression/Evaluable.swift index 649326e..71ec5db 100644 --- a/Sources/AEPRulesEngine/Evaluable.swift +++ b/Sources/AEPRulesEngine/Expression/Evaluable.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Sources/AEPRulesEngine/Expression/LogicalExpression.swift b/Sources/AEPRulesEngine/Expression/LogicalExpression.swift index f11aa2d..06e6f76 100644 --- a/Sources/AEPRulesEngine/Expression/LogicalExpression.swift +++ b/Sources/AEPRulesEngine/Expression/LogicalExpression.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -43,7 +43,7 @@ public struct LogicalExpression: Evaluable { } return Result.failure(.innerFailures(message: "`Or` returns false", errors: operandsResolve.filter { !$0.value }.map { $0.error ?? RulesFailure.unknown })) default: - return .failure(.missingOperator(message: "Unkonwn conjunction operator")) + return .failure(.missingOperator(message: "Unknown conjunction operator '\(operationName)'")) } } } diff --git a/Sources/AEPRulesEngine/Expression/Operand.swift b/Sources/AEPRulesEngine/Expression/Operand.swift index 51a66e1..9d3df7b 100644 --- a/Sources/AEPRulesEngine/Expression/Operand.swift +++ b/Sources/AEPRulesEngine/Expression/Operand.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -51,9 +51,9 @@ extension Operand: CustomStringConvertible { case .none: return "" case let .some(value): - return "" + return "" case let .token(mustache): - return "" + return "" } } } diff --git a/Sources/AEPRulesEngine/Expression/UnaryExpression.swift b/Sources/AEPRulesEngine/Expression/UnaryExpression.swift index dff8ec2..335c142 100644 --- a/Sources/AEPRulesEngine/Expression/UnaryExpression.swift +++ b/Sources/AEPRulesEngine/Expression/UnaryExpression.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -23,7 +23,7 @@ public struct UnaryExpression: Evaluable { } public func evaluate(in context: Context) -> Result { - RulesEngineLog.trace(label: LOG_TAG, "Evaluating \(operationName) - \(lhs)") + Log.trace(label: LOG_TAG, "Evaluating \(operationName) - \(lhs)") let resolvedLhs = lhs(context) if let resolvedLhs_ = resolvedLhs { return context.evaluator.evaluate(operation: operationName, lhs: resolvedLhs_) diff --git a/Sources/AEPRulesEngine/RulesEngineLog.swift b/Sources/AEPRulesEngine/Log/Log.swift similarity index 85% rename from Sources/AEPRulesEngine/RulesEngineLog.swift rename to Sources/AEPRulesEngine/Log/Log.swift index 9c6b718..c24280f 100644 --- a/Sources/AEPRulesEngine/RulesEngineLog.swift +++ b/Sources/AEPRulesEngine/Log/Log.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -12,8 +12,11 @@ import Foundation -public class RulesEngineLog { - public static var logging: RulesEngineLogging? +/// The `Log` class will be dormant unless its static `logging` variable is initialized. +/// To enable logging from the RulesEngine, implement a class that conforms to the +/// `Logging` protocol and use an instance of it to set the `Log.logging` variable. +public class Log { + public static var logging: Logging? /// Used to print more verbose information. /// - Parameters: /// - label: the name of the label to localize message diff --git a/Sources/AEPRulesEngine/RulesEngineLogging.swift b/Sources/AEPRulesEngine/Log/LogLevel.swift similarity index 56% rename from Sources/AEPRulesEngine/RulesEngineLogging.swift rename to Sources/AEPRulesEngine/Log/LogLevel.swift index c34a226..221e7a5 100644 --- a/Sources/AEPRulesEngine/RulesEngineLogging.swift +++ b/Sources/AEPRulesEngine/Log/LogLevel.swift @@ -1,9 +1,9 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language @@ -11,30 +11,22 @@ */ import Foundation -public protocol RulesEngineLogging { - /// Logs a message - /// - Parameters: - /// - level: One of the message level identifiers, e.g., DEBUG - /// - label: Name of a label to localize message - /// - message: The string message - func log(level: RulesEngineLogLevel, label: String, message: String) -} -public enum RulesEngineLogLevel: Int, Comparable { +public enum LogLevel: Int, Comparable { case error = 0 case warning = 1 case debug = 2 case trace = 3 - - /// Compares two `RulesEngineLogLevel`s for order + + /// Compares two `LogLevel`s for order /// - Parameters: - /// - lhs: the first `RulesEngineLogLevel` to be compared - /// - rhs: the second `RulesEngineLogLevel` to be compared - /// - Returns: true, only if the second `LogLevel` is more critical - public static func < (lhs: RulesEngineLogLevel, rhs: RulesEngineLogLevel) -> Bool { + /// - lhs: the first `LogLevel` to be compared + /// - rhs: the second `LogLevel` to be compared + /// - Returns: true if the second `LogLevel` is more critical + public static func < (lhs: LogLevel, rhs: LogLevel) -> Bool { lhs.rawValue < rhs.rawValue } - + public func toString() -> String { switch self { case .trace: diff --git a/Sources/AEPRulesEngine/Log/Logging.swift b/Sources/AEPRulesEngine/Log/Logging.swift new file mode 100644 index 0000000..c3e4b57 --- /dev/null +++ b/Sources/AEPRulesEngine/Log/Logging.swift @@ -0,0 +1,22 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +import Foundation + +public protocol Logging { + /// Logs a message + /// - Parameters: + /// - level: A `LogLevel` identifying the severity of the log. e.g. - `.debug` + /// - label: Label for the log + /// - message: The `String` message + func log(level: LogLevel, label: String, message: String) +} diff --git a/Sources/AEPRulesEngine/Operand+Literal.swift b/Sources/AEPRulesEngine/Operand+Literal.swift index 7e92b66..f741f65 100644 --- a/Sources/AEPRulesEngine/Operand+Literal.swift +++ b/Sources/AEPRulesEngine/Operand+Literal.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Sources/AEPRulesEngine/Result+RulesFailure.swift b/Sources/AEPRulesEngine/Result+RulesFailure.swift index cdefc23..ec3e25b 100644 --- a/Sources/AEPRulesEngine/Result+RulesFailure.swift +++ b/Sources/AEPRulesEngine/Result+RulesFailure.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Sources/AEPRulesEngine/Rule.swift b/Sources/AEPRulesEngine/Rule.swift index fe59f7a..867c2c4 100644 --- a/Sources/AEPRulesEngine/Rule.swift +++ b/Sources/AEPRulesEngine/Rule.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Sources/AEPRulesEngine/RulesEngine.swift b/Sources/AEPRulesEngine/RulesEngine.swift index e074337..67e152b 100644 --- a/Sources/AEPRulesEngine/RulesEngine.swift +++ b/Sources/AEPRulesEngine/RulesEngine.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -20,7 +20,7 @@ public class RulesEngine { var tracer: RulesTracer? var rules = [T]() - public init(evaluator: Evaluating, transformer: Transforming = Transform()) { + public init(evaluator: Evaluating, transformer: Transforming = Transformer()) { self.evaluator = evaluator self.transformer = transformer } @@ -51,24 +51,9 @@ public class RulesEngine { rules = [T]() } - /// trace the result of each rule eveluation - /// - Parameter tracer: the rules tracer will be called after each rule eveluation + /// trace the result of each rule evaluation + /// - Parameter tracer: the `RulesTracer` which will be called after each rule evaluation public func trace(with tracer: @escaping RulesTracer) { self.tracer = tracer } } - -public struct Context { - public let data: Traversable - public let evaluator: Evaluating - public let transformer: Transforming -} - -public enum RulesFailure: Error { - case unknown - case conditionNotMatched(message: String) - case typeMismatched(message: String) - case missingOperator(message: String) - indirect case innerFailure(message: String, error: RulesFailure) - indirect case innerFailures(message: String, errors: [RulesFailure]) -} diff --git a/Sources/AEPRulesEngine/RulesFailure.swift b/Sources/AEPRulesEngine/RulesFailure.swift new file mode 100644 index 0000000..fc47864 --- /dev/null +++ b/Sources/AEPRulesEngine/RulesFailure.swift @@ -0,0 +1,22 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +import Foundation + +public enum RulesFailure: Error { + case unknown + case conditionNotMatched(message: String) + case typeMismatched(message: String) + case missingOperator(message: String) + indirect case innerFailure(message: String, error: RulesFailure) + indirect case innerFailures(message: String, errors: [RulesFailure]) +} diff --git a/Sources/AEPRulesEngine/Template/MustacheError.swift b/Sources/AEPRulesEngine/Template/MustacheError.swift new file mode 100644 index 0000000..d0d9ddc --- /dev/null +++ b/Sources/AEPRulesEngine/Template/MustacheError.swift @@ -0,0 +1,22 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +import Foundation + +public struct MustacheError: Error { + /// Eventual error message + public let message: String? + + public init(message: String? = nil) { + self.message = message + } +} diff --git a/Sources/AEPRulesEngine/Template/MustacheToken.swift b/Sources/AEPRulesEngine/Template/MustacheToken.swift index eb693e0..f813a2f 100644 --- a/Sources/AEPRulesEngine/Template/MustacheToken.swift +++ b/Sources/AEPRulesEngine/Template/MustacheToken.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -11,6 +11,7 @@ */ import Foundation + public indirect enum MustacheToken { /// text case variable(text: String) diff --git a/Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift b/Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift new file mode 100644 index 0000000..00de45f --- /dev/null +++ b/Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift @@ -0,0 +1,37 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +import Foundation + +struct ParserTagDelimiters { + let tagDelimiterPair: DelimiterPair + + init(_ tagDelimiterPair: DelimiterPair) { + self.tagDelimiterPair = tagDelimiterPair + } + + var startTag: String { + return tagDelimiterPair.0 + } + + var startTagLength: Int { + return startTag.count + } + + var endTag: String { + return tagDelimiterPair.1 + } + + var endTagLength: Int { + return endTag.count + } +} diff --git a/Sources/AEPRulesEngine/Template/Segment.swift b/Sources/AEPRulesEngine/Template/Segment.swift index e120a31..4f16bbd 100644 --- a/Sources/AEPRulesEngine/Template/Segment.swift +++ b/Sources/AEPRulesEngine/Template/Segment.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -10,15 +10,6 @@ governing permissions and limitations under the License. */ -public struct MustacheError: Error { - /// Eventual error message - public let message: String? - - public init(message: String? = nil) { - self.message = message - } -} - public struct Segment { enum `Type` { /// text diff --git a/Sources/AEPRulesEngine/Template/Template.swift b/Sources/AEPRulesEngine/Template/Template.swift index b2ff21c..c3f10ce 100644 --- a/Sources/AEPRulesEngine/Template/Template.swift +++ b/Sources/AEPRulesEngine/Template/Template.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Sources/AEPRulesEngine/Template/TemplateParser.swift b/Sources/AEPRulesEngine/Template/TemplateParser.swift index cc5187c..3cbc3cb 100644 --- a/Sources/AEPRulesEngine/Template/TemplateParser.swift +++ b/Sources/AEPRulesEngine/Template/TemplateParser.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -13,6 +13,8 @@ import Foundation /// A pair of tag delimiters, such as `("{{", "}}")`. +public typealias DelimiterPair = (String, String) + public struct TemplateParser { static let DefaultTagDelimiterPair: DelimiterPair = ("{{", "}}") @@ -27,15 +29,15 @@ public struct TemplateParser { while i < end { switch state { case .start: - if index(i, isAt: currentDelimiters.tagDelimiterPair.0, in: templateString) { + if index(i, isAt: currentDelimiters.startTag, in: templateString) { state = .tag(startIndex: i) - i = templateString.index(i, offsetBy: currentDelimiters.tagStartLength) + i = templateString.index(i, offsetBy: currentDelimiters.startTagLength) i = templateString.index(before: i) } else { state = .text(startIndex: i) } case let .text(startIndex): - if index(i, isAt: currentDelimiters.tagDelimiterPair.0, in: templateString) { + if index(i, isAt: currentDelimiters.startTag, in: templateString) { if startIndex != i { let range = startIndex ..< i let token = Segment( @@ -47,13 +49,13 @@ public struct TemplateParser { tokens.append(token) } state = .tag(startIndex: i) - i = templateString.index(i, offsetBy: currentDelimiters.tagStartLength) + i = templateString.index(i, offsetBy: currentDelimiters.startTagLength) i = templateString.index(before: i) } case let .tag(startIndex): - if index(i, isAt: currentDelimiters.tagDelimiterPair.1, in: templateString) { - let tagInitialIndex = templateString.index(startIndex, offsetBy: currentDelimiters.tagStartLength) - let tokenRange = startIndex ..< templateString.index(i, offsetBy: currentDelimiters.tagEndLength) + if index(i, isAt: currentDelimiters.endTag, in: templateString) { + let tagInitialIndex = templateString.index(startIndex, offsetBy: currentDelimiters.startTagLength) + let tokenRange = startIndex ..< templateString.index(i, offsetBy: currentDelimiters.endTagLength) let content = String(templateString[tagInitialIndex ..< i]) let mustacheToken = MustacheToken(content) @@ -65,7 +67,7 @@ public struct TemplateParser { tokens.append(token) state = .start - i = templateString.index(i, offsetBy: currentDelimiters.tagEndLength) + i = templateString.index(i, offsetBy: currentDelimiters.endTagLength) i = templateString.index(before: i) } } @@ -107,18 +109,3 @@ public struct TemplateParser { case tag(startIndex: String.Index) } } - -/// A pair of tag delimiters, such as `("{{", "}}")`. -public typealias DelimiterPair = (String, String) - -public struct ParserTagDelimiters { - let tagDelimiterPair: DelimiterPair - let tagStartLength: Int - let tagEndLength: Int - init(_ tagDelimiterPair: DelimiterPair) { - self.tagDelimiterPair = tagDelimiterPair - - tagStartLength = tagDelimiterPair.0.distance(from: tagDelimiterPair.0.startIndex, to: tagDelimiterPair.0.endIndex) - tagEndLength = tagDelimiterPair.1.distance(from: tagDelimiterPair.1.startIndex, to: tagDelimiterPair.1.endIndex) - } -} diff --git a/Sources/AEPRulesEngine/Transformer.swift b/Sources/AEPRulesEngine/Transformer.swift new file mode 100644 index 0000000..dc5e53c --- /dev/null +++ b/Sources/AEPRulesEngine/Transformer.swift @@ -0,0 +1,32 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +import Foundation + +public class Transformer: Transforming { + var transformations: [String: Transformation] = [:] + + public init() {} + + public func register(name: String, transformation: @escaping Transformation) { + transformations[name] = transformation + } + + // MARK: - Transforming + + public func transform(name: String, parameter: Any) -> Any { + guard let transformation = transformations[name] else { + return parameter + } + return transformation(parameter) + } +} diff --git a/Sources/AEPRulesEngine/Transforming.swift b/Sources/AEPRulesEngine/Transforming.swift index 3f15da5..47e6969 100644 --- a/Sources/AEPRulesEngine/Transforming.swift +++ b/Sources/AEPRulesEngine/Transforming.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -11,25 +11,10 @@ */ import Foundation + public typealias Transformation = (Any) -> Any public protocol Transforming { func transform(name: String, parameter: Any) -> Any } -public class Transform: Transforming { - var transformations: [String: Transformation] = [:] - - public init() {} - - public func transform(name: String, parameter: Any) -> Any { - guard let transformation = transformations[name] else { - return parameter - } - return transformation(parameter) - } - - public func register(name: String, transformation: @escaping Transformation) { - transformations[name] = transformation - } -} diff --git a/Sources/AEPRulesEngine/Traversable.swift b/Sources/AEPRulesEngine/Traversable.swift index 5db00e5..e4ecf70 100644 --- a/Sources/AEPRulesEngine/Traversable.swift +++ b/Sources/AEPRulesEngine/Traversable.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Tests/AEPRulesEngineTests/UnitTests/ExpressionTests.swift b/Tests/AEPRulesEngineTests/UnitTests/ExpressionTests.swift index ac3ef3c..50499da 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/ExpressionTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/ExpressionTests.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -33,7 +33,7 @@ class ExpressionTests: XCTestCase { let evaluator = ConditionEvaluator(options: .defaultOptions) let a = ComparisonExpression(lhs: 3, operationName: "equals", rhs: 3) - let result = a.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transform())) + let result = a.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(result.value) } @@ -43,7 +43,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: a, b) - let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(result.value) } @@ -53,7 +53,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc1") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "or", operands: a, b) - let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(result.value) } @@ -63,7 +63,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc1") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc1") let c = LogicalExpression(operationName: "or", operands: a, b) - let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(!result.value) } @@ -73,7 +73,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc1") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc1") let c = LogicalExpression(operationName: "unkonwn", operands: a, b) - let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(!result.value) } @@ -87,7 +87,7 @@ class ExpressionTests: XCTestCase { let a = UnaryExpression(lhs: mustache, operationName: "isTrue") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: a, b) - let result = c.evaluate(in: Context(data: ["custom1": CustomOperand()], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: ["custom1": CustomOperand()], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(!result.value) } @@ -97,7 +97,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: mustache, operationName: "equals", rhs: "abc") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: a, b) - let result = c.evaluate(in: Context(data: ["key": "abc"], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: ["key": "abc"], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(result.value) } @@ -107,7 +107,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: mustache, operationName: "equals", rhs: "abc") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: a, b) - let result = c.evaluate(in: Context(data: ["key1": "abc"], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: ["key1": "abc"], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(!result.value) } @@ -117,7 +117,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: mustache, operationName: "equals", rhs: "abc") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: [a, b]) - let result = c.evaluate(in: Context(data: ["someelse": "abc"], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: ["someelse": "abc"], evaluator: evaluator, transformer: Transformer())) XCTAssertFalse(result.value) } @@ -127,7 +127,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: mustache, operationName: "nx", rhs: Operand.none) let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: a, b) - let result = c.evaluate(in: Context(data: ["key": "abc"], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: ["key": "abc"], evaluator: evaluator, transformer: Transformer())) XCTAssertFalse(result.value) } @@ -138,7 +138,7 @@ class ExpressionTests: XCTestCase { let a = ComparisonExpression(lhs: mustache, operationName: "notExist", rhs: Operand.none) let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: a, b) - let result = c.evaluate(in: Context(data: ["key": "abc"], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: ["key": "abc"], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(result.value) } @@ -153,7 +153,7 @@ class ExpressionTests: XCTestCase { let a = UnaryExpression(lhs: mustache, operationName: "isAmazing") let b = ComparisonExpression(lhs: "abc", operationName: "equals", rhs: "abc") let c = LogicalExpression(operationName: "and", operands: a, b) - let result = c.evaluate(in: Context(data: ["custom": CustomOperand()], evaluator: evaluator, transformer: Transform())) + let result = c.evaluate(in: Context(data: ["custom": CustomOperand()], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(result.value) } @@ -163,7 +163,7 @@ class ExpressionTests: XCTestCase { true } let a = ComparisonExpression(lhs: "3", operationName: "equals", rhs: 3) - let result = a.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transform())) + let result = a.evaluate(in: Context(data: [:], evaluator: evaluator, transformer: Transformer())) XCTAssertTrue(result.value) } } diff --git a/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift b/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift index 7227354..d542cf4 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -24,12 +24,12 @@ class OperandTests: XCTestCase { func testDoubleValue(){ let operand = Operand(floatLiteral: 1.2) - XCTAssertEqual("", String(describing: operand)) + XCTAssertEqual("", String(describing: operand)) } func testBoolValue(){ let operand = Operand(booleanLiteral: true) - XCTAssertEqual("", String(describing: operand)) + XCTAssertEqual("", String(describing: operand)) } func testNilValue(){ diff --git a/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift b/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift index dbf40a7..b201e70 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -31,19 +31,19 @@ class ParserTests: XCTestCase { func testPerformanceExample() { let template = Template(templateString: "sdfdfd{{test}}aaa") - let result = template.render(data: ["test": "value"], transformers: Transform()) + let result = template.render(data: ["test": "value"], transformers: Transformer()) XCTAssertEqual("sdfdfdvalueaaa", result) } func testCustomizedTokenFormat() { let template = Template(templateString: "sdfdfd[[test]]aaa", tagDelimiterPair: ("[[","]]")) - let result = template.render(data: ["test": "value"], transformers: Transform()) + let result = template.render(data: ["test": "value"], transformers: Transformer()) XCTAssertEqual("sdfdfdvalueaaa", result) } func testTransform() { let template = Template(templateString: "sdfdfd{{dash(test)}}aaa") - let tran = Transform() + let tran = Transformer() tran.register(name: "dash", transformation: { value in if value is String { return "-\(value as! String)-" @@ -58,21 +58,21 @@ class ParserTests: XCTestCase { func testTransform1() { let template = Template(templateString: "sdfdfd{{dash(test)}}aaa{{dash(int)}}") - let tran = Transform() + let tran = Transformer() let result = template.render(data: ["test": "value", "int": 5], transformers: tran) XCTAssertEqual("sdfdfdvalueaaa5", result) } func testTransform12() { let template = Template(templateString: "sdfdfd{{dash(test)}}aaa{{dash(int)}") - let tran = Transform() + let tran = Transformer() let result = template.render(data: ["test": "value", "int": 5], transformers: tran) XCTAssertEqual("", result) } func testTransform123() { let template = Template(templateString: "sdfdfd{{}}") - let tran = Transform() + let tran = Transformer() let result = template.render(data: ["test": "value", "int": 5], transformers: tran) XCTAssertEqual("sdfdfd", result) } diff --git a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift index 5f686ef..5e71e9e 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -16,15 +16,15 @@ import XCTest class RulesEngineLogLevelTests: XCTestCase { func testLogLevelComparison() { - XCTAssertTrue(RulesEngineLogLevel.error < RulesEngineLogLevel.warning) - XCTAssertTrue(RulesEngineLogLevel.warning < RulesEngineLogLevel.debug) - XCTAssertTrue(RulesEngineLogLevel.debug < RulesEngineLogLevel.trace) + XCTAssertTrue(LogLevel.error < LogLevel.warning) + XCTAssertTrue(LogLevel.warning < LogLevel.debug) + XCTAssertTrue(LogLevel.debug < LogLevel.trace) } func testLogLevelToString() { - XCTAssertEqual(RulesEngineLogLevel.error.toString(), "ERROR") - XCTAssertEqual(RulesEngineLogLevel.warning.toString(), "WARNING") - XCTAssertEqual(RulesEngineLogLevel.debug.toString(), "DEBUG") - XCTAssertEqual(RulesEngineLogLevel.trace.toString(), "TRACE") + XCTAssertEqual(LogLevel.error.toString(), "ERROR") + XCTAssertEqual(LogLevel.warning.toString(), "WARNING") + XCTAssertEqual(LogLevel.debug.toString(), "DEBUG") + XCTAssertEqual(LogLevel.trace.toString(), "TRACE") } } diff --git a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLoggingTests.swift b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLoggingTests.swift index a7c8bd3..5270ae2 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLoggingTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLoggingTests.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -15,11 +15,11 @@ import XCTest @testable import AEPRulesEngine -private class Log: RulesEngineLogging { +private class TestLogger: Logging { public var message = "" public var label = "" - public var level = RulesEngineLogLevel.debug - public func log(level: RulesEngineLogLevel, label: String, message: String) { + public var level = LogLevel.debug + public func log(level: LogLevel, label: String, message: String) { self.message = message self.level = level self.label = label @@ -28,15 +28,15 @@ private class Log: RulesEngineLogging { class RulesEngineLoggingTests: XCTestCase { func testLogging() { - let log = Log() - RulesEngineLog.logging = log - RulesEngineLog.debug(label: "labelA", "debug message") + let log = TestLogger() + Log.logging = log + Log.debug(label: "labelA", "debug message") XCTAssertEqual("labelA", log.label) XCTAssertEqual("debug message", log.message) - XCTAssertEqual(RulesEngineLogLevel.debug, log.level) - RulesEngineLog.warning(label: "labelA", "warning message") - XCTAssertEqual(RulesEngineLogLevel.warning, log.level) - RulesEngineLog.error(label: "labelA", "error message") - XCTAssertEqual(RulesEngineLogLevel.error, log.level) + XCTAssertEqual(LogLevel.debug, log.level) + Log.warning(label: "labelA", "warning message") + XCTAssertEqual(LogLevel.warning, log.level) + Log.error(label: "labelA", "error message") + XCTAssertEqual(LogLevel.error, log.level) } } diff --git a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift index ba02fda..265e00f 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/Tests/AEPRulesEngineTests/UnitTests/TraverseTests.swift b/Tests/AEPRulesEngineTests/UnitTests/TraverseTests.swift index 4fc8217..f08279c 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/TraverseTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/TraverseTests.swift @@ -1,5 +1,5 @@ /* - Copyright 2020 Adobe. All rights reserved. + Copyright 2021 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 From 828a45939e95dbff016fa0d907a053e0ec6ed4eb Mon Sep 17 00:00:00 2001 From: steve benedick Date: Wed, 6 Jan 2021 16:32:46 -0700 Subject: [PATCH 5/7] -fix linter and format warnings --- Sources/AEPRulesEngine/ConditionEvaluator.swift | 14 +++++++------- Sources/AEPRulesEngine/Context.swift | 2 +- .../Expression/ComparisonExpression.swift | 2 +- Sources/AEPRulesEngine/Expression/Operand.swift | 4 ++-- Sources/AEPRulesEngine/Log/Log.swift | 2 +- Sources/AEPRulesEngine/Log/LogLevel.swift | 6 +++--- Sources/AEPRulesEngine/RulesFailure.swift | 2 +- .../AEPRulesEngine/Template/MustacheError.swift | 4 ++-- .../Template/ParserTagDelimiters.swift | 12 ++++++------ .../AEPRulesEngine/Template/TemplateParser.swift | 2 +- Sources/AEPRulesEngine/Transformer.swift | 10 +++++----- Sources/AEPRulesEngine/Transforming.swift | 1 - .../UnitTests/OperandTests.swift | 13 ++++++------- .../UnitTests/ParserTests.swift | 4 ++-- .../UnitTests/RulesEngineLogLevelTests.swift | 1 - .../UnitTests/RulesEngineTests.swift | 2 +- 16 files changed, 39 insertions(+), 42 deletions(-) diff --git a/Sources/AEPRulesEngine/ConditionEvaluator.swift b/Sources/AEPRulesEngine/ConditionEvaluator.swift index cde5a90..f6820b3 100644 --- a/Sources/AEPRulesEngine/ConditionEvaluator.swift +++ b/Sources/AEPRulesEngine/ConditionEvaluator.swift @@ -13,11 +13,12 @@ public class ConditionEvaluator: Evaluating { fileprivate let LOG_TAG = "ConditionEvaluator" var operators: [String: Any] = [:] - + // MARK: - Evaluating + public func evaluate(operation: String, lhs: A) -> Result { let op = operators[getHash(operation: operation, typeA: A.self)] as? ((A) -> Bool) - + guard let op_ = op else { let message = "No operator defined for \(getHash(operation: operation, typeA: A.self))" Log.trace(label: LOG_TAG, message) @@ -38,16 +39,16 @@ public class ConditionEvaluator: Evaluating { } } -extension ConditionEvaluator { - public func addUnaryOperator(operation: String, closure: @escaping (A) -> Bool) { +public extension ConditionEvaluator { + func addUnaryOperator(operation: String, closure: @escaping (A) -> Bool) { operators[getHash(operation: operation, typeA: A.self)] = closure } - public func addComparisonOperator(operation: String, closure: @escaping (A, B) -> Bool) { + func addComparisonOperator(operation: String, closure: @escaping (A, B) -> Bool) { operators[getHash(operation: operation, typeA: A.self, typeB: B.self)] = closure } - public func addComparisonOperator(operation: String, type _: A.Type, closure: @escaping (A, A) -> Bool) { + func addComparisonOperator(operation: String, type _: A.Type, closure: @escaping (A, A) -> Bool) { operators[getHash(operation: operation, typeA: A.self, typeB: A.self)] = closure } @@ -81,7 +82,6 @@ public extension ConditionEvaluator { } private func addDefaultOperators() { - addComparisonOperator(operation: "and", type: Bool.self, closure: { $0 && $1 }) addComparisonOperator(operation: "or", type: Bool.self, closure: { $0 || $1 }) diff --git a/Sources/AEPRulesEngine/Context.swift b/Sources/AEPRulesEngine/Context.swift index 965b743..ea68a69 100644 --- a/Sources/AEPRulesEngine/Context.swift +++ b/Sources/AEPRulesEngine/Context.swift @@ -3,7 +3,7 @@ This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language diff --git a/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift b/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift index b9e604f..4f2bd83 100644 --- a/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift +++ b/Sources/AEPRulesEngine/Expression/ComparisonExpression.swift @@ -25,7 +25,7 @@ public struct ComparisonExpression: Evaluable { } // MARK: - Evaluable - + public func evaluate(in context: Context) -> Result { Log.trace(label: LOG_TAG, "Evaluating \(lhs) - \(operationName) - \(rhs)") let resolvedLhs = lhs(context) diff --git a/Sources/AEPRulesEngine/Expression/Operand.swift b/Sources/AEPRulesEngine/Expression/Operand.swift index 9d3df7b..4538604 100644 --- a/Sources/AEPRulesEngine/Expression/Operand.swift +++ b/Sources/AEPRulesEngine/Expression/Operand.swift @@ -34,8 +34,8 @@ public enum Operand { } } -extension Operand { - public init(mustache: String) { +public extension Operand { + init(mustache: String) { let tokens = try? TemplateParser.parse(mustache).get() if let tokens = tokens, tokens.count > 0, case let .mustache(token) = tokens[0].type { self = .token(token) diff --git a/Sources/AEPRulesEngine/Log/Log.swift b/Sources/AEPRulesEngine/Log/Log.swift index c24280f..74f2e2b 100644 --- a/Sources/AEPRulesEngine/Log/Log.swift +++ b/Sources/AEPRulesEngine/Log/Log.swift @@ -15,7 +15,7 @@ import Foundation /// The `Log` class will be dormant unless its static `logging` variable is initialized. /// To enable logging from the RulesEngine, implement a class that conforms to the /// `Logging` protocol and use an instance of it to set the `Log.logging` variable. -public class Log { +public enum Log { public static var logging: Logging? /// Used to print more verbose information. /// - Parameters: diff --git a/Sources/AEPRulesEngine/Log/LogLevel.swift b/Sources/AEPRulesEngine/Log/LogLevel.swift index 221e7a5..2b23790 100644 --- a/Sources/AEPRulesEngine/Log/LogLevel.swift +++ b/Sources/AEPRulesEngine/Log/LogLevel.swift @@ -3,7 +3,7 @@ This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language @@ -17,7 +17,7 @@ public enum LogLevel: Int, Comparable { case warning = 1 case debug = 2 case trace = 3 - + /// Compares two `LogLevel`s for order /// - Parameters: /// - lhs: the first `LogLevel` to be compared @@ -26,7 +26,7 @@ public enum LogLevel: Int, Comparable { public static func < (lhs: LogLevel, rhs: LogLevel) -> Bool { lhs.rawValue < rhs.rawValue } - + public func toString() -> String { switch self { case .trace: diff --git a/Sources/AEPRulesEngine/RulesFailure.swift b/Sources/AEPRulesEngine/RulesFailure.swift index fc47864..812eeab 100644 --- a/Sources/AEPRulesEngine/RulesFailure.swift +++ b/Sources/AEPRulesEngine/RulesFailure.swift @@ -3,7 +3,7 @@ This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language diff --git a/Sources/AEPRulesEngine/Template/MustacheError.swift b/Sources/AEPRulesEngine/Template/MustacheError.swift index d0d9ddc..f2770fd 100644 --- a/Sources/AEPRulesEngine/Template/MustacheError.swift +++ b/Sources/AEPRulesEngine/Template/MustacheError.swift @@ -3,7 +3,7 @@ This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language @@ -15,7 +15,7 @@ import Foundation public struct MustacheError: Error { /// Eventual error message public let message: String? - + public init(message: String? = nil) { self.message = message } diff --git a/Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift b/Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift index 00de45f..5adfae5 100644 --- a/Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift +++ b/Sources/AEPRulesEngine/Template/ParserTagDelimiters.swift @@ -3,7 +3,7 @@ This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language @@ -14,23 +14,23 @@ import Foundation struct ParserTagDelimiters { let tagDelimiterPair: DelimiterPair - + init(_ tagDelimiterPair: DelimiterPair) { self.tagDelimiterPair = tagDelimiterPair } - + var startTag: String { return tagDelimiterPair.0 } - + var startTagLength: Int { return startTag.count } - + var endTag: String { return tagDelimiterPair.1 } - + var endTagLength: Int { return endTag.count } diff --git a/Sources/AEPRulesEngine/Template/TemplateParser.swift b/Sources/AEPRulesEngine/Template/TemplateParser.swift index 3cbc3cb..470b768 100644 --- a/Sources/AEPRulesEngine/Template/TemplateParser.swift +++ b/Sources/AEPRulesEngine/Template/TemplateParser.swift @@ -15,7 +15,7 @@ import Foundation /// A pair of tag delimiters, such as `("{{", "}}")`. public typealias DelimiterPair = (String, String) -public struct TemplateParser { +public enum TemplateParser { static let DefaultTagDelimiterPair: DelimiterPair = ("{{", "}}") static func parse(_ templateString: String, tagDelimiterPair: DelimiterPair = TemplateParser.DefaultTagDelimiterPair) -> Result<[Segment], Error> { diff --git a/Sources/AEPRulesEngine/Transformer.swift b/Sources/AEPRulesEngine/Transformer.swift index dc5e53c..b6a8ace 100644 --- a/Sources/AEPRulesEngine/Transformer.swift +++ b/Sources/AEPRulesEngine/Transformer.swift @@ -3,7 +3,7 @@ This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language @@ -14,15 +14,15 @@ import Foundation public class Transformer: Transforming { var transformations: [String: Transformation] = [:] - + public init() {} - + public func register(name: String, transformation: @escaping Transformation) { transformations[name] = transformation } - + // MARK: - Transforming - + public func transform(name: String, parameter: Any) -> Any { guard let transformation = transformations[name] else { return parameter diff --git a/Sources/AEPRulesEngine/Transforming.swift b/Sources/AEPRulesEngine/Transforming.swift index 47e6969..b28be3e 100644 --- a/Sources/AEPRulesEngine/Transforming.swift +++ b/Sources/AEPRulesEngine/Transforming.swift @@ -17,4 +17,3 @@ public typealias Transformation = (Any) -> Any public protocol Transforming { func transform(name: String, parameter: Any) -> Any } - diff --git a/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift b/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift index d542cf4..b963dcb 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/OperandTests.swift @@ -16,23 +16,22 @@ import XCTest @testable import AEPRulesEngine class OperandTests: XCTestCase { - func testMustacheNoneValue() { let mustache = Operand(mustache: "") XCTAssertEqual("", String(describing: mustache)) } - - func testDoubleValue(){ + + func testDoubleValue() { let operand = Operand(floatLiteral: 1.2) XCTAssertEqual("", String(describing: operand)) } - - func testBoolValue(){ + + func testBoolValue() { let operand = Operand(booleanLiteral: true) XCTAssertEqual("", String(describing: operand)) } - - func testNilValue(){ + + func testNilValue() { let operand: Operand = nil XCTAssertEqual("", String(describing: operand)) } diff --git a/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift b/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift index b201e70..73f4014 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/ParserTests.swift @@ -34,9 +34,9 @@ class ParserTests: XCTestCase { let result = template.render(data: ["test": "value"], transformers: Transformer()) XCTAssertEqual("sdfdfdvalueaaa", result) } - + func testCustomizedTokenFormat() { - let template = Template(templateString: "sdfdfd[[test]]aaa", tagDelimiterPair: ("[[","]]")) + let template = Template(templateString: "sdfdfd[[test]]aaa", tagDelimiterPair: ("[[", "]]")) let result = template.render(data: ["test": "value"], transformers: Transformer()) XCTAssertEqual("sdfdfdvalueaaa", result) } diff --git a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift index 5e71e9e..18ce06b 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineLogLevelTests.swift @@ -14,7 +14,6 @@ import XCTest class RulesEngineLogLevelTests: XCTestCase { - func testLogLevelComparison() { XCTAssertTrue(LogLevel.error < LogLevel.warning) XCTAssertTrue(LogLevel.warning < LogLevel.debug) diff --git a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift index 265e00f..b71fd99 100644 --- a/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift +++ b/Tests/AEPRulesEngineTests/UnitTests/RulesEngineTests.swift @@ -50,7 +50,7 @@ class RulesEngineTests: XCTestCase { let rule = TestRule(condition: andCondition) rulesEngine.addRules(rules: [rule]) var passed = true - var error:RulesFailure? + var error: RulesFailure? rulesEngine.trace { result, _, _, failure in passed = result error = failure From 109e3ced2695278256d2c10ec08a3412df870f4c Mon Sep 17 00:00:00 2001 From: steve benedick Date: Thu, 7 Jan 2021 11:09:32 -0700 Subject: [PATCH 6/7] -update readme --- README.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index c9b1297..52fd87b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ # AEPRulesEngine + +[![SPM](https://img.shields.io/badge/SPM-Supported-orange.svg?logo=apple&logoColor=white)](https://swift.org/package-manager/) +[![CircleCI](https://img.shields.io/circleci/project/github/adobe/aepsdk-rulesengine-ios/main.svg?logo=circleci)](https://circleci.com/gh/adobe/workflows/aepsdk-rulesengine-ios) +[![Code Coverage](https://img.shields.io/codecov/c/github/adobe/aepsdk-rulesengine-ios/main.svg?logo=codecov)](https://codecov.io/gh/adobe/aepsdk-rulesengine-ios/branch/main) + ## BETA AEPRulesEngine is currently in beta. Use of this code is by invitation only and not otherwise supported by Adobe. Please contact your Adobe Customer Success Manager to learn more. @@ -10,7 +17,7 @@ A simple, generic, extensible Rules Engine in Swift. ## Requirements - Xcode 11.0 (or newer) -- Swift 5.0 (or newer) +- Swift 5.1 (or newer) ## Installation @@ -19,20 +26,8 @@ A simple, generic, extensible Rules Engine in Swift. # Podfile use_frameworks! -# for app development, include all the following pods target 'YOUR_TARGET_NAME' do - pod 'AEPRulesEngine', :git => 'https://github.com/adobe/aepsdk-rulesengine-ios.git', :branch => 'main' - pod 'AEPCore', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' - pod 'AEPServices', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' - pod 'AEPLifecycle', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' - pod 'AEPIdentity', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' -end - -# for extension development, include AEPCore and its dependencies -target 'YOUR_TARGET_NAME' do - pod 'AEPRulesEngine', :git => 'https://github.com/adobe/aepsdk-rulesengine-ios.git', :branch => 'main' - pod 'AEPCore', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' - pod 'AEPServices', :git => 'https://github.com/adobe/aepsdk-core-ios.git', :branch => 'main' + pod 'AEPRulesEngine', :git => 'https://github.com/adobe/aepsdk-rulesengine-ios.git', :branch => 'main' end ``` @@ -50,7 +45,7 @@ To add the AEPRulesEngine package to your application, from the Xcode menu selec Enter the URL for the AEPRulesEngine package repository: `https://github.com/adobe/aepsdk-rulesengine-ios.git`. -When prompted, make sure you change the branch to `main`. +When prompted, make sure you change the branch to `main`. There are three options for selecting your dependencies as identified by the *suffix* of the library name: @@ -68,7 +63,6 @@ dependencies: [ ## Usage - ### Initialize the Rules Engine To create a `RulesEngine` instance, define an `Evaluator` and pass it to the `RulesEngine`'s initializer: From 3a9439f29169ff1bd4768d927713cb82c31c6d67 Mon Sep 17 00:00:00 2001 From: steve benedick Date: Thu, 7 Jan 2021 11:13:09 -0700 Subject: [PATCH 7/7] -cleanup after merge from main --- AEPRulesEngine.podspec | 3 +-- README.md | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/AEPRulesEngine.podspec b/AEPRulesEngine.podspec index dcf99c1..8a658bc 100644 --- a/AEPRulesEngine.podspec +++ b/AEPRulesEngine.podspec @@ -16,7 +16,6 @@ Pod::Spec.new do |s| s.pod_target_xcconfig = { 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } s.swift_version = '5.0' - s.source_files = 'Sources/AEPRulesEngine/**/*.swift' - + s.source_files = 'Sources/AEPRulesEngine/**/*.swift' end diff --git a/README.md b/README.md index 9ee3e41..52fd87b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -[![codecov](https://codecov.io/gh/yangyansong-adbe/aepsdk-rulesengine-ios/branch/dev/graph/badge.svg?token=T8LRU71KTB)](undefined) - # AEPRulesEngine