gherkin 1.0.3-java → 1.0.4-java
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +15 -6
- data/README.rdoc +23 -0
- data/Rakefile +1 -0
- data/VERSION.yml +1 -1
- data/features/step_definitions/gherkin_steps.rb +1 -1
- data/features/step_definitions/{pretty_printer_steps.rb → pretty_listener_step.rb} +2 -2
- data/gherkin.gemspec +24 -35
- data/java/Gherkin.iml +8 -14
- data/java/src/{gherkin → main/java/gherkin}/lexer/.gitignore +0 -0
- data/lib/gherkin.rb +1 -1
- data/lib/gherkin/c_lexer.rb +2 -2
- data/lib/gherkin/{format → formatter}/argument.rb +1 -1
- data/lib/gherkin/{tools → formatter}/colors.rb +1 -1
- data/lib/gherkin/{format → formatter}/monochrome_format.rb +1 -1
- data/lib/gherkin/{tools → formatter}/pretty_listener.rb +8 -9
- data/lib/gherkin/i18n.rb +27 -5
- data/lib/gherkin/i18n_lexer.rb +18 -44
- data/lib/gherkin/parser/filter_listener.rb +191 -0
- data/lib/gherkin/parser/parser.rb +142 -0
- data/lib/gherkin/parser/sexp.rb +45 -0
- data/lib/gherkin/parser/tag_expression.rb +46 -0
- data/lib/gherkin/rb_lexer.rb +2 -2
- data/ragel/lexer_common.rl.erb +1 -1
- data/spec/gherkin/{format → formatter}/argument_spec.rb +2 -2
- data/spec/gherkin/{tools → formatter}/colors_spec.rb +2 -2
- data/spec/gherkin/{tools → formatter}/pretty_listener_spec.rb +5 -5
- data/spec/gherkin/i18n_lexer_spec.rb +3 -3
- data/spec/gherkin/parser/filter_listener_spec.rb +363 -0
- data/spec/gherkin/parser/parser_spec.rb +35 -0
- data/spec/gherkin/parser/tag_expression_spec.rb +120 -0
- data/spec/gherkin/rb_lexer_spec.rb +0 -1
- data/spec/gherkin/sexp_recorder.rb +3 -3
- data/spec/gherkin/shared/lexer_spec.rb +19 -19
- data/spec/gherkin/shared/tags_spec.rb +4 -4
- data/tasks/bench.rake +2 -2
- data/tasks/compile.rake +1 -1
- data/tasks/ragel_task.rb +1 -1
- metadata +25 -36
- data/java/build.xml +0 -16
- data/java/src/gherkin/FixJava.java +0 -37
- data/java/src/gherkin/I18nLexer.java +0 -48
- data/java/src/gherkin/Lexer.java +0 -5
- data/java/src/gherkin/LexingError.java +0 -7
- data/java/src/gherkin/Listener.java +0 -29
- data/java/src/gherkin/Main.java +0 -17
- data/java/src/gherkin/ParseError.java +0 -22
- data/java/src/gherkin/Parser.java +0 -191
- data/java/src/gherkin/formatter/Argument.java +0 -39
- data/java/src/gherkin/formatter/ArgumentFormat.java +0 -17
- data/java/src/gherkin/formatter/Colors.java +0 -7
- data/java/src/gherkin/formatter/Formatter.java +0 -15
- data/java/src/gherkin/formatter/PrettyFormatter.java +0 -219
- data/java/src/gherkin/parser/StateMachineReader.java +0 -67
- data/java/test/gherkin/formatter/ArgumentTest.java +0 -17
- data/lib/gherkin/lexer.rb +0 -35
- data/lib/gherkin/parser.rb +0 -19
- data/lib/gherkin/rb_parser.rb +0 -125
- data/spec/gherkin/parser_spec.rb +0 -33
@@ -1,48 +0,0 @@
|
|
1
|
-
package gherkin;
|
2
|
-
|
3
|
-
import java.util.regex.Matcher;
|
4
|
-
import java.util.regex.Pattern;
|
5
|
-
|
6
|
-
public class I18nLexer implements Lexer {
|
7
|
-
private static final Pattern LANGUAGE_PATTERN = Pattern.compile("language\\s*:\\s*(.*)");
|
8
|
-
private final Listener listener;
|
9
|
-
private String i18nLanguage;
|
10
|
-
|
11
|
-
public I18nLexer(Listener listener) {
|
12
|
-
this.listener = listener;
|
13
|
-
}
|
14
|
-
|
15
|
-
/**
|
16
|
-
* @return the i18n language code from the previous scanned source.
|
17
|
-
*/
|
18
|
-
public String getI18nLanguage() {
|
19
|
-
return i18nLanguage;
|
20
|
-
}
|
21
|
-
|
22
|
-
public void scan(CharSequence source) {
|
23
|
-
createDelegate(source).scan(source);
|
24
|
-
}
|
25
|
-
|
26
|
-
private Lexer createDelegate(CharSequence source) {
|
27
|
-
i18nLanguage = lang(source);
|
28
|
-
String i18nLanguage = this.i18nLanguage.replaceAll("[\\s-]", "").toLowerCase();
|
29
|
-
String i18nLexerClassName = i18nLanguage.substring(0,1).toUpperCase() + i18nLanguage.substring(1);
|
30
|
-
String qualifiedI18nLexerClassName = "gherkin.lexer." + i18nLexerClassName;
|
31
|
-
try {
|
32
|
-
Class<?> delegateClass = Class.forName(qualifiedI18nLexerClassName);
|
33
|
-
return (Lexer) delegateClass.getConstructor(Listener.class).newInstance(listener);
|
34
|
-
} catch (Exception e) {
|
35
|
-
throw new RuntimeException("Couldn't load lexer class: " + qualifiedI18nLexerClassName, e);
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
private String lang(CharSequence source) {
|
40
|
-
String lineOne = source.toString().split("\\n")[0];
|
41
|
-
Matcher matcher = LANGUAGE_PATTERN.matcher(lineOne);
|
42
|
-
if(matcher.find()) {
|
43
|
-
return matcher.group(1);
|
44
|
-
} else {
|
45
|
-
return "en";
|
46
|
-
}
|
47
|
-
}
|
48
|
-
}
|
data/java/src/gherkin/Lexer.java
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
package gherkin;
|
2
|
-
|
3
|
-
import java.util.List;
|
4
|
-
|
5
|
-
public interface Listener {
|
6
|
-
void tag(String name, int line);
|
7
|
-
|
8
|
-
void comment(String content, int line);
|
9
|
-
|
10
|
-
void feature(String keyword, String name, int line);
|
11
|
-
|
12
|
-
void background(String keyword, String name, int line);
|
13
|
-
|
14
|
-
void scenario(String keyword, String name, int line);
|
15
|
-
|
16
|
-
void scenario_outline(String keyword, String name, int line);
|
17
|
-
|
18
|
-
void examples(String keyword, String name, int line);
|
19
|
-
|
20
|
-
void step(String keyword, String name, int line);
|
21
|
-
|
22
|
-
void row(List<String> row, int line);
|
23
|
-
|
24
|
-
void py_string(String string, int line);
|
25
|
-
|
26
|
-
void eof();
|
27
|
-
|
28
|
-
void syntax_error(String state, String event, List<String> legalEvents, int line);
|
29
|
-
}
|
data/java/src/gherkin/Main.java
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
package gherkin;
|
2
|
-
|
3
|
-
import gherkin.formatter.PrettyFormatter;
|
4
|
-
|
5
|
-
import java.io.FileReader;
|
6
|
-
import java.io.IOException;
|
7
|
-
|
8
|
-
public class Main {
|
9
|
-
public static void main(String[] args) throws IOException {
|
10
|
-
Parser p = new Parser(new PrettyFormatter(System.out, true));
|
11
|
-
Lexer l = new I18nLexer(p);
|
12
|
-
|
13
|
-
CharSequence input = FixJava.readReader(new FileReader(args[0]));
|
14
|
-
l.scan(input);
|
15
|
-
}
|
16
|
-
|
17
|
-
}
|
@@ -1,22 +0,0 @@
|
|
1
|
-
package gherkin;
|
2
|
-
|
3
|
-
import java.util.List;
|
4
|
-
|
5
|
-
public class ParseError extends RuntimeException {
|
6
|
-
private final String state;
|
7
|
-
private final List<String> expectedEvents;
|
8
|
-
|
9
|
-
public ParseError(String state, String event, List<String> expectedEvents, int line) {
|
10
|
-
super("Parse error on line " + line + ". Found " + event + " when expecting one of: " + FixJava.join(expectedEvents, ", ") + ". (Current state: " + state + ").");
|
11
|
-
this.state = state;
|
12
|
-
this.expectedEvents = expectedEvents;
|
13
|
-
}
|
14
|
-
|
15
|
-
public String state() {
|
16
|
-
return state;
|
17
|
-
}
|
18
|
-
|
19
|
-
public List<String> expectedEvents() {
|
20
|
-
return expectedEvents;
|
21
|
-
}
|
22
|
-
}
|
@@ -1,191 +0,0 @@
|
|
1
|
-
package gherkin;
|
2
|
-
|
3
|
-
import gherkin.parser.StateMachineReader;
|
4
|
-
|
5
|
-
import java.util.*;
|
6
|
-
import java.util.regex.Matcher;
|
7
|
-
import java.util.regex.Pattern;
|
8
|
-
|
9
|
-
public class Parser implements Listener {
|
10
|
-
List<Machine> machines = new ArrayList<Machine>();
|
11
|
-
|
12
|
-
private Listener listener;
|
13
|
-
private boolean throwOnError;
|
14
|
-
|
15
|
-
public Parser(Listener listener) {
|
16
|
-
this(listener, true);
|
17
|
-
}
|
18
|
-
|
19
|
-
public Parser(Listener listener, boolean throwOnError) {
|
20
|
-
this(listener, throwOnError, "root");
|
21
|
-
}
|
22
|
-
|
23
|
-
public Parser(Listener listener, boolean throwOnError, String machineName) {
|
24
|
-
this.listener = listener;
|
25
|
-
this.throwOnError = throwOnError;
|
26
|
-
pushMachine(machineName);
|
27
|
-
}
|
28
|
-
|
29
|
-
private void pushMachine(String machineName) {
|
30
|
-
machines.add(new Machine(this, machineName));
|
31
|
-
}
|
32
|
-
|
33
|
-
private void popMachine() {
|
34
|
-
machines.remove(machines.size() - 1);
|
35
|
-
}
|
36
|
-
|
37
|
-
public void tag(String name, int line) {
|
38
|
-
if (event("tag", line))
|
39
|
-
listener.tag(name, line);
|
40
|
-
}
|
41
|
-
|
42
|
-
public void py_string(String string, int line) {
|
43
|
-
if (event("py_string", line))
|
44
|
-
listener.py_string(string, line);
|
45
|
-
}
|
46
|
-
|
47
|
-
public void feature(String keyword, String name, int line) {
|
48
|
-
if (event("feature", line))
|
49
|
-
listener.feature(keyword, name, line);
|
50
|
-
}
|
51
|
-
|
52
|
-
public void background(String keyword, String name, int line) {
|
53
|
-
if (event("background", line))
|
54
|
-
listener.background(keyword, name, line);
|
55
|
-
}
|
56
|
-
|
57
|
-
public void scenario(String keyword, String name, int line) {
|
58
|
-
if (event("scenario", line))
|
59
|
-
listener.scenario(keyword, name, line);
|
60
|
-
}
|
61
|
-
|
62
|
-
public void scenario_outline(String keyword, String name, int line) {
|
63
|
-
if (event("scenario_outline", line))
|
64
|
-
listener.scenario_outline(keyword, name, line);
|
65
|
-
}
|
66
|
-
|
67
|
-
public void examples(String keyword, String name, int line) {
|
68
|
-
if (event("examples", line))
|
69
|
-
listener.examples(keyword, name, line);
|
70
|
-
}
|
71
|
-
|
72
|
-
public void step(String keyword, String name, int line) {
|
73
|
-
if (event("step", line))
|
74
|
-
listener.step(keyword, name, line);
|
75
|
-
}
|
76
|
-
|
77
|
-
public void comment(String content, int line) {
|
78
|
-
if (event("comment", line))
|
79
|
-
listener.comment(content, line);
|
80
|
-
}
|
81
|
-
|
82
|
-
public void row(List<String> row, int line) {
|
83
|
-
if (event("row", line))
|
84
|
-
listener.row(row, line);
|
85
|
-
}
|
86
|
-
|
87
|
-
public void eof() {
|
88
|
-
if (event("eof", 1))
|
89
|
-
listener.eof();
|
90
|
-
}
|
91
|
-
|
92
|
-
public void syntax_error(String name, String event, List<String> strings, int line) {
|
93
|
-
}
|
94
|
-
|
95
|
-
private boolean event(String event, int line) {
|
96
|
-
try {
|
97
|
-
machine().event(event, line);
|
98
|
-
return true;
|
99
|
-
} catch (ParseError e) {
|
100
|
-
if (throwOnError) {
|
101
|
-
throw e;
|
102
|
-
} else {
|
103
|
-
listener.syntax_error(e.state(), event, e.expectedEvents(), line);
|
104
|
-
return false;
|
105
|
-
}
|
106
|
-
}
|
107
|
-
}
|
108
|
-
|
109
|
-
private Machine machine() {
|
110
|
-
return machines.get(machines.size() - 1);
|
111
|
-
}
|
112
|
-
|
113
|
-
private static class Machine {
|
114
|
-
private static final Pattern PUSH = Pattern.compile("push\\((.+)\\)");
|
115
|
-
private static final Map<String, Map<String, Map<String, String>>> TRANSITION_MAPS = new HashMap<String, Map<String, Map<String, String>>>();
|
116
|
-
|
117
|
-
private final Parser parser;
|
118
|
-
private final String name;
|
119
|
-
private String state;
|
120
|
-
private Map<String, Map<String, String>> transitionMap;
|
121
|
-
|
122
|
-
public Machine(Parser parser, String name) {
|
123
|
-
this.parser = parser;
|
124
|
-
this.name = name;
|
125
|
-
this.state = name;
|
126
|
-
this.transitionMap = transitionMap(name);
|
127
|
-
}
|
128
|
-
|
129
|
-
public void event(String event, int line) {
|
130
|
-
Map<String, String> states = transitionMap.get(state);
|
131
|
-
if (states == null) {
|
132
|
-
throw new RuntimeException("Unknown state: " + state + " for machine " + name);
|
133
|
-
}
|
134
|
-
String newState = states.get(event);
|
135
|
-
if (newState == null) {
|
136
|
-
throw new RuntimeException("Unknown transition: " + event + " among " + states + " for machine " + name + " in state " + state);
|
137
|
-
}
|
138
|
-
if ("E".equals(newState)) {
|
139
|
-
throw new ParseError(state, event, expectedEvents(), line);
|
140
|
-
} else {
|
141
|
-
Matcher push = PUSH.matcher(newState);
|
142
|
-
if (push.matches()) {
|
143
|
-
parser.pushMachine(push.group(1));
|
144
|
-
parser.event(event, line);
|
145
|
-
} else if ("pop()".equals(newState)) {
|
146
|
-
parser.popMachine();
|
147
|
-
parser.event(event, line);
|
148
|
-
} else {
|
149
|
-
state = newState;
|
150
|
-
}
|
151
|
-
}
|
152
|
-
}
|
153
|
-
|
154
|
-
private List<String> expectedEvents() {
|
155
|
-
List<String> result = new ArrayList<String>();
|
156
|
-
for (String event : transitionMap.get(state).keySet()) {
|
157
|
-
if (!transitionMap.get(state).get(event).equals("E")) {
|
158
|
-
result.add(event);
|
159
|
-
}
|
160
|
-
}
|
161
|
-
Collections.sort(result);
|
162
|
-
result.remove("eof");
|
163
|
-
return result;
|
164
|
-
}
|
165
|
-
|
166
|
-
private Map<String, Map<String, String>> transitionMap(String name) {
|
167
|
-
Map<String, Map<String, String>> map = TRANSITION_MAPS.get(name);
|
168
|
-
if(map == null) {
|
169
|
-
map = buildTransitionMap(name);
|
170
|
-
TRANSITION_MAPS.put(name, map);
|
171
|
-
}
|
172
|
-
return map;
|
173
|
-
}
|
174
|
-
|
175
|
-
private Map<String, Map<String, String>> buildTransitionMap(String name) {
|
176
|
-
Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();
|
177
|
-
List<List<String>> transitionTable = new StateMachineReader(name).transitionTable();
|
178
|
-
List<String> events = transitionTable.get(0).subList(1, transitionTable.get(0).size());
|
179
|
-
for (List<String> actions : transitionTable.subList(1, transitionTable.size())) {
|
180
|
-
Map<String, String> transitions = new HashMap<String, String>();
|
181
|
-
int col = 1;
|
182
|
-
for (String event : events) {
|
183
|
-
transitions.put(event, actions.get(col++));
|
184
|
-
}
|
185
|
-
String state = actions.get(0);
|
186
|
-
result.put(state, transitions);
|
187
|
-
}
|
188
|
-
return result;
|
189
|
-
}
|
190
|
-
}
|
191
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
package gherkin.formatter;
|
2
|
-
|
3
|
-
import java.io.UnsupportedEncodingException;
|
4
|
-
import java.util.List;
|
5
|
-
|
6
|
-
public class Argument {
|
7
|
-
private final int byteOffset;
|
8
|
-
private final byte[] val;
|
9
|
-
|
10
|
-
public Argument(int byteOffset, String val) throws UnsupportedEncodingException {
|
11
|
-
this.byteOffset = byteOffset;
|
12
|
-
this.val = val.getBytes("UTF-8");
|
13
|
-
}
|
14
|
-
|
15
|
-
public static String format(String string, ArgumentFormat format, List<Argument> arguments) throws UnsupportedEncodingException {
|
16
|
-
return format(string, format, (Argument[]) arguments.toArray(new Argument[arguments.size()]));
|
17
|
-
}
|
18
|
-
|
19
|
-
public static String format(String string, ArgumentFormat format, Argument... arguments) throws UnsupportedEncodingException {
|
20
|
-
byte[] result = string.getBytes("UTF-8");
|
21
|
-
int offset = 0, pastOffset = 0;
|
22
|
-
for (Argument argument : arguments) {
|
23
|
-
if (argument.byteOffset != -1 && argument.byteOffset >= pastOffset) {
|
24
|
-
byte[] replacement = format.formatArgument(argument.val);
|
25
|
-
int delta = replacement.length - argument.val.length;
|
26
|
-
byte[] newResult = new byte[result.length + delta];
|
27
|
-
|
28
|
-
System.arraycopy(result, 0, newResult, 0, argument.byteOffset+offset);
|
29
|
-
System.arraycopy(replacement, 0, newResult, argument.byteOffset+offset, replacement.length);
|
30
|
-
int n = argument.byteOffset + argument.val.length + offset;
|
31
|
-
System.arraycopy(result, n, newResult, argument.byteOffset + replacement.length, result.length - n);
|
32
|
-
|
33
|
-
offset += delta;
|
34
|
-
result = newResult;
|
35
|
-
}
|
36
|
-
}
|
37
|
-
return new String(result, "UTF-8");
|
38
|
-
}
|
39
|
-
}
|
@@ -1,17 +0,0 @@
|
|
1
|
-
package gherkin.formatter;
|
2
|
-
|
3
|
-
import java.io.UnsupportedEncodingException;
|
4
|
-
|
5
|
-
public class ArgumentFormat {
|
6
|
-
private final String prefix;
|
7
|
-
private final String suffix;
|
8
|
-
|
9
|
-
public ArgumentFormat(String prefix, String suffix) {
|
10
|
-
this.prefix = prefix;
|
11
|
-
this.suffix = suffix;
|
12
|
-
}
|
13
|
-
|
14
|
-
public byte[] formatArgument(byte[] argument) throws UnsupportedEncodingException {
|
15
|
-
return (prefix + new String(argument, "UTF-8") + suffix).getBytes("UTF-8");
|
16
|
-
}
|
17
|
-
}
|
@@ -1,15 +0,0 @@
|
|
1
|
-
package gherkin.formatter;
|
2
|
-
|
3
|
-
import gherkin.Listener;
|
4
|
-
|
5
|
-
import java.util.List;
|
6
|
-
|
7
|
-
/**
|
8
|
-
* This interface extends the Listener interface with extra methods for formatting
|
9
|
-
* Gherkin features during execution.
|
10
|
-
*/
|
11
|
-
public interface Formatter extends Listener {
|
12
|
-
void scenario(String keyword, String name, int line, String location);
|
13
|
-
void step(String keyword, String name, int line, String status, List<Argument> arguments, String location);
|
14
|
-
void flushTable();
|
15
|
-
}
|
@@ -1,219 +0,0 @@
|
|
1
|
-
package gherkin.formatter;
|
2
|
-
|
3
|
-
import java.io.OutputStream;
|
4
|
-
import java.io.PrintWriter;
|
5
|
-
import java.util.ArrayList;
|
6
|
-
import java.util.Collections;
|
7
|
-
import java.util.List;
|
8
|
-
import java.util.regex.Pattern;
|
9
|
-
|
10
|
-
import static gherkin.FixJava.join;
|
11
|
-
import static gherkin.formatter.Colors.*;
|
12
|
-
|
13
|
-
public class PrettyFormatter implements Formatter {
|
14
|
-
private final PrintWriter out;
|
15
|
-
private final boolean monochrome;
|
16
|
-
private int maxStepLength = 0;
|
17
|
-
private int[] stepLengths;
|
18
|
-
private int stepIndex;
|
19
|
-
private List<List<String>> rows;
|
20
|
-
private List<String> comments;
|
21
|
-
private List<String> tags;
|
22
|
-
|
23
|
-
public PrettyFormatter(OutputStream out, boolean monochrome) {
|
24
|
-
this.out = new PrintWriter(out);
|
25
|
-
this.monochrome = monochrome;
|
26
|
-
}
|
27
|
-
|
28
|
-
public void tag(String name, int line) {
|
29
|
-
if (tags == null) tags = new ArrayList<String>();
|
30
|
-
tags.add('@' + name);
|
31
|
-
}
|
32
|
-
|
33
|
-
public void comment(String content, int line) {
|
34
|
-
if (comments == null) comments = new ArrayList<String>();
|
35
|
-
comments.add(content);
|
36
|
-
}
|
37
|
-
|
38
|
-
public void feature(String keyword, String name, int line) {
|
39
|
-
printCommentsAndTags("");
|
40
|
-
out.println(keyword + ": " + indent(name, " "));
|
41
|
-
out.flush();
|
42
|
-
}
|
43
|
-
|
44
|
-
public void background(String keyword, String name, int line) {
|
45
|
-
out.println();
|
46
|
-
printCommentsAndTags(" ");
|
47
|
-
out.println(" " + keyword + ": " + name);
|
48
|
-
}
|
49
|
-
|
50
|
-
public void scenario(String keyword, String name, int line) {
|
51
|
-
scenario(keyword, name, line, null);
|
52
|
-
}
|
53
|
-
|
54
|
-
public void scenario(String keyword, String name, int line, String location) {
|
55
|
-
flushTable();
|
56
|
-
out.println();
|
57
|
-
printCommentsAndTags(" ");
|
58
|
-
out.println(" " + keyword + ": " + indent(name, " ") + indentedScenarioLocation(keyword, name, location));
|
59
|
-
out.flush();
|
60
|
-
}
|
61
|
-
|
62
|
-
public void scenario_outline(String keyword, String name, int line) {
|
63
|
-
flushTable();
|
64
|
-
out.println();
|
65
|
-
printCommentsAndTags(" ");
|
66
|
-
out.println(" " + keyword + ": " + name);
|
67
|
-
}
|
68
|
-
|
69
|
-
public void examples(String keyword, String name, int line) {
|
70
|
-
flushTable();
|
71
|
-
out.println();
|
72
|
-
printCommentsAndTags(" ");
|
73
|
-
out.println(" " + keyword + ": " + name);
|
74
|
-
}
|
75
|
-
|
76
|
-
public void step(String keyword, String name, int line, String status, List<Argument> arguments, String location) {
|
77
|
-
flushTable();
|
78
|
-
out.println(" " + keyword + indent(name, " ") + indentedStepLocation(location));
|
79
|
-
out.flush();
|
80
|
-
}
|
81
|
-
|
82
|
-
public void flushTable() {
|
83
|
-
if (rows == null) return;
|
84
|
-
int columnCount = rows.get(0).size();
|
85
|
-
int[][] cellLengths = new int[rows.size()][columnCount];
|
86
|
-
int[] maxLengths = new int[columnCount];
|
87
|
-
for (int i = 0; i < rows.size(); i++) {
|
88
|
-
for (int j = 0; j < columnCount; j++) {
|
89
|
-
int length = rows.get(i).get(j).length();
|
90
|
-
cellLengths[i][j] = length;
|
91
|
-
maxLengths[j] = Math.max(maxLengths[j], length);
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
|
-
for (int i = 0; i < rows.size(); i++) {
|
96
|
-
out.write(" | ");
|
97
|
-
for (int j = 0; j < columnCount; j++) {
|
98
|
-
out.write(rows.get(i).get(j));
|
99
|
-
padSpace(maxLengths[j] - cellLengths[i][j]);
|
100
|
-
if (j < columnCount - 1) {
|
101
|
-
out.write(" | ");
|
102
|
-
} else {
|
103
|
-
out.write(" |");
|
104
|
-
}
|
105
|
-
}
|
106
|
-
out.println();
|
107
|
-
}
|
108
|
-
out.flush();
|
109
|
-
rows = null;
|
110
|
-
}
|
111
|
-
|
112
|
-
public void step(String keyword, String name, int line) {
|
113
|
-
step(keyword, name, line, null, Collections.<Argument>emptyList(), null);
|
114
|
-
}
|
115
|
-
|
116
|
-
public void row(List<String> row, int line) {
|
117
|
-
if (rows == null) rows = new ArrayList<List<String>>();
|
118
|
-
rows.add(row);
|
119
|
-
}
|
120
|
-
|
121
|
-
public void py_string(String string, int line) {
|
122
|
-
out.println(" \"\"\"");
|
123
|
-
out.print(Pattern.compile("^", Pattern.MULTILINE).matcher(string).replaceAll(" "));
|
124
|
-
out.println("\n \"\"\"");
|
125
|
-
}
|
126
|
-
|
127
|
-
public void eof() {
|
128
|
-
flushTable();
|
129
|
-
out.flush();
|
130
|
-
}
|
131
|
-
|
132
|
-
public void syntax_error(String state, String event, List<String> legalEvents, int line) {
|
133
|
-
out.println("Syntax error:" + state + ' ' + event);
|
134
|
-
}
|
135
|
-
|
136
|
-
public void steps(List<List<String>> steps) {
|
137
|
-
stepLengths = new int[steps.size()];
|
138
|
-
int i = 0;
|
139
|
-
for (List<String> step : steps) {
|
140
|
-
int stepLength = step.get(0).length() + step.get(1).length();
|
141
|
-
stepLengths[i++] = stepLength;
|
142
|
-
maxStepLength = Math.max(maxStepLength, stepLength);
|
143
|
-
}
|
144
|
-
stepIndex = -1;
|
145
|
-
}
|
146
|
-
|
147
|
-
private void padSpace(int indent, StringBuffer buffer) {
|
148
|
-
for (int i = 0; i < indent; i++) {
|
149
|
-
buffer.append(" ");
|
150
|
-
}
|
151
|
-
}
|
152
|
-
|
153
|
-
private void padSpace(int indent) {
|
154
|
-
for (int i = 0; i < indent; i++) {
|
155
|
-
out.write(" ");
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
private void printCommentsAndTags(String indent) {
|
160
|
-
printComments(indent);
|
161
|
-
printTags(indent);
|
162
|
-
}
|
163
|
-
|
164
|
-
private boolean printComments(String indent) {
|
165
|
-
if (comments == null) return false;
|
166
|
-
for (String comment : comments) {
|
167
|
-
out.print(indent);
|
168
|
-
out.println(comment);
|
169
|
-
}
|
170
|
-
out.flush();
|
171
|
-
comments = null;
|
172
|
-
return true;
|
173
|
-
}
|
174
|
-
|
175
|
-
private boolean printTags(String indent) {
|
176
|
-
if (tags == null) return false;
|
177
|
-
out.print(indent);
|
178
|
-
out.println(join(tags, " "));
|
179
|
-
out.flush();
|
180
|
-
tags = null;
|
181
|
-
return true;
|
182
|
-
}
|
183
|
-
|
184
|
-
private String indent(String name, String indentation) {
|
185
|
-
String indent = "";
|
186
|
-
StringBuilder sb = new StringBuilder();
|
187
|
-
String[] lines = name.split("\\n");
|
188
|
-
for (int i = 0; i < lines.length; i++) {
|
189
|
-
sb.append(indent).append(lines[i]);
|
190
|
-
if (i < lines.length - 1) {
|
191
|
-
sb.append("\n");
|
192
|
-
}
|
193
|
-
indent = indentation;
|
194
|
-
}
|
195
|
-
return sb.toString();
|
196
|
-
}
|
197
|
-
|
198
|
-
private String indentedScenarioLocation(String keyword, String name, String location) {
|
199
|
-
if (location == null || "".equals(location)) return "";
|
200
|
-
int l = keyword.length() + name.length();
|
201
|
-
maxStepLength = Math.max(maxStepLength, l);
|
202
|
-
int indent = maxStepLength - l;
|
203
|
-
|
204
|
-
StringBuffer buffer = new StringBuffer();
|
205
|
-
padSpace(indent, buffer);
|
206
|
-
buffer.append(" ").append(comments("# " + location, monochrome));
|
207
|
-
return buffer.toString();
|
208
|
-
}
|
209
|
-
|
210
|
-
private String indentedStepLocation(String location) {
|
211
|
-
if (location == null || "".equals(location)) return "";
|
212
|
-
int indent = maxStepLength - stepLengths[stepIndex += 1];
|
213
|
-
|
214
|
-
StringBuffer buffer = new StringBuffer();
|
215
|
-
padSpace(indent, buffer);
|
216
|
-
buffer.append(" ").append(comments("# " + location, monochrome));
|
217
|
-
return buffer.toString();
|
218
|
-
}
|
219
|
-
}
|