added recursive resolution for superclass properties
This commit is contained in:
@@ -100,15 +100,9 @@ public struct Variable : Equatable, Resolvable {
|
|||||||
current = object.value(forKey: bit)
|
current = object.value(forKey: bit)
|
||||||
#endif
|
#endif
|
||||||
} else if let value = current {
|
} else if let value = current {
|
||||||
let mirror = Mirror(reflecting: value)
|
current = Mirror(reflecting: value).getValue(for: bit)
|
||||||
current = mirror.descendant(bit)
|
|
||||||
|
|
||||||
if current == nil {
|
if current == nil {
|
||||||
return nil
|
return nil
|
||||||
// mirror returns non-nil value even for nil-containing properties
|
|
||||||
// so we have to check if its value is actually nil or not
|
|
||||||
} else if let current = current, String(describing: current) == "nil" {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
@@ -179,3 +173,18 @@ func parseFilterComponents(token: String) -> (String, [Variable]) {
|
|||||||
.map { Variable($0) }
|
.map { Variable($0) }
|
||||||
return (name, variables)
|
return (name, variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Mirror {
|
||||||
|
func getValue(for key: String) -> Any? {
|
||||||
|
let result = descendant(key)
|
||||||
|
if result == nil {
|
||||||
|
// go through inheritance chain to reach superclass properties
|
||||||
|
return superclassMirror?.getValue(for: key)
|
||||||
|
} else if let result = result, String(describing: result) == "nil" {
|
||||||
|
// mirror returns non-nil value even for nil-containing properties
|
||||||
|
// so we have to check if its value is actually nil or not
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ import Spectre
|
|||||||
|
|
||||||
|
|
||||||
#if os(OSX)
|
#if os(OSX)
|
||||||
@objc class Object : NSObject {
|
@objc class Superclass: NSObject {
|
||||||
|
let name = "Foo"
|
||||||
|
}
|
||||||
|
@objc class Object : Superclass {
|
||||||
let title = "Hello World"
|
let title = "Hello World"
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -17,6 +20,13 @@ fileprivate struct Article {
|
|||||||
let author: Person
|
let author: Person
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate class WebSite {
|
||||||
|
let url: String = "blog.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate class Blog: WebSite {
|
||||||
|
let articles: [Article] = [Article(author: Person(name: "Kyle"))]
|
||||||
|
}
|
||||||
|
|
||||||
func testVariable() {
|
func testVariable() {
|
||||||
describe("Variable") {
|
describe("Variable") {
|
||||||
@@ -35,6 +45,7 @@ func testVariable() {
|
|||||||
#if os(OSX)
|
#if os(OSX)
|
||||||
context["object"] = Object()
|
context["object"] = Object()
|
||||||
#endif
|
#endif
|
||||||
|
context["blog"] = Blog()
|
||||||
|
|
||||||
$0.it("can resolve a string literal with double quotes") {
|
$0.it("can resolve a string literal with double quotes") {
|
||||||
let variable = Variable("\"name\"")
|
let variable = Variable("\"name\"")
|
||||||
@@ -122,6 +133,25 @@ func testVariable() {
|
|||||||
let result = try variable.resolve(context) as? String
|
let result = try variable.resolve(context) as? String
|
||||||
try expect(result) == "Hello World"
|
try expect(result) == "Hello World"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$0.it("can resolve a superclass value via KVO") {
|
||||||
|
let variable = Variable("object.name")
|
||||||
|
let result = try variable.resolve(context) as? String
|
||||||
|
try expect(result) == "Foo"
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
$0.it("can resolve a value via reflection") {
|
||||||
|
let variable = Variable("blog.articles.0.author.name")
|
||||||
|
let result = try variable.resolve(context) as? String
|
||||||
|
try expect(result) == "Kyle"
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("can resolve a superclass value via reflection") {
|
||||||
|
let variable = Variable("blog.url")
|
||||||
|
let result = try variable.resolve(context) as? String
|
||||||
|
try expect(result) == "blog.com"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user