gherkin 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/History.txt +15 -6
  2. data/README.rdoc +23 -0
  3. data/Rakefile +1 -0
  4. data/VERSION.yml +1 -1
  5. data/features/step_definitions/gherkin_steps.rb +1 -1
  6. data/features/step_definitions/{pretty_printer_steps.rb → pretty_listener_step.rb} +2 -2
  7. data/gherkin.gemspec +24 -35
  8. data/java/Gherkin.iml +8 -14
  9. data/java/src/{gherkin → main/java/gherkin}/lexer/.gitignore +0 -0
  10. data/lib/gherkin.rb +1 -1
  11. data/lib/gherkin/c_lexer.rb +2 -2
  12. data/lib/gherkin/{format → formatter}/argument.rb +1 -1
  13. data/lib/gherkin/{tools → formatter}/colors.rb +1 -1
  14. data/lib/gherkin/{format → formatter}/monochrome_format.rb +1 -1
  15. data/lib/gherkin/{tools → formatter}/pretty_listener.rb +8 -9
  16. data/lib/gherkin/i18n.rb +27 -5
  17. data/lib/gherkin/i18n_lexer.rb +18 -44
  18. data/lib/gherkin/parser/filter_listener.rb +191 -0
  19. data/lib/gherkin/parser/parser.rb +142 -0
  20. data/lib/gherkin/parser/sexp.rb +45 -0
  21. data/lib/gherkin/parser/tag_expression.rb +46 -0
  22. data/lib/gherkin/rb_lexer.rb +2 -2
  23. data/ragel/lexer_common.rl.erb +1 -1
  24. data/spec/gherkin/{format → formatter}/argument_spec.rb +2 -2
  25. data/spec/gherkin/{tools → formatter}/colors_spec.rb +2 -2
  26. data/spec/gherkin/{tools → formatter}/pretty_listener_spec.rb +5 -5
  27. data/spec/gherkin/i18n_lexer_spec.rb +3 -3
  28. data/spec/gherkin/parser/filter_listener_spec.rb +363 -0
  29. data/spec/gherkin/parser/parser_spec.rb +35 -0
  30. data/spec/gherkin/parser/tag_expression_spec.rb +120 -0
  31. data/spec/gherkin/rb_lexer_spec.rb +0 -1
  32. data/spec/gherkin/sexp_recorder.rb +3 -3
  33. data/spec/gherkin/shared/lexer_spec.rb +19 -19
  34. data/spec/gherkin/shared/tags_spec.rb +4 -4
  35. data/tasks/bench.rake +2 -2
  36. data/tasks/compile.rake +1 -1
  37. data/tasks/ragel_task.rb +1 -1
  38. metadata +25 -36
  39. data/java/build.xml +0 -16
  40. data/java/src/gherkin/FixJava.java +0 -37
  41. data/java/src/gherkin/I18nLexer.java +0 -48
  42. data/java/src/gherkin/Lexer.java +0 -5
  43. data/java/src/gherkin/LexingError.java +0 -7
  44. data/java/src/gherkin/Listener.java +0 -29
  45. data/java/src/gherkin/Main.java +0 -17
  46. data/java/src/gherkin/ParseError.java +0 -22
  47. data/java/src/gherkin/Parser.java +0 -191
  48. data/java/src/gherkin/formatter/Argument.java +0 -39
  49. data/java/src/gherkin/formatter/ArgumentFormat.java +0 -17
  50. data/java/src/gherkin/formatter/Colors.java +0 -7
  51. data/java/src/gherkin/formatter/Formatter.java +0 -15
  52. data/java/src/gherkin/formatter/PrettyFormatter.java +0 -219
  53. data/java/src/gherkin/parser/StateMachineReader.java +0 -67
  54. data/java/test/gherkin/formatter/ArgumentTest.java +0 -17
  55. data/lib/gherkin/lexer.rb +0 -35
  56. data/lib/gherkin/parser.rb +0 -19
  57. data/lib/gherkin/rb_parser.rb +0 -125
  58. data/spec/gherkin/parser_spec.rb +0 -33
