yard-lucid 0.1.0
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 +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +87 -0
- data/Rakefile +6 -0
- data/bin/console +13 -0
- data/bin/setup +8 -0
- data/lib/docserver/default/fulldoc/html/js/lucid.js +69 -0
- data/lib/docserver/default/layout/html/headers.erb +13 -0
- data/lib/docserver/doc_server/full_list/html/full_list.erb +37 -0
- data/lib/docserver/doc_server/full_list/html/setup.rb +19 -0
- data/lib/lucid/gherkin_repr.rb +307 -0
- data/lib/templates/default/feature/html/docstring.erb +3 -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 +52 -0
- data/lib/templates/default/feature/html/scenario.erb +52 -0
- data/lib/templates/default/feature/html/setup.rb +51 -0
- data/lib/templates/default/feature/html/steps.erb +37 -0
- data/lib/templates/default/feature/html/table.erb +19 -0
- data/lib/templates/default/featuredirectory/html/alpha_table.erb +30 -0
- data/lib/templates/default/featuredirectory/html/directory.erb +30 -0
- data/lib/templates/default/featuredirectory/html/setup.rb +41 -0
- data/lib/templates/default/featuretags/html/namespace.erb +127 -0
- data/lib/templates/default/featuretags/html/setup.rb +33 -0
- data/lib/templates/default/fulldoc/html/css/lucid.css +224 -0
- data/lib/templates/default/fulldoc/html/directories.erb +27 -0
- data/lib/templates/default/fulldoc/html/full_list_featuredirectories.erb +11 -0
- data/lib/templates/default/fulldoc/html/full_list_features.erb +36 -0
- data/lib/templates/default/fulldoc/html/full_list_stepdefinitions.erb +20 -0
- data/lib/templates/default/fulldoc/html/full_list_steps.erb +20 -0
- data/lib/templates/default/fulldoc/html/full_list_tags.erb +16 -0
- data/lib/templates/default/fulldoc/html/js/lucid.js +284 -0
- data/lib/templates/default/fulldoc/html/setup.rb +199 -0
- data/lib/templates/default/layout/html/setup.rb +111 -0
- data/lib/templates/default/specifications/html/alpha_table.erb +26 -0
- data/lib/templates/default/specifications/html/setup.rb +49 -0
- data/lib/templates/default/specifications/html/specifications.erb +46 -0
- data/lib/templates/default/steptransformers/html/header.erb +12 -0
- data/lib/templates/default/steptransformers/html/index.erb +9 -0
- data/lib/templates/default/steptransformers/html/setup.rb +92 -0
- data/lib/templates/default/steptransformers/html/transformers.erb +74 -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 +26 -0
- data/lib/templates/default/tag/html/tag.erb +31 -0
- data/lib/yard/code_objects/lucid/base.rb +23 -0
- data/lib/yard/code_objects/lucid/feature.rb +12 -0
- data/lib/yard/code_objects/lucid/namespace_object.rb +43 -0
- data/lib/yard/code_objects/lucid/scenario.rb +20 -0
- data/lib/yard/code_objects/lucid/scenario_outline.rb +66 -0
- data/lib/yard/code_objects/lucid/step.rb +32 -0
- data/lib/yard/code_objects/lucid/tag.rb +21 -0
- data/lib/yard/code_objects/step_definition.rb +3 -0
- data/lib/yard/code_objects/step_transform.rb +3 -0
- data/lib/yard/code_objects/step_transformer.rb +85 -0
- data/lib/yard/handlers/lucid/base.rb +19 -0
- data/lib/yard/handlers/lucid/feature_handler.rb +102 -0
- data/lib/yard/handlers/step_definition_handler.rb +67 -0
- data/lib/yard/handlers/step_transform_handler.rb +28 -0
- data/lib/yard/parser/lucid/feature.rb +58 -0
- data/lib/yard/server/adapter.rb +32 -0
- data/lib/yard/server/commands/list_command.rb +25 -0
- data/lib/yard/server/router.rb +23 -0
- data/lib/yard/templates/helpers/base_helper.rb +22 -0
- data/lib/yard-lucid/version.rb +3 -0
- data/lib/yard-lucid.rb +36 -0
- data/yard-lucid.gemspec +38 -0
- metadata +215 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
module YARD::CodeObjects::Lucid
|
2
|
+
class ScenarioOutline < NamespaceObject
|
3
|
+
attr_accessor :value, :comments, :keyword, :description, :steps, :tags, :feature
|
4
|
+
attr_accessor :scenarios, :examples
|
5
|
+
|
6
|
+
def initialize(namespace,name)
|
7
|
+
super(namespace,name.to_s.strip)
|
8
|
+
@comments = @description = @value = @feature = nil
|
9
|
+
@steps = []
|
10
|
+
@tags = []
|
11
|
+
@scenarios = []
|
12
|
+
@examples = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def background?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def outline?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def examples?
|
24
|
+
@examples.find { |example| example.rows }
|
25
|
+
end
|
26
|
+
|
27
|
+
class Examples
|
28
|
+
attr_accessor :name, :line, :keyword, :comments, :rows
|
29
|
+
|
30
|
+
# The first row of the rows contains the headers for the table
|
31
|
+
def headers
|
32
|
+
rows.first
|
33
|
+
end
|
34
|
+
|
35
|
+
# The data of the table starts at the second row. When there is no data then
|
36
|
+
# return a empty string.
|
37
|
+
def data
|
38
|
+
rows ? rows[1..-1] : ""
|
39
|
+
end
|
40
|
+
|
41
|
+
def values_for_row(row)
|
42
|
+
hash = {}
|
43
|
+
|
44
|
+
headers.each_with_index do |header,index|
|
45
|
+
hash[header] = data[row][index]
|
46
|
+
end
|
47
|
+
|
48
|
+
hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_hash
|
52
|
+
hash = {}
|
53
|
+
|
54
|
+
rows.each_with_index do |header,index|
|
55
|
+
hash[header] = rows.collect { |row| row[index] }
|
56
|
+
end
|
57
|
+
|
58
|
+
hash
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize(parameters = {})
|
62
|
+
parameters.each { |key,value| send("#{key.to_sym}=",value) if respond_to? "#{key.to_sym}=" }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module YARD::CodeObjects::Lucid
|
2
|
+
class Step < Base
|
3
|
+
attr_accessor :comments, :definition, :examples, :keyword, :scenario, :table, :text, :transforms, :value
|
4
|
+
|
5
|
+
def initialize(namespace,name)
|
6
|
+
super(namespace,name.to_s.strip)
|
7
|
+
@comments = @definition = @description = @keyword = @table = @text = @value = nil
|
8
|
+
@examples = {}
|
9
|
+
@transforms = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_table?
|
13
|
+
!@table.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_text?
|
17
|
+
!@text.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
def definition=(stepdef)
|
21
|
+
@definition = stepdef
|
22
|
+
|
23
|
+
unless stepdef.steps.map(&:files).include?(files)
|
24
|
+
stepdef.steps << self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def transformed?
|
29
|
+
!@transforms.empty?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module YARD::CodeObjects::Lucid
|
2
|
+
class Tag < NamespaceObject
|
3
|
+
attr_accessor :value, :owners
|
4
|
+
|
5
|
+
def features
|
6
|
+
@owners.find_all { |owner| owner.is_a?(Feature) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def scenarios
|
10
|
+
@owners.find_all { |owner| owner.is_a?(Scenario) || owner.is_a?(ScenarioOutline) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def indirect_scenarios
|
14
|
+
@owners.find_all { |owner| owner.is_a?(Feature) }.collect { |feature| feature.scenarios }.flatten
|
15
|
+
end
|
16
|
+
|
17
|
+
def all_scenarios
|
18
|
+
scenarios + indirect_scenarios
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module YARD::CodeObjects
|
2
|
+
class StepTransformerObject < Base
|
3
|
+
|
4
|
+
include Lucid::LocationHelper
|
5
|
+
|
6
|
+
attr_reader :constants, :keyword, :source, :value, :literal_value
|
7
|
+
attr_accessor :steps, :pending, :substeps
|
8
|
+
|
9
|
+
# This defines an escape pattern within a string or regex:
|
10
|
+
# /^the first #{CONSTANT} step$/
|
11
|
+
#
|
12
|
+
# This is used below in the value to process it if there happen to be
|
13
|
+
# constants defined here. It's important to note that this will not
|
14
|
+
# handle the result of method calls and it will not handle multiple
|
15
|
+
# constants within the same escaped area.
|
16
|
+
def escape_pattern
|
17
|
+
/#\{\s*(\w+)\s*\}/
|
18
|
+
end
|
19
|
+
|
20
|
+
# The idea of this is method is that when requesting a step tranform object
|
21
|
+
# value, process it, if it hasn't alredy been processed, replacing any
|
22
|
+
# constants that may be escaped within the value.
|
23
|
+
#
|
24
|
+
# Processing here means looking for any escaped characters that happen to
|
25
|
+
# be CONSTANTS that could be matched and then replaced. This needs to be
|
26
|
+
# done recursively since CONSTANTS can be defined with more CONSTANTS.
|
27
|
+
def value
|
28
|
+
unless @processed
|
29
|
+
@processed = true
|
30
|
+
until (nested = constants_from_value).empty?
|
31
|
+
nested.each { |n| @value.gsub!(value_regex(n),find_value_for_constant(n)) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
@value
|
36
|
+
end
|
37
|
+
|
38
|
+
# Set the literal value and the value of the step definition.
|
39
|
+
#
|
40
|
+
# The literal value is as it appears in the step definition file with any
|
41
|
+
# constants. The value, when retrieved will attempt to replace those
|
42
|
+
# constants with their regex or string equivalents to hopefully match more
|
43
|
+
# steps and step definitions.
|
44
|
+
def value=(value)
|
45
|
+
@literal_value = format_source(value)
|
46
|
+
@value = format_source(value)
|
47
|
+
|
48
|
+
@steps = []
|
49
|
+
value
|
50
|
+
end
|
51
|
+
|
52
|
+
# Generate a regex with the step transform value.
|
53
|
+
def regex
|
54
|
+
@regex ||= /#{strip_regex_from(value)}/
|
55
|
+
end
|
56
|
+
|
57
|
+
# Look through the specified data for the escape pattern and return an
|
58
|
+
# array of those constants found. This defaults to the @value within the
|
59
|
+
# step transform as it is used internally, however, it can be called
|
60
|
+
# externally if it's needed somewhere.
|
61
|
+
def constants_from_value(data=@value)
|
62
|
+
data.scan(escape_pattern).flatten.collect { |value| value.strip }
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
# This looks through all the constants in the registry and returns the value
|
68
|
+
# with the regex items replaced from the constnat if present.
|
69
|
+
def find_value_for_constant(name)
|
70
|
+
constant = YARD::Registry.all(:constant).find { |c| c.name == name.to_sym }
|
71
|
+
log.warn "StepTransformer#find_value_for_constant : Could not find the CONSTANT [#{name}] using the string value." unless constant
|
72
|
+
constant ? strip_regex_from(constant.value) : name
|
73
|
+
end
|
74
|
+
|
75
|
+
# Return a regex of the value.
|
76
|
+
def value_regex(value)
|
77
|
+
/#\{\s*#{value}\s*\}/
|
78
|
+
end
|
79
|
+
|
80
|
+
# Strip the regex starting / and ending / from the value.
|
81
|
+
def strip_regex_from(value)
|
82
|
+
value.gsub(/^\/|\/$/,'')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module YARD
|
2
|
+
module Handlers
|
3
|
+
module Lucid
|
4
|
+
class Base < Handlers::Base
|
5
|
+
class << self
|
6
|
+
include Parser::Lucid
|
7
|
+
def handles?(node)
|
8
|
+
handlers.any? do |a_handler|
|
9
|
+
node.class == a_handler
|
10
|
+
end
|
11
|
+
end
|
12
|
+
include Parser::Lucid
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Processor.register_handler_namespace :feature, Lucid
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module YARD
|
2
|
+
module Handlers
|
3
|
+
module Lucid
|
4
|
+
class FeatureHandler < Base
|
5
|
+
handles CodeObjects::Lucid::Feature
|
6
|
+
|
7
|
+
# This method is currently not needed. It would be needed if there was
|
8
|
+
# further processing to be done on the features.
|
9
|
+
def process
|
10
|
+
end
|
11
|
+
|
12
|
+
# Register, once, when all files are finished. This will trigger the
|
13
|
+
# final matching of feature steps to step definitions and steps to
|
14
|
+
# transforms.
|
15
|
+
YARD::Parser::SourceParser.after_parse_list do |files,globals|
|
16
|
+
YARD::Registry.all(:feature).each do |feature|
|
17
|
+
FeatureHandler.match_steps_to_step_definitions(feature)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
@@step_definitions = nil
|
23
|
+
@@step_transforms = nil
|
24
|
+
|
25
|
+
def match_steps_to_step_definitions(statement)
|
26
|
+
# Create a cache of all of the steps and the transforms.
|
27
|
+
@@step_definitions = cache(:stepdefinition) unless @@step_definitions
|
28
|
+
@@step_transforms = cache(:steptransform) unless @@step_transforms
|
29
|
+
|
30
|
+
if statement
|
31
|
+
# For the background and the scenario, find the steps that have
|
32
|
+
# definitions.
|
33
|
+
process_scenario(statement.background) if statement.background
|
34
|
+
|
35
|
+
statement.scenarios.each do |scenario|
|
36
|
+
if scenario.outline?
|
37
|
+
scenario.scenarios.each_with_index do |example,index|
|
38
|
+
process_scenario(example)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
process_scenario(scenario)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
else
|
45
|
+
log.warn "Empty feature file. A feature failed to process correctly or contains no feature"
|
46
|
+
end
|
47
|
+
|
48
|
+
rescue YARD::Handlers::NamespaceMissingError
|
49
|
+
rescue Exception => exception
|
50
|
+
log.error "Skipping feature because an error has occurred."
|
51
|
+
log.debug "\n#{exception}\n#{exception.backtrace.join("\n")}\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
# The cache is used to store all comparable items with their
|
55
|
+
# compare_value as the key and the item as the value. This will
|
56
|
+
# reject any compare values that contain escapes -- #{} -- because
|
57
|
+
# that means the values have unpacked constants.
|
58
|
+
def cache(type)
|
59
|
+
YARD::Registry.all(type).inject({}) do |hash,item|
|
60
|
+
hash[item.regex] = item if item.regex
|
61
|
+
hash
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def process_scenario(scenario)
|
66
|
+
scenario.steps.each {|step| process_step(step) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def process_step(step)
|
70
|
+
match_step_to_step_definition_and_transforms(step)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Given a step object, attempt to match that step to a transform.
|
74
|
+
def match_step_to_step_definition_and_transforms(step)
|
75
|
+
@@step_definitions.each_pair do |stepdef,stepdef_object|
|
76
|
+
stepdef_matches = step.value.match(stepdef)
|
77
|
+
|
78
|
+
if stepdef_matches
|
79
|
+
step.definition = stepdef_object
|
80
|
+
stepdef_matches[-1..1].each do |match|
|
81
|
+
@@step_transforms.each do |steptrans,steptransform_object|
|
82
|
+
if steptrans.match(match)
|
83
|
+
step.transforms << steptransform_object
|
84
|
+
steptransform_object.steps << step
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# A this point the step has been matched to the definition and
|
90
|
+
# to any transforms. As a design note, if the step were to
|
91
|
+
# match again, it would be possible to display any steps that
|
92
|
+
# are considered ambiguous.
|
93
|
+
# This would be a nice to have.
|
94
|
+
break
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Finds and processes all the step matchers defined in the source code.
|
2
|
+
#
|
3
|
+
# To override the language you can define the step keywords in the YARD
|
4
|
+
# configuration file `~./yard/config`.
|
5
|
+
class YARD::Handlers::Ruby::StepDefinitionHandler < YARD::Handlers::Ruby::Base
|
6
|
+
def self.default_step_definitions
|
7
|
+
[ "Given", "When", "Then", "And", "But", "*" ]
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.custom_step_definitions
|
11
|
+
YARD::Config.options["yard-lucid"]["language"]["step_definitions"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.custom_step_definitions_defined?
|
15
|
+
YARD::Config.options["yard-lucid"] and
|
16
|
+
YARD::Config.options["yard-lucid"]["language"] and
|
17
|
+
YARD::Config.options["yard-lucid"]["language"]["step_definitions"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.step_definitions
|
21
|
+
if custom_step_definitions_defined?
|
22
|
+
custom_step_definitions
|
23
|
+
else
|
24
|
+
default_step_definitions
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
step_definitions.each { |step_def| handles method_call(step_def) }
|
29
|
+
|
30
|
+
process do
|
31
|
+
instance = YARD::CodeObjects::StepDefinitionObject.new(step_transform_namespace, step_definition_name) do |o|
|
32
|
+
o.source = statement.source
|
33
|
+
o.comments = statement.comments
|
34
|
+
o.keyword = statement.method_name.source
|
35
|
+
o.value = statement.parameters.source
|
36
|
+
o.pending = pending_keyword_used?(statement.block)
|
37
|
+
end
|
38
|
+
|
39
|
+
obj = register instance
|
40
|
+
parse_block(statement[2],:owner => obj)
|
41
|
+
end
|
42
|
+
|
43
|
+
def pending_keyword
|
44
|
+
"pending"
|
45
|
+
end
|
46
|
+
|
47
|
+
def pending_command_statement?(line)
|
48
|
+
(line.type == :command || line.type == :vcall) && line.first.source == pending_keyword
|
49
|
+
end
|
50
|
+
|
51
|
+
def pending_keyword_used?(block)
|
52
|
+
code_in_block = block.last
|
53
|
+
code_in_block.find { |line| pending_command_statement?(line) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def step_transform_namespace
|
57
|
+
YARD::CodeObjects::Lucid::LUCID_STEPTRANSFORM_NAMESPACE
|
58
|
+
end
|
59
|
+
|
60
|
+
def step_definition_name
|
61
|
+
"step_definition#{self.class.generate_unique_id}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.generate_unique_id
|
65
|
+
@step_definition_count = @step_definition_count.to_i + 1
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class YARD::Handlers::Ruby::StepTransformHandler < YARD::Handlers::Ruby::Base
|
2
|
+
handles method_call(:Transform)
|
3
|
+
|
4
|
+
process do
|
5
|
+
instance = YARD::CodeObjects::StepTransformObject.new(step_transform_namespace,step_transformer_name) do |o|
|
6
|
+
o.source = statement.source
|
7
|
+
o.comments = statement.comments
|
8
|
+
o.keyword = statement[0].source
|
9
|
+
o.value = statement[1].source
|
10
|
+
end
|
11
|
+
|
12
|
+
obj = register instance
|
13
|
+
parse_block(statement[2],:owner => obj)
|
14
|
+
end
|
15
|
+
|
16
|
+
def step_transform_namespace
|
17
|
+
YARD::CodeObjects::Lucid::LUCID_STEPTRANSFORM_NAMESPACE
|
18
|
+
end
|
19
|
+
|
20
|
+
def step_transformer_name
|
21
|
+
"step_transform#{self.class.generate_unique_id}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.generate_unique_id
|
25
|
+
@step_transformer_count = @step_transformer_count.to_i + 1
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "yard"
|
2
|
+
|
3
|
+
module YARD::Parser::Lucid
|
4
|
+
class FeatureParser < YARD::Parser::Base
|
5
|
+
# Each feature found creates a new FeatureParser.
|
6
|
+
#
|
7
|
+
# A Gherkin "builder" is created that will store a representation of the
|
8
|
+
# feature file. That feature file is then sent to the Gherkin parser.
|
9
|
+
# The Lucid::Parser::GherkinRepr is being used to parse the elements of
|
10
|
+
# the faeture file into YARD::CodeObjects.
|
11
|
+
def initialize(source, file = '(stdin)')
|
12
|
+
@builder = Lucid::Parser::GherkinRepr.new(file)
|
13
|
+
@tag_counts = {}
|
14
|
+
@parser = Gherkin::Parser.new(@builder)
|
15
|
+
|
16
|
+
@source = source
|
17
|
+
@file = file
|
18
|
+
|
19
|
+
@feature = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
# When parse is called, the Gherkin parser is executed and all the feature
|
23
|
+
# elements that are found are sent to the various methods in the
|
24
|
+
# Lucid::Parser::GherkinRepr. The result of this is a syntax tree
|
25
|
+
# representation of the feature that contains all the scenarios and steps.
|
26
|
+
def parse
|
27
|
+
begin
|
28
|
+
@parser.parse(@source)
|
29
|
+
@feature = @builder.ast
|
30
|
+
return nil if @feature.nil?
|
31
|
+
|
32
|
+
# The parser used the following keywords when parsing the feature
|
33
|
+
# @feature.language = @parser.i18n_language.get_code_keywords.map {|word| word }
|
34
|
+
|
35
|
+
rescue Gherkin::ParserError => e
|
36
|
+
e.message.insert(0, "#{@file}: ")
|
37
|
+
warn e
|
38
|
+
end
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
# While the method is necessary, nothing actually happens here because all
|
44
|
+
# of the work is done in the parse method.
|
45
|
+
def tokenize
|
46
|
+
end
|
47
|
+
|
48
|
+
# The only enumeration that can be done at this level is the feature
|
49
|
+
# itself. There is no construct higher than a feature wherein a feature
|
50
|
+
# can be enumerated.
|
51
|
+
def enumerator
|
52
|
+
[@feature]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Register all feature files to be processed with the above FeatureParser
|
57
|
+
YARD::Parser::SourceParser.register_parser_type :feature, FeatureParser, 'feature'
|
58
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module YARD
|
2
|
+
module Server
|
3
|
+
class Adapter
|
4
|
+
class << self
|
5
|
+
alias_method :yard_setup, :setup
|
6
|
+
|
7
|
+
# To provide the templates necessary for `yard-lucid` to integrate
|
8
|
+
# with YARD the adapter has to around-alias the setup method to place
|
9
|
+
# the `yard-lucid` server templates as the last template in the list.
|
10
|
+
#
|
11
|
+
# When they are normally loaded with the plugin they cause an error with
|
12
|
+
# the `yardoc` command. They are also not used because the YARD server
|
13
|
+
# templates are placed after all plugin templates.
|
14
|
+
def setup
|
15
|
+
yard_setup
|
16
|
+
YARD::Templates::Engine.template_paths +=
|
17
|
+
[File.dirname(__FILE__) + '/../../templates',File.dirname(__FILE__) + '/../../docserver']
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :yard_shutdown, :shutdown
|
21
|
+
|
22
|
+
# Similar to the addition, it is good business to tear down the templates
|
23
|
+
# that were added by again around-aliasing the shutdown method.
|
24
|
+
def shutdown
|
25
|
+
yard_shutdown
|
26
|
+
YARD::Templates::Engine.template_paths -=
|
27
|
+
[File.dirname(__FILE__) + '/../../templates',File.dirname(__FILE__) + '/../../docserver']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module YARD
|
2
|
+
module Server
|
3
|
+
module Commands
|
4
|
+
# List Features powers the features menu option in `yard server`
|
5
|
+
class ListFeaturesCommand < ListCommand
|
6
|
+
def type; :features end
|
7
|
+
|
8
|
+
def items
|
9
|
+
Registry.load_all
|
10
|
+
run_verifier(Registry.all(:feature))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# List Tags powers the tags menu option in `yard server`
|
15
|
+
class ListTagsCommand < ListCommand
|
16
|
+
def type; :tags end
|
17
|
+
|
18
|
+
def items
|
19
|
+
Registry.load_all
|
20
|
+
run_verifier(Registry.all(:tag).sort_by {|t| t.value.to_s })
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module YARD
|
2
|
+
module Server
|
3
|
+
# The YARD::Server::Router needs the following modification,
|
4
|
+
# so that it will provide routing for the features and tags commands
|
5
|
+
# to their appropriate definitions
|
6
|
+
Router.class_eval do
|
7
|
+
alias_method :core_route_list, :route_list
|
8
|
+
|
9
|
+
# Provide the full list of features and tags
|
10
|
+
def route_list(library, paths)
|
11
|
+
if paths && !paths.empty? && paths.first =~ /^(?:features|tags)$/
|
12
|
+
case paths.shift
|
13
|
+
when "features"; cmd = Commands::ListFeaturesCommand
|
14
|
+
when "tags"; cmd = Commands::ListTagsCommand
|
15
|
+
end
|
16
|
+
cmd.new(final_options(library, paths)).call(request)
|
17
|
+
else
|
18
|
+
core_route_list(library,paths)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module YARD::Templates::Helpers
|
2
|
+
module BaseHelper
|
3
|
+
def format_object_title(object)
|
4
|
+
if object.is_a?(YARD::CodeObjects::Lucid::FeatureTags)
|
5
|
+
"Tags"
|
6
|
+
elsif object.is_a?(YARD::CodeObjects::Lucid::StepTransformersObject)
|
7
|
+
"Steps and Transforms"
|
8
|
+
elsif object.is_a?(YARD::CodeObjects::Lucid::NamespaceObject)
|
9
|
+
"#{format_object_type(object)}#{object.value ? ": #{object.value}" : ''}"
|
10
|
+
elsif object.is_a?(YARD::CodeObjects::Lucid::FeatureDirectory)
|
11
|
+
"Feature Directory: #{object.name}"
|
12
|
+
else
|
13
|
+
case object
|
14
|
+
when YARD::CodeObjects::RootObject
|
15
|
+
"Top Level Namespace"
|
16
|
+
else
|
17
|
+
format_object_type(object) + ": " + object.path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/yard-lucid.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "gherkin/parser"
|
2
|
+
|
3
|
+
require "yard-lucid/version"
|
4
|
+
|
5
|
+
require "lucid/gherkin_repr"
|
6
|
+
|
7
|
+
require "yard/parser/lucid/feature"
|
8
|
+
|
9
|
+
require "yard/code_objects/lucid/base"
|
10
|
+
require "yard/code_objects/lucid/namespace_object"
|
11
|
+
require "yard/code_objects/lucid/feature"
|
12
|
+
require "yard/code_objects/lucid/scenario_outline"
|
13
|
+
require "yard/code_objects/lucid/scenario"
|
14
|
+
require "yard/code_objects/lucid/step"
|
15
|
+
require "yard/code_objects/lucid/tag"
|
16
|
+
require "yard/code_objects/step_transformer"
|
17
|
+
require "yard/code_objects/step_definition"
|
18
|
+
require "yard/code_objects/step_transform"
|
19
|
+
|
20
|
+
require "yard/handlers/lucid/base"
|
21
|
+
require "yard/handlers/lucid/feature_handler"
|
22
|
+
require "yard/handlers/step_definition_handler"
|
23
|
+
require "yard/handlers/step_transform_handler"
|
24
|
+
|
25
|
+
require "yard/templates/helpers/base_helper"
|
26
|
+
|
27
|
+
require "yard/server/adapter"
|
28
|
+
require "yard/server/commands/list_command"
|
29
|
+
require "yard/server/router"
|
30
|
+
|
31
|
+
# This registered template works for yardoc
|
32
|
+
YARD::Templates::Engine.register_template_path File.dirname(__FILE__) + '/templates'
|
33
|
+
|
34
|
+
# The following paths are needed for the yard server
|
35
|
+
YARD::Server.register_static_path File.dirname(__FILE__) + "/templates/default/fulldoc/html"
|
36
|
+
YARD::Server.register_static_path File.dirname(__FILE__) + "/docserver/default/fulldoc/html"
|
data/yard-lucid.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'yard-lucid/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "yard-lucid"
|
8
|
+
spec.version = YardLucid::VERSION
|
9
|
+
spec.authors = ["Jeff Nyman"]
|
10
|
+
spec.email = ["jeffnyman@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{YARD Documentation Generator for Gherkin-based Repositories}
|
13
|
+
spec.description = %q{YARD Documentation Generator for Gherkin-based Repositories}
|
14
|
+
spec.homepage = "https://github.com/jeffnyman/yard-lucid"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "pry"
|
28
|
+
|
29
|
+
spec.add_runtime_dependency "yard"
|
30
|
+
spec.add_runtime_dependency "gherkin", "~> 4.0"
|
31
|
+
spec.add_runtime_dependency "cucumber", "~> 2.0"
|
32
|
+
|
33
|
+
spec.post_install_message = %{
|
34
|
+
(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)
|
35
|
+
Yard-Lucid #{YardLucid::VERSION} has been installed.
|
36
|
+
(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)
|
37
|
+
}
|
38
|
+
end
|