busser 0.9.1 → 0.9.2

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.
@@ -14,10 +14,19 @@ After do
14
14
  end
15
15
  end
16
16
 
17
+ # Stashes an environment variable so a scenario can change it and have the
18
+ # original put back afterwards.
19
+ #
20
+ # @param key [String] the variable name
21
+ # @return [String, nil] the stashed value
17
22
  def backup_envvar(key)
18
23
  ENV["_CUKE_#{key}"] = ENV[key]
19
24
  end
20
25
 
26
+ # Puts back a variable stashed by {backup_envvar}.
27
+ #
28
+ # @param key [String] the variable name
29
+ # @return [String, nil] the restored value
21
30
  def restore_envvar(key)
22
31
  ENV[key] = ENV.delete("_CUKE_#{key}")
23
32
  end
@@ -29,22 +29,41 @@ module Busser
29
29
 
30
30
  module_function
31
31
 
32
+ # Path to the suites directory, or to one suite inside it.
33
+ #
34
+ # @param name [String, nil] a suite name, or nil for the containing
35
+ # directory
36
+ # @return [Pathname] absolute path beneath the Busser root
32
37
  def suite_path(name = nil)
33
38
  path = root_path + "suites"
34
39
  path += name if name
35
40
  path.expand_path
36
41
  end
37
42
 
43
+ # Path to the vendor directory, or to one vendored product inside it.
44
+ #
45
+ # @param product [String, nil] a product name, or nil for the containing
46
+ # directory
47
+ # @return [Pathname] absolute path beneath the Busser root
38
48
  def vendor_path(product = nil)
39
49
  path = root_path + "vendor"
40
50
  path += product if product
41
51
  path.expand_path
42
52
  end
43
53
 
54
+ # The Busser root, where plugins, suites and vendored products live.
55
+ #
56
+ # @return [Pathname] BUSSER_ROOT if set, otherwise /opt/busser
44
57
  def root_path
45
58
  Pathname.new(ENV["BUSSER_ROOT"] || "/opt/busser")
46
59
  end
47
60
 
61
+ # No longer supported. Kept so a plugin still calling it warns rather
62
+ # than dying with a NoMethodError halfway through a test run.
63
+ #
64
+ # @param config [Hash] ignored
65
+ # @return [void]
66
+ # @deprecated Shell out or use a Thor action instead.
48
67
  def chef_apply(config = {}, &block)
49
68
  warn "Apologies, but Busser no longer supports the chef_apply helper," +
50
69
  " so the contents of this block will not be executed. Please refactor" +
@@ -52,6 +71,11 @@ module Busser
52
71
  " strategy"
53
72
  end
54
73
 
74
+ # Installs a gem into the Busser root's gem home.
75
+ #
76
+ # @param gem [String] the gem name
77
+ # @param version [String, nil] a requirement string, or nil for any version
78
+ # @return [Gem::Specification, nil] the spec that was installed
55
79
  def install_gem(gem, version = nil)
56
80
  Busser::RubyGems.install_gem(gem, version)
57
81
  end
data/lib/busser/plugin.rb CHANGED
@@ -17,6 +17,7 @@
17
17
 
18
18
  module Busser
19
19
 
20
+ # Namespace that runner plugins define their classes inside.
20
21
  module RunnerPlugin
21
22
  end
22
23
 
@@ -28,10 +29,17 @@ module Busser
28
29
 
29
30
  module_function
30
31
 
32
+ # @param plugin_name [String] short plugin name, such as "bash"
33
+ # @return [String] the path to require for that plugin
31
34
  def runner_plugin(plugin_name)
32
35
  "busser/runner_plugin/#{plugin_name}"
33
36
  end
34
37
 
38
+ # Require paths for the named plugins, or for every installed plugin.
39
+ #
40
+ # @param plugin_names [Array<String>, String, nil] plugin names, or nil for
41
+ # everything installed
42
+ # @return [Array<String>] require paths, without duplicates
35
43
  def runner_plugins(plugin_names = nil)