@@ -1,67 +0,0 @@
1
- package gherkin.parser;
2
-
3
- import gherkin.FixJava;
4
- import gherkin.Lexer;
5
- import gherkin.Listener;
6
- import gherkin.lexer.En;
7
-
8
- import java.io.IOException;
9
- import java.util.List;
10
- import java.util.ArrayList;
11
-
12
- public class StateMachineReader implements Listener {
13
- private final String machinePath;
14
- private List<List<String>> transitionTable;
15
-
16
- public StateMachineReader(String name) {
17
- machinePath = "/gherkin/parser/" + name + ".txt";
18
- }
19
-
20
- public List<List<String>> transitionTable() {
21
- transitionTable = new ArrayList<List<String>>();
22
- Lexer lexer = new En(this);
23
- try {
24
- lexer.scan(FixJava.readResource(machinePath));
25
- } catch (IOException e) {
26
- throw new RuntimeException("Fatal error. Couldn't read " + machinePath);
27
- }
28
- return transitionTable;
29
- }
30
-
31
- public void tag(String name, int line) {
32
- }
33
-
34
- public void comment(String content, int line) {
35
- }
36
-
37
- public void feature(String keyword, String name, int line) {
38
- }
39
-
40
- public void background(String keyword, String name, int line) {
41
- }
42
-
43
- public void scenario(String keyword, String name, int line) {
44
- }
45
-
46
- public void scenario_outline(String keyword, String name, int line) {
47
- }
48
-
49
- public void examples(String keyword, String name, int line) {
50
- }
51
-
52
- public void step(String keyword, String name, int line) {
53
- }
54
-
55
- public void py_string(String string, int line) {
56
- }
57
-
58
- public void eof() {
59
- }
60
-
61
- public void syntax_error(String name, String event, List<String> strings, int line) {
62
- }
63
-
64
- public void row(List<String> row, int line) {
65
- transitionTable.add(row);
66
- }
67
- }
@@ -1,17 +0,0 @@
1
- package gherkin.formatter;
2
-
3
- import org.junit.Test;
4
-
5
- import java.io.UnsupportedEncodingException;
6
-
7
- import static org.junit.Assert.assertEquals;
8
-
9
- public class ArgumentTest {
10
- @Test
11
- public void shouldFormatAscii() throws UnsupportedEncodingException {
12
- assertEquals("I have [[[[åtte] cukes i [[[[bøtta]", Argument.format("I have åtte cukes i bøtta", new ArgumentFormat("[[[[", "]"),
13
- new Argument(7, "åtte"),
14
- new Argument(21, "bøtta")
15
- ));
16
- }
17
- }
@@ -1,35 +0,0 @@
1
- module Gherkin
2
- module Lexer
3
-
4
- class << self
5
- def [](i18n_lang)
6
- begin
7
- begin
8
- c[i18n_lang]
9
- rescue NameError, LoadError => e
10
- raise("WARNING: #{e.message}. Reverting to Ruby lexer.") unless defined?(@warned)
11
- @warned = true
12
- rb[i18n_lang]
13
- end
14
- rescue LoadError => e
15
- raise I18nLexerNotFound, "No lexer was found for #{i18n_lang} (#{e.message}). Supported languages are listed in gherkin/i18n.yml."
16
- end
17
- end
18
-
19
- def c
20
- require 'gherkin/c_lexer'
21
- CLexer
22
- end
23
-
24
- def csharp
25
- require 'gherkin/csharp_lexer'
26
- CSharpLexer
27
- end
28
-
29
- def rb
30
- require 'gherkin/rb_lexer'
31
- RbLexer
32
- end
33
- end
34
- end
35
- end
@@ -1,19 +0,0 @@
1
- module Gherkin
2
- class ParseError < StandardError
3
- def initialize(state, new_state, expected_states, line)
4
- super("Parse error on line #{line}. Found #{new_state} when expecting one of: #{expected_states.join(', ')}. (Current state: #{state}).")
5
- end
6
- end
7
-
8
- class Parser
9
- def self.new(listener, raise_on_error=false, machine_name='root')
10
- if defined?(JRUBY_VERSION)
11
- require 'gherkin.jar'
12
- Java::Gherkin::Parser.new(listener, raise_on_error, machine_name)
13
- else
14
- require 'gherkin/rb_parser'
15
- Gherkin::RbParser.new(listener, raise_on_error, machine_name)
16
- end
17
- end
18
- end
19
- end
@@ -1,125 +0,0 @@
1
- module Gherkin
2
- class RbParser
3
- # Initialize the parser. +machine_name+ refers to a state machine table.
4
- def initialize(listener, raise_on_error, machine_name)
5
- @listener = listener
6
- @raise_on_error = raise_on_error
7
- @machines = []
8
- push_machine(machine_name)
9
- end
10
-
11
- # Doesn't yet fall back to super
12
- def method_missing(method, *args)
13
- # TODO: Catch exception and call super
14
- if(event(method.to_s, args[-1]))
15
- @listener.send(method, *args)
16
- end
17
- end
18
-
19
- def event(ev, line)
20
- machine.event(ev, line) do |state, expected|
21
- if @raise_on_error
22
- raise ParseError.new(state, ev, expected, line)
23
- else
24
- @listener.syntax_error(state, ev, expected, line)
25
- return false
26
- end
27
- end
28
- true
29
- end
30
-
31
- def push_machine(name)
32
- @machines.push(Machine.new(self, name))
33
- end
34
-
35
- def pop_machine
36
- @machines.pop
37
- end
38
-
39
- def machine
40
- @machines[-1]
41
- end
42
-
43
- def expected
44
- machine.expected
45
- end
46
-
47
- def force_state(state)
48
- machine.instance_variable_set('@state', state)
49
- end
50
-
51
- class Machine
52
- def initialize(parser, name)
53
- @parser = parser
54
- @name = name
55
- @transition_map = transition_map(name)
56
- @state = name
57
- end
58
-
59
- def event(ev, line)
60
- states = @transition_map[@state]
61
- raise "Unknown state: #{@state.inspect} for machine #{@name}" if states.nil?
62
- new_state = states[ev]
63
- case new_state
64
- when "E"
65
- yield @state, expected
66
- when /push\((.+)\)/
67
- @parser.push_machine($1)
68
- @parser.event(ev, line)
69
- when "pop()"
70
- @parser.pop_machine()
71
- @parser.event(ev, line)
72
- else
73
- raise "Unknown transition: #{ev.inspect} among #{states.inspect} for machine #{@name}" if new_state.nil?
74
- @state = new_state
75
- end
76
- end
77
-
78
- def expected
79
- allowed = @transition_map[@state].find_all { |_, action| action != "E" }
80
- allowed.collect { |state| state[0] }.sort - ['eof']
81
- end
82
-
83
- private
84
-
85
- @@transition_maps = {}
86
-
87
- def transition_map(name)
88
- @@transition_maps[name] ||= build_transition_map(name)
89
- end
90
-
91
- def build_transition_map(name)
92
- table = transition_table(name)
93
- events = table.shift[1..-1]
94
- table.inject({}) do |machine, actions|
95
- state = actions.shift
96
- machine[state] = Hash[*events.zip(actions).flatten]
97
- machine
98
- end
99
- end
100
-
101
- def transition_table(name)
102
- state_machine_reader = StateMachineReader.new
103
- lexer = Gherkin::I18nLexer.lexer_class('en', false).new(state_machine_reader)
104
- lexer.scan(File.read(File.dirname(__FILE__) + "/parser/#{name}.txt"))
105
- state_machine_reader.rows
106
- end
107
-
108
- class StateMachineReader
109
- attr_reader :rows
110
-
111
- def initialize
112
- @rows = []
113
- end
114
-
115
- def row(row, line_number)
116
- @rows << row
117
- end
118
-
119
- def eof
120
- end
121
- end
122
-
123
- end
124
- end
125
- end
@@ -1,33 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
- require 'gherkin/parser'
3
-
4
- module Gherkin
5
- describe Parser do
6
- before do
7
- @listener = mock('listener')
8
- @parser = Parser.new(@listener, true)
9
- end
10
-
11
- it "should delegate events to the listener" do
12
- @listener.should_receive(:comment).with("# Content", 1)
13
- @parser.comment("# Content", 1)
14
- end
15
-
16
- it "should raise helpful error messages by default" do
17
- lambda {
18
- @parser.scenario("Scenario", "My pet scenario", 12)
19
- }.should raise_error(/Parse error on line 12\. Found scenario when expecting one of: comment, feature, tag\. \(Current state: root\)\.$/)
20
- end
21
-
22
- it "should allow empty files" do
23
- @listener.should_receive(:eof)
24
- @parser.eof
25
- end
26
-
27
- it "should delegate an error message when raise on error is false" do
28
- @listener.should_receive(:syntax_error).with(sym(:root), sym(:background), a([:comment, :feature, :tag]), 1)
29
- @parser = Parser.new(@listener, false)
30
- @parser.background("Background", "Content", 1)
31
- end
32
- end
33
- end