cucumber-in-the-yard 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +3 -0
- data/Manifest +51 -0
- data/README.txt +55 -0
- data/Rakefile +28 -0
- data/cucumber-in-the-yard.gemspec +42 -0
- data/example/example.feature +13 -0
- data/example/example.step.rb +48 -0
- data/example/example.third.feature +30 -0
- data/example/second_example.feature +36 -0
- data/lib/city.rb +23 -0
- data/lib/cucumber/city_builder.rb +130 -0
- data/lib/yard/code_objects/cucumber_location_helper.rb +15 -0
- data/lib/yard/code_objects/feature.rb +24 -0
- data/lib/yard/code_objects/scenario.rb +25 -0
- data/lib/yard/code_objects/step.rb +25 -0
- data/lib/yard/code_objects/tags.rb +63 -0
- data/lib/yard/extensions.rb +38 -0
- data/lib/yard/handlers/base.rb +21 -0
- data/lib/yard/handlers/feature_handler.rb +41 -0
- data/lib/yard/parser/feature.rb +46 -0
- data/lib/yard/rake/city_task.rb +12 -0
- data/lib/yard/rb_extensions.rb +152 -0
- data/lib/yard/templates/default/feature/html/feature.erb +243 -0
- data/lib/yard/templates/default/feature/setup.rb +5 -0
- data/lib/yard/templates/default/fulldoc/html/css/common.css +182 -0
- data/lib/yard/templates/default/fulldoc/html/full_list.erb +34 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_features.erb +10 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_scenarios.erb +10 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_stepdefinitions.erb +11 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_steps.erb +13 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_tagusages.erb +10 -0
- data/lib/yard/templates/default/fulldoc/html/index.erb +24 -0
- data/lib/yard/templates/default/fulldoc/html/js/cucumber.js +13 -0
- data/lib/yard/templates/default/fulldoc/html/setup.rb +73 -0
- data/lib/yard/templates/default/layout/html/headers.erb +14 -0
- data/lib/yard/templates/default/layout/html/search.erb +8 -0
- data/lib/yard/templates/default/module/html/step_transforms.erb +23 -0
- data/lib/yard/templates/default/module/setup.rb +5 -0
- data/lib/yard/templates/default/scenario/html/scenario.erb +26 -0
- data/lib/yard/templates/default/scenario/setup.rb +5 -0
- data/lib/yard/templates/default/steptransformers/html/stepdefinition.erb +38 -0
- data/lib/yard/templates/default/steptransformers/setup.rb +5 -0
- data/lib/yard/templates/default/tagusage/html/tagusage.erb +65 -0
- data/lib/yard/templates/default/tagusage/setup.rb +5 -0
- data/spec/city/feature_parser_spec_examples.rb +153 -0
- data/spec/city/gherkin_loader_spec.rb +39 -0
- data/spec/city/test.feature +36 -0
- data/spec/city/yard_handlers_cucumber_spec.rb +24 -0
- data/spec/city/yard_namespace_object_spec.rb +8 -0
- data/spec/city/yard_parser_cucumber_spec.rb +215 -0
- data/spec/city/yard_rb_extensions_spec.rb +128 -0
- data/spec/spec_helper.rb +5 -0
- data.tar.gz.sig +0 -0
- metadata +201 -0
- metadata.gz.sig +0 -0
data/History.txt
ADDED
data/Manifest
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
History.txt
|
2
|
+
README.txt
|
3
|
+
Rakefile
|
4
|
+
example/example.feature
|
5
|
+
example/example.step.rb
|
6
|
+
example/example.third.feature
|
7
|
+
example/second_example.feature
|
8
|
+
lib/city.rb
|
9
|
+
lib/cucumber/city_builder.rb
|
10
|
+
lib/yard/code_objects/cucumber_location_helper.rb
|
11
|
+
lib/yard/code_objects/feature.rb
|
12
|
+
lib/yard/code_objects/scenario.rb
|
13
|
+
lib/yard/code_objects/step.rb
|
14
|
+
lib/yard/code_objects/tags.rb
|
15
|
+
lib/yard/extensions.rb
|
16
|
+
lib/yard/handlers/base.rb
|
17
|
+
lib/yard/handlers/feature_handler.rb
|
18
|
+
lib/yard/parser/feature.rb
|
19
|
+
lib/yard/rb_extensions.rb
|
20
|
+
lib/yard/rake/city_task.rb
|
21
|
+
lib/yard/templates/default/feature/html/feature.erb
|
22
|
+
lib/yard/templates/default/feature/setup.rb
|
23
|
+
lib/yard/templates/default/fulldoc/html/css/common.css
|
24
|
+
lib/yard/templates/default/fulldoc/html/full_list.erb
|
25
|
+
lib/yard/templates/default/fulldoc/html/full_list_features.erb
|
26
|
+
lib/yard/templates/default/fulldoc/html/full_list_scenarios.erb
|
27
|
+
lib/yard/templates/default/fulldoc/html/full_list_stepdefinitions.erb
|
28
|
+
lib/yard/templates/default/fulldoc/html/full_list_steps.erb
|
29
|
+
lib/yard/templates/default/fulldoc/html/full_list_tagusages.erb
|
30
|
+
lib/yard/templates/default/fulldoc/html/index.erb
|
31
|
+
lib/yard/templates/default/fulldoc/html/js/cucumber.js
|
32
|
+
lib/yard/templates/default/fulldoc/html/setup.rb
|
33
|
+
lib/yard/templates/default/layout/html/headers.erb
|
34
|
+
lib/yard/templates/default/layout/html/search.erb
|
35
|
+
lib/yard/templates/default/module/html/step_transforms.erb
|
36
|
+
lib/yard/templates/default/module/setup.rb
|
37
|
+
lib/yard/templates/default/scenario/html/scenario.erb
|
38
|
+
lib/yard/templates/default/scenario/setup.rb
|
39
|
+
lib/yard/templates/default/steptransformers/html/stepdefinition.erb
|
40
|
+
lib/yard/templates/default/steptransformers/setup.rb
|
41
|
+
lib/yard/templates/default/tagusage/html/tagusage.erb
|
42
|
+
lib/yard/templates/default/tagusage/setup.rb
|
43
|
+
spec/city/feature_parser_spec_examples.rb
|
44
|
+
spec/city/gherkin_loader_spec.rb
|
45
|
+
spec/city/test.feature
|
46
|
+
spec/city/yard_handlers_cucumber_spec.rb
|
47
|
+
spec/city/yard_namespace_object_spec.rb
|
48
|
+
spec/city/yard_parser_cucumber_spec.rb
|
49
|
+
spec/city/yard_rb_extensions_spec.rb
|
50
|
+
spec/spec_helper.rb
|
51
|
+
Manifest
|
data/README.txt
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
= CITY Cucumber-In-The-YARD (CITY): A Requirements Documentation Tool
|
2
|
+
|
3
|
+
== DESCRIPTION:
|
4
|
+
|
5
|
+
There are two things that I enjoy: a test framework written in my own Domain Specific Language (DSL) that is easily understood by all those on a project and the ability for all participants to easily read, search, and view the tests.
|
6
|
+
|
7
|
+
Cucumber is an amazing tool that allowed me to define exercisable requirements. My biggest obstacle was bringing these requirements to my team, the product owner, and other stakeholders.
|
8
|
+
|
9
|
+
Initially I tried to expose more of the functionality by providing freshly authored requirements through email, attachments to JIRA tickets, or linked in wiki documents. None of these methods were very sustainable or successful. First, I was continually pushing out the documents to those interested. Second, the documents were displayed to the user in text without the syntax highlighting that was exceedingly helpful for quickly understanding the requirements.
|
10
|
+
|
11
|
+
I also found it hard to share the test framework that I had put together with another developer that joined the team. It was difficult to direct them around the features, tags, step definitions, and transforms. It was when I started to convey to them the conventions that I had established that I wished I had a tool that would allow me to provide documentation like one would find generated by a great tool like YARD.
|
12
|
+
|
13
|
+
So I set out to integrate Cucumber objects like features, backgrounds, scenarios, tags, steps, step definitions, and transforms into a YARD template. From my quick survey of the landscape I can see that the my needs are different than a lot of others that use Cucumber. The entire project that spawned this effort was solely to exercise the functionality of a different, large project and so there is a huge dependence on having the requirements documented. This is in contrast to other projects that are using this on a small scale to test the functionality of small software component. Though, ultimately, I realized that the functionality may provide a valuable tool for many as I feel it helps more solidly bridge the reporting of the documentation by putting a coat of paint on it.
|
14
|
+
|
15
|
+
|
16
|
+
== FEATURES/PROBLEMS:
|
17
|
+
|
18
|
+
**1. Searchable Features, Scenarios, Steps, and Tags**: Similar to how YARD provides the ability to search through classes and methods, CITY provides the ability to search through all of the requirements documentation quickly and easily through the browser. This makes it easy to provide reports for product owners and other stakeholders.
|
19
|
+
|
20
|
+
**2. Tags**: Tag view will show all features and scenarios that employ the tag.
|
21
|
+
|
22
|
+
**3. Steps map to Step Definitions**: Steps provide links to their step definitions so developers and maintainers of the requirements suite can quickly find their way around the project. As well, step definitions report all their implemented step definitions to provide a quick way of understanding the impact of augmenting a step definition as well as providing examples.
|
23
|
+
|
24
|
+
== SYNOPSIS:
|
25
|
+
|
26
|
+
== REQUIREMENTS:
|
27
|
+
|
28
|
+
== INSTALL:
|
29
|
+
|
30
|
+
== DEVELOPERS:
|
31
|
+
|
32
|
+
== LICENSE:
|
33
|
+
|
34
|
+
(The MIT License)
|
35
|
+
|
36
|
+
Copyright (c) 2010 FIX
|
37
|
+
|
38
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
39
|
+
a copy of this software and associated documentation files (the
|
40
|
+
'Software'), to deal in the Software without restriction, including
|
41
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
42
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
43
|
+
permit persons to whom the Software is furnished to do so, subject to
|
44
|
+
the following conditions:
|
45
|
+
|
46
|
+
The above copyright notice and this permission notice shall be
|
47
|
+
included in all copies or substantial portions of the Software.
|
48
|
+
|
49
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
50
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
51
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
52
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
53
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
54
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
55
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'echoe'
|
3
|
+
require 'yard'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
task :default => :yard
|
7
|
+
|
8
|
+
task :gendoc do
|
9
|
+
`yardoc -e lib/city.rb -p lib/yard/templates 'example/**/*.rb' 'example/**/*.feature' --quiet --verbose`
|
10
|
+
end
|
11
|
+
|
12
|
+
yard_task = YARD::Rake::YardocTask.new
|
13
|
+
yard_task.files = FileList['example/**/*.feature','example/**/*.rb']
|
14
|
+
yard_task.options = %w{ -e lib/city.rb -p lib/yard/templates 'example/**/*.rb' 'examples/**/*.feature' --debug }
|
15
|
+
|
16
|
+
|
17
|
+
Echoe.new('cucumber-in-the-yard', '1.0') do |g|
|
18
|
+
g.author = "Frank;lin Webber"
|
19
|
+
g.email = "franklin.webber@gmail.com"
|
20
|
+
g.url = "http://github.com/burtlo/Cucumber-In-The-Yard"
|
21
|
+
g.description = %{
|
22
|
+
Cucumber-In-The-Yard is a YARD extension that processes Cucumber Features, Scenarios, Steps,
|
23
|
+
Step Definitions, Transforms, and Tags and provides a documentation interface that allows you
|
24
|
+
easily view and investigate the test suite. This tools hopes to bridge the gap of being able
|
25
|
+
to provide your feature descriptions to your Product Owners and Stakeholders. }
|
26
|
+
g.ignore_pattern = FileList["{doc,autotest}/**/*"].to_a
|
27
|
+
g.runtime_dependencies = [ "cucumber >=0.7.5", "yard >=0.6.1" ]
|
28
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{cucumber-in-the-yard}
|
5
|
+
s.version = "1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Frank;lin Webber"]
|
9
|
+
s.cert_chain = ["/Users/frank/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2010-10-10}
|
11
|
+
s.description = %q{
|
12
|
+
Cucumber-In-The-Yard is a YARD extension that processes Cucumber Features, Scenarios, Steps,
|
13
|
+
Step Definitions, Transforms, and Tags and provides a documentation interface that allows you
|
14
|
+
easily view and investigate the test suite. This tools hopes to bridge the gap of being able
|
15
|
+
to provide your feature descriptions to your Product Owners and Stakeholders. }
|
16
|
+
s.email = %q{franklin.webber@gmail.com}
|
17
|
+
s.extra_rdoc_files = ["README.txt", "lib/city.rb", "lib/cucumber/city_builder.rb", "lib/yard/code_objects/cucumber_location_helper.rb", "lib/yard/code_objects/feature.rb", "lib/yard/code_objects/scenario.rb", "lib/yard/code_objects/step.rb", "lib/yard/code_objects/tags.rb", "lib/yard/extensions.rb", "lib/yard/handlers/base.rb", "lib/yard/handlers/feature_handler.rb", "lib/yard/parser/feature.rb", "lib/yard/rb_extensions.rb", "lib/yard/rake/city_task.rb", "lib/yard/templates/default/feature/html/feature.erb", "lib/yard/templates/default/feature/setup.rb", "lib/yard/templates/default/fulldoc/html/css/common.css", "lib/yard/templates/default/fulldoc/html/full_list.erb", "lib/yard/templates/default/fulldoc/html/full_list_features.erb", "lib/yard/templates/default/fulldoc/html/full_list_scenarios.erb", "lib/yard/templates/default/fulldoc/html/full_list_stepdefinitions.erb", "lib/yard/templates/default/fulldoc/html/full_list_steps.erb", "lib/yard/templates/default/fulldoc/html/full_list_tagusages.erb", "lib/yard/templates/default/fulldoc/html/index.erb", "lib/yard/templates/default/fulldoc/html/js/cucumber.js", "lib/yard/templates/default/fulldoc/html/setup.rb", "lib/yard/templates/default/layout/html/headers.erb", "lib/yard/templates/default/layout/html/search.erb", "lib/yard/templates/default/module/html/step_transforms.erb", "lib/yard/templates/default/module/setup.rb", "lib/yard/templates/default/scenario/html/scenario.erb", "lib/yard/templates/default/scenario/setup.rb", "lib/yard/templates/default/steptransformers/html/stepdefinition.erb", "lib/yard/templates/default/steptransformers/setup.rb", "lib/yard/templates/default/tagusage/html/tagusage.erb", "lib/yard/templates/default/tagusage/setup.rb"]
|
18
|
+
s.files = ["History.txt", "README.txt", "Rakefile", "example/example.feature", "example/example.step.rb", "example/example.third.feature", "example/second_example.feature", "lib/city.rb", "lib/cucumber/city_builder.rb", "lib/yard/code_objects/cucumber_location_helper.rb", "lib/yard/code_objects/feature.rb", "lib/yard/code_objects/scenario.rb", "lib/yard/code_objects/step.rb", "lib/yard/code_objects/tags.rb", "lib/yard/extensions.rb", "lib/yard/handlers/base.rb", "lib/yard/handlers/feature_handler.rb", "lib/yard/parser/feature.rb", "lib/yard/rb_extensions.rb", "lib/yard/rake/city_task.rb", "lib/yard/templates/default/feature/html/feature.erb", "lib/yard/templates/default/feature/setup.rb", "lib/yard/templates/default/fulldoc/html/css/common.css", "lib/yard/templates/default/fulldoc/html/full_list.erb", "lib/yard/templates/default/fulldoc/html/full_list_features.erb", "lib/yard/templates/default/fulldoc/html/full_list_scenarios.erb", "lib/yard/templates/default/fulldoc/html/full_list_stepdefinitions.erb", "lib/yard/templates/default/fulldoc/html/full_list_steps.erb", "lib/yard/templates/default/fulldoc/html/full_list_tagusages.erb", "lib/yard/templates/default/fulldoc/html/index.erb", "lib/yard/templates/default/fulldoc/html/js/cucumber.js", "lib/yard/templates/default/fulldoc/html/setup.rb", "lib/yard/templates/default/layout/html/headers.erb", "lib/yard/templates/default/layout/html/search.erb", "lib/yard/templates/default/module/html/step_transforms.erb", "lib/yard/templates/default/module/setup.rb", "lib/yard/templates/default/scenario/html/scenario.erb", "lib/yard/templates/default/scenario/setup.rb", "lib/yard/templates/default/steptransformers/html/stepdefinition.erb", "lib/yard/templates/default/steptransformers/setup.rb", "lib/yard/templates/default/tagusage/html/tagusage.erb", "lib/yard/templates/default/tagusage/setup.rb", "spec/city/feature_parser_spec_examples.rb", "spec/city/gherkin_loader_spec.rb", "spec/city/test.feature", "spec/city/yard_handlers_cucumber_spec.rb", "spec/city/yard_namespace_object_spec.rb", "spec/city/yard_parser_cucumber_spec.rb", "spec/city/yard_rb_extensions_spec.rb", "spec/spec_helper.rb", "Manifest", "cucumber-in-the-yard.gemspec"]
|
19
|
+
s.homepage = %q{http://github.com/burtlo/Cucumber-In-The-Yard}
|
20
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Cucumber-in-the-yard", "--main", "README.txt"]
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
s.rubyforge_project = %q{cucumber-in-the-yard}
|
23
|
+
s.rubygems_version = %q{1.3.6}
|
24
|
+
s.signing_key = %q{/Users/frank/gem-private_key.pem}
|
25
|
+
s.summary = %q{Cucumber-In-The-Yard is a YARD extension that processes Cucumber Features, Scenarios, Steps, Step Definitions, Transforms, and Tags and provides a documentation interface that allows you easily view and investigate the test suite. This tools hopes to bridge the gap of being able to provide your feature descriptions to your Product Owners and Stakeholders.}
|
26
|
+
|
27
|
+
if s.respond_to? :specification_version then
|
28
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
29
|
+
s.specification_version = 3
|
30
|
+
|
31
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
32
|
+
s.add_runtime_dependency(%q<cucumber>, [">= 0.7.5"])
|
33
|
+
s.add_runtime_dependency(%q<yard>, [">= 0.6.1"])
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<cucumber>, [">= 0.7.5"])
|
36
|
+
s.add_dependency(%q<yard>, [">= 0.6.1"])
|
37
|
+
end
|
38
|
+
else
|
39
|
+
s.add_dependency(%q<cucumber>, [">= 0.7.5"])
|
40
|
+
s.add_dependency(%q<yard>, [">= 0.6.1"])
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
@customer
|
2
|
+
Feature: Customer Login Feature
|
3
|
+
As a customer of the product I am able to login as myself
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given this undefined step definition
|
7
|
+
|
8
|
+
@bvt
|
9
|
+
Scenario: Customer with valid login is able to login
|
10
|
+
Given that a customer is a valid customer
|
11
|
+
When a customer logs in as username 'frank' with password 'default'
|
12
|
+
Then I expect them to have logged in successfully
|
13
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
CUSTOMER = /(?:(?:an?|the) customer|#{TEDDY_BEAR})/
|
4
|
+
|
5
|
+
TEDDY_BEAR = /teddy bear/
|
6
|
+
|
7
|
+
Transform /^an? customer$/ do |customer|
|
8
|
+
"a transformed customer"
|
9
|
+
end
|
10
|
+
|
11
|
+
Transform /^the customer$/ do |customer|
|
12
|
+
"the transformed customer"
|
13
|
+
end
|
14
|
+
|
15
|
+
Given /^that (#{CUSTOMER}) is a valid customer$/ do |customer|
|
16
|
+
pending "Customer #{customer} validation"
|
17
|
+
end
|
18
|
+
|
19
|
+
When /^a customer logs in as username '([^']+)' with password '([^']+)'$/ do |username,password|
|
20
|
+
pending "Customer logs in with #{username} and #{password}"
|
21
|
+
end
|
22
|
+
|
23
|
+
Then /^I expect them to have logged in successfully $/ do
|
24
|
+
pending "Validation that the customer has logged in successfully"
|
25
|
+
end
|
26
|
+
|
27
|
+
When /^the customer logs out$/ do
|
28
|
+
pending
|
29
|
+
end
|
30
|
+
|
31
|
+
Then /^I expect the customer to be shown the logout page$/ do
|
32
|
+
pending
|
33
|
+
end
|
34
|
+
|
35
|
+
And /^this third defined step definition$/ do
|
36
|
+
pending
|
37
|
+
end
|
38
|
+
|
39
|
+
And /^edits their the biography to state:$/ do |bio|
|
40
|
+
pending "text_field not present for bio #{bio} for this release"
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Some details about the helper method that might be picked up in the documentation.
|
45
|
+
#
|
46
|
+
def a_helper_method
|
47
|
+
puts "performs some operation"
|
48
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
@customer
|
2
|
+
Feature: Customer Account
|
3
|
+
As a customer of the product I am able to configure settings for my account
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given this third defined step definition
|
7
|
+
|
8
|
+
@bvt
|
9
|
+
Scenario: Customer is able to change their password
|
10
|
+
Given that a customer that is logged in to the system
|
11
|
+
When the customer changes their password to 'lions_tigers_and_bears'
|
12
|
+
Then I expect when they login again that it will use this new password
|
13
|
+
|
14
|
+
@wip
|
15
|
+
Scenario: Customer cannot change settings if they are not logged in
|
16
|
+
Given that a customer is a valid customer
|
17
|
+
When the customer visits the account settings page
|
18
|
+
Then I expect the customer to be presented with the login page
|
19
|
+
|
20
|
+
@wip
|
21
|
+
Scenario: Customer cannot change settings if they are not logged in
|
22
|
+
Given that a customer that is logged in to the system
|
23
|
+
When the customer visits the account settings page
|
24
|
+
And edits their the biography to state:
|
25
|
+
"""
|
26
|
+
I am an avid golfer, spelunker, and designer of clothing for stuffed
|
27
|
+
animals.
|
28
|
+
"""
|
29
|
+
Then I expect the customer to be presented with the login page
|
30
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
@customer
|
2
|
+
Feature: Customer Logout Feature
|
3
|
+
As a customer of the product I am able to logout
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given this undefined step definition
|
7
|
+
|
8
|
+
@bvt
|
9
|
+
Scenario: Customer that is logged in is able to log out
|
10
|
+
Given that a customer is a valid customer
|
11
|
+
And a customer logs in as username 'frank' with password 'default'
|
12
|
+
And I expect them to have logged in successfully
|
13
|
+
When the customer logs out
|
14
|
+
Then I expect the customer to be shown the logout page
|
15
|
+
|
16
|
+
Scenario: Customers with a complete profile are allowed to post
|
17
|
+
Given that a customer is a valid customer
|
18
|
+
And the customer has the following details:
|
19
|
+
| Name | Email | Age |
|
20
|
+
| Frank | f@email.com | 22 |
|
21
|
+
When a customer logs in as username 'frank' with password 'default'
|
22
|
+
And visits the customer update page
|
23
|
+
Then I expect the customer is able able to post to their profile
|
24
|
+
|
25
|
+
@product
|
26
|
+
Scenario Outline: Customers that bought a product are included in their product groups
|
27
|
+
Given that <Customer> is a valid customer
|
28
|
+
And that the product, named '<Product>', is a valid product
|
29
|
+
When the customer has purchased the product
|
30
|
+
Then I expect the customer to be a member of the '<Product>' group
|
31
|
+
|
32
|
+
Examples:
|
33
|
+
| Customer | Product |
|
34
|
+
| Customer A | Product A |
|
35
|
+
| Customer A | Product B |
|
36
|
+
| Customer A | Product C |
|
data/lib/city.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'gherkin/rubify'
|
2
|
+
require 'cucumber/parser/gherkin_builder'
|
3
|
+
require 'gherkin/parser/parser'
|
4
|
+
require 'gherkin/formatter/tag_count_formatter'
|
5
|
+
|
6
|
+
require File.dirname(__FILE__) + "/cucumber/city_builder.rb"
|
7
|
+
|
8
|
+
require 'yard'
|
9
|
+
|
10
|
+
require File.dirname(__FILE__) + "/yard/code_objects/cucumber_location_helper.rb"
|
11
|
+
require File.dirname(__FILE__) + "/yard/code_objects/feature.rb"
|
12
|
+
require File.dirname(__FILE__) + "/yard/code_objects/scenario.rb"
|
13
|
+
require File.dirname(__FILE__) + "/yard/code_objects/step.rb"
|
14
|
+
require File.dirname(__FILE__) + "/yard/code_objects/tags.rb"
|
15
|
+
|
16
|
+
require File.dirname(__FILE__) + "/yard/extensions.rb"
|
17
|
+
require File.dirname(__FILE__) + "/yard/rb_extensions.rb"
|
18
|
+
require File.dirname(__FILE__) + "/yard/parser/feature.rb"
|
19
|
+
require File.dirname(__FILE__) + "/yard/handlers/base.rb"
|
20
|
+
require File.dirname(__FILE__) + "/yard/handlers/feature_handler.rb"
|
21
|
+
|
22
|
+
require File.dirname(__FILE__) + "/yard/rake/city_task.rb"
|
23
|
+
|
@@ -0,0 +1,130 @@
|
|
1
|
+
|
2
|
+
module Cucumber
|
3
|
+
module Parser
|
4
|
+
class CityBuilder
|
5
|
+
include Gherkin::Rubify
|
6
|
+
|
7
|
+
def initialize(file)
|
8
|
+
@file = file
|
9
|
+
end
|
10
|
+
|
11
|
+
def ast
|
12
|
+
@feature || @multiline_arg
|
13
|
+
end
|
14
|
+
|
15
|
+
def feature(feature)
|
16
|
+
#log.debug "FEATURE: #{feature.name} #{feature.line} #{feature.keyword} #{feature.description}"
|
17
|
+
@feature = YARD::CodeObjects::Cucumber::Feature.new(:root,@file.gsub('.','_')) do |f|
|
18
|
+
f.comments = feature.comments.map{|comment| comment.value}.join("\n")
|
19
|
+
f.description = feature.description
|
20
|
+
f.add_file(@file,feature.line)
|
21
|
+
f.keyword = feature.keyword
|
22
|
+
f.value = feature.name
|
23
|
+
f.tags = []
|
24
|
+
|
25
|
+
feature.tags.map{|tag| tag.name}.each_with_index do |tag,index|
|
26
|
+
f.tags << YARD::CodeObjects::Cucumber::Tag.new(:root,"#{f.name}_feature_tag_#{index}") do |t|
|
27
|
+
t.value = tag
|
28
|
+
t.add_file(@file,feature.line)
|
29
|
+
t.feature = f
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def background(background)
|
38
|
+
#log.debug "BACKGROUND #{background.keyword} #{background.name} #{background.line} #{background.description}"
|
39
|
+
@background = YARD::CodeObjects::Cucumber::Scenario.new(:root,"#{@feature.name}_background") do |b|
|
40
|
+
b.comments = background.comments.map{|comment| comment.value}.join("\n")
|
41
|
+
b.description = background.description
|
42
|
+
b.keyword = background.keyword
|
43
|
+
b.value = background.name
|
44
|
+
b.add_file(@file,background.line)
|
45
|
+
end
|
46
|
+
|
47
|
+
@feature.background = @background
|
48
|
+
@background.feature = @feature
|
49
|
+
@step_container = @background
|
50
|
+
end
|
51
|
+
|
52
|
+
def scenario(statement)
|
53
|
+
#log.debug "SCENARIO"
|
54
|
+
scenario = YARD::CodeObjects::Cucumber::Scenario.new(:root,"#{@feature.name}_scenario_#{@feature.scenarios.length + 1}") do |s|
|
55
|
+
s.comments = statement.comments.map{|comment| comment.value}.join("\n")
|
56
|
+
s.description = statement.description
|
57
|
+
s.add_file(@file,statement.line)
|
58
|
+
s.keyword = statement.keyword
|
59
|
+
s.value = statement.name
|
60
|
+
|
61
|
+
statement.tags.map{|tag| tag.name}.each_with_index do |tag,index|
|
62
|
+
s.tags << YARD::CodeObjects::Cucumber::Tag.new(:root,"#{s.name}_tag_#{index}") do |t|
|
63
|
+
t.value = tag
|
64
|
+
t.add_file(@file,@feature.line)
|
65
|
+
t.scenario = s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
scenario.feature = @feature
|
71
|
+
@feature.scenarios << scenario
|
72
|
+
@step_container = scenario
|
73
|
+
end
|
74
|
+
|
75
|
+
def scenario_outline(statement)
|
76
|
+
scenario(statement)
|
77
|
+
end
|
78
|
+
|
79
|
+
def examples(examples)
|
80
|
+
#log.debug "EXAMPLES"
|
81
|
+
@step_container.examples << [
|
82
|
+
examples.keyword,
|
83
|
+
examples.name,
|
84
|
+
examples.line,
|
85
|
+
examples.comments.map{|comment| comment.value}.join("\n"),
|
86
|
+
matrix(examples.rows) ]
|
87
|
+
end
|
88
|
+
|
89
|
+
def step(step)
|
90
|
+
#log.debug "STEP #{step.multiline_arg}"
|
91
|
+
@table_owner = YARD::CodeObjects::Cucumber::Step.new(:root,"#{@feature.name}_#{step.line}") do |s|
|
92
|
+
s.keyword = step.keyword
|
93
|
+
s.value = step.name
|
94
|
+
s.add_file(@file,step.line)
|
95
|
+
end
|
96
|
+
|
97
|
+
multiline_arg = rubify(step.multiline_arg)
|
98
|
+
case(multiline_arg)
|
99
|
+
when Gherkin::Formatter::Model::PyString
|
100
|
+
@table_owner.text = multiline_arg.value
|
101
|
+
when Array
|
102
|
+
@table_owner.table = matrix(multiline_arg)
|
103
|
+
end
|
104
|
+
|
105
|
+
@table_owner.scenario = @step_container
|
106
|
+
@step_container.steps << @table_owner
|
107
|
+
end
|
108
|
+
|
109
|
+
def eof
|
110
|
+
end
|
111
|
+
|
112
|
+
def syntax_error(state, event, legal_events, line)
|
113
|
+
# raise "SYNTAX ERROR"
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def matrix(gherkin_table)
|
119
|
+
gherkin_table.map do |gherkin_row|
|
120
|
+
row = gherkin_row.cells
|
121
|
+
class << row
|
122
|
+
attr_accessor :line
|
123
|
+
end
|
124
|
+
row.line = gherkin_row.line
|
125
|
+
row
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module YARD::CodeObjects::Cucumber
|
4
|
+
|
5
|
+
class Feature < YARD::CodeObjects::Base
|
6
|
+
include CucumberLocationHelper
|
7
|
+
|
8
|
+
attr_accessor :background, :comments, :description, :keyword, :scenarios, :tags, :value
|
9
|
+
|
10
|
+
def initialize(namespace,name)
|
11
|
+
super(namespace,name.to_s.strip)
|
12
|
+
@comments = []
|
13
|
+
@scenarios = []
|
14
|
+
@tags = []
|
15
|
+
end
|
16
|
+
|
17
|
+
#TODO: this is likely a bad hack because I couldn't understand path
|
18
|
+
def filename
|
19
|
+
"#{self.name.to_s.gsub(/\//,'_')}.html"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module YARD::CodeObjects::Cucumber
|
4
|
+
|
5
|
+
class Scenario < YARD::CodeObjects::Base
|
6
|
+
include CucumberLocationHelper
|
7
|
+
|
8
|
+
attr_accessor :value, :description, :steps, :tags, :feature, :examples
|
9
|
+
|
10
|
+
def initialize(namespace,name)
|
11
|
+
super(namespace,name.to_s.strip)
|
12
|
+
@description = @value = @feature = nil
|
13
|
+
@steps = []
|
14
|
+
@tags = []
|
15
|
+
@examples = []
|
16
|
+
end
|
17
|
+
|
18
|
+
#TODO: this is likely a bad hack because I couldn't understand path
|
19
|
+
def filename
|
20
|
+
"#{self.name.to_s.gsub(/\//,'_')}.html"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module YARD::CodeObjects::Cucumber
|
4
|
+
|
5
|
+
class Step < YARD::CodeObjects::Base
|
6
|
+
include CucumberLocationHelper
|
7
|
+
|
8
|
+
attr_accessor :definition, :keyword, :scenario, :table, :text, :value
|
9
|
+
|
10
|
+
def initialize(namespace,name)
|
11
|
+
super(namespace,name.to_s.strip)
|
12
|
+
@definition = @description = @keyword = @table = @text = @value = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def has_table?
|
16
|
+
!@table.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_text?
|
20
|
+
!@text.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module YARD::CodeObjects::Cucumber
|
4
|
+
|
5
|
+
class Tag < YARD::CodeObjects::Base
|
6
|
+
include CucumberLocationHelper
|
7
|
+
|
8
|
+
attr_accessor :value, :feature, :scenario
|
9
|
+
|
10
|
+
def filename
|
11
|
+
"#{self.name.to_s.gsub(/\//,'_')}.html"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
class TagUsage < YARD::CodeObjects::Base
|
18
|
+
|
19
|
+
attr_reader :value
|
20
|
+
|
21
|
+
attr_accessor :tags
|
22
|
+
|
23
|
+
def filename
|
24
|
+
"#{self.name}.html"
|
25
|
+
end
|
26
|
+
|
27
|
+
def push(tag)
|
28
|
+
@tags = [] unless @tags
|
29
|
+
@tags << tag
|
30
|
+
|
31
|
+
if tag.scenario
|
32
|
+
@scenario_count = 0 unless @scenario_count
|
33
|
+
@scenario_count += 1
|
34
|
+
else
|
35
|
+
@feature_count = 0 unless @feature_count
|
36
|
+
@indirect_scenario_count = 0 unless @indirect_scenario_count
|
37
|
+
@feature_count += 1
|
38
|
+
@indirect_scenario_count += tag.feature.scenarios.length
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def scenario_count
|
44
|
+
@scenario_count || 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def feature_count
|
48
|
+
@feature_count || 0
|
49
|
+
end
|
50
|
+
|
51
|
+
def indirect_scenario_count
|
52
|
+
@indirect_scenario_count || 0
|
53
|
+
end
|
54
|
+
|
55
|
+
def total_scenario_count
|
56
|
+
scenario_count + indirect_scenario_count
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :<<, :push
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|