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,119 @@
1
+ module Lucid
2
+ module InterfaceRb
3
+ # It is necessary for the RbLucid module to be mixed in to the top level
4
+ # object. This is what allows TDL test definitions and hooks to be
5
+ # resolved as valid methods.
6
+ module RbLucid
7
+ class << self
8
+ attr_writer :rb_language
9
+
10
+ def alias_adverb(adverb)
11
+ alias_method adverb, :register_rb_step_definition
12
+ end
13
+
14
+ def build_rb_world_factory(domain_modules, proc)
15
+ @rb_language.build_rb_world_factory(domain_modules, proc)
16
+ end
17
+
18
+ def register_rb_hook(phase, tag_names, proc)
19
+ @rb_language.register_rb_hook(phase, tag_names, proc)
20
+ end
21
+
22
+ def register_rb_transform(regexp, proc)
23
+ @rb_language.register_rb_transform(regexp, proc)
24
+ end
25
+
26
+ def register_rb_step_definition(regexp, proc_or_sym, options = {})
27
+ @rb_language.register_rb_step_definition(regexp, proc_or_sym, options)
28
+ end
29
+ end
30
+
31
+ # Registers any number of +domain_modules+ (Ruby Modules) and/or a Proc.
32
+ # The +proc+ will be executed once before each scenario to create an
33
+ # Object that the scenario's steps will run within. Any +domain_modules+
34
+ # will be mixed into this Object (via Object#extend).
35
+ #
36
+ # This method is typically called from one or more Ruby scripts under
37
+ # <tt>common/support</tt>. You can call this method as many times as you
38
+ # like (to register more modules), but if you try to register more than
39
+ # one Proc you will get an error.
40
+ #
41
+ # Lucid will not yield anything to the +proc+. Examples:
42
+ #
43
+ # Domain do
44
+ # MyClass.new
45
+ # end
46
+ #
47
+ # Domain(MyModule)
48
+ #
49
+ def Domain(*domain_modules, &proc)
50
+ RbLucid.build_rb_world_factory(domain_modules, proc)
51
+ end
52
+
53
+ # Registers a proc that will run before each Scenario. You can register as many
54
+ # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
55
+ def Before(*tag_expressions, &proc)
56
+ RbLucid.register_rb_hook('before', tag_expressions, proc)
57
+ end
58
+
59
+ # Registers a proc that will run after each Scenario. You can register as many
60
+ # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
61
+ def After(*tag_expressions, &proc)
62
+ RbLucid.register_rb_hook('after', tag_expressions, proc)
63
+ end
64
+
65
+ # Registers a proc that will be wrapped around each scenario. The proc
66
+ # should accept two arguments: two arguments: the scenario and a "block"
67
+ # argument (but passed as a regular argument, since blocks cannot accept
68
+ # blocks in 1.8), on which it should call the .call method. You can register
69
+ # as many as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
70
+ def Around(*tag_expressions, &proc)
71
+ RbLucid.register_rb_hook('around', tag_expressions, proc)
72
+ end
73
+
74
+ # Registers a proc that will run after each Step. You can register as
75
+ # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
76
+ def AfterStep(*tag_expressions, &proc)
77
+ RbLucid.register_rb_hook('after_step', tag_expressions, proc)
78
+ end
79
+
80
+ # Registers a proc that will be called with a step definition argument if it
81
+ # matches the pattern passed as the first argument to Transform. Alternatively, if
82
+ # the pattern contains captures then they will be yielded as arguments to the
83
+ # provided proc. The return value of the proc is consequently yielded to the
84
+ # step definition.
85
+ def Transform(regexp, &proc)
86
+ RbLucid.register_rb_transform(regexp, proc)
87
+ end
88
+
89
+ # Registers a proc that will run after Lucid is configured. You can register as
90
+ # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
91
+ # TODO: Deprecate this
92
+ def AfterConfiguration(&proc)
93
+ RbLucid.register_rb_hook('after_configuration', [], proc)
94
+ end
95
+
96
+ # Registers a new Ruby StepDefinition. This method is aliased
97
+ # to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>, and
98
+ # also to the i18n translations whenever a feature of a
99
+ # new language is loaded.
100
+ #
101
+ # If provided, the +symbol+ is sent to the <tt>Domain</tt> object
102
+ # as defined by #Domain. A new <tt>Domain</tt> object is created
103
+ # for each scenario and is shared across step definitions within
104
+ # that scenario. If the +options+ hash contains an <tt>:on</tt>
105
+ # key, the value for this is assumed to be a proc. This proc
106
+ # will be executed in the context of the <tt>Domain</tt> object
107
+ # and then sent the +symbol+.
108
+ #
109
+ # If no +symbol+ if provided then the +&proc+ gets executed in
110
+ # the context of the <tt>Domain</tt> object.
111
+ def register_rb_step_definition(regexp, symbol = nil, options = {}, &proc)
112
+ proc_or_sym = symbol || proc
113
+ RbLucid.register_rb_step_definition(regexp, proc_or_sym, options)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ extend(Lucid::InterfaceRb::RbLucid)
@@ -0,0 +1,122 @@
1
+ require 'lucid/step_match'
2
+ require 'lucid/core_ext/string'
3
+ require 'lucid/core_ext/proc'
4
+ require 'lucid/interface_rb/regexp_argument_matcher'
5
+
6
+ module Lucid
7
+ module InterfaceRb
8
+ # A Ruby Step Definition holds a Regexp and a Proc, and is created
9
+ # by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>
10
+ # in the <tt>step_definitions</tt> ruby files. See also RbLucid.
11
+ #
12
+ # Example:
13
+ #
14
+ # Given /I have (\d+) lucid testing on the mind/ do
15
+ # # some code here
16
+ # end
17
+ #
18
+ class RbStepDefinition
19
+
20
+ class MissingProc < StandardError
21
+ def message
22
+ "Step definitions must always have a proc or symbol"
23
+ end
24
+ end
25
+
26
+ class << self
27
+ def new(rb_language, pattern, proc_or_sym, options)
28
+ raise MissingProc if proc_or_sym.nil?
29
+ super rb_language, parse_pattern(pattern), create_proc(proc_or_sym, options)
30
+ end
31
+
32
+ private
33
+
34
+ def parse_pattern(pattern)
35
+ return pattern if pattern.is_a?(Regexp)
36
+ raise ArgumentError unless pattern.is_a?(String)
37
+ p = Regexp.escape(pattern)
38
+ p = p.gsub(/\\\$\w+/, '(.*)') # Replace $var with (.*)
39
+ Regexp.new("^#{p}$")
40
+ end
41
+
42
+ def create_proc(proc_or_sym, options)
43
+ return proc_or_sym if proc_or_sym.is_a?(Proc)
44
+ raise ArgumentError unless proc_or_sym.is_a?(Symbol)
45
+ message = proc_or_sym
46
+ target_proc = parse_target_proc_from(options)
47
+ lambda do |*args|
48
+ target = instance_exec(&target_proc)
49
+ target.send(message, *args)
50
+ end
51
+ end
52
+
53
+ def parse_target_proc_from(options)
54
+ return lambda { self } unless options.key?(:on)
55
+ target = options[:on]
56
+ case target
57
+ when Proc
58
+ target
59
+ when Symbol
60
+ lambda { self.send(target) }
61
+ else
62
+ lambda { raise ArgumentError, "Target must be a symbol or a proc" }
63
+ end
64
+ end
65
+ end
66
+
67
+ def initialize(rb_language, regexp, proc)
68
+ @rb_language, @regexp, @proc = rb_language, regexp, proc
69
+ @rb_language.available_step_definition(regexp_source, file_colon_line)
70
+ end
71
+
72
+ def regexp_source
73
+ @regexp.inspect
74
+ end
75
+
76
+ def to_hash
77
+ flags = ''
78
+ flags += 'm' if (@regexp.options & Regexp::MULTILINE) != 0
79
+ flags += 'i' if (@regexp.options & Regexp::IGNORECASE) != 0
80
+ flags += 'x' if (@regexp.options & Regexp::EXTENDED) != 0
81
+ {'source' => @regexp.source, 'flags' => flags}
82
+ end
83
+
84
+ def ==(step_definition)
85
+ regexp_source == step_definition.regexp_source
86
+ end
87
+
88
+ def arguments_from(step_name)
89
+ args = RegexpArgumentMatcher.arguments_from(@regexp, step_name)
90
+ @rb_language.invoked_step_definition(regexp_source, file_colon_line) if args
91
+ args
92
+ end
93
+
94
+ def invoke(args)
95
+ begin
96
+ args = @rb_language.execute_transforms(args)
97
+ @rb_language.current_domain.lucid_instance_exec(true, regexp_source, *args, &@proc)
98
+ rescue Lucid::ArityMismatchError => e
99
+ e.backtrace.unshift(self.backtrace_line)
100
+ raise e
101
+ end
102
+ end
103
+
104
+ def backtrace_line
105
+ @proc.backtrace_line(regexp_source)
106
+ end
107
+
108
+ def file_colon_line
109
+ case @proc
110
+ when Proc
111
+ @proc.file_colon_line
112
+ when Symbol
113
+ ":#{@proc}"
114
+ end
115
+ end
116
+
117
+ def file
118
+ @file ||= file_colon_line.split(':')[0]
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,57 @@
1
+ module Lucid
2
+ module InterfaceRb
3
+ # A Ruby Transform holds a Regexp and a Proc, and is created
4
+ # by calling <tt>Transform in the <tt>support</tt> ruby files.
5
+ # See also RbLucid.
6
+ #
7
+ # Example:
8
+ #
9
+ # Transform /^(\d+) lucid tests$/ do |lucid_string|
10
+ # lucid_string.to_i
11
+ # end
12
+ #
13
+ class RbTransform
14
+ class MissingProc < StandardError
15
+ def message
16
+ "Transforms must always have a proc with at least one argument"
17
+ end
18
+ end
19
+
20
+ def initialize(rb_language, pattern, proc)
21
+ raise MissingProc if proc.nil? || proc.arity < 1
22
+ @rb_language, @regexp, @proc = rb_language, Regexp.new(pattern), proc
23
+ end
24
+
25
+ def match(arg)
26
+ arg ? arg.match(@regexp) : nil
27
+ end
28
+
29
+ def invoke(arg)
30
+ if matched = match(arg)
31
+ args = matched.captures.empty? ? [arg] : matched.captures
32
+ @rb_language.current_domain.lucid_instance_exec(true, @regexp.inspect, *args, &@proc)
33
+ end
34
+ end
35
+
36
+ def to_s
37
+ convert_captures(strip_anchors(@regexp.source))
38
+ end
39
+
40
+ private
41
+ def convert_captures(regexp_source)
42
+ regexp_source.gsub(/(\()(?!\?:)/,'(?:')
43
+ end
44
+
45
+ def strip_captures(regexp_source)
46
+ regexp_source.
47
+ gsub(/(\()/, '').
48
+ gsub(/(\))/, '')
49
+ end
50
+
51
+ def strip_anchors(regexp_source)
52
+ regexp_source.
53
+ gsub(/(^\^|\$$)/, '')
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,136 @@
1
+ require 'gherkin/formatter/ansi_escapes'
2
+
3
+ module Lucid
4
+ module InterfaceRb
5
+ # Defines the basic DSL methods available in all Lucid test definitions.
6
+ #
7
+ # You can, and probably should, extend this DSL with your own methods that
8
+ # make sense in your own domain.
9
+ # @see Lucid::InterfaceRb::RbLucid#Domain
10
+ module RbDomain
11
+
12
+ AnsiEscapes = Gherkin::Formatter::AnsiEscapes
13
+
14
+ # Call a Transform with a string from another Transform definition
15
+ def Transform(arg)
16
+ rb = @__lucid_runtime.load_code_language('rb')
17
+ rb.execute_transforms([arg]).first
18
+ end
19
+
20
+ # @private
21
+ attr_writer :__lucid_runtime, :__natural_language
22
+
23
+ # Run a single Gherkin step
24
+ # @example Call another step
25
+ # step "I am logged in"
26
+ # @example Call a step with quotes in the name
27
+ # step %{the user "Jeff" is logged in}
28
+ # @example Passing a table
29
+ # step "the following users exist:", table(%{
30
+ # | name | email |
31
+ # | Jeff | jeff@jeff.com |
32
+ # | Harley | harley@jeff.com |
33
+ # })
34
+ # @example Passing a multiline string
35
+ # step "the email should contain:", "Dear sir,\nYou've won a prize!\n"
36
+ # @param [String] name The name of the step
37
+ # @param [String,Lucid::AST::DocString,Lucid::AST::Table] multiline_argument
38
+ def step(name, multiline_argument=nil)
39
+ @__lucid_runtime.invoke(name, multiline_argument)
40
+ end
41
+
42
+ # Run a matcher of Gherkin
43
+ # @example
44
+ # steps %{
45
+ # Given the user "Jeff" exists
46
+ # And I am logged in as "Jeff"
47
+ # }
48
+ # @param [String] steps_text The Gherkin matcher to run
49
+ def steps(steps_text)
50
+ @__lucid_runtime.invoke_steps(steps_text, @__natural_language, caller[0])
51
+ end
52
+
53
+ # Parse Gherkin into a {Lucid::AST::Table} object.
54
+ #
55
+ # Useful in conjunction with the #step method.
56
+ # @example Create a table
57
+ # users = table(%{
58
+ # | name | email |
59
+ # | Jeff | jeff@jeff.com |
60
+ # | Harley | harley@jeff.com |
61
+ # })
62
+ # @param [String] text_or_table The Gherkin string that represents the table
63
+ def table(text_or_table, file=nil, line_offset=0)
64
+ @__lucid_runtime.table(text_or_table, file, line_offset)
65
+ end
66
+
67
+ # Create an {Lucid::AST::DocString} object
68
+ #
69
+ # Useful in conjunction with the #step method, when
70
+ # want to specify a content type.
71
+ # @example Create a multiline string
72
+ # code = multiline_string(%{
73
+ # puts "this is ruby code"
74
+ # %}, 'ruby')
75
+ def doc_string(string_without_triple_quotes, content_type='', line_offset=0)
76
+ # TODO: rename this method to multiline_string
77
+ @__lucid_runtime.doc_string(string_without_triple_quotes, content_type, line_offset)
78
+ end
79
+
80
+ # @deprecated Use {#puts} instead.
81
+ def announce(*messages)
82
+ STDERR.puts AnsiEscapes.failed + "WARNING: #announce is deprecated. Use #puts instead:" + caller[0] + AnsiEscapes.reset
83
+ puts(*messages)
84
+ end
85
+
86
+ # Print a message to the output.
87
+ #
88
+ # @note Lucid might surprise you with the behavior of this method. Instead
89
+ # of sending the output directly to STDOUT, Lucid will intercept and cache
90
+ # the message until the current step has finished, and then display it.
91
+ #
92
+ # If you'd prefer to see the message immediately, call {Kernel.puts} instead.
93
+ def puts(*messages)
94
+ @__lucid_runtime.puts(*messages)
95
+ end
96
+
97
+ # Pause the tests and ask the operator for input
98
+ def ask(question, timeout_seconds=60)
99
+ @__lucid_runtime.ask(question, timeout_seconds)
100
+ end
101
+
102
+ # Embed an image in the output
103
+ def embed(file, mime_type, label='Screenshot')
104
+ @__lucid_runtime.embed(file, mime_type, label)
105
+ end
106
+
107
+ # Mark the matched step as pending.
108
+ def pending(message = "TODO")
109
+ if block_given?
110
+ begin
111
+ yield
112
+ rescue Exception
113
+ raise Pending.new(message)
114
+ end
115
+ raise Pending.new("Expected pending '#{message}' to fail. No Error was raised. No longer pending?")
116
+ else
117
+ raise Pending.new(message)
118
+ end
119
+ end
120
+
121
+ # Prints the list of modules that are included in the Domain
122
+ def inspect
123
+ modules = [self.class]
124
+ (class << self; self; end).instance_eval do
125
+ modules += included_modules
126
+ end
127
+ sprintf("#<%s:0x%x>", modules.join('+'), self.object_id)
128
+ end
129
+
130
+ # see {#inspect}
131
+ def to_s
132
+ inspect
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,21 @@
1
+ require 'gherkin/formatter/argument'
2
+
3
+ module Lucid
4
+ module InterfaceRb
5
+ class RegexpArgumentMatcher
6
+ def self.arguments_from(regexp, step_name)
7
+ match = regexp.match(step_name)
8
+ if match
9
+ n = 0
10
+ match.captures.map do |val|
11
+ n += 1
12
+ offset = match.offset(n)[0]
13
+ Gherkin::Formatter::Argument.new(offset, val)
14
+ end
15
+ else
16
+ nil
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end