Skip to content

Commit

Permalink
Merge pull request #7 from adam-fowler/latest-foundation
Browse files Browse the repository at this point in the history
Get rid of CoreFoundation import
  • Loading branch information
adam-fowler authored Aug 1, 2024
2 parents 0d9765c + 68ae192 commit 3796a32
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 68 deletions.
17 changes: 9 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ on:

jobs:
macos:
runs-on: macOS-latest
runs-on: macOS-13
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: SPM tests
run: swift test --enable-code-coverage --sanitize=thread
run: swift test --enable-code-coverage
- name: Convert coverage files
run: |
xcrun llvm-cov export -format "lcov" \
.build/debug/jmespath.swiftPackageTests.xctest/Contents/MacOs/jmespath.swiftPackageTests \
-ignore-filename-regex="\/Tests\/" \
-instr-profile=.build/debug/codecov/default.profdata > info.lcov
- name: Upload to codecov.io
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v4
with:
file: info.lcov

Expand All @@ -36,14 +36,15 @@ jobs:
strategy:
matrix:
tag:
- swift:5.6
- swift:5.7
- swift:5.8
- swift:5.9
- swift:5.10
- swiftlang/swift:nightly-6.0-jammy
container:
image: ${{ matrix.tag }}
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Test
Expand All @@ -55,6 +56,6 @@ jobs:
-ignore-filename-regex="\/Tests\/" \
-instr-profile .build/debug/codecov/default.profdata > info.lcov
- name: Upload to codecov.io
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v4
with:
file: info.lcov
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/.build
/.swiftpm
/.vscode
/.devcontainer
/Packages
/*.xcodeproj
/docs
Expand Down
35 changes: 23 additions & 12 deletions Sources/JMESPath/Variable.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import CoreFoundation
import Foundation

public typealias JMESArray = [Any]
Expand Down Expand Up @@ -27,7 +26,7 @@ public enum JMESVariable {
case let number as NSNumber:
// both booleans and integer/float point types can be converted to a `NSNumber`
// We have to check to see the type id to see if it is a boolean
if CFGetTypeID(number) == CFBooleanGetTypeID() {
if type(of: number) == Self.nsNumberBoolType {
self = .boolean(number.boolValue)
} else {
self = .number(number)
Expand Down Expand Up @@ -56,7 +55,9 @@ public enum JMESVariable {
case .dictionary:
var object: JMESObject = [:]
var index: Int = 0
while let key = mirror.descendant(index, "key") as? String, let value = mirror.descendant(index, "value") {
while let key = mirror.descendant(index, "key") as? String,
let value = mirror.descendant(index, "value")
{
object[key] = Self.unwrap(value) ?? NSNull()
index += 1
}
Expand Down Expand Up @@ -115,12 +116,18 @@ public enum JMESVariable {
case .boolean(let bool):
return String(describing: bool)
case .array(let array):
guard let jsonData = try? JSONSerialization.data(withJSONObject: array, options: [.fragmentsAllowed]) else {
guard
let jsonData = try? JSONSerialization.data(
withJSONObject: array, options: [.fragmentsAllowed])
else {
return nil
}
return String(decoding: jsonData, as: Unicode.UTF8.self)
case .object(let object):
guard let jsonData = try? JSONSerialization.data(withJSONObject: object, options: [.fragmentsAllowed]) else {
guard
let jsonData = try? JSONSerialization.data(
withJSONObject: object, options: [.fragmentsAllowed])
else {
return nil
}
return String(decoding: jsonData, as: Unicode.UTF8.self)
Expand Down Expand Up @@ -148,12 +155,12 @@ public enum JMESVariable {
public func isSameType(as variable: JMESVariable) -> Bool {
switch (self, variable) {
case (.null, .null),
(.string, .string),
(.boolean, .boolean),
(.number, .number),
(.array, .array),
(.object, .object),
(.expRef, .expRef):
(.string, .string),
(.boolean, .boolean),
(.number, .number),
(.array, .array),
(.object, .object),
(.expRef, .expRef):
return true
default:
return false
Expand Down Expand Up @@ -259,6 +266,8 @@ public enum JMESVariable {
guard let first = mirror.children.first else { return nil }
return first.value
}

fileprivate static var nsNumberBoolType = type(of: NSNumber(value: true))
}

extension JMESVariable: Equatable {
Expand Down Expand Up @@ -304,7 +313,9 @@ extension JMESObject {
fileprivate func equalTo(_ rhs: JMESObject) -> Bool {
guard self.count == rhs.count else { return false }
for element in self {
guard let rhsValue = rhs[element.key], JMESVariable(from: rhsValue) == JMESVariable(from: element.value) else {
guard let rhsValue = rhs[element.key],
JMESVariable(from: rhsValue) == JMESVariable(from: element.value)
else {
return false
}
}
Expand Down
107 changes: 59 additions & 48 deletions Tests/JMESPathTests/ComplianceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
//

import Foundation
import XCTest

@testable import JMESPath

import Foundation
#if os(Linux)
import FoundationNetworking
import FoundationNetworking
#endif
@testable import JMESPath
import XCTest

public struct AnyDecodable: Decodable {
public let value: Any
Expand All @@ -22,8 +22,8 @@ public struct AnyDecodable: Decodable {
}
}

public extension AnyDecodable {
init(from decoder: Decoder) throws {
extension AnyDecodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()

if container.decodeNil() {
Expand All @@ -43,7 +43,8 @@ public extension AnyDecodable {
} else if let dictionary = try? container.decode([String: AnyDecodable].self) {
self.init(dictionary.mapValues { $0.value })
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "AnyDecodable value cannot be decoded")
throw DecodingError.dataCorruptedError(
in: container, debugDescription: "AnyDecodable value cannot be decoded")
}
}
}
Expand All @@ -67,7 +68,7 @@ final class ComplianceTests: XCTestCase {
@available(iOS 11.0, tvOS 11.0, watchOS 5.0, *)
func run() throws {
for c in self.cases {
if let _ = c.bench {
if c.bench != nil {
self.testBenchmark(c)
} else if let error = c.error {
self.testError(c, error: error)
Expand Down Expand Up @@ -106,11 +107,13 @@ final class ComplianceTests: XCTestCase {
let expression = try JMESExpression.compile(c.expression)

let resultJson: String? = try result.map {
let data = try JSONSerialization.data(withJSONObject: $0, options: [.fragmentsAllowed, .sortedKeys])
let data = try JSONSerialization.data(
withJSONObject: $0, options: [.fragmentsAllowed, .sortedKeys])
return String(decoding: data, as: Unicode.UTF8.self)
}
if let value = try expression.search(object: self.given.value) {
let valueData = try JSONSerialization.data(withJSONObject: value, options: [.fragmentsAllowed, .sortedKeys])
let valueData = try JSONSerialization.data(
withJSONObject: value, options: [.fragmentsAllowed, .sortedKeys])
let valueJson = String(decoding: valueData, as: Unicode.UTF8.self)
XCTAssertEqual(resultJson, valueJson)
} else {
Expand All @@ -124,7 +127,8 @@ final class ComplianceTests: XCTestCase {
@available(iOS 11.0, tvOS 11.0, watchOS 5.0, *)
func output(_ c: Case, expected: String?, result: String?) {
if expected != result {
let data = try! JSONSerialization.data(withJSONObject: self.given.value, options: [.fragmentsAllowed, .sortedKeys])
let data = try! JSONSerialization.data(
withJSONObject: self.given.value, options: [.fragmentsAllowed, .sortedKeys])
let givenJson = String(decoding: data, as: Unicode.UTF8.self)
if let comment = c.comment {
print("Comment: \(comment)")
Expand All @@ -137,13 +141,20 @@ final class ComplianceTests: XCTestCase {
}
}

func testCompliance(name: String, ignoring: [String] = []) throws {
let url = URL(string: "https://raw.githubusercontent.com/jmespath/jmespath.test/master/tests/\(name).json")!
try testCompliance(url: url, ignoring: ignoring)
func testCompliance(name: String, ignoring: [String] = []) async throws {
let url = URL(
string:
"https://raw.githubusercontent.com/jmespath/jmespath.test/master/tests/\(name).json"
)!
try await testCompliance(url: url, ignoring: ignoring)
}

func testCompliance(url: URL, ignoring: [String] = []) throws {
let data = try Data(contentsOf: url)
func testCompliance(url: URL, ignoring: [String] = []) async throws {
#if compiler(>=6.0)
let (data, _) = try await URLSession.shared.data(from: url, delegate: nil)
#else
let data = try Data(contentsOf: url)
#endif
let tests = try JSONDecoder().decode([ComplianceTest].self, from: data)

if #available(iOS 11.0, tvOS 11.0, watchOS 5.0, *) {
Expand All @@ -153,67 +164,67 @@ final class ComplianceTests: XCTestCase {
}
}

func testBasic() throws {
try self.testCompliance(name: "basic")
func testBasic() async throws {
try await self.testCompliance(name: "basic")
}

func testBenchmarks() throws {
try self.testCompliance(name: "benchmarks")
func testBenchmarks() async throws {
try await self.testCompliance(name: "benchmarks")
}

func testBoolean() throws {
try self.testCompliance(name: "boolean")
func testBoolean() async throws {
try await self.testCompliance(name: "boolean")
}

func testCurrent() throws {
try self.testCompliance(name: "current")
func testCurrent() async throws {
try await self.testCompliance(name: "current")
}

func testEscape() throws {
try self.testCompliance(name: "escape")
func testEscape() async throws {
try await self.testCompliance(name: "escape")
}

func testFilters() throws {
try self.testCompliance(name: "filters")
func testFilters() async throws {
try await self.testCompliance(name: "filters")
}

func testFunctions() throws {
try self.testCompliance(name: "functions")
func testFunctions() async throws {
try await self.testCompliance(name: "functions")
}

func testIdentifiers() throws {
try self.testCompliance(name: "identifiers")
func testIdentifiers() async throws {
try await self.testCompliance(name: "identifiers")
}

func testIndices() throws {
try self.testCompliance(name: "indices")
func testIndices() async throws {
try await self.testCompliance(name: "indices")
}

func testLiteral() throws {
try self.testCompliance(name: "literal")
func testLiteral() async throws {
try await self.testCompliance(name: "literal")
}

func testMultiSelect() throws {
try self.testCompliance(name: "multiselect")
func testMultiSelect() async throws {
try await self.testCompliance(name: "multiselect")
}

func testPipe() throws {
try self.testCompliance(name: "pipe")
func testPipe() async throws {
try await self.testCompliance(name: "pipe")
}

func testSlice() throws {
try self.testCompliance(name: "slice")
func testSlice() async throws {
try await self.testCompliance(name: "slice")
}

func testSyntax() throws {
try self.testCompliance(name: "syntax")
func testSyntax() async throws {
try await self.testCompliance(name: "syntax")
}

func testUnicode() throws {
try self.testCompliance(name: "unicode")
func testUnicode() async throws {
try await self.testCompliance(name: "unicode")
}

func testWildcards() throws {
try self.testCompliance(name: "wildcard")
func testWildcards() async throws {
try await self.testCompliance(name: "wildcard")
}
}

0 comments on commit 3796a32

Please sign in to comment.