-
-
Notifications
You must be signed in to change notification settings - Fork 16
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
Correct subtest placement #50
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,18 @@ | |
*/ | ||
package org.tap4j.parser; | ||
|
||
import org.tap4j.model.BailOut; | ||
import org.tap4j.model.Comment; | ||
import org.tap4j.model.Footer; | ||
import org.tap4j.model.Header; | ||
import org.tap4j.model.Plan; | ||
import org.tap4j.model.TapElement; | ||
import org.tap4j.model.TapElementFactory; | ||
import org.tap4j.model.TestResult; | ||
import org.tap4j.model.TestSet; | ||
import org.tap4j.model.Text; | ||
import org.yaml.snakeyaml.Yaml; | ||
|
||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.FileNotFoundException; | ||
|
@@ -38,18 +50,6 @@ | |
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
import org.tap4j.model.BailOut; | ||
import org.tap4j.model.Comment; | ||
import org.tap4j.model.Footer; | ||
import org.tap4j.model.Header; | ||
import org.tap4j.model.Plan; | ||
import org.tap4j.model.TapElement; | ||
import org.tap4j.model.TapElementFactory; | ||
import org.tap4j.model.TestResult; | ||
import org.tap4j.model.TestSet; | ||
import org.tap4j.model.Text; | ||
import org.yaml.snakeyaml.Yaml; | ||
|
||
/** | ||
* TAP 13 parser. | ||
* | ||
|
@@ -72,7 +72,7 @@ public class Tap13Parser implements Parser { | |
* Stack of stream status information bags. Every bag stores state of the parser | ||
* related to certain indentation level. This is to support subtest feature. | ||
*/ | ||
private Stack<StreamStatus> states = new Stack<StreamStatus>(); | ||
private Stack<StreamStatus> states = new Stack<>(); | ||
|
||
/** | ||
* The current state. | ||
|
@@ -97,6 +97,11 @@ public class Tap13Parser implements Parser { | |
*/ | ||
private boolean enableSubtests = true; | ||
|
||
/** | ||
* A stack that holds subtests for which we don't know exact parent yet. | ||
*/ | ||
private Stack<StreamStatus> subStack = new Stack<>(); | ||
|
||
/** | ||
* Parser Constructor. | ||
* | ||
|
@@ -280,31 +285,24 @@ public void parseLine(String tapLine) { | |
baseIndentation = indentation; | ||
} | ||
|
||
if (indentation != state.getIndentationLevel()) { // indentation changed | ||
StreamStatus prevState = null; | ||
if (indentation != state.getIndentationLevel() && enableSubtests) { // indentation changed | ||
|
||
if (indentation > state.getIndentationLevel()) { | ||
StreamStatus parentState = state; | ||
int prevIndent = state.getIndentationLevel(); | ||
pushState(indentation); // make room for children | ||
|
||
TapElement lastParentElement = parentState.getLastParsedElement(); | ||
if (lastParentElement instanceof TestResult) { | ||
final TestResult lastTestResult = (TestResult) lastParentElement; | ||
// whatever test set comes should be attached to parent | ||
if (lastTestResult.getSubtest() == null && this.enableSubtests) { | ||
lastTestResult.setSubtest(state.getTestSet()); | ||
state.attachedToParent = true; | ||
} | ||
} | ||
if (indentation - prevIndent > 4) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Well, specification is not the strong point of TAP at all... I see at least a long conversation at TestAnything/Specification#2. But the thing is, all origin sources of truth(e.g. Perl) are using exact four spaces, not de jure, but de facto standard. It is up to you, of course, but I think If someone is doing weird indentation, it is theirs thing to patch.
Yes, We cannot use
and
That's why we are checking exact more than 4 spaces. |
||
subStack.push(state); | ||
} else { | ||
// going down | ||
do { | ||
StreamStatus prevState = state; | ||
if (states.peek().getIndentationLevel() == indentation) { | ||
prevState = state; | ||
state = states.pop(); | ||
if (!prevState.attachedToParent && this.enableSubtests) { | ||
state.looseSubtests = prevState.getTestSet(); | ||
} | ||
// there could be more than one level diff | ||
} while (indentation < state.getIndentationLevel()); | ||
} else { | ||
state = new StreamStatus(); | ||
state.setIndentationLevel(indentation); | ||
subStack.push(state); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -343,7 +341,7 @@ public void parseLine(String tapLine) { | |
|
||
final TestResult testResult = (TestResult) tapElement; | ||
if (testResult.getTestNumber() == 0) { | ||
if (state.getTestSet().getPlan() != null && state.isPlanBeforeTestResult() == false) { | ||
if (state.getTestSet().getPlan() != null && !state.isPlanBeforeTestResult()) { | ||
return; // done testing mark | ||
} | ||
if (state.getTestSet().getPlan() != null && | ||
|
@@ -354,9 +352,21 @@ public void parseLine(String tapLine) { | |
} | ||
|
||
state.getTestSet().addTestResult(testResult); | ||
if (state.looseSubtests != null && this.enableSubtests) { | ||
testResult.setSubtest(state.looseSubtests); | ||
state.looseSubtests = null; | ||
|
||
if (prevState != null && enableSubtests) { | ||
state.getTestSet().getTestResults().get( | ||
state.getTestSet().getNumberOfTestResults() - 1) | ||
.setSubtest(prevState.getTestSet()); | ||
} | ||
|
||
if (indentation == 0 && enableSubtests) { | ||
TestResult currLast = state.getTestSet().getTestResults().get( | ||
state.getTestSet().getNumberOfTestResults() - 1); | ||
while (!subStack.empty()) { | ||
StreamStatus nextLevel = subStack.pop(); | ||
currLast.setSubtest(nextLevel.getTestSet()); | ||
currLast = nextLevel.getTestSet().getTestResults().get(0); | ||
} | ||
} | ||
|
||
} else if (tapElement instanceof Footer) { | ||
|
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.
Any reason why we should remove tabs here too?
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.
The thing is
\s
includes\t
, so it's redundant to use alternating matching between them. See https://docs.oracle.com/javase/tutorial/essential/regex/pre_char_classes.htmlThere 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.
And this minor issue is present in other regexes too, but I didn't fix it, because not sure if wanted.
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.
Just past midnight here, so the new day barely started and I can proudly say Today-I-Learned.
Had no idea they were redundant. I've been using both in Perl, shell, java... might have a few places to fix besides tap4j.
This change is definitely wanted. But we can fix in another issue if that's easier.
Thanks!!!
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.
Also,
*
takes exactly zero or more elements, so you can omit redundant?
.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.
Right. I think you are talking about this part:
([^#]*)?
I thought that it would resolve
[^#]*
as zero or more of[^#]
in a group()?
. And so the group was receiving the?
, and thus would appear zero or at most once?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 wrote about e.g.
((\\s|\\t)*)?
(putting \t symbol aside) - in this case,?
is redundant.We capture "zero or more space characters" for "zero or one time". It could be meaningful with
(.+)?
("one or more any character" could or could not occur), but it's roughly a wordy equivalent of just(.*)
.That's what I meant.
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.
Aahh! Sure. You fixed that one already, but I agree for the remaining regular expressions. Gonna start thinking a bit more when writing regexes now :)