36
44
  if plugin_names
37
45
  Array(plugin_names).map { |plugin| runner_plugin(plugin) }.uniq
@@ -46,33 +54,67 @@ module Busser
46
54
  # duplicates made `busser test` run a suite twice and `busser plugin list`
47
55
  # print it twice. The path is what gets required, and require resolves to
48
56
  # the active version, so collapsing the repeats is safe.
57
+ # Require paths for every runner plugin installed on this machine.
58
+ #
59
+ # @return [Array<String>] require paths, without duplicates
49
60
  def all_runner_plugins
50
61
  Gem.find_files("busser/runner_plugin/*.rb").map do |file|
51
62
  "busser/runner_plugin/#{File.basename(file).sub(/\.rb$/, "")}"
52
63
  end.uniq
53
64
  end
54
65
 
66
+ # Requires a plugin, exiting with a readable message rather than a
67
+ # backtrace if it cannot be loaded.
68
+ #
69
+ # @param plugin_path [String] the path to require
70
+ # @return [void]
55
71
  def require!(plugin_path)
56
72
  require plugin_path
57
73
  rescue LoadError => e
58
74
  Busser::UI.die "Could not load #{plugin_path} (#{e.class}: #{e.message})"
59
75
  end
60
76
 
77
+ # @param klass [String, Symbol] a constant name inside
78
+ # {Busser::RunnerPlugin}
79
+ # @return [Class] the runner plugin class
61
80
  def runner_class(klass)
62
81
  Busser::RunnerPlugin.const_get(klass)
63
82
  end
64
83
 
84
+ # Finds the gemspec a plugin was loaded from.
85
+ #
86
+ # A plugin being developed locally is not an installed gem, so the local
87
+ # gemspec is preferred when the plugin resolves inside the working tree.
88
+ #
89
+ # @param plugin_path [String] the plugin's require path
90
+ # @return [Gem::Specification] the spec the plugin belongs to
65
91
  def gem_from_path(plugin_path)
66
- local_gem_path = "#{File.expand_path(plugin_path, $LOAD_PATH.first)}"
67
- local_gemspec = File.join(
68
- File.dirname($LOAD_PATH.first), "busser.gemspec"
69
- )
92
+ # Ask RubyGems first. Loading a gemspec *evaluates* it, and these
93
+ # gemspecs shell out to `git ls-files` to build their file list -- so
94
+ # asking the working tree first printed "fatal: not a git repository"
95
+ # into the middle of `busser plugin list` for every installed plugin.
96
+ # find_by_path answers from the installed specs without running anything.
97
+ Gem::Specification.find_by_path(plugin_path) ||
98
+ local_gemspec_for(plugin_path)
99
+ end
70
100
 
71
- if ! Dir.glob("#{local_gem_path}#{Gem.suffix_pattern}").empty?
72
- Gem::Specification.load(File.expand_path(local_gemspec))
73
- else
74
- Gem::Specification.find_by_path(plugin_path)
75
- end
101
+ # Falls back to a gemspec in the working tree, which is how a plugin being
102
+ # developed locally -- and so not installed as a gem -- is resolved.
103
+ #
104
+ # @param plugin_path [String] the plugin's require path
105
+ # @return [Gem::Specification, nil] the spec, or nil if there is no local
106
+ # gemspec to read
107
+ def local_gemspec_for(plugin_path)
108
+ root = $LOAD_PATH.first
109
+ return nil if root.nil?
110
+
111
+ local_gem_path = File.expand_path(plugin_path, root)
112
+ return nil if Dir.glob("#{local_gem_path}#{Gem.suffix_pattern}").empty?
113
+
114
+ local_gemspec = File.join(File.dirname(root), "busser.gemspec")
115
+ return nil unless File.exist?(local_gemspec)
116
+
117
+ Gem::Specification.load(local_gemspec)
76
118
  end
77
119
  end
78
120
  end
@@ -27,11 +27,24 @@ module Busser
27
27
 
28
28
  module_function
29
29
 
30
+ # @param name [String] the gem name
31
+ # @param version [String, nil] a requirement string, or nil for any version
32
+ # @return [Boolean] true if a matching gem is already available
30
33
  def gem_installed?(name, version)
31
34
  version = Gem::Requirement.default unless version
32
35
  ! Gem::Dependency.new(name, version).matching_specs.empty?
33
36
  end
34
37
 
38
+ # Installs a gem into GEM_HOME.
39
+ #
40
+ # RubyGems under bundler points Gem.dir at the bundle, which is not where
41
+ # Busser plugins belong, so GEM_HOME is applied explicitly before the
42
+ # install and the freshly installed spec is put on the load path by hand.
43
+ #
44
+ # @param gem_name [String] the gem name
45
+ # @param version [String, nil] a requirement string, or nil for any version
46
+ # @return [Gem::Specification, nil] the installed spec, or nil if the gem
47
+ # was not among those installed
35
48
  def install_gem(gem_name, version)
36
49
  version = Gem::Requirement.default unless version
37
50
 
@@ -54,6 +67,8 @@ module Busser
54
67
  spec
55
68
  end
56
69
 
70
+ # @return [Hash] options handed to RubyGems' dependency installer, with
71
+ # the install directory pinned to GEM_HOME
57
72
  def rbg_options
58
73
  @rbg_options ||= Gem::DependencyInstaller::DEFAULT_OPTIONS.merge(
59
74
  suggest_alternate: false,
@@ -67,6 +82,11 @@ module Busser
67
82
  )
68
83
  end
69
84
 
85
+ # Runs a block with RubyGems' own progress output suppressed, unless the
86
+ # user asked for verbose output.
87
+ #
88
+ # @yield the block to run quietly
89
+ # @return [Object] whatever the block returned
70
90
  def silence_gem_ui
71
91
  interaction = Gem::DefaultUserInteraction.ui
72
92
  unless Gem.configuration.really_verbose
@@ -34,6 +34,9 @@ class Busser::RunnerPlugin::Dummy < Busser::RunnerPlugin::Base
34
34
  create_file("#{dummy_path}/foobar.txt", "The Dummy Driver.")
35
35
  end
36
36
 
37
+ # Prints a line so Busser's own suite can prove a plugin ran.
38
+ #
39
+ # @return [void]
37
40
  def test
38
41
  banner "[dummy] Running"
39
42
  if File.exist?(File.join(suite_path("dummy"), "foobar.txt"))
@@ -27,6 +27,11 @@ module Busser
27
27
  #
28
28
  class Base < Busser::Thor::BaseGroup
29
29
 
30
+ # Declares work to run once, when Busser installs this plugin -- which
31
+ # is where a plugin installs the test framework it drives.
32
+ #
33
+ # @yield the postinstall body, evaluated on the plugin instance
34
+ # @return [void]
30
35
  def self.postinstall(&block)
31
36
  (class << self; self; end).send(:define_method, :run_postinstall) do
32
37
  klass = Class.new(Busser::Thor::BaseGroup) do
data/lib/busser/thor.rb CHANGED
@@ -22,6 +22,7 @@ require "busser/ui"
22
22
 
23
23
  module Busser
24
24
 
25
+ # Thor base classes preloaded with Busser's helpers and output methods.
25
26
  module Thor
26
27
 
27
28
  # Base class for all Thor subclasses which includes useful mixins.
@@ -33,6 +34,17 @@ module Busser
33
34
  include Helpers
34
35
  include UI
35
36
  include ::Thor::Actions
37
+
38
+ # Thor exits 0 when a command fails unless this is true, and warns on
39
+ # every failure that it is not set. Busser is a test runner: a failure
40
+ # has to be a non-zero exit or CI reports a red suite as green. Thor 2
41
+ # makes this the default; setting it now silences the deprecation on
42
+ # every failing run and pins the behaviour we already rely on.
43
+ #
44
+ # @return [true]
45
+ def self.exit_on_failure?
46
+ true
47
+ end
36
48
  end
37
49
 
38
50
  # Base class for all Thor Group subclasses which includes useful mixins.
@@ -44,6 +56,17 @@ module Busser
44
56
  include Helpers
45
57
  include UI
46
58
  include ::Thor::Actions
59
+
60
+ # Thor exits 0 when a command fails unless this is true, and warns on
61
+ # every failure that it is not set. Busser is a test runner: a failure
62
+ # has to be a non-zero exit or CI reports a red suite as green. Thor 2
63
+ # makes this the default; setting it now silences the deprecation on
64
+ # every failing run and pins the behaviour we already rely on.
65
+ #
66
+ # @return [true]
67
+ def self.exit_on_failure?
68
+ true
69
+ end
47
70
  end
48
71
  end
49
72
  end
data/lib/busser/ui.rb CHANGED
@@ -29,30 +29,56 @@ module Busser
29
29
 
30
30
  # Thor::Shell's delegated methods are not mixed into this module, so
31
31
  # provide the two output primitives it relies on.
32
+ # @param msg [String] text to write to stdout
33
+ # @return [void]
32
34
  def say(msg)
33
35
  $stdout.puts(msg)
34
36
  end
35
37
 
38
+ # @param msg [String] text to write to stderr
39
+ # @return [void]
36
40
  def error(msg)
37
41
  $stderr.puts(msg)
38
42
  end
39
43
 
44
+ # Announces a step, at the top level of the output.
45
+ #
46
+ # @param msg [String] the message
47
+ # @return [void]
40
48
  def banner(msg)
41
49
  say("-----> #{msg}")
42
50
  end
43
51
 
52
+ # Reports detail beneath a banner.
53
+ #
54
+ # @param msg [String] the message
55
+ # @return [void]
44
56
  def info(msg)
45
57
  say(" #{msg}")
46
58
  end
47
59
 
60
+ # Reports something the user should notice but which is not fatal.
61
+ #
62
+ # @param msg [String] the message
63
+ # @return [void]
48
64
  def warn(msg)
49
65
  say(">>>>>> #{msg}")
50
66
  end
51
67
 
68
+ # Reports a failure, on stderr.
69
+ #
70
+ # @param msg [String] the message
71
+ # @return [void]
52
72
  def fatal(msg)
53
73
  error("!!!!!! #{msg}")
54
74
  end
55
75
 
76
+ # Runs a shell command, exiting with a diagnosis if it fails.
77
+ #
78
+ # @param cmd [String] the command line
79
+ # @param config [Hash] options passed through to Thor's runner
80
+ # @return [true] if the command succeeded
81
+ # @see #handle_command
56
82
  def run!(cmd, config = {})
57
83
  config = { capture: false, verbose: false }.merge(config)
58
84
 
@@ -61,6 +87,13 @@ module Busser
61
87
  end
62
88
  end
63
89
 
90
+ # Runs a Ruby script with the current interpreter, exiting with a
91
+ # diagnosis if it fails.
92
+ #
93
+ # @param cmd [String] the script and its arguments
94
+ # @param config [Hash] options passed through to Thor's runner
95
+ # @return [true] if the script succeeded
96
+ # @see #handle_command
64
97
  def run_ruby_script!(cmd, config = {})
65
98
  config = { capture: false, verbose: false }.merge(config)
66
99
 
@@ -69,15 +102,37 @@ module Busser
69
102
  end
70
103
  end
71
104
 
105
+ # Reports a failure and exits.
106
+ #
107
+ # @param msg [String] the message
108
+ # @param exitstatus [Integer] the status to exit with
109
+ # @return [void] does not return
72
110
  def die(msg, exitstatus = 1)
73
111
  fatal(msg)
74
112
  exit(exitstatus)
75
113
  end
76
114
 
115
+ # Wrapped so tests can stub it.
116
+ #
117
+ # @return [Process::Status, nil] the status of the last child process
77
118
  def status
78
119
  $?
79
120
  end
80
121
 
122
+ # Runs a block and turns however the child process ended into a readable
123
+ # message and a matching exit status.
124
+ #
125
+ # Three endings are distinguished because they mean different things to
126
+ # someone reading CI output: a nil status usually means the machine ran out
127
+ # of memory before the child could report; a signal means something killed
128
+ # the run, typically the out of memory killer; and an exit code means the
129
+ # command itself failed.
130
+ #
131
+ # @param type [String] what was run, for the message
132
+ # @param cmd [String] the command line, for the message
133
+ # @yield runs the command
134
+ # @return [true] if the command succeeded
135
+ # @raise [StandardError] re-raised if the block itself raised
81
136
  def handle_command(type, cmd)
82
137
  begin
83
138
  yield
@@ -16,5 +16,6 @@
16
16
  # limitations under the License.
17
17
 
18
18
  module Busser
19
- VERSION = "0.9.1".freeze
19
+ # Version string for Busser
20
+ VERSION = "0.9.2".freeze
20
21
  end
@@ -7,7 +7,9 @@
7
7
  "changelog-path": "CHANGELOG.md",
8
8
  "release-type": "ruby",
9
9
  "include-component-in-tag": false,
10
- "version-file": "lib/busser/version.rb"
10
+ "version-file": "lib/busser/version.rb",
11
+ "bump-minor-pre-major": true,
12
+ "bump-patch-for-minor-pre-major": true
11
13
  }
12
14
  }
13
15
  }
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  #
3
2
  # Licensed under the Apache License, Version 2.0 (the "License");
4
3
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  #
3
2
  # Licensed under the Apache License, Version 2.0 (the "License");
4
3
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,44 @@
1
+ require_relative "../../spec_helper"
2
+
3
+ require "busser/command/plugin_install"
4
+
5
+ describe Busser::Command::PluginInstall do
6
+ let(:command) { Busser::Command::PluginInstall.new([%w{busser-dummy}]) }
7
+
8
+ describe "#drop_ssl_verify_peer" do
9
+ # VERIFY_PEER is a process-global constant, so anything that leaves it
10
+ # lowered affects every later gem download in the same run. `busser plugin
11
+ # install` takes a list of plugins, which is exactly that situation.
12
+ it "lowers verification for the block" do
13
+ inside = nil
14
+ command.send(:drop_ssl_verify_peer) { inside = OpenSSL::SSL::VERIFY_PEER }
15
+
16
+ _(inside).must_equal OpenSSL::SSL::VERIFY_NONE
17
+ end
18
+
19
+ it "restores verification afterwards" do
20
+ before = OpenSSL::SSL::VERIFY_PEER
21
+ command.send(:drop_ssl_verify_peer) { nil }
22
+
23
+ _(OpenSSL::SSL::VERIFY_PEER).must_equal before
24
+ end
25
+
26
+ # The regression this guards. A postinstall raising is not exotic: it is
27
+ # how a plugin reports that it could not install its test framework.
28
+ it "restores verification when the block raises" do
29
+ before = OpenSSL::SSL::VERIFY_PEER
30
+
31
+ _(proc { command.send(:drop_ssl_verify_peer) { raise "postinstall blew up" } })
32
+ .must_raise RuntimeError
33
+
34
+ _(OpenSSL::SSL::VERIFY_PEER).must_equal before
35
+ end
36
+
37
+ it "restores verification when the block throws" do
38
+ before = OpenSSL::SSL::VERIFY_PEER
39
+ catch(:done) { command.send(:drop_ssl_verify_peer) { throw :done } }
40
+
41
+ _(OpenSSL::SSL::VERIFY_PEER).must_equal before
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,49 @@
1
+ require_relative "../../spec_helper"
2
+
3
+ require "busser/command/plugin_list"
4
+
5
+ describe Busser::Command::PluginList do
6
+ let(:command) { Busser::Command::PluginList.new }
7
+
8
+ describe "#plugin_data" do
9
+ def stub_plugins(paths, specs = {})
10
+ Busser::Plugin.stubs(:runner_plugins).returns(paths)
11
+ paths.each do |path|
12
+ Busser::Plugin.stubs(:gem_from_path).with(path).returns(specs[path])
13
+ end
14
+ end
15
+
16
+ def spec_for(name, version)
17
+ Gem::Specification.new { |s| s.name = name; s.version = version }
18
+ end
19
+
20
+ it "reports each plugin's short name and version" do
21
+ stub_plugins(["busser/runner_plugin/bash"],
22
+ "busser/runner_plugin/bash" => spec_for("busser-bash", "0.2.0"))
23
+
24
+ _(command.send(:plugin_data)).must_equal [["bash", Gem::Version.new("0.2.0")]]
25
+ end
26
+
27
+ # dummy is a fixture shipped inside busser for its own tests, not something
28
+ # anyone installed. `busser test` already passes over it, so listing it was
29
+ # inconsistent as well as confusing.
30
+ it "leaves out the internal dummy runner" do
31
+ stub_plugins(["busser/runner_plugin/dummy", "busser/runner_plugin/bash"],
32
+ "busser/runner_plugin/bash" => spec_for("busser-bash", "0.2.0"))
33
+
34
+ _(command.send(:plugin_data).map(&:first)).must_equal %w{bash}
35
+ end
36
+
37
+ it "reports a nil version rather than raising when no spec is found" do
38
+ stub_plugins(["busser/runner_plugin/bash"])
39
+
40
+ _(command.send(:plugin_data)).must_equal [["bash", nil]]
41
+ end
42
+
43
+ it "returns an empty list when dummy is all there is" do
44
+ stub_plugins(["busser/runner_plugin/dummy"])
45
+
46
+ _(command.send(:plugin_data)).must_be_empty
47
+ end
48
+ end
49
+ end
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  #
3
2
  # Licensed under the Apache License, Version 2.0 (the "License");
