gherkin 1.0.2-java → 1.0.3-java
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitattributes +1 -0
- data/History.txt +18 -0
- data/README.rdoc +4 -1
- data/Rakefile +4 -2
- data/VERSION.yml +1 -1
- data/bin/gherkin +1 -1
- data/dotnet/.gitignore +13 -0
- data/features/feature_parser.feature +22 -2
- data/features/native_lexer.feature +1 -1
- data/features/parser_with_native_lexer.feature +1 -1
- data/features/step_definitions/gherkin_steps.rb +2 -6
- data/features/step_definitions/pretty_printer_steps.rb +2 -3
- data/features/steps_parser.feature +1 -1
- data/gherkin.gemspec +40 -13
- data/java/Gherkin.iml +2 -4
- data/java/build.xml +3 -0
- data/java/src/gherkin/FixJava.java +6 -3
- data/java/src/gherkin/I18nLexer.java +48 -0
- data/java/src/gherkin/Listener.java +3 -1
- data/java/src/gherkin/Main.java +17 -0
- data/java/src/gherkin/Parser.java +9 -3
- data/java/src/gherkin/formatter/Argument.java +39 -0
- data/java/src/gherkin/formatter/ArgumentFormat.java +17 -0
- data/java/src/gherkin/formatter/Colors.java +7 -0
- data/java/src/gherkin/formatter/Formatter.java +15 -0
- data/java/src/gherkin/formatter/PrettyFormatter.java +219 -0
- data/java/src/gherkin/parser/StateMachineReader.java +8 -3
- data/java/test/gherkin/formatter/ArgumentTest.java +17 -0
- data/lib/gherkin/csharp_lexer.rb +15 -0
- data/lib/gherkin/format/argument.rb +35 -0
- data/lib/gherkin/format/monochrome_format.rb +9 -0
- data/lib/gherkin/i18n.rb +22 -0
- data/lib/gherkin/i18n.yml +34 -20
- data/lib/gherkin/i18n_lexer.rb +57 -13
- data/lib/gherkin/lexer.rb +9 -18
- data/lib/gherkin/parser.rb +3 -3
- data/lib/gherkin/parser/meta.txt +5 -4
- data/lib/gherkin/parser/root.txt +11 -9
- data/lib/gherkin/parser/steps.txt +4 -3
- data/lib/gherkin/rb_parser.rb +13 -5
- data/lib/gherkin/tools/colors.rb +119 -0
- data/lib/gherkin/tools/files.rb +6 -1
- data/lib/gherkin/tools/pretty_listener.rb +115 -23
- data/ragel/lexer.c.rl.erb +67 -51
- data/ragel/lexer.csharp.rl.erb +240 -0
- data/ragel/lexer.java.rl.erb +27 -18
- data/ragel/lexer.rb.rl.erb +17 -17
- data/ragel/lexer_common.rl.erb +8 -8
- data/spec/gherkin/c_lexer_spec.rb +4 -4
- data/spec/gherkin/csharp_lexer_spec.rb +20 -0
- data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
- data/spec/gherkin/fixtures/complex.feature +2 -0
- data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
- data/spec/gherkin/fixtures/i18n_fr.feature +1 -0
- data/spec/gherkin/fixtures/i18n_no.feature +1 -0
- data/spec/gherkin/fixtures/i18n_zh-CN.feature +1 -0
- data/spec/gherkin/format/argument_spec.rb +28 -0
- data/spec/gherkin/i18n_lexer_spec.rb +4 -4
- data/spec/gherkin/i18n_spec.rb +31 -23
- data/spec/gherkin/java_lexer_spec.rb +4 -3
- data/spec/gherkin/parser_spec.rb +5 -0
- data/spec/gherkin/rb_lexer_spec.rb +4 -2
- data/spec/gherkin/sexp_recorder.rb +1 -1
- data/spec/gherkin/shared/lexer_spec.rb +169 -60
- data/spec/gherkin/shared/py_string_spec.rb +6 -0
- data/spec/gherkin/shared/row_spec.rb +107 -0
- data/spec/gherkin/shared/tags_spec.rb +1 -1
- data/spec/gherkin/tools/colors_spec.rb +19 -0
- data/spec/gherkin/tools/pretty_listener_spec.rb +147 -0
- data/spec/spec_helper.rb +31 -7
- data/tasks/compile.rake +81 -7
- data/tasks/ragel_task.rb +6 -4
- data/tasks/rspec.rake +2 -2
- metadata +86 -26
- data/lib/gherkin/java_lexer.rb +0 -10
- data/spec/gherkin/shared/table_spec.rb +0 -97
data/lib/gherkin/i18n.rb
CHANGED
@@ -18,6 +18,23 @@ module Gherkin
|
|
18
18
|
def languages
|
19
19
|
@languages ||= {}
|
20
20
|
end
|
21
|
+
|
22
|
+
# Returns all keyword translations and aliases of +keywords+, escaped and joined with <tt>|</tt>.
|
23
|
+
# This method is convenient for editor support and syntax highlighting engines for Gherkin, where
|
24
|
+
# there is typically a code generation tool to generate regular expressions for recognising the
|
25
|
+
# various I18n translations of Gherkin's keywords.
|
26
|
+
#
|
27
|
+
# The +keywords+ arguments can be one of <tt>:feature</tt>, <tt>:background</tt>, <tt>:scenario</tt>,
|
28
|
+
# <tt>:scenario_outline</tt>, <tt>:examples</tt>, <tt>:step</tt>.
|
29
|
+
def keyword_regexp(*keywords)
|
30
|
+
unique_keywords = all.map do |lang|
|
31
|
+
keywords.map do |keyword|
|
32
|
+
lang.__send__("#{keyword}_keywords".to_sym)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
unique_keywords.flatten.compact.sort.reverse.uniq.join('|').gsub(/\*/, '\*')
|
37
|
+
end
|
21
38
|
end
|
22
39
|
|
23
40
|
attr_reader :key
|
@@ -69,12 +86,17 @@ module Gherkin
|
|
69
86
|
%w{given when then and but}.map{|key| keywords(key, true)}.flatten.uniq
|
70
87
|
end
|
71
88
|
|
89
|
+
def gwt_keywords
|
90
|
+
%w{given when then}.map{|key| keywords(key, true)}.flatten.uniq
|
91
|
+
end
|
92
|
+
|
72
93
|
def keywords(key, space=false)
|
73
94
|
raise "No #{key} in #{@keywords.inspect}" if @keywords[key].nil?
|
74
95
|
@keywords[key].split('|').map{|kw| space ? keyword_space(kw) : kw}
|
75
96
|
end
|
76
97
|
|
77
98
|
def adverbs
|
99
|
+
# TODO: looks very similar to #step_keywords. Lose this? Where is it used from?
|
78
100
|
%w{given when then and but}.map{|keyword| @keywords[keyword].split('|').map{|w| w.gsub(/[\s<']/, '')}}.flatten
|
79
101
|
end
|
80
102
|
|
data/lib/gherkin/i18n.yml
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
#
|
3
|
-
#
|
2
|
+
#
|
3
|
+
# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if appliccable):
|
4
|
+
# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
5
|
+
# http://en.wikipedia.org/wiki/ISO_3166-1
|
4
6
|
#
|
5
7
|
# If you want several aliases for a keyword, just separate them
|
6
8
|
# with a | character. Make sure there are no ambiguities in the
|
7
9
|
# keywords.
|
8
10
|
#
|
11
|
+
# If you do *not* want a trailing space after a keyword, end it with a < character.
|
12
|
+
# (See Chinese for examples).
|
13
|
+
#
|
9
14
|
"en":
|
10
15
|
name: English
|
11
16
|
native: English
|
@@ -20,10 +25,6 @@
|
|
20
25
|
and: "*|And"
|
21
26
|
but: "*|But"
|
22
27
|
|
23
|
-
# Please help us keeping the languages below uptodate. The parsers for a language
|
24
|
-
# that is missing a keyword will expect the English word until the missing word(s)
|
25
|
-
# are added.
|
26
|
-
#
|
27
28
|
# Please keep the grammars in alphabetical order by name from here and down.
|
28
29
|
|
29
30
|
"ar":
|
@@ -52,20 +53,20 @@
|
|
52
53
|
then: "*|То"
|
53
54
|
and: "*|И"
|
54
55
|
but: "*|Но"
|
55
|
-
"
|
56
|
+
"ca":
|
56
57
|
name: Catalan
|
57
58
|
native: català
|
58
59
|
background: Rerefons|Antecedents
|
59
|
-
feature: Característica
|
60
|
+
feature: Característica|Funcionalitat
|
60
61
|
scenario: Escenari
|
61
62
|
scenario_outline: Esquema de l'escenari
|
62
63
|
examples: Exemples
|
63
|
-
given: "*|Donat|Donada"
|
64
|
+
given: "*|Donat|Donada|Atès|Atesa"
|
64
65
|
when: "*|Quan"
|
65
|
-
then: "*|Aleshores"
|
66
|
+
then: "*|Aleshores|Cal"
|
66
67
|
and: "*|I"
|
67
68
|
but: "*|Però"
|
68
|
-
"cy":
|
69
|
+
"cy-GB":
|
69
70
|
name: Welsh
|
70
71
|
native: Cymraeg
|
71
72
|
background: Cefndir
|
@@ -112,7 +113,7 @@
|
|
112
113
|
scenario: Szenario
|
113
114
|
scenario_outline: Szenariogrundriss
|
114
115
|
examples: Beispiele
|
115
|
-
given: "*|Gegeben sei"
|
116
|
+
given: "*|Angenommen|Gegeben sei"
|
116
117
|
when: "*|Wenn"
|
117
118
|
then: "*|Dann"
|
118
119
|
and: "*|Und"
|
@@ -143,6 +144,19 @@
|
|
143
144
|
then: "*|DEN"
|
144
145
|
and: "*|AN"
|
145
146
|
but: "*|BUT"
|
147
|
+
"en-Scouse":
|
148
|
+
name: Scouse
|
149
|
+
native: Scouse
|
150
|
+
feature: Feature
|
151
|
+
background: "Dis is what went down"
|
152
|
+
scenario: "The thing of it is"
|
153
|
+
scenario_outline: "Wharrimean is"
|
154
|
+
examples: Examples
|
155
|
+
given: "*|Givun|Youse know when youse got"
|
156
|
+
when: "*|Wun|Youse know like when"
|
157
|
+
then: "*|Dun|Den youse gotta"
|
158
|
+
and: "*|An"
|
159
|
+
but: "*|Buh"
|
146
160
|
"en-tx":
|
147
161
|
name: Texan
|
148
162
|
native: Texan
|
@@ -294,11 +308,11 @@
|
|
294
308
|
scenario: 시나리오
|
295
309
|
scenario_outline: 시나리오 개요
|
296
310
|
examples: 예
|
297
|
-
given: "
|
298
|
-
when: "
|
311
|
+
given: "*|조건<|먼저<"
|
312
|
+
when: "*|만일<|만약<"
|
299
313
|
then: "*|그러면<"
|
300
314
|
and: "*|그리고<"
|
301
|
-
but: "
|
315
|
+
but: "*|하지만<|단<"
|
302
316
|
"lt":
|
303
317
|
name: Lithuanian
|
304
318
|
native: lietuvių kalba
|
@@ -390,7 +404,7 @@
|
|
390
404
|
then: "*|Atunci"
|
391
405
|
and: "*|Si"
|
392
406
|
but: "*|Dar"
|
393
|
-
"
|
407
|
+
"ro-RO":
|
394
408
|
name: Romanian (diacritical)
|
395
409
|
native: română (diacritical)
|
396
410
|
background: Condiţii
|
@@ -416,7 +430,7 @@
|
|
416
430
|
then: "*|То"
|
417
431
|
and: "*|И|К тому же"
|
418
432
|
but: "*|Но|А"
|
419
|
-
"
|
433
|
+
"sv":
|
420
434
|
name: Swedish
|
421
435
|
native: Svenska
|
422
436
|
feature: Egenskap
|
@@ -443,8 +457,8 @@
|
|
443
457
|
and: "*|A"
|
444
458
|
but: "*|Ale"
|
445
459
|
"sr-Latn":
|
446
|
-
name:
|
447
|
-
native:
|
460
|
+
name: Serbian (Latin)
|
461
|
+
native: Srpski (Latinica)
|
448
462
|
feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
|
449
463
|
background: Kontekst|Osnova|Pozadina
|
450
464
|
scenario: Scenario|Primer
|
@@ -455,7 +469,7 @@
|
|
455
469
|
then: "*|Onda"
|
456
470
|
and: "*|I"
|
457
471
|
but: "*|Ali"
|
458
|
-
"sr":
|
472
|
+
"sr-Cyrl":
|
459
473
|
name: Serbian
|
460
474
|
native: Српски
|
461
475
|
feature: Функционалност|Могућност|Особина
|
data/lib/gherkin/i18n_lexer.rb
CHANGED
@@ -1,29 +1,73 @@
|
|
1
|
-
require 'gherkin/lexer'
|
2
1
|
require 'gherkin/i18n'
|
3
2
|
|
4
3
|
module Gherkin
|
4
|
+
I18nLexerNotFound = Class.new(LoadError)
|
5
|
+
LexingError = Class.new(StandardError)
|
6
|
+
|
5
7
|
# The main entry point to lexing Gherkin source.
|
6
8
|
class I18nLexer
|
7
9
|
LANGUAGE_PATTERN = /language\s*:\s*(.*)/ #:nodoc:
|
8
10
|
|
9
|
-
attr_reader :
|
11
|
+
attr_reader :i18n_language
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def new(parser, force_ruby)
|
15
|
+
if !force_ruby && defined?(JRUBY_VERSION)
|
16
|
+
require 'gherkin.jar'
|
17
|
+
Java::Gherkin::I18nLexer.new(parser)
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def lexer_class(i18n_lang, force_ruby)
|
24
|
+
begin
|
25
|
+
if force_ruby
|
26
|
+
rb[i18n_lang]
|
27
|
+
else
|
28
|
+
begin
|
29
|
+
c[i18n_lang]
|
30
|
+
rescue NameError, LoadError => e
|
31
|
+
warn("WARNING: #{e.message}. Reverting to Ruby lexer.")
|
32
|
+
rb[i18n_lang]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
rescue LoadError => e
|
36
|
+
raise I18nLexerNotFound, "No lexer was found for #{i18n_lang} (#{e.message}). Supported languages are listed in gherkin/i18n.yml."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def i18n_language(source)
|
41
|
+
line_one = source.split(/\n/)[0]
|
42
|
+
match = LANGUAGE_PATTERN.match(line_one)
|
43
|
+
I18n.get(match ? match[1] : 'en').key
|
44
|
+
end
|
45
|
+
|
46
|
+
def c
|
47
|
+
require 'gherkin/c_lexer'
|
48
|
+
CLexer
|
49
|
+
end
|
50
|
+
|
51
|
+
def csharp
|
52
|
+
require 'gherkin/csharp_lexer'
|
53
|
+
CSharpLexer
|
54
|
+
end
|
10
55
|
|
11
|
-
|
56
|
+
def rb
|
57
|
+
require 'gherkin/rb_lexer'
|
58
|
+
RbLexer
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize(parser, force_ruby)
|
12
63
|
@parser = parser
|
64
|
+
@force_ruby = force_ruby
|
13
65
|
end
|
14
66
|
|
15
67
|
def scan(source)
|
16
|
-
@
|
17
|
-
delegate =
|
68
|
+
@i18n_language = self.class.i18n_language(source)
|
69
|
+
delegate = self.class.lexer_class(@i18n_language, @force_ruby).new(@parser)
|
18
70
|
delegate.scan(source)
|
19
71
|
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def lang(source)
|
24
|
-
line_one = source.split(/\n/)[0]
|
25
|
-
match = LANGUAGE_PATTERN.match(line_one)
|
26
|
-
I18n.get(match ? match[1] : 'en')
|
27
|
-
end
|
28
72
|
end
|
29
73
|
end
|
data/lib/gherkin/lexer.rb
CHANGED
@@ -1,24 +1,15 @@
|
|
1
1
|
module Gherkin
|
2
2
|
module Lexer
|
3
|
-
I18nLexerNotFound = Class.new(LoadError)
|
4
|
-
LexingError = Class.new(StandardError)
|
5
3
|
|
6
4
|
class << self
|
7
5
|
def [](i18n_lang)
|
8
6
|
begin
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
begin
|
16
|
-
c[i18n_lang]
|
17
|
-
rescue NameError, LoadError => e
|
18
|
-
warn("WARNING: #{e.message}. Reverting to Ruby lexer.") unless defined?(@warned)
|
19
|
-
@warned = true
|
20
|
-
rb[i18n_lang]
|
21
|
-
end
|
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]
|
22
13
|
end
|
23
14
|
rescue LoadError => e
|
24
15
|
raise I18nLexerNotFound, "No lexer was found for #{i18n_lang} (#{e.message}). Supported languages are listed in gherkin/i18n.yml."
|
@@ -30,9 +21,9 @@ module Gherkin
|
|
30
21
|
CLexer
|
31
22
|
end
|
32
23
|
|
33
|
-
def
|
34
|
-
require 'gherkin/
|
35
|
-
|
24
|
+
def csharp
|
25
|
+
require 'gherkin/csharp_lexer'
|
26
|
+
CSharpLexer
|
36
27
|
end
|
37
28
|
|
38
29
|
def rb
|
data/lib/gherkin/parser.rb
CHANGED
@@ -6,13 +6,13 @@ module Gherkin
|
|
6
6
|
end
|
7
7
|
|
8
8
|
class Parser
|
9
|
-
def self.new(listener, raise_on_error=false,
|
9
|
+
def self.new(listener, raise_on_error=false, machine_name='root')
|
10
10
|
if defined?(JRUBY_VERSION)
|
11
11
|
require 'gherkin.jar'
|
12
|
-
Java::Gherkin::Parser.new(listener, raise_on_error,
|
12
|
+
Java::Gherkin::Parser.new(listener, raise_on_error, machine_name)
|
13
13
|
else
|
14
14
|
require 'gherkin/rb_parser'
|
15
|
-
Gherkin::RbParser.new(listener, raise_on_error,
|
15
|
+
Gherkin::RbParser.new(listener, raise_on_error, machine_name)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
data/lib/gherkin/parser/meta.txt
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
| | feature | background | scenario | scenario_outline | examples | step |
|
2
|
-
| meta | E | E | E | E | E | E | E | E | comment | tag |
|
3
|
-
| comment | pop() | pop() | pop() | pop() | pop() | pop() | pop() | pop() | pop() | tag |
|
4
|
-
| tag | pop() | E | pop() | pop() | pop() | E | E | E | E | tag |
|
1
|
+
| | feature | background | scenario | scenario_outline | examples | step | row | py_string | eof | comment | tag |
|
2
|
+
| meta | E | E | E | E | E | E | E | E | eof | comment | tag |
|
3
|
+
| comment | pop() | pop() | pop() | pop() | pop() | pop() | pop() | pop() | eof | pop() | tag |
|
4
|
+
| tag | pop() | E | pop() | pop() | pop() | E | E | E | E | E | tag |
|
5
|
+
| eof | E | E | E | E | E | E | E | E | E | E | E |
|
data/lib/gherkin/parser/root.txt
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
| | feature | background | scenario | scenario_outline | examples | step
|
2
|
-
| root | feature | E | E | E | E | E
|
3
|
-
| feature | E | background | scenario | scenario_outline | E | E
|
4
|
-
| step | E | E | scenario | scenario_outline |
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
| | feature | background | scenario | scenario_outline | examples | step | row | py_string | eof | comment | tag |
|
2
|
+
| root | feature | E | E | E | E | E | E | E | eof | push(meta) | push(meta) |
|
3
|
+
| feature | E | background | scenario | scenario_outline | E | E | E | E | eof | push(meta) | push(meta) |
|
4
|
+
| step | E | E | scenario | scenario_outline | E | step | step | step | eof | push(meta) | push(meta) |
|
5
|
+
| outline_step | E | E | scenario | scenario_outline | examples | outline_step | outline_step | outline_step | eof | push(meta) | push(meta) |
|
6
|
+
| background | E | E | scenario | scenario_outline | E | step | E | E | eof | push(meta) | push(meta) |
|
7
|
+
| scenario | E | E | scenario | scenario_outline | E | step | E | E | eof | push(meta) | push(meta) |
|
8
|
+
| scenario_outline | E | E | E | E | E | outline_step | E | E | eof | push(meta) | push(meta) |
|
9
|
+
| examples | E | E | E | E | E | E | examples_table | E | eof | push(meta) | push(meta) |
|
10
|
+
| examples_table | E | E | scenario | scenario_outline | examples | E | examples_table | E | eof | push(meta) | push(meta) |
|
11
|
+
| eof | E | E | E | E | E | E | E | E | E | E | E |
|
@@ -1,3 +1,4 @@
|
|
1
|
-
| | feature | background | scenario | scenario_outline | examples | step |
|
2
|
-
| steps | E | E | E | E | E | step | E
|
3
|
-
| step | E | E | E | E | E | step |
|
1
|
+
| | feature | background | scenario | scenario_outline | examples | step | row | py_string | eof | comment | tag |
|
2
|
+
| steps | E | E | E | E | E | step | E | E | eof | E | E |
|
3
|
+
| step | E | E | E | E | E | step | step | steps | eof | E | E |
|
4
|
+
| eof | E | E | E | E | E | E | E | E | E | E | E |
|
data/lib/gherkin/rb_parser.rb
CHANGED
@@ -77,7 +77,7 @@ module Gherkin
|
|
77
77
|
|
78
78
|
def expected
|
79
79
|
allowed = @transition_map[@state].find_all { |_, action| action != "E" }
|
80
|
-
allowed.collect { |state| state[0] }.sort
|
80
|
+
allowed.collect { |state| state[0] }.sort - ['eof']
|
81
81
|
end
|
82
82
|
|
83
83
|
private
|
@@ -100,18 +100,26 @@ module Gherkin
|
|
100
100
|
|
101
101
|
def transition_table(name)
|
102
102
|
state_machine_reader = StateMachineReader.new
|
103
|
-
lexer = Gherkin::
|
103
|
+
lexer = Gherkin::I18nLexer.lexer_class('en', false).new(state_machine_reader)
|
104
104
|
lexer.scan(File.read(File.dirname(__FILE__) + "/parser/#{name}.txt"))
|
105
105
|
state_machine_reader.rows
|
106
106
|
end
|
107
107
|
|
108
108
|
class StateMachineReader
|
109
109
|
attr_reader :rows
|
110
|
-
|
111
|
-
|
110
|
+
|
111
|
+
def initialize
|
112
|
+
@rows = []
|
113
|
+
end
|
114
|
+
|
115
|
+
def row(row, line_number)
|
116
|
+
@rows << row
|
117
|
+
end
|
118
|
+
|
119
|
+
def eof
|
112
120
|
end
|
113
121
|
end
|
114
122
|
|
115
123
|
end
|
116
124
|
end
|
117
|
-
end
|
125
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'term/ansicolor'
|
2
|
+
|
3
|
+
module Gherkin
|
4
|
+
module Tools
|
5
|
+
# Defines aliases for coloured output. You don't invoke any methods from this
|
6
|
+
# module directly, but you can change the output colours by defining
|
7
|
+
# a <tt>GHERKIN_COLORS</tt> variable in your shell, very much like how you can
|
8
|
+
# tweak the familiar POSIX command <tt>ls</tt> with
|
9
|
+
# <a href="http://mipsisrisc.com/rambling/2008/06/27/lscolorsls_colors-now-with-linux-support/">$LSCOLORS/$LS_COLORS</a>
|
10
|
+
#
|
11
|
+
# The colours that you can change are:
|
12
|
+
#
|
13
|
+
# * <tt>undefined</tt> - defaults to <tt>yellow</tt>
|
14
|
+
# * <tt>pending</tt> - defaults to <tt>yellow</tt>
|
15
|
+
# * <tt>pending_param</tt> - defaults to <tt>yellow,bold</tt>
|
16
|
+
# * <tt>failed</tt> - defaults to <tt>red</tt>
|
17
|
+
# * <tt>failed_param</tt> - defaults to <tt>red,bold</tt>
|
18
|
+
# * <tt>passed</tt> - defaults to <tt>green</tt>
|
19
|
+
# * <tt>passed_param</tt> - defaults to <tt>green,bold</tt>
|
20
|
+
# * <tt>outline</tt> - defaults to <tt>cyan</tt>
|
21
|
+
# * <tt>outline_param</tt> - defaults to <tt>cyan,bold</tt>
|
22
|
+
# * <tt>skipped</tt> - defaults to <tt>cyan</tt>
|
23
|
+
# * <tt>skipped_param</tt> - defaults to <tt>cyan,bold</tt>
|
24
|
+
# * <tt>comment</tt> - defaults to <tt>grey</tt>
|
25
|
+
# * <tt>tag</tt> - defaults to <tt>cyan</tt>
|
26
|
+
#
|
27
|
+
# For instance, if your shell has a black background and a green font (like the
|
28
|
+
# "Homebrew" settings for OS X' Terminal.app), you may want to override passed
|
29
|
+
# steps to be white instead of green. Examples:
|
30
|
+
#
|
31
|
+
# export GHERKIN_COLORS="passed=white"
|
32
|
+
# export GHERKIN_COLORS="passed=white,bold:passed_param=white,bold,underline"
|
33
|
+
#
|
34
|
+
# (If you're on Windows, use SET instead of export).
|
35
|
+
# To see what colours and effects are available, just run this in your shell:
|
36
|
+
#
|
37
|
+
# ruby -e "require 'rubygems'; require 'term/ansicolor'; puts Term::ANSIColor.attributes"
|
38
|
+
#
|
39
|
+
# Although not listed, you can also use <tt>grey</tt>
|
40
|
+
module Colors
|
41
|
+
include Term::ANSIColor
|
42
|
+
|
43
|
+
ALIASES = Hash.new do |h,k|
|
44
|
+
if k.to_s =~ /(.*)_param/
|
45
|
+
h[$1] + ',bold'
|
46
|
+
end
|
47
|
+
end.merge({
|
48
|
+
'undefined' => 'yellow',
|
49
|
+
'pending' => 'yellow',
|
50
|
+
'failed' => 'red',
|
51
|
+
'passed' => 'green',
|
52
|
+
'outline' => 'cyan',
|
53
|
+
'skipped' => 'cyan',
|
54
|
+
'comments' => 'grey',
|
55
|
+
'tag' => 'cyan'
|
56
|
+
})
|
57
|
+
|
58
|
+
if ENV['GHERKIN_COLORS'] # Example: export GHERKIN_COLORS="passed=red:failed=yellow"
|
59
|
+
ENV['GHERKIN_COLORS'].split(':').each do |pair|
|
60
|
+
a = pair.split('=')
|
61
|
+
ALIASES[a[0]] = a[1]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
ALIASES.each do |method, color|
|
66
|
+
unless method =~ /.*_param/
|
67
|
+
code = <<-EOF
|
68
|
+
def #{method}(string=nil, monochrome=false, &proc)
|
69
|
+
return string if monochrome
|
70
|
+
#{ALIASES[method].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method].split(",").length}
|
71
|
+
end
|
72
|
+
# This resets the colour to the non-param colour
|
73
|
+
def #{method}_param(string=nil, monochrome=false, &proc)
|
74
|
+
return string if monochrome
|
75
|
+
#{ALIASES[method+'_param'].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method+'_param'].split(",").length} + #{ALIASES[method].split(",").join(' + ')}
|
76
|
+
end
|
77
|
+
EOF
|
78
|
+
eval(code)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.define_grey #:nodoc:
|
83
|
+
begin
|
84
|
+
gem 'genki-ruby-terminfo'
|
85
|
+
require 'terminfo'
|
86
|
+
case TermInfo.default_object.tigetnum("colors")
|
87
|
+
when 0
|
88
|
+
raise "Your terminal doesn't support colours"
|
89
|
+
when 1
|
90
|
+
::Term::ANSIColor.coloring = false
|
91
|
+
alias grey white
|
92
|
+
when 2..8
|
93
|
+
alias grey white
|
94
|
+
else
|
95
|
+
define_real_grey
|
96
|
+
end
|
97
|
+
rescue Exception => e
|
98
|
+
if e.class.name == 'TermInfo::TermInfoError'
|
99
|
+
STDERR.puts "*** WARNING ***"
|
100
|
+
STDERR.puts "You have the genki-ruby-terminfo gem installed, but you haven't set your TERM variable."
|
101
|
+
STDERR.puts "Try setting it to TERM=xterm-256color to get grey colour in output"
|
102
|
+
STDERR.puts "\n"
|
103
|
+
alias grey white
|
104
|
+
else
|
105
|
+
define_real_grey
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.define_real_grey #:nodoc:
|
111
|
+
def grey(m) #:nodoc:
|
112
|
+
"\e[90m#{m}\e[0m"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
define_grey
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|