From 8c57f26e9938eba4ed82d40cb56d2ccc3943f37e Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Wed, 1 May 2019 01:37:45 -0600 Subject: [PATCH] More informative failure for example parsing --- .../TheIntercept/main.hank | 0 .../TheIntercept/original.ink | 0 .../TheIntercept/partialdebugtest1.hlog | 0 .../TheIntercept/partialtest1.hlog | 0 hank/Parser.hx | 15 +++++++++----- hank/StoryTestCase.hx | 20 +++++++++++++------ tests/ParserTest.hx | 2 ++ 7 files changed, 26 insertions(+), 11 deletions(-) rename {old-examples => examples}/TheIntercept/main.hank (100%) rename {old-examples => examples}/TheIntercept/original.ink (100%) rename {old-examples => examples}/TheIntercept/partialdebugtest1.hlog (100%) rename {old-examples => examples}/TheIntercept/partialtest1.hlog (100%) diff --git a/old-examples/TheIntercept/main.hank b/examples/TheIntercept/main.hank similarity index 100% rename from old-examples/TheIntercept/main.hank rename to examples/TheIntercept/main.hank diff --git a/old-examples/TheIntercept/original.ink b/examples/TheIntercept/original.ink similarity index 100% rename from old-examples/TheIntercept/original.ink rename to examples/TheIntercept/original.ink diff --git a/old-examples/TheIntercept/partialdebugtest1.hlog b/examples/TheIntercept/partialdebugtest1.hlog similarity index 100% rename from old-examples/TheIntercept/partialdebugtest1.hlog rename to examples/TheIntercept/partialdebugtest1.hlog diff --git a/old-examples/TheIntercept/partialtest1.hlog b/examples/TheIntercept/partialtest1.hlog similarity index 100% rename from old-examples/TheIntercept/partialtest1.hlog rename to examples/TheIntercept/partialtest1.hlog diff --git a/hank/Parser.hx b/hank/Parser.hx index ce5849e..3bef1d1 100644 --- a/hank/Parser.hx +++ b/hank/Parser.hx @@ -120,12 +120,16 @@ class Parser { } /** Split the given line into n tokens, throwing an error if there are any number of tokens other than n **/ - static function lineTokens(buffer: HankBuffer, n: Int, position: HankBuffer.Position, rtrim: Bool = true): Array { + static function lineTokens(buffer: HankBuffer, n: Int, position: HankBuffer.Position, throwOnMismatch: Bool = true, rtrim: Bool = true): Array { var line = buffer.takeLine().unwrap(); if (rtrim) line = line.rtrim(); var tokens = line.split(' '); if (tokens.length != n) { - throw 'Wrong number of tokens at ${position}: ${tokens.length} tokens provided--should be ${n}.\nLine: `${line}`\nTokens: ${tokens}'; + if (throwOnMismatch) { + throw 'Wrong number of tokens at ${position}: ${tokens.length} tokens provided--should be ${n}.\nLine: `${line}`\nTokens: ${tokens}'; + } else { + return tokens.slice(0, n); + } } return tokens; } @@ -138,7 +142,7 @@ class Parser { static function divert(buffer: HankBuffer, position: HankBuffer.Position) : ExprType { buffer.drop('->'); buffer.skipWhitespace(); - var tokens = lineTokens(buffer, 1, position, true); + var tokens = lineTokens(buffer, 1, position, true, true); return EDivert(tokens[0]); } @@ -148,19 +152,20 @@ class Parser { static function knot(buffer: HankBuffer, position: HankBuffer.Position) : ExprType { buffer.drop('=='); + // Allow 3 equals signs like some Ink scripts use if (buffer.peekAhead(0, 1) == '=') { buffer.drop('='); } buffer.skipWhitespace(); - var tokens = lineTokens(buffer, 1, position); + var tokens = lineTokens(buffer, 1, position, false); // Don't throw if there's another token, like === return EKnot(tokens[0]); } static function stitch(buffer: HankBuffer, position: HankBuffer.Position) : ExprType { buffer.drop('='); buffer.skipWhitespace(); - var tokens = lineTokens(buffer, 1, position); + var tokens = lineTokens(buffer, 1, position, false); return EStitch(tokens[0]); } diff --git a/hank/StoryTestCase.hx b/hank/StoryTestCase.hx index 5b09911..34e7557 100644 --- a/hank/StoryTestCase.hx +++ b/hank/StoryTestCase.hx @@ -57,7 +57,15 @@ class StoryTestCase extends utest.Test { transcriptLines.remove(transcriptLines[0]); } - var story: Story = Story.FromFile(storyFile, randomSeed); + var story: Story = null; + try { + story = Story.FromFile(storyFile, randomSeed); + } catch (e: Dynamic) { + trace('Error parsing $storyFile: $e'); + trace(CallStack.exceptionStack()); + Assert.fail(); + return; + } story.hInterface.addVariable("DEBUG", debug); @@ -65,15 +73,15 @@ class StoryTestCase extends utest.Test { while (i < transcriptLines.length) { var line = transcriptLines[i]; lastTranscriptLine = i; - var frame = story.nextFrame(); - // TODO Allow white-box story testing through variable checks prefixed with # -/* + // Allow white-box story testing through expression value checks prefixed with # if (line.startsWith("#")) { var parts = line.substr(1).trim().split(':'); - HankAssert.equals(parts[1].trim(), Std.string(story.hInterface.resolve(parts[0], ''))); + HankAssert.equals(parts[1].trim(), story.hInterface.evaluateExpr(parts[0], story.nodeScopes)); + i +=1; + continue; } -*/ + var frame = story.nextFrame(); if (line.startsWith("*")) { // Collect the expected set of choices from the transcript. var choices = new Array(); diff --git a/tests/ParserTest.hx b/tests/ParserTest.hx index cdc678b..d3d83cd 100644 --- a/tests/ParserTest.hx +++ b/tests/ParserTest.hx @@ -8,6 +8,8 @@ import hank.HankAssert; /** These tests are hard to maintain, and may not be relevant now that parsing largely works + + Maybe a better way to test parsing would be to execute individual lines?? idk **/ class ParserTest extends utest.Test { var ast: HankAST;