4
3
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,36 @@
1
+ require_relative "../../spec_helper"
2
+
3
+ require "shellwords"
4
+ require "busser/command/test"
5
+
6
+ describe Busser::Command::Test do
7
+ describe ".prepare_sh_command" do
8
+ it "runs the script with sh" do
9
+ cmd = Busser::Command::Test.prepare_sh_command("/opt/busser/suites/bats/prepare.sh")
10
+
11
+ _(Shellwords.split(cmd)).must_equal ["/bin/sh", "/opt/busser/suites/bats/prepare.sh"]
12
+ end
13
+
14
+ # BUSSER_ROOT is chosen by whoever runs Busser, and Test Kitchen puts it
15
+ # under a path the user controls. Unquoted, a space split the path and sh
16
+ # was handed a fragment.
17
+ it "quotes a path containing spaces" do
18
+ cmd = Busser::Command::Test.prepare_sh_command("/tmp/my tests/suites/bats/prepare.sh")
19
+
20
+ _(Shellwords.split(cmd))
21
+ .must_equal ["/bin/sh", "/tmp/my tests/suites/bats/prepare.sh"]
22
+ end
23
+
24
+ it "neutralises shell metacharacters in the path" do
25
+ cmd = Busser::Command::Test.prepare_sh_command("/tmp/a;touch pwned/prepare.sh")
26
+
27
+ _(Shellwords.split(cmd)).must_equal ["/bin/sh", "/tmp/a;touch pwned/prepare.sh"]
28
+ end
29
+
30
+ it "accepts a Pathname" do
31
+ cmd = Busser::Command::Test.prepare_sh_command(Pathname.new("/a/prepare.sh"))
32
+
33
+ _(Shellwords.split(cmd).last).must_equal "/a/prepare.sh"
34
+ end
35
+ end
36
+ end
@@ -1,6 +1,6 @@
1
- require_relative '../spec_helper'
1
+ require_relative "../spec_helper"
2
2
 
3
- require 'busser/helpers'
3
+ require "busser/helpers"
4
4
 
5
5
  describe Busser::Helpers do
6
6
 
@@ -25,16 +25,16 @@ describe Busser::Helpers do
25
25
 
26
26
  describe "with a custom root path" do
27
27
 
28
- before { ENV['_SPEC_BUSSER_ROOT'] = ENV['BUSSER_ROOT'] }
29
- after { ENV['BUSSER_ROOT'] = ENV.delete('_SPEC_BUSSER_ROOT') }
28
+ before { ENV["_SPEC_BUSSER_ROOT"] = ENV["BUSSER_ROOT"] }
29
+ after { ENV["BUSSER_ROOT"] = ENV.delete("_SPEC_BUSSER_ROOT") }
30
30
 
31
31
  it "returns a base path if no suite name is given" do
32
- ENV['BUSSER_ROOT'] = "/path/to/busser"
32
+ ENV["BUSSER_ROOT"] = "/path/to/busser"
33
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
- ENV['BUSSER_ROOT'] = "/path/to/busser"
37
+ ENV["BUSSER_ROOT"] = "/path/to/busser"
38
38
  _(suite_path("fuzzy").to_s).must_match %r{/path/to/busser/suites/fuzzy$}
39
39
  end
40
40
  end
@@ -59,16 +59,16 @@ describe Busser::Helpers do
59
59
 
60
60
  describe "with a custom root path" do
61
61
 
62
- before { ENV['_SPEC_BUSSER_ROOT'] = ENV['BUSSER_ROOT'] }
63
- after { ENV['BUSSER_ROOT'] = ENV.delete('_SPEC_BUSSER_ROOT') }
62
+ before { ENV["_SPEC_BUSSER_ROOT"] = ENV["BUSSER_ROOT"] }
63
+ after { ENV["BUSSER_ROOT"] = ENV.delete("_SPEC_BUSSER_ROOT") }
64
64
 
65
65
  it "returns a base path if no product name is given" do
66
- ENV['BUSSER_ROOT'] = "/path/to/busser"
66
+ ENV["BUSSER_ROOT"] = "/path/to/busser"
67
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
- ENV['BUSSER_ROOT'] = "/path/to/busser"
71
+ ENV["BUSSER_ROOT"] = "/path/to/busser"
72
72
  _(vendor_path("maximal").to_s).must_match \
73
73
  %r{/path/to/busser/vendor/maximal$}
74
74
  end
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  #
3
2
  # Licensed under the Apache License, Version 2.0 (the "License");
4
3
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
- require_relative '../spec_helper'
1
+ require_relative "../spec_helper"
2
2
 
3
- require 'busser/ui'
3
+ require "busser/ui"
4
4
 
5
5
  # Dummy class containing diagnostic methods approximating Thor mixins
6
6
  class SneakyUI
@@ -11,7 +11,7 @@ class SneakyUI
11
11
  attr_accessor :status
12
12
 
13
13
  def say(msg)
14
- msg
14
+ msg
15
15
  end
16
16
 
17
17
  def error(msg)
@@ -111,7 +111,7 @@ describe Busser::UI do
111
111
 
112
112
  _(ui.run_args).must_equal([
113
113
  "doitpls",
114
- { :capture => false, :verbose => false}
114
+ { capture: false, verbose: false },
115
115
  ])
116
116
  end
117
117
 
@@ -181,16 +181,16 @@ describe Busser::UI do
181
181
 
182
182
  _(ui.run_ruby_script_args).must_equal([
183
183
  "theworks.rb",
184
- { :capture => false, :verbose => false }
184
+ { capture: false, verbose: false },
185
185
  ])
186
186
  end
187
187
 
188
188
  it "calls #run_ruby_script with correct default options" do
189
- ui.invoke_run_ruby_script!("theworks.rb", :verbose => true)
189
+ ui.invoke_run_ruby_script!("theworks.rb", verbose: true)
190
190
 
191
191
  _(ui.run_ruby_script_args).must_equal([
192
192
  "theworks.rb",
193
- { :capture => false, :verbose => true }
193
+ { capture: false, verbose: true },
194
194
  ])
195
195
  end
196
196