diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Lookup.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Lookup.xcscheme index dc772ba..a16930b 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/Lookup.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/Lookup.xcscheme @@ -40,7 +40,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> diff --git a/Sources/Lookup/Lookup.swift b/Sources/Lookup/Lookup.swift index 62a5b3c..b4b607b 100644 --- a/Sources/Lookup/Lookup.swift +++ b/Sources/Lookup/Lookup.swift @@ -3,7 +3,9 @@ import Foundation // MARK: - extension Array Helper merging multi lookup into one lookup public extension Array where Element == Lookup { - /// Merging multi rawDict into one + /// Merging multi `rawDict` into one + /// ⚠️ Only support `Dictionary` + /// /// - Parameter uniquingKeysWith: uniquing keys with conflict /// - Returns: Merged `Lookup` func merging(uniquingKeysWith: (Any, Any) -> Any) -> Lookup { @@ -30,7 +32,6 @@ fileprivate func unwrap(_ object: Any) -> Any { switch object { case let lookup as Lookup: return unwrap(lookup.object) - case let number as NSNumber: return number case let str as String: @@ -147,7 +148,6 @@ public struct Lookup: Swift.CustomStringConvertible, Swift.CustomDebugStringConv } } - public subscript (dynamicMember dynamicMember: String) -> Lookup { if dynamicMember.contains(".") { var keys = dynamicMember.components(separatedBy: ".") diff --git a/Sources/Lookup/LookupEnum.swift b/Sources/Lookup/LookupEnum.swift index e8595b5..66480c4 100644 --- a/Sources/Lookup/LookupEnum.swift +++ b/Sources/Lookup/LookupEnum.swift @@ -1,7 +1,4 @@ // -// File.swift -// -// // Created by iww on 2022/4/6. // @@ -10,9 +7,7 @@ import Foundation /// LookupEnum /// /// Default implemention `Int` and `String` -public protocol LookupEnum { - var lookupRawValue: Any { get } -} +public protocol LookupEnum: LookupRawValue { } extension LookupEnum where Self: RawRepresentable, Self.RawValue == Int { var lookupRawValue: Any { diff --git a/Sources/Lookup/LookupRawValue.swift b/Sources/Lookup/LookupRawValue.swift new file mode 100644 index 0000000..21aaba5 --- /dev/null +++ b/Sources/Lookup/LookupRawValue.swift @@ -0,0 +1,16 @@ +// +// Created by iww on 2022/4/6. +// + +import Foundation + +public protocol LookupRawValue { + var lookupRawValue: Any { get } +} + +extension Date: LookupRawValue { + + public var lookupRawValue: Any { + self.timeIntervalSince1970 + } +} diff --git a/Sources/Lookup/Mirrors.swift b/Sources/Lookup/Mirrors.swift index 1cf4289..988ddeb 100644 --- a/Sources/Lookup/Mirrors.swift +++ b/Sources/Lookup/Mirrors.swift @@ -5,20 +5,23 @@ import Foundation func canMirrorInto(_ reflecting: Any?) -> Bool { + if let _ = reflecting as? LookupRawValue { + return false + } guard let ref = reflecting else { return false } let mirror = Mirror(reflecting: ref) guard let displayStyle = mirror.displayStyle else { return false } - return displayStyle == .class || displayStyle == .struct + return (displayStyle == .class || displayStyle == .struct) } func mirrorValue(_ value: Any) -> Any { + if let lookupRawValue = value as? LookupRawValue { + return lookupRawValue.lookupRawValue + } let mirror = Mirror(reflecting: value) guard mirror.displayStyle == .enum else { return value } - if let lookupEnum = value as? LookupEnum { - return lookupEnum.lookupRawValue - } return "\(value)" } diff --git a/Tests/LookupTests/LookupTests.swift b/Tests/LookupTests/LookupTests.swift index 43137c5..34ffa17 100644 --- a/Tests/LookupTests/LookupTests.swift +++ b/Tests/LookupTests/LookupTests.swift @@ -1,6 +1,7 @@ import Quick import Nimble @testable import Lookup +import Foundation enum AnimalType { case dog, cat @@ -21,13 +22,17 @@ struct Animal { let intType: AnimalIntType } -final class AnimalClass { +open class AnimalClass { let name: String = "Dog" let age: Int = 4 let type: AnimalType = .dog let intType: AnimalIntType = .dog } +final class Species: AnimalClass { + let start: Date = Date() +} + final class LookupTests: QuickSpec { override func spec() { @@ -77,6 +82,16 @@ final class LookupTests: QuickSpec { expect(lookup.type.string) == "dog" expect(lookup.intType.int) == 0 } + + it("has super class's initialization") { + let species = Species() + let lookup = Lookup(species) + expect(lookup.name.string) == "Dog" + expect(lookup.age.int) == 4 + expect(lookup.type.string) == "dog" + expect(lookup.intType.int) == 0 + expect(lookup.start.double).toNot(beNil()) + } } context("test chain value") { @@ -169,6 +184,42 @@ final class LookupTests: QuickSpec { } } + context("test merge lookup") { + it("merge dictionary lookups") { + let lookup1 = Lookup(["name": "Lookup", "age": 3]) + let lookup2 = Lookup(["age": 1]) + let merged = [lookup1, lookup2].merging(uniquingKeysWith: { $1 }) + expect(merged.name.string) == "Lookup" + expect(merged.age.int) == 1 + } + + // MARK: NOT SUPOORT NOW + xit("merge array lookups") { + //let lookup1 = Lookup([1, 2, 3]) + //let lookup2 = Lookup([4, 5, 6]) + //let merged = [lookup1, lookup2].merging(uniquingKeysWith: { $1 }) + } + } + + context("test codable") { + it("encode") { + let jsonString = "{\"name\": \"Lookup\", \"age\": 1, \"list\": \"[1,2,3]\"}" + let lookup = try JSONDecoder().decode(Lookup.self, from: jsonString.data(using: .utf8)!) + expect(lookup.name.string) == "Lookup" + expect(lookup.age.int) == 1 + expect(lookup.list.0.int) == 1 + expect(lookup.list.1.int) == 2 + expect(lookup.list.2.int) == 3 + + let jsonData = try JSONEncoder().encode(lookup) + let _jsonString = String(data: jsonData, encoding: .utf8) + expect(_jsonString).toNot(beNil()) + let rLookup = Lookup(_jsonString!) + expect(rLookup.name.string) == "Lookup" + expect(rLookup.age.int) == 1 + } + } + // MARK: ⚠️ NOT SUPPORT NUMBER KEY NOW context("test dictionary with number key") { it("test") {