features_report 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.
@@ -0,0 +1,2 @@
1
+ == 0.1.0 2009-01-09
2
+
@@ -0,0 +1,23 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/features_report
6
+ lib/features_report.rb
7
+ lib/features_report/cli.rb
8
+ lib/features_report/cucumber/tree/feature.rb
9
+ lib/features_report/generator.rb
10
+ lib/features_report/git.rb
11
+ lib/features_report/reader.rb
12
+ spec/cucumber/tree/feature_spec.rb
13
+ spec/features_report_spec.rb
14
+ spec/fixtures/features.pdf
15
+ spec/fixtures/features/login.feature
16
+ spec/fixtures/features/signup.feature
17
+ spec/fixtures/steps/login_steps.rb
18
+ spec/fixtures/steps/signup_steps.rb
19
+ spec/git_spec.rb
20
+ spec/reader_spec.rb
21
+ spec/spec.opts
22
+ spec/spec_helper.rb
23
+ tasks/rspec.rake
@@ -0,0 +1,64 @@
1
+
2
+ = features_report
3
+
4
+ * Daniel Lucraft (daniellucraft.com) and Niko Felger
5
+ * http://features_report.rubyforge.org/
6
+ * sponsored by Songkick.com. Find live music playing near you!
7
+
8
+ == DESCRIPTION:
9
+
10
+ Generates a PDF report of a set of Cucumber features.
11
+
12
+ == FEATURES/PROBLEMS:
13
+
14
+ Features:
15
+ * Lists features and scenarios
16
+ * Table of contents
17
+ * Your logo on the front page
18
+ * Annotates scenarios with authorship date last changed by comments (git only)
19
+
20
+ Problems:
21
+ - Table of contents is at the back. Can't figure out how to make Prawn do
22
+ one at the front.
23
+ - FIT tables are not included properly (only their title will appear).
24
+
25
+ == SYNOPSIS:
26
+
27
+ features_report features/*/*.features
28
+
29
+ == REQUIREMENTS:
30
+
31
+ * Trollop
32
+ * Cucumber
33
+ * Prawn
34
+ * Grit (optional, needed for git only features)
35
+ * RSpec (optional, needed to run specs)
36
+
37
+ == INSTALL:
38
+
39
+ * sudo gem install features_report
40
+
41
+ == LICENSE:
42
+
43
+ (The MIT License)
44
+
45
+ Copyright (c) 2009 FIXME full name
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of this software and associated documentation files (the
49
+ 'Software'), to deal in the Software without restriction, including
50
+ without limitation the rights to use, copy, modify, merge, publish,
51
+ distribute, sublicense, and/or sell copies of the Software, and to
52
+ permit persons to whom the Software is furnished to do so, subject to
53
+ the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be
56
+ included in all copies or substantial portions of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
59
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
60
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
61
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
62
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
63
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
64
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/features_report'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('features_report', FeaturesReport::VERSION) do |p|
7
+ p.developer('Daniel Lucraft', 'dan@fluentradical.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.rubyforge_name = "features_report" # TODO this is default value
10
+ p.extra_deps = [
11
+ ['trollop','>= 1.10.2'],
12
+ ['cucumber', '>= 0.1.14'],
13
+ ['prawn', '>= 0.3.0']
14
+ ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+
19
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
+ p.rsync_args = '-av --delete --ignore-errors'
23
+ end
24
+
25
+ require 'newgem/tasks' # load /tasks/*.rake
26
+ Dir['tasks/**/*.rake'].each { |t| load t }
27
+
28
+ # TODO - want other tests/tasks run by default? Add them to the list
29
+ # task :default => [:spec, :features]
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/features_report")
4
+
5
+ FeaturesReport::CLI.execute
@@ -0,0 +1,23 @@
1
+
2
+ $:.unshift(File.dirname(__FILE__)) unless
3
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
4
+
5
+ module FeaturesReport
6
+ VERSION = '0.1.0'
7
+ end
8
+
9
+ require 'rubygems'
10
+ require 'prawn'
11
+ require 'trollop'
12
+
13
+ begin
14
+ require 'grit'
15
+ rescue
16
+ end
17
+
18
+ require 'features_report/reader'
19
+ require 'features_report/generator'
20
+ require 'features_report/cli'
21
+ require 'features_report/git'
22
+ FeaturesReport::Reader.load_cucumber
23
+ require 'features_report/cucumber/tree/feature'
@@ -0,0 +1,29 @@
1
+
2
+ module FeaturesReport
3
+ class CLI
4
+ def self.execute
5
+ opts = Trollop.options do
6
+ version "features_report 0.1 (c) 2008 Daniel Lucraft & Niko Felger"
7
+ banner <<-EOS
8
+ features_report turns Cucumber features into a pretty PDF report. Output is put in features.pdf.
9
+
10
+ Usage:
11
+ features_report [options] <filenames>+
12
+
13
+ where [options] are:
14
+ EOS
15
+
16
+ opt :logo, "Path to image for the front page", :type => :string
17
+ end
18
+ Trollop.die "no features files given" if ARGV.empty?
19
+ reader = Reader.new(ARGV)
20
+ if defined?(Grit) and Git.git_repo?(ARGV.first)
21
+ git = Git.new(ARGV)
22
+ else
23
+ git = nil
24
+ end
25
+ generator = Generator.new(reader, git, opts)
26
+ generator.generate
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+
2
+ class Cucumber::Tree::Feature
3
+ def title
4
+ header.split("\n").first.strip.gsub(/^Feature: /, "")
5
+ end
6
+ end
@@ -0,0 +1,162 @@
1
+
2
+ module FeaturesReport
3
+ class Generator
4
+ def initialize(reader, git, opts)
5
+ @reader = reader
6
+ @opts = opts
7
+ @git = git
8
+ @feature_pages ||= {}
9
+ @features = reader.features.map{|f| Feature.new(f, @git)}
10
+ end
11
+
12
+ attr_reader :pdf, :reader, :opts
13
+
14
+ def generate
15
+ @pdf = Prawn::Document.new :page_size => "A4", :top_margin => 60
16
+
17
+ pdf.header [pdf.bounds.right, pdf.bounds.bottom + 10] do
18
+ pdf.text pdf.page_count-1 unless pdf.page_count == 1
19
+ end
20
+
21
+ @original_bottom_left = [pdf.bounds.left, pdf.bounds.bottom - 10]
22
+
23
+ generate_front_page
24
+
25
+ sorted_features.each do |feature|
26
+ generate_feature(feature)
27
+ end
28
+
29
+ generate_contents_page
30
+ pdf.render_file("features.pdf")
31
+ end
32
+
33
+ FEATURE_TITLE_STYLE = {:size => 24}
34
+ SCENARIO_TITLE_STYLE = {:size => 16}
35
+ STEP_STYLE = {}
36
+ FOOTER_STYLE = {:size => 12}
37
+ DOC_TITLE_STYLE = {:size => 32, :align => :center}
38
+
39
+ private
40
+
41
+ def generate_front_page
42
+ pdf.move_down(200)
43
+
44
+ if opts[:logo]
45
+ pdf.image opts[:logo]
46
+ end
47
+
48
+ pdf.text "Features Report", DOC_TITLE_STYLE
49
+ pdf.move_down(10)
50
+ pdf.text Time.now.strftime("%e %B %Y"), :align => :center
51
+
52
+ start_new_page
53
+ end
54
+
55
+ class Feature
56
+ def initialize(feature, git)
57
+ @feature = feature
58
+ @git = git
59
+ end
60
+
61
+ def header
62
+ @feature.header
63
+ end
64
+
65
+ def last_commit
66
+ @last_commit ||= @git.last_commit(@feature)
67
+ end
68
+
69
+ def last_changed
70
+ last_commit.date
71
+ end
72
+
73
+ def last_author
74
+ last_commit.author.name
75
+ end
76
+
77
+ def scenarios
78
+ @feature.scenarios
79
+ end
80
+
81
+ def title
82
+ @feature.title
83
+ end
84
+
85
+ def contents_text
86
+ title + "\n" + header.split("\n")[1..-1].join("\n")
87
+ end
88
+ end
89
+
90
+ def sorted_features
91
+ return @sorted_features if @sorted_features
92
+
93
+ @sorted_features = @features.sort_by do |feature|
94
+ if @git
95
+ feature.last_changed
96
+ else
97
+ feature.title
98
+ end
99
+ end
100
+
101
+ @sorted_features = @sorted_features.reverse if @git
102
+
103
+ @sorted_features
104
+ end
105
+
106
+ def generate_contents_page
107
+ clear_footer
108
+ pdf.text "Contents", :size => 20, :align => :center
109
+
110
+ data = []
111
+ widths, headers = nil, nil
112
+
113
+ sorted_features.each_with_index do |feature, index|
114
+ if @git
115
+ data << [index + 1, feature.title, feature.last_changed.strftime("%e %b"), feature.last_author.split.map{|word| word[0..0].upcase}.join, @feature_pages[feature]]
116
+ widths = {0 => 30, 1 => 340, 2 => 70, 3 => 40, 4 => 40}
117
+ headers = ["", "Title", "Last Changed", "By", "Page"]
118
+ else
119
+ data << [index + 1, feature.title, @feature_pages[feature]]
120
+ widths = {0 => 30, 1 => 470, 2 => 30}
121
+ headers = ["", "", ""]
122
+ end
123
+ end
124
+
125
+ pdf.move_down 35
126
+ pdf.table data, :border_width => 0, :widths => widths, :headers => headers
127
+ end
128
+
129
+ def clear_footer
130
+ pdf.footer(pdf.bounds.bottom_left) {}
131
+ end
132
+
133
+ def generate_feature(feature)
134
+ pdf.text "Feature: " + feature.title, FEATURE_TITLE_STYLE
135
+ pdf.text feature.header.split("\n")[1..-1].join("\n")
136
+
137
+ pdf.footer @original_bottom_left do
138
+ pdf.text feature.title, FOOTER_STYLE
139
+ end
140
+
141
+ pdf.move_down 20
142
+ @feature_pages[feature] = pdf.page_count-1
143
+
144
+ feature.scenarios.each do |scenario|
145
+ pdf.text scenario.name, SCENARIO_TITLE_STYLE
146
+ pdf.move_down 4
147
+ scenario.steps.each do |step|
148
+ next if step.is_a?(Cucumber::Tree::RowStep) or step.is_a?(Cucumber::Tree::RowStepOutline) # TODO: deal with these
149
+ pdf.text step.keyword + " " + step.name, STEP_STYLE
150
+ end
151
+ pdf.move_down 10
152
+ end
153
+
154
+ start_new_page
155
+ end
156
+
157
+ def start_new_page
158
+ pdf.start_new_page(:bottom_margin => 60)
159
+ end
160
+
161
+ end
162
+ end
@@ -0,0 +1,31 @@
1
+
2
+ module FeaturesReport
3
+ class Git
4
+ def self.git_repo?(filename)
5
+ path = File.expand_path(filename)
6
+ while path and path != ""
7
+ if File.exist?(path + "/.git")
8
+ return path
9
+ end
10
+ path = path.split("/")[0..-2].join("/")
11
+ end
12
+ false
13
+ end
14
+
15
+ def initialize(files)
16
+ @repo = Grit::Repo.new(Git.git_repo?(files.first))
17
+ @files = files
18
+ end
19
+
20
+ def git_dir
21
+ @repo.path.split("/")[0..-2].join("/")
22
+ end
23
+
24
+ def last_commit(feature)
25
+ filename = File.expand_path(feature.file, git_dir).gsub(/^#{Regexp.escape(git_dir)}\//, "")
26
+ commit = @repo.log(@repo.head.name, filename).first
27
+ end
28
+
29
+ attr_reader :files
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+
2
+ module FeaturesReport
3
+ class Reader
4
+ attr_reader :files
5
+
6
+ def initialize(files)
7
+ @files = files
8
+ end
9
+
10
+ def self.load_cucumber
11
+ require "cucumber"
12
+ require "cucumber/treetop_parser/feature_en"
13
+ Cucumber.load_language("en")
14
+
15
+ Cucumber::Tree::Feature.class_eval do
16
+ attr_reader :scenarios
17
+ end
18
+ end
19
+
20
+ def features
21
+ return @features if @features
22
+ @features = files.map do |file|
23
+ parser.parse_feature(file)
24
+ end
25
+ end
26
+
27
+ def parser
28
+ @parser ||= Cucumber::TreetopParser::FeatureParser.new
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+
2
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
3
+
4
+ describe Cucumber::Tree::Feature do
5
+ before(:each) do
6
+ reader = Reader.new(["spec/fixtures/features/login.feature"])
7
+ @feature = reader.features.first
8
+ end
9
+
10
+ it "should have a title" do
11
+ @feature.title.should == "Log in to the site"
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper.rb'
3
+
4
+ describe "" do
5
+
6
+ end
@@ -0,0 +1,68 @@
1
+ Feature: Log in to the site
2
+ As a user,
3
+ I want to be able to log in to the site
4
+ So I can access personalized features
5
+
6
+ Scenario: Log in
7
+ Given I have an account
8
+ When I visit the login page
9
+ And I enter my login details
10
+ And I press "Login"
11
+ Then I should be viewing my user page
12
+
13
+ Scenario: Log in with bad password
14
+ Given I have an account
15
+ When I visit the login page
16
+ And I enter my login details with a bad password
17
+ And I press "Login"
18
+ Then I should be viewing the login page
19
+ And I should see the text "Bad username or password"
20
+
21
+ Scenario: Log in with bad email
22
+ Given I have an account
23
+ When I visit the login page
24
+ And I enter my login details with a bad email
25
+ And I press "Login"
26
+ Then I should be viewing the login page
27
+ And I should see the text "Bad username or password"
28
+
29
+ Scenario: Log in with bad password and then log in
30
+ Given I have an account
31
+ When I visit the login page
32
+ And I enter my login details with a bad email
33
+ And I press "Login"
34
+ And I enter my login details
35
+ And I press "Login"
36
+ Then I should be viewing my user page
37
+
38
+ Scenario: Log in
39
+ Given I have an account
40
+ When I visit the login page
41
+ And I enter my login details
42
+ And I press "Login"
43
+ Then I should be viewing my user page
44
+
45
+ Scenario: Log in with bad password
46
+ Given I have an account
47
+ When I visit the login page
48
+ And I enter my login details with a bad password
49
+ And I press "Login"
50
+ Then I should be viewing the login page
51
+ And I should see the text "Bad username or password"
52
+
53
+ Scenario: Log in with bad email
54
+ Given I have an account
55
+ When I visit the login page
56
+ And I enter my login details with a bad email
57
+ And I press "Login"
58
+ Then I should be viewing the login page
59
+ And I should see the text "Bad username or password"
60
+
61
+ Scenario: Log in with bad password and then log in
62
+ Given I have an account
63
+ When I visit the login page
64
+ And I enter my login details with a bad email
65
+ And I press "Login"
66
+ And I enter my login details
67
+ And I press "Login"
68
+ Then I should be viewing my user page
@@ -0,0 +1,27 @@
1
+ Feature: Sign up to the site
2
+ As a visitor
3
+ I want to be able to sign up for a user account
4
+ So I can gain access to the personalized features of the site
5
+
6
+ Scenario: Sign up
7
+ When I visit the sign up page
8
+ And I enter my sign up details with username "leoban"
9
+ And I press "Sign up"
10
+ Then I should be viewing the user page for user "leoban"
11
+
12
+ Scenario: Sign up with missing email
13
+ When I visit the sign up page
14
+ And I enter my sign up details with username "leoban"
15
+ And I forget to enter an email
16
+ And I press "Sign up"
17
+ Then I should be viewing the sign up page
18
+ And I should see the text "email required"
19
+
20
+ Scenario: Sign up with duplicate username
21
+ Given there is a user with username "leoban"
22
+ When I visit the sign up page
23
+ And I enter my sign up details with username "leoban"
24
+ And I press "Sign up"
25
+ Then I should be viewing the sign up page
26
+ And I should see the text "that username is already taken"
27
+
@@ -0,0 +1,26 @@
1
+ Given /^I have an account$/ do
2
+ end
3
+
4
+ When /^I visit the login page$/ do
5
+ end
6
+
7
+ When /^I enter my login details$/ do
8
+ end
9
+
10
+ When /^I press "Login"$/ do
11
+ end
12
+
13
+ Then /^I should be viewing my user page$/ do
14
+ end
15
+
16
+ When /^I enter my login details with a bad password$/ do
17
+ end
18
+
19
+ Then /^I should be viewing the login page$/ do
20
+ end
21
+
22
+ Then /^I should see the text "Bad username or password"$/ do
23
+ end
24
+
25
+ When /^I enter my login details with a bad email$/ do
26
+ end
@@ -0,0 +1,27 @@
1
+
2
+ When /^I visit the sign up page$/ do
3
+ end
4
+
5
+ When /^I enter my sign up details with username "leoban"$/ do
6
+ end
7
+
8
+ When /^I press "Sign up"$/ do
9
+ end
10
+
11
+ Then /^I should be viewing the user page for user "leoban"$/ do
12
+ end
13
+
14
+ When /^I forget to enter an email$/ do
15
+ end
16
+
17
+ Then /^I should be viewing the sign up page$/ do
18
+ end
19
+
20
+ Then /^I should see the text "email required"$/ do
21
+ end
22
+
23
+ Given /^there is a user with username "leoban"$/ do
24
+ end
25
+
26
+ Then /^I should see the text "that username is already taken"$/ do
27
+ end
@@ -0,0 +1,18 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper.rb'
3
+
4
+ include FeaturesReport
5
+
6
+ describe FeaturesReport::Git do
7
+ describe ".git_repo?" do
8
+ it "should be true if in a git repo" do
9
+ Git.git_repo?("spec/").should_not be_nil
10
+ end
11
+
12
+ it "should be false if not in a git repo" do
13
+ # linux specific
14
+ Git.git_repo?("/usr/local").should be_false
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,24 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper.rb'
3
+
4
+ include FeaturesReport
5
+
6
+ describe FeaturesReport::Reader do
7
+
8
+ before(:each) do
9
+ @reader = Reader.new(Dir[FEATURE_FIXTURES_GLOB])
10
+ end
11
+
12
+ it "should load the features" do
13
+ @reader.features.length.should == 2
14
+
15
+ @reader.features.map {|f| f.title}.sort.should == ["Log in to the site", "Sign up to the site"]
16
+ end
17
+
18
+ it "should load the scenarios" do
19
+ login_feature = @reader.features.detect {|f| f.title == "Log in to the site"}
20
+ login_feature.scenarios.length.should == 8
21
+ login_scenario = login_feature.scenarios.last
22
+ login_scenario.name.should == "Log in with bad password and then log in"
23
+ end
24
+ end
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,13 @@
1
+
2
+ begin
3
+ require 'spec'
4
+ rescue LoadError
5
+ require 'rubygems'
6
+ gem 'rspec'
7
+ require 'spec'
8
+ end
9
+
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+ require 'features_report'
12
+
13
+ FEATURE_FIXTURES_GLOB = "spec/fixtures/features/*.feature" unless defined?(FEATURE_FIXTURES_GLOB)
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: features_report
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Lucraft
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-12 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: trollop
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.10.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: cucumber
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.14
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: prawn
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.3.0
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: newgem
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.2.3
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: hoe
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.8.0
64
+ version:
65
+ description: Generates a PDF report of a set of Cucumber features.
66
+ email:
67
+ - dan@fluentradical.com
68
+ executables:
69
+ - features_report
70
+ extensions: []
71
+
72
+ extra_rdoc_files:
73
+ - History.txt
74
+ - Manifest.txt
75
+ - README.rdoc
76
+ files:
77
+ - History.txt
78
+ - Manifest.txt
79
+ - README.rdoc
80
+ - Rakefile
81
+ - bin/features_report
82
+ - lib/features_report.rb
83
+ - lib/features_report/cli.rb
84
+ - lib/features_report/cucumber/tree/feature.rb
85
+ - lib/features_report/generator.rb
86
+ - lib/features_report/git.rb
87
+ - lib/features_report/reader.rb
88
+ - spec/cucumber/tree/feature_spec.rb
89
+ - spec/features_report_spec.rb
90
+ - spec/fixtures/features.pdf
91
+ - spec/fixtures/features/login.feature
92
+ - spec/fixtures/features/signup.feature
93
+ - spec/fixtures/steps/login_steps.rb
94
+ - spec/fixtures/steps/signup_steps.rb
95
+ - spec/git_spec.rb
96
+ - spec/reader_spec.rb
97
+ - spec/spec.opts
98
+ - spec/spec_helper.rb
99
+ - tasks/rspec.rake
100
+ has_rdoc: true
101
+ homepage: " * Daniel Lucraft (daniellucraft.com) and Niko Felger"
102
+ post_install_message:
103
+ rdoc_options:
104
+ - --main
105
+ - README.rdoc
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: "0"
113
+ version:
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: "0"
119
+ version:
120
+ requirements: []
121
+
122
+ rubyforge_project: features_report
123
+ rubygems_version: 1.2.0
124
+ signing_key:
125
+ specification_version: 2
126
+ summary: Generates a PDF report of a set of Cucumber features.
127
+ test_files: []
128
+