yard-cucumber2 2.3.3
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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +37 -0
- data/History.txt +274 -0
- data/LICENSE.txt +22 -0
- data/README.md +188 -0
- data/Rakefile +25 -0
- data/example/README.md +8 -0
- data/example/child_feature/README.md +21 -0
- data/example/child_feature/child.feature +11 -0
- data/example/child_feature/grandchild_feature/grandchild.feature +12 -0
- data/example/empty.feature +2 -0
- data/example/french.feature +18 -0
- data/example/scenario.feature +63 -0
- data/example/scenario_outline.feature +94 -0
- data/example/scenario_outline_multi.feature +15 -0
- data/example/step_definitions/example.step.rb +109 -0
- data/example/step_definitions/first.step.rb +21 -0
- data/example/step_definitions/french_steps.rb +32 -0
- data/example/step_definitions/struct.rb +11 -0
- data/example/step_definitions/support/env.rb +7 -0
- data/example/step_definitions/support/env_support.rb +12 -0
- data/example/step_definitions/support/support.rb +6 -0
- data/example/tags.feature +18 -0
- data/example/transform.feature +13 -0
- data/lib/cucumber/city_builder.rb +331 -0
- data/lib/docserver/default/fulldoc/html/js/cucumber.js +85 -0
- data/lib/docserver/default/layout/html/headers.erb +14 -0
- data/lib/docserver/doc_server/full_list/html/full_list.erb +39 -0
- data/lib/docserver/doc_server/full_list/html/setup.rb +18 -0
- data/lib/templates/default/feature/html/feature.erb +39 -0
- data/lib/templates/default/feature/html/no_steps_defined.erb +1 -0
- data/lib/templates/default/feature/html/outline.erb +56 -0
- data/lib/templates/default/feature/html/pystring.erb +3 -0
- data/lib/templates/default/feature/html/scenario.erb +55 -0
- data/lib/templates/default/feature/html/setup.rb +55 -0
- data/lib/templates/default/feature/html/steps.erb +39 -0
- data/lib/templates/default/feature/html/table.erb +20 -0
- data/lib/templates/default/featuredirectory/html/alpha_table.erb +30 -0
- data/lib/templates/default/featuredirectory/html/directory.erb +32 -0
- data/lib/templates/default/featuredirectory/html/setup.rb +41 -0
- data/lib/templates/default/featuretags/html/namespace.erb +131 -0
- data/lib/templates/default/featuretags/html/setup.rb +34 -0
- data/lib/templates/default/fulldoc/html/css/cucumber.css +227 -0
- data/lib/templates/default/fulldoc/html/directories.erb +53 -0
- data/lib/templates/default/fulldoc/html/full_list_featuredirectories.erb +11 -0
- data/lib/templates/default/fulldoc/html/full_list_features.erb +29 -0
- data/lib/templates/default/fulldoc/html/full_list_stepdefinitions.erb +16 -0
- data/lib/templates/default/fulldoc/html/full_list_steps.erb +17 -0
- data/lib/templates/default/fulldoc/html/full_list_tags.erb +12 -0
- data/lib/templates/default/fulldoc/html/js/cucumber.js +305 -0
- data/lib/templates/default/fulldoc/html/setup.rb +175 -0
- data/lib/templates/default/layout/html/setup.rb +56 -0
- data/lib/templates/default/requirements/html/alpha_table.erb +26 -0
- data/lib/templates/default/requirements/html/requirements.erb +50 -0
- data/lib/templates/default/requirements/html/setup.rb +51 -0
- data/lib/templates/default/steptransformers/html/header.erb +12 -0
- data/lib/templates/default/steptransformers/html/index.erb +10 -0
- data/lib/templates/default/steptransformers/html/setup.rb +94 -0
- data/lib/templates/default/steptransformers/html/transformers.erb +79 -0
- data/lib/templates/default/steptransformers/html/undefinedsteps.erb +26 -0
- data/lib/templates/default/tag/html/alpha_table.erb +32 -0
- data/lib/templates/default/tag/html/setup.rb +27 -0
- data/lib/templates/default/tag/html/tag.erb +35 -0
- data/lib/yard-cucumber.rb +47 -0
- data/lib/yard-cucumber/version.rb +3 -0
- data/lib/yard/code_objects/cucumber/base.rb +32 -0
- data/lib/yard/code_objects/cucumber/feature.rb +18 -0
- data/lib/yard/code_objects/cucumber/namespace_object.rb +49 -0
- data/lib/yard/code_objects/cucumber/scenario.rb +26 -0
- data/lib/yard/code_objects/cucumber/scenario_outline.rb +75 -0
- data/lib/yard/code_objects/cucumber/step.rb +38 -0
- data/lib/yard/code_objects/cucumber/tag.rb +27 -0
- data/lib/yard/code_objects/step_definition.rb +7 -0
- data/lib/yard/code_objects/step_transform.rb +7 -0
- data/lib/yard/code_objects/step_transformer.rb +97 -0
- data/lib/yard/handlers/cucumber/base.rb +21 -0
- data/lib/yard/handlers/cucumber/feature_handler.rb +131 -0
- data/lib/yard/handlers/legacy/step_definition_handler.rb +45 -0
- data/lib/yard/handlers/legacy/step_transform_handler.rb +24 -0
- data/lib/yard/handlers/step_definition_handler.rb +86 -0
- data/lib/yard/handlers/step_transform_handler.rb +31 -0
- data/lib/yard/parser/cucumber/feature.rb +73 -0
- data/lib/yard/server/adapter.rb +43 -0
- data/lib/yard/server/commands/list_command.rb +31 -0
- data/lib/yard/server/router.rb +32 -0
- data/lib/yard/templates/helpers/base_helper.rb +26 -0
- data/yard-cucumber.gemspec +65 -0
- metadata +199 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module YARD
|
|
2
|
+
module Handlers
|
|
3
|
+
module Cucumber
|
|
4
|
+
|
|
5
|
+
class Base < Handlers::Base
|
|
6
|
+
class << self
|
|
7
|
+
include Parser::Cucumber
|
|
8
|
+
def handles?(node)
|
|
9
|
+
handlers.any? do |a_handler|
|
|
10
|
+
#log.debug "YARD::Handlers::Cucumber::Base#handles?(#{node.class})"
|
|
11
|
+
node.class == a_handler
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
include Parser::Cucumber
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Processor.register_handler_namespace :feature, Cucumber
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
module YARD
|
|
2
|
+
module Handlers
|
|
3
|
+
module Cucumber
|
|
4
|
+
class FeatureHandler < Base
|
|
5
|
+
|
|
6
|
+
handles CodeObjects::Cucumber::Feature
|
|
7
|
+
|
|
8
|
+
def process
|
|
9
|
+
#
|
|
10
|
+
# Features have already been created when they were parsed. So there
|
|
11
|
+
# is no need to process the feature further. Previously this is where
|
|
12
|
+
# feature steps were matched to step definitions and step definitions
|
|
13
|
+
# were matched to step transforms. This only worked if the feature
|
|
14
|
+
# files were were assured to be processed last which was accomplished
|
|
15
|
+
# by overriding YARD::SourceParser to make it load file in a similar
|
|
16
|
+
# order as Cucumber.
|
|
17
|
+
#
|
|
18
|
+
# As of YARD 0.7.0 this is no longer necessary as there are callbacks
|
|
19
|
+
# that can be registered after all the files have been loaded. That
|
|
20
|
+
# callback _after_parse_list_ is defined below and performs the
|
|
21
|
+
# functionality described above.
|
|
22
|
+
#
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Register, once, when that when all files are finished to perform
|
|
27
|
+
# the final matching of feature steps to step definitions and step
|
|
28
|
+
# definitions to step transforms.
|
|
29
|
+
#
|
|
30
|
+
YARD::Parser::SourceParser.after_parse_list do |files,globals|
|
|
31
|
+
# For every feature found in the Registry, find their steps and step
|
|
32
|
+
# definitions...
|
|
33
|
+
YARD::Registry.all(:feature).each do |feature|
|
|
34
|
+
log.debug "Finding #{feature.file} - steps, step definitions, and step transforms"
|
|
35
|
+
FeatureHandler.match_steps_to_step_definitions(feature)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class << self
|
|
41
|
+
|
|
42
|
+
@@step_definitions = nil
|
|
43
|
+
@@step_transforms = nil
|
|
44
|
+
|
|
45
|
+
def match_steps_to_step_definitions(statement)
|
|
46
|
+
# Create a cache of all of the step definitions and the step transforms
|
|
47
|
+
@@step_definitions = cache(:stepdefinition) unless @@step_definitions
|
|
48
|
+
@@step_transforms = cache(:steptransform) unless @@step_transforms
|
|
49
|
+
|
|
50
|
+
if statement
|
|
51
|
+
# For the background and the scenario, find the steps that have definitions
|
|
52
|
+
process_scenario(statement.background) if statement.background
|
|
53
|
+
|
|
54
|
+
statement.scenarios.each do |scenario|
|
|
55
|
+
if scenario.outline?
|
|
56
|
+
#log.info "Scenario Outline: #{scenario.value}"
|
|
57
|
+
scenario.scenarios.each_with_index do |example,index|
|
|
58
|
+
#log.info " * Processing Example #{index + 1}"
|
|
59
|
+
process_scenario(example)
|
|
60
|
+
end
|
|
61
|
+
else
|
|
62
|
+
process_scenario(scenario)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
else
|
|
68
|
+
log.warn "Empty feature file. A feature failed to process correctly or contains no feature"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
rescue YARD::Handlers::NamespaceMissingError
|
|
72
|
+
rescue Exception => exception
|
|
73
|
+
log.error "Skipping feature because an error has occurred."
|
|
74
|
+
log.debug "\n#{exception}\n#{exception.backtrace.join("\n")}\n"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Store all comparable items with their compare_value as the key and the item as the value
|
|
79
|
+
# - Reject any compare values that contain escapes #{} as that means they have unpacked constants
|
|
80
|
+
#
|
|
81
|
+
def cache(type)
|
|
82
|
+
YARD::Registry.all(type).inject({}) do |hash,item|
|
|
83
|
+
hash[item.regex] = item if item.regex
|
|
84
|
+
hash
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# process a scenario
|
|
89
|
+
def process_scenario(scenario)
|
|
90
|
+
scenario.steps.each {|step| process_step(step) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# process a step
|
|
94
|
+
def process_step(step)
|
|
95
|
+
match_step_to_step_definition_and_transforms(step)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Given a step object, attempt to match that step to a step
|
|
100
|
+
# transformation
|
|
101
|
+
#
|
|
102
|
+
def match_step_to_step_definition_and_transforms(step)
|
|
103
|
+
@@step_definitions.each_pair do |stepdef,stepdef_object|
|
|
104
|
+
stepdef_matches = step.value.match(stepdef)
|
|
105
|
+
|
|
106
|
+
if stepdef_matches
|
|
107
|
+
step.definition = stepdef_object
|
|
108
|
+
stepdef_matches[-1..1].each do |match|
|
|
109
|
+
@@step_transforms.each do |steptrans,steptransform_object|
|
|
110
|
+
if steptrans.match(match)
|
|
111
|
+
step.transforms << steptransform_object
|
|
112
|
+
steptransform_object.steps << step
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Step has been matched to step definition and step transforms
|
|
118
|
+
# TODO: If the step were to match again then we would be able to display ambigous step definitions
|
|
119
|
+
break
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
class YARD::Handlers::Ruby::Legacy::StepDefinitionHandler < YARD::Handlers::Ruby::Legacy::Base
|
|
2
|
+
STEP_DEFINITION_MATCH = /^((When|Given|And|Then)\s*(\/.+\/)\s+do(?:\s*\|.+\|)?\s*)$/ unless defined?(STEP_DEFINITION_MATCH)
|
|
3
|
+
handles STEP_DEFINITION_MATCH
|
|
4
|
+
|
|
5
|
+
@@unique_name = 0
|
|
6
|
+
|
|
7
|
+
def process
|
|
8
|
+
keyword = statement.tokens.to_s[STEP_DEFINITION_MATCH,2]
|
|
9
|
+
step_definition = statement.tokens.to_s[STEP_DEFINITION_MATCH,3]
|
|
10
|
+
|
|
11
|
+
@@unique_name = @@unique_name + 1
|
|
12
|
+
|
|
13
|
+
stepdef_instance = StepDefinitionObject.new(YARD::CodeObjects::Cucumber::CUCUMBER_STEPTRANSFORM_NAMESPACE, "definition_#{@@unique_name}") do |o|
|
|
14
|
+
o.source = "#{keyword} #{step_definition} do #{statement.block.to_s =~ /^\s*\|.+/ ? '' : "\n "}#{statement.block.to_s}\nend"
|
|
15
|
+
o.value = step_definition
|
|
16
|
+
o.keyword = keyword
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
obj = register stepdef_instance
|
|
20
|
+
parse_block :owner => obj
|
|
21
|
+
|
|
22
|
+
rescue YARD::Handlers::NamespaceMissingError
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Step Definitions can contain defined steps within them. While it is likely that they could not
|
|
27
|
+
# very easily be parsed because of variables that are only calculated at runtime, it would be nice
|
|
28
|
+
# to at least list those in use within a step definition and if you can find a match, go ahead and
|
|
29
|
+
# make it
|
|
30
|
+
#
|
|
31
|
+
def find_steps_defined_in_block(block)
|
|
32
|
+
#log.debug "#{block} #{block.class}"
|
|
33
|
+
block.each_with_index do |token,index|
|
|
34
|
+
#log.debug "Token #{token.class} #{token.text}"
|
|
35
|
+
if token.is_a?(YARD::Parser::Ruby::Legacy::RubyToken::TkCONSTANT) &&
|
|
36
|
+
token.text =~ /^(given|when|then|and)$/i &&
|
|
37
|
+
block[index + 2].is_a?(YARD::Parser::Ruby::Legacy::RubyToken::TkSTRING)
|
|
38
|
+
log.debug "Step found in Step Definition: #{block[index + 2].text} "
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class YARD::Handlers::Ruby::Legacy::StepTransformHandler < YARD::Handlers::Ruby::Legacy::Base
|
|
2
|
+
STEP_TRANSFORM_MATCH = /^(Transform\s*(\/.+\/)\s+do(?:\s*\|.+\|)?\s*)$/ unless defined?(STEP_TRANSFORM_MATCH)
|
|
3
|
+
handles STEP_TRANSFORM_MATCH
|
|
4
|
+
|
|
5
|
+
@@unique_name = 0
|
|
6
|
+
|
|
7
|
+
def process
|
|
8
|
+
transform = statement.tokens.to_s[STEP_TRANSFORM_MATCH,2]
|
|
9
|
+
@@unique_name = @@unique_name + 1
|
|
10
|
+
|
|
11
|
+
instance = StepTransformObject.new(YARD::CodeObjects::Cucumber::CUCUMBER_STEPTRANSFORM_NAMESPACE, "transform_#{@@unique_name}") do |o|
|
|
12
|
+
o.source = "Transform #{transform} do #{statement.block.to_s}\nend"
|
|
13
|
+
o.value = transform
|
|
14
|
+
o.keyword = "Transform"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
obj = register instance
|
|
18
|
+
parse_block :owner => obj
|
|
19
|
+
|
|
20
|
+
rescue YARD::Handlers::NamespaceMissingError
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Finds and processes all the step definitions defined in the ruby source
|
|
3
|
+
# code. By default the english gherkin language will be parsed.
|
|
4
|
+
#
|
|
5
|
+
# To override the language you can define the step definitions in the YARD
|
|
6
|
+
# configuration file `~./yard/config`:
|
|
7
|
+
#
|
|
8
|
+
# @example `~/.yard/config` with LOLCatz step definitions
|
|
9
|
+
#
|
|
10
|
+
# :"yard-cucumber":
|
|
11
|
+
# language:
|
|
12
|
+
# step_definitions: [ 'WEN', 'I CAN HAZ', 'AN', 'DEN' ]
|
|
13
|
+
#
|
|
14
|
+
# @example `~/.yard/config` with French step definitions
|
|
15
|
+
#
|
|
16
|
+
# :"yard-cucumber":
|
|
17
|
+
# language:
|
|
18
|
+
# step_definitions: [ 'Soit', 'Etantdonné', 'Lorsque', 'Lorsqu', 'Alors', 'Et' ]
|
|
19
|
+
#
|
|
20
|
+
class YARD::Handlers::Ruby::StepDefinitionHandler < YARD::Handlers::Ruby::Base
|
|
21
|
+
|
|
22
|
+
def self.default_step_definitions
|
|
23
|
+
[ "When", "Given", "And", "Then" ]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.custom_step_definitions
|
|
27
|
+
YARD::Config.options["yard-cucumber"]["language"]["step_definitions"]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.custom_step_definitions_defined?
|
|
31
|
+
YARD::Config.options["yard-cucumber"] and
|
|
32
|
+
YARD::Config.options["yard-cucumber"]["language"] and
|
|
33
|
+
YARD::Config.options["yard-cucumber"]["language"]["step_definitions"]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.step_definitions
|
|
37
|
+
if custom_step_definitions_defined?
|
|
38
|
+
custom_step_definitions
|
|
39
|
+
else
|
|
40
|
+
default_step_definitions
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
step_definitions.each { |step_def| handles method_call(step_def) }
|
|
45
|
+
|
|
46
|
+
process do
|
|
47
|
+
|
|
48
|
+
instance = YARD::CodeObjects::StepDefinitionObject.new(step_transform_namespace,step_definition_name) do |o|
|
|
49
|
+
o.source = statement.source
|
|
50
|
+
o.comments = statement.comments
|
|
51
|
+
o.keyword = statement.method_name.source
|
|
52
|
+
o.value = statement.parameters.source
|
|
53
|
+
o.pending = pending_keyword_used?(statement.block)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
obj = register instance
|
|
57
|
+
parse_block(statement[2],:owner => obj)
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def pending_keyword
|
|
62
|
+
"pending"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def pending_command_statement?(line)
|
|
66
|
+
(line.type == :command || line.type == :vcall) && line.first.source == pending_keyword
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def pending_keyword_used?(block)
|
|
70
|
+
code_in_block = block.last
|
|
71
|
+
code_in_block.find { |line| pending_command_statement?(line) }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def step_transform_namespace
|
|
75
|
+
YARD::CodeObjects::Cucumber::CUCUMBER_STEPTRANSFORM_NAMESPACE
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def step_definition_name
|
|
79
|
+
"step_definition#{self.class.generate_unique_id}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def self.generate_unique_id
|
|
83
|
+
@step_definition_count = @step_definition_count.to_i + 1
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
class YARD::Handlers::Ruby::StepTransformHandler < YARD::Handlers::Ruby::Base
|
|
3
|
+
handles method_call(:Transform)
|
|
4
|
+
|
|
5
|
+
process do
|
|
6
|
+
|
|
7
|
+
instance = YARD::CodeObjects::StepTransformObject.new(step_transform_namespace,step_transformer_name) do |o|
|
|
8
|
+
o.source = statement.source
|
|
9
|
+
o.comments = statement.comments
|
|
10
|
+
o.keyword = statement[0].source
|
|
11
|
+
o.value = statement[1].source
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
obj = register instance
|
|
15
|
+
parse_block(statement[2],:owner => obj)
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def step_transform_namespace
|
|
20
|
+
YARD::CodeObjects::Cucumber::CUCUMBER_STEPTRANSFORM_NAMESPACE
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def step_transformer_name
|
|
24
|
+
"step_transform#{self.class.generate_unique_id}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.generate_unique_id
|
|
28
|
+
@step_transformer_count = @step_transformer_count.to_i + 1
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module YARD::Parser::Cucumber
|
|
2
|
+
|
|
3
|
+
class FeatureParser < YARD::Parser::Base
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# Each found feature found is creates a new FeatureParser
|
|
7
|
+
#
|
|
8
|
+
# This logic was copied from the logic found in Cucumber to create the builder
|
|
9
|
+
# and then set up the formatter and parser. The difference is really the
|
|
10
|
+
# custom Cucumber::Parser::CityBuilder that is being used to parse the elements
|
|
11
|
+
# of the feature into YARD::CodeObjects.
|
|
12
|
+
#
|
|
13
|
+
# @param [<String>] source containing the string conents of the feauture file
|
|
14
|
+
# @param [<String>] file the filename that contains the source
|
|
15
|
+
#
|
|
16
|
+
def initialize(source, file = '(stdin)')
|
|
17
|
+
|
|
18
|
+
@builder = Cucumber::Parser::CityBuilder.new(file)
|
|
19
|
+
@tag_counts = {}
|
|
20
|
+
@tag_formatter = Gherkin::Formatter::TagCountFormatter.new(@builder, @tag_counts)
|
|
21
|
+
@parser = Gherkin::Parser::Parser.new(@tag_formatter, true, "root", false)
|
|
22
|
+
|
|
23
|
+
@source = source
|
|
24
|
+
@file = file
|
|
25
|
+
|
|
26
|
+
@feature = nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# When parse is called, the gherkin parser is executed and all the feature
|
|
31
|
+
# elements that are found are sent to the various methods in the
|
|
32
|
+
# Cucumber::Parser::CityBuilder. The result of which is the feature element
|
|
33
|
+
# that contains all the scenarios, steps, etc. associated with that feature.
|
|
34
|
+
#
|
|
35
|
+
# @see Cucumber::Parser::CityBuilder
|
|
36
|
+
def parse
|
|
37
|
+
begin
|
|
38
|
+
@parser.parse(@source, @file, 0)
|
|
39
|
+
@feature = @builder.ast
|
|
40
|
+
return nil if @feature.nil? # Nothing matched
|
|
41
|
+
|
|
42
|
+
# The parser used the following keywords when parsing the feature
|
|
43
|
+
# @feature.language = @parser.i18n_language.get_code_keywords.map {|word| word }
|
|
44
|
+
|
|
45
|
+
rescue Gherkin::Lexer::LexingError, Gherkin::Parser::ParseError => e
|
|
46
|
+
e.message.insert(0, "#{@file}: ")
|
|
47
|
+
raise e
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# This is not used as all the work is done in the parse method
|
|
55
|
+
#
|
|
56
|
+
def tokenize
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# The only enumeration that can be done here is returning the feature itself
|
|
62
|
+
#
|
|
63
|
+
def enumerator
|
|
64
|
+
[@feature]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# Register all feature files (.feature) to be processed with the above FeatureParser
|
|
71
|
+
YARD::Parser::SourceParser.register_parser_type :feature, FeatureParser, 'feature'
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module YARD
|
|
2
|
+
module Server
|
|
3
|
+
|
|
4
|
+
class Adapter
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
|
|
8
|
+
alias_method :yard_setup, :setup
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# To provide the templates necessary for `yard-cucumber` to integrate
|
|
12
|
+
# with YARD the adapter has to around-alias the setup method to place
|
|
13
|
+
# the `yard-cucumber` server templates as the last template in the list.
|
|
14
|
+
#
|
|
15
|
+
# When they are normally loaded with the plugin they cause an error with
|
|
16
|
+
# the `yardoc` command. They are also not used because the YARD server
|
|
17
|
+
# templates are placed after all plugin templates.
|
|
18
|
+
#
|
|
19
|
+
def setup
|
|
20
|
+
yard_setup
|
|
21
|
+
YARD::Templates::Engine.template_paths +=
|
|
22
|
+
[File.dirname(__FILE__) + '/../../templates',File.dirname(__FILE__) + '/../../docserver']
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
alias_method :yard_shutdown, :shutdown
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Similar to the addition, it is good business to tear down the templates
|
|
29
|
+
# that were added by again around-aliasing the shutdown method.
|
|
30
|
+
#
|
|
31
|
+
def shutdown
|
|
32
|
+
yard_shutdown
|
|
33
|
+
YARD::Templates::Engine.template_paths -=
|
|
34
|
+
[File.dirname(__FILE__) + '/../../templates',File.dirname(__FILE__) + '/../../docserver']
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|