Skip to content

AnyCodableComparable#16

Merged
timkimadobe merged 25 commits intoadobe:mainfrom
timkimadobe:anycodable-comparable2
Dec 20, 2023
Merged

AnyCodableComparable#16
timkimadobe merged 25 commits intoadobe:mainfrom
timkimadobe:anycodable-comparable2

Conversation

@timkimadobe
Copy link
Copy Markdown
Contributor

Note

This PR should be merged after: #15

This PR introduces the concept of the AnyCodableComparable protocol, which allows the JSON comparison methods to automatically convert common Swift and Experience Platform SDK representations of JSON data into AnyCodable format.

The base protocol requires a simple conversion method:

func toAnyCodable() -> AnyCodable?

Conforming types simply implement whatever conversion to AnyCodable makes the most sense for the given type:

extension String: AnyCodableComparable {
    public func toAnyCodable() -> AnyCodable? {
        guard let data = self.data(using: .utf8) else { return nil }
        return try? JSONDecoder().decode(AnyCodable.self, from: data)
    }
}

The list of conforming types in this PR:

  1. Optional
  2. Dictionary
  3. String
  4. AnyCodable (AEP)
  5. Event (AEP)
  6. NetworkRequest (AEP)

The JSON comparison methods accept all types conforming to the new AnyCodableComparable protocol and handle the conversion to AnyCodable. This means that:

  1. Callers of the JSON comparison methods do not have to perform any pre-conversion to AnyCodable before calling the comparison method itself (given the input type conforms to AnyCodableComparable)
    i. The getAnyCodable methods are now redundant and removed

Note that assertEqual does allow for a nil expected value, however assertTypeMatch and assertExactMatch do not allow expected to be nil - users should instead use XCTAssertNil. This is to:

  1. Prevent unexpected nil values due to conversion failures
  2. Make the expectation of nil values more explicit
  3. Reduce boilerplate at the callsite by removing the requirement to pass a valid AnyCodable (and auto emitting a test failure)

Note the reduction of boilerplate:

BEFORE

let expectedJSONString = """
[1, 2]
"""

let actualJSONString = """
["a", "b", 1, 2]
"""

let expected = getAnyCodable(expectedJSONString)!
let actual = getAnyCodable(actualJSONString)!

assertExactMatch(expected: expected, actual: actual, typeMatchPaths: ["[*0]", "[*1]"])

AFTER

let expected = """
[1, 2]
"""

let actual = """
["a", "b", 1, 2]
"""

assertExactMatch(expected: expected, actual: actual, typeMatchPaths: ["[*0]", "[*1]"])

Related Issue

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Refactor AnyCodable assert methods to use new NodeConfig class
Update method docs
Rename helper method to more generic validateJSON
# Conflicts:
#	Sources/NodeConfig.swift
#	Sources/XCTestCase+AnyCodableAsserts.swift
Add additional docs for test case
…nstead of single Bool

Refactor JSON validation to traverse actual for negative validation cases like key must be absent
Refactor assertExactMatch and assertTypeMatch to funnel into same validation method since only initial subtree state is different
Add tests for path options
Copy link
Copy Markdown
Contributor

@cdhoffmann cdhoffmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

# Conflicts:
#	Sources/XCTestCase+AnyCodableAsserts.swift
#	Tests/UnitTests/AnyCodablePathOptionsTests.swift
@timkimadobe timkimadobe merged commit e386a96 into adobe:main Dec 20, 2023
@timkimadobe timkimadobe deleted the anycodable-comparable2 branch December 20, 2023 03:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants