gherkin 1.0.2-i386-mswin32 → 1.0.3-i386-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/.gitattributes +1 -0
  2. data/History.txt +18 -0
  3. data/README.rdoc +12 -1
  4. data/Rakefile +4 -2
  5. data/VERSION.yml +1 -1
  6. data/bin/gherkin +1 -1
  7. data/dotnet/.gitignore +13 -0
  8. data/features/feature_parser.feature +22 -2
  9. data/features/native_lexer.feature +1 -1
  10. data/features/parser_with_native_lexer.feature +1 -1
  11. data/features/step_definitions/gherkin_steps.rb +2 -6
  12. data/features/step_definitions/pretty_printer_steps.rb +2 -3
  13. data/features/steps_parser.feature +1 -1
  14. data/gherkin.gemspec +40 -13
  15. data/java/Gherkin.iml +2 -4
  16. data/java/build.xml +3 -0
  17. data/java/src/gherkin/FixJava.java +6 -3
  18. data/java/src/gherkin/I18nLexer.java +48 -0
  19. data/java/src/gherkin/Listener.java +3 -1
  20. data/java/src/gherkin/Main.java +17 -0
  21. data/java/src/gherkin/Parser.java +9 -3
  22. data/java/src/gherkin/formatter/Argument.java +39 -0
  23. data/java/src/gherkin/formatter/ArgumentFormat.java +17 -0
  24. data/java/src/gherkin/formatter/Colors.java +7 -0
  25. data/java/src/gherkin/formatter/Formatter.java +15 -0
  26. data/java/src/gherkin/formatter/PrettyFormatter.java +219 -0
  27. data/java/src/gherkin/parser/StateMachineReader.java +8 -3
  28. data/java/test/gherkin/formatter/ArgumentTest.java +17 -0
  29. data/lib/gherkin/csharp_lexer.rb +15 -0
  30. data/lib/gherkin/format/argument.rb +35 -0
  31. data/lib/gherkin/format/monochrome_format.rb +9 -0
  32. data/lib/gherkin/i18n.rb +22 -0
  33. data/lib/gherkin/i18n.yml +34 -20
  34. data/lib/gherkin/i18n_lexer.rb +57 -13
  35. data/lib/gherkin/lexer.rb +9 -18
  36. data/lib/gherkin/parser.rb +3 -3
  37. data/lib/gherkin/parser/meta.txt +5 -4
  38. data/lib/gherkin/parser/root.txt +11 -9
  39. data/lib/gherkin/parser/steps.txt +4 -3
  40. data/lib/gherkin/rb_parser.rb +13 -5
  41. data/lib/gherkin/tools/colors.rb +119 -0
  42. data/lib/gherkin/tools/files.rb +6 -1
  43. data/lib/gherkin/tools/pretty_listener.rb +115 -23
  44. data/ragel/lexer.c.rl.erb +67 -51
  45. data/ragel/lexer.csharp.rl.erb +240 -0
  46. data/ragel/lexer.java.rl.erb +27 -18
  47. data/ragel/lexer.rb.rl.erb +17 -17
  48. data/ragel/lexer_common.rl.erb +8 -8
  49. data/spec/gherkin/c_lexer_spec.rb +4 -4
  50. data/spec/gherkin/csharp_lexer_spec.rb +20 -0
  51. data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
  52. data/spec/gherkin/fixtures/complex.feature +2 -0
  53. data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
  54. data/spec/gherkin/fixtures/i18n_fr.feature +1 -0
  55. data/spec/gherkin/fixtures/i18n_no.feature +1 -0
  56. data/spec/gherkin/fixtures/i18n_zh-CN.feature +1 -0
  57. data/spec/gherkin/format/argument_spec.rb +28 -0
  58. data/spec/gherkin/i18n_lexer_spec.rb +4 -4
  59. data/spec/gherkin/i18n_spec.rb +31 -23
  60. data/spec/gherkin/java_lexer_spec.rb +4 -3
  61. data/spec/gherkin/parser_spec.rb +5 -0
  62. data/spec/gherkin/rb_lexer_spec.rb +4 -2
  63. data/spec/gherkin/sexp_recorder.rb +1 -1
  64. data/spec/gherkin/shared/lexer_spec.rb +169 -60
  65. data/spec/gherkin/shared/py_string_spec.rb +6 -0
  66. data/spec/gherkin/shared/row_spec.rb +107 -0
  67. data/spec/gherkin/shared/tags_spec.rb +1 -1
  68. data/spec/gherkin/tools/colors_spec.rb +19 -0
  69. data/spec/gherkin/tools/pretty_listener_spec.rb +147 -0
  70. data/spec/spec_helper.rb +31 -7
  71. data/tasks/compile.rake +81 -7
  72. data/tasks/ragel_task.rb +6 -4
  73. data/tasks/rspec.rake +2 -2
  74. metadata +86 -26
  75. data/lib/gherkin/java_lexer.rb +0 -10
  76. data/spec/gherkin/shared/table_spec.rb +0 -97
@@ -0,0 +1,9 @@
1
+ module Gherkin
2
+ module Format
3
+ class MonochromeFormat
4
+ def format_argument(arg)
5
+ arg
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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
 
@@ -1,11 +1,16 @@
1
1
  # encoding: UTF-8
2
- # We use the codes here (prefer 2 letters when possible)
3
- # http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
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
- "cat":
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
- "ro2":
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
- "se":
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: Serbian_latin
447
- native: Srpski_latinica
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: Функционалност|Могућност|Особина
@@ -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 :language
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
- def initialize(parser)
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
- @language = lang(source)
17
- delegate = Lexer[@language.key].new(@parser)
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
@@ -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
- # Uncomment the line below (during development) to force use of Ruby lexer
10
- # return rb[i18n_lang]
11
-
12
- if defined?(JRUBY_VERSION)
13
- java[i18n_lang]
14
- else
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 java
34
- require 'gherkin/java_lexer'
35
- JavaLexer
24
+ def csharp
25
+ require 'gherkin/csharp_lexer'
26
+ CSharpLexer
36
27
  end
37
28
 
38
29
  def rb
@@ -6,13 +6,13 @@ module Gherkin
6
6
  end
7
7
 
8
8
  class Parser
9
- def self.new(listener, raise_on_error=false, machine_names='root')
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, machine_names)
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, machine_names)
15
+ Gherkin::RbParser.new(listener, raise_on_error, machine_name)
16
16
  end
17
17
  end
18
18
  end
@@ -1,4 +1,5 @@
1
- | | feature | background | scenario | scenario_outline | examples | step | table | py_string | comment | tag |
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 |
@@ -1,9 +1,11 @@
1
- | | feature | background | scenario | scenario_outline | examples | step | table | py_string | comment | tag |
2
- | root | feature | E | E | E | E | E | E | E | push(meta) | push(meta) |
3
- | feature | E | background | scenario | scenario_outline | E | E | E | E | push(meta) | push(meta) |
4
- | step | E | E | scenario | scenario_outline | examples | step | step | step | push(meta) | push(meta) |
5
- | background | E | E | scenario | scenario_outline | E | step | E | E | push(meta) | push(meta) |
6
- | scenario | E | E | scenario | scenario_outline | E | step | E | E | push(meta) | push(meta) |
7
- | scenario_outline | E | E | E | E | E | step | E | E | push(meta) | push(meta) |
8
- | examples | E | E | E | E | E | E | examples_table | E | push(meta) | push(meta) |
9
- | examples_table | E | E | scenario | scenario_outline | examples | E | E | E | push(meta) | push(meta) |
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 | table | py_string | comment | tag |
2
- | steps | E | E | E | E | E | step | E | E | E | E |
3
- | step | E | E | E | E | E | step | steps | steps | E | E |
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 |
@@ -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::Lexer['en'].new(state_machine_reader)
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
- def table(rows, line_number)
111
- @rows = 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
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