yard-cucumber 2.0.3 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.md +59 -19
- data/city.gemspec +1 -1
- data/example/french.feature +18 -0
- data/example/step_definitions/french_steps.rb +32 -0
- data/lib/cucumber/city_builder.rb +98 -8
- data/lib/templates/default/fulldoc/html/css/{common.css → cucumber.css} +0 -0
- data/lib/templates/default/fulldoc/html/js/cucumber.js +15 -7
- data/lib/templates/default/fulldoc/html/setup.rb +38 -10
- data/lib/templates/default/layout/html/setup.rb +49 -7
- data/lib/yard-cucumber.rb +2 -2
- data/lib/yard/code_objects/step_transformer.rb +53 -9
- data/lib/yard/handlers/cucumber/base.rb +1 -2
- data/lib/yard/handlers/cucumber/feature_handler.rb +98 -60
- data/lib/yard/handlers/legacy/step_definition_handler.rb +0 -1
- data/lib/yard/handlers/step_definition_handler.rb +38 -2
- data/lib/yard/parser/cucumber/feature.rb +27 -3
- metadata +6 -9
- data/lib/templates/default/fulldoc/html/full_list.erb +0 -36
- data/lib/templates/default/fulldoc/html/index.erb +0 -24
- data/lib/templates/default/layout/html/headers.erb +0 -14
- data/lib/templates/default/layout/html/search.erb +0 -5
- data/lib/yard/parser/source_parser.rb +0 -58
data/History.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
=== 2.1.0 / 2011-05-22
|
2
|
+
|
3
|
+
* YARD 0.7.0 compatibility (removed some monkey-patching)
|
4
|
+
* Add more menus (Steps and Step Definitions)
|
5
|
+
* Define step definitions in your language Internalization (Ruby 1.9.2)
|
6
|
+
|
1
7
|
=== 2.0.3 / 2011-05-22
|
2
8
|
|
3
9
|
* Updated Cucumber links to the new github organization
|
data/README.md
CHANGED
@@ -40,19 +40,23 @@ The implemented example has been deployed at [http://recursivegames.com/cukes/](
|
|
40
40
|
|
41
41
|
**9. Feature directories with a README.md will be parsed into the description** [example](http://recursivegames.com/cukes/requirements/example/child_feature.html)
|
42
42
|
|
43
|
+
**10. Configurable Menus - want a searchable steps menu and remove the tags menu**
|
44
|
+
|
45
|
+
**11. Step definitions in your language (Ruby 1.9.2 - Internationalization)**
|
46
|
+
|
43
47
|
Installation
|
44
48
|
------------
|
45
49
|
|
46
|
-
Cucumber
|
50
|
+
YARD-Cucumber requires the following gems installed:
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
Gherkin 2.3.5 - http://cukes.info
|
53
|
+
Cucumber 0.7.5 - http://cukes.info
|
54
|
+
YARD 0.7.0 - http://yardoc.org
|
51
55
|
|
52
|
-
To install
|
56
|
+
To install `yard-cucumber` use the following command:
|
57
|
+
|
58
|
+
$ gem install yard-cucumber
|
53
59
|
|
54
|
-
$ gem install yard-cucumber
|
55
|
-
|
56
60
|
(Add `sudo` if you're installing under a POSIX system as root)
|
57
61
|
|
58
62
|
Usage
|
@@ -61,25 +65,61 @@ Usage
|
|
61
65
|
YARD supports for automatically including gems with the prefix `yard-`
|
62
66
|
as a plugin. To enable automatic loading yard-cucumber.
|
63
67
|
|
64
|
-
|
68
|
+
$ yard config load_plugins true
|
69
|
+
$ yardoc 'example/**/*.rb' 'example/**/*.feature'
|
65
70
|
|
66
|
-
|
71
|
+
Now you can run YARD as you [normally](https://github.com/lsegal/yard) would and
|
72
|
+
have your features, step definitions and transforms captured.
|
67
73
|
|
68
|
-
|
74
|
+
An example with the rake task:
|
69
75
|
|
70
|
-
|
71
|
-
files. yard-cucumber will even process your step definitions and transforms.
|
76
|
+
require 'yard'
|
72
77
|
|
73
|
-
|
78
|
+
YARD::Rake::YardocTask.new do |t|
|
79
|
+
t.files = ['features/**/*.feature', 'features/**/*.rb']
|
80
|
+
t.options = ['--any', '--extra', '--opts'] # optional
|
81
|
+
end
|
74
82
|
|
75
|
-
An example with the rake task:
|
76
83
|
|
77
|
-
|
84
|
+
Configuration
|
85
|
+
-------------
|
86
|
+
|
87
|
+
* Adding or Removing search fields (yardoc)
|
88
|
+
|
89
|
+
Be default the yardoc output will generate a search field for features and tags.
|
90
|
+
This can be configured through the yard configuration file `~./yard/config` to
|
91
|
+
add or remove these search fields.
|
92
|
+
|
93
|
+
--- !map:SymbolHash
|
94
|
+
:load_plugins: true
|
95
|
+
:ignored_plugins: []
|
96
|
+
|
97
|
+
:autoload_plugins: []
|
98
|
+
|
99
|
+
:safe_mode: false
|
100
|
+
|
101
|
+
:"yard-cucumber":
|
102
|
+
menus: [ 'features', 'tags', 'steps', 'stepdefinitions' ]
|
103
|
+
|
104
|
+
|
105
|
+
By default the configuration, yaml format, that is generate by the `yard config`
|
106
|
+
command will save a `SymbolHash`. You can still edit this file add the entry for
|
107
|
+
`:"yard-cucumber":` and the sub-entry `menus:` which can contain all of the above
|
108
|
+
mentioned menus or simply an empty array `[]` if you want no additional menus.
|
109
|
+
|
110
|
+
* Step definitions in your language (Ruby 1.9.2)
|
111
|
+
|
112
|
+
Again the yard configuration file you can define additional step definitions that
|
113
|
+
can be matched.
|
114
|
+
|
115
|
+
:"yard-cucumber":
|
116
|
+
language:
|
117
|
+
step_definitions: [ 'Given', 'When', 'Then', 'And', 'Soit', 'Etantdonné', 'Lorsque', 'Lorsqu', 'Alors', 'Et' ]
|
78
118
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
119
|
+
In this example, I have included the French step definition words alongside the
|
120
|
+
English step definitions. Even without specifying this feature files in other
|
121
|
+
languages are found, this provides the ability for the step definitions to match
|
122
|
+
correctly to step definitions.
|
83
123
|
|
84
124
|
Details
|
85
125
|
--------
|
data/city.gemspec
CHANGED
@@ -56,7 +56,7 @@ Gem::Specification.new do |s|
|
|
56
56
|
|
57
57
|
s.add_dependency 'gherkin', '>= 2.2.9'
|
58
58
|
s.add_dependency 'cucumber', '>= 0.7.5'
|
59
|
-
s.add_dependency 'yard', '>= 0.
|
59
|
+
s.add_dependency 'yard', '>= 0.7.0'
|
60
60
|
|
61
61
|
s.rubygems_version = "1.3.7"
|
62
62
|
s.files = `git ls-files`.split("\n")
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# language: fr
|
2
|
+
Fonctionnalité: Addition
|
3
|
+
Afin de gagner du temps lors du calcul de la facture
|
4
|
+
En tant que commerçant
|
5
|
+
Je souhaite pouvoir faire une addition
|
6
|
+
|
7
|
+
Plan du Scénario: Addition de deux nombres
|
8
|
+
Soit une calculatrice
|
9
|
+
Et que j'entre <a> pour le premier nombre
|
10
|
+
Et que je tape sur la touche "+"
|
11
|
+
Et que j'entre <b> pour le second nombre
|
12
|
+
Lorsque je tape sur la touche "="
|
13
|
+
Alors le résultat affiché doit être <somme>
|
14
|
+
|
15
|
+
Exemples:
|
16
|
+
| a | b | somme |
|
17
|
+
| 2 | 2 | 4 |
|
18
|
+
| 2 | 3 | 5 |
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
Soit /^une calculatrice$/ do
|
3
|
+
@calc = Calculatrice.new
|
4
|
+
end
|
5
|
+
|
6
|
+
Etantdonné /^qu'on tape (.*)$/ do |n|
|
7
|
+
@calc.push n.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
Etantdonné /^que j'entre (\d+) pour le (.*) nombre/ do |n, x|
|
11
|
+
@calc.push n.to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
Lorsque /^je tape sur la touche "="$/ do
|
15
|
+
@expected_result = @calc.additionner
|
16
|
+
end
|
17
|
+
|
18
|
+
Lorsqu /on tape additionner/ do
|
19
|
+
@expected_result = @calc.additionner
|
20
|
+
end
|
21
|
+
|
22
|
+
Alors /le résultat affiché doit être (\d*)/ do |result|
|
23
|
+
result.to_i.should == @expected_result
|
24
|
+
end
|
25
|
+
|
26
|
+
Alors /le résultat doit être (\d*)/ do |result|
|
27
|
+
result.to_i.should == @expected_result
|
28
|
+
end
|
29
|
+
|
30
|
+
Soit /^que je tape sur la touche "\+"$/ do
|
31
|
+
# noop
|
32
|
+
end
|
@@ -3,17 +3,48 @@ module Cucumber
|
|
3
3
|
module Parser
|
4
4
|
class CityBuilder
|
5
5
|
include Gherkin::Rubify
|
6
|
-
|
6
|
+
|
7
|
+
#
|
8
|
+
# The Gherkin Parser is going to call the various methods within this
|
9
|
+
# class as it finds items. This is similar to how Cucumber generates
|
10
|
+
# it's Abstract Syntax Tree (AST). Here instead this generates the
|
11
|
+
# various YARD::CodeObjects defined within this template.
|
12
|
+
#
|
13
|
+
# A namespace is specified and that is the place in the YARD namespacing
|
14
|
+
# where all cucumber features generated will reside. The namespace specified
|
15
|
+
# is the root namespaces.
|
16
|
+
#
|
17
|
+
# @param [String] file the name of the file which the content belongs
|
18
|
+
#
|
7
19
|
def initialize(file)
|
8
20
|
@namespace = YARD::CodeObjects::Cucumber::CUCUMBER_NAMESPACE
|
9
21
|
find_or_create_namespace(file)
|
10
22
|
@file = file
|
11
23
|
end
|
12
24
|
|
25
|
+
# Return the feature that has been defined. This method is the final
|
26
|
+
# method that is called when all the work is done. It is called by
|
27
|
+
# the feature parser to return the complete Feature object that was created
|
28
|
+
#
|
29
|
+
# @return [YARD::CodeObject::Cucumber::Feature] the completed feature
|
30
|
+
#
|
31
|
+
# @see YARD::Parser::Cucumber::FeatureParser
|
13
32
|
def ast
|
14
|
-
@feature
|
33
|
+
@feature
|
15
34
|
end
|
16
|
-
|
35
|
+
|
36
|
+
#
|
37
|
+
# Feature that are found in sub-directories are considered, in the way
|
38
|
+
# that I chose to implement it, in another namespace. This is because
|
39
|
+
# when you execute a cucumber test run on a directory any sub-directories
|
40
|
+
# of features will be executed with that directory so the file is split
|
41
|
+
# and then namespaces are generated if they have not already have been.
|
42
|
+
#
|
43
|
+
# The other duty that this does is look for a README.md file within the
|
44
|
+
# specified directory of the file and loads it as the description for the
|
45
|
+
# namespace. This is useful if you want to give a particular directory
|
46
|
+
# some flavor or text to describe what is going on.
|
47
|
+
#
|
17
48
|
def find_or_create_namespace(file)
|
18
49
|
@namespace = YARD::CodeObjects::Cucumber::CUCUMBER_NAMESPACE
|
19
50
|
|
@@ -26,7 +57,20 @@ module Cucumber
|
|
26
57
|
@namespace.description = File.read("#{File.dirname(file)}/README.md")
|
27
58
|
end
|
28
59
|
end
|
29
|
-
|
60
|
+
|
61
|
+
#
|
62
|
+
# Find the tag if it exists within the YARD Registry, if it doesn' t then
|
63
|
+
# create it.
|
64
|
+
#
|
65
|
+
# We note that the tag was used in this file at the current line.
|
66
|
+
#
|
67
|
+
# Then we add the tag to the current scenario or feature. We also add the
|
68
|
+
# feature or scenario to the tag.
|
69
|
+
#
|
70
|
+
# @param [String] tag_name the name of the tag
|
71
|
+
# @param [parent] parent the scenario or feature that is going to adopt
|
72
|
+
# this tag.
|
73
|
+
#
|
30
74
|
def find_or_create_tag(tag_name,parent)
|
31
75
|
#log.debug "Processing tag #{tag_name}"
|
32
76
|
tag_code_object = YARD::Registry.all(:tag).find {|tag| tag.value == tag_name } ||
|
@@ -37,7 +81,12 @@ module Cucumber
|
|
37
81
|
parent.tags << tag_code_object unless parent.tags.find {|tag| tag == tag_code_object }
|
38
82
|
tag_code_object.owners << parent unless tag_code_object.owners.find {|owner| owner == parent}
|
39
83
|
end
|
40
|
-
|
84
|
+
|
85
|
+
#
|
86
|
+
# Each feature found will call this method, generating the feature object.
|
87
|
+
# This is once, as the gherking parser does not like multiple feature per
|
88
|
+
# file.
|
89
|
+
#
|
41
90
|
def feature(feature)
|
42
91
|
#log.debug "FEATURE"
|
43
92
|
|
@@ -52,7 +101,11 @@ module Cucumber
|
|
52
101
|
feature.tags.each {|feature_tag| find_or_create_tag(feature_tag.name,f) }
|
53
102
|
end
|
54
103
|
end
|
55
|
-
|
104
|
+
|
105
|
+
#
|
106
|
+
# Called when a background has been found
|
107
|
+
#
|
108
|
+
# @see #scenario
|
56
109
|
def background(background)
|
57
110
|
#log.debug "BACKGROUND"
|
58
111
|
|
@@ -68,7 +121,20 @@ module Cucumber
|
|
68
121
|
@background.feature = @feature
|
69
122
|
@step_container = @background
|
70
123
|
end
|
71
|
-
|
124
|
+
|
125
|
+
#
|
126
|
+
# Called when a scenario has been found
|
127
|
+
# - create a scenario
|
128
|
+
# - assign the scenario to the feature
|
129
|
+
# - assign the feature to the scenario
|
130
|
+
# - find or create tags associated with the scenario
|
131
|
+
#
|
132
|
+
# The scenario is set as the @step_container, which means that any steps
|
133
|
+
# found before another scenario is defined belong to this scenario
|
134
|
+
#
|
135
|
+
# @param [Scenario] statement is a scenario object returned from Gherkin
|
136
|
+
# @see #find_or_create_tag
|
137
|
+
#
|
72
138
|
def scenario(statement)
|
73
139
|
#log.debug "SCENARIO"
|
74
140
|
|
@@ -86,7 +152,14 @@ module Cucumber
|
|
86
152
|
@feature.scenarios << scenario
|
87
153
|
@step_container = scenario
|
88
154
|
end
|
89
|
-
|
155
|
+
|
156
|
+
#
|
157
|
+
# Called when a scenario outline is found. Very similar to a scenario,
|
158
|
+
# the ScenarioOutline is still a distinct object as it can contain
|
159
|
+
# multiple different example groups that can contain different values.
|
160
|
+
#
|
161
|
+
# @see #scenario
|
162
|
+
#
|
90
163
|
def scenario_outline(statement)
|
91
164
|
#log.debug "SCENARIO OUTLINE"
|
92
165
|
|
@@ -105,6 +178,13 @@ module Cucumber
|
|
105
178
|
@step_container = outline
|
106
179
|
end
|
107
180
|
|
181
|
+
#
|
182
|
+
# Examples for a scenario outline are called here. This section differs
|
183
|
+
# from the Cucumber parser because here each of the examples are exploded
|
184
|
+
# out here as individual scenarios and step definitions. This is so that
|
185
|
+
# later we can ensure that we have all the variations of the scenario
|
186
|
+
# outline defined to be displayed.
|
187
|
+
#
|
108
188
|
def examples(examples)
|
109
189
|
#log.debug "EXAMPLES"
|
110
190
|
|
@@ -157,6 +237,14 @@ module Cucumber
|
|
157
237
|
|
158
238
|
end
|
159
239
|
|
240
|
+
#
|
241
|
+
# Called when a step is found. The step is refered to a table owner, though
|
242
|
+
# not all steps have a table or multliline arguments associated with them.
|
243
|
+
#
|
244
|
+
# If a multiline string is present with the step it is included as the text
|
245
|
+
# of the step. If the step has a table it is added to the step using the
|
246
|
+
# same method used by the Cucumber Gherkin model.
|
247
|
+
#
|
160
248
|
def step(step)
|
161
249
|
#log.debug "STEP"
|
162
250
|
|
@@ -182,9 +270,11 @@ module Cucumber
|
|
182
270
|
@step_container.steps << @table_owner
|
183
271
|
end
|
184
272
|
|
273
|
+
# Defined in the cucumber version so left here. No events for the end-of-file
|
185
274
|
def eof
|
186
275
|
end
|
187
276
|
|
277
|
+
# When a syntax error were to occurr. This parser is not interested in errors
|
188
278
|
def syntax_error(state, event, legal_events, line)
|
189
279
|
# raise "SYNTAX ERROR"
|
190
280
|
end
|
File without changes
|
@@ -1,22 +1,30 @@
|
|
1
1
|
function cucumberSearchFrameLinks() {
|
2
|
-
$('#
|
2
|
+
$('#feature_list_link').click(function() {
|
3
3
|
toggleSearchFrame(this, relpath + 'feature_list.html');
|
4
4
|
});
|
5
|
-
$('#
|
5
|
+
$('#tag_list_link').click(function() {
|
6
6
|
toggleSearchFrame(this, relpath + 'tag_list.html');
|
7
7
|
});
|
8
|
+
$('#step_list_link').click(function() {
|
9
|
+
toggleSearchFrame(this, relpath + 'step_list.html');
|
10
|
+
});
|
11
|
+
$('#stepdefinition_list_link').click(function() {
|
12
|
+
toggleSearchFrame(this, relpath + 'stepdefinition_list.html');
|
13
|
+
});
|
8
14
|
}
|
9
15
|
|
10
16
|
function cucumberKeyboardShortcuts() {
|
11
17
|
if (window.top.frames.main) return;
|
12
18
|
$(document).keypress(function(evt) {
|
13
19
|
if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) return;
|
14
|
-
if (typeof evt.
|
15
|
-
(evt.
|
16
|
-
evt.
|
20
|
+
if (typeof evt.target !== "undefined" &&
|
21
|
+
(evt.target.nodeName == "INPUT" ||
|
22
|
+
evt.target.nodeName == "TEXTAREA")) return;
|
17
23
|
switch (evt.charCode) {
|
18
|
-
case
|
19
|
-
case
|
24
|
+
case 68: case 100: $('#stepdefinition_list_link').click(); break; // 'd'
|
25
|
+
case 82: case 114: $('#feature_list_link').click(); break; // 'r'
|
26
|
+
case 83: case 115: $('#step_list_link').click(); break; // 's'
|
27
|
+
case 84: case 116: $('#tag_list_link').click(); break; // 't'
|
20
28
|
}
|
21
29
|
});
|
22
30
|
}
|
@@ -15,7 +15,7 @@ def init
|
|
15
15
|
|
16
16
|
if @features
|
17
17
|
@features.each {|feature| serialize(feature) }
|
18
|
-
generate_full_list @features.sort {|x,y| x.value.to_s <=> y.value.to_s }, :feature
|
18
|
+
#generate_full_list @features.sort {|x,y| x.value.to_s <=> y.value.to_s }, :feature
|
19
19
|
end
|
20
20
|
|
21
21
|
#
|
@@ -28,7 +28,7 @@ def init
|
|
28
28
|
|
29
29
|
if @tags
|
30
30
|
@tags.each {|tag| serialize(tag) }
|
31
|
-
generate_full_list @tags.sort {|x,y| y.all_scenarios.size <=> x.all_scenarios.size }, :tag
|
31
|
+
#generate_full_list @tags.sort {|x,y| y.all_scenarios.size <=> x.all_scenarios.size }, :tag
|
32
32
|
end
|
33
33
|
|
34
34
|
# Generates the requirements splash page with the 'requirements' template
|
@@ -46,15 +46,43 @@ def init
|
|
46
46
|
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
# Generate
|
51
|
-
#
|
49
|
+
|
50
|
+
# Generate feature list
|
51
|
+
# @note this method is called automically by YARD based on the menus defined in the layout
|
52
|
+
def generate_feature_list
|
53
|
+
@features = Registry.all(:feature)
|
54
|
+
generate_full_list @features.sort {|x,y| x.value.to_s <=> y.value.to_s }, :feature
|
55
|
+
end
|
56
|
+
|
57
|
+
# Generate tag list
|
58
|
+
# @note this method is called automically by YARD based on the menus defined in the layout
|
59
|
+
def generate_tag_list
|
60
|
+
@tags = Registry.all(:tag)
|
61
|
+
generate_full_list @tags.sort {|x,y| y.all_scenarios.size <=> x.all_scenarios.size }, :tag
|
62
|
+
end
|
63
|
+
|
64
|
+
# Generate a step definition list
|
65
|
+
# @note this menu is not automatically added until yard configuration has this menu added
|
66
|
+
# See the layout template method that loads the menus
|
67
|
+
def generate_stepdefinition_list
|
68
|
+
generate_full_list YARD::Registry.all(:stepdefinition), :stepdefinition
|
69
|
+
end
|
70
|
+
|
71
|
+
# Generate a step list
|
72
|
+
# @note this menu is not automatically added until yard configuration has this menu added
|
73
|
+
# See the layout template method that loads the menus
|
74
|
+
def generate_step_list
|
75
|
+
generate_full_list YARD::Registry.all(:step), :step
|
76
|
+
end
|
77
|
+
|
78
|
+
# Helpler method to generate a full_list page of the specified objects with the
|
79
|
+
# specified type.
|
52
80
|
def generate_full_list(objects,list_type,friendly_name=nil)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
81
|
+
@items = objects
|
82
|
+
@list_type = "#{list_type}s"
|
83
|
+
@list_title = "#{friendly_name || list_type.to_s.capitalize} List"
|
84
|
+
@list_class = "class"
|
85
|
+
asset("#{list_type}_list.html",erb(:full_list))
|
58
86
|
end
|
59
87
|
|
60
88
|
#
|
@@ -2,12 +2,54 @@ def init
|
|
2
2
|
super
|
3
3
|
end
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
#
|
6
|
+
# Append yard-cucumber stylesheet to yard core stylesheets
|
7
|
+
#
|
8
|
+
def stylesheets
|
9
|
+
super + %w(css/cucumber.css)
|
8
10
|
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
#
|
13
|
+
# Append yard-cucumber javascript to yard core javascripts
|
14
|
+
#
|
15
|
+
def javascripts
|
16
|
+
super + %w(js/cucumber.js)
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Append yard-cucumber specific menus 'features' and 'tags'
|
21
|
+
#
|
22
|
+
# 'features' and 'tags' are enabled by default.
|
23
|
+
#
|
24
|
+
# 'step definitions' and 'steps' may be enabled by setting up a value in
|
25
|
+
# yard configuration file '~/.yard/config'
|
26
|
+
#
|
27
|
+
# @example `~/.yard.config`
|
28
|
+
#
|
29
|
+
# yard-cucumber:
|
30
|
+
# menus: [ 'features', 'tags', 'step definitions', 'steps' ]
|
31
|
+
#
|
32
|
+
def menu_lists
|
33
|
+
|
34
|
+
menus = [ "features", "tags" ]
|
35
|
+
|
36
|
+
# load the yard-cucumber menus defined in the configuration file
|
37
|
+
if YARD::Config.options["yard-cucumber"] and YARD::Config.options["yard-cucumber"]["menus"]
|
38
|
+
menus = YARD::Config.options["yard-cucumber"]["menus"]
|
39
|
+
end
|
40
|
+
|
41
|
+
menus.map {|menu_name| yard_cucumber_menus[menu_name] }.compact + super
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# When a menu is specified in the yard configuration file, this hash contains
|
46
|
+
# the details about the menu necessary for it to be displayed.
|
47
|
+
#
|
48
|
+
# @see #menu_lists
|
49
|
+
#
|
50
|
+
def yard_cucumber_menus
|
51
|
+
{ "features" => { :type => 'feature', :title => 'Features', :search_title => 'Features' },
|
52
|
+
"tags" => { :type => 'tag', :title => 'Tags', :search_title => 'Tags' },
|
53
|
+
"step definitions" => { :type => 'stepdefinition', :title => 'Step Definitions', :search_title => 'Step Defs' },
|
54
|
+
"steps" => { :type => 'step', :title => 'Steps', :search_title => 'Steps' } }
|
55
|
+
end
|
data/lib/yard-cucumber.rb
CHANGED
@@ -4,7 +4,7 @@ require 'gherkin/formatter/tag_count_formatter'
|
|
4
4
|
|
5
5
|
|
6
6
|
module CucumberInTheYARD
|
7
|
-
VERSION = '2.0
|
7
|
+
VERSION = '2.1.0'
|
8
8
|
end
|
9
9
|
|
10
10
|
require File.dirname(__FILE__) + "/yard/code_objects/cucumber/base.rb"
|
@@ -34,7 +34,7 @@ end
|
|
34
34
|
require File.dirname(__FILE__) + "/yard/handlers/legacy/step_definition_handler.rb"
|
35
35
|
require File.dirname(__FILE__) + "/yard/handlers/legacy/step_transform_handler.rb"
|
36
36
|
|
37
|
-
require File.dirname(__FILE__) + "/yard/parser/source_parser.rb"
|
37
|
+
#require File.dirname(__FILE__) + "/yard/parser/source_parser.rb"
|
38
38
|
require File.dirname(__FILE__) + "/yard/templates/helpers/base_helper.rb"
|
39
39
|
|
40
40
|
require File.dirname(__FILE__) + "/yard/server/adapter.rb"
|
@@ -7,45 +7,89 @@ module YARD::CodeObjects
|
|
7
7
|
|
8
8
|
attr_reader :constants, :keyword, :source, :value, :literal_value
|
9
9
|
attr_accessor :steps
|
10
|
-
|
10
|
+
|
11
|
+
# This defines an escape pattern within a string or regex:
|
12
|
+
# /^the first #{CONSTANT} step$/
|
13
|
+
#
|
14
|
+
# This is used below in the value to process it if there happen to be
|
15
|
+
# constants defined here.
|
16
|
+
#
|
17
|
+
# @note this does not handle the result of method calls
|
18
|
+
# @note this does not handle multiple constants within the same escaped area
|
19
|
+
#
|
11
20
|
ESCAPE_PATTERN = /#\{\s*(\w+)\s*\}/ unless defined?(ESCAPE_PATTERN)
|
12
21
|
|
22
|
+
#
|
23
|
+
# When requesting a step tranformer object value, process it, it it hasn't
|
24
|
+
# alredy been processed, replacing any constants that may be lurking within
|
25
|
+
# the value.
|
26
|
+
#
|
27
|
+
# Processing it means looking for any escaped characters that happen to be
|
28
|
+
# CONSTANTS that could be matched and then replaced. This is done recursively
|
29
|
+
# as CONSTANTS can be defined with more CONSTANTS.
|
30
|
+
#
|
31
|
+
def value
|
32
|
+
unless @processed
|
33
|
+
@processed = true
|
34
|
+
until (nested = constants_from_value).empty?
|
35
|
+
nested.each {|n| @value.gsub!(value_regex(n),find_value_for_constant(n)) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@value
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Set the literal value and the value of the step definition.
|
44
|
+
#
|
45
|
+
# The literal value is as it appears in the step definition file with any
|
46
|
+
# constants. The value, when retrieved will attempt to replace those
|
47
|
+
# constants with their regex or string equivalents to hopefully match more
|
48
|
+
# steps and step definitions.
|
49
|
+
#
|
50
|
+
#
|
13
51
|
def value=(value)
|
14
52
|
@literal_value = format_source(value)
|
15
53
|
@value = format_source(value)
|
16
54
|
|
17
|
-
until (nested = constants_from_value).empty?
|
18
|
-
nested.each {|n| @value.gsub!(value_regex(n),find_value_for_constant(n)) }
|
19
|
-
end
|
20
|
-
|
21
55
|
@steps = []
|
56
|
+
value
|
22
57
|
end
|
23
58
|
|
59
|
+
# Generate a regex with the step transformers value
|
24
60
|
def regex
|
25
|
-
@regex ||= /#{strip_regex_from(
|
61
|
+
@regex ||= /#{strip_regex_from(value)}/
|
26
62
|
end
|
27
|
-
|
63
|
+
|
64
|
+
# Look through the specified data for the escape pattern and return an array
|
65
|
+
# of those constants found. This defaults to the @value within step transformer
|
66
|
+
# as it is used internally, however, it can be called externally if it's
|
67
|
+
# needed somewhere.
|
28
68
|
def constants_from_value(data=@value)
|
29
69
|
data.scan(ESCAPE_PATTERN).flatten.collect { |value| value.strip }
|
30
70
|
end
|
31
71
|
|
32
72
|
protected
|
33
73
|
|
74
|
+
#
|
75
|
+
# Looking through all the constants in the registry and returning the value
|
76
|
+
# with the regex items replaced from the constnat if present
|
77
|
+
#
|
34
78
|
def find_value_for_constant(name)
|
35
79
|
constant = YARD::Registry.all(:constant).find{|c| c.name == name.to_sym }
|
36
80
|
log.warn "StepTransformer#find_value_for_constant : Could not find the CONSTANT [#{name}] using the string value." unless constant
|
37
81
|
constant ? strip_regex_from(constant.value) : name
|
38
82
|
end
|
39
83
|
|
84
|
+
# Return a regex of the value
|
40
85
|
def value_regex(value)
|
41
86
|
/#\{\s*#{value}\s*\}/
|
42
87
|
end
|
43
88
|
|
89
|
+
# Step the regex starting / and ending / from the value
|
44
90
|
def strip_regex_from(value)
|
45
91
|
value.gsub(/^\/|\/$/,'')
|
46
92
|
end
|
47
|
-
|
48
|
-
|
49
93
|
end
|
50
94
|
|
51
95
|
end
|
@@ -5,87 +5,125 @@ module YARD
|
|
5
5
|
|
6
6
|
handles CodeObjects::Cucumber::Feature
|
7
7
|
|
8
|
-
@@step_definitions = nil
|
9
|
-
@@step_transforms = nil
|
10
|
-
|
11
8
|
def process
|
9
|
+
#
|
10
|
+
# Features have already been created when they were parsed. So there
|
11
|
+
# is no need to process the feature furhter. 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
|
12
41
|
|
13
|
-
|
14
|
-
@@
|
15
|
-
@@step_transforms = cache(:steptransform) unless @@step_transforms
|
42
|
+
@@step_definitions = nil
|
43
|
+
@@step_transforms = nil
|
16
44
|
|
17
|
-
|
18
|
-
#
|
19
|
-
|
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
|
20
49
|
|
21
|
-
statement
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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)
|
27
63
|
end
|
28
|
-
else
|
29
|
-
process_scenario(scenario)
|
30
64
|
end
|
31
|
-
end
|
32
65
|
|
33
66
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
rescue YARD::Handlers::NamespaceMissingError
|
39
|
-
rescue Exception => exception
|
40
|
-
log.error "Skipping feature because an error has occurred."
|
41
|
-
log.debug "\n#{exception}\n#{exception.backtrace.join("\n")}\n"
|
42
|
-
end
|
67
|
+
else
|
68
|
+
log.warn "Empty feature file. A feature failed to process correctly or contains no feature"
|
69
|
+
end
|
43
70
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def cache(type)
|
49
|
-
YARD::Registry.all(type).inject({}) do |hash,item|
|
50
|
-
hash[item.regex] = item if item.regex
|
51
|
-
hash
|
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"
|
52
75
|
end
|
53
|
-
end
|
54
|
-
|
55
76
|
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
59
87
|
|
60
|
-
|
61
|
-
|
88
|
+
# process a scenario
|
89
|
+
def process_scenario(scenario)
|
90
|
+
scenario.steps.each {|step| process_step(step) }
|
91
|
+
end
|
62
92
|
|
63
|
-
|
93
|
+
# process a step
|
94
|
+
def process_step(step)
|
95
|
+
match_step_to_step_definition_and_transforms(step)
|
96
|
+
end
|
64
97
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
stepdef_matches
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
76
114
|
end
|
77
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
|
+
|
78
121
|
end
|
79
|
-
|
80
|
-
# Step has been matched to step definition and step transforms
|
81
|
-
# TODO: If the step were to match again then we would be able to display ambigous step definitions
|
82
|
-
break
|
83
|
-
|
122
|
+
|
84
123
|
end
|
85
124
|
|
86
125
|
end
|
87
126
|
|
88
|
-
|
89
127
|
end
|
90
128
|
end
|
91
129
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class YARD::Handlers::Ruby::Legacy::StepDefinitionHandler < YARD::Handlers::Ruby::Legacy::Base
|
2
|
-
#TODO: This needs to become language independent.
|
3
2
|
STEP_DEFINITION_MATCH = /^((When|Given|And|Then)\s*(\/.+\/)\s+do(?:\s*\|.+\|)?\s*)$/ unless defined?(STEP_DEFINITION_MATCH)
|
4
3
|
handles STEP_DEFINITION_MATCH
|
5
4
|
|
@@ -1,6 +1,42 @@
|
|
1
|
-
|
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
|
+
#
|
2
20
|
class YARD::Handlers::Ruby::StepDefinitionHandler < YARD::Handlers::Ruby::Base
|
3
|
-
|
21
|
+
|
22
|
+
#
|
23
|
+
# By default the english gherkin language will be parsed, however, if the
|
24
|
+
# YARD configuration file `~./yard/config` defines different step definition
|
25
|
+
# handlers those are used.
|
26
|
+
#
|
27
|
+
#
|
28
|
+
if YARD::Config.options["yard-cucumber"] and
|
29
|
+
YARD::Config.options["yard-cucumber"]["language"] and
|
30
|
+
YARD::Config.options["yard-cucumber"]["language"]["step_definitions"]
|
31
|
+
|
32
|
+
YARD::Config.options["yard-cucumber"]["language"]["step_definitions"].each do |step_word|
|
33
|
+
handles method_call(step_word.to_sym)
|
34
|
+
end
|
35
|
+
|
36
|
+
else
|
37
|
+
handles method_call(:When),method_call(:Given),method_call(:And),method_call(:Then)
|
38
|
+
end
|
39
|
+
|
4
40
|
|
5
41
|
@@unique_name = 0
|
6
42
|
|
@@ -1,7 +1,18 @@
|
|
1
1
|
module YARD::Parser::Cucumber
|
2
2
|
|
3
3
|
class FeatureParser < YARD::Parser::Base
|
4
|
-
|
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
|
+
#
|
5
16
|
def initialize(source, file = '(stdin)')
|
6
17
|
|
7
18
|
@builder = Cucumber::Parser::CityBuilder.new(file)
|
@@ -15,6 +26,13 @@ module YARD::Parser::Cucumber
|
|
15
26
|
@feature = nil
|
16
27
|
end
|
17
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
|
18
36
|
def parse
|
19
37
|
begin
|
20
38
|
@parser.parse(@source, @file, 0)
|
@@ -29,18 +47,24 @@ module YARD::Parser::Cucumber
|
|
29
47
|
self
|
30
48
|
end
|
31
49
|
|
50
|
+
#
|
51
|
+
# This is not used as all the work is done in the parse method
|
52
|
+
#
|
32
53
|
def tokenize
|
33
54
|
|
34
55
|
end
|
35
56
|
|
36
|
-
|
57
|
+
#
|
58
|
+
# The only enumeration that can be done here is returning the feature itself
|
59
|
+
#
|
37
60
|
def enumerator
|
38
61
|
[@feature]
|
39
62
|
end
|
40
63
|
|
41
64
|
end
|
42
65
|
|
43
|
-
|
66
|
+
#
|
67
|
+
# Register all feature files (.feature) to be processed with the above FeatureParser
|
44
68
|
YARD::Parser::SourceParser.register_parser_type :feature, FeatureParser, 'feature'
|
45
69
|
|
46
70
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: yard-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 2.0
|
5
|
+
version: 2.1.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Franklin Webber
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0.
|
46
|
+
version: 0.7.0
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id003
|
49
49
|
description: " \n YARD-Cucumber is a YARD extension that processes Cucumber Features, Scenarios, Steps,\n Step Definitions, Transforms, and Tags and provides a documentation interface that allows you\n easily view and investigate the test suite. This tools hopes to bridge the gap of being able\n to provide your feature descriptions to your Product Owners and Stakeholders. "
|
@@ -66,10 +66,12 @@ files:
|
|
66
66
|
- example/child_feature/child.feature
|
67
67
|
- example/child_feature/grandchild_feature/grandchild.feature
|
68
68
|
- example/empty.feature
|
69
|
+
- example/french.feature
|
69
70
|
- example/scenario.feature
|
70
71
|
- example/scenario_outline.feature
|
71
72
|
- example/step_definitions/example.step.rb
|
72
73
|
- example/step_definitions/first.step.rb
|
74
|
+
- example/step_definitions/french_steps.rb
|
73
75
|
- example/step_definitions/support/env.rb
|
74
76
|
- example/step_definitions/support/env_support.rb
|
75
77
|
- example/step_definitions/support/support.rb
|
@@ -93,17 +95,13 @@ files:
|
|
93
95
|
- lib/templates/default/featuredirectory/html/setup.rb
|
94
96
|
- lib/templates/default/featuretags/html/namespace.erb
|
95
97
|
- lib/templates/default/featuretags/html/setup.rb
|
96
|
-
- lib/templates/default/fulldoc/html/css/
|
97
|
-
- lib/templates/default/fulldoc/html/full_list.erb
|
98
|
+
- lib/templates/default/fulldoc/html/css/cucumber.css
|
98
99
|
- lib/templates/default/fulldoc/html/full_list_features.erb
|
99
100
|
- lib/templates/default/fulldoc/html/full_list_stepdefinitions.erb
|
100
101
|
- lib/templates/default/fulldoc/html/full_list_steps.erb
|
101
102
|
- lib/templates/default/fulldoc/html/full_list_tags.erb
|
102
|
-
- lib/templates/default/fulldoc/html/index.erb
|
103
103
|
- lib/templates/default/fulldoc/html/js/cucumber.js
|
104
104
|
- lib/templates/default/fulldoc/html/setup.rb
|
105
|
-
- lib/templates/default/layout/html/headers.erb
|
106
|
-
- lib/templates/default/layout/html/search.erb
|
107
105
|
- lib/templates/default/layout/html/setup.rb
|
108
106
|
- lib/templates/default/requirements/html/alpha_table.erb
|
109
107
|
- lib/templates/default/requirements/html/requirements.erb
|
@@ -134,7 +132,6 @@ files:
|
|
134
132
|
- lib/yard/handlers/step_definition_handler.rb
|
135
133
|
- lib/yard/handlers/step_transform_handler.rb
|
136
134
|
- lib/yard/parser/cucumber/feature.rb
|
137
|
-
- lib/yard/parser/source_parser.rb
|
138
135
|
- lib/yard/server/adapter.rb
|
139
136
|
- lib/yard/server/commands/list_command.rb
|
140
137
|
- lib/yard/server/router.rb
|
@@ -144,7 +141,7 @@ homepage: http://github.com/burtlo/yard-cucumber
|
|
144
141
|
licenses: []
|
145
142
|
|
146
143
|
post_install_message: "\n\
|
147
|
-
(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)\n\n Thank you for installing yard-cucumber 2.0
|
144
|
+
(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)\n\n Thank you for installing yard-cucumber 2.1.0 / 2011-05-22.\n \n Changes:\n \n * YARD 0.7.0 compatibility (removed some monkey-patching)\n * Add more menus (Steps and Step Definitions)\n * Define step definitions in your language Internalization (Ruby 1.9.2)\n \n\n\
|
148
145
|
(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)\n\n"
|
149
146
|
rdoc_options:
|
150
147
|
- --charset=UTF-8
|
@@ -1,36 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
-
<html>
|
4
|
-
<head>
|
5
|
-
<meta name="Content-Type" content="text/html; charset=<%= charset %>" />
|
6
|
-
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" charset="utf-8" />
|
7
|
-
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
|
8
|
-
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
9
|
-
<script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
|
10
|
-
<base id="base_target" target="_parent" />
|
11
|
-
</head>
|
12
|
-
<body>
|
13
|
-
<script type="text/javascript" charset="utf-8">
|
14
|
-
if (window.top.frames.main) {
|
15
|
-
document.getElementById('base_target').target = 'main';
|
16
|
-
document.body.className = 'frames';
|
17
|
-
}
|
18
|
-
</script>
|
19
|
-
<div id="content">
|
20
|
-
<h1 id="full_list_header"><%= @list_title %></h1>
|
21
|
-
<div id="nav">
|
22
|
-
<a target="_self" href="feature_list.html">Features</a> |
|
23
|
-
<a target="_self" href="tag_list.html">Tags</a> |
|
24
|
-
<a target="_self" href="class_list.html">Classes</a> |
|
25
|
-
<a target="_self" href="method_list.html">Methods</a> |
|
26
|
-
<a target="_self" href="file_list.html">Files</a>
|
27
|
-
</div>
|
28
|
-
<div id="search">Search: <input type="text" /></div>
|
29
|
-
|
30
|
-
<ul id="full_list" class="<%= @list_class || @list_type %>">
|
31
|
-
<%= erb "full_list_#{@list_type}" %>
|
32
|
-
</ul>
|
33
|
-
</div>
|
34
|
-
</body>
|
35
|
-
</html>
|
36
|
-
|
@@ -1,24 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
-
<head>
|
5
|
-
<%= T('layout/headers') %>
|
6
|
-
</head>
|
7
|
-
<body>
|
8
|
-
<script type="text/javascript" charset="utf-8">
|
9
|
-
if (window.top.frames.main) document.body.className = 'frames';
|
10
|
-
</script>
|
11
|
-
|
12
|
-
<div id="header">
|
13
|
-
<%= T('layout/breadcrumb') %>
|
14
|
-
<%= T('layout/search') %>
|
15
|
-
<div class="clear"></div>
|
16
|
-
</div>
|
17
|
-
|
18
|
-
<iframe id="search_frame"></iframe>
|
19
|
-
|
20
|
-
<div id="content"><%= yieldall %></div>
|
21
|
-
|
22
|
-
<%= T('layout/footer') %>
|
23
|
-
</body>
|
24
|
-
</html>
|
@@ -1,14 +0,0 @@
|
|
1
|
-
<meta http-equiv="Content-Type" content="text/html; charset=<%= charset %>" />
|
2
|
-
<title><%= @page_title %></title>
|
3
|
-
<link rel="stylesheet" href="<%= url_for("css/style.css") %>" type="text/css" media="screen" charset="utf-8" />
|
4
|
-
<link rel="stylesheet" href="<%= url_for("css/common.css") %>" type="text/css" media="screen" charset="utf-8" />
|
5
|
-
<% if @extra_css %>
|
6
|
-
<link rel="stylesheet" href="<%= url_for @extra_css %>" type="text/css" media="screen" charset="utf-8" />
|
7
|
-
<% end %>
|
8
|
-
<script type="text/javascript" charset="utf-8">
|
9
|
-
relpath = '<%= url_for('') %>';
|
10
|
-
if (relpath != '') relpath += '/';
|
11
|
-
</script>
|
12
|
-
<% javascript_files.each do |js_file| %>
|
13
|
-
<script type="text/javascript" charset="utf-8" src="<%= url_for(js_file) %>"></script>
|
14
|
-
<% end %>
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module YARD::Parser
|
2
|
-
|
3
|
-
class SourceParser
|
4
|
-
class << self
|
5
|
-
|
6
|
-
#
|
7
|
-
# Following the conventions of ordering as Cucumber performs it
|
8
|
-
#
|
9
|
-
# environment files - 'directory/support/env.rb,env_*.rb'
|
10
|
-
# support files - 'directory/support/*.rb' (but not env prefixed)
|
11
|
-
# directory files - 'directory/*.rb'
|
12
|
-
#
|
13
|
-
# feature files - 'directory/*.feature'
|
14
|
-
#
|
15
|
-
def order_by_cucumber_standards(*files)
|
16
|
-
|
17
|
-
non_feature_files = files.reject {|x| x =~ /^.+\.feature$/}
|
18
|
-
feature_files = files.find_all {|x| x =~ /^.+\.feature$/ }
|
19
|
-
|
20
|
-
support_files = non_feature_files.find_all {|file| file =~ /support\/.+\.rb$/ }
|
21
|
-
other_files = non_feature_files - support_files
|
22
|
-
|
23
|
-
environment_files = support_files.find_all {|file| file =~ /support\/env.*\.rb$/ }
|
24
|
-
environment_files.sort_by {|x| x.length if x }
|
25
|
-
|
26
|
-
support_files = support_files - environment_files
|
27
|
-
|
28
|
-
environment_files + support_files + other_files + feature_files
|
29
|
-
end
|
30
|
-
|
31
|
-
#
|
32
|
-
# Overriding the parse_in_order method was necessary so that step definitions
|
33
|
-
# match to steps utilizing the load ordering that is used by Cucumber.
|
34
|
-
#
|
35
|
-
def parse_in_order(*files)
|
36
|
-
|
37
|
-
files = order_by_cucumber_standards(*files)
|
38
|
-
|
39
|
-
while file = files.shift
|
40
|
-
begin
|
41
|
-
if file.is_a?(Array) && file.last.is_a?(Continuation)
|
42
|
-
log.debug("Re-processing #{file.first}")
|
43
|
-
file.last.call
|
44
|
-
elsif file.is_a?(String)
|
45
|
-
log.debug("Processing #{file}...")
|
46
|
-
new(parser_type, true).parse(file)
|
47
|
-
end
|
48
|
-
rescue LoadOrderError => e
|
49
|
-
# Out of order file. Push the context to the end and we'll call it
|
50
|
-
files.push([file, e.message])
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|