Skip to content

Commit

Permalink
fix: accessing optional properties through reflection (#204)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyapuchka authored and kylef committed Apr 5, 2018
1 parent 9184720 commit 8fa0bd2
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- Fixed checking dictionary values for nil in `default` filter
- Fixed comparing string variables with string literals, in Swift 4 string literals became `Substring` and thus couldn't be directly compared to strings.
- Integer literals now resolve into Int values, not Float
- Fixed accessing properties of optional properties via reflection


## 0.10.1
Expand Down
30 changes: 26 additions & 4 deletions Sources/Variable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,33 @@ extension Mirror {
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
} else if let result = result {
guard String(describing: result) != "nil" else {
// 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
}
if let result = (result as? AnyOptional)?.wrapped {
return result
} else {
return result
}
}
return result
}
}

protocol AnyOptional {
var wrapped: Any? { get }
}

extension Optional: AnyOptional {
var wrapped: Any? {
switch self {
case let .some(value): return value
case .none: return nil
}
}
}


7 changes: 7 additions & 0 deletions Tests/StencilTests/VariableSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fileprivate class WebSite {

fileprivate class Blog: WebSite {
let articles: [Article] = [Article(author: Person(name: "Kyle"))]
let featuring: Article? = Article(author: Person(name: "Jhon"))
}

func testVariable() {
Expand Down Expand Up @@ -160,5 +161,11 @@ func testVariable() {
try expect(result) == "blog.com"
}

$0.it("can resolve optional variable property using reflection") {
let variable = Variable("blog.featuring.author.name")
let result = try variable.resolve(context) as? String
try expect(result) == "Jhon"
}

}
}

0 comments on commit 8fa0bd2

Please sign in to comment.