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
Errors logs improvements #167
Conversation
0316714
to
bf65546
Compare
Sources/Context.swift
Outdated
|
||
init(dictionary: [String: Any]? = nil, environment: Environment? = nil) { | ||
init(dictionary: [String: Any?]? = nil, environment: Environment? = nil) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen this change in multiple pull requests. Wanna split this out into a separate PR for discussion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's in #166 , I just based all other branches on its branch so that tests don't randomly fail, that's why you see them in each pr =)
998a2b5
to
526f05e
Compare
6dbbdcb
to
e9c2e1c
Compare
@kylef this started to fail on swift 3.1 with some creepy compiler error. Maybe we should just drop it already? |
…en highlighted in error message
…nclude and extend nodes
- moved back to single line string literal - fixed calculating string lenght
this resolves warning related to Never type
f6c0920
to
b542927
Compare
Whoa this looks cool. I'd like to +1 here so somebody from the team takes a look :) |
@ilyapuchka Any idea how hard it'd be to rebase/rework this on master for you? |
@djbe I've updated this with the latest master. If you are going to merge any PRs please merge this first. |
Tests/StencilTests/ForNodeSpec.swift
Outdated
@@ -98,15 +98,15 @@ func testForNode() { | |||
|
|||
$0.it("renders the given nodes while filtering items using where expression") { | |||
let nodes: [NodeType] = [VariableNode(variable: "item"), VariableNode(variable: "forloop.counter")] | |||
let `where` = try parseExpression(components: ["item", ">", "1"], tokenParser: TokenParser(tokens: [], environment: Environment())) | |||
let `where` = try parseExpression(components: ["item", ">", "1"], tokenParser: TokenParser(tokens: [], environment: Environment()), token: .text(value: "", at: .unknown)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation?
Tests/StencilTests/ForNodeSpec.swift
Outdated
let node = ForNode(resolvable: Variable("items"), loopVariables: ["item"], nodes: nodes, emptyNodes: [], where: `where`) | ||
try expect(try node.render(context)) == "2132" | ||
} | ||
|
||
$0.it("renders the given empty nodes when all items filtered out with where expression") { | ||
let nodes: [NodeType] = [VariableNode(variable: "item")] | ||
let emptyNodes: [NodeType] = [TextNode(text: "empty")] | ||
let `where` = try parseExpression(components: ["item", "==", "0"], tokenParser: TokenParser(tokens: [], environment: Environment())) | ||
let `where` = try parseExpression(components: ["item", "==", "0"], tokenParser: TokenParser(tokens: [], environment: Environment()), token: .text(value: "", at: .unknown)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation?
Sources/ForTag.swift
Outdated
: nil | ||
|
||
return ForNode(resolvable: resolvable, loopVariables: loopVariables, nodes: forNodes, emptyNodes:emptyNodes, where: `where`) | ||
return ForNode(resolvable: resolvable, loopVariables: loopVariables, nodes: forNodes, emptyNodes:emptyNodes, where: `where`, token: token) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space after the :
.
Sources/ForTag.swift
Outdated
} | ||
|
||
init(resolvable: Resolvable, loopVariables: [String], nodes:[NodeType], emptyNodes:[NodeType], where: Expression? = nil) { | ||
init(resolvable: Resolvable, loopVariables: [String], nodes:[NodeType], emptyNodes:[NodeType], where: Expression? = nil, token: Token? = nil) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space after the :
.
Sources/Lexer.swift
Outdated
lineContent = line | ||
if let rangeOfLine = self.range(of: line), rangeOfLine.contains(range.lowerBound) { | ||
offset = distance(from: rangeOfLine.lowerBound, to: | ||
range.lowerBound) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bizarre spacing here?
Sources/Node.swift
Outdated
} | ||
|
||
|
||
/// Render the collection of nodes in the given context | ||
public func renderNodes(_ nodes:[NodeType], _ context:Context) throws -> String { | ||
return try nodes.map { try $0.render(context) }.joined(separator: "") | ||
return try nodes.map({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those ()
aren't needed for the map
.
Sources/Parser.swift
Outdated
do { | ||
return try FilterExpression(token: filterToken, parser: self) | ||
} catch { | ||
if var error = error as? TemplateSyntaxError, error.token == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to use a guard here? It avoids 1 level of indentation.
@@ -32,9 +39,304 @@ func testEnvironment() { | |||
|
|||
try expect(result) == "here" | |||
} | |||
|
|||
func expectedSyntaxError(token: String, template: Template, description: String) -> TemplateSyntaxError { | |||
let range = template.templateString.range(of: token)! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always avoid implicit unwraps. You can replace this with a guard that falls back to an error with less information if the token isn't found. Or a fatalError
(as this is a test, might as well break early).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer failing here as it is crystal clear what is the reason than pollute the code with boilerplate guards especially considering that this is a test and we don't need graceful error handling or whatever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A guard
with a fatalError
and a message then. It's not because it's a test that it shouldn't be good code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this code is good enough, but I will do that if that's what it takes to merge this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file: String = #file, line: Int = #line, function: String = #function) throws { | ||
let expectedError = expectedSyntaxError(token: token, template: template, description: reason) | ||
|
||
let error = try expect(environment.render(template: template, context: ["names": ["Bob", "Alice"], "name": "Bob"]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both the declaration of this func
as well as this line have some bizarre indentation. This also applies to the similar functions below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is repeated quite a few times. That could be rewritten?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer this to 6 arguments stacked on each other
this can be cleared up sometime later, this PR is big without it
Tests/StencilTests/LexerSpec.swift
Outdated
"%}{{\n" + | ||
"name\n" + | ||
"}}{%\n" + | ||
"endif %}." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation for this last line.
Seeing as you'd rather merge this first, I'll review this one before the others. |
@djbe fixed indentations |
Sources/Environment.swift
Outdated
public init(loader: Loader? = nil, | ||
extensions: [Extension]? = nil, | ||
templateClass: Template.Type = Template.self, | ||
errorReporter: ErrorReporter = SimpleErrorReporter()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, the errorReporter property is only used by context's errorReporter property. But that isn't used anywhere (I may have missed this)?
What is the reason that the Environment and Context should hold the errorReporter? If I understand how this is intended to be used, a consumer of the library would catch an error and pass it to the errorReporter themselves? In that case I think it would make sense to remove the property from Environment and Context leaving the consumer free to create their own ErrorReporter as desired. Decoupling these a little bit.
@kylef you'd like to add something? |
Seeing as there's no more feedback, and this PR is GTM for me, we can go on to the next PRs 🎉 |
Original PR #146
Example error logs: