guard-bdd 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/LICENSE +21 -0
- data/README.md +70 -0
- data/Rakefile +154 -0
- data/doc/flowchart.dia +0 -0
- data/guard-bdd.gemspec +50 -0
- data/lib/guard/bdd.rb +53 -0
- data/lib/guard/bdd/state_machine.rb +180 -0
- data/lib/guard/bdd/templates/Guardfile +4 -0
- data/spec/unit/state_machine_spec.rb +61 -0
- metadata +113 -0
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2012 Nikolay Sturm <sturm@erisiandiscord.de>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
Guard::BDD
|
2
|
+
==========
|
3
|
+
|
4
|
+
BDD guard is an opinionated RSpec and Cucumber runner.
|
5
|
+
|
6
|
+
I like to partition my test suite into 3 or 4 groups:
|
7
|
+
- fast unit tests
|
8
|
+
- slower integration tests for interfaces to external libraries or services
|
9
|
+
- slow RSpec acceptance tests and/or
|
10
|
+
slow Cucumber features
|
11
|
+
|
12
|
+
Whenever the test suite goes from red to green, I like my tests to be run in
|
13
|
+
the order given above. As soon as one group of tests fails to run successfully,
|
14
|
+
test execution stops.
|
15
|
+
|
16
|
+
Install
|
17
|
+
-------
|
18
|
+
|
19
|
+
Install the gem:
|
20
|
+
|
21
|
+
$ gem install guard-bdd
|
22
|
+
|
23
|
+
or add it to your Gemfile:
|
24
|
+
|
25
|
+
``` ruby
|
26
|
+
gem 'guard-bdd'
|
27
|
+
```
|
28
|
+
|
29
|
+
Add guard definition to your Guardfile by running this command:
|
30
|
+
|
31
|
+
$ guard init bdd
|
32
|
+
|
33
|
+
Guardfile
|
34
|
+
---------
|
35
|
+
|
36
|
+
``` ruby
|
37
|
+
guard 'bdd' do
|
38
|
+
watch(%r{lib/(.*)\.rb$}) { |m| "spec/unit/#{File.basename(m[1])}_spec.rb"}
|
39
|
+
watch(%r{spec/.*_spec\.rb})
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
Options
|
44
|
+
-------
|
45
|
+
|
46
|
+
You can configure the paths to the different test groups:
|
47
|
+
|
48
|
+
- `:unit_paths` defaults to `['spec/unit']`
|
49
|
+
- `:integration_paths` defaults to `['spec/integration']`
|
50
|
+
- `:acceptance_paths` defaults to `['spec/acceptance']`
|
51
|
+
- `:feature_paths` defaults to `['features']`
|
52
|
+
|
53
|
+
Development
|
54
|
+
-----------
|
55
|
+
|
56
|
+
* Source hosted at [GitHub](https://github.com/nistude/guard-bdd)
|
57
|
+
* Report Issues/Questions/Feature requests on [GitHub Issues](https://github.com/nistude/guard-bdd/issues)
|
58
|
+
|
59
|
+
Pull requests are very welcome! Make sure your patches are well tested. Please
|
60
|
+
create a topic branch for every separate change you make.
|
61
|
+
|
62
|
+
Bugs
|
63
|
+
----
|
64
|
+
|
65
|
+
Cucumber support is still missing.
|
66
|
+
|
67
|
+
Author
|
68
|
+
------
|
69
|
+
|
70
|
+
[Nikolay Sturm](http://blog.nistu.de/)
|
data/Rakefile
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
#############################################################################
|
6
|
+
#
|
7
|
+
# Helper functions
|
8
|
+
#
|
9
|
+
#############################################################################
|
10
|
+
|
11
|
+
def name
|
12
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def shortname
|
16
|
+
@shortname ||= name.split('-')[1]
|
17
|
+
end
|
18
|
+
|
19
|
+
def version
|
20
|
+
line = File.read("lib/guard/#{shortname}.rb")[/^\s*VERSION\s*=\s*.*/]
|
21
|
+
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def date
|
25
|
+
Date.today.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def rubyforge_project
|
29
|
+
name
|
30
|
+
end
|
31
|
+
|
32
|
+
def gemspec_file
|
33
|
+
"#{name}.gemspec"
|
34
|
+
end
|
35
|
+
|
36
|
+
def gem_file
|
37
|
+
"#{name}-#{version}.gem"
|
38
|
+
end
|
39
|
+
|
40
|
+
def replace_header(head, header_name)
|
41
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
42
|
+
end
|
43
|
+
|
44
|
+
#############################################################################
|
45
|
+
#
|
46
|
+
# Standard tasks
|
47
|
+
#
|
48
|
+
#############################################################################
|
49
|
+
|
50
|
+
task :default => :test
|
51
|
+
|
52
|
+
require 'rake/testtask'
|
53
|
+
Rake::TestTask.new(:test) do |test|
|
54
|
+
test.libs << 'lib' << 'test'
|
55
|
+
test.pattern = 'test/**/test_*.rb'
|
56
|
+
test.verbose = true
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "Generate RCov test coverage and open in your browser"
|
60
|
+
task :coverage do
|
61
|
+
require 'rcov'
|
62
|
+
sh "rm -fr coverage"
|
63
|
+
sh "rcov test/test_*.rb"
|
64
|
+
sh "open coverage/index.html"
|
65
|
+
end
|
66
|
+
|
67
|
+
require 'rdoc/task'
|
68
|
+
Rake::RDocTask.new do |rdoc|
|
69
|
+
rdoc.rdoc_dir = 'rdoc'
|
70
|
+
rdoc.title = "#{name} #{version}"
|
71
|
+
rdoc.rdoc_files.include('README*')
|
72
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "Open an irb session preloaded with this library"
|
76
|
+
task :console do
|
77
|
+
sh "irb -rubygems -r ./lib/guard/#{shortname}.rb"
|
78
|
+
end
|
79
|
+
|
80
|
+
#############################################################################
|
81
|
+
#
|
82
|
+
# Custom tasks (add your own tasks here)
|
83
|
+
#
|
84
|
+
#############################################################################
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
#############################################################################
|
89
|
+
#
|
90
|
+
# Packaging tasks
|
91
|
+
#
|
92
|
+
#############################################################################
|
93
|
+
|
94
|
+
desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
|
95
|
+
task :release => :build do
|
96
|
+
unless `git branch` =~ /^\* master$/
|
97
|
+
puts "You must be on the master branch to release!"
|
98
|
+
exit!
|
99
|
+
end
|
100
|
+
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
101
|
+
sh "git tag v#{version}"
|
102
|
+
sh "git push origin master"
|
103
|
+
sh "git push origin v#{version}"
|
104
|
+
sh "gem push pkg/#{name}-#{version}.gem"
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "Build #{gem_file} into the pkg directory"
|
108
|
+
task :build => :gemspec do
|
109
|
+
sh "mkdir -p pkg"
|
110
|
+
sh "gem build #{gemspec_file}"
|
111
|
+
sh "mv #{gem_file} pkg"
|
112
|
+
end
|
113
|
+
|
114
|
+
desc "Generate #{gemspec_file}"
|
115
|
+
task :gemspec => :validate do
|
116
|
+
# read spec file and split out manifest section
|
117
|
+
spec = File.read(gemspec_file)
|
118
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
119
|
+
|
120
|
+
# replace name version and date
|
121
|
+
replace_header(head, :name)
|
122
|
+
replace_header(head, :version)
|
123
|
+
replace_header(head, :date)
|
124
|
+
#comment this out if your rubyforge_project has a different name
|
125
|
+
#replace_header(head, :rubyforge_project)
|
126
|
+
|
127
|
+
# determine file list from git ls-files
|
128
|
+
files = `git ls-files`.
|
129
|
+
split("\n").
|
130
|
+
sort.
|
131
|
+
reject { |file| file =~ /^\./ }.
|
132
|
+
reject { |file| file =~ /^(rdoc|pkg)/ }.
|
133
|
+
map { |file| " #{file}" }.
|
134
|
+
join("\n")
|
135
|
+
|
136
|
+
# piece file back together and write
|
137
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
138
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
139
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
140
|
+
puts "Updated #{gemspec_file}"
|
141
|
+
end
|
142
|
+
|
143
|
+
desc "Validate #{gemspec_file}"
|
144
|
+
task :validate do
|
145
|
+
libfiles = Dir['lib/guard/*'] - ["lib/guard/#{shortname}.rb", "lib/guard/#{shortname}"]
|
146
|
+
unless libfiles.empty?
|
147
|
+
puts "Directory `lib/guard` should only contain a `#{shortname}.rb` file and `#{shortname}` dir."
|
148
|
+
exit!
|
149
|
+
end
|
150
|
+
unless Dir['VERSION*'].empty?
|
151
|
+
puts "A `VERSION` file at root level violates Gem best practices."
|
152
|
+
exit!
|
153
|
+
end
|
154
|
+
end
|
data/doc/flowchart.dia
ADDED
Binary file
|
data/guard-bdd.gemspec
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
3
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
|
+
s.rubygems_version = '1.3.5'
|
5
|
+
|
6
|
+
s.name = 'guard-bdd'
|
7
|
+
s.version = '0.0.1'
|
8
|
+
s.date = '2012-04-15'
|
9
|
+
s.rubyforge_project = 'guard-bdd'
|
10
|
+
|
11
|
+
s.summary = "An opinionated RSpec and Cucumber runner for guard"
|
12
|
+
s.description = "Opinionated guard plugin for BDD workflow with Cucumber and RSpec"
|
13
|
+
|
14
|
+
s.authors = ["Nikolay Sturm"]
|
15
|
+
s.email = 'sturm@erisiandiscord.de'
|
16
|
+
s.homepage = 'http://github.com/nistude/guard-bdd'
|
17
|
+
|
18
|
+
s.require_paths = %w[lib]
|
19
|
+
|
20
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
21
|
+
s.extra_rdoc_files = %w[README.md LICENSE]
|
22
|
+
|
23
|
+
s.add_dependency('guard', '~> 1.0')
|
24
|
+
s.add_dependency('guard-cucumber', '~> 0.7')
|
25
|
+
s.add_dependency('guard-rspec', '~> 0.7')
|
26
|
+
s.add_dependency('rspec', '~> 2.9')
|
27
|
+
s.add_dependency('state_machine', '~> 1.1')
|
28
|
+
|
29
|
+
#s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"])
|
30
|
+
|
31
|
+
# = MANIFEST =
|
32
|
+
s.files = %w[
|
33
|
+
Gemfile
|
34
|
+
Guardfile
|
35
|
+
LICENSE
|
36
|
+
README.md
|
37
|
+
Rakefile
|
38
|
+
doc/flowchart.dia
|
39
|
+
guard-bdd.gemspec
|
40
|
+
lib/guard/bdd.rb
|
41
|
+
lib/guard/bdd/state_machine.rb
|
42
|
+
lib/guard/bdd/templates/Guardfile
|
43
|
+
spec/unit/state_machine_spec.rb
|
44
|
+
]
|
45
|
+
# = MANIFEST =
|
46
|
+
|
47
|
+
## Test files will be grabbed from the file list. Make sure the path glob
|
48
|
+
## matches what you actually use.
|
49
|
+
##s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
|
50
|
+
end
|
data/lib/guard/bdd.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'guard'
|
2
|
+
require 'guard/guard'
|
3
|
+
require 'guard/bdd/state_machine'
|
4
|
+
|
5
|
+
module Guard
|
6
|
+
class Bdd < Guard
|
7
|
+
VERSION = '0.0.1'
|
8
|
+
|
9
|
+
# Initialize a Guard.
|
10
|
+
# @param [Array<Guard::Watcher>] watchers the Guard file watchers
|
11
|
+
# @param [Hash] options the custom Guard options
|
12
|
+
def initialize(watchers = [], options = {})
|
13
|
+
super
|
14
|
+
options = {
|
15
|
+
:acceptance_paths => ['spec/acceptance'],
|
16
|
+
:feature_paths => ['features'],
|
17
|
+
:integration_paths => ['spec/integration'],
|
18
|
+
:unit_paths => ['spec/unit']
|
19
|
+
}.merge(options)
|
20
|
+
@state_machine = StateMachine.new(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Call once when Guard starts. Please override initialize method to init
|
24
|
+
# stuff.
|
25
|
+
# @raise [:task_has_failed] when start has failed
|
26
|
+
def start
|
27
|
+
@state_machine.startup
|
28
|
+
end
|
29
|
+
|
30
|
+
# Called when just `enter` is pressed
|
31
|
+
# This method should be principally used for long action like running all
|
32
|
+
# specs/tests/...
|
33
|
+
# @raise [:task_has_failed] when run_all has failed
|
34
|
+
def run_all
|
35
|
+
@state_machine.run_all
|
36
|
+
end
|
37
|
+
|
38
|
+
# Called on file(s) modifications that the Guard watches.
|
39
|
+
# @param [Array<String>] paths the changes files or paths
|
40
|
+
# @raise [:task_has_failed] when run_on_change has failed
|
41
|
+
def run_on_change(paths)
|
42
|
+
@state_machine.changed_paths = paths
|
43
|
+
@state_machine.run_on_change
|
44
|
+
end
|
45
|
+
|
46
|
+
# Called on file(s) deletions that the Guard watches.
|
47
|
+
# @param [Array<String>] paths the deleted files or paths
|
48
|
+
# @raise [:task_has_failed] when run_on_change has failed
|
49
|
+
def run_on_deletion(paths)
|
50
|
+
@state_machine.remove(paths)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'state_machine'
|
2
|
+
require 'guard/rspec/runner'
|
3
|
+
require 'guard/rspec/inspector'
|
4
|
+
|
5
|
+
module Guard
|
6
|
+
class Bdd < Guard
|
7
|
+
class StateMachine
|
8
|
+
attr_writer :changed_paths
|
9
|
+
|
10
|
+
state_machine :bdd, :initial => :cold do
|
11
|
+
# startup
|
12
|
+
state :cold
|
13
|
+
|
14
|
+
event :startup do
|
15
|
+
transition :from => :cold, :to => :run_all
|
16
|
+
end
|
17
|
+
|
18
|
+
# generic states
|
19
|
+
state :run_all
|
20
|
+
after_transition :to => :run_all, :do => :run_all_unit_specs
|
21
|
+
|
22
|
+
state :test_failure
|
23
|
+
after_transition :to => :test_failure, :do => :throw_up
|
24
|
+
|
25
|
+
state :test_success
|
26
|
+
|
27
|
+
# generic events
|
28
|
+
event :run_all do
|
29
|
+
transition :to => :run_all
|
30
|
+
end
|
31
|
+
|
32
|
+
state :run_on_change_green
|
33
|
+
after_transition :to => :run_on_change_green, :do => :run_changed
|
34
|
+
|
35
|
+
state :run_on_change_red
|
36
|
+
after_transition :to => :run_on_change_red, :do => :run_changed
|
37
|
+
|
38
|
+
event :run_on_change do
|
39
|
+
transition :from => :test_success, :to => :run_on_change_green
|
40
|
+
transition :from => :test_failure, :to => :run_on_change_red
|
41
|
+
end
|
42
|
+
|
43
|
+
event :run_changed_success do
|
44
|
+
transition :from => :run_on_change_green, :to => :test_success
|
45
|
+
transition :from => :run_on_change_red, :to => :run_all
|
46
|
+
end
|
47
|
+
|
48
|
+
event :run_changed_failure do
|
49
|
+
transition :to => :test_failure
|
50
|
+
end
|
51
|
+
|
52
|
+
# unit specs
|
53
|
+
event :unit_specs_success do
|
54
|
+
transition :to => :unit_specs_green
|
55
|
+
end
|
56
|
+
event :unit_specs_failure do
|
57
|
+
transition :to => :test_failure
|
58
|
+
end
|
59
|
+
|
60
|
+
state :unit_specs_green
|
61
|
+
after_transition :to => :unit_specs_green, :do => :run_all_integration_specs
|
62
|
+
|
63
|
+
# integration specs
|
64
|
+
event :integration_specs_success do
|
65
|
+
transition :to => :integration_specs_green
|
66
|
+
end
|
67
|
+
event :integration_specs_failure do
|
68
|
+
transition :to => :test_failure
|
69
|
+
end
|
70
|
+
|
71
|
+
state :integration_specs_green
|
72
|
+
after_transition :to => :integration_specs_green, :do => :run_all_acceptance_specs
|
73
|
+
|
74
|
+
# acceptance specs
|
75
|
+
event :acceptance_specs_success do
|
76
|
+
transition :to => :acceptance_specs_green
|
77
|
+
end
|
78
|
+
event :acceptance_specs_failure do
|
79
|
+
transition :to => :test_failure
|
80
|
+
end
|
81
|
+
|
82
|
+
state :acceptance_specs_green
|
83
|
+
after_transition :to => :acceptance_specs_green, :do => :run_all_cucumber_features
|
84
|
+
|
85
|
+
# cucumber features
|
86
|
+
event :cucumber_features_success do
|
87
|
+
transition :to => :test_success
|
88
|
+
end
|
89
|
+
event :cucumber_features_failure do
|
90
|
+
transition :to => :test_failure
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def initialize(options)
|
95
|
+
@options = options
|
96
|
+
@changed_paths = []
|
97
|
+
@failed_paths = []
|
98
|
+
|
99
|
+
@rspec_runner = RSpec::Runner.new(@options)
|
100
|
+
|
101
|
+
super()
|
102
|
+
end
|
103
|
+
|
104
|
+
def remove(paths)
|
105
|
+
@failed_paths -= paths
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
def run_all_acceptance_specs
|
110
|
+
paths = @options[:acceptance_paths].select { |path| File.exist?(path) }
|
111
|
+
if paths.empty?
|
112
|
+
acceptance_specs_success
|
113
|
+
else
|
114
|
+
passed = @rspec_runner.run(paths)
|
115
|
+
passed ? acceptance_specs_success : acceptance_specs_failure
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def run_all_cucumber_features
|
120
|
+
# passed = @cucumber_runner.run(@options[:feature_paths])
|
121
|
+
# if passed
|
122
|
+
# @failed_paths = []
|
123
|
+
cucumber_features_success
|
124
|
+
# else
|
125
|
+
# cucumber_features_failure
|
126
|
+
# end
|
127
|
+
end
|
128
|
+
|
129
|
+
def run_all_integration_specs
|
130
|
+
paths = @options[:integration_paths].select { |path| File.exist?(path) }
|
131
|
+
if paths.empty?
|
132
|
+
integration_specs_success
|
133
|
+
else
|
134
|
+
passed = @rspec_runner.run(paths)
|
135
|
+
passed ? integration_specs_success : integration_specs_failure
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def run_all_unit_specs
|
140
|
+
paths = @options[:unit_paths].select { |path| File.exist?(path) }
|
141
|
+
if paths.empty?
|
142
|
+
unit_specs_success
|
143
|
+
else
|
144
|
+
passed = @rspec_runner.run(paths)
|
145
|
+
passed ? unit_specs_success : unit_specs_failure
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def run_changed
|
150
|
+
paths = @changed_paths
|
151
|
+
paths += @failed_paths
|
152
|
+
|
153
|
+
spec_paths = []
|
154
|
+
[:acceptance_paths, :integration_paths, :unit_paths].each do |path|
|
155
|
+
spec_paths += @options[path]
|
156
|
+
end
|
157
|
+
paths = RSpec::Inspector.new(:spec_paths => spec_paths).clean(paths)
|
158
|
+
|
159
|
+
if paths.empty?
|
160
|
+
@changed_paths = []
|
161
|
+
run_changed_success
|
162
|
+
else
|
163
|
+
passed = @rspec_runner.run(paths)
|
164
|
+
@changed_paths = []
|
165
|
+
if passed
|
166
|
+
@failed_paths -= paths
|
167
|
+
run_changed_success
|
168
|
+
else
|
169
|
+
@failed_paths = (@failed_paths + paths).uniq
|
170
|
+
run_changed_failure
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def throw_up
|
176
|
+
throw :task_has_failed
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'guard/bdd'
|
2
|
+
|
3
|
+
describe Guard::Bdd::StateMachine do
|
4
|
+
let(:runner) { double(Guard::RSpec::Runner) }
|
5
|
+
let(:state_machine) {
|
6
|
+
state_machine = Guard::Bdd::StateMachine.new(
|
7
|
+
:acceptance_paths => ['acceptance'],
|
8
|
+
:features_path => ['feature'],
|
9
|
+
:integration_paths => ['integration'],
|
10
|
+
:unit_paths => ['unit']
|
11
|
+
)
|
12
|
+
}
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
runner.stub(:run).and_return(true)
|
16
|
+
Guard::RSpec::Runner.stub(:new).and_return(runner)
|
17
|
+
|
18
|
+
File.stub(:exist?).and_return(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'on startup' do
|
22
|
+
it 'runs all test groups' do
|
23
|
+
state_machine.startup
|
24
|
+
|
25
|
+
state_machine.bdd.should == 'test_success'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when a test directory does not exist' do
|
30
|
+
%w{unit integration acceptance feature}.each do |kind|
|
31
|
+
it "skips missing #{kind} tests" do
|
32
|
+
File.stub(:exist?).with(kind).and_return(false)
|
33
|
+
|
34
|
+
runner.should_not_receive(:run).with([kind])
|
35
|
+
|
36
|
+
state_machine.startup
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when a single test fails' do
|
42
|
+
it 'keeps that test on the run list until all tests succeed' do
|
43
|
+
state_machine.bdd = 'test_success'
|
44
|
+
|
45
|
+
inspector = double(Guard::RSpec::Inspector)
|
46
|
+
inspector.stub(:clean).and_return(['foo'], ['bar', 'foo'])
|
47
|
+
Guard::RSpec::Inspector.stub(:new).and_return(inspector)
|
48
|
+
|
49
|
+
runner.stub(:run).with(['foo']).and_return(false)
|
50
|
+
state_machine.changed_paths = ['foo']
|
51
|
+
expect { state_machine.run_on_change }.to throw_symbol(:task_has_failed)
|
52
|
+
state_machine.instance_variable_get(:@failed_paths).should == ['foo']
|
53
|
+
state_machine.bdd.should == 'test_failure'
|
54
|
+
|
55
|
+
state_machine.changed_paths = ['bar']
|
56
|
+
state_machine.run_on_change
|
57
|
+
state_machine.bdd.should == 'test_success'
|
58
|
+
state_machine.instance_variable_get(:@failed_paths).should == []
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: guard-bdd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nikolay Sturm
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: guard
|
16
|
+
requirement: &7296460 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *7296460
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: guard-cucumber
|
27
|
+
requirement: &7295060 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.7'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *7295060
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: guard-rspec
|
38
|
+
requirement: &7294380 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0.7'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *7294380
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &7293780 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.9'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *7293780
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: state_machine
|
60
|
+
requirement: &7293100 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '1.1'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *7293100
|
69
|
+
description: Opinionated guard plugin for BDD workflow with Cucumber and RSpec
|
70
|
+
email: sturm@erisiandiscord.de
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- README.md
|
75
|
+
- LICENSE
|
76
|
+
files:
|
77
|
+
- Gemfile
|
78
|
+
- Guardfile
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- doc/flowchart.dia
|
83
|
+
- guard-bdd.gemspec
|
84
|
+
- lib/guard/bdd.rb
|
85
|
+
- lib/guard/bdd/state_machine.rb
|
86
|
+
- lib/guard/bdd/templates/Guardfile
|
87
|
+
- spec/unit/state_machine_spec.rb
|
88
|
+
homepage: http://github.com/nistude/guard-bdd
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options:
|
92
|
+
- --charset=UTF-8
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project: guard-bdd
|
109
|
+
rubygems_version: 1.8.10
|
110
|
+
signing_key:
|
111
|
+
specification_version: 2
|
112
|
+
summary: An opinionated RSpec and Cucumber runner for guard
|
113
|
+
test_files: []
|