Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of CoreFoundation import #7

Merged
merged 7 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
}
}
Loading