├── .github └── workflows │ └── swift.yml ├── .gitignore ├── .idea ├── .name ├── codeStyles │ └── codeStyleConfig.xml ├── dictionaries │ └── christoskoninis.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsonlogic-swift.iml ├── misc.xml ├── modules.xml ├── runConfigurations │ ├── jsonlogic_Package.xml │ └── jsonlogic_cli.xml ├── vcs.xml ├── workspace.xml └── xcode.xml ├── .swiftlint.yml ├── .swiftpm └── xcode │ ├── package.xcworkspace │ └── contents.xcworkspacedata │ └── xcshareddata │ └── xcschemes │ ├── JSON.xcscheme │ ├── jsonlogic-Package.xcscheme │ ├── jsonlogic-cli.xcscheme │ └── jsonlogic.xcscheme ├── .travis.yml ├── Example ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ ├── json-enum.podspec.json │ │ └── jsonlogic.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── json-enum.xcscheme │ │ │ └── jsonlogic.xcscheme │ └── Target Support Files │ │ ├── Pods-jsonlogicExample │ │ ├── Pods-jsonlogicExample-Info.plist │ │ ├── Pods-jsonlogicExample-acknowledgements.markdown │ │ ├── Pods-jsonlogicExample-acknowledgements.plist │ │ ├── Pods-jsonlogicExample-dummy.m │ │ ├── Pods-jsonlogicExample-frameworks-Debug-input-files.xcfilelist │ │ ├── Pods-jsonlogicExample-frameworks-Debug-output-files.xcfilelist │ │ ├── Pods-jsonlogicExample-frameworks-Release-input-files.xcfilelist │ │ ├── Pods-jsonlogicExample-frameworks-Release-output-files.xcfilelist │ │ ├── Pods-jsonlogicExample-frameworks.sh │ │ ├── Pods-jsonlogicExample-umbrella.h │ │ ├── Pods-jsonlogicExample.debug.xcconfig │ │ ├── Pods-jsonlogicExample.modulemap │ │ └── Pods-jsonlogicExample.release.xcconfig │ │ ├── json-enum │ │ ├── json-enum-Info.plist │ │ ├── json-enum-dummy.m │ │ ├── json-enum-prefix.pch │ │ ├── json-enum-umbrella.h │ │ ├── json-enum.debug.xcconfig │ │ ├── json-enum.modulemap │ │ ├── json-enum.release.xcconfig │ │ └── json-enum.xcconfig │ │ └── jsonlogic │ │ ├── jsonlogic-Info.plist │ │ ├── jsonlogic-dummy.m │ │ ├── jsonlogic-prefix.pch │ │ ├── jsonlogic-umbrella.h │ │ ├── jsonlogic.debug.xcconfig │ │ ├── jsonlogic.modulemap │ │ ├── jsonlogic.release.xcconfig │ │ └── jsonlogic.xcconfig ├── jsonlogic │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── jsonlogicExample.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── jsonlogicExample.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── LICENSE ├── Package.resolved ├── Package.swift ├── README.md ├── Sources ├── JSON │ └── JSON.swift ├── jsonlogic-cli │ └── main.swift └── jsonlogic │ ├── JsonLogic.swift │ └── Parser.swift ├── Tests ├── JSONTests │ ├── JSONTests.swift │ └── XCTestManifests.swift ├── LinuxMain.swift └── jsonlogicTests │ ├── AccessingDataOperations │ ├── AllTests.swift │ ├── ArrayMapTests.swift │ ├── MergeArrayTests.swift │ ├── MissingTests.swift │ ├── NoneTests.swift │ ├── SomeTests.swift │ └── VarTests.swift │ ├── ArithmeticTests.swift │ ├── CompoundTests.swift │ ├── CustomOperatorTests.swift │ ├── JsonLogicTests.swift │ ├── LogicAndBooleanOperations │ ├── AndTests.swift │ ├── DoubleNegationTests.swift │ ├── EqualsTests.swift │ ├── IfTests.swift │ ├── NotStrictEqualsTests.swift │ └── OrTests.swift │ ├── MinMaxTests.swift │ ├── NumericalOperations │ ├── BetweenTests.swift │ ├── GreaterThanOrEqualTests.swift │ ├── GreaterThanTests.swift │ ├── LessThanOrEqualTests.swift │ └── LessThanTests.swift │ ├── StringOperations │ ├── CatTests.swift │ ├── InTests.swift │ ├── LogTests.swift │ └── SubstringTests.swift │ ├── TestUtils.swift │ └── XCTestManifests.swift ├── genenate-xcodeproj.sh ├── json-enum.podspec ├── jsonlogic.podspec └── run-tests.sh /.github/workflows/swift.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Swift project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift 3 | 4 | name: Swift 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: macos-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Build 20 | run: swift build -v 21 | - name: Run tests 22 | run: swift test -v 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | .DS_Store 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData/ 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata/ 21 | 22 | ## Other 23 | *.moved-aside 24 | *.xccheckout 25 | *.xcscmblueprint 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | .build/ 44 | 45 | # CocoaPods 46 | # 47 | # We recommend against adding the Pods directory to your .gitignore. However 48 | # you should judge for yourself, the pros and cons are mentioned at: 49 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 50 | # 51 | # Pods/ 52 | # 53 | # Add this line if you want to avoid checking in source code from the Xcode workspace 54 | # *.xcworkspace 55 | 56 | # Carthage 57 | # 58 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 59 | # Carthage/Checkouts 60 | 61 | Carthage/Build 62 | 63 | # fastlane 64 | # 65 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 66 | # screenshots whenever they are needed. 67 | # For more information about the recommended setup visit: 68 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 69 | 70 | fastlane/report.xml 71 | fastlane/Preview.html 72 | fastlane/screenshots/**/*.png 73 | fastlane/test_output 74 | 75 | #This is generated from Swift PM using the swift package generate-xcodeproj see genenate-xcodeproj.sh 76 | jsonlogic.xcodeproj 77 | # Code Injection 78 | # 79 | # After new code Injection tools there's a generated folder /iOSInjectionProject 80 | # https://github.com/johnno1962/injectionforxcode 81 | 82 | iOSInjectionProject/ -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | jsonlogic -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/dictionaries/christoskoninis.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | aren 5 | ints 6 | jsonlogic 7 | koninis 8 | lala 9 | lgpl 10 | swiftlint 11 | thruthy 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/jsonlogic-swift.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/jsonlogic_Package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/jsonlogic_cli.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/xcode.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: # rule identifiers to exclude from running 2 | # - colon 3 | # - opening_brace 4 | # - comma 5 | # - trailing_comma 6 | # - force_cast 7 | # - type_name 8 | - nesting 9 | # - trailing_semicolon 10 | # - function_body_length 11 | # - nesting 12 | # - conditional_binding_cascade 13 | # - operator_whitespace 14 | # - control_statement 15 | # - legacy_constant 16 | # - line_length 17 | # - return_arrow_whitespace 18 | # - trailing_whitespace 19 | # - closing_brace 20 | # - statement_position 21 | # - type_body_length 22 | # - function_parameter_count 23 | # - todo 24 | # - legacy_constructor 25 | # - valid_docs 26 | # - missing_docs 27 | # - file_length 28 | # - leading_whitespace 29 | # - trailing_newline 30 | - identifier_name 31 | # - syntactic_sugar 32 | # - vertical_parameter_alignment 33 | # - void_return 34 | # - vertical_whitespace 35 | # - mark 36 | # - notification_center_detachment 37 | # - for_where 38 | - large_tuple 39 | # - class_delegate_protocol 40 | # - closure_parameter_position 41 | # - shorthand_operator 42 | # - cyclomatic_complexity 43 | # - implicit_getter 44 | # - unused_optional_binding 45 | # - unused_closure_parameter 46 | # - redundant_void_return 47 | # - unused_enumerated 48 | # - redundant_discardable_let 49 | opt_in_rules: # some rules are only opt-in 50 | - empty_count 51 | - anyobject_protocol 52 | - array_init 53 | - contains_over_first_not_nil 54 | - empty_string 55 | - empty_xctest_method 56 | - convenience_type 57 | - unused_import 58 | - missing_docs 59 | - untyped_error_in_catch 60 | - first_where 61 | # - implicit_return 62 | # - implicitly_unwrapped_optional 63 | - let_var_whitespace 64 | - literal_expression_end_indentation 65 | - multiline_arguments 66 | - multiline_parameters 67 | - number_separator 68 | - operator_usage_whitespace 69 | - pattern_matching_keywords 70 | - sorted_first_last 71 | # - sorted_imports 72 | - switch_case_on_newline 73 | # - vertical_parameter_alignment_on_call bug -> https://github.com/realm/SwiftLint/issues/2468 74 | - yoda_condition 75 | # Find all the available rules by running: 76 | # swiftlint rules 77 | included: # paths to include during linting. `--path` is ignored if present. 78 | - Sources 79 | - Tests 80 | # - ProductProtype 81 | # - PrototypeTests 82 | # - ProductWidget 83 | # - SDK 84 | excluded: # paths to ignore during linting. Takes precedence over `included`. 85 | - Carthage 86 | - Pods 87 | - .build 88 | #The following are generated sources from `swift test --generate-linuxmain` 89 | - Tests/jsonlogicTests/XCTestManifests.swift 90 | - Tests/LinuxMain.swift 91 | cyclomatic_complexity: 92 | warning: 14 93 | error: 16 94 | empty_count: 95 | severity: warning 96 | force_cast: 97 | severity: warning 98 | force_try: 99 | severity: warning 100 | line_length: 100 101 | function_body_length: 102 | warning: 30 103 | error: 40 104 | type_body_length: 105 | warning: 250 106 | file_length: 107 | warning: 1000 108 | type_name: 109 | min_length: 3 110 | max_length: 64 111 | identifier_name: 112 | min_length: # only min_length 113 | warning: 3 # only error 114 | max_length: # only min_length 115 | warning: 64 # only error 116 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji) 117 | custom_rules: 118 | late_force_unwrapping: 119 | included: ".*.swift" 120 | regex: '\(\S+\?\.\S+\)!' 121 | name: "Late Force Unwrapping" 122 | message: "Don't use ? first to force unwrap later – directly unwrap within the parantheses." 123 | severity: warning 124 | # multiple_closure_params: 125 | # included: ".*.swift" 126 | # regex: '\} *\) *\{' 127 | # name: "Multiple Closure Params" 128 | # message: "Don't use multiple in-line closures – save one or more of them to variables instead." 129 | # severity: warning 130 | single_line_return: 131 | included: ".*.swift" 132 | regex: '\.\S+ *\{(?: *return|[^\n\}]+ in return) [^\}]+\}' 133 | name: "Single Line Return" 134 | message: "Remove the 'return' when returning from a single line closure." 135 | severity: warning 136 | unnecessary_case_break: 137 | included: ".*.swift" 138 | regex: '(case)(?:[^\n\}]+\n){2,}\s*break *\n|\n *\n *break(?:\n *\n|\n *\})' 139 | name: "Unnecessary Case Break" 140 | message: "Don't use break in switch cases – Swift breaks by default. Use () for empty statement." 141 | severity: warning 142 | unnecessary_nil_assignment: 143 | included: ".*.swift" 144 | regex: 'var \S+\s*:\s*[^\s]+\?\s*=\s*nil' 145 | name: "Unnecessary Nil Assignment" 146 | message: "Don't assign nil as a value when defining an optional type – it's nil by default." 147 | severity: warning 148 | vertical_whitespaces_around_mark: 149 | included: ".*.swift" 150 | regex: '\/\/\s*MARK:[^\n]*(\n)(?!\n)|(\n\n\n)[ \t]*\/\/\s*MARK:|[^\s{]\n[^\n\/]*\/\/\s*MARK:' 151 | name: "Vertical Whitespaces Around MARK:" 152 | message: "Include a single vertical whitespace (empty line) before and after MARK: comments." 153 | vertical_whitespace_closing_braces: 154 | included: ".*.swift" 155 | regex: '\n[ \t]*\n[ \t]*[)}\]]' 156 | name: "Vertical Whitespace before Closing Braces" 157 | message: "Don't include vertical whitespace (empty line) before closing braces." 158 | severity: warning -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.swiftpm/xcode/xcshareddata/xcschemes/JSON.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /.swiftpm/xcode/xcshareddata/xcschemes/jsonlogic-Package.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 57 | 63 | 64 | 65 | 66 | 67 | 72 | 73 | 75 | 81 | 82 | 83 | 85 | 91 | 92 | 93 | 94 | 95 | 105 | 106 | 112 | 113 | 114 | 115 | 121 | 122 | 128 | 129 | 130 | 131 | 133 | 134 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /.swiftpm/xcode/xcshareddata/xcschemes/jsonlogic-cli.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 48 | 54 | 55 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 95 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /.swiftpm/xcode/xcshareddata/xcschemes/jsonlogic.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | matrix: 2 | include: 3 | - os: osx 4 | osx_image: xcode12.2 5 | sudo: required 6 | - os: linux 7 | language: generic 8 | dist: bionic 9 | sudo: required 10 | before_install: 11 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew uninstall swiftlint || true && brew install swiftlint ; fi 12 | install: 13 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" ; fi 14 | 15 | script: 16 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then swiftlint ; fi 17 | - swift test -Xswiftc -swift-version -Xswiftc 4 18 | - swift test -Xswiftc -swift-version -Xswiftc 4.2 19 | - swift test -Xswiftc -swift-version -Xswiftc 5 --enable-code-coverage 20 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then xcrun llvm-cov export -format="lcov" $TRAVIS_BUILD_DIR/.build/debug/jsonlogicPackageTests.xctest/Contents/MacOS/jsonlogicPackageTests -instr-profile $TRAVIS_BUILD_DIR/.build/debug/codecov/default.profdata > $TRAVIS_BUILD_DIR/coverage.lcov ; fi 21 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then bash <(curl -s https://codecov.io/bash) ; fi 22 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '8.0' 2 | 3 | target 'jsonlogicExample' do 4 | use_frameworks! 5 | 6 | pod 'jsonlogic', :path => '../' 7 | pod 'json-enum', :path => '../' 8 | 9 | end 10 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - json-enum (1.1.0) 3 | - jsonlogic (1.1.0): 4 | - json-enum (~> 1.1) 5 | 6 | DEPENDENCIES: 7 | - json-enum (from `../`) 8 | - jsonlogic (from `../`) 9 | 10 | EXTERNAL SOURCES: 11 | json-enum: 12 | :path: "../" 13 | jsonlogic: 14 | :path: "../" 15 | 16 | SPEC CHECKSUMS: 17 | json-enum: 76ac9934251153e252fbb5ba786a570e9b536fba 18 | jsonlogic: 52ff96c22e6f9fa733355dcdc34677bd1a7bdc70 19 | 20 | PODFILE CHECKSUM: 6ab1f77c01eab073b400e717f58b529f12e3c8d7 21 | 22 | COCOAPODS: 1.10.1 23 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/json-enum.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-enum", 3 | "version": "1.1.0", 4 | "summary": "Parsing JSON to Swift enum parsing library", 5 | "description": "Representing a JSON using a enumerated type makes it easy and type safe.", 6 | "homepage": "https://github.com/advantagefse/json-logic-swift", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Christos Koninis": "c.koninis@afse.eu" 13 | }, 14 | "source": { 15 | "git": "https://github.com/advantagefse/json-logic-swift.git", 16 | "tag": "json-enum-1.1.0" 17 | }, 18 | "platforms": { 19 | "ios": "8.0", 20 | "tvos": "10.0", 21 | "watchos": "2.0", 22 | "osx": "10.12" 23 | }, 24 | "cocoapods_version": ">= 1.6.1", 25 | "frameworks": "Foundation", 26 | "source_files": "Sources/JSON/*.swift", 27 | "module_name": "JSON" 28 | } 29 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/jsonlogic.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsonlogic", 3 | "version": "1.1.0", 4 | "summary": "A JsonLogic Swift library", 5 | "description": "A JsonLogic implementation in Swift. JsonLogic is a way to write rules that involve computations in JSON format, these can be applied on JSON data with consistent results. So you can share between server and clients rules in a common format.", 6 | "homepage": "https://github.com/advantagefse/json-logic-swift", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Christos Koninis": "c.koninis@afse.eu" 13 | }, 14 | "source": { 15 | "git": "https://github.com/advantagefse/json-logic-swift.git", 16 | "tag": "1.1.0" 17 | }, 18 | "platforms": { 19 | "ios": "8.0", 20 | "tvos": "10.0", 21 | "watchos": "2.0", 22 | "osx": "10.12" 23 | }, 24 | "cocoapods_version": ">= 1.6.1", 25 | "frameworks": "Foundation", 26 | "source_files": "Sources/jsonlogic/*.swift", 27 | "module_name": "jsonlogic", 28 | "dependencies": { 29 | "json-enum": [ 30 | "~> 1.1" 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - json-enum (1.1.0) 3 | - jsonlogic (1.1.0): 4 | - json-enum (~> 1.1) 5 | 6 | DEPENDENCIES: 7 | - json-enum (from `../`) 8 | - jsonlogic (from `../`) 9 | 10 | EXTERNAL SOURCES: 11 | json-enum: 12 | :path: "../" 13 | jsonlogic: 14 | :path: "../" 15 | 16 | SPEC CHECKSUMS: 17 | json-enum: 76ac9934251153e252fbb5ba786a570e9b536fba 18 | jsonlogic: 52ff96c22e6f9fa733355dcdc34677bd1a7bdc70 19 | 20 | PODFILE CHECKSUM: 6ab1f77c01eab073b400e717f58b529f12e3c8d7 21 | 22 | COCOAPODS: 1.10.1 23 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/json-enum.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/jsonlogic.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## json-enum 5 | 6 | MIT License 7 | 8 | Copyright (c) 2019 Advantage FSE 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | ## jsonlogic 30 | 31 | MIT License 32 | 33 | Copyright (c) 2019 Advantage FSE 34 | 35 | Permission is hereby granted, free of charge, to any person obtaining a copy 36 | of this software and associated documentation files (the "Software"), to deal 37 | in the Software without restriction, including without limitation the rights 38 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 39 | copies of the Software, and to permit persons to whom the Software is 40 | furnished to do so, subject to the following conditions: 41 | 42 | The above copyright notice and this permission notice shall be included in all 43 | copies or substantial portions of the Software. 44 | 45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 51 | SOFTWARE. 52 | 53 | Generated by CocoaPods - https://cocoapods.org 54 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2019 Advantage FSE 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | json-enum 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | MIT License 49 | 50 | Copyright (c) 2019 Advantage FSE 51 | 52 | Permission is hereby granted, free of charge, to any person obtaining a copy 53 | of this software and associated documentation files (the "Software"), to deal 54 | in the Software without restriction, including without limitation the rights 55 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 56 | copies of the Software, and to permit persons to whom the Software is 57 | furnished to do so, subject to the following conditions: 58 | 59 | The above copyright notice and this permission notice shall be included in all 60 | copies or substantial portions of the Software. 61 | 62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 63 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 64 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 65 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 66 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 67 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 68 | SOFTWARE. 69 | 70 | License 71 | MIT 72 | Title 73 | jsonlogic 74 | Type 75 | PSGroupSpecifier 76 | 77 | 78 | FooterText 79 | Generated by CocoaPods - https://cocoapods.org 80 | Title 81 | 82 | Type 83 | PSGroupSpecifier 84 | 85 | 86 | StringsTable 87 | Acknowledgements 88 | Title 89 | Acknowledgements 90 | 91 | 92 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_jsonlogicExample : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_jsonlogicExample 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/json-enum/JSON.framework 3 | ${BUILT_PRODUCTS_DIR}/jsonlogic/jsonlogic.framework -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSON.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsonlogic.framework -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/json-enum/JSON.framework 3 | ${BUILT_PRODUCTS_DIR}/jsonlogic/jsonlogic.framework -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSON.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsonlogic.framework -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 116 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 117 | fi 118 | fi 119 | } 120 | 121 | # Used as a return value for each invocation of `strip_invalid_archs` function. 122 | STRIP_BINARY_RETVAL=0 123 | 124 | # Strip invalid architectures 125 | strip_invalid_archs() { 126 | binary="$1" 127 | warn_missing_arch=${2:-true} 128 | # Get architectures for current target binary 129 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 130 | # Intersect them with the architectures we are building for 131 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 132 | # If there are no archs supported by this binary then warn the user 133 | if [[ -z "$intersected_archs" ]]; then 134 | if [[ "$warn_missing_arch" == "true" ]]; then 135 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 136 | fi 137 | STRIP_BINARY_RETVAL=1 138 | return 139 | fi 140 | stripped="" 141 | for arch in $binary_archs; do 142 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 143 | # Strip non-valid architectures in-place 144 | lipo -remove "$arch" -output "$binary" "$binary" 145 | stripped="$stripped $arch" 146 | fi 147 | done 148 | if [[ "$stripped" ]]; then 149 | echo "Stripped $binary of architectures:$stripped" 150 | fi 151 | STRIP_BINARY_RETVAL=0 152 | } 153 | 154 | # Copies the bcsymbolmap files of a vendored framework 155 | install_bcsymbolmap() { 156 | local bcsymbolmap_path="$1" 157 | local destination="${BUILT_PRODUCTS_DIR}" 158 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 159 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 160 | } 161 | 162 | # Signs a framework with the provided identity 163 | code_sign_if_enabled() { 164 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 165 | # Use the current code_sign_identity 166 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 167 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 168 | 169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 170 | code_sign_cmd="$code_sign_cmd &" 171 | fi 172 | echo "$code_sign_cmd" 173 | eval "$code_sign_cmd" 174 | fi 175 | } 176 | 177 | if [[ "$CONFIGURATION" == "Debug" ]]; then 178 | install_framework "${BUILT_PRODUCTS_DIR}/json-enum/JSON.framework" 179 | install_framework "${BUILT_PRODUCTS_DIR}/jsonlogic/jsonlogic.framework" 180 | fi 181 | if [[ "$CONFIGURATION" == "Release" ]]; then 182 | install_framework "${BUILT_PRODUCTS_DIR}/json-enum/JSON.framework" 183 | install_framework "${BUILT_PRODUCTS_DIR}/jsonlogic/jsonlogic.framework" 184 | fi 185 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 186 | wait 187 | fi 188 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_jsonlogicExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_jsonlogicExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/json-enum" "${PODS_CONFIGURATION_BUILD_DIR}/jsonlogic" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/json-enum/JSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/jsonlogic/jsonlogic.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "JSON" -framework "jsonlogic" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_jsonlogicExample { 2 | umbrella header "Pods-jsonlogicExample-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-jsonlogicExample/Pods-jsonlogicExample.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/json-enum" "${PODS_CONFIGURATION_BUILD_DIR}/jsonlogic" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/json-enum/JSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/jsonlogic/jsonlogic.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "JSON" -framework "jsonlogic" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_json_enum : NSObject 3 | @end 4 | @implementation PodsDummy_json_enum 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double JSONVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char JSONVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/json-enum 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum.modulemap: -------------------------------------------------------------------------------- 1 | framework module JSON { 2 | umbrella header "json-enum-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/json-enum 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/json-enum/json-enum.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/json-enum 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_jsonlogic : NSObject 3 | @end 4 | @implementation PodsDummy_jsonlogic 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double jsonlogicVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char jsonlogicVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/jsonlogic 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/json-enum" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic.modulemap: -------------------------------------------------------------------------------- 1 | framework module jsonlogic { 2 | umbrella header "jsonlogic-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/jsonlogic 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/json-enum" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/jsonlogic/jsonlogic.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/jsonlogic 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/json-enum" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | -------------------------------------------------------------------------------- /Example/jsonlogic/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // jsonlogic 4 | // 5 | // Created by Christos Koninis on 25/03/2019. 6 | // Copyright © 2019 Christos Koninis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import jsonlogic 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | 18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | self.window = UIWindow(frame: UIScreen.main.bounds) 20 | 21 | //Example parsing 22 | 23 | let rule = 24 | """ 25 | { "var" : "name" } 26 | """ 27 | let data = 28 | """ 29 | { "name" : "Jon" } 30 | """ 31 | 32 | let result: String? = try? applyRule(rule, to: data) 33 | 34 | print("result = \(String(describing: result))") 35 | 36 | self.window?.rootViewController = UIViewController() 37 | self.window!.backgroundColor = UIColor.white 38 | self.window!.makeKeyAndVisible() 39 | 40 | return true 41 | } 42 | 43 | func applicationWillResignActive(_ application: UIApplication) { 44 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 45 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 46 | } 47 | 48 | func applicationDidEnterBackground(_ application: UIApplication) { 49 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 50 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 51 | } 52 | 53 | func applicationWillEnterForeground(_ application: UIApplication) { 54 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 55 | } 56 | 57 | func applicationDidBecomeActive(_ application: UIApplication) { 58 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 59 | } 60 | 61 | func applicationWillTerminate(_ application: UIApplication) { 62 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 63 | } 64 | 65 | 66 | } 67 | 68 | -------------------------------------------------------------------------------- /Example/jsonlogic/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Example/jsonlogic/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/jsonlogic/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/jsonlogic/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/jsonlogicExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/jsonlogicExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/jsonlogicExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/jsonlogicExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Advantage FSE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | 5 | ] 6 | }, 7 | "version": 1 8 | } 9 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "jsonlogic", 8 | platforms: [ 9 | .macOS(.v10_13), .iOS(.v11), .tvOS(.v9), .watchOS(.v4) 10 | ], 11 | products: [ 12 | .library( 13 | name: "jsonlogic", 14 | targets: ["jsonlogic"]), 15 | .library( 16 | name: "JSON", 17 | targets: ["JSON"]), 18 | .executable( 19 | name: "jsonlogic-cli", 20 | targets: ["jsonlogic-cli"]), 21 | ], 22 | targets: [ 23 | .target( 24 | name: "jsonlogic-cli", 25 | dependencies: ["jsonlogic"]), 26 | .target( 27 | name: "jsonlogic", 28 | dependencies: ["JSON"]), 29 | .target( 30 | name: "JSON", 31 | dependencies: []), 32 | .testTarget( 33 | name: "jsonlogicTests", 34 | dependencies: ["jsonlogic"]), 35 | .testTarget( 36 | name: "JSONTests", 37 | dependencies: ["JSON"]) 38 | ], 39 | swiftLanguageVersions: [.v5, .v4_2, .v4] 40 | ) 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jsonlogic-swift 2 | 3 | [![CI Status](http://img.shields.io/travis/advantagefse/json-logic-swift.svg?style=flat)](https://travis-ci.org/advantagefse/json-logic-swift) 4 | [![Version](https://img.shields.io/cocoapods/v/jsonlogic.svg?style=flat)](https://cocoapods.org/pods/jsonlogic) 5 | [![Platform](https://img.shields.io/cocoapods/p/jsonlogic.svg?style=flat)](https://cocoapods.org/pods/jsonlogic) 6 | [![codecov](https://codecov.io/gh/advantagefse/json-logic-swift/branch/master/graph/badge.svg)](https://codecov.io/gh/advantagefse/json-logic-swift) 7 | 8 | A native Swift JsonLogic implementation. This parser accepts [JsonLogic](http://jsonlogic.com) 9 | rules and executes them. 10 | 11 | JsonLogic is a way to write rules that involve computations in JSON 12 | format, these can be applied on JSON data with consistent results. So you can share between server and clients rules in a common format. Original JS JsonLogic implementation is developed by Jeremy Wadhams. 13 | 14 | ## Instalation 15 | 16 | #### Using CocoaPods 17 | 18 | To use the pod in your project add in the Podfile: 19 | 20 | pod jsonlogic 21 | 22 | To run the example project, just run: 23 | 24 | pod try jsonlogic 25 | 26 | #### Using Swift Package Manager 27 | 28 | if you use Swift Package Manager add the following in dependencies: 29 | 30 | dependencies: [ 31 | .package( 32 | url: "https://github.com/advantagefse/json-logic-swift", from: "1.0.0" 33 | ) 34 | ] 35 | 36 | ## Usage 37 | 38 | You simply import the module and either call the applyRule global method: 39 | 40 | ```swift 41 | import jsonlogic 42 | 43 | let rule = 44 | """ 45 | { "var" : "name" } 46 | """ 47 | let data = 48 | """ 49 | { "name" : "Jon" } 50 | """ 51 | 52 | //Example parsing 53 | let result: String? = try? applyRule(rule, to: data) 54 | 55 | print("result = \(String(describing: result))") 56 | ``` 57 | 58 | The ```applyRule``` will parse the rule then apply it to the ```data``` and try to convert the 59 | result to 60 | the 61 | inferred return 62 | type, 63 | if it fails an error will be thrown. 64 | 65 | If you need to apply the same rule to multiple data then it will be better to parse the rule once. 66 | You can do this by initializing a ```JsonRule``` object with the rule and then calling 67 | ```applyRule```. 68 | 69 | ```swift 70 | 71 | //Example parsing 72 | let jsonlogic = try JsonLogic(rule) 73 | 74 | var result: Bool = jsonlogic.applyRule(to: data1) 75 | result = jsonlogic.applyRule(to: data2) 76 | //etc.. 77 | 78 | ``` 79 | 80 | ## Examples 81 | 82 | #### Simple 83 | ```Swift 84 | let rule = """ 85 | { "==" : [1, 1] } 86 | """ 87 | 88 | let result: Bool = try applyRule(rule) 89 | //evaluates to true 90 | ``` 91 | 92 | This is a simple test, equivalent to `1 == 1`. A few things about the format: 93 | 94 | 1. The operator is always in the "key" position. There is only one key per JsonLogic rule. 95 | 1. The values are typically an array. 96 | 1. Each value can be a string, number, boolean, array (non-associative), or null 97 | 98 | #### Compound 99 | Here we're beginning to nest rules. 100 | 101 | ```Swift 102 | let rule = """ 103 | {"and" : [ 104 | { ">" : [3,1] }, 105 | { "<" : [1,3] } 106 | ] } 107 | """ 108 | let result: Bool = try applyRule(rule) 109 | //evaluates to true 110 | ``` 111 | 112 | In an infix language this could be written as: 113 | 114 | ```Swift 115 | ( (3 > 1) && (1 < 3) ) 116 | ``` 117 | 118 | #### Data-Driven 119 | 120 | Obviously these rules aren't very interesting if they can only take static literal data. 121 | Typically `jsonLogic` will be called with a rule object and a data object. You can use the `var` 122 | operator to get attributes of the data object: 123 | 124 | ```Swift 125 | let rule = """ 126 | { "var" : ["a"] } 127 | """ 128 | let data = """ 129 | { a : 1, b : 2 } 130 | """ 131 | let result: Int = try applyRule(rule, to: data) 132 | //evaluates to 1 133 | ``` 134 | 135 | If you like, we support to skip the array around values: 136 | 137 | ```Swift 138 | let rule = """ 139 | { "var" : "a" } 140 | """ 141 | let data = """ 142 | { a : 1, b : 2 } 143 | """ 144 | let result: Int = try applyRule(rule, to: data) 145 | //evaluates to 1 146 | ``` 147 | 148 | You can also use the `var` operator to access an array by numeric index: 149 | 150 | ```js 151 | jsonLogic.apply( 152 | {"var" : 1 }, 153 | [ "apple", "banana", "carrot" ] 154 | ); 155 | // "banana" 156 | ``` 157 | 158 | Here's a complex rule that mixes literals and data. The pie isn't ready to eat unless it's cooler than 110 degrees, *and* filled with apples. 159 | 160 | ```Swift 161 | let rule = """ 162 | { "and" : [ 163 | {"<" : [ { "var" : "temp" }, 110 ]}, 164 | {"==" : [ { "var" : "pie.filling" }, "apple" ] } 165 | ] } 166 | """ 167 | let data = """ 168 | { "temp" : 100, "pie" : { "filling" : "apple" } } 169 | """ 170 | 171 | let result: Bool = try applyRule(rule, to: data) 172 | //evaluates to true 173 | ``` 174 | 175 | ### Custom operators 176 | 177 | You can register a custom operator 178 | 179 | ```Swift 180 | import jsonlogic 181 | import JSON 182 | 183 | // the key is the operator and the value is a closure that takes as argument 184 | // a JSON and returns a JSON 185 | let customRules = 186 | ["numberOfElementsInArray": { (json: JSON?) -> JSON in 187 | switch json { 188 | case let .Array(array): 189 | return JSON(array.count) 190 | default: 191 | return JSON(0) 192 | } 193 | }] 194 | 195 | let rule = """ 196 | { "numberOfElementsInArray" : [1, 2, 3] } 197 | """ 198 | 199 | // The value is 3 200 | let value: Int = try JsonLogic(rule, customOperators: customRules).applyRule() 201 | ``` 202 | 203 | ### Other operators 204 | 205 | For a complete list of the supported operators and their usages see [jsonlogic operators](http://jsonlogic.com/operations.html). 206 | 207 | ### Command Line Interface 208 | 209 | Comming soon... 210 | 211 | ## Contributing 212 | 213 | Making changes are welcome. 214 | If you find a bug please submit a unit test that reproduces it, before submitting the fix. 215 | 216 | Because the project was created and build using the Swift PM there is no Xcode project file 217 | committed in the repo. If you need one you can generated by running ```genenate-xcodeproj.sh ``` 218 | in the terminal: 219 | 220 | ``` 221 | $ . generate-xcodeproj.sh 222 | ``` 223 | 224 | ## Requirements 225 | 226 | 227 | | iOS | tvOS | watchOS | macOS | 228 | | :------: |:----------:|:----------:|:----------:| 229 | | >=9.0 | >=10.0 | >=2.0 | >=10.12 | 230 | 231 | 232 | ## Author 233 | 234 | Christos Koninis, c.koninis@afse.eu 235 | 236 | ## License 237 | 238 | JsonLogic for Swift is available under the MIT license. See the LICENSE file for more info. 239 | -------------------------------------------------------------------------------- /Sources/jsonlogic-cli/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSON.swift 3 | // JSON 4 | // 5 | // Created by Christos Koninis on 09/03/2019. 6 | // Licensed under MIT 7 | // 8 | 9 | import jsonlogic 10 | 11 | //Example parsing 12 | 13 | let rule = 14 | """ 15 | { "var" : "name" } 16 | """ 17 | let data = 18 | """ 19 | { "name" : "Jon" } 20 | """ 21 | 22 | let result: String? = try? applyRule(rule, to: data) 23 | 24 | print("result = \(String(describing: result))") 25 | -------------------------------------------------------------------------------- /Sources/jsonlogic/JsonLogic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JsonLogic.swift 3 | // jsonlogic 4 | // 5 | // Created by Christos Koninis on 06/06/2018. 6 | // Licensed under MIT 7 | // 8 | 9 | import Foundation 10 | import JSON 11 | 12 | /// Errors that can be thrown from JsonLogic methods 13 | public enum JSONLogicError: Error, Equatable { 14 | public static func == (lhs: JSONLogicError, rhs: JSONLogicError) -> Bool { 15 | switch lhs { 16 | case let canNotParseJSONData(ltype): 17 | if case let canNotParseJSONData(rtype) = rhs { 18 | return ltype == rtype 19 | } 20 | return false 21 | case let canNotConvertResultToType(ltype): 22 | if case let canNotConvertResultToType(rtype) = rhs { 23 | return ltype == rtype 24 | } 25 | return false 26 | case let .canNotParseJSONRule(ltype): 27 | if case let canNotParseJSONRule(rtype) = rhs { 28 | return ltype == rtype 29 | } 30 | return false 31 | } 32 | } 33 | 34 | /// Invalid json data was passed 35 | case canNotParseJSONData(String) 36 | 37 | /// Invalid json rule was passed 38 | case canNotParseJSONRule(String) 39 | 40 | /// Could not convert the result from applying the rule to the expected type 41 | case canNotConvertResultToType(Any.Type) 42 | } 43 | 44 | /** 45 | A shortcut method to parse and apply a json logic rule. 46 | 47 | If you need to apply the same rule to multiple json data, it is more efficient to 48 | instantiate a `JsonLogic` class that will cache and reuse the parsed rule. 49 | */ 50 | public func applyRule(_ jsonRule: String, to jsonDataOrNil: String? = nil) throws -> T { 51 | return try JsonLogic(jsonRule).applyRule(to: jsonDataOrNil) 52 | } 53 | 54 | /** 55 | It parses json rule strings and executes the rules on provided data. 56 | */ 57 | public final class JsonLogic { 58 | // The parsed json string to an Expression that can be used for evaluation upon specific data 59 | private let parsedRule: Expression 60 | 61 | /** 62 | It parses the string containing a json logic and caches the result for reuse. 63 | 64 | All calls to `applyRule()` will use the same parsed rule. 65 | 66 | - parameters: 67 | - jsonRule: A valid json rule string 68 | 69 | - throws: 70 | - `JSONLogicError.canNotParseJSONRule` 71 | If The jsonRule could not be parsed, possible the syntax is invalid 72 | - `ParseError.UnimplementedExpressionFor(_ operator: String)` : 73 | If you pass an json logic operation that is not currently implemented 74 | - `ParseError.GenericError(String)` : 75 | An error occurred during parsing of the rule 76 | */ 77 | public convenience init(_ jsonRule: String) throws { 78 | try self.init(jsonRule, customOperators: nil) 79 | } 80 | 81 | /** 82 | It parses the string containing a json logic and caches the result for reuse. 83 | 84 | All calls to `applyRule()` will use the same parsed rule. 85 | 86 | - parameters: 87 | - jsonRule: A valid json rule string 88 | - customOperators: custom operations that will be used during evalution 89 | 90 | - throws: 91 | - `JSONLogicError.canNotParseJSONRule` 92 | If The jsonRule could not be parsed, possible the syntax is invalid 93 | - `ParseError.UnimplementedExpressionFor(_ operator: String)` : 94 | If you pass an json logic operation that is not currently implemented 95 | - `ParseError.GenericError(String)` : 96 | An error occurred during parsing of the rule 97 | */ 98 | public init(_ jsonRule: String, customOperators: [String: (JSON?) -> JSON]?) throws { 99 | guard let rule = JSON(string: jsonRule) else { 100 | throw JSONLogicError.canNotParseJSONRule("Not valid JSON object") 101 | } 102 | parsedRule = try Parser(json: rule, customOperators: customOperators).parse() 103 | } 104 | 105 | /** 106 | It applies the rule, you can optionally pass data to be used for the rule. 107 | 108 | - parameter jsonDataOrNil: Data for the rule to operate on 109 | 110 | - throws: 111 | - `JSONLogicError.canNotConvertResultToType(Any.Type)` : 112 | When the result from the calculation can not be converted to the return type 113 | 114 | //This throws JSONLogicError.canNotConvertResultToType(Double) 115 | let r: Double = JsonLogic("{ "===" : [1, 1] }").applyRule() 116 | - `JSONLogicError.canNotParseJSONData(String)` : 117 | If `jsonDataOrNil` is not valid json 118 | */ 119 | public func applyRule(to jsonDataOrNil: String? = nil) throws -> T { 120 | var jsonData: JSON? 121 | 122 | if let jsonDataOrNil = jsonDataOrNil { 123 | jsonData = JSON(string: jsonDataOrNil) 124 | } 125 | 126 | let result = try parsedRule.evalWithData(jsonData) 127 | 128 | let convertedToSwiftStandardType = try result.convertToSwiftTypes() 129 | 130 | switch convertedToSwiftStandardType { 131 | case let .some(value): 132 | guard let convertedResult = value as? T else { 133 | print(" canNotConvertResultToType \(T.self) from \(type(of: value))") 134 | throw JSONLogicError.canNotConvertResultToType(T.self) 135 | } 136 | return convertedResult 137 | default: 138 | // workaround for swift bug that cause to fail when casting 139 | // from generic type that resolves to Ant? to Any? in certain compilers, see SR-14356 140 | #if compiler(>=5) && swift(<5) 141 | guard let convertedResult = (convertedToSwiftStandardType as Any) as? T else { 142 | // print("canNotConvertResultToType \(T.self) from \(type(of: convertedToSwiftStandardType))") 143 | throw JSONLogicError.canNotConvertResultToType(T.self) 144 | } 145 | #else 146 | guard let convertedResult = convertedToSwiftStandardType as? T else { 147 | // print("canNotConvertResultToType \(T.self) from \(type(of: convertedToSwiftStandardType))") 148 | throw JSONLogicError.canNotConvertResultToType(T.self) 149 | } 150 | #endif 151 | return convertedResult 152 | } 153 | } 154 | } 155 | 156 | extension JSON { 157 | func convertToSwiftTypes() throws -> Any? { 158 | switch self { 159 | case .Error: 160 | throw JSONLogicError.canNotParseJSONData("\(self)") 161 | case .Null: 162 | return Optional.none 163 | case .Bool: 164 | return self.bool 165 | case .Int: 166 | return Swift.Int(self.int!) 167 | case .Double: 168 | return self.double 169 | case .String: 170 | return self.string 171 | case let JSON.Array(array): 172 | return try array.map { try $0.convertToSwiftTypes() } 173 | case .Dictionary: 174 | let o = self.dictionary! 175 | return try o.mapValues { 176 | try $0.convertToSwiftTypes() 177 | } 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /Tests/JSONTests/JSONTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by Christos Koninis on 3/17/21. 6 | // 7 | 8 | import Foundation 9 | import XCTest 10 | @testable import JSON 11 | 12 | class JSONTests: XCTestCase { 13 | 14 | func testJSONEquality() { 15 | XCTAssertEqual(JSON(10.10), JSON(10.10)) 16 | XCTAssertEqual(JSON(10), JSON(10)) 17 | XCTAssertEqual(JSON(10.0), JSON(10)) 18 | XCTAssertEqual(JSON(10), JSON(10.0)) 19 | XCTAssertEqual(JSON(0), JSON(false)) 20 | XCTAssertEqual(JSON(false), JSON(0)) 21 | XCTAssertEqual(JSON(1), JSON(true)) 22 | XCTAssertEqual(JSON(true), JSON(1)) 23 | XCTAssertEqual(JSON("10.10"), JSON("10.10")) 24 | XCTAssertEqual(JSON(10.10), JSON("10.10")) 25 | XCTAssertEqual(JSON("10.10"), JSON(10.10)) 26 | XCTAssertEqual(JSON(10), JSON("10.0")) 27 | XCTAssertEqual(JSON("10.0"), JSON(10)) 28 | XCTAssertEqual(JSON(10), JSON("10")) 29 | XCTAssertEqual(JSON("10"), JSON(10)) 30 | XCTAssertEqual(JSON(false), JSON(false)) 31 | XCTAssertEqual(JSON(true), JSON(true)) 32 | XCTAssertEqual(JSON([1, 2]), JSON([1, 2])) 33 | XCTAssertEqual(JSON(["123": [1, 2]]), JSON(["123": [1, 2]])) 34 | XCTAssertEqual(JSON([1, 2, 123]), JSON([1, 2.0, "123"])) 35 | } 36 | 37 | func testJSONInEquality() { 38 | XCTAssertNotEqual(JSON(10.10), JSON(10.20)) 39 | XCTAssertNotEqual(JSON(11), JSON(10)) 40 | XCTAssertNotEqual(JSON(10.1), JSON(10)) 41 | XCTAssertNotEqual(JSON(10), JSON(10.1)) 42 | XCTAssertNotEqual(JSON(0), JSON(true)) 43 | XCTAssertNotEqual(JSON(true), JSON(0)) 44 | XCTAssertNotEqual(JSON(1), JSON(false)) 45 | XCTAssertNotEqual(JSON(false), JSON(1)) 46 | XCTAssertNotEqual(JSON("10.10"), JSON("10.00")) 47 | XCTAssertNotEqual(JSON(10.10), JSON("10.00")) 48 | XCTAssertNotEqual(JSON("10.10"), JSON(10.0)) 49 | XCTAssertNotEqual(JSON("a"), JSON("abc")) 50 | XCTAssertNotEqual(JSON(10.0), JSON("abc")) 51 | XCTAssertNotEqual(JSON("abc"), JSON(10.0)) 52 | XCTAssertNotEqual(JSON(10), JSON("abc")) 53 | XCTAssertNotEqual(JSON("abc"), JSON(10)) 54 | XCTAssertNotEqual(JSON(10), JSON("11")) 55 | XCTAssertNotEqual(JSON("11"), JSON(10)) 56 | XCTAssertNotEqual(JSON(true), JSON(false)) 57 | XCTAssertNotEqual(JSON(false), JSON(true)) 58 | XCTAssertNotEqual(JSON([]), JSON(true)) 59 | XCTAssertNotEqual(JSON([1, 2]), JSON([1, 2, 3])) 60 | XCTAssertNotEqual(JSON([1, 2, 123]), JSON([1, 2.0, false])) 61 | } 62 | 63 | func testJSONStrictEquality() { 64 | XCTAssertTrue(JSON(10.10) === JSON(10.10)) 65 | XCTAssertTrue(JSON(11) === JSON(11)) 66 | XCTAssertTrue(JSON(false) === JSON(false)) 67 | XCTAssertTrue(JSON(true) === JSON(true)) 68 | XCTAssertTrue(JSON("abc") === JSON("abc")) 69 | XCTAssertTrue(JSON("10.0") === JSON("10.0")) 70 | XCTAssertTrue(JSON([]) === JSON([])) 71 | XCTAssertTrue(JSON([1, 2]) === JSON([1, 2])) 72 | XCTAssertTrue(JSON([1, 2, "123"]) === JSON([1, 2, "123"])) 73 | XCTAssertTrue(JSON(["123": [1, 2]]) === JSON(["123": [1, 2]])) 74 | } 75 | 76 | func testJSONStrictInEquality() { 77 | XCTAssertTrue(JSON(10.0) !== JSON(10)) 78 | XCTAssertTrue(JSON(10) !== JSON(10.0)) 79 | XCTAssertTrue(JSON("10.10") !== JSON(10.10)) 80 | XCTAssertTrue(JSON(10.10) !== JSON("10.10")) 81 | XCTAssertTrue(JSON(0) !== JSON(false)) 82 | XCTAssertTrue(JSON(false) !== JSON(0)) 83 | XCTAssertTrue(JSON(1) !== JSON(true)) 84 | XCTAssertTrue(JSON(true) !== JSON(1)) 85 | XCTAssertTrue(JSON(10.10) !== JSON(10.20)) 86 | XCTAssertTrue(JSON(11) !== JSON(10)) 87 | XCTAssertTrue(JSON(10.1) !== JSON(10)) 88 | XCTAssertTrue(JSON(10) !== JSON(10.1)) 89 | XCTAssertTrue(JSON(0) !== JSON(true)) 90 | XCTAssertTrue(JSON(true) !== JSON(0)) 91 | XCTAssertTrue(JSON(1) !== JSON(false)) 92 | XCTAssertTrue(JSON(false) !== JSON(1)) 93 | XCTAssertTrue(JSON("10.10") !== JSON("10.00")) 94 | XCTAssertTrue(JSON(10.10) !== JSON("10.00")) 95 | XCTAssertTrue(JSON("10.10") !== JSON(10.0)) 96 | XCTAssertTrue(JSON("a") !== JSON("abc")) 97 | XCTAssertTrue(JSON(10.0) !== JSON("abc")) 98 | XCTAssertTrue(JSON("abc") !== JSON(10.0)) 99 | XCTAssertTrue(JSON(10) !== JSON("abc")) 100 | XCTAssertTrue(JSON("abc") !== JSON(10)) 101 | XCTAssertTrue(JSON(10) !== JSON("11")) 102 | XCTAssertTrue(JSON("11") !== JSON(10)) 103 | XCTAssertTrue(JSON(true) !== JSON(false)) 104 | XCTAssertTrue(JSON(false) !== JSON(true)) 105 | XCTAssertTrue(JSON([]) !== JSON(true)) 106 | XCTAssertTrue(JSON([1, 2]) !== JSON([1, 2, 3])) 107 | XCTAssertTrue(JSON([1, 2, 123]) !== JSON([1, 2.0, "123"])) 108 | XCTAssertTrue(JSON(["312": [1, 2], "123": [1, 2]]) 109 | !== JSON(["123": [1, 2], "312": [1, "2"]])) 110 | XCTAssertTrue(JSON(["123": [1, 2]]) !== JSON(["123": [1, "2"]])) 111 | XCTAssertTrue(JSON(["123": [1, 2]]) !== JSON(["123": [1, 2.0]])) 112 | } 113 | 114 | func testJSONAdd() { 115 | XCTAssertEqual(JSON(10.10) + JSON(10.10), JSON(20.20)) 116 | XCTAssertEqual(JSON(10.10) + JSON(10), JSON(20.10)) 117 | XCTAssertEqual(JSON(10) + JSON(10.10), JSON(20.10)) 118 | XCTAssertEqual(JSON(10) + JSON("10.10"), JSON.Null) 119 | } 120 | 121 | func testJSONMinus() { 122 | XCTAssertEqual(-JSON(-10), JSON(10)) 123 | XCTAssertEqual(-JSON(-10.0), JSON(10.0)) 124 | } 125 | 126 | func testJSONMultiply() { 127 | XCTAssertEqual(JSON(10.0) * JSON(10.0), JSON(100.0)) 128 | XCTAssertEqual(JSON(10) * JSON(10.0), JSON(100.0)) 129 | XCTAssertEqual(JSON(10.0) * JSON(10), JSON(100.0)) 130 | XCTAssertEqual(JSON(10) * JSON(10), JSON(100)) 131 | XCTAssertEqual(JSON(10) * JSON("abc"), JSON.Null) 132 | } 133 | 134 | func testJSONMDivide() { 135 | XCTAssertEqual(JSON(10.0) / JSON(10.0), JSON(1.0)) 136 | XCTAssertEqual(JSON(10) / JSON(10.0), JSON(1.0)) 137 | XCTAssertEqual(JSON(10.0) / JSON(10), JSON(1.0)) 138 | XCTAssertEqual(JSON(10) / JSON(10), JSON(1)) 139 | XCTAssertEqual(JSON(10) / JSON("abc"), JSON.Null) 140 | } 141 | 142 | func testJSONMModulo() { 143 | XCTAssertEqual(JSON(101) % JSON(2), JSON(1)) 144 | XCTAssertEqual(JSON(101.0) % JSON(2.0), JSON(1.0)) 145 | XCTAssertEqual(JSON(101.0) % JSON(2.5), JSON(1.0)) 146 | XCTAssertEqual(JSON(101.75) % JSON(2), JSON(1.75)) 147 | XCTAssertEqual(JSON(101) % JSON(1.5), JSON(0.5)) 148 | XCTAssertEqual(JSON(10) % JSON("abc"), JSON.Null) 149 | } 150 | 151 | func testJSONMLessThan() { 152 | XCTAssertTrue(JSON(10.0) < JSON(10.1)) 153 | XCTAssertTrue(JSON(10) < JSON(11)) 154 | XCTAssertTrue(JSON(10.0) < JSON(11)) 155 | XCTAssertTrue(JSON(11) < JSON(12.0)) 156 | XCTAssertTrue(JSON(11) < JSON("12.0")) 157 | XCTAssertTrue(JSON(11.0) < JSON("12.0")) 158 | XCTAssertTrue(JSON("11") < JSON(12.0)) 159 | XCTAssertFalse(JSON("ABC") < JSON(12.0)) 160 | XCTAssertTrue(JSON(false) < JSON(true)) 161 | XCTAssertTrue(JSON([1,22]) < JSON([2,1])) 162 | XCTAssertFalse(JSON([1,22]) < JSON([])) 163 | XCTAssertFalse(JSON([]) < JSON([])) 164 | } 165 | 166 | func testJSONMInitializationFromValue() { 167 | XCTAssertEqual(JSON(10.0), JSON.Double(10.0)) 168 | XCTAssertEqual(JSON("10.0"), JSON.String("10.0")) 169 | XCTAssertEqual(JSON(10), JSON.Int(10)) 170 | XCTAssertEqual(JSON(true), JSON.Bool(true)) 171 | XCTAssertEqual(JSON(nil), JSON.Null) 172 | 173 | XCTAssertEqual(JSON([1]), JSON.Array([JSON.Int(1)])) 174 | XCTAssertEqual(JSON([1, 1]), JSON.Array([JSON.Int(1), JSON.Int(1)])) 175 | XCTAssertEqual(JSON([1, 1, 2]), JSON.Array([JSON.Int(1), JSON.Int(1), JSON.Int(2)])) 176 | 177 | // This is differnt from how original jsonlogic JS implementation works 178 | // since it does not allow comparing dictionaries/arrays 179 | XCTAssertEqual(JSON(["1": 1]), JSON.Dictionary(["1": 1])) 180 | } 181 | 182 | 183 | func testJSONMInitializationFromLiteral() { 184 | var json: JSON = [1] 185 | XCTAssertEqual(json, JSON.Array([JSON.Int(1)])) 186 | 187 | json = ["1": 1] 188 | XCTAssertEqual(json, JSON.Dictionary(["1": 1])) 189 | 190 | json = 10.0 191 | XCTAssertEqual(json, JSON.Double(10.0)) 192 | 193 | json = "10.0" 194 | XCTAssertEqual(json, JSON.String("10.0")) 195 | 196 | json = 10 197 | XCTAssertEqual(json, JSON.Int(10)) 198 | 199 | json = true 200 | XCTAssertEqual(json, JSON.Bool(true)) 201 | 202 | json = nil 203 | XCTAssertEqual(json, JSON.Null) 204 | } 205 | 206 | func testJSONSubscriptGet_GivenJSONArray() throws { 207 | let jsonInts = JSON.Array([3, 2, 1]) 208 | 209 | XCTAssertEqual(jsonInts[0], 3) 210 | XCTAssertEqual(jsonInts[1], 2) 211 | XCTAssertEqual(jsonInts[2], 1) 212 | 213 | let jsonMixed = JSON.Array([.Bool(false), .String("123"), .Null]) 214 | 215 | XCTAssertEqual(jsonMixed[0], false) 216 | XCTAssertEqual(jsonMixed[1], "123") 217 | XCTAssertEqual(jsonMixed[2], nil) 218 | 219 | 220 | let error: JSON.JSON2Error? = { 221 | if case let JSON.Error(error) = jsonInts[3] { 222 | return error 223 | } 224 | return nil 225 | }() 226 | XCTAssertEqual(error, .indexOutOfRange(3)) 227 | } 228 | 229 | func testJSONSubscriptSet_GivenJSONArray() throws { 230 | var jsonInts = JSON.Array([3, 2, 1]) 231 | 232 | jsonInts[0] = "123" 233 | jsonInts[1] = nil 234 | jsonInts[2] = 1.1 235 | XCTAssertEqual(jsonInts[0], "123") 236 | XCTAssertEqual(jsonInts[1], nil) 237 | XCTAssertEqual(jsonInts[2], 1.1) 238 | 239 | let error: JSON.JSON2Error? = { 240 | if case let JSON.Error(error) = jsonInts[3] { 241 | return error 242 | } 243 | return nil 244 | }() 245 | XCTAssertEqual(error, .indexOutOfRange(3)) 246 | } 247 | 248 | func testJSONSubscriptSetPadsArrayWithNil_WhenIndexIsOutOfRange_GivenJSONArray() throws { 249 | var jsonInts = JSON.Array([3, 2, 1]) 250 | 251 | jsonInts[8] = 0 252 | 253 | //It should pad the index with nil (JSON.Nil) 254 | XCTAssertEqual(jsonInts, JSON([3, 2, 1, nil, nil, nil, nil, nil, 0])) 255 | } 256 | 257 | func testJSONSubscriptGet_GivenJSONDictionary() throws { 258 | let jsonInts = JSON.Dictionary(["1": 1, "abc": 2]) 259 | 260 | XCTAssertEqual(jsonInts["1"], 1) 261 | XCTAssertEqual(jsonInts["abc"], 2) 262 | 263 | let notSubscribableJSONType = JSON.Bool(true) 264 | 265 | let error: JSON.JSON2Error? = { 266 | if case let JSON.Error(error) = notSubscribableJSONType["abc"] { 267 | return error 268 | } 269 | return nil 270 | }() 271 | XCTAssertEqual(error, .notSubscriptableType(JSON.Bool(true).type)) 272 | } 273 | 274 | func testJSONSubscriptSet_GivenJSONDictionary() throws { 275 | var jsonInts = JSON.Dictionary(["1": 1, "abc": 2]) 276 | 277 | jsonInts["1"] = 123 278 | jsonInts["abc"] = false 279 | 280 | XCTAssertEqual(jsonInts["1"], 123) 281 | XCTAssertEqual(jsonInts["abc"], false) 282 | } 283 | 284 | func testTruthy() { 285 | //https://jsonlogic.com/truthy.html 286 | 287 | XCTAssertEqual(JSON.Int(0).truthy(), false) 288 | XCTAssertEqual(JSON.Int(1).truthy(), true) 289 | XCTAssertEqual(JSON.Int(-1).truthy(), true) 290 | XCTAssertEqual(JSON.Double(1.1).truthy(), true) 291 | 292 | XCTAssertEqual(JSON.Array([]).truthy(), false) 293 | XCTAssertEqual(JSON.Array([1, 2]).truthy(), true) 294 | 295 | XCTAssertEqual(JSON.String("").truthy(), false) 296 | XCTAssertEqual(JSON.String("abc").truthy(), true) 297 | XCTAssertEqual(JSON.String("0").truthy(), true) 298 | 299 | XCTAssertEqual(JSON.Null.truthy(), false) 300 | 301 | XCTAssertEqual(JSON.Bool(true).truthy(), true) 302 | XCTAssertEqual(JSON.Bool(false).truthy(), false) 303 | 304 | XCTAssertEqual(JSON.init(string: "{}")!.truthy(), false) 305 | XCTAssertEqual(JSON.Dictionary(["": 1]).truthy(), true) 306 | 307 | XCTAssertEqual(JSON.Error(.notJSONValue).truthy(), false) 308 | } 309 | 310 | func testToNumberConversion() { 311 | XCTAssertEqual(JSON.Int(0).toNumber(), JSON.Int(0)) 312 | XCTAssertEqual(JSON.Double(1.1).toNumber(), JSON.Double(1.1)) 313 | 314 | XCTAssertEqual(JSON.Bool(true).toNumber(), JSON.Int(1)) 315 | XCTAssertEqual(JSON.Bool(false).toNumber(), JSON.Int(0)) 316 | 317 | XCTAssertEqual(JSON.String("0").toNumber(), JSON.Int(0)) 318 | XCTAssertEqual(JSON.String("1").toNumber(), JSON.Int(1)) 319 | XCTAssertEqual(JSON.String("1.0").toNumber(), JSON.Int(1)) 320 | XCTAssertEqual(JSON.String("1.0").toNumber(), JSON.Double(1.0)) 321 | XCTAssertEqual(JSON.String("1.1").toNumber(), JSON.Double(1.1)) 322 | 323 | XCTAssertEqual(JSON.String("1.1.").toNumber(), JSON.Null) 324 | XCTAssertEqual(JSON.Array([]).toNumber(), JSON.Null) 325 | XCTAssertEqual(JSON.Array([1, 2]).toNumber(), JSON.Null) 326 | XCTAssertEqual(JSON.Null.toNumber(), JSON.Null) 327 | XCTAssertEqual(JSON.init(string: "{}")!.toNumber(), JSON.Null) 328 | XCTAssertEqual(JSON.Dictionary(["": 1]).toNumber(), JSON.Null) 329 | XCTAssertEqual(JSON.Error(.notJSONValue).toNumber(), JSON.Null) 330 | } 331 | 332 | func testContentTypeConversion() { 333 | XCTAssertEqual(JSON.Int(0).type, JSON.ContentType.number) 334 | XCTAssertEqual(JSON.Double(1.1).type, JSON.ContentType.number) 335 | XCTAssertEqual(JSON.Bool(true).type, JSON.ContentType.bool) 336 | XCTAssertEqual(JSON.String("abc").type, JSON.ContentType.string) 337 | XCTAssertEqual(JSON.Array([]).type, JSON.ContentType.array) 338 | XCTAssertEqual(JSON.Array([1, 2]).type, JSON.ContentType.array) 339 | XCTAssertEqual(JSON.init(string: "{}")!.type, JSON.ContentType.object) 340 | XCTAssertEqual(JSON.Error(.notJSONValue).type, JSON.ContentType.error) 341 | XCTAssertEqual(JSON.Null.type, JSON.ContentType.null) 342 | } 343 | 344 | func testInitializationWithDefaultValue() { 345 | XCTAssertEqual(JSON(), JSON.Null) 346 | } 347 | 348 | func testInitializationWithInvalidValue() throws { 349 | class AClass {} 350 | 351 | let jsonInvalid = JSON(AClass()) 352 | 353 | let error: JSON.JSON2Error? = { 354 | if case let JSON.Error(error) = jsonInvalid { 355 | return error 356 | } 357 | return nil 358 | }() 359 | 360 | let parseError = NSError(domain: "Can't convert value \(AClass()) to JSON", code: 1) 361 | XCTAssertEqual(error, .NSError(parseError)) 362 | } 363 | } 364 | 365 | -------------------------------------------------------------------------------- /Tests/JSONTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | #if !canImport(ObjectiveC) 2 | import XCTest 3 | 4 | extension JSONTests { 5 | // DO NOT MODIFY: This is autogenerated, use: 6 | // `swift test --generate-linuxmain` 7 | // to regenerate. 8 | static let __allTests__JSONTests = [ 9 | ("testContentTypeConversion", testContentTypeConversion), 10 | ("testInitializationWithDefaultValue", testInitializationWithDefaultValue), 11 | ("testInitializationWithInvalidValue", testInitializationWithInvalidValue), 12 | ("testJSONAdd", testJSONAdd), 13 | ("testJSONEquality", testJSONEquality), 14 | ("testJSONInEquality", testJSONInEquality), 15 | ("testJSONMDivide", testJSONMDivide), 16 | ("testJSONMInitializationFromLiteral", testJSONMInitializationFromLiteral), 17 | ("testJSONMInitializationFromValue", testJSONMInitializationFromValue), 18 | ("testJSONMinus", testJSONMinus), 19 | ("testJSONMLessThan", testJSONMLessThan), 20 | ("testJSONMModulo", testJSONMModulo), 21 | ("testJSONMultiply", testJSONMultiply), 22 | ("testJSONStrictEquality", testJSONStrictEquality), 23 | ("testJSONStrictInEquality", testJSONStrictInEquality), 24 | ("testJSONSubscriptGet_GivenJSONArray", testJSONSubscriptGet_GivenJSONArray), 25 | ("testJSONSubscriptGet_GivenJSONDictionary", testJSONSubscriptGet_GivenJSONDictionary), 26 | ("testJSONSubscriptSet_GivenJSONArray", testJSONSubscriptSet_GivenJSONArray), 27 | ("testJSONSubscriptSet_GivenJSONDictionary", testJSONSubscriptSet_GivenJSONDictionary), 28 | ("testJSONSubscriptSetPadsArrayWithNil_WhenIndexIsOutOfRange_GivenJSONArray", testJSONSubscriptSetPadsArrayWithNil_WhenIndexIsOutOfRange_GivenJSONArray), 29 | ("testToNumberConversion", testToNumberConversion), 30 | ("testTruthy", testTruthy), 31 | ] 32 | } 33 | 34 | public func __allTests() -> [XCTestCaseEntry] { 35 | return [ 36 | testCase(JSONTests.__allTests__JSONTests), 37 | ] 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import JSONTests 4 | import jsonlogicTests 5 | 6 | var tests = [XCTestCaseEntry]() 7 | tests += JSONTests.__allTests() 8 | tests += jsonlogicTests.__allTests() 9 | 10 | XCTMain(tests) 11 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/AccessingDataOperations/AllTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class AllTests: XCTestCase { 12 | 13 | let emptyIntArray = [Int]() 14 | 15 | func testAll_withCurrentArrayElement() { 16 | var rule = 17 | """ 18 | {"all":[{"var":"integers"}, {">=":[{"var":""}, 1]}]} 19 | """ 20 | var data = 21 | """ 22 | {"integers":[1,2,3]} 23 | """ 24 | XCTAssertTrue(try applyRule(rule, to: data)) 25 | 26 | rule = 27 | """ 28 | {"all":[{"var":"integers"}, {"==":[{"var":""}, 1]}]} 29 | """ 30 | XCTAssertFalse(try applyRule(rule, to: data)) 31 | 32 | rule = 33 | """ 34 | {"all":[{"var":"integers"}, {"<":[{"var":""}, 1]}]} 35 | """ 36 | XCTAssertFalse(try applyRule(rule, to: data)) 37 | 38 | rule = 39 | """ 40 | {"all":[{"var":"integers"}, {"<=":[{"var":""}, 1]}]} 41 | """ 42 | XCTAssertFalse(try applyRule(rule, to: data)) 43 | 44 | rule = 45 | """ 46 | {"all":[{"var":"integers"}, {"<":[{"var":""}, 1]}]} 47 | """ 48 | data = 49 | """ 50 | {"integers":[]} 51 | """ 52 | XCTAssertFalse(try applyRule(rule, to: data)) 53 | } 54 | 55 | func testAll_withNestedArrayElement() { 56 | var rule = 57 | """ 58 | {"all":[ {"var":"items"}, {">=":[{"var":"qty"}, 1]}]} 59 | """ 60 | var data = 61 | """ 62 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 63 | """ 64 | XCTAssertTrue(try applyRule(rule, to: data)) 65 | 66 | rule = 67 | """ 68 | {"all":[ {"var":"items"}, {">":[{"var":"qty"}, 1]}]} 69 | """ 70 | data = 71 | """ 72 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 73 | """ 74 | XCTAssertFalse(try applyRule(rule, to: data)) 75 | 76 | rule = 77 | """ 78 | {"all":[ {"var":"items"}, {"<":[{"var":"qty"}, 1]}]} 79 | """ 80 | data = 81 | """ 82 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 83 | """ 84 | XCTAssertFalse(try applyRule(rule, to: data)) 85 | } 86 | 87 | func testAll_withEmptyDataArray() { 88 | let rule = 89 | """ 90 | {"all":[ {"var":"items"}, {">=":[{"var":"qty"}, 1]}]} 91 | """ 92 | let data = 93 | """ 94 | {"items":[]} 95 | """ 96 | XCTAssertFalse(try applyRule(rule, to: data)) 97 | } 98 | 99 | 100 | func testAll_withMissingArguments() { 101 | let rule = 102 | """ 103 | {"all":[]} 104 | """ 105 | XCTAssertNil(try applyRule(rule)) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/AccessingDataOperations/ArrayMapTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | //swiftlint:disable function_body_length 12 | class ArrayMapTests: XCTestCase { 13 | 14 | let emptyIntArray = [Int]() 15 | 16 | func testMap() { 17 | var rule = 18 | """ 19 | {"map":[{"var":"integers"}, {"*":[{"var":""},2]}]} 20 | """ 21 | var data = 22 | """ 23 | {"integers":[1,2,3]} 24 | """ 25 | XCTAssertEqual([2, 4, 6], try applyRule(rule, to: data)) 26 | 27 | rule = 28 | """ 29 | {"map":[{"var":"integers"}, {"*":[{"var":""},2]}]} 30 | """ 31 | XCTAssertEqual(emptyIntArray, try applyRule(rule, to: nil)) 32 | 33 | rule = 34 | """ 35 | {"map":[{"var":"desserts"}, {"var":"qty"}]} 36 | """ 37 | data = 38 | """ 39 | {"desserts":[ 40 | {"name":"apple","qty":1}, 41 | {"name":"brownie","qty":2}, 42 | {"name":"cupcake","qty":3} 43 | ]} 44 | """ 45 | XCTAssertEqual([1, 2, 3], try applyRule(rule, to: data)) 46 | 47 | rule = 48 | """ 49 | {"map":[{"var":"desserts"}]} 50 | """ 51 | XCTAssertEqual(emptyIntArray, try applyRule(rule)) 52 | } 53 | 54 | func testReduce() { 55 | var rule = 56 | """ 57 | {"reduce":[ 58 | {"var":"integers"}, 59 | {"+":[{"var":"current"}, {"var":"accumulator"}]}, 60 | 0 61 | ]} 62 | """ 63 | var data = 64 | """ 65 | {"integers":[1,2,3,4]} 66 | """ 67 | XCTAssertEqual(10, try applyRule(rule, to: data)) 68 | 69 | rule = 70 | """ 71 | {"reduce":[ 72 | {"var":"integers"}, 73 | {"+":[{"var":"current"}, {"var":"accumulator"}]}, 74 | 0 75 | ]} 76 | """ 77 | XCTAssertEqual(0, try applyRule(rule, to: nil)) 78 | 79 | rule = 80 | """ 81 | {"reduce":[ 82 | {"var":"integers"}, 83 | {"*":[{"var":"current"}, {"var":"accumulator"}]}, 84 | 1 85 | ]} 86 | """ 87 | data = 88 | """ 89 | {"integers":[1,2,3,4]} 90 | """ 91 | XCTAssertEqual(24, try applyRule(rule, to: data)) 92 | 93 | rule = 94 | """ 95 | {"reduce":[ 96 | {"var":"integers"}, 97 | {"*":[{"var":"current"}, {"var":"accumulator"}]}, 98 | 0 99 | ]} 100 | """ 101 | data = 102 | """ 103 | {"integers":[1,2,3,4]} 104 | """ 105 | XCTAssertEqual(0, try applyRule(rule, to: data)) 106 | 107 | rule = 108 | """ 109 | {"reduce": [ 110 | {"var":"desserts"}, 111 | {"+":[ {"var":"accumulator"}, {"var":"current.qty"}]}, 112 | 0 113 | ]} 114 | """ 115 | data = 116 | """ 117 | {"desserts":[ 118 | {"name":"apple","qty":1}, 119 | {"name":"brownie","qty":2}, 120 | {"name":"cupcake","qty":3} 121 | ]} 122 | """ 123 | XCTAssertEqual(6, try applyRule(rule, to: data)) 124 | } 125 | 126 | func testFilter() { 127 | var rule = 128 | """ 129 | {"filter":[{"var":"integers"}, true]} 130 | """ 131 | var data = 132 | """ 133 | {"integers":[1,2,3]} 134 | """ 135 | XCTAssertEqual([1, 2, 3], try applyRule(rule, to: data)) 136 | 137 | rule = 138 | """ 139 | {"filter":[{"var":"integers"}, false]} 140 | """ 141 | data = 142 | """ 143 | {"integers":[1,2,3]} 144 | """ 145 | XCTAssertEqual(emptyIntArray, try applyRule(rule, to: data)) 146 | 147 | rule = 148 | """ 149 | {"filter":[{"var":"integers"}, {">=":[{"var":""},2]}]} 150 | """ 151 | data = 152 | """ 153 | {"integers":[1,2,3]} 154 | """ 155 | XCTAssertEqual([2, 3], try applyRule(rule, to: data)) 156 | 157 | rule = 158 | """ 159 | {"filter":[{"var":"integers"}, {"%":[{"var":""},2]}]} 160 | """ 161 | data = 162 | """ 163 | {"integers":[1,2,3]} 164 | """ 165 | XCTAssertEqual([1, 3], try applyRule(rule, to: data)) 166 | 167 | rule = 168 | """ 169 | {"filter":[{"var":"integers"}]} 170 | """ 171 | XCTAssertEqual(emptyIntArray, try applyRule(rule, to: data)) 172 | } 173 | 174 | func testFilter_withMissingArguments() { 175 | let rule = 176 | """ 177 | {"filter":[]} 178 | """ 179 | XCTAssertEqual(emptyIntArray, try applyRule(rule)) 180 | } 181 | 182 | func testReduce_withMissingArguments() { 183 | let rule = 184 | """ 185 | {"reduce":[]} 186 | """ 187 | XCTAssertNil(try applyRule(rule)) 188 | } 189 | 190 | func testMap_withMissingArguments() { 191 | let rule = 192 | """ 193 | {"map":[]} 194 | """ 195 | XCTAssertEqual(emptyIntArray, try applyRule(rule)) 196 | } 197 | 198 | func testAccessingVariableWithArrayIndexPath() { 199 | let rule = 200 | """ 201 | { "var" : "person.name.0" } 202 | """ 203 | let data = 204 | """ 205 | { "person" : { "name" : ["John", "Green"] } } 206 | """ 207 | XCTAssertEqual("John", try applyRule(rule, to: data)) 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/AccessingDataOperations/MergeArrayTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class MergeTests: XCTestCase { 12 | 13 | let emptyIntArray = [Int]() 14 | 15 | func testMerge() { 16 | var rule = 17 | """ 18 | {"merge":[]} 19 | """ 20 | XCTAssertEqual(emptyIntArray, try applyRule(rule, to: nil)) 21 | rule = 22 | """ 23 | {"merge":[[1]]} 24 | """ 25 | XCTAssertEqual([1], try applyRule(rule, to: nil)) 26 | 27 | rule = 28 | """ 29 | {"merge":[[1],[]]} 30 | """ 31 | XCTAssertEqual([1], try applyRule(rule, to: nil)) 32 | 33 | rule = 34 | """ 35 | {"merge":[[1],[2]]} 36 | """ 37 | XCTAssertEqual([1, 2], try applyRule(rule, to: nil)) 38 | 39 | rule = 40 | """ 41 | {"merge":[[1], [2], [3]]} 42 | """ 43 | XCTAssertEqual([1, 2, 3], try applyRule(rule, to: nil)) 44 | 45 | rule = 46 | """ 47 | {"merge":[[1, 2], [3]]} 48 | """ 49 | XCTAssertEqual([1, 2, 3], try applyRule(rule, to: nil)) 50 | } 51 | 52 | func testMerge_withNonArrayArguments() { 53 | var rule = 54 | """ 55 | {"merge":1} 56 | """ 57 | XCTAssertEqual([1], try applyRule(rule, to: nil)) 58 | 59 | rule = 60 | """ 61 | {"merge":[1,2]} 62 | """ 63 | XCTAssertEqual([1, 2], try applyRule(rule, to: nil)) 64 | 65 | rule = 66 | """ 67 | {"merge":[1,[2]]} 68 | """ 69 | XCTAssertEqual([1, 2], try applyRule(rule, to: nil)) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/AccessingDataOperations/MissingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | //swiftlint:disable function_body_length 12 | class MissingTests: XCTestCase { 13 | 14 | let emptyStringArray = [String]() 15 | 16 | func testVar_withEmptyVarName() { 17 | let rule = 18 | """ 19 | {"var":[""]} 20 | """ 21 | let data = 22 | """ 23 | [1, 2, 3] 24 | """ 25 | XCTAssertEqual([1, 2, 3], try applyRule(rule, to: data)) 26 | } 27 | 28 | func testMissing() { 29 | var rule = 30 | """ 31 | {"missing":["a", "b"]} 32 | """ 33 | var data = 34 | """ 35 | {"a":"apple", "c":"carrot"} 36 | """ 37 | XCTAssertEqual(["b"], try applyRule(rule, to: data)) 38 | 39 | rule = 40 | """ 41 | {"missing":["a", "b"]} 42 | """ 43 | data = 44 | """ 45 | {"a":"apple", "b":"banana"} 46 | """ 47 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 48 | 49 | rule = 50 | """ 51 | {"missing":[]} 52 | """ 53 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: nil)) 54 | 55 | rule = 56 | """ 57 | {"missing":["a"]} 58 | """ 59 | XCTAssertEqual(["a"], try applyRule(rule, to: nil)) 60 | 61 | rule = 62 | """ 63 | {"missing":"a"} 64 | """ 65 | XCTAssertEqual(["a"], try applyRule(rule, to: nil)) 66 | 67 | rule = 68 | """ 69 | {"missing":"a"} 70 | """ 71 | data = 72 | """ 73 | {"a":"apple"} 74 | """ 75 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 76 | 77 | rule = 78 | """ 79 | {"missing":["a"]} 80 | """ 81 | data = 82 | """ 83 | {"a":"apple"} 84 | """ 85 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 86 | 87 | rule = 88 | """ 89 | {"missing":["a","b"]} 90 | """ 91 | data = 92 | """ 93 | {"a":"apple"} 94 | """ 95 | XCTAssertEqual(["b"], try applyRule(rule, to: data)) 96 | 97 | rule = 98 | """ 99 | {"missing":["a","b"]} 100 | """ 101 | data = 102 | """ 103 | {"b":"banana"} 104 | """ 105 | XCTAssertEqual(["a"], try applyRule(rule, to: data)) 106 | 107 | rule = 108 | """ 109 | {"missing":["a","b"]} 110 | """ 111 | data = 112 | """ 113 | {"a":"apple", "b":"banana"} 114 | """ 115 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 116 | 117 | rule = 118 | """ 119 | {"missing":["a","b"]} 120 | """ 121 | data = 122 | """ 123 | {} 124 | """ 125 | XCTAssertEqual(["a", "b"], try applyRule(rule, to: data)) 126 | 127 | rule = 128 | """ 129 | {"missing":["a","b"]} 130 | """ 131 | XCTAssertEqual(["a", "b"], try applyRule(rule, to: nil)) 132 | } 133 | 134 | func testMissing_NestedKeys() { 135 | var rule = 136 | """ 137 | {"missing":["a.b"]} 138 | """ 139 | var data = 140 | """ 141 | {"a":"apple"} 142 | """ 143 | XCTAssertEqual(["a.b"], try applyRule(rule, to: data)) 144 | 145 | rule = 146 | """ 147 | {"missing":["a.b"]} 148 | """ 149 | XCTAssertEqual(["a.b"], try applyRule(rule, to: nil)) 150 | 151 | rule = 152 | """ 153 | {"missing":["a.b"]} 154 | """ 155 | data = 156 | """ 157 | {"a":{"c":"apple cake"}} 158 | """ 159 | XCTAssertEqual(["a.b"], try applyRule(rule, to: data)) 160 | 161 | rule = 162 | """ 163 | {"missing":["a.b"]} 164 | """ 165 | data = 166 | """ 167 | {"a":{"b":"apple brownie"}} 168 | """ 169 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 170 | 171 | rule = 172 | """ 173 | {"missing":["a.b", "a.c"]} 174 | """ 175 | data = 176 | """ 177 | {"a":{"b":"apple brownie"}} 178 | """ 179 | XCTAssertEqual(["a.c"], try applyRule(rule, to: data)) 180 | } 181 | 182 | func testMissing_some() { 183 | var rule = 184 | """ 185 | {"missing_some":[1, ["a", "b"]]} 186 | """ 187 | var data = 188 | """ 189 | {"a":"apple"} 190 | """ 191 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 192 | 193 | rule = 194 | """ 195 | {"missing_some":[1, ["a", "b"]]} 196 | """ 197 | data = 198 | """ 199 | {"b":"banana"} 200 | """ 201 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 202 | 203 | rule = 204 | """ 205 | {"missing_some":[1, ["a", "b"]]} 206 | """ 207 | data = 208 | """ 209 | {"b":"banana"} 210 | """ 211 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 212 | 213 | rule = 214 | """ 215 | {"missing_some":[2, ["a", "b", "c"]]} 216 | """ 217 | data = 218 | """ 219 | {"a":"apple"} 220 | """ 221 | XCTAssertEqual(["b", "c"], try applyRule(rule, to: data)) 222 | 223 | //Following the rules for var for . notation 224 | rule = 225 | """ 226 | {"missing_some":[2, ["person.name", "b", "c"]]} 227 | """ 228 | data = 229 | """ 230 | {"a":"apple", "person": {"name": "Bruce"} } 231 | """ 232 | XCTAssertEqual(["b", "c"], try applyRule(rule, to: data)) 233 | 234 | rule = 235 | """ 236 | {"missing_some":[1, ["person.name", "b", "c"]]} 237 | """ 238 | data = 239 | """ 240 | {"a":"apple", "person": {"name": "Bruce"} } 241 | """ 242 | XCTAssertEqual(emptyStringArray, try applyRule(rule, to: data)) 243 | 244 | //with wrong arguments 245 | rule = 246 | """ 247 | {"missing_some":[1]} 248 | """ 249 | data = 250 | """ 251 | {"b":"banana"} 252 | """ 253 | XCTAssertNil(try applyRule(rule, to: data)) 254 | 255 | rule = 256 | """ 257 | {"if" :[ 258 | {"merge": [ 259 | {"missing":["first_name", "last_name"]}, 260 | {"missing_some":[1, ["cell_phone", "home_phone"] ]} 261 | ]}, 262 | "We require first name, last name, and one phone number.", 263 | "OK to proceed" 264 | ]} 265 | """ 266 | 267 | data = 268 | """ 269 | {"first_name":"Bruce", "last_name":"Wayne"} 270 | """ 271 | XCTAssertEqual("We require first name, last name, and one phone number.", try applyRule(rule, to: data)) 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/AccessingDataOperations/NoneTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class NoneTests: XCTestCase { 12 | 13 | func testNone() { 14 | var rule = 15 | """ 16 | {"none":[{"var":"integers"}, {">=":[{"var":""}, 1]}]} 17 | """ 18 | let data = 19 | """ 20 | {"integers":[1,2,3]} 21 | """ 22 | XCTAssertEqual(false, try applyRule(rule, to: data)) 23 | 24 | rule = 25 | """ 26 | {"none":[{"var":"integers"}, {"==":[{"var":""}, 1]}]} 27 | """ 28 | XCTAssertEqual(false, try applyRule(rule, to: data)) 29 | 30 | rule = 31 | """ 32 | {"none":[{"var":"integers"}, {"<":[{"var":""}, 1]}]} 33 | """ 34 | XCTAssertEqual(true, try applyRule(rule, to: data)) 35 | 36 | rule = 37 | """ 38 | {"none":[{"var":"integers"}, {"<=":[{"var":""}, 1]}]} 39 | """ 40 | XCTAssertEqual(false, try applyRule(rule, to: data)) 41 | } 42 | 43 | func testNone_WithEmptyDataArray() { 44 | var rule = 45 | """ 46 | {"none":[{"var":"integers"}, {"<":[{"var":""}, 1]}]} 47 | """ 48 | var data = 49 | """ 50 | {"integers":[]} 51 | """ 52 | XCTAssertEqual(true, try applyRule(rule, to: data)) 53 | 54 | rule = 55 | """ 56 | {"none":[ {"var":"items"}, {">=":[{"var":"qty"}, 1]}]} 57 | """ 58 | data = 59 | """ 60 | {"items":[]} 61 | """ 62 | XCTAssertEqual(true, try applyRule(rule, to: data)) 63 | 64 | rule = 65 | """ 66 | {"none":[ {"var":"items"}, {">=":[{"var":"qty"}, 1]}]} 67 | """ 68 | data = 69 | """ 70 | {"items":[]} 71 | """ 72 | XCTAssertEqual(true, try applyRule(rule, to: data)) 73 | } 74 | 75 | func testNone_WithNestedDataItems() { 76 | var rule = 77 | """ 78 | {"none":[ {"var":"items"}, {">=":[{"var":"qty"}, 1]}]} 79 | """ 80 | var data = 81 | """ 82 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 83 | """ 84 | XCTAssertEqual(false, try applyRule(rule, to: data)) 85 | 86 | rule = 87 | """ 88 | {"none":[ {"var":"items"}, {">":[{"var":"qty"}, 1]}]} 89 | """ 90 | data = 91 | """ 92 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 93 | """ 94 | XCTAssertEqual(false, try applyRule(rule, to: data)) 95 | 96 | rule = 97 | """ 98 | {"none":[ {"var":"items"}, {"<":[{"var":"qty"}, 1]}]} 99 | """ 100 | data = 101 | """ 102 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 103 | """ 104 | XCTAssertEqual(true, try applyRule(rule, to: data)) 105 | } 106 | 107 | func testNone_WithMissingArguments() { 108 | var rule = 109 | """ 110 | {"none":[{"var":"integers"}]} 111 | """ 112 | XCTAssertNil(try applyRule(rule)) 113 | 114 | rule = 115 | """ 116 | {"none":[]} 117 | """ 118 | XCTAssertNil(try applyRule(rule)) 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/AccessingDataOperations/SomeTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class SomeTests: XCTestCase { 12 | 13 | func testSome() { 14 | var rule = 15 | """ 16 | {"some":[{"var":"integers"}, {">=":[{"var":""}, 1]}]} 17 | """ 18 | let data = 19 | """ 20 | {"integers":[1,2,3]} 21 | """ 22 | XCTAssertEqual(true, try applyRule(rule, to: data)) 23 | 24 | rule = 25 | """ 26 | {"some":[{"var":"integers"}, {"==":[{"var":""}, 1]}]} 27 | """ 28 | XCTAssertEqual(true, try applyRule(rule, to: data)) 29 | 30 | rule = 31 | """ 32 | {"some":[{"var":"integers"}, {"<":[{"var":""}, 1]}]} 33 | """ 34 | XCTAssertEqual(false, try applyRule(rule, to: data)) 35 | 36 | rule = 37 | """ 38 | {"some":[{"var":"integers"}, {"<=":[{"var":""}, 1]}]} 39 | """ 40 | XCTAssertEqual(true, try applyRule(rule, to: data)) 41 | } 42 | 43 | func testSome_WithEmptyDataArray() { 44 | var rule = 45 | """ 46 | {"some":[{"var":"integers"}, {"<":[{"var":""}, 1]}]} 47 | """ 48 | var data = 49 | """ 50 | {"integers":[]} 51 | """ 52 | XCTAssertEqual(false, try applyRule(rule, to: data)) 53 | 54 | rule = 55 | """ 56 | {"some":[ {"var":"items"}, {">=":[{"var":"qty"}, 1]}]} 57 | """ 58 | data = 59 | """ 60 | {"items":[]} 61 | """ 62 | XCTAssertEqual(false, try applyRule(rule, to: data)) 63 | } 64 | 65 | func testNone_WithNestedDataItems() { 66 | var rule = 67 | """ 68 | {"some":[ {"var":"items"}, {">=":[{"var":"qty"}, 1]}]} 69 | """ 70 | var data = 71 | """ 72 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 73 | """ 74 | XCTAssertEqual(true, try applyRule(rule, to: data)) 75 | 76 | rule = 77 | """ 78 | {"some":[ {"var":"items"}, {">":[{"var":"qty"}, 1]}]} 79 | """ 80 | data = 81 | """ 82 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 83 | """ 84 | XCTAssertEqual(true, try applyRule(rule, to: data)) 85 | 86 | rule = 87 | """ 88 | {"some":[ {"var":"items"}, {"<":[{"var":"qty"}, 1]}]} 89 | """ 90 | data = 91 | """ 92 | {"items":[{"qty":1,"sku":"apple"},{"qty":2,"sku":"banana"}]} 93 | """ 94 | XCTAssertEqual(false, try applyRule(rule, to: data)) 95 | } 96 | 97 | func testSome_WithMissingArguments() { 98 | var rule = 99 | """ 100 | {"some":[{"var":"integers"}]} 101 | """ 102 | XCTAssertNil(try applyRule(rule)) 103 | 104 | rule = 105 | """ 106 | {"some":[]} 107 | """ 108 | XCTAssertNil(try applyRule(rule)) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/AccessingDataOperations/VarTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VarTests.swift 3 | // jsonlogic 4 | // 5 | // Created by Christos Koninis on 2/12/22. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | import JSON 11 | 12 | class VarTests: XCTestCase { 13 | 14 | let emptyIntArray = [Int]() 15 | 16 | func testVar_withDefaultArgument_GivenArgumentIsMissing() { 17 | let rule = 18 | """ 19 | {"var": ["a"]} 20 | """ 21 | XCTAssertNil(try applyRule(rule)) 22 | } 23 | 24 | func testVar_withDefaultArgument() { 25 | let rule = 26 | """ 27 | {"var": ["a", 0]} 28 | """ 29 | XCTAssertEqual(try applyRule(rule), 0) 30 | } 31 | 32 | func testVar_withInvalidVarPath() { 33 | let rule = 34 | """ 35 | {"var": ["a..b"]} 36 | """ 37 | XCTAssertNil(try applyRule(rule)) 38 | } 39 | 40 | func testVar_withInvalidVarPath_GivenArgumentIsMissing() { 41 | let rule = 42 | """ 43 | {"var": ["a..b", 0]} 44 | """ 45 | XCTAssertEqual(try applyRule(rule), 0) 46 | } 47 | 48 | func testVar_withDefaultArgumentString() { 49 | let rule = 50 | """ 51 | {"var": ["a", "0"]} 52 | """ 53 | XCTAssertEqual(try applyRule(rule), "0") 54 | } 55 | 56 | func testVar_withDefaultArgumentString_GivenArgumentExistsInData() { 57 | let rule = 58 | """ 59 | {"var": ["a", "0"]} 60 | """ 61 | let data = 62 | """ 63 | {"a": "1"} 64 | """ 65 | XCTAssertEqual(try applyRule(rule, to: data), "1") 66 | } 67 | 68 | func testVar_withDefaultArgumentString_GivenArgumentDoesNotExistsInData() { 69 | let rule = 70 | """ 71 | {"var": ["a", "0"]} 72 | """ 73 | let data = 74 | """ 75 | {"b": "1"} 76 | """ 77 | XCTAssertEqual(try applyRule(rule, to: data), "0") 78 | } 79 | 80 | func testVar_withDefaultArgumentString_GivenNestedArgumentDoesNotExistsInData() { 81 | let rule = 82 | """ 83 | {"var": ["a.b", "0"]} 84 | """ 85 | let data = 86 | """ 87 | {"a": "1"} 88 | """ 89 | XCTAssertEqual(try applyRule(rule, to: data), "0") 90 | } 91 | 92 | 93 | } 94 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/ArithmeticTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Arithmetic.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class Arithmetic: XCTestCase { 12 | 13 | func testAddition() { 14 | var rule = 15 | """ 16 | { "+" : [4, 2] } 17 | """ 18 | XCTAssertEqual(6, try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | { "+" : [4, "2"] } 23 | """ 24 | XCTAssertEqual(6, try applyRule(rule, to: nil)) 25 | 26 | rule = 27 | """ 28 | { "+" : [2, 2, 2, 2, 2]} 29 | """ 30 | XCTAssertEqual(10, try applyRule(rule, to: nil)) 31 | 32 | rule = 33 | """ 34 | { "+" : "3.14"} 35 | """ 36 | XCTAssertEqual(3.14, try applyRule(rule, to: nil)) 37 | } 38 | 39 | func testSubtraction() { 40 | var rule = 41 | """ 42 | { "-" : [4, 2] } 43 | """ 44 | XCTAssertEqual(2, try applyRule(rule, to: nil)) 45 | 46 | rule = 47 | """ 48 | { "-" : [2, 3] } 49 | """ 50 | XCTAssertEqual(-1, try applyRule(rule, to: nil)) 51 | 52 | rule = 53 | """ 54 | { "-" : [3] } 55 | """ 56 | XCTAssertEqual(-3, try applyRule(rule, to: nil)) 57 | 58 | rule = 59 | """ 60 | { "-" : [1, "1"] } 61 | """ 62 | XCTAssertEqual(0, try applyRule(rule, to: nil)) 63 | } 64 | 65 | func testMultiplication() { 66 | var rule = 67 | """ 68 | { "*" : [4, 2] } 69 | """ 70 | XCTAssertEqual(8, try applyRule(rule, to: nil)) 71 | 72 | rule = 73 | """ 74 | { "*" : [2, 2, 2, 2, 2]} 75 | """ 76 | XCTAssertEqual(32, try applyRule(rule, to: nil)) 77 | 78 | rule = 79 | """ 80 | { "*" : [3, 2] } 81 | """ 82 | XCTAssertEqual(6, try applyRule(rule, to: nil)) 83 | 84 | rule = 85 | """ 86 | { "*" : [1]} 87 | """ 88 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 89 | 90 | rule = 91 | """ 92 | { "*" : ["1", 1]} 93 | """ 94 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 95 | } 96 | 97 | func testMultiplication_TypeCoercion() { 98 | var rule = 99 | """ 100 | {"*":["2","2"]} 101 | """ 102 | XCTAssertEqual(4, try applyRule(rule, to: nil)) 103 | 104 | rule = 105 | """ 106 | {"*":["2"]} 107 | """ 108 | XCTAssertEqual(2, try applyRule(rule, to: nil)) 109 | } 110 | 111 | func testDivision() { 112 | var rule = 113 | """ 114 | { "/" : [4, 2]} 115 | """ 116 | XCTAssertEqual(2, try applyRule(rule, to: nil)) 117 | 118 | rule = 119 | """ 120 | { "/" : [2, 4]} 121 | """ 122 | XCTAssertEqual(0.5, try applyRule(rule, to: nil)) 123 | 124 | rule = 125 | """ 126 | { "+" : [2, 2, 2, 2, 2]} 127 | """ 128 | XCTAssertEqual(10, try applyRule(rule, to: nil)) 129 | 130 | rule = 131 | """ 132 | { "/" : ["1", 1]} 133 | """ 134 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 135 | } 136 | 137 | func testModulo() { 138 | var rule = 139 | """ 140 | { "%" : [1, 2]} 141 | """ 142 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 143 | 144 | rule = 145 | """ 146 | { "%" : [2, 2]} 147 | """ 148 | XCTAssertEqual(0, try applyRule(rule, to: nil)) 149 | 150 | rule = 151 | """ 152 | { "%" : [3, 2]} 153 | """ 154 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 155 | } 156 | 157 | func testUnaryMinus() { 158 | var rule = 159 | """ 160 | { "-" : [2] } 161 | """ 162 | XCTAssertEqual(-2, try applyRule(rule, to: nil)) 163 | 164 | rule = 165 | """ 166 | { "-" : [-2] } 167 | """ 168 | XCTAssertEqual(2, try applyRule(rule, to: nil)) 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/CompoundTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class CompoundTests: XCTestCase { 12 | 13 | func testCompound() { 14 | var rule = 15 | """ 16 | {"and":[{">":[3,1]},true]} 17 | """ 18 | XCTAssertEqual(true, try applyRule(rule, to: "{}")) 19 | 20 | rule = 21 | """ 22 | {"and":[{">":[3,1]},false]} 23 | """ 24 | XCTAssertEqual(false, try applyRule(rule, to: "{}")) 25 | 26 | rule = 27 | """ 28 | {"and":[{">":[3,1]},{"!":true}]} 29 | """ 30 | XCTAssertEqual(false, try applyRule(rule, to: "{}")) 31 | 32 | rule = 33 | """ 34 | {"and":[{">":[3,1]},{"<":[1,3]}]} 35 | """ 36 | XCTAssertEqual(true, try applyRule(rule, to: "{}")) 37 | 38 | rule = 39 | """ 40 | {"?:":[{">":[3,1]},"visible","hidden"]} 41 | """ 42 | XCTAssertEqual("visible", try applyRule(rule, to: "{}")) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/CustomOperatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomOperatorTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 3/15/21. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | import JSON 11 | 12 | private class CustomOperatorWrapper { 13 | var isCustomOperatorCalled = false 14 | var evalutedJSONInput: JSON? 15 | 16 | lazy var customOperator: ((JSON?) -> JSON) = { [weak self] json in 17 | guard let strongSelf = self else { return JSON.Null } 18 | strongSelf.isCustomOperatorCalled = true 19 | strongSelf.evalutedJSONInput = json 20 | 21 | guard let array = json?.array else { return JSON.Null } 22 | 23 | return array.reduce(into: JSON(0)) { (result, arrayItem) in 24 | //swiftlint:disable:next shorthand_operator 25 | result = result + arrayItem.toNumber() 26 | } 27 | } 28 | } 29 | 30 | class CustomOperatorTests: XCTestCase { 31 | 32 | func testCustomOperatorIsCalled_GivenItIsRegisted() throws { 33 | let rule = 34 | """ 35 | { "plus" : [1, 2] } 36 | """ 37 | 38 | let customOperatorWrapper = CustomOperatorWrapper() 39 | let customOperators = ["plus": customOperatorWrapper.customOperator] 40 | 41 | XCTAssertEqual(3, try JsonLogic(rule, customOperators: customOperators).applyRule()) 42 | XCTAssertTrue(customOperatorWrapper.isCustomOperatorCalled) 43 | } 44 | 45 | func testCustomOperatorIsNotCalled_GivenItIsNotRegisted() throws { 46 | let rule = 47 | """ 48 | { "plus" : [1, 2] } 49 | """ 50 | 51 | let customOperatorWrapper = CustomOperatorWrapper() 52 | 53 | let block = { 54 | try JsonLogic(rule, customOperators: [:]).applyRule() as Int 55 | } 56 | 57 | try _XCTAssertThrowsError(try block(), "") { 58 | let parseError: ParseError = try XCTUnwrap($0 as? ParseError) 59 | XCTAssertEqual(parseError, .UnimplementedExpressionFor("plus")) 60 | } 61 | XCTAssertFalse(customOperatorWrapper.isCustomOperatorCalled) 62 | } 63 | 64 | func testCustomOperatorIsNotCalled_GivenItIsRegistedWithSameNameAsInternalOperators() { 65 | let rule = 66 | """ 67 | { "*" : [1, 2] } 68 | """ 69 | 70 | let customOperatorWrapper = CustomOperatorWrapper() 71 | let customOperators = ["*": customOperatorWrapper.customOperator] 72 | 73 | XCTAssertEqual(2, try JsonLogic(rule, customOperators: customOperators).applyRule()) 74 | XCTAssertFalse(customOperatorWrapper.isCustomOperatorCalled, 75 | "the custom operator should not override the internal") 76 | } 77 | 78 | func testCustomOperatorIsGivenExpetedJSONToEvaluate() throws { 79 | let rule = 80 | """ 81 | { "plus" : [1, {"var" : "aVariable"}] } 82 | """ 83 | 84 | let data = 85 | """ 86 | { "aVariable" : 3 } 87 | """ 88 | 89 | let expectedJSONInput = JSON(string: "[1, 3]") 90 | 91 | let customOperatorWrapper = CustomOperatorWrapper() 92 | let customOperators = ["plus": customOperatorWrapper.customOperator] 93 | 94 | let result: Int = try JsonLogic(rule, customOperators: customOperators).applyRule(to: data) 95 | XCTAssertEqual(4, result) 96 | XCTAssertEqual(expectedJSONInput, customOperatorWrapper.evalutedJSONInput) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/JsonLogicTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | @testable import jsonlogic 4 | 5 | final class JsonLogicTests: XCTestCase { 6 | 7 | func testEqualsWithTwoSameConstants() { 8 | let rule = 9 | """ 10 | { "===" : [1, 1] } 11 | """ 12 | 13 | XCTAssertTrue(try applyRule(rule, to: nil)) 14 | } 15 | 16 | func testEqualsWithDifferentSameConstants() { 17 | let rule = 18 | """ 19 | { "===" : [1, 2] } 20 | """ 21 | 22 | XCTAssertFalse(try applyRule(rule, to: nil)) 23 | } 24 | 25 | func testSetOneStringVariableFromData() { 26 | let rule = 27 | """ 28 | { "var" : "a" } 29 | """ 30 | let data = 31 | """ 32 | { "a" : "1" } 33 | """ 34 | 35 | XCTAssertEqual("1", try applyRule(rule, to: data)) 36 | } 37 | 38 | func testSetOneIntegerVariableFromData() { 39 | let rule = 40 | """ 41 | { "var" : "a" } 42 | """ 43 | let data = 44 | """ 45 | { "a" : 1 } 46 | """ 47 | 48 | XCTAssertEqual(1, try applyRule(rule, to: data)) 49 | } 50 | 51 | func testSetOneBoolVariableFromData() { 52 | let rule = 53 | """ 54 | { "var" : "a" } 55 | """ 56 | let data = 57 | """ 58 | { "a" : true } 59 | """ 60 | 61 | XCTAssertTrue(try applyRule(rule, to: data)) 62 | } 63 | 64 | func testSetTwoStringVariablesFromData() { 65 | let rule = 66 | """ 67 | { "var" : "a" } 68 | """ 69 | let data = 70 | """ 71 | { "a" : true } 72 | """ 73 | 74 | XCTAssertTrue(try applyRule(rule, to: data)) 75 | } 76 | 77 | func testSetOneStringNestedVariableFromData() { 78 | let rule = 79 | """ 80 | { "var" : "person.name" } 81 | """ 82 | let data = 83 | """ 84 | { "person" : { "name" : "Jon" } } 85 | """ 86 | 87 | XCTAssertEqual("Jon", try applyRule(rule, to: data)) 88 | } 89 | 90 | func testSetOneStringArrayVariableFromData() { 91 | let rule = 92 | """ 93 | { "var" : ["a"] } 94 | """ 95 | let data = 96 | """ 97 | { "a" : "1" } 98 | """ 99 | 100 | XCTAssertEqual("1", try applyRule(rule, to: data)) 101 | } 102 | 103 | func testAddTwoIntsFromVariables() { 104 | let rule = 105 | """ 106 | { "===" : [{ "var" : ["a"] }, "1"] } 107 | """ 108 | let data = 109 | """ 110 | { "a" : "1" } 111 | """ 112 | 113 | XCTAssertTrue(try applyRule(rule, to: data)) 114 | } 115 | 116 | func testNestedVar() { 117 | let rule = 118 | """ 119 | { "var" : [{ "var" : ["a"] }] } 120 | """ 121 | let data = 122 | """ 123 | { "a" : "b", "b" : "1" } 124 | """ 125 | 126 | XCTAssertEqual("1", try applyRule(rule, to: data)) 127 | } 128 | 129 | func testNestedVarWithStrictEquals() { 130 | let rule = 131 | """ 132 | { "===" : [ {"var" : [ {"var" : ["a"]} ] }, {"var" : ["oneNest.one"]}] } 133 | """ 134 | let data = 135 | """ 136 | { "a" : "b", "b" : "1", "oneNest" : {"one" : "1"} } 137 | """ 138 | 139 | XCTAssertTrue(try applyRule(rule, to: data)) 140 | } 141 | 142 | func testNestedStrictEqualsWithVar() { 143 | let rule = 144 | """ 145 | { "var" : [ {"var" : [ {"var" : ["a"] } ] } ] } 146 | """ 147 | let data = 148 | """ 149 | { "a" : "b", "b" : "oneNest.one", "oneNest" : {"one" : "10"} } 150 | """ 151 | 152 | XCTAssertEqual("10", try applyRule(rule, to: data)) 153 | } 154 | 155 | func testNotSupportedResultType() { 156 | let rule = 157 | """ 158 | { "===" : [1, 1] } 159 | """ 160 | 161 | class SomeType {} 162 | 163 | XCTAssertThrowsError(try { try applyRule(rule) as SomeType }(), "") { 164 | //swiftlint:disable:next force_cast 165 | XCTAssertEqual($0 as! JSONLogicError, .canNotConvertResultToType(SomeType.self)) 166 | } 167 | } 168 | 169 | /// Test for the bug advantagefse/json-logic-swift/issues/24 170 | func testComplexRule() { 171 | let rule = 172 | """ 173 | { 174 | "!": [{ 175 | "and": [{ 176 | "in": ["Population", { 177 | "var": "CHOIX" 178 | }] 179 | }, 180 | { 181 | "in": [{ 182 | "var": "TAILLE_POP" 183 | }, 184 | ["", null] 185 | ] 186 | } 187 | ] 188 | }] 189 | } 190 | """ 191 | let data = 192 | """ 193 | { "COMPARTIEMENT" : "Faune/Wildlife", "ACTIF" : "false" } 194 | """ 195 | 196 | XCTAssertTrue(try applyRule(rule, to: data)) 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/LogicAndBooleanOperations/AndTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AndTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 12/02/2019. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import jsonlogic 11 | 12 | class AndTests: XCTestCase { 13 | 14 | func testAnd_twoBooleans() { 15 | XCTAssertEqual(true, try applyRule(""" 16 | {"and": [true, true]} 17 | """, to: nil)) 18 | 19 | XCTAssertEqual(false, try applyRule(""" 20 | { "and" : [true, false] } 21 | """, to: nil)) 22 | 23 | XCTAssertEqual(true, try applyRule(""" 24 | { "and" : [true] } 25 | """, to: nil)) 26 | XCTAssertEqual(false, try applyRule(""" 27 | { "and" : [false] } 28 | """, to: nil)) 29 | } 30 | 31 | func testAnd_mixedArguments() { 32 | XCTAssertEqual(3, try applyRule(""" 33 | { "and": [1, 3] } 34 | """, to: nil)) 35 | 36 | XCTAssertEqual("a", try applyRule(""" 37 | { "and": ["a"] } 38 | """, to: nil)) 39 | 40 | XCTAssertEqual("", try applyRule(""" 41 | { "and": [true,"",3] } 42 | """, to: nil)) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/LogicAndBooleanOperations/DoubleNegationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AndTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 12/02/2019. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import jsonlogic 11 | 12 | class DoubleNegationTests: XCTestCase { 13 | 14 | func testDoubleNegation_withBooleans() { 15 | XCTAssertEqual(false, try applyRule(""" 16 | { "and" : [false] } 17 | """, to: nil)) 18 | 19 | XCTAssertEqual(true, try applyRule(""" 20 | { "and" : [true] } 21 | """, to: nil)) 22 | } 23 | 24 | func testDoubleNegation_withObject() { 25 | XCTAssertEqual(true, try applyRule(""" 26 | { "!!" : true } 27 | """, to: nil)) 28 | 29 | XCTAssertEqual(false, try applyRule(""" 30 | { "!!" : false } 31 | """, to: nil)) 32 | 33 | XCTAssertEqual(true, try applyRule(""" 34 | { "!!" : "0" } 35 | """, to: nil)) 36 | } 37 | 38 | func testDoubleNegation_withArrays() { 39 | XCTAssertEqual(false, try applyRule(""" 40 | { "!!" : [ [] ] } 41 | """, to: nil)) 42 | 43 | XCTAssertEqual(true, try applyRule(""" 44 | { "!!" : [ [0] ] } 45 | """, to: nil)) 46 | } 47 | 48 | func testDoubleNegation_withStrings() { 49 | XCTAssertEqual(false, try applyRule(""" 50 | { "!!" : [ "" ] } 51 | """, to: nil)) 52 | 53 | XCTAssertEqual(true, try applyRule(""" 54 | { "!!" : [ "0" ] } 55 | """, to: nil)) 56 | } 57 | 58 | func testDoubleNegation_withNumbers() { 59 | XCTAssertEqual(false, try applyRule(""" 60 | { "!!" : [ 0 ] } 61 | """, to: nil)) 62 | 63 | XCTAssertEqual(true, try applyRule(""" 64 | { "!!" : [ 1 ] } 65 | """, to: nil)) 66 | 67 | XCTAssertEqual(true, try applyRule(""" 68 | { "!!" : [ -1 ] } 69 | """, to: nil)) 70 | 71 | XCTAssertEqual(true, try applyRule(""" 72 | { "!!" : [ 1000 ] } 73 | """, to: nil)) 74 | } 75 | 76 | func testDoubleNegation_withNull() { 77 | XCTAssertEqual(false, try applyRule(""" 78 | { "!!" : [ null ] } 79 | """, to: nil)) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/LogicAndBooleanOperations/EqualsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EqualsTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 17/02/2019. 6 | // 7 | 8 | import Foundation 9 | import XCTest 10 | @testable import jsonlogic 11 | 12 | class EqualsTests: XCTestCase { 13 | 14 | func testEquals() { 15 | var rule = 16 | """ 17 | {"==":[1,1]} 18 | """ 19 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 20 | 21 | rule = 22 | """ 23 | {"==":[1,2]} 24 | """ 25 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 26 | } 27 | 28 | func testEquals_WithTypeCoercion() { 29 | var rule = 30 | """ 31 | {"==":[1,"1"]} 32 | """ 33 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 34 | 35 | rule = 36 | """ 37 | {"==":[1,"2"]} 38 | """ 39 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 40 | 41 | rule = 42 | """ 43 | {"==":[1,"1.0"]} 44 | """ 45 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 46 | 47 | rule = 48 | """ 49 | {"==":[null,1]} 50 | """ 51 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 52 | 53 | rule = 54 | """ 55 | {"==":[0,false]} 56 | """ 57 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 58 | 59 | rule = 60 | """ 61 | {"==":[[1],[1]]} 62 | """ 63 | //http://jsonlogic.com/play.html returns false here 64 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 65 | } 66 | 67 | func testNotEquals() { 68 | var rule = 69 | """ 70 | {"!=":[1,2]} 71 | """ 72 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 73 | 74 | rule = 75 | """ 76 | {"!=":[1,1]} 77 | """ 78 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 79 | 80 | rule = 81 | """ 82 | {"!=":[1,"1"]} 83 | """ 84 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 85 | } 86 | 87 | func testNotEquals_WithTypeCoersion() { 88 | var rule = 89 | """ 90 | {"!=":[1,"1"]} 91 | """ 92 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 93 | 94 | rule = 95 | """ 96 | {"!=":[1,"1.0"]} 97 | """ 98 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 99 | 100 | rule = 101 | """ 102 | {"!=":[0,true]} 103 | """ 104 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/LogicAndBooleanOperations/IfTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | //swiftlint:disable function_body_length 12 | class IfTests: XCTestCase { 13 | 14 | func testIf_ToofewArgs() { 15 | var rule = 16 | """ 17 | { "if":[ [], "apple", "banana"] } 18 | """ 19 | XCTAssertEqual("banana", try applyRule(rule, to: nil)) 20 | 21 | rule = 22 | """ 23 | { "if":[ [1], "apple", "banana"] } 24 | """ 25 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 26 | 27 | rule = 28 | """ 29 | { "if":[ [1,2,3,4], "apple", "banana"] } 30 | """ 31 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 32 | } 33 | 34 | func testIf_SimpleCases() { 35 | var rule = 36 | """ 37 | {"if":[ {">":[2,1]}, "apple", "banana"]} 38 | """ 39 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 40 | 41 | rule = 42 | """ 43 | {"if":[ {">":[1,2]}, "apple", "banana"]} 44 | """ 45 | XCTAssertEqual("banana", try applyRule(rule, to: nil)) 46 | 47 | rule = 48 | """ 49 | {"if":[false, "apple", true, "banana", "carrot"]} 50 | """ 51 | XCTAssertEqual("banana", try applyRule(rule, to: nil)) 52 | 53 | rule = 54 | """ 55 | {"if":[true, "apple", true, "banana", true, "carrot", "date"]} 56 | """ 57 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 58 | } 59 | 60 | func testIf_EmptyArraysAreFalsey() { 61 | var rule = 62 | """ 63 | { "if" : [] } 64 | """ 65 | XCTAssertNil(try applyRule(rule, to: nil)) 66 | 67 | rule = 68 | """ 69 | { "if" : [true] } 70 | """ 71 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 72 | 73 | rule = 74 | """ 75 | { "if" : [false] } 76 | """ 77 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 78 | 79 | rule = 80 | """ 81 | { "if" : ["apple"] } 82 | """ 83 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 84 | } 85 | 86 | func testIf_NonEmptyOtherStringsAreTruthy() { 87 | var rule = 88 | """ 89 | {"if":[ "", "apple", "banana"]} 90 | """ 91 | XCTAssertEqual("banana", try applyRule(rule, to: nil)) 92 | 93 | rule = 94 | """ 95 | {"if":[ "zucchini", "apple", "banana"]} 96 | """ 97 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 98 | 99 | rule = 100 | """ 101 | {"if":[ "0", "apple", "banana"]} 102 | """ 103 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 104 | } 105 | 106 | func testIf_IfThenElseIfThenCases() { 107 | var rule = 108 | """ 109 | {"if":[true, "apple", true, "banana"]} 110 | """ 111 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 112 | 113 | rule = 114 | """ 115 | {"if":[true, "apple", false, "banana"]} 116 | """ 117 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 118 | 119 | rule = 120 | """ 121 | {"if":[false, "apple", true, "banana"]} 122 | """ 123 | XCTAssertEqual("banana", try applyRule(rule, to: nil)) 124 | 125 | rule = 126 | """ 127 | {"if":[false, "apple", false, "banana"]} 128 | """ 129 | XCTAssertNil(try applyRule(rule, to: nil)) 130 | 131 | rule = 132 | """ 133 | {"if":[true, "apple", true, "banana", "carrot"]} 134 | """ 135 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 136 | 137 | rule = 138 | """ 139 | {"if":[true, "apple", false, "banana", "carrot"]} 140 | """ 141 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 142 | 143 | rule = 144 | """ 145 | {"if":[false, "apple", true, "banana", "carrot"]} 146 | """ 147 | XCTAssertEqual("banana", try applyRule(rule, to: nil)) 148 | 149 | rule = 150 | """ 151 | {"if":[false, "apple", false, "banana", "carrot"]} 152 | """ 153 | XCTAssertEqual("carrot", try applyRule(rule, to: nil)) 154 | 155 | rule = 156 | """ 157 | {"if":[false, "apple", false, "banana", false, "carrot"]} 158 | """ 159 | XCTAssertNil(try applyRule(rule, to: nil)) 160 | 161 | rule = 162 | """ 163 | {"if":[false, "apple", false, "banana", false, "carrot", "date"]} 164 | """ 165 | XCTAssertEqual("date", try applyRule(rule, to: nil)) 166 | 167 | rule = 168 | """ 169 | {"if":[false, "apple", true, "banana", false, "carrot", "date"]} 170 | """ 171 | XCTAssertEqual("banana", try applyRule(rule, to: nil)) 172 | 173 | rule = 174 | """ 175 | {"if":[true, "apple", false, "banana", false, "carrot", "date"]} 176 | """ 177 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 178 | 179 | rule = 180 | """ 181 | {"if":[true, "apple", false, "banana", true, "carrot", "date"]} 182 | """ 183 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 184 | 185 | rule = 186 | """ 187 | {"if":[true, "apple", true, "banana", false, "carrot", "date"]} 188 | """ 189 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 190 | 191 | rule = 192 | """ 193 | {"if":[true, "apple", true, "banana", true, "carrot", "date"]} 194 | """ 195 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 196 | } 197 | 198 | func testIf_FizzBuzz() { 199 | let rule = 200 | """ 201 | { 202 | "if": [ 203 | {"==": [ { "%": [ { "var": "i" }, 15 ] }, 0]}, 204 | "fizzbuzz", 205 | 206 | {"==": [ { "%": [ { "var": "i" }, 3 ] }, 0]}, 207 | "fizz", 208 | 209 | {"==": [ { "%": [ { "var": "i" }, 5 ] }, 0]}, 210 | "buzz", 211 | 212 | { "var": "i" } 213 | ] 214 | } 215 | """ 216 | 217 | XCTAssertEqual("fizzbuzz", try applyRule(rule, to: "{\"i\" : 0}")) 218 | XCTAssertEqual(1, try applyRule(rule, to: "{\"i\" : 1}")) 219 | XCTAssertEqual(2, try applyRule(rule, to: "{\"i\" : 2}")) 220 | XCTAssertEqual("fizz", try applyRule(rule, to: "{\"i\" : 3}")) 221 | XCTAssertEqual("buzz", try applyRule(rule, to: "{\"i\" : 5}")) 222 | XCTAssertEqual("fizzbuzz", try applyRule(rule, to: "{\"i\" : 15}")) 223 | XCTAssertEqual("fizzbuzz", try applyRule(rule, to: "{\"i\" : 45}")) 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/LogicAndBooleanOperations/NotStrictEqualsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotStringEquals.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import jsonlogic 11 | 12 | class NotStrictEquals: XCTestCase { 13 | 14 | func testNot_StrictEquals_withConstants() { 15 | let rule = 16 | """ 17 | { "!==" : [1, 2] } 18 | """ 19 | 20 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 21 | } 22 | 23 | func testNot_StrictEquals_withConstants1() { 24 | let rule = 25 | """ 26 | { "!==" : [1, "1"] } 27 | """ 28 | 29 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 30 | } 31 | 32 | func testNot_StrictEquals_withConstants2() { 33 | let rule = 34 | """ 35 | { "!==" : [1, 1] } 36 | """ 37 | 38 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 39 | } 40 | 41 | func testNot_StrictEquals_withConstants3() { 42 | let rule = 43 | """ 44 | { "!==" : [1, []] } 45 | """ 46 | 47 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 48 | } 49 | 50 | func testNotStringEquals_NestedVar() { 51 | let rule = 52 | """ 53 | { "!==" : [ {"var" : [ {"var" : ["a"]} ] }, {"var" : ["oneNest.one"]}] } 54 | """ 55 | let data = 56 | """ 57 | { "a" : "b", "b" : "1", "oneNest" : {"one" : "1"} } 58 | """ 59 | 60 | XCTAssertEqual(false, try applyRule(rule, to: data)) 61 | } 62 | 63 | func testLogicalNot_withBooleanConstants() { 64 | var rule = 65 | """ 66 | { "!" : [true] } 67 | """ 68 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 69 | 70 | rule = 71 | """ 72 | { "!" : [false] } 73 | """ 74 | XCTAssertTrue(try applyRule(rule, to: nil)) 75 | 76 | rule = 77 | """ 78 | {"!" : true} 79 | """ 80 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 81 | 82 | rule = 83 | """ 84 | {"!" : false} 85 | """ 86 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 87 | } 88 | 89 | func testLogicalNot_withArrays() { 90 | var rule = 91 | """ 92 | {"!" : []} 93 | """ 94 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 95 | 96 | rule = 97 | """ 98 | {"!" : [[]]} 99 | """ 100 | XCTAssertTrue(try applyRule(rule, to: nil)) 101 | 102 | rule = 103 | """ 104 | {"!" : [[]]} 105 | """ 106 | XCTAssertTrue(try applyRule(rule, to: nil)) 107 | 108 | rule = 109 | """ 110 | {"!" : [true, 2, 3]} 111 | """ 112 | XCTAssertFalse(try applyRule(rule, to: nil)) 113 | 114 | rule = 115 | """ 116 | {"!" : [false, 2, 3]} 117 | """ 118 | XCTAssertTrue(try applyRule(rule, to: nil)) 119 | } 120 | 121 | func testLogicalNot_withNumbers() { 122 | var rule = 123 | """ 124 | { "!" : 0 } 125 | """ 126 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 127 | 128 | rule = 129 | """ 130 | { "!" : 1 } 131 | """ 132 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 133 | } 134 | 135 | func testLogicalNot_withStrings() { 136 | var rule = 137 | """ 138 | {"!" : ""} 139 | """ 140 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 141 | 142 | rule = 143 | """ 144 | {"!" : ""} 145 | """ 146 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 147 | 148 | rule = 149 | """ 150 | {"!" : "1"} 151 | """ 152 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 153 | } 154 | 155 | func testLogicalNot_withNull() { 156 | let rule = 157 | """ 158 | {"!" : null} 159 | """ 160 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 161 | } 162 | 163 | func testLogicalNot_withVariables() { 164 | let data = 165 | """ 166 | { "a" : "b", "b" : "1", "oneNest" : {"one" : true} } 167 | """ 168 | 169 | var rule = 170 | """ 171 | { "!" : [ {"var" : ["oneNest.one"] } ] } 172 | """ 173 | XCTAssertEqual(false, try applyRule(rule, to: data )) 174 | 175 | rule = 176 | """ 177 | { "!" : {"var" : ["a"] } } 178 | """ 179 | XCTAssertEqual(false, try applyRule(rule, to: data )) 180 | 181 | rule = 182 | """ 183 | { "!" : {"var" : ["nonExistant"] } } 184 | """ 185 | XCTAssertEqual(true, try applyRule(rule, to: data )) 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/LogicAndBooleanOperations/OrTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OrTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 12/02/2019. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import jsonlogic 11 | 12 | class OrTests: XCTestCase { 13 | 14 | func testOr_twoBooleans() { 15 | var rule = 16 | """ 17 | {"or": [true, true]} 18 | """ 19 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 20 | 21 | rule = 22 | """ 23 | { "or" : [true, false] } 24 | """ 25 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 26 | 27 | rule = 28 | """ 29 | { "or" : [false, false] } 30 | """ 31 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 32 | 33 | rule = 34 | """ 35 | { "or" : [true] } 36 | """ 37 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 38 | 39 | rule = 40 | """ 41 | { "or" : [false] } 42 | """ 43 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 44 | } 45 | 46 | func testOr_mixedArguments() { 47 | XCTAssertEqual(1, try applyRule(""" 48 | { "or": [1, 3] } 49 | """, to: nil)) 50 | 51 | XCTAssertEqual("a", try applyRule(""" 52 | { "or": ["a"] } 53 | """, to: nil)) 54 | 55 | XCTAssertEqual(true, try applyRule(""" 56 | { "or": [true,"",3] } 57 | """, to: nil)) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/MinMaxTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Arithmetic.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class MinMaxTests: XCTestCase { 12 | 13 | func testMin_MultiplePositiveValues() { 14 | var rule = """ 15 | { "min" : [1, 2, 3] } 16 | """ 17 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 18 | 19 | rule = """ 20 | { "min" : [1, 1, 3] } 21 | """ 22 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 23 | 24 | rule = """ 25 | { "min" : [3, 2, 1] } 26 | """ 27 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 28 | } 29 | 30 | func testMin_SinglePositiveItem() { 31 | let rule = """ 32 | { "min" : [1] } 33 | """ 34 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 35 | } 36 | 37 | func testMin_MultipleNegativeValues() { 38 | var rule = """ 39 | { "min" : [-1, -2] } 40 | """ 41 | XCTAssertEqual(-2, try applyRule(rule, to: nil)) 42 | 43 | rule = """ 44 | { "min" : [-1, 1] } 45 | """ 46 | XCTAssertEqual(-1, try applyRule(rule, to: nil)) 47 | } 48 | 49 | func testMax_MultiplePositiveValues() { 50 | var rule = """ 51 | { "max" : [1, 2, 3] } 52 | """ 53 | XCTAssertEqual(3, try applyRule(rule, to: nil)) 54 | 55 | rule = """ 56 | { "max" : [1, 1, 3] } 57 | """ 58 | XCTAssertEqual(3, try applyRule(rule, to: nil)) 59 | 60 | rule = """ 61 | { "max" : [3, 2, 1] } 62 | """ 63 | XCTAssertEqual(3, try applyRule(rule, to: nil)) 64 | } 65 | 66 | func testMax_SinglePositiveItem() { 67 | let rule = """ 68 | { "max" : [1] } 69 | """ 70 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 71 | } 72 | 73 | func testMax_MultipleNegativeValues() { 74 | var rule = """ 75 | { "max" : [-1, -2] } 76 | """ 77 | XCTAssertEqual(-1, try applyRule(rule, to: nil)) 78 | 79 | rule = """ 80 | { "max" : [-1, 1] } 81 | """ 82 | XCTAssertEqual(1, try applyRule(rule, to: nil)) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/NumericalOperations/BetweenTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BetweenTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class BetweenTests: XCTestCase { 12 | 13 | func testBetween_withNumberConstants() { 14 | var rule = 15 | """ 16 | { "<" : [1, 2, 3] } 17 | """ 18 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | { "<" : [1, 1, 3] } 23 | """ 24 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 25 | 26 | rule = 27 | """ 28 | { "<" : [1, 3, 3] } 29 | """ 30 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 31 | 32 | rule = 33 | """ 34 | { "<=" : [1, 3, 3] } 35 | """ 36 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 37 | 38 | rule = 39 | """ 40 | { "<=" : [2, 2, 3] } 41 | """ 42 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 43 | 44 | rule = 45 | """ 46 | { "<=" : [1, 4, 3] } 47 | """ 48 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 49 | } 50 | 51 | // func testBetween_withNonNumbericConstants() { 52 | // let rulesAndResults = [ 53 | // //When both are strings the comparison in done lexicographaclly e.g. "111111" < "2" 54 | // """ 55 | // { "<" : ["1", "2222", "3"] } 56 | // """ : true, 57 | // """ 58 | // { "<=" : ["2", "2", "3"] } 59 | // """ : true, 60 | // """ 61 | // { "<" : ["2", "2", "3"] } 62 | // """ : false, 63 | // """ 64 | // { "<=" : [null, [], "2"] } 65 | // """ : true, 66 | // """ 67 | // { "<" : [null, [], "2"] } 68 | // """ : false 69 | // ] 70 | // 71 | // for (rule, result) in rulesAndResults { 72 | // XCTAssertEqual(result, try applyRule(rule, to: nil)) 73 | // } 74 | // } 75 | 76 | // func testBetween_withMixedNumbericAndNonConstants() { 77 | // let rulesAndResults = [ 78 | // //When one is numeric then the other is converted to numberic 79 | // """ 80 | // { "<=" : ["111", "2", 1111] } 81 | // """ : true, 82 | // """ 83 | // { "<=" : ["1", "2222", 11111] } 84 | // """ : false, 85 | // """ 86 | // { "<=" : [1, "b", 1111] } 87 | // """ : false, 88 | // //Anything but null when compared with null is greater 89 | // """ 90 | // { "<" : [0, 1, null] } 91 | // """ : false, 92 | // """ 93 | // { "<=" : [[], 0, "2"] } 94 | // """ : true, 95 | // """ 96 | // { "<=" : [10, 10, "11"] } 97 | // """ : true, 98 | // """ 99 | // { "<=" : [null, [], null] } 100 | // """ : false, 101 | // """ 102 | // { "<=" : [null, [], 2] } 103 | // """ : true, 104 | // """ 105 | // { "<=" : ["11", "2", 3] } 106 | // """ : true, 107 | // """ 108 | // { "<=" : ["", 1, [[]]] } 109 | // """ : false 110 | // ] 111 | // 112 | // for (rule, result) in rulesAndResults { 113 | // XCTAssertEqual(result, try applyRule(rule, to: nil)) 114 | // } 115 | // } 116 | 117 | func testBetween_withVariables() { 118 | var rule = 119 | """ 120 | { "<=" : [3, {"var" : ["b"]}, 9] } 121 | """ 122 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 123 | 124 | rule = 125 | """ 126 | { "<=" : [0, {"var" : ["b"] }, 2] } 127 | """ 128 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 129 | 130 | rule = 131 | """ 132 | { "<=" : [1, {"var" : ["a"] }, 9] } 133 | """ 134 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 135 | 136 | rule = 137 | """ 138 | { "<=" : [1, 3, 3] } 139 | """ 140 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/NumericalOperations/GreaterThanOrEqualTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GreaterThanOrEqualsTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class GreaterThanOrEqualTests: XCTestCase { 12 | 13 | func testGreaterThan_withNumberConstants() { 14 | var rule = 15 | """ 16 | { ">=" : [3, 1] } 17 | """ 18 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | { ">=" : [1, 1] } 23 | """ 24 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 25 | 26 | rule = 27 | """ 28 | { ">=" : [1, 3] } 29 | """ 30 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 31 | } 32 | 33 | func testGreaterThan_withNonNumbericConstants() { 34 | var rule = 35 | """ 36 | { ">=" : ["2", "1111"] } 37 | """ 38 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 39 | 40 | rule = 41 | """ 42 | { ">=" : [null, null] } 43 | """ 44 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 45 | 46 | rule = 47 | """ 48 | { ">=" : [null, []] } 49 | """ 50 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 51 | 52 | rule = 53 | """ 54 | { ">=" : ["1", ""] } 55 | """ 56 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 57 | } 58 | 59 | func testGreaterThan_withMixedArgumentTypes() { 60 | var rule = 61 | """ 62 | { ">=" : ["2", 1111] } 63 | """ 64 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 65 | 66 | rule = 67 | """ 68 | { ">=" : ["2222", 1111] } 69 | """ 70 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 71 | 72 | rule = 73 | """ 74 | { ">=" : ["b", 1111] } 75 | """ 76 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 77 | 78 | rule = 79 | """ 80 | { ">=" : [1, null] } 81 | """ 82 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 83 | 84 | rule = 85 | """ 86 | { ">=" : [1, []] } 87 | """ 88 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 89 | 90 | rule = 91 | """ 92 | { ">=" : [[[]], 0] } 93 | """ 94 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 95 | } 96 | 97 | func testGreaterThan_withVariables() { 98 | var rule = 99 | """ 100 | { ">=" : [3, {"var" : ["oneNest.one"]} ] } 101 | """ 102 | let data = 103 | """ 104 | { "a" : "b", "b" : "1", "oneNest" : {"one" : true} } 105 | """ 106 | XCTAssertEqual(true, try applyRule(rule, to: data)) 107 | 108 | rule = 109 | """ 110 | { ">=" : [1, {"var" : ["oneNest.one"]} ] } 111 | """ 112 | XCTAssertEqual(true, try applyRule(rule, to: data)) 113 | 114 | rule = 115 | """ 116 | { ">=" : [1, {"var" : ["a"] }] } 117 | """ 118 | XCTAssertEqual(false, try applyRule(rule, to: data)) 119 | 120 | rule = 121 | """ 122 | { ">=" : [1, ["nonExistent"]] } 123 | """ 124 | XCTAssertEqual(false, try applyRule(rule, to: data)) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/NumericalOperations/GreaterThanTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GreaterThanTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class GreaterThanTests: XCTestCase { 12 | 13 | func testGreaterThan_withNumberConstants() { 14 | var rule = 15 | """ 16 | { ">" : [3, 1] } 17 | """ 18 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | { ">" : [1, 1] } 23 | """ 24 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 25 | 26 | rule = 27 | """ 28 | { ">" : [1, 3] } 29 | """ 30 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 31 | } 32 | 33 | func testGreaterThan_withNonNumbericConstants() { 34 | var rule = 35 | """ 36 | { ">" : ["2", "1111"] } 37 | """ 38 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 39 | 40 | rule = 41 | """ 42 | { ">" : [null, null] } 43 | """ 44 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 45 | 46 | rule = 47 | """ 48 | { ">" : [null, []] } 49 | """ 50 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 51 | 52 | rule = 53 | """ 54 | { ">" : ["1", ""] } 55 | """ 56 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 57 | } 58 | 59 | func testGreaterThan_withMixedArguments() { 60 | var rule = 61 | """ 62 | { ">" : ["2", 1111] } 63 | """ 64 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 65 | 66 | rule = 67 | """ 68 | { ">" : ["2222", 1111] } 69 | """ 70 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 71 | 72 | rule = 73 | """ 74 | { ">" : ["b", 1111] } 75 | """ 76 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 77 | 78 | rule = 79 | """ 80 | { ">" : [1, null] } 81 | """ 82 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 83 | 84 | rule = 85 | """ 86 | { ">" : [1, []] } 87 | """ 88 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 89 | 90 | rule = 91 | """ 92 | { ">" : [[[]], 0] } 93 | """ 94 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 95 | } 96 | 97 | func testGreaterThan_withVariables() { 98 | let data = 99 | """ 100 | { "a" : "b", "b" : "1", "oneNest" : {"one" : true} } 101 | """ 102 | 103 | var rule = 104 | """ 105 | { ">" : [3, {"var" : ["oneNest.one"]}] } 106 | """ 107 | XCTAssertEqual(true, try applyRule(rule, to: data)) 108 | 109 | rule = 110 | """ 111 | { ">" : [1, {"var" : ["a"] }] } 112 | """ 113 | XCTAssertEqual(false, try applyRule(rule, to: data)) 114 | 115 | rule = 116 | """ 117 | { ">" : [1, ["nonExistant"]] } 118 | """ 119 | XCTAssertEqual(false, try applyRule(rule, to: data)) 120 | 121 | rule = 122 | """ 123 | { ">" : [2, ["b"]] } 124 | """ 125 | XCTAssertEqual(false, try applyRule(rule, to: data)) 126 | } 127 | 128 | func testGreaterThan_withThreeArguments() { 129 | var rule = 130 | """ 131 | { ">" : [3, 1, 0] } 132 | """ 133 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 134 | 135 | rule = 136 | """ 137 | { ">" : [1, 2, 10] } 138 | """ 139 | 140 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/NumericalOperations/LessThanOrEqualTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LessThanOrEqualTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class LessThanOrEqualTests: XCTestCase { 12 | 13 | func testLessThan_withNumberConstants() { 14 | var rule = 15 | """ 16 | { "<=" : [1, 3] } 17 | """ 18 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | { "<=" : [1, 1] } 23 | """ 24 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 25 | 26 | rule = 27 | """ 28 | { "<=" : [3, 1] } 29 | """ 30 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 31 | } 32 | 33 | func testLessThan_withNonNumericConstants() { 34 | var rule = 35 | """ 36 | { "<=" : ["2", "1111"] } 37 | """ 38 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 39 | 40 | rule = 41 | """ 42 | { "<=" : [null, null] } 43 | """ 44 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 45 | 46 | rule = 47 | """ 48 | { "<=" : [null, []] } 49 | """ 50 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 51 | 52 | rule = 53 | """ 54 | { "<=" : ["1", ""] } 55 | """ 56 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 57 | } 58 | 59 | func testLessThan_withMixedArgumentTypes() { 60 | var rule = 61 | """ 62 | { "<=" : ["2", 1111] } 63 | """ 64 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 65 | 66 | rule = 67 | """ 68 | { "<=" : ["2222", 1111] } 69 | """ 70 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 71 | 72 | rule = 73 | """ 74 | { "<=" : ["b", 1111] } 75 | """ 76 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 77 | 78 | rule = 79 | """ 80 | { "<=" : [1, null] } 81 | """ 82 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 83 | 84 | rule = 85 | """ 86 | { "<=" : [1, []] } 87 | """ 88 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 89 | 90 | rule = 91 | """ 92 | { "<=" : [[[]], 0] } 93 | """ 94 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 95 | } 96 | 97 | func testLessThan_withVariables() { 98 | let data = 99 | """ 100 | { "a" : "b", "b" : "1", "oneNest" : {"one" : true} } 101 | """ 102 | 103 | var rule = 104 | """ 105 | { "<=" : [3, {"var" : ["oneNest.one"]} ] } 106 | """ 107 | XCTAssertEqual(false, try applyRule(rule, to: data)) 108 | 109 | rule = 110 | """ 111 | { "<=" : [1, {"var" : ["b"] }] } 112 | """ 113 | XCTAssertEqual(true, try applyRule(rule, to: data)) 114 | 115 | rule = 116 | """ 117 | { "<=" : [1, ["nonExistant"]] } 118 | """ 119 | //note that http://jsonlogic.com/play.html returns false 120 | XCTAssertEqual(false, try applyRule(rule, to: data)) 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/NumericalOperations/LessThanTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // lessThanTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class LessThanTests: XCTestCase { 12 | 13 | func testLessThan_withNumberConstants() { 14 | var rule = 15 | """ 16 | { "<" : [1, 3] } 17 | """ 18 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | { "<" : [1, 1] } 23 | """ 24 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 25 | 26 | rule = 27 | """ 28 | { "<" : [3, 1] } 29 | """ 30 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 31 | } 32 | 33 | func testLessThan_withNonNumbericConstants() { 34 | var rule = 35 | """ 36 | { "<" : ["2", "1111"] } 37 | """ 38 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 39 | 40 | rule = 41 | """ 42 | { "<" : [null, null] } 43 | """ 44 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 45 | 46 | rule = 47 | """ 48 | { "<" : [null, []] } 49 | """ 50 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 51 | 52 | rule = 53 | """ 54 | { "<" : ["1", ""] } 55 | """ 56 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 57 | } 58 | 59 | func testLessThan_withMixedArgumentsTypes() { 60 | var rule = 61 | """ 62 | { "<" : ["2", 1111] } 63 | """ 64 | //When one is numeric then the other is converted to numberic 65 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 66 | 67 | rule = 68 | """ 69 | { "<" : ["2222", 1111] } 70 | """ 71 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 72 | 73 | rule = 74 | """ 75 | { "<" : ["b", 1111] } 76 | """ 77 | //Anything but null when compared with null is greater 78 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 79 | 80 | rule = 81 | """ 82 | { "<" : [1, null] } 83 | """ 84 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 85 | 86 | rule = 87 | """ 88 | { "<" : [1, []] } 89 | """ 90 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 91 | 92 | rule = 93 | """ 94 | { "<" : [[[]], 0] } 95 | """ 96 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 97 | } 98 | 99 | func testLessThan_withVariables() { 100 | var rule = 101 | """ 102 | { "<" : [3, {"var" : ["oneNest.one"]}] } 103 | """ 104 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 105 | 106 | rule = 107 | """ 108 | { "<" : [1, {"var" : ["a"] }] } 109 | """ 110 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 111 | 112 | rule = 113 | """ 114 | { "<" : [1, ["nonExistant"]] } 115 | """ 116 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 117 | 118 | rule = 119 | """ 120 | { "<" : [0, ["b"]] } 121 | """ 122 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/StringOperations/CatTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | //swiftlint:disable function_body_length 12 | class CatTests: XCTestCase { 13 | 14 | func testCat() { 15 | var rule = 16 | """ 17 | {"cat":"ice"} 18 | """ 19 | XCTAssertEqual("ice", try applyRule(rule, to: nil)) 20 | 21 | rule = 22 | """ 23 | {"cat":["ice"]} 24 | """ 25 | XCTAssertEqual("ice", try applyRule(rule, to: nil)) 26 | 27 | rule = 28 | """ 29 | {"cat":["ice","cream"]} 30 | """ 31 | XCTAssertEqual("icecream", try applyRule(rule, to: nil)) 32 | 33 | rule = 34 | """ 35 | {"cat":[1,2]} 36 | """ 37 | XCTAssertEqual("12", try applyRule(rule, to: nil)) 38 | 39 | rule = 40 | """ 41 | {"cat":[1.1,2.1]} 42 | """ 43 | XCTAssertEqual("1.12.1", try applyRule(rule, to: nil)) 44 | 45 | rule = 46 | """ 47 | {"cat":["Robocop",2]} 48 | """ 49 | XCTAssertEqual("Robocop2", try applyRule(rule, to: nil)) 50 | 51 | rule = 52 | """ 53 | {"cat":["we all scream for ","ice","cream"]} 54 | """ 55 | XCTAssertEqual("we all scream for icecream", try applyRule(rule, to: nil)) 56 | } 57 | 58 | func testCat_WithNullOrEmpty() { 59 | var rule = 60 | """ 61 | {"cat":[1,null]} 62 | """ 63 | XCTAssertEqual("1", try applyRule(rule, to: nil)) 64 | 65 | rule = 66 | """ 67 | {"cat":[1,[]]} 68 | """ 69 | XCTAssertEqual("1", try applyRule(rule, to: nil)) 70 | 71 | rule = 72 | """ 73 | {"cat":[1,""]} 74 | """ 75 | XCTAssertEqual("1", try applyRule(rule, to: nil)) 76 | } 77 | 78 | func testCat_WithBoolean() { 79 | var rule = 80 | """ 81 | {"cat":["jsonlogic", true]} 82 | """ 83 | XCTAssertEqual("jsonlogictrue", try applyRule(rule, to: nil)) 84 | 85 | rule = 86 | """ 87 | {"cat":[false, true]} 88 | """ 89 | XCTAssertEqual("falsetrue", try applyRule(rule, to: nil)) 90 | } 91 | 92 | func testCat_WithArrays() { 93 | var rule = 94 | """ 95 | {"cat":[1,[2,3]]} 96 | """ 97 | XCTAssertEqual("12,3", try applyRule(rule, to: nil)) 98 | 99 | rule = 100 | """ 101 | {"cat":[[1]]} 102 | """ 103 | XCTAssertEqual("1", try applyRule(rule, to: nil)) 104 | 105 | rule = 106 | """ 107 | {"cat":[1,[false,true]]} 108 | """ 109 | XCTAssertEqual("1false,true", try applyRule(rule, to: nil)) 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/StringOperations/InTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class InTests: XCTestCase { 12 | 13 | func testIn_StringArgument() { 14 | var rule = 15 | """ 16 | { "in" : ["Spring", "Springfield"] } 17 | """ 18 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | {"in":["Spring","Springfield"]} 23 | """ 24 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 25 | 26 | rule = 27 | """ 28 | {"in":["i","team"]} 29 | """ 30 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 31 | } 32 | 33 | func testIn_ArrayArgument() { 34 | var rule = 35 | """ 36 | {"in":["Bart",["Bart","Homer","Lisa","Marge","Maggie"]]} 37 | """ 38 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 39 | 40 | rule = 41 | """ 42 | {"in":["Milhouse",["Bart","Homer","Lisa","Marge","Maggie"]]} 43 | """ 44 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 45 | } 46 | 47 | func testIn_IntegerArgument() { 48 | var rule = 49 | """ 50 | {"in":[5,[-1,0,1,2,3,4,5]]} 51 | """ 52 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 53 | 54 | rule = 55 | """ 56 | {"in":[5,[-0,0,1,2,3,4,6]]} 57 | """ 58 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 59 | } 60 | 61 | func testIn_DoubleArgument() { 62 | var rule = 63 | """ 64 | {"in":[5.1,[1.2,2.5,3.5,4.333,5.1]]} 65 | """ 66 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 67 | 68 | rule = 69 | """ 70 | {"in":[5.1,[1.2,2,2.5,3.5,4.333,5]]} 71 | """ 72 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 73 | } 74 | 75 | func testIn_BoolArgument() { 76 | var rule = 77 | """ 78 | {"in":[true,[false, true, false]]} 79 | """ 80 | XCTAssertEqual(true, try applyRule(rule, to: nil)) 81 | 82 | rule = 83 | """ 84 | {"in":[true,[false, false, false]]} 85 | """ 86 | XCTAssertEqual(false, try applyRule(rule, to: nil)) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/StringOperations/LogTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class LogTests: XCTestCase { 12 | 13 | func testLog() { 14 | let rule = 15 | """ 16 | {"log":"apple"} 17 | """ 18 | XCTAssertEqual("apple", try applyRule(rule, to: nil)) 19 | } 20 | 21 | func testLog_withComplexExpression() { 22 | let rule = 23 | """ 24 | {"log":{"cat":[1,[2,3]]}} 25 | """ 26 | XCTAssertEqual("12,3", try applyRule(rule, to: nil)) 27 | } 28 | 29 | //swiftlint:disable:next function_body_length 30 | func testLog_nestedInOtherExpressions() { 31 | 32 | let rule = 33 | """ 34 | { 35 | "if": [{ 36 | "==": [{ 37 | "log": { 38 | "%": [{ 39 | "var": "i" 40 | }, 15] 41 | } 42 | }, 0] 43 | }, "fizzbuzz", { 44 | "log": { 45 | "==": [{ 46 | "%": [{ 47 | "var": "i" 48 | }, 3] 49 | }, 0] 50 | } 51 | }, "fizz", { 52 | "==": [{ 53 | "%": [{ 54 | "var": "i" 55 | }, { 56 | "log": 5 57 | }] 58 | }, 0] 59 | }, { 60 | "log": "buzz" 61 | }, { 62 | "var": "i" 63 | }] 64 | } 65 | """ 66 | 67 | XCTAssertEqual("fizzbuzz", try applyRule(rule, to: "{\"i\" : 0}")) 68 | XCTAssertEqual(1, try applyRule(rule, to: "{\"i\" : 1}")) 69 | XCTAssertEqual(2, try applyRule(rule, to: "{\"i\" : 2}")) 70 | XCTAssertEqual("fizz", try applyRule(rule, to: "{\"i\" : 3}")) 71 | XCTAssertEqual("buzz", try applyRule(rule, to: "{\"i\" : 5}")) 72 | XCTAssertEqual("fizzbuzz", try applyRule(rule, to: "{\"i\" : 15}")) 73 | XCTAssertEqual("fizzbuzz", try applyRule(rule, to: "{\"i\" : 45}")) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/StringOperations/SubstringTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IfTests.swift 3 | // jsonlogicTests 4 | // 5 | // Created by Christos Koninis on 11/02/2019. 6 | // 7 | 8 | import XCTest 9 | @testable import jsonlogic 10 | 11 | class SubstringTests: XCTestCase { 12 | 13 | func testSubstring() { 14 | var rule = 15 | """ 16 | {"substr":["jsonlogic", 4]} 17 | """ 18 | XCTAssertEqual("logic", try applyRule(rule, to: nil)) 19 | 20 | rule = 21 | """ 22 | {"substr":["jsonlogic", -5]} 23 | """ 24 | XCTAssertEqual("logic", try applyRule(rule, to: nil)) 25 | } 26 | 27 | func testSubstring_withRange() { 28 | var rule = 29 | """ 30 | {"substr":["jsonlogic", 0, 1]} 31 | """ 32 | XCTAssertEqual("j", try applyRule(rule, to: nil)) 33 | 34 | rule = 35 | """ 36 | {"substr":["jsonlogic", -1, 1]} 37 | """ 38 | XCTAssertEqual("c", try applyRule(rule, to: nil)) 39 | 40 | rule = 41 | """ 42 | {"substr":["jsonlogic", 4, 5]} 43 | """ 44 | XCTAssertEqual("logic", try applyRule(rule, to: nil)) 45 | 46 | rule = 47 | """ 48 | {"substr":["jsonlogic", -5, 5]} 49 | """ 50 | XCTAssertEqual("logic", try applyRule(rule, to: nil)) 51 | 52 | rule = 53 | """ 54 | {"substr":["jsonlogic", -5, -2]} 55 | """ 56 | XCTAssertEqual("log", try applyRule(rule, to: nil)) 57 | 58 | rule = 59 | """ 60 | {"substr":["jsonlogic", 1, -5]} 61 | """ 62 | XCTAssertEqual("son", try applyRule(rule, to: nil)) 63 | } 64 | 65 | func testSunString_withInvalidLength() { 66 | let rule = 67 | """ 68 | {"substr":["jsonlogic", 1, null]} 69 | """ 70 | XCTAssertNil(try applyRule(rule, to: nil)) 71 | } 72 | 73 | func testSunString_withInvalidStart() { 74 | var rule = 75 | """ 76 | {"substr":["jsonlogic", null, 1]} 77 | """ 78 | XCTAssertNil(try applyRule(rule, to: nil)) 79 | 80 | rule = 81 | """ 82 | {"substr":["jsonlogic", null]} 83 | """ 84 | XCTAssertNil(try applyRule(rule, to: nil)) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Tests/jsonlogicTests/TestUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by Christos Koninis on 3/18/21. 6 | // 7 | 8 | import XCTest 9 | 10 | //Implementation that allows for throwing errors from error handler block 11 | func _XCTAssertThrowsError(_ expression: @autoclosure () throws -> T, 12 | _ message: @autoclosure () -> String = "", 13 | file: StaticString = #file, 14 | line: UInt = #line, 15 | _ errorHandler: (_ error: Swift.Error) throws -> Void) rethrows { 16 | 17 | var iError: Error? 18 | XCTAssertThrowsError(try expression(), message(), file: file, line: line, { aError in 19 | iError = aError 20 | }) 21 | 22 | if let iError = iError { 23 | try errorHandler(iError) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /genenate-xcodeproj.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | swift package generate-xcodeproj 3 | 4 | -------------------------------------------------------------------------------- /json-enum.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "json-enum" 3 | s.version = "1.2.3" 4 | s.summary = "Parsing JSON to Swift enum parsing library" 5 | s.description = "Representing a JSON using an enumerated type makes it easy and type safe." 6 | s.homepage = "https://github.com/advantagefse/json-logic-swift" 7 | s.license = { :type => "MIT", :file => "LICENSE" } 8 | s.author = { "Christos Koninis" => "c.koninis@afse.eu" } 9 | s.source = { :git => "https://github.com/advantagefse/json-logic-swift.git", :tag => 'json-enum-1.2.3' } 10 | 11 | s.ios.deployment_target = '11.0' 12 | s.tvos.deployment_target = '11.0' 13 | s.watchos.deployment_target = '4.0' 14 | s.osx.deployment_target = '10.13' 15 | 16 | s.cocoapods_version = '>= 1.6.1' 17 | s.swift_version = '5' 18 | 19 | s.frameworks = 'Foundation' 20 | 21 | s.source_files = 'Sources/JSON/*.swift' 22 | s.module_name = 'JSON' 23 | 24 | end 25 | -------------------------------------------------------------------------------- /jsonlogic.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "jsonlogic" 3 | s.version = "1.2.4" 4 | s.summary = "A JsonLogic Swift library" 5 | s.description = "A JsonLogic implementation in Swift. JsonLogic is a way to write rules that involve computations in JSON format, these can be applied on JSON data with consistent results. So you can share between server and clients rules in a common format." 6 | s.homepage = "https://github.com/advantagefse/json-logic-swift" 7 | s.license = { :type => "MIT", :file => "LICENSE" } 8 | s.author = { "Christos Koninis" => "c.koninis@afse.eu" } 9 | s.source = { :git => "https://github.com/advantagefse/json-logic-swift.git", :tag => s.version } 10 | 11 | s.ios.deployment_target = '11.0' 12 | s.tvos.deployment_target = '11.0' 13 | s.watchos.deployment_target = '4.0' 14 | s.osx.deployment_target = '10.13' 15 | 16 | s.cocoapods_version = '>= 1.6.1' 17 | s.swift_version = '5' 18 | 19 | s.frameworks = 'Foundation' 20 | 21 | s.source_files = 'Sources/jsonlogic/*.swift' 22 | s.module_name = 'jsonlogic' 23 | s.dependency 'json-enum', '~> 1.2.3' 24 | 25 | end 26 | -------------------------------------------------------------------------------- /run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Run the test suite for all supported swift versions 4 | swift test -Xswiftc -swift-version -Xswiftc 5 5 | swift test -Xswiftc -swift-version -Xswiftc 4.2 6 | swift test -Xswiftc -swift-version -Xswiftc 4 7 | --------------------------------------------------------------------------------