busser 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +32 -0
- data/.github/workflows/pr-title.yml +28 -0
- data/.github/workflows/publish.yml +45 -0
- data/.gitignore +0 -1
- data/.markdownlint.yaml +6 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +9 -0
- data/.yamllint +6 -0
- data/CHANGELOG.md +43 -0
- data/CONTRIBUTING.md +103 -0
- data/Gemfile +10 -6
- data/README.md +77 -19
- data/Rakefile +6 -23
- data/bin/busser +2 -4
- data/busser.gemspec +12 -15
- data/features/deserialize_command.feature +4 -1
- data/features/plugin_create_command.feature +7 -9
- data/features/plugin_install_command.feature +1 -1
- data/features/support/env.rb +4 -16
- data/lib/busser/cli.rb +6 -7
- data/lib/busser/command/deserialize.rb +16 -11
- data/lib/busser/command/plugin.rb +4 -5
- data/lib/busser/command/plugin_create.rb +40 -27
- data/lib/busser/command/plugin_install.rb +15 -16
- data/lib/busser/command/plugin_list.rb +3 -4
- data/lib/busser/command/setup.rb +34 -21
- data/lib/busser/command/suite.rb +3 -4
- data/lib/busser/command/suite_cleanup.rb +3 -3
- data/lib/busser/command/suite_path.rb +2 -3
- data/lib/busser/command/test.rb +4 -4
- data/lib/busser/cucumber/hooks.rb +1 -9
- data/lib/busser/cucumber.rb +69 -49
- data/lib/busser/helpers.rb +4 -5
- data/lib/busser/plugin.rb +12 -6
- data/lib/busser/rubygems.rb +25 -11
- data/lib/busser/runner_plugin/dummy.rb +2 -3
- data/lib/busser/runner_plugin.rb +1 -2
- data/lib/busser/thor.rb +3 -4
- data/lib/busser/ui.rb +23 -5
- data/lib/busser/version.rb +1 -2
- data/lib/busser.rb +3 -4
- data/release-please-config.json +13 -0
- data/renovate.json +8 -0
- data/spec/busser/command/deserialize_spec.rb +110 -0
- data/spec/busser/command/plugin_create_spec.rb +175 -0
- data/spec/busser/command/setup_spec.rb +121 -0
- data/spec/busser/helpers_spec.rb +10 -10
- data/spec/busser/plugin_spec.rb +133 -0
- data/spec/busser/ui_spec.rb +84 -32
- data/spec/spec_helper.rb +1 -7
- data/templates/plugin/Rakefile.erb +4 -24
- data/templates/plugin/features_env.rb.erb +4 -4
- data/templates/plugin/gemspec.erb +7 -8
- data/templates/plugin/github_workflow.yml.erb +26 -0
- metadata +29 -88
- data/.cane +0 -0
- data/.simplecov +0 -10
- data/.travis.yml +0 -52
- data/Guardfile +0 -18
- data/appveyor.yml +0 -36
- data/templates/plugin/tailor.erb +0 -4
- data/templates/plugin/travis.yml.erb +0 -11
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require_relative "../../spec_helper"
|
|
16
|
+
|
|
17
|
+
require "tmpdir"
|
|
18
|
+
|
|
19
|
+
require "busser/command/plugin_create"
|
|
20
|
+
|
|
21
|
+
# The generated project is what a plugin author starts from, so the checks
|
|
22
|
+
# worth having are the ones a new project would trip over on day one.
|
|
23
|
+
describe Busser::Command::PluginCreate do
|
|
24
|
+
|
|
25
|
+
before do
|
|
26
|
+
@tmpdir = Dir.mktmpdir("busser-plugin-create")
|
|
27
|
+
@pwd = Dir.pwd
|
|
28
|
+
Dir.chdir(@tmpdir)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
after do
|
|
32
|
+
Dir.chdir(@pwd)
|
|
33
|
+
FileUtils.rm_rf(@tmpdir)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "the generated gemspec" do
|
|
37
|
+
|
|
38
|
+
it "loads" do
|
|
39
|
+
generate
|
|
40
|
+
|
|
41
|
+
_(gemspec.name).must_equal "busser-demo"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# RubyGems validates spec.license against the SPDX list and warns on
|
|
45
|
+
# anything else. The generator used to emit "Apache 2.0", the human
|
|
46
|
+
# readable name rather than the identifier.
|
|
47
|
+
it "declares a license RubyGems recognises" do
|
|
48
|
+
generate
|
|
49
|
+
|
|
50
|
+
_(Gem::Licenses.match?(gemspec.license)).must_equal true
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
"apachev2" => "Apache-2.0",
|
|
55
|
+
"mit" => "MIT",
|
|
56
|
+
"lgplv3" => "LGPL-3.0-only",
|
|
57
|
+
}.each do |option, identifier|
|
|
58
|
+
it "maps --license #{option} to #{identifier}" do
|
|
59
|
+
generate(license: option)
|
|
60
|
+
|
|
61
|
+
_(gemspec.license).must_equal identifier
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# "All rights reserved" has no SPDX identifier, so declaring nothing is
|
|
66
|
+
# the only correct option.
|
|
67
|
+
it "declares no license for an all rights reserved plugin" do
|
|
68
|
+
generate(license: "reserved")
|
|
69
|
+
|
|
70
|
+
_(gemspec.license).must_be_nil
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# bundler ~> 1.3 cannot be satisfied by any bundler in use today, so a
|
|
74
|
+
# freshly generated plugin failed to resolve before running anything.
|
|
75
|
+
it "does not constrain bundler" do
|
|
76
|
+
generate
|
|
77
|
+
|
|
78
|
+
_(dev_dependencies).wont_include "bundler"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# cane, tailor and countloc have been unmaintained for about a decade.
|
|
82
|
+
%w{cane tailor countloc}.each do |gem_name|
|
|
83
|
+
it "does not depend on #{gem_name}" do
|
|
84
|
+
generate
|
|
85
|
+
|
|
86
|
+
_(dev_dependencies).wont_include gem_name
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "depends on what the generated Rakefile needs" do
|
|
91
|
+
generate
|
|
92
|
+
|
|
93
|
+
_(dev_dependencies).must_include "rake"
|
|
94
|
+
_(dev_dependencies).must_include "cucumber"
|
|
95
|
+
_(dev_dependencies).must_include "aruba"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "states a supported Ruby version" do
|
|
99
|
+
generate
|
|
100
|
+
|
|
101
|
+
requirement = gemspec.required_ruby_version
|
|
102
|
+
|
|
103
|
+
_(requirement.satisfied_by?(Gem::Version.new("3.2.0"))).must_equal true
|
|
104
|
+
_(requirement.satisfied_by?(Gem::Version.new("2.7.0"))).must_equal false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def gemspec
|
|
108
|
+
Gem::Specification.load(File.join(plugin_dir, "busser-demo.gemspec"))
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def dev_dependencies
|
|
112
|
+
gemspec.development_dependencies.map(&:name)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe "the generated project" do
|
|
117
|
+
|
|
118
|
+
it "ships a CI workflow rather than a Travis config" do
|
|
119
|
+
generate
|
|
120
|
+
|
|
121
|
+
_(File.exist?(File.join(plugin_dir, ".github/workflows/test.yml")))
|
|
122
|
+
.must_equal true
|
|
123
|
+
_(File.exist?(File.join(plugin_dir, ".travis.yml"))).must_equal false
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Both linters are long dead, and the Rakefile's default task depended on
|
|
127
|
+
# them, so `rake` failed on a freshly generated plugin.
|
|
128
|
+
it "ships no dead linter configuration" do
|
|
129
|
+
generate
|
|
130
|
+
|
|
131
|
+
_(File.exist?(File.join(plugin_dir, ".tailor"))).must_equal false
|
|
132
|
+
_(File.exist?(File.join(plugin_dir, ".cane"))).must_equal false
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "has a Rakefile that only references tasks it defines" do
|
|
136
|
+
generate
|
|
137
|
+
|
|
138
|
+
rakefile = File.read(File.join(plugin_dir, "Rakefile"))
|
|
139
|
+
|
|
140
|
+
_(rakefile).wont_match(/cane|tailor|countloc/)
|
|
141
|
+
_(rakefile).must_match(/Cucumber::Rake::Task/)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# aruba 1.0 dropped @aruba_timeout_seconds, and setting it on aruba 2 is
|
|
145
|
+
# silently ignored, so the generated timeout did nothing at all.
|
|
146
|
+
it "configures aruba through the supported API" do
|
|
147
|
+
generate
|
|
148
|
+
|
|
149
|
+
env = File.read(File.join(plugin_dir, "features/support/env.rb"))
|
|
150
|
+
|
|
151
|
+
_(env).wont_match(/@aruba_timeout_seconds/)
|
|
152
|
+
_(env).must_match(/Aruba\.configure/)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def generate(license: "apachev2")
|
|
157
|
+
command = Busser::Command::PluginCreate.new(
|
|
158
|
+
["demo"], { "type" => "runner", "license" => license }
|
|
159
|
+
)
|
|
160
|
+
command.stubs(:initialize_git)
|
|
161
|
+
capture_stdout { command.create }
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def plugin_dir
|
|
165
|
+
File.join(@tmpdir, "busser-demo")
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def capture_stdout
|
|
169
|
+
original = $stdout
|
|
170
|
+
$stdout = StringIO.new
|
|
171
|
+
yield
|
|
172
|
+
ensure
|
|
173
|
+
$stdout = original
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require_relative "../../spec_helper"
|
|
16
|
+
|
|
17
|
+
require "tmpdir"
|
|
18
|
+
|
|
19
|
+
require "busser/command/setup"
|
|
20
|
+
|
|
21
|
+
# The binstub exists to give Busser an isolated gem environment on the machine
|
|
22
|
+
# under test, so what it does to the environment before exec is the contract
|
|
23
|
+
# worth pinning down.
|
|
24
|
+
describe Busser::Command::Setup do
|
|
25
|
+
|
|
26
|
+
# Anything left set here lets the calling Ruby environment reach into
|
|
27
|
+
# Busser's. RUBYOPT was once the only way in; RubyGems now requires
|
|
28
|
+
# bundler/setup whenever BUNDLER_SETUP is present, and bundler then resets
|
|
29
|
+
# GEM_HOME to the calling project's bundle.
|
|
30
|
+
LEAKY_VARIABLES = %w{
|
|
31
|
+
RUBYOPT GEMRC RUBYLIB
|
|
32
|
+
BUNDLER_SETUP BUNDLER_VERSION
|
|
33
|
+
BUNDLE_BIN_PATH BUNDLE_GEMFILE BUNDLE_LOCKFILE BUNDLE_PATH
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
before do
|
|
37
|
+
@tmpdir = Dir.mktmpdir("busser-setup")
|
|
38
|
+
@original_root = ENV["BUSSER_ROOT"]
|
|
39
|
+
ENV["BUSSER_ROOT"] = @tmpdir
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
after do
|
|
43
|
+
ENV["BUSSER_ROOT"] = @original_root
|
|
44
|
+
FileUtils.rm_rf(@tmpdir)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "the bourne binstub" do
|
|
48
|
+
|
|
49
|
+
it "is created and executable" do
|
|
50
|
+
run_setup
|
|
51
|
+
|
|
52
|
+
_(File.exist?(binstub)).must_equal true
|
|
53
|
+
_(File.stat(binstub).mode & 0o111).wont_equal 0
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "pins BUSSER_ROOT and the gem paths" do
|
|
57
|
+
run_setup
|
|
58
|
+
|
|
59
|
+
_(binstub_body).must_match(/BUSSER_ROOT="#{Regexp.escape(@tmpdir)}"/)
|
|
60
|
+
_(binstub_body).must_match(/^GEM_HOME=/)
|
|
61
|
+
_(binstub_body).must_match(/^GEM_PATH=/)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
LEAKY_VARIABLES.each do |name|
|
|
65
|
+
it "unsets #{name} before exec" do
|
|
66
|
+
run_setup
|
|
67
|
+
|
|
68
|
+
_(unset_variables).must_include name
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "unsets everything before handing off to ruby" do
|
|
73
|
+
run_setup
|
|
74
|
+
|
|
75
|
+
unset_line = binstub_body.index("unset ")
|
|
76
|
+
exec_line = binstub_body.index("exec ")
|
|
77
|
+
|
|
78
|
+
_(unset_line).must_be :<, exec_line
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def binstub
|
|
82
|
+
File.join(@tmpdir, "bin", "busser")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def unset_variables
|
|
86
|
+
binstub_body.scan(/^unset (.+)$/).flatten.join(" ").split(/\s+/)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "the bat binstub" do
|
|
91
|
+
|
|
92
|
+
LEAKY_VARIABLES.each do |name|
|
|
93
|
+
it "clears #{name} before exec" do
|
|
94
|
+
run_setup(type: "bat")
|
|
95
|
+
|
|
96
|
+
_(binstub_body).must_match(/^SET #{name}=\s*$/)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def binstub
|
|
101
|
+
File.join(@tmpdir, "bin", "busser.bat")
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def run_setup(type: "bourne")
|
|
106
|
+
command = Busser::Command::Setup.new([], { "type" => type })
|
|
107
|
+
capture_stdout { command.perform }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def binstub_body
|
|
111
|
+
File.read(binstub)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def capture_stdout
|
|
115
|
+
original = $stdout
|
|
116
|
+
$stdout = StringIO.new
|
|
117
|
+
yield
|
|
118
|
+
ensure
|
|
119
|
+
$stdout = original
|
|
120
|
+
end
|
|
121
|
+
end
|
data/spec/busser/helpers_spec.rb
CHANGED
|
@@ -9,17 +9,17 @@ describe Busser::Helpers do
|
|
|
9
9
|
describe ".suite_path" do
|
|
10
10
|
|
|
11
11
|
it "returns a Pathname" do
|
|
12
|
-
suite_path.must_be_kind_of Pathname
|
|
12
|
+
_(suite_path).must_be_kind_of Pathname
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
describe "with a default root path" do
|
|
16
16
|
|
|
17
17
|
it "returns a base path if no suite name is given" do
|
|
18
|
-
suite_path.to_s.must_match %r{/opt/busser/suites$}
|
|
18
|
+
_(suite_path.to_s).must_match %r{/opt/busser/suites$}
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it "returns a suite path given a suite name" do
|
|
22
|
-
suite_path("fuzzy").to_s.must_match %r{/opt/busser/suites/fuzzy$}
|
|
22
|
+
_(suite_path("fuzzy").to_s).must_match %r{/opt/busser/suites/fuzzy$}
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -30,12 +30,12 @@ describe Busser::Helpers do
|
|
|
30
30
|
|
|
31
31
|
it "returns a base path if no suite name is given" do
|
|
32
32
|
ENV['BUSSER_ROOT'] = "/path/to/busser"
|
|
33
|
-
suite_path.to_s.must_match %r{/path/to/busser/suites$}
|
|
33
|
+
_(suite_path.to_s).must_match %r{/path/to/busser/suites$}
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it "returns a suite path given a suite name" do
|
|
37
37
|
ENV['BUSSER_ROOT'] = "/path/to/busser"
|
|
38
|
-
suite_path("fuzzy").to_s.must_match %r{/path/to/busser/suites/fuzzy$}
|
|
38
|
+
_(suite_path("fuzzy").to_s).must_match %r{/path/to/busser/suites/fuzzy$}
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -43,17 +43,17 @@ describe Busser::Helpers do
|
|
|
43
43
|
describe ".vendor_path" do
|
|
44
44
|
|
|
45
45
|
it "returns a Pathname" do
|
|
46
|
-
vendor_path.must_be_kind_of Pathname
|
|
46
|
+
_(vendor_path).must_be_kind_of Pathname
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
describe "with a default root path" do
|
|
50
50
|
|
|
51
51
|
it "returns a base path if no product name is given" do
|
|
52
|
-
vendor_path.to_s.must_match %r{/opt/busser/vendor$}
|
|
52
|
+
_(vendor_path.to_s).must_match %r{/opt/busser/vendor$}
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
it "returns a vendor path given a product name" do
|
|
56
|
-
vendor_path("supreme").to_s.must_match %r{/opt/busser/vendor/supreme$}
|
|
56
|
+
_(vendor_path("supreme").to_s).must_match %r{/opt/busser/vendor/supreme$}
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -64,12 +64,12 @@ describe Busser::Helpers do
|
|
|
64
64
|
|
|
65
65
|
it "returns a base path if no product name is given" do
|
|
66
66
|
ENV['BUSSER_ROOT'] = "/path/to/busser"
|
|
67
|
-
vendor_path.to_s.must_match %r{/path/to/busser/vendor$}
|
|
67
|
+
_(vendor_path.to_s).must_match %r{/path/to/busser/vendor$}
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
it "returns a suite path given a product name" do
|
|
71
71
|
ENV['BUSSER_ROOT'] = "/path/to/busser"
|
|
72
|
-
vendor_path("maximal").to_s.must_match \
|
|
72
|
+
_(vendor_path("maximal").to_s).must_match \
|
|
73
73
|
%r{/path/to/busser/vendor/maximal$}
|
|
74
74
|
end
|
|
75
75
|
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require_relative "../spec_helper"
|
|
16
|
+
|
|
17
|
+
require "busser/plugin"
|
|
18
|
+
require "busser/ui"
|
|
19
|
+
|
|
20
|
+
describe Busser::Plugin do
|
|
21
|
+
|
|
22
|
+
describe ".runner_plugin" do
|
|
23
|
+
|
|
24
|
+
it "builds the require path for a plugin name" do
|
|
25
|
+
_(Busser::Plugin.runner_plugin("bash"))
|
|
26
|
+
.must_equal "busser/runner_plugin/bash"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe ".runner_plugins" do
|
|
31
|
+
|
|
32
|
+
it "maps each given name to its require path" do
|
|
33
|
+
_(Busser::Plugin.runner_plugins(%w{bash minitest})).must_equal [
|
|
34
|
+
"busser/runner_plugin/bash",
|
|
35
|
+
"busser/runner_plugin/minitest",
|
|
36
|
+
]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "accepts a single name that is not in an array" do
|
|
40
|
+
_(Busser::Plugin.runner_plugins("bash"))
|
|
41
|
+
.must_equal ["busser/runner_plugin/bash"]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Callers run one suite per entry, so a repeated name would run that
|
|
45
|
+
# suite twice.
|
|
46
|
+
it "returns a name given more than once only once" do
|
|
47
|
+
_(Busser::Plugin.runner_plugins(%w{bash bash}))
|
|
48
|
+
.must_equal ["busser/runner_plugin/bash"]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "falls back to every installed plugin when given no names" do
|
|
52
|
+
Busser::Plugin.expects(:all_runner_plugins).returns(["stubbed"])
|
|
53
|
+
|
|
54
|
+
_(Busser::Plugin.runner_plugins).must_equal ["stubbed"]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe ".all_runner_plugins" do
|
|
59
|
+
|
|
60
|
+
it "turns each found file into a require path" do
|
|
61
|
+
stub_found_files %w{
|
|
62
|
+
/gems/busser-bash-0.1.1/lib/busser/runner_plugin/bash.rb
|
|
63
|
+
/gems/busser-serverspec-0.5.0/lib/busser/runner_plugin/serverspec.rb
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_(Busser::Plugin.all_runner_plugins).must_equal [
|
|
67
|
+
"busser/runner_plugin/bash",
|
|
68
|
+
"busser/runner_plugin/serverspec",
|
|
69
|
+
]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Gem.find_files searches every installed version of every gem. A machine
|
|
73
|
+
# that has installed a plugin more than once therefore reports it once per
|
|
74
|
+
# version, which made `busser test` run that suite repeatedly and
|
|
75
|
+
# `busser plugin list` print it repeatedly.
|
|
76
|
+
it "reports a plugin once when several versions of its gem are installed" do
|
|
77
|
+
stub_found_files %w{
|
|
78
|
+
/gems/busser-bash-0.1.1/lib/busser/runner_plugin/bash.rb
|
|
79
|
+
/gems/busser-bash-0.1.0/lib/busser/runner_plugin/bash.rb
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_(Busser::Plugin.all_runner_plugins)
|
|
83
|
+
.must_equal ["busser/runner_plugin/bash"]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "keeps the first occurrence, which is the newest version found" do
|
|
87
|
+
stub_found_files %w{
|
|
88
|
+
/gems/busser-bash-0.1.1/lib/busser/runner_plugin/bash.rb
|
|
89
|
+
/gems/busser-bash-0.1.0/lib/busser/runner_plugin/bash.rb
|
|
90
|
+
/gems/busser-serverspec-0.5.0/lib/busser/runner_plugin/serverspec.rb
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_(Busser::Plugin.all_runner_plugins).must_equal [
|
|
94
|
+
"busser/runner_plugin/bash",
|
|
95
|
+
"busser/runner_plugin/serverspec",
|
|
96
|
+
]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "returns nothing when no plugins are installed" do
|
|
100
|
+
stub_found_files []
|
|
101
|
+
|
|
102
|
+
_(Busser::Plugin.all_runner_plugins).must_equal []
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def stub_found_files(files)
|
|
106
|
+
Gem.expects(:find_files)
|
|
107
|
+
.with("busser/runner_plugin/*.rb")
|
|
108
|
+
.returns(files)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe ".require!" do
|
|
113
|
+
|
|
114
|
+
it "requires the given path" do
|
|
115
|
+
Busser::Plugin.expects(:require).with("busser/runner_plugin/bash")
|
|
116
|
+
|
|
117
|
+
Busser::Plugin.require!("busser/runner_plugin/bash")
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# A plugin gem that is listed but not loadable is a common failure on a
|
|
121
|
+
# test instance, and the message is the only clue the user gets.
|
|
122
|
+
it "dies with the offending path when the plugin cannot be loaded" do
|
|
123
|
+
Busser::Plugin.stubs(:require).raises(LoadError, "no such file")
|
|
124
|
+
Busser::UI.expects(:die).with do |message|
|
|
125
|
+
message.include?("busser/runner_plugin/nope") &&
|
|
126
|
+
message.include?("LoadError") &&
|
|
127
|
+
message.include?("no such file")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
Busser::Plugin.require!("busser/runner_plugin/nope")
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|