├── .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 |
4 |
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 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/jsonlogic-swift.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/jsonlogic_cli.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
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 | [](https://travis-ci.org/advantagefse/json-logic-swift)
4 | [](https://cocoapods.org/pods/jsonlogic)
5 | [](https://cocoapods.org/pods/jsonlogic)
6 | [](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 |
--------------------------------------------------------------------------------