lucid 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/.gitignore +30 -10
  2. data/.rspec +1 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +15 -0
  6. data/Gemfile +4 -2
  7. data/HISTORY.md +22 -0
  8. data/{LICENSE.txt → LICENSE} +6 -3
  9. data/README.md +22 -8
  10. data/Rakefile +2 -1
  11. data/bin/lucid +10 -10
  12. data/bin/lucid-gen +4 -0
  13. data/lib/autotest/discover.rb +11 -0
  14. data/lib/autotest/lucid.rb +6 -0
  15. data/lib/autotest/lucid_mixin.rb +135 -0
  16. data/lib/autotest/lucid_rails.rb +6 -0
  17. data/lib/autotest/lucid_rails_rspec.rb +6 -0
  18. data/lib/autotest/lucid_rails_rspec2.rb +6 -0
  19. data/lib/autotest/lucid_rspec.rb +6 -0
  20. data/lib/autotest/lucid_rspec2.rb +6 -0
  21. data/lib/lucid.rb +32 -1
  22. data/lib/lucid/ast.rb +20 -0
  23. data/lib/lucid/ast/background.rb +116 -0
  24. data/lib/lucid/ast/comment.rb +24 -0
  25. data/lib/lucid/ast/doc_string.rb +44 -0
  26. data/lib/lucid/ast/empty_background.rb +33 -0
  27. data/lib/lucid/ast/examples.rb +49 -0
  28. data/lib/lucid/ast/feature.rb +99 -0
  29. data/lib/lucid/ast/has_steps.rb +74 -0
  30. data/lib/lucid/ast/location.rb +41 -0
  31. data/lib/lucid/ast/multiline_argument.rb +31 -0
  32. data/lib/lucid/ast/names.rb +13 -0
  33. data/lib/lucid/ast/outline_table.rb +194 -0
  34. data/lib/lucid/ast/scenario.rb +103 -0
  35. data/lib/lucid/ast/scenario_outline.rb +144 -0
  36. data/lib/lucid/ast/specs.rb +38 -0
  37. data/lib/lucid/ast/step.rb +122 -0
  38. data/lib/lucid/ast/step_collection.rb +92 -0
  39. data/lib/lucid/ast/step_invocation.rb +196 -0
  40. data/lib/lucid/ast/table.rb +730 -0
  41. data/lib/lucid/ast/tags.rb +28 -0
  42. data/lib/lucid/ast/tdl_walker.rb +195 -0
  43. data/lib/lucid/cli/app.rb +78 -0
  44. data/lib/lucid/cli/configuration.rb +261 -0
  45. data/lib/lucid/cli/options.rb +463 -0
  46. data/lib/lucid/cli/profile.rb +101 -0
  47. data/lib/lucid/configuration.rb +53 -0
  48. data/lib/lucid/core_ext/disable_autorunners.rb +15 -0
  49. data/lib/lucid/core_ext/instance_exec.rb +70 -0
  50. data/lib/lucid/core_ext/proc.rb +36 -0
  51. data/lib/lucid/core_ext/string.rb +9 -0
  52. data/lib/lucid/errors.rb +40 -0
  53. data/lib/lucid/factory.rb +43 -0
  54. data/lib/lucid/formatter/ansicolor.rb +168 -0
  55. data/lib/lucid/formatter/console.rb +218 -0
  56. data/lib/lucid/formatter/debug.rb +33 -0
  57. data/lib/lucid/formatter/duration.rb +11 -0
  58. data/lib/lucid/formatter/gherkin_formatter_adapter.rb +94 -0
  59. data/lib/lucid/formatter/gpretty.rb +24 -0
  60. data/lib/lucid/formatter/html.rb +610 -0
  61. data/lib/lucid/formatter/interceptor.rb +66 -0
  62. data/lib/lucid/formatter/io.rb +31 -0
  63. data/lib/lucid/formatter/jquery-min.js +154 -0
  64. data/lib/lucid/formatter/json.rb +19 -0
  65. data/lib/lucid/formatter/json_pretty.rb +10 -0
  66. data/lib/lucid/formatter/junit.rb +177 -0
  67. data/lib/lucid/formatter/lucid.css +283 -0
  68. data/lib/lucid/formatter/lucid.sass +244 -0
  69. data/lib/lucid/formatter/ordered_xml_markup.rb +24 -0
  70. data/lib/lucid/formatter/progress.rb +95 -0
  71. data/lib/lucid/formatter/rerun.rb +91 -0
  72. data/lib/lucid/formatter/standard.rb +235 -0
  73. data/lib/lucid/formatter/stepdefs.rb +14 -0
  74. data/lib/lucid/formatter/steps.rb +49 -0
  75. data/lib/lucid/formatter/summary.rb +35 -0
  76. data/lib/lucid/formatter/unicode.rb +53 -0
  77. data/lib/lucid/formatter/usage.rb +132 -0
  78. data/lib/lucid/generator.rb +21 -0
  79. data/lib/lucid/generators/project.rb +70 -0
  80. data/lib/lucid/generators/project/Gemfile.tt +6 -0
  81. data/lib/lucid/generators/project/browser-symbiont.rb +24 -0
  82. data/lib/lucid/generators/project/driver-symbiont.rb +4 -0
  83. data/lib/lucid/generators/project/errors.rb +26 -0
  84. data/lib/lucid/generators/project/events-symbiont.rb +36 -0
  85. data/lib/lucid/generators/project/lucid-symbiont.yml +6 -0
  86. data/lib/lucid/interface.rb +8 -0
  87. data/lib/lucid/interface_methods.rb +125 -0
  88. data/lib/lucid/interface_rb/matcher.rb +108 -0
  89. data/lib/lucid/interface_rb/rb_hook.rb +18 -0
  90. data/lib/lucid/interface_rb/rb_language.rb +190 -0
  91. data/lib/lucid/interface_rb/rb_lucid.rb +119 -0
  92. data/lib/lucid/interface_rb/rb_step_definition.rb +122 -0
  93. data/lib/lucid/interface_rb/rb_transform.rb +57 -0
  94. data/lib/lucid/interface_rb/rb_world.rb +136 -0
  95. data/lib/lucid/interface_rb/regexp_argument_matcher.rb +21 -0
  96. data/lib/lucid/load_path.rb +13 -0
  97. data/lib/lucid/parser.rb +2 -126
  98. data/lib/lucid/platform.rb +27 -0
  99. data/lib/lucid/rspec/allow_doubles.rb +20 -0
  100. data/lib/lucid/rspec/disallow_options.rb +27 -0
  101. data/lib/lucid/runtime.rb +200 -0
  102. data/lib/lucid/runtime/facade.rb +60 -0
  103. data/lib/lucid/runtime/interface_io.rb +60 -0
  104. data/lib/lucid/runtime/orchestrator.rb +218 -0
  105. data/lib/lucid/runtime/results.rb +64 -0
  106. data/lib/lucid/runtime/specs_loader.rb +79 -0
  107. data/lib/lucid/spec_file.rb +112 -0
  108. data/lib/lucid/step_definition_light.rb +20 -0
  109. data/lib/lucid/step_definitions.rb +13 -0
  110. data/lib/lucid/step_match.rb +99 -0
  111. data/lib/lucid/tdl_builder.rb +282 -0
  112. data/lib/lucid/term/ansicolor.rb +118 -0
  113. data/lib/lucid/unit.rb +11 -0
  114. data/lib/lucid/wire_support/configuration.rb +38 -0
  115. data/lib/lucid/wire_support/connection.rb +61 -0
  116. data/lib/lucid/wire_support/request_handler.rb +32 -0
  117. data/lib/lucid/wire_support/wire_exception.rb +32 -0
  118. data/lib/lucid/wire_support/wire_language.rb +54 -0
  119. data/lib/lucid/wire_support/wire_packet.rb +34 -0
  120. data/lib/lucid/wire_support/wire_protocol.rb +43 -0
  121. data/lib/lucid/wire_support/wire_protocol/requests.rb +125 -0
  122. data/lib/lucid/wire_support/wire_step_definition.rb +26 -0
  123. data/lucid.gemspec +25 -14
  124. metadata +220 -12
  125. data/lib/lucid/app.rb +0 -103
  126. data/lib/lucid/options.rb +0 -168
  127. data/lib/lucid/version.rb +0 -3
  128. data/lucid.yml +0 -8
@@ -0,0 +1,20 @@
1
+ module Lucid
2
+ # Only used for keeping track of available and invoked step definitions
3
+ # in a way that also works for other programming languages (i.e. cuke4duke)
4
+ # Used for reporting purposes only (usage formatter).
5
+ class StepDefinitionLight
6
+ attr_reader :regexp_source, :file_colon_line
7
+
8
+ def initialize(regexp_source, file_colon_line)
9
+ @regexp_source, @file_colon_line = regexp_source, file_colon_line
10
+ end
11
+
12
+ def eql?(o)
13
+ regexp_source == o.regexp_source && file_colon_line == o.file_colon_line
14
+ end
15
+
16
+ def hash
17
+ regexp_source.hash + 31*file_colon_line.hash
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Lucid
2
+ class StepDefinitions
3
+ def initialize(configuration = Configuration.default)
4
+ configuration = Configuration.parse(configuration)
5
+ @orchestrator = Runtime::Orchestrator.new(nil, false)
6
+ @orchestrator.load_files_from_paths(configuration.autoload_code_paths)
7
+ end
8
+
9
+ def to_json
10
+ @orchestrator.step_definitions.map{|stepdef| stepdef.to_hash}.to_json
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,99 @@
1
+ module Lucid
2
+ class StepMatch #:nodoc:
3
+ attr_reader :step_definition, :step_arguments
4
+
5
+ def initialize(step_definition, name_to_match, name_to_report, step_arguments)
6
+ raise "name_to_match can't be nil" if name_to_match.nil?
7
+ raise "step_arguments can't be nil (but it can be an empty array)" if step_arguments.nil?
8
+ @step_definition = step_definition
9
+ @name_to_match = name_to_match
10
+ @name_to_report = name_to_report
11
+ @step_arguments = step_arguments
12
+ end
13
+
14
+ def args
15
+ @step_arguments.map{|g| g.val}
16
+ end
17
+
18
+ def name
19
+ @name_to_report
20
+ end
21
+
22
+ def invoke(multiline_arg)
23
+ all_args = args
24
+ all_args << multiline_arg.to_step_definition_arg if multiline_arg
25
+ @step_definition.invoke(all_args)
26
+ end
27
+
28
+ def format_args(format = lambda{|a| a}, &proc)
29
+ @name_to_report || replace_arguments(@name_to_match, @step_arguments, format, &proc)
30
+ end
31
+
32
+ def file_colon_line
33
+ @step_definition.file_colon_line
34
+ end
35
+
36
+ def backtrace_line
37
+ "#{file_colon_line}:in `#{@step_definition.regexp_source}'"
38
+ end
39
+
40
+ def text_length
41
+ @step_definition.regexp_source.unpack('U*').length
42
+ end
43
+
44
+ def replace_arguments(string, step_arguments, format, &proc)
45
+ s = string.dup
46
+ offset = past_offset = 0
47
+ step_arguments.each do |step_argument|
48
+ next if step_argument.offset.nil? || step_argument.offset < past_offset
49
+
50
+ replacement = if block_given?
51
+ proc.call(step_argument.val)
52
+ elsif Proc === format
53
+ format.call(step_argument.val)
54
+ else
55
+ format % step_argument.val
56
+ end
57
+
58
+ s[step_argument.offset + offset, step_argument.val.length] = replacement
59
+ offset += replacement.unpack('U*').length - step_argument.val.unpack('U*').length
60
+ past_offset = step_argument.offset + step_argument.val.length
61
+ end
62
+ s
63
+ end
64
+
65
+ def inspect #:nodoc:
66
+ sprintf("#<%s:0x%x>", self.class, self.object_id)
67
+ end
68
+ end
69
+
70
+ class NoStepMatch #:nodoc:
71
+ attr_reader :step_definition, :name
72
+
73
+ def initialize(step, name)
74
+ @step = step
75
+ @name = name
76
+ end
77
+
78
+ def format_args(format)
79
+ @name
80
+ end
81
+
82
+ def file_colon_line
83
+ raise "No file:line for #{@step}" unless @step.file_colon_line
84
+ @step.file_colon_line
85
+ end
86
+
87
+ def backtrace_line
88
+ @step.backtrace_line
89
+ end
90
+
91
+ def text_length
92
+ @step.text_length
93
+ end
94
+
95
+ def step_arguments
96
+ []
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,282 @@
1
+ require 'lucid/ast'
2
+ require 'gherkin/rubify'
3
+ require 'lucid/ast/multiline_argument'
4
+ require 'lucid/ast/empty_background'
5
+
6
+ module Lucid
7
+ module Parser
8
+ # The TDL Builder conforms to the Gherkin event API.
9
+ class TDLBuilder
10
+ include Gherkin::Rubify
11
+
12
+ def initialize(path = 'UNKNOWN-FILE')
13
+ @path = path
14
+ end
15
+
16
+ def result
17
+ return nil unless @feature_builder
18
+ @feature_builder.result(language)
19
+ end
20
+
21
+ def language=(language)
22
+ @language = language
23
+ end
24
+
25
+ def uri(uri)
26
+ @path = uri
27
+ end
28
+
29
+ def feature(node)
30
+ @feature_builder = FeatureBuilder.new(file, node)
31
+ end
32
+
33
+ def background(node)
34
+ builder = BackgroundBuilder.new(file, node)
35
+ @feature_builder.background_builder = builder
36
+ @current = builder
37
+ end
38
+
39
+ def scenario(node)
40
+ builder = ScenarioBuilder.new(file, node)
41
+ @feature_builder.add_child builder
42
+ @current = builder
43
+ end
44
+
45
+ def scenario_outline(node)
46
+ builder = ScenarioOutlineBuilder.new(file, node)
47
+ @feature_builder.add_child builder
48
+ @current = builder
49
+ end
50
+
51
+ def examples(examples)
52
+ examples_fields = [
53
+ AST::Location.new(file, examples.line),
54
+ AST::Comment.new(examples.comments.map{|comment| comment.value}.join("\n")),
55
+ examples.keyword,
56
+ examples.name,
57
+ examples.description,
58
+ matrix(examples.rows)
59
+ ]
60
+ @current.add_examples examples_fields, examples
61
+ end
62
+
63
+ def step(node)
64
+ builder = StepBuilder.new(file, node)
65
+ @current.add_child builder
66
+ end
67
+
68
+ def eof
69
+ end
70
+
71
+ def syntax_error(state, event, legal_events, line)
72
+ # raise "SYNTAX ERROR"
73
+ end
74
+
75
+ private
76
+
77
+ if defined?(JRUBY_VERSION)
78
+ java_import java.util.ArrayList
79
+ ArrayList.__persistent__ = true
80
+ end
81
+
82
+ def matrix(gherkin_table)
83
+ gherkin_table.map do |gherkin_row|
84
+ row = gherkin_row.cells
85
+ class << row
86
+ attr_accessor :line
87
+ end
88
+ row.line = gherkin_row.line
89
+ row
90
+ end
91
+ end
92
+
93
+ def language
94
+ @language || raise("Language has not been set")
95
+ end
96
+
97
+ def file
98
+ if Lucid::WINDOWS && !ENV['LUCID_FORWARD_SLASH_PATHS']
99
+ @path.gsub(/\//, '\\')
100
+ else
101
+ @path
102
+ end
103
+ end
104
+
105
+ class Builder
106
+ def initialize(file, node)
107
+ @file, @node = file, node
108
+ end
109
+
110
+ private
111
+
112
+ def tags
113
+ AST::Tags.new(nil, node.tags)
114
+ end
115
+
116
+ def location
117
+ AST::Location.new(file, node.line)
118
+ end
119
+
120
+ def comment
121
+ AST::Comment.new(node.comments.map{ |comment| comment.value }.join("\n"))
122
+ end
123
+
124
+ attr_reader :file, :node
125
+ end
126
+
127
+ class FeatureBuilder < Builder
128
+ def result(language)
129
+ background = background(language)
130
+ feature = AST::Feature.new(
131
+ location,
132
+ background,
133
+ comment,
134
+ tags,
135
+ node.keyword,
136
+ node.name.lstrip,
137
+ node.description.rstrip,
138
+ children.map { |builder| builder.result(background, language, tags) }
139
+ )
140
+ feature.gherkin_statement(node)
141
+ feature.language = language
142
+ feature
143
+ end
144
+
145
+ def background_builder=(builder)
146
+ @background_builder = builder
147
+ end
148
+
149
+ def add_child(child)
150
+ children << child
151
+ end
152
+
153
+ def children
154
+ @children ||= []
155
+ end
156
+
157
+ private
158
+
159
+ def background(language)
160
+ return AST::EmptyBackground.new unless @background_builder
161
+ @background ||= @background_builder.result(language)
162
+ end
163
+ end
164
+
165
+ class BackgroundBuilder < Builder
166
+ def result(language)
167
+ background = AST::Background.new(
168
+ language,
169
+ location,
170
+ comment,
171
+ node.keyword,
172
+ node.name,
173
+ node.description,
174
+ steps(language)
175
+ )
176
+ background.gherkin_statement(node)
177
+ background
178
+ end
179
+
180
+ def steps(language)
181
+ children.map { |child| child.result(language) }
182
+ end
183
+
184
+ def add_child(child)
185
+ children << child
186
+ end
187
+
188
+ def children
189
+ @children ||= []
190
+ end
191
+
192
+ end
193
+
194
+ class ScenarioBuilder < Builder
195
+ def result(background, language, feature_tags)
196
+ scenario = AST::Scenario.new(
197
+ language,
198
+ location,
199
+ background,
200
+ comment,
201
+ tags,
202
+ feature_tags,
203
+ node.keyword,
204
+ node.name,
205
+ node.description,
206
+ steps(language)
207
+ )
208
+ scenario.gherkin_statement(node)
209
+ scenario
210
+ end
211
+
212
+ def steps(language)
213
+ children.map { |child| child.result(language) }
214
+ end
215
+
216
+ def add_child(child)
217
+ children << child
218
+ end
219
+
220
+ def children
221
+ @children ||= []
222
+ end
223
+ end
224
+
225
+ class ScenarioOutlineBuilder < Builder
226
+ def result(background, language, feature_tags)
227
+ scenario_outline = AST::ScenarioOutline.new(
228
+ language,
229
+ location,
230
+ background,
231
+ comment,
232
+ tags,
233
+ feature_tags,
234
+ node.keyword,
235
+ node.name,
236
+ node.description,
237
+ steps(language),
238
+ examples_sections
239
+ )
240
+ scenario_outline.gherkin_statement(node)
241
+ scenario_outline
242
+ end
243
+
244
+ def add_examples(examples_section, node)
245
+ @examples_sections ||= []
246
+ @examples_sections << [examples_section, node]
247
+ end
248
+
249
+ def steps(language)
250
+ children.map { |child| child.result(language) }
251
+ end
252
+
253
+ def add_child(child)
254
+ children << child
255
+ end
256
+
257
+ def children
258
+ @children ||= []
259
+ end
260
+
261
+ private
262
+
263
+ attr_reader :examples_sections
264
+ end
265
+
266
+ class StepBuilder < Builder
267
+ def result(language)
268
+ step = AST::Step.new(
269
+ language,
270
+ location,
271
+ node.keyword,
272
+ node.name,
273
+ AST::MultilineArgument.from(node.doc_string || node.rows)
274
+ )
275
+ step.gherkin_statement(node)
276
+ step
277
+ end
278
+ end
279
+
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,118 @@
1
+ module Lucid
2
+ module Term
3
+ # The ANSIColor module can be used for namespacing and mixed into your own
4
+ # classes.
5
+ module ANSIColor
6
+ # :stopdoc:
7
+ ATTRIBUTES = [
8
+ [ :clear , 0 ],
9
+ [ :reset , 0 ], # synonym for :clear
10
+ [ :bold , 1 ],
11
+ [ :dark , 2 ],
12
+ [ :italic , 3 ], # not widely implemented
13
+ [ :underline , 4 ],
14
+ [ :underscore , 4 ], # synonym for :underline
15
+ [ :blink , 5 ],
16
+ [ :rapid_blink , 6 ], # not widely implemented
17
+ [ :negative , 7 ], # no reverse because of String#reverse
18
+ [ :concealed , 8 ],
19
+ [ :strikethrough, 9 ], # not widely implemented
20
+ [ :black , 30 ],
21
+ [ :red , 31 ],
22
+ [ :green , 32 ],
23
+ [ :yellow , 33 ],
24
+ [ :blue , 34 ],
25
+ [ :magenta , 35 ],
26
+ [ :cyan , 36 ],
27
+ [ :white , 37 ],
28
+ [ :on_black , 40 ],
29
+ [ :on_red , 41 ],
30
+ [ :on_green , 42 ],
31
+ [ :on_yellow , 43 ],
32
+ [ :on_blue , 44 ],
33
+ [ :on_magenta , 45 ],
34
+ [ :on_cyan , 46 ],
35
+ [ :on_white , 47 ],
36
+ ]
37
+
38
+ ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
39
+ # :startdoc:
40
+
41
+ # Returns true, if the coloring function of this module
42
+ # is switched on, false otherwise.
43
+ def self.coloring?
44
+ @coloring
45
+ end
46
+
47
+ # Turns the coloring on or off globally, so you can easily do
48
+ # this for example:
49
+ # Lucid::Term::ANSIColor::coloring = STDOUT.isatty
50
+ def self.coloring=(val)
51
+ @coloring = val
52
+ end
53
+ self.coloring = true
54
+
55
+ ATTRIBUTES.each do |c, v|
56
+ eval %Q{
57
+ def #{c}(string = nil)
58
+ result = ''
59
+ result << "\e[#{v}m" if Lucid::Term::ANSIColor.coloring?
60
+ if block_given?
61
+ result << yield
62
+ elsif string
63
+ result << string
64
+ elsif respond_to?(:to_str)
65
+ result << to_str
66
+ else
67
+ return result #only switch on
68
+ end
69
+ result << "\e[0m" if Lucid::Term::ANSIColor.coloring?
70
+ result
71
+ end
72
+ }
73
+ end
74
+
75
+ # Regular expression that is used to scan for ANSI-sequences while
76
+ # uncoloring strings.
77
+ COLORED_REGEXP = /\e\[(?:[34][0-7]|[0-9])?m/
78
+
79
+
80
+ def self.included(klass)
81
+ if version_is_greater_than_18? and klass == String
82
+ ATTRIBUTES.delete(:clear)
83
+ ATTRIBUTE_NAMES.delete(:clear)
84
+ end
85
+ end
86
+
87
+ # Returns an uncolored version of the string, that is all
88
+ # ANSI-sequences are stripped from the string.
89
+ def uncolored(string = nil) # :yields:
90
+ if block_given?
91
+ yield.gsub(COLORED_REGEXP, '')
92
+ elsif string
93
+ string.gsub(COLORED_REGEXP, '')
94
+ elsif respond_to?(:to_str)
95
+ to_str.gsub(COLORED_REGEXP, '')
96
+ else
97
+ ''
98
+ end
99
+ end
100
+
101
+ module_function
102
+
103
+ # Returns an array of all Lucid::Term::ANSIColor attributes as symbols.
104
+ def attributes
105
+ ATTRIBUTE_NAMES
106
+ end
107
+ extend self
108
+
109
+ private
110
+
111
+ def version_is_greater_than_18?
112
+ version = RUBY_VERSION.split('.')
113
+ version.map! &:to_i
114
+ version[0] >= 1 && version[1] > 8
115
+ end
116
+ end
117
+ end
118
+ end