[DRE-commits] [ruby-guard] 03/08: remove due to import upstream source with specs

Daisuke Higuchi dai at moszumanska.debian.org
Thu Jan 4 09:39:55 UTC 2018


This is an automated email from the git hooks/post-receive script.

dai pushed a commit to branch master
in repository ruby-guard.

commit 82d59c6ac04638e578721a44b057e94572d2babb
Author: HIGUCHI Daisuke (VDR dai) <dai at debian.org>
Date:   Thu Jan 4 18:22:07 2018 +0900

    remove due to import upstream source with specs
---
 debian/patches/add_specs.patch | 7722 ----------------------------------------
 debian/patches/series          |    1 -
 2 files changed, 7723 deletions(-)

diff --git a/debian/patches/add_specs.patch b/debian/patches/add_specs.patch
deleted file mode 100644
index c2d03c3..0000000
--- a/debian/patches/add_specs.patch
+++ /dev/null
@@ -1,7722 +0,0 @@
-Description: add specs
-Author: HIGUCHI Daisuke (VDR dai) <dai at debian.org>
-Origin: upstream
-Forwarded: not-needed
-Last-Update: 2017-11-28
-
-Index: ruby-guard/spec/.gitignore
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/.gitignore
-@@ -0,0 +1 @@
-+/fake-home/
-Index: ruby-guard/spec/lib/guard/bin_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/bin_spec.rb
-@@ -0,0 +1,137 @@
-+path = File.expand_path("../../../../bin/guard", __FILE__)
-+load path
-+
-+RSpec.describe GuardReloader do
-+  let(:config) { instance_double(described_class::Config) }
-+
-+  subject { described_class.new(config) }
-+
-+  let(:guard_core_path) { "/home/me/.rvm/gems/ruby-2.2.2/bin/_guard-core" }
-+
-+  before do
-+    allow(described_class::Config).to receive(:new).and_return(config)
-+
-+    allow(config).to receive(:current_bundler_gemfile).
-+      and_return(bundle_gemfile_env)
-+
-+    allow(config).to receive(:using_bundler?).and_return(bundle_gemfile_env)
-+    allow(config).to receive(:guard_core_path).and_return(guard_core_path)
-+
-+    allow(config).to receive(:program_arguments).and_return(%w(foo bar baz))
-+    allow(config).to receive(:using_rubygems?).and_return(rubygems_deps_env)
-+    allow(config).to receive(:program_path).and_return(program_path)
-+  end
-+
-+  let(:program_path) { Pathname("/home/me/.rvm/gems/ruby-2.2.2/bin/guard") }
-+  let(:rubygems_deps_env) { nil } # or any gemfile path
-+
-+  context "when running with bundler" do
-+    let(:bundle_gemfile_env) { "./Gemfile" }
-+
-+    it "sets up bundler" do
-+      expect(config).to receive(:setup_bundler)
-+      subject.setup
-+    end
-+  end
-+
-+  context "when not running with bundler" do
-+    let(:bundle_gemfile_env) { nil }
-+
-+    context "when running with rubygems_gemdeps" do
-+      let(:rubygems_deps_env) { "-" } # or any gemfile path
-+
-+      it "sets up rubygems" do
-+        expect(config).to receive(:setup_rubygems_for_deps)
-+        subject.setup
-+      end
-+    end
-+
-+    context "when not running with rubygems_gemdeps" do
-+      let(:rubygems_deps_env) { nil }
-+
-+      context "when running as binstub" do
-+        let(:program_path) { Pathname("/my/project/bin/guard") }
-+
-+        context "when the relative Gemfile exists" do
-+          before do
-+            allow(config).to receive(:exist?).
-+              with(Pathname("/my/project/Gemfile")).and_return(true)
-+
-+            allow(config).to receive(:setup_bundler)
-+            allow(config).to receive(:setup_bundler_env)
-+          end
-+
-+          it "sets up bundler" do
-+            expect(config).to receive(:setup_bundler)
-+            subject.setup
-+          end
-+
-+          it "sets the Gemfile" do
-+            expect(config).to receive(:setup_bundler_env).
-+              with("/my/project/Gemfile")
-+            subject.setup
-+          end
-+        end
-+
-+        context "when the relative Gemfile does not exist" do
-+          before do
-+            allow(config).to receive(:exist?).
-+              with(Pathname("/my/project/Gemfile")).and_return(false)
-+
-+            allow(config).to receive(:exist?).with(Pathname("Gemfile")).
-+              and_return(false)
-+          end
-+
-+          it "does not setup bundler" do
-+            subject.setup
-+          end
-+
-+          it "does not setup rubygems" do
-+            subject.setup
-+          end
-+
-+          it "shows no warning" do
-+            expect(STDERR).to_not receive(:puts)
-+            subject.setup
-+          end
-+        end
-+      end
-+
-+      context "when not run as binstub" do
-+        let(:program_path) do
-+          Pathname("/home/me/.rvm/gems/ruby-2.2.2/bin/guard")
-+        end
-+
-+        before do
-+          allow(config).to receive(:exist?).with(
-+            Pathname("/home/me/.rvm/gems/ruby-2.2.2/Gemfile")
-+          ).and_return(false)
-+        end
-+
-+        context "when Gemfile exists" do
-+          before do
-+            allow(config).to receive(:exist?).with(Pathname("Gemfile")).
-+              and_return(true)
-+          end
-+
-+          it "shows a warning" do
-+            expect(STDERR).to receive(:puts).with(/Warning: you have a Gemfile/)
-+            subject.setup
-+          end
-+        end
-+
-+        context "when no Gemfile exists" do
-+          before do
-+            allow(config).to receive(:exist?).with(Pathname("Gemfile")).
-+              and_return(false)
-+          end
-+
-+          it "shows no warning" do
-+            expect(STDERR).to_not receive(:puts)
-+            subject.setup
-+          end
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/cli/environments/bundler_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/cli/environments/bundler_spec.rb
-@@ -0,0 +1,60 @@
-+require "guard/cli/environments/bundler"
-+
-+# TODO: instead of shared examples, use have_received if possible
-+RSpec.shared_examples "avoids Bundler warning" do
-+  it "does not show the Bundler warning" do
-+    expect(Guard::UI).to_not have_received(:info).with(/Guard here!/)
-+  end
-+end
-+
-+RSpec.shared_examples "shows Bundler warning" do
-+  it "shows the Bundler warning" do
-+    expect(Guard::UI).to have_received(:info).with(/Guard here!/)
-+  end
-+end
-+
-+RSpec.describe Guard::Cli::Environments::Bundler do
-+  describe "#verify" do
-+    let(:gemdeps) { nil }
-+    let(:gemfile) { nil }
-+
-+    before do
-+      allow(ENV).to receive(:[]).with("BUNDLE_GEMFILE").and_return(gemfile)
-+      allow(ENV).to receive(:[]).with("RUBYGEMS_GEMDEPS").and_return(gemdeps)
-+
-+      allow(File).to receive(:exist?).with("Gemfile").
-+        and_return(gemfile_present)
-+
-+      subject.verify
-+    end
-+
-+    context "without an existing Gemfile" do
-+      let(:gemfile_present) { false }
-+      include_examples "avoids Bundler warning"
-+    end
-+
-+    context "with an existing Gemfile" do
-+      let(:gemfile_present) { true }
-+
-+      context "with Bundler" do
-+        let(:gemdeps) { nil }
-+        let(:gemfile) { "Gemfile" }
-+        include_examples "avoids Bundler warning"
-+      end
-+
-+      context "without Bundler" do
-+        let(:gemfile) { nil }
-+
-+        context "with Rubygems Gemfile autodetection or custom Gemfile" do
-+          let(:gemdeps) { "-" }
-+          include_examples "avoids Bundler warning"
-+        end
-+
-+        context "without Rubygems Gemfile handling" do
-+          let(:gemdeps) { nil }
-+          include_examples "shows Bundler warning"
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/cli/environments/evaluate_only_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/cli/environments/evaluate_only_spec.rb
-@@ -0,0 +1,73 @@
-+require "guard/cli/environments/evaluate_only"
-+
-+RSpec.describe Guard::Cli::Environments::EvaluateOnly do
-+  subject { described_class.new(options) }
-+  let(:options) { double("options") }
-+
-+  describe "#evaluate" do
-+    let(:evaluator) { instance_double("Guard::Guardfile::Evaluator") }
-+    let(:state) { instance_double("Guard::Internals::State") }
-+    let(:session) { instance_double("Guard::Internals::Session") }
-+
-+    before do
-+      allow(Guard::Guardfile::Evaluator).to receive(:new).and_return(evaluator)
-+      allow(evaluator).to receive(:evaluate)
-+      allow(Guard).to receive(:init)
-+      allow(Guard).to receive(:state).and_return(state)
-+      allow(state).to receive(:session).and_return(session)
-+      allow(session).to receive(:evaluator_options)
-+    end
-+
-+    it "calls Guard.init" do
-+      expect(Guard).to receive(:init)
-+      subject.evaluate
-+    end
-+
-+    it "initializes Guard with options" do
-+      expect(Guard).to receive(:init).with(options)
-+      subject.evaluate
-+    end
-+
-+    it "evaluates the guardfile" do
-+      expect(evaluator).to receive(:evaluate)
-+      subject.evaluate
-+    end
-+
-+    it "passes options to evaluator" do
-+      evaluator_options = double("evaluator_options")
-+      allow(session).to receive(:evaluator_options).
-+        and_return(evaluator_options)
-+
-+      expect(Guard::Guardfile::Evaluator).to receive(:new).
-+        with(evaluator_options).and_return(evaluator)
-+
-+      subject.evaluate
-+    end
-+
-+    [
-+      Guard::Dsl::Error,
-+      Guard::Guardfile::Evaluator::NoPluginsError,
-+      Guard::Guardfile::Evaluator::NoGuardfileError,
-+      Guard::Guardfile::Evaluator::NoCustomGuardfile
-+    ].each do |error_class|
-+      context "when a #{error_class} error occurs" do
-+        before do
-+          allow(Guard).to receive(:init).
-+            and_raise(error_class, "#{error_class} error!")
-+        end
-+
-+        it "aborts" do
-+          expect { subject.evaluate }.to raise_error(SystemExit)
-+        end
-+
-+        it "shows error message" do
-+          expect(Guard::UI).to receive(:error).with(/#{error_class} error!/)
-+          begin
-+            subject.evaluate
-+          rescue SystemExit
-+          end
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/cli/environments/valid_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/cli/environments/valid_spec.rb
-@@ -0,0 +1,253 @@
-+require "guard/cli/environments/valid"
-+require "guard/cli/environments/bundler"
-+
-+RSpec.describe Guard::Cli::Environments::Valid do
-+  subject { described_class.new(options) }
-+  let(:options) { double("options") }
-+
-+  before do
-+    # TODO: start should be an instance method of something
-+    allow(Guard).to receive(:start)
-+  end
-+
-+  describe "#start_guard" do
-+    let(:bundler) { instance_double("Guard::Cli::Environments::Bundler") }
-+
-+    before do
-+      allow(Guard::Cli::Environments::Bundler).to receive(:new).
-+        and_return(bundler)
-+
-+      allow(bundler).to receive(:verify)
-+    end
-+
-+    context "with a valid bundler setup" do
-+      before do
-+        allow(bundler).to receive(:verify)
-+
-+        allow(options).to receive(:[]).with(:no_bundler_warning).
-+          and_return(false)
-+      end
-+
-+      it "starts guard" do
-+        expect(Guard).to receive(:start)
-+        subject.start_guard
-+      end
-+
-+      it "start guard with options" do
-+        expect(Guard).to receive(:start).with(options)
-+        subject.start_guard
-+      end
-+
-+      it "returns exit code" do
-+        exitcode = double("exitcode")
-+        expect(Guard).to receive(:start).and_return(exitcode)
-+        expect(subject.start_guard).to be(exitcode)
-+      end
-+
-+      [
-+        Guard::Dsl::Error,
-+        Guard::Guardfile::Evaluator::NoPluginsError,
-+        Guard::Guardfile::Evaluator::NoGuardfileError,
-+        Guard::Guardfile::Evaluator::NoCustomGuardfile
-+      ].each do |error_class|
-+        context "when a #{error_class} error occurs" do
-+          before do
-+            allow(Guard).to receive(:start).
-+              and_raise(error_class, "#{error_class} error!")
-+          end
-+
-+          it "aborts" do
-+            expect { subject.start_guard }.to raise_error(SystemExit)
-+          end
-+
-+          it "shows error message" do
-+            expect(Guard::UI).to receive(:error).with(/#{error_class} error!/)
-+            begin
-+              subject.start_guard
-+            rescue SystemExit
-+            end
-+          end
-+        end
-+      end
-+    end
-+
-+    context "without no_bundler_warning option" do
-+      subject { described_class.new(no_bundler_warning: false) }
-+
-+      it "verifies bundler presence" do
-+        expect(bundler).to receive(:verify)
-+        subject.start_guard
-+      end
-+
-+      context "without a valid bundler setup" do
-+        before do
-+          allow(bundler).to receive(:verify).and_raise(SystemExit)
-+        end
-+
-+        it "does not start guard" do
-+          expect(Guard).to_not receive(:start)
-+
-+          begin
-+            subject.start_guard
-+          rescue SystemExit
-+          end
-+        end
-+      end
-+    end
-+
-+    context "with no_bundler_warning option" do
-+      subject { described_class.new(no_bundler_warning: true) }
-+
-+      it "does not verify bundler presence" do
-+        expect(bundler).to_not receive(:verify)
-+        subject.start_guard
-+      end
-+
-+      it "starts guard" do
-+        expect(Guard).to receive(:start)
-+        subject.start_guard
-+      end
-+    end
-+
-+    describe "return value" do
-+      let(:exitcode) { double("Fixnum") }
-+      subject { described_class.new(no_bundler_warning: true) }
-+
-+      before do
-+        allow(Guard).to receive(:start).and_return(exitcode)
-+      end
-+
-+      it "matches return value of Guard.start" do
-+        expect(subject.start_guard).to be(exitcode)
-+      end
-+    end
-+  end
-+
-+  describe "#initialize_guardfile" do
-+    let(:evaluator) { instance_double("Guard::Guardfile::Evaluator") }
-+    let(:generator) { instance_double("Guard::Guardfile::Generator") }
-+    let(:state) { instance_double("Guard::Internals::State") }
-+    let(:session) { instance_double("Guard::Internals::Session") }
-+
-+    before do
-+      stub_file("Gemfile")
-+
-+      allow(evaluator).to receive(:evaluate)
-+      allow(generator).to receive(:create_guardfile)
-+      allow(generator).to receive(:initialize_all_templates)
-+
-+      allow(session).to receive(:evaluator_options)
-+      allow(state).to receive(:session).and_return(session)
-+
-+      allow(Guard::Internals::State).to receive(:new).and_return(state)
-+      allow(Guard::Guardfile::Evaluator).to receive(:new).and_return(evaluator)
-+      allow(Guard::Guardfile::Generator).to receive(:new).and_return(generator)
-+    end
-+
-+    context "with bare option" do
-+      before do
-+        expect(options).to receive(:[]).with(:bare).and_return(true)
-+      end
-+
-+      it "Only creates the Guardfile without initializing any Guard template" do
-+        allow(evaluator).to receive(:evaluate).
-+          and_raise(Guard::Guardfile::Evaluator::NoGuardfileError)
-+
-+        allow(File).to receive(:exist?).with("Gemfile").and_return(false)
-+        expect(generator).to receive(:create_guardfile)
-+        expect(generator).to_not receive(:initialize_template)
-+        expect(generator).to_not receive(:initialize_all_templates)
-+
-+        subject.initialize_guardfile
-+      end
-+
-+      it "returns an exit code" do
-+        # TODO: ideally, we'd capture known exceptions and return nonzero
-+        expect(subject.initialize_guardfile).to be_zero
-+      end
-+    end
-+
-+    context "with no bare option" do
-+      before do
-+        expect(options).to receive(:[]).with(:bare).and_return(false)
-+      end
-+
-+      it "evaluates created or existing guardfile" do
-+        expect(evaluator).to receive(:evaluate)
-+        subject.initialize_guardfile
-+      end
-+
-+      it "creates a Guardfile" do
-+        expect(evaluator).to receive(:evaluate).
-+          and_raise(Guard::Guardfile::Evaluator::NoGuardfileError).once
-+        expect(evaluator).to receive(:evaluate)
-+
-+        expect(Guard::Guardfile::Generator).to receive(:new).
-+          and_return(generator)
-+        expect(generator).to receive(:create_guardfile)
-+
-+        subject.initialize_guardfile
-+      end
-+
-+      it "initializes templates of all installed Guards" do
-+        allow(File).to receive(:exist?).with("Gemfile").and_return(false)
-+
-+        expect(generator).to receive(:initialize_all_templates)
-+
-+        subject.initialize_guardfile
-+      end
-+
-+      it "initializes each passed template" do
-+        allow(File).to receive(:exist?).with("Gemfile").and_return(false)
-+
-+        expect(generator).to receive(:initialize_template).with("rspec")
-+        expect(generator).to receive(:initialize_template).with("pow")
-+
-+        subject.initialize_guardfile(%w(rspec pow))
-+      end
-+
-+      context "when passed a guard name" do
-+        context "when the Guardfile is empty" do
-+          before do
-+            allow(evaluator).to receive(:evaluate).
-+              and_raise Guard::Guardfile::Evaluator::NoPluginsError
-+            allow(generator).to receive(:initialize_template)
-+          end
-+
-+          it "works without without errors" do
-+            expect(subject.initialize_guardfile(%w(rspec))).to be_zero
-+          end
-+
-+          it "adds the template" do
-+            expect(generator).to receive(:initialize_template).with("rspec")
-+            subject.initialize_guardfile(%w(rspec))
-+          end
-+        end
-+
-+        it "initializes the template of the passed Guard" do
-+          expect(generator).to receive(:initialize_template).with("rspec")
-+          subject.initialize_guardfile(%w(rspec))
-+        end
-+      end
-+
-+      it "returns an exit code" do
-+        expect(subject.initialize_guardfile).to be_zero
-+      end
-+
-+      context "when passed an unknown guard name" do
-+        before do
-+          expect(generator).to receive(:initialize_template).with("foo").
-+            and_raise(Guard::Guardfile::Generator::NoSuchPlugin, "foo")
-+        end
-+
-+        it "returns an exit code" do
-+          expect(::Guard::UI).to receive(:error).with(
-+            "Could not load 'guard/foo' or '~/.guard/templates/foo'"\
-+            " or find class Guard::Foo\n"
-+          )
-+          expect(subject.initialize_guardfile(%w(foo))).to be(1)
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/cli_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/cli_spec.rb
-@@ -0,0 +1,155 @@
-+require "guard/cli"
-+
-+RSpec.describe Guard::CLI do
-+  let(:valid_environment) { instance_double("Guard::Cli::Environments::Valid") }
-+  let(:bare_environment) do
-+    instance_double("Guard::Cli::Environments::EvaluateOnly")
-+  end
-+
-+  let(:dsl_describer) { instance_double("Guard::DslDescriber") }
-+
-+  before do
-+    @options = {}
-+    allow(subject).to receive(:options).and_return(@options)
-+    allow(::Guard::DslDescriber).to receive(:new).with(no_args).
-+      and_return(dsl_describer)
-+
-+    allow(Guard::Cli::Environments::EvaluateOnly).to receive(:new).
-+      and_return(bare_environment)
-+
-+    allow(Guard::Cli::Environments::Valid).to receive(:new).
-+      and_return(valid_environment)
-+  end
-+
-+  describe "#start" do
-+    before do
-+      allow(valid_environment).to receive(:start_guard).and_return(0)
-+    end
-+
-+    it "delegates to Guard::Environment.start" do
-+      pending "needs JRuby support first" if defined?(JRUBY_VERSION)
-+
-+      expect(valid_environment).to receive(:start_guard).and_return(0)
-+      begin
-+        subject.start
-+      rescue SystemExit
-+      end
-+    end
-+
-+    it "exits with given exit code" do
-+      pending "needs JRuby support first" if defined?(JRUBY_VERSION)
-+
-+      allow(valid_environment).to receive(:start_guard).and_return(4)
-+      expect { subject.start }.to raise_error(SystemExit) do |exception|
-+        expect(exception.status).to eq(4)
-+        exception
-+      end
-+    end
-+
-+    it "passes options" do
-+      pending "needs JRuby support first" if defined?(JRUBY_VERSION)
-+
-+      expect(Guard::Cli::Environments::Valid).to receive(:new).with(@options).
-+        and_return(valid_environment)
-+      begin
-+        subject.start
-+      rescue SystemExit
-+      end
-+    end
-+  end
-+
-+  describe "#list" do
-+    before do
-+      allow(bare_environment).to receive(:evaluate)
-+      allow(dsl_describer).to receive(:list)
-+      subject.list
-+    end
-+
-+    it "calls the evaluation" do
-+      expect(bare_environment).to have_received(:evaluate)
-+    end
-+
-+    it "outputs the Guard plugins list" do
-+      expect(dsl_describer).to have_received(:list)
-+    end
-+  end
-+
-+  describe "#notifiers" do
-+    before do
-+      allow(bare_environment).to receive(:evaluate)
-+      allow(dsl_describer).to receive(:notifiers)
-+      subject.notifiers
-+    end
-+
-+    it "calls the evaluation" do
-+      expect(bare_environment).to have_received(:evaluate)
-+    end
-+
-+    it "outputs the notifiers list" do
-+      expect(dsl_describer).to have_received(:notifiers)
-+    end
-+  end
-+
-+  describe "#version" do
-+    it "shows the current version" do
-+      expect(STDOUT).to receive(:puts).with(/#{ ::Guard::VERSION }/)
-+      subject.version
-+    end
-+  end
-+
-+  describe "#init" do
-+    before do
-+      allow(Guard::Cli::Environments::Valid).to receive(:new).
-+        and_return(valid_environment)
-+      allow(valid_environment).to receive(:initialize_guardfile).and_return(0)
-+    end
-+
-+    it "delegates to Guard::Environment.start" do
-+      begin
-+        subject.init
-+      rescue SystemExit
-+      end
-+    end
-+
-+    it "exits with given exit code" do
-+      allow(valid_environment).to receive(:initialize_guardfile).and_return(4)
-+      expect { subject.init }.to raise_error(SystemExit) do |exception|
-+        expect(exception.status).to eq(4)
-+      end
-+    end
-+
-+    it "passes options" do
-+      expect(Guard::Cli::Environments::Valid).to receive(:new).with(@options).
-+        and_return(valid_environment)
-+      begin
-+        subject.init
-+      rescue SystemExit
-+      end
-+    end
-+
-+    it "passes plugin names" do
-+      plugins = [double("plugin1"), double("plugin2")]
-+      expect(valid_environment).to receive(:initialize_guardfile).with(plugins)
-+      begin
-+        subject.init(*plugins)
-+      rescue SystemExit
-+      end
-+    end
-+  end
-+
-+  describe "#show" do
-+    before do
-+      allow(bare_environment).to receive(:evaluate)
-+      allow(dsl_describer).to receive(:show)
-+      subject.show
-+    end
-+
-+    it "calls the evaluation" do
-+      expect(bare_environment).to have_received(:evaluate)
-+    end
-+
-+    it "outputs the Guard::DslDescriber.list result" do
-+      expect(dsl_describer).to have_received(:show)
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commander_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commander_spec.rb
-@@ -0,0 +1,272 @@
-+require "guard/commander"
-+
-+RSpec.describe Guard::Commander do
-+  subject { Guard }
-+
-+  let(:interactor) { instance_double("Guard::Interactor") }
-+  let(:runner) { instance_double("Guard::Runner", run: true) }
-+
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+
-+  before do
-+    allow(state).to receive(:scope).and_return(scope)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(Guard::Interactor).to receive(:new) { interactor }
-+    allow(Guard::Runner).to receive(:new).and_return(runner)
-+  end
-+
-+  describe ".start" do
-+    let(:listener) do
-+      instance_double("Listen::Listener", start: true, stop: true)
-+    end
-+
-+    let(:watched_dir) { Dir.pwd }
-+
-+    before do
-+      stub_guardfile(" ")
-+      stub_user_guard_rb
-+
-+      # from stop()
-+      allow(Guard).to receive(:setup)
-+      allow(Guard).to receive(:listener).and_return(listener)
-+      allow(session).to receive(:watchdirs).and_return(%w(dir1 dir2))
-+      allow(Guard).to receive(:interactor).and_return(interactor)
-+
-+      # Simulate Ctrl-D in Pry, or Ctrl-C in non-interactive mode
-+      allow(interactor).to receive(:foreground).and_return(:exit)
-+
-+      allow(interactor).to receive(:background)
-+      allow(Guard::Notifier).to receive(:disconnect)
-+    end
-+
-+    it "calls Guard setup" do
-+      expect(Guard).to receive(:setup).with(foo: "bar")
-+      Guard.start(foo: "bar")
-+    end
-+
-+    it "displays an info message" do
-+      expect(Guard::UI).to receive(:info).
-+        with("Guard is now watching at 'dir1', 'dir2'")
-+
-+      Guard.start
-+    end
-+
-+    it "tell the runner to run the :start task" do
-+      expect(runner).to receive(:run).with(:start)
-+      allow(listener).to receive(:stop)
-+      Guard.start
-+    end
-+
-+    it "start the listener" do
-+      expect(listener).to receive(:start)
-+
-+      Guard.start
-+    end
-+
-+    context "when finished" do
-+      it "stops everything" do
-+        expect(interactor).to receive(:foreground).and_return(:exit)
-+
-+        # From stop()
-+        expect(interactor).to receive(:background)
-+        expect(listener).to receive(:stop)
-+        expect(runner).to receive(:run).with(:stop)
-+        expect(Guard::UI).to receive(:info).with("Bye bye...", reset: true)
-+
-+        Guard.start
-+      end
-+    end
-+  end
-+
-+  describe ".stop" do
-+    let(:runner) { instance_double("Guard::Runner", run: true) }
-+    let(:listener) { instance_double("Listen::Listener", stop: true) }
-+
-+    before do
-+      allow(Guard::Notifier).to receive(:disconnect)
-+      allow(Guard).to receive(:listener).and_return(listener)
-+      allow(listener).to receive(:stop)
-+      allow(Guard).to receive(:interactor).and_return(interactor)
-+      allow(interactor).to receive(:background)
-+
-+      Guard.stop
-+    end
-+
-+    it "turns off the interactor" do
-+      expect(interactor).to have_received(:background)
-+    end
-+
-+    it "turns the notifier off" do
-+      expect(Guard::Notifier).to have_received(:disconnect)
-+    end
-+
-+    it "tell the runner to run the :stop task" do
-+      expect(runner).to have_received(:run).with(:stop)
-+    end
-+
-+    it "stops the listener" do
-+      expect(listener).to have_received(:stop)
-+    end
-+  end
-+
-+  describe ".reload" do
-+    let(:runner) { instance_double("Guard::Runner", run: true) }
-+    let(:group) { instance_double("Guard::Group", name: "frontend") }
-+
-+    before do
-+      allow(Guard::Notifier).to receive(:connect)
-+      allow(Guard::UI).to receive(:info)
-+      allow(Guard::UI).to receive(:clear)
-+
-+      allow(scope).to receive(:titles).and_return(["all"])
-+
-+      stub_guardfile(" ")
-+      stub_user_guard_rb
-+    end
-+
-+    it "clears the screen" do
-+      expect(Guard::UI).to receive(:clear)
-+
-+      Guard.reload
-+    end
-+
-+    it "reloads Guard" do
-+      expect(runner).to receive(:run).with(:reload, groups: [group])
-+      Guard.reload(groups: [group])
-+    end
-+  end
-+
-+  describe ".run_all" do
-+    let(:group) { instance_double("Guard::Group", name: "frontend") }
-+
-+    before do
-+      allow(::Guard::Notifier).to receive(:connect)
-+      allow(::Guard::UI).to receive(:action_with_scopes)
-+      allow(::Guard::UI).to receive(:clear)
-+    end
-+
-+    context "with a given scope" do
-+      it "runs all with the scope" do
-+        expect(runner).to receive(:run).with(:run_all, groups: [group])
-+
-+        subject.run_all(groups: [group])
-+      end
-+    end
-+
-+    context "with an empty scope" do
-+      it "runs all" do
-+        expect(runner).to receive(:run).with(:run_all, {})
-+
-+        subject.run_all
-+      end
-+    end
-+  end
-+
-+  describe ".pause" do
-+    context "when unpaused" do
-+      let(:listener) { instance_double("Listen::Listener") }
-+
-+      before do
-+        allow(::Guard::Notifier).to receive(:connect)
-+        allow(Guard).to receive(:listener).and_return(listener)
-+        allow(listener).to receive(:paused?) { false }
-+      end
-+
-+      [:toggle, nil, :paused].each do |mode|
-+        context "with #{mode.inspect}" do
-+          before do
-+            allow(listener).to receive(:pause)
-+          end
-+
-+          it "pauses" do
-+            expect(listener).to receive(:pause)
-+            Guard.pause(mode)
-+          end
-+
-+          it "shows a message" do
-+            expected = /File event handling has been paused/
-+            expect(Guard::UI).to receive(:info).with(expected)
-+            Guard.pause(mode)
-+          end
-+        end
-+      end
-+
-+      context "with :unpaused" do
-+        it "does nothing" do
-+          expect(listener).to_not receive(:start)
-+          expect(listener).to_not receive(:pause)
-+          Guard.pause(:unpaused)
-+        end
-+      end
-+
-+      context "with invalid parameter" do
-+        it "raises an ArgumentError" do
-+          expect { Guard.pause(:invalid) }.
-+            to raise_error(ArgumentError, "invalid mode: :invalid")
-+        end
-+      end
-+    end
-+
-+    context "when already paused" do
-+      let(:listener) { instance_double("Listen::Listener") }
-+
-+      before do
-+        allow(::Guard::Notifier).to receive(:connect)
-+        allow(Guard).to receive(:listener).and_return(listener)
-+        allow(listener).to receive(:paused?) { true }
-+      end
-+
-+      [:toggle, nil, :unpaused].each do |mode|
-+        context "with #{mode.inspect}" do
-+          before do
-+            allow(listener).to receive(:start)
-+          end
-+
-+          it "unpauses" do
-+            expect(listener).to receive(:start)
-+            Guard.pause(mode)
-+          end
-+
-+          it "shows a message" do
-+            expected = /File event handling has been resumed/
-+            expect(Guard::UI).to receive(:info).with(expected)
-+            Guard.pause(mode)
-+          end
-+        end
-+      end
-+
-+      context "with :paused" do
-+        it "does nothing" do
-+          expect(listener).to_not receive(:start)
-+          expect(listener).to_not receive(:pause)
-+          Guard.pause(:paused)
-+        end
-+      end
-+
-+      context "with invalid parameter" do
-+        it "raises an ArgumentError" do
-+          expect { Guard.pause(:invalid) }.
-+            to raise_error(ArgumentError, "invalid mode: :invalid")
-+        end
-+      end
-+    end
-+  end
-+
-+  describe ".show" do
-+    let(:dsl_describer) { instance_double("Guard::DslDescriber") }
-+
-+    before do
-+      allow(Guard::DslDescriber).to receive(:new).with(no_args).
-+        and_return(dsl_describer)
-+    end
-+
-+    it "shows list of plugins" do
-+      expect(dsl_describer).to receive(:show)
-+      Guard.show
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commands/all_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commands/all_spec.rb
-@@ -0,0 +1,83 @@
-+require "guard/plugin"
-+
-+require "guard/commands/all"
-+
-+require "guard/internals/session"
-+require "guard/internals/state"
-+
-+RSpec.describe Guard::Commands::All do
-+  let(:foo_group) { instance_double(Guard::Group) }
-+  let(:bar_guard) { instance_double(Guard::Plugin) }
-+  let(:output) { instance_double(Pry::Output) }
-+
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+
-+  class FakePry < Pry::Command
-+    def self.output
-+    end
-+  end
-+
-+  before do
-+    allow(session).to receive(:convert_scope).with(given_scope).
-+      and_return(converted_scope)
-+
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(FakePry).to receive(:output).and_return(output)
-+    allow(Pry::Commands).to receive(:create_command).with("all") do |&block|
-+      FakePry.instance_eval(&block)
-+    end
-+
-+    described_class.import
-+  end
-+
-+  context "without scope" do
-+    let(:given_scope) { [] }
-+    let(:converted_scope) { [{ groups: [], plugins: [] }, []] }
-+
-+    it "runs the :run_all action" do
-+      expect(Guard).to receive(:async_queue_add).
-+        with([:guard_run_all, groups: [], plugins: []])
-+
-+      FakePry.process
-+    end
-+  end
-+
-+  context "with a valid Guard group scope" do
-+    let(:given_scope) { ["foo"] }
-+    let(:converted_scope) { [{ groups: [foo_group], plugins: [] }, []] }
-+
-+    it "runs the :run_all action with the given scope" do
-+      expect(Guard).to receive(:async_queue_add).
-+        with([:guard_run_all, groups: [foo_group], plugins: []])
-+
-+      FakePry.process("foo")
-+    end
-+  end
-+
-+  context "with a valid Guard plugin scope" do
-+    let(:given_scope) { ["bar"] }
-+    let(:converted_scope) { [{ groups: [], plugins: [bar_guard] }, []] }
-+
-+    it "runs the :run_all action with the given scope" do
-+      expect(Guard).to receive(:async_queue_add).
-+        with([:guard_run_all, plugins: [bar_guard], groups: []])
-+
-+      FakePry.process("bar")
-+    end
-+  end
-+
-+  context "with an invalid scope" do
-+    let(:given_scope) { ["baz"] }
-+    let(:converted_scope) { [{ groups: [], plugins: [] }, ["baz"]] }
-+
-+    it "does not run the action" do
-+      expect(output).to receive(:puts).with("Unknown scopes: baz")
-+      expect(Guard).to_not receive(:async_queue_add)
-+
-+      FakePry.process("baz")
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commands/change_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commands/change_spec.rb
-@@ -0,0 +1,46 @@
-+require "guard/commands/change"
-+
-+RSpec.describe Guard::Commands::Change do
-+  let(:output) { instance_double(Pry::Output) }
-+
-+  class FakePry < Pry::Command
-+    def self.output
-+    end
-+  end
-+
-+  before do
-+    allow(FakePry).to receive(:output).and_return(output)
-+    allow(Pry::Commands).to receive(:create_command).with("change") do |&block|
-+      FakePry.instance_eval(&block)
-+    end
-+
-+    described_class.import
-+  end
-+
-+  context "with a file" do
-+    it "runs the :run_on_changes action with the given file" do
-+      expect(::Guard).to receive(:async_queue_add).
-+        with(modified: ["foo"], added: [], removed: [])
-+
-+      FakePry.process("foo")
-+    end
-+  end
-+
-+  context "with multiple files" do
-+    it "runs the :run_on_changes action with the given files" do
-+      expect(::Guard).to receive(:async_queue_add).
-+        with(modified: %w(foo bar baz), added: [], removed: [])
-+
-+      FakePry.process("foo", "bar", "baz")
-+    end
-+  end
-+
-+  context "without a file" do
-+    it "does not run the :run_on_changes action" do
-+      expect(::Guard).to_not receive(:async_queue_add)
-+      expect(output).to receive(:puts).with("Please specify a file.")
-+
-+      FakePry.process
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commands/notification_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commands/notification_spec.rb
-@@ -0,0 +1,24 @@
-+require "guard/commands/notification"
-+
-+RSpec.describe Guard::Commands::Notification do
-+  let(:output) { instance_double(Pry::Output) }
-+
-+  class FakePry < Pry::Command
-+    def self.output; end
-+  end
-+
-+  before do
-+    allow(FakePry).to receive(:output).and_return(output)
-+    allow(Pry::Commands).to receive(:create_command).
-+      with("notification") do |&block|
-+      FakePry.instance_eval(&block)
-+    end
-+
-+    described_class.import
-+  end
-+
-+  it "toggles the Guard notifier" do
-+    expect(::Guard::Notifier).to receive(:toggle)
-+    FakePry.process
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commands/pause_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commands/pause_spec.rb
-@@ -0,0 +1,22 @@
-+require "guard/commands/pause"
-+
-+RSpec.describe Guard::Commands::Pause do
-+  class FakePry < Pry::Command
-+    def self.output
-+    end
-+  end
-+
-+  before do
-+    allow(FakePry).to receive(:output).and_return(output)
-+    allow(Pry::Commands).to receive(:create_command).with("pause") do |&block|
-+      FakePry.instance_eval(&block)
-+    end
-+
-+    described_class.import
-+  end
-+
-+  it "tells Guard to pause" do
-+    expect(::Guard).to receive(:async_queue_add).with([:guard_pause])
-+    FakePry.process
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commands/reload_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commands/reload_spec.rb
-@@ -0,0 +1,77 @@
-+require "guard/commands/reload"
-+
-+require "guard/internals/session"
-+require "guard/internals/state"
-+
-+RSpec.describe Guard::Commands::Reload do
-+  let(:output) { instance_double(Pry::Output) }
-+
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+
-+  let(:foo_group) { instance_double(Guard::Group) }
-+  let(:bar_guard) { instance_double(Guard::Plugin) }
-+
-+  class FakePry < Pry::Command
-+    def self.output; end
-+  end
-+
-+  before do
-+    allow(session).to receive(:convert_scope).with(given_scope).
-+      and_return(converted_scope)
-+
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(FakePry).to receive(:output).and_return(output)
-+    allow(Pry::Commands).to receive(:create_command).with("reload") do |&block|
-+      FakePry.instance_eval(&block)
-+    end
-+
-+    described_class.import
-+  end
-+
-+  context "without scope" do
-+    let(:given_scope) { [] }
-+    let(:converted_scope) { [{ groups: [], plugins: [] }, []] }
-+
-+    it "triggers the :reload action" do
-+      expect(Guard).to receive(:async_queue_add).
-+        with([:guard_reload, { groups: [], plugins: [] }])
-+      FakePry.process
-+    end
-+  end
-+
-+  context "with a valid Guard group scope" do
-+    let(:given_scope) { ["foo"] }
-+    let(:converted_scope) { [{ groups: [foo_group], plugins: [] }, []] }
-+
-+    it "triggers the :reload action with the given scope" do
-+      expect(Guard).to receive(:async_queue_add).
-+        with([:guard_reload, { groups: [foo_group], plugins: [] }])
-+      FakePry.process("foo")
-+    end
-+  end
-+
-+  context "with a valid Guard plugin scope" do
-+    let(:given_scope) { ["bar"] }
-+    let(:converted_scope) { [{ groups: [], plugins: [bar_guard] }, []] }
-+
-+    it "triggers the :reload action with the given scope" do
-+      expect(Guard).to receive(:async_queue_add).
-+        with([:guard_reload, { plugins: [bar_guard], groups: [] }])
-+      FakePry.process("bar")
-+    end
-+  end
-+
-+  context "with an invalid scope" do
-+    let(:given_scope) { ["baz"] }
-+    let(:converted_scope) { [{ groups: [], plugins: [] }, ["baz"]] }
-+
-+    it "does not trigger the action" do
-+      allow(output).to receive(:puts).with("Unknown scopes: baz")
-+      expect(Guard).to_not receive(:async_queue_add)
-+      FakePry.process("baz")
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commands/scope_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commands/scope_spec.rb
-@@ -0,0 +1,81 @@
-+require "guard/commands/scope"
-+
-+require "guard/internals/session"
-+require "guard/internals/state"
-+
-+RSpec.describe Guard::Commands::Scope do
-+  let(:output) { instance_double(Pry::Output) }
-+
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+
-+  let(:foo_group) { instance_double(Guard::Group) }
-+  let(:bar_guard) { instance_double(Guard::PluginUtil) }
-+
-+  class FakePry < Pry::Command
-+    def self.output; end
-+  end
-+
-+  before do
-+    allow(session).to receive(:convert_scope).with(given_scope).
-+      and_return(converted_scope)
-+
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(FakePry).to receive(:output).and_return(output)
-+    allow(Pry::Commands).to receive(:create_command).with("scope") do |&block|
-+      FakePry.instance_eval(&block)
-+    end
-+
-+    allow(state).to receive(:scope).and_return(scope)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    described_class.import
-+  end
-+
-+  context "without scope" do
-+    let(:given_scope) { [] }
-+    let(:converted_scope) { [{ groups: [], plugins: [] }, []] }
-+
-+    it "does not call :scope= and shows usage" do
-+      expect(output).to receive(:puts).with("Usage: scope <scope>")
-+      expect(scope).to_not receive(:from_interactor)
-+      FakePry.process
-+    end
-+  end
-+
-+  context "with a valid Guard group scope" do
-+    let(:given_scope) { ["foo"] }
-+    let(:converted_scope) { [{ groups: [foo_group], plugins: [] }, []] }
-+
-+    it "sets up the scope with the given scope" do
-+      expect(scope).to receive(:from_interactor).
-+        with(groups: [foo_group], plugins: [])
-+      FakePry.process("foo")
-+    end
-+  end
-+
-+  context "with a valid Guard plugin scope" do
-+    let(:given_scope) { ["bar"] }
-+    let(:converted_scope) { [{ groups: [], plugins: [bar_guard] }, []] }
-+
-+    it "runs the :scope= action with the given scope" do
-+      expect(scope).to receive(:from_interactor).
-+        with(plugins: [bar_guard], groups: [])
-+      FakePry.process("bar")
-+    end
-+  end
-+
-+  context "with an invalid scope" do
-+    let(:given_scope) { ["baz"] }
-+    let(:converted_scope) { [{ groups: [], plugins: [] }, ["baz"]] }
-+
-+    it "does not change the scope and shows unknown scopes" do
-+      expect(output).to receive(:puts).with("Unknown scopes: baz")
-+      expect(scope).to_not receive(:from_interactor)
-+      FakePry.process("baz")
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/commands/show_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/commands/show_spec.rb
-@@ -0,0 +1,26 @@
-+require "guard/commands/show"
-+
-+# TODO: we only need the async queue
-+require "guard"
-+
-+RSpec.describe Guard::Commands::Show do
-+  let(:output) { instance_double(Pry::Output) }
-+
-+  class FakePry < Pry::Command
-+    def self.output; end
-+  end
-+
-+  before do
-+    allow(FakePry).to receive(:output).and_return(output)
-+    allow(Pry::Commands).to receive(:create_command).with("show") do |&block|
-+      FakePry.instance_eval(&block)
-+    end
-+
-+    described_class.import
-+  end
-+
-+  it "tells Guard to output DSL description" do
-+    expect(::Guard).to receive(:async_queue_add).with([:guard_show])
-+    FakePry.process
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/config_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/config_spec.rb
-@@ -0,0 +1,22 @@
-+require "guard/config"
-+
-+RSpec.describe Guard::Config, exclude_stubs: [:Nenv] do
-+  it { is_expected.to respond_to(:strict?) }
-+  it { is_expected.to respond_to(:silence_deprecations?) }
-+
-+  describe ".strict?" do
-+    before do
-+      allow(subject).to receive(:strict?).and_return(result)
-+    end
-+
-+    context "when GUARD_STRICT is set to a 'true' value" do
-+      let(:result) { true }
-+      it { is_expected.to be_strict }
-+    end
-+
-+    context "when GUARD_STRICT is set to a 'false' value" do
-+      let(:result) { false }
-+      it { is_expected.to_not be_strict }
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/deprecated/dsl_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/deprecated/dsl_spec.rb
-@@ -0,0 +1,57 @@
-+require "guard/config"
-+
-+unless Guard::Config.new.strict?
-+
-+  # Require listen now, so the requiring below doesn't use File methods
-+  require "listen"
-+
-+  require "guard/deprecated/dsl"
-+
-+  require "guard/ui"
-+  require "guard/config"
-+
-+  RSpec.describe Guard::Deprecated::Dsl do
-+    subject do
-+      module TestModule; end.tap { |mod| described_class.add_deprecated(mod) }
-+    end
-+
-+    describe ".evaluate_guardfile" do
-+      before { stub_user_guard_rb }
-+      before { stub_guardfile(" ") }
-+      before { stub_user_guardfile }
-+      before { stub_user_project_guardfile }
-+      let(:evaluator) { instance_double("Guard::Guardfile::Evaluator") }
-+
-+      before do
-+        # TODO: this is a workaround for a bad require loop
-+        allow_any_instance_of(Guard::Config).to receive(:strict?).
-+          and_return(false)
-+
-+        require "guard/guardfile/evaluator"
-+
-+        allow(Guard::Guardfile::Evaluator).to receive(:new).
-+          and_return(evaluator)
-+
-+        allow(evaluator).to receive(:evaluate_guardfile)
-+
-+        allow(Guard::UI).to receive(:deprecation)
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Dsl::ClassMethods::EVALUATE_GUARDFILE)
-+
-+        subject.evaluate_guardfile
-+      end
-+
-+      it "delegates to Guard::Guardfile::Generator" do
-+        expect(Guard::Guardfile::Evaluator).to receive(:new).
-+          with(foo: "bar") { evaluator }
-+
-+        expect(evaluator).to receive(:evaluate_guardfile)
-+
-+        subject.evaluate_guardfile(foo: "bar")
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/deprecated/evaluator_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/deprecated/evaluator_spec.rb
-@@ -0,0 +1,50 @@
-+require "guard/config"
-+
-+unless Guard::Config.new.strict?
-+
-+  require "guard/deprecated/evaluator"
-+  require "guard/internals/state"
-+
-+  RSpec.describe Guard::Deprecated::Evaluator do
-+    subject do
-+      class TestClass
-+        def evaluate
-+        end
-+      end
-+      described_class.add_deprecated(TestClass)
-+      TestClass.new
-+    end
-+
-+    let(:state) { instance_double("Guard::Internals::State") }
-+
-+    before do
-+      allow(Guard::UI).to receive(:deprecation)
-+      allow(Guard).to receive(:state).and_return(state)
-+    end
-+
-+    describe "#evaluate_guardfile" do
-+      before do
-+        allow(subject).to receive(:evaluate)
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Evaluator::EVALUATE_GUARDFILE)
-+        subject.evaluate_guardfile
-+      end
-+
-+      it "calls the recommended method" do
-+        expect(subject).to receive(:evaluate)
-+        subject.evaluate_guardfile
-+      end
-+    end
-+
-+    describe "#reevaluate_guardfile" do
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Evaluator::REEVALUATE_GUARDFILE)
-+        subject.reevaluate_guardfile
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/deprecated/guard_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/deprecated/guard_spec.rb
-@@ -0,0 +1,422 @@
-+require "guard/config"
-+
-+unless Guard::Config.new.strict?
-+
-+  # require guard, to avoid circular require
-+  require "guard"
-+  # require "guard/deprecated/guard"
-+
-+  require "guard/config"
-+
-+  RSpec.describe Guard::Deprecated::Guard do
-+    let(:session) { instance_double("Guard::Internals::Session") }
-+    let(:state) { instance_double("Guard::Internals::State") }
-+    let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+    let(:groups) { instance_double("Guard::Internals::Groups") }
-+    let(:scope) { instance_double("Guard::Internals::Scope") }
-+
-+    subject do
-+      module TestModule
-+        def self.listener
-+        end
-+
-+        def self._pluginless_guardfile?
-+          false
-+        end
-+      end
-+      TestModule.tap { |mod| described_class.add_deprecated(mod) }
-+    end
-+
-+    before do
-+      allow(session).to receive(:evaluator_options).and_return({})
-+      allow(state).to receive(:scope).and_return(scope)
-+      allow(state).to receive(:session).and_return(session)
-+      allow(session).to receive(:plugins).and_return(plugins)
-+      allow(session).to receive(:groups).and_return(groups)
-+      allow(::Guard).to receive(:state).and_return(state)
-+      allow(Guard::UI).to receive(:deprecation)
-+      allow(plugins).to receive(:all)
-+      allow(groups).to receive(:all)
-+    end
-+
-+    describe ".guards" do
-+      before do
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::GUARDS)
-+        subject.guards
-+      end
-+
-+      it "delegates to Plugins" do
-+        expect(plugins).to receive(:all).with(group: "backend")
-+        subject.guards(group: "backend")
-+      end
-+    end
-+
-+    describe ".add_guard" do
-+      before { allow(plugins).to receive(:add).with("rspec", {}) }
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::ADD_GUARD)
-+
-+        subject.add_guard("rspec")
-+      end
-+
-+      it "delegates to Guard.plugins" do
-+        expect(subject).to receive(:add_plugin).with("rspec", group: "backend")
-+
-+        subject.add_guard("rspec", group: "backend")
-+      end
-+    end
-+
-+    describe ".get_guard_class" do
-+      let(:plugin_util) do
-+        instance_double("Guard::PluginUtil", plugin_class: true)
-+      end
-+
-+      before do
-+        allow(Guard::PluginUtil).to receive(:new).with("rspec").
-+          and_return(plugin_util)
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::GET_GUARD_CLASS)
-+        subject.get_guard_class("rspec")
-+      end
-+
-+      it "delegates to Guard::PluginUtil" do
-+        expect(plugin_util).to receive(:plugin_class).
-+          with(fail_gracefully: false)
-+        subject.get_guard_class("rspec")
-+      end
-+
-+      describe ":fail_gracefully" do
-+        it "pass it to get_guard_class" do
-+          expect(plugin_util).to receive(:plugin_class).
-+            with(fail_gracefully: true)
-+          subject.get_guard_class("rspec", true)
-+        end
-+      end
-+    end
-+
-+    describe ".locate_guard" do
-+      let(:plugin_util) do
-+        instance_double("Guard::PluginUtil", plugin_location: true)
-+      end
-+
-+      before do
-+        allow(Guard::PluginUtil).to receive(:new) { plugin_util }
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::LOCATE_GUARD)
-+
-+        subject.locate_guard("rspec")
-+      end
-+
-+      it "delegates to Guard::PluginUtil" do
-+        expect(Guard::PluginUtil).to receive(:new).with("rspec") { plugin_util }
-+        expect(plugin_util).to receive(:plugin_location)
-+
-+        subject.locate_guard("rspec")
-+      end
-+    end
-+
-+    describe ".guard_gem_names" do
-+      before { allow(Guard::PluginUtil).to receive(:plugin_names) }
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::GUARD_GEM_NAMES)
-+
-+        subject.guard_gem_names
-+      end
-+
-+      it "delegates to Guard::PluginUtil" do
-+        expect(Guard::PluginUtil).to receive(:plugin_names)
-+
-+        subject.guard_gem_names
-+      end
-+    end
-+
-+    describe ".running" do
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::RUNNING)
-+
-+        subject.running
-+      end
-+    end
-+
-+    describe ".lock" do
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::LOCK)
-+
-+        subject.lock
-+      end
-+    end
-+
-+    describe ".listener=" do
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::LISTENER_ASSIGN)
-+
-+        subject.listener = 123
-+      end
-+
-+      it "provides and alternative implementation" do
-+        subject.listener = 123
-+      end
-+    end
-+
-+    describe "reset_evaluator" do
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::RESET_EVALUATOR)
-+        subject.reset_evaluator({})
-+      end
-+    end
-+
-+    describe "evaluator" do
-+      before do
-+        allow(Guard::Guardfile::Evaluator).to receive(:new).
-+          and_return(double("evaluator"))
-+      end
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::EVALUATOR)
-+        subject.evaluator
-+      end
-+    end
-+
-+    describe "evaluate_guardfile" do
-+      let(:evaluator) { instance_double("Guard::Guardfile::Evaluator") }
-+
-+      before do
-+        allow(::Guard::Guardfile::Evaluator).to receive(:new).
-+          and_return(evaluator)
-+        allow(evaluator).to receive(:evaluate)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::EVALUATOR)
-+        subject.evaluate_guardfile
-+      end
-+
-+      it "evaluates the guardfile" do
-+        expect(evaluator).to receive(:evaluate)
-+        subject.evaluate_guardfile
-+      end
-+    end
-+
-+    describe "options" do
-+      before do
-+        allow(session).to receive(:clearing?)
-+        allow(session).to receive(:debug?)
-+        allow(session).to receive(:watchdirs)
-+        allow(session).to receive(:notify_options).and_return({})
-+        allow(session).to receive(:interactor_name)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::OPTIONS)
-+        subject.options
-+      end
-+
-+      describe ":clear" do
-+        before do
-+          allow(session).to receive(:clearing?).and_return(clearing)
-+        end
-+        context "when being set to true" do
-+          let(:clearing) { true }
-+          it "sets the clearing option accordingly" do
-+            expect(session).to receive(:clearing).with(true)
-+            subject.options[:clear] = true
-+          end
-+        end
-+
-+        context "when being set to false" do
-+          let(:clearing) { false }
-+          it "sets the clearing option accordingly" do
-+            expect(session).to receive(:clearing).with(false)
-+            subject.options[:clear] = false
-+          end
-+        end
-+
-+        context "when being read" do
-+          context "when not set" do
-+            let(:clearing) { false }
-+            it "provides an alternative implementation" do
-+              expect(subject.options).to include(clear: false)
-+            end
-+          end
-+
-+          context "when set" do
-+            let(:clearing) { true }
-+            it "provides an alternative implementation" do
-+              expect(subject.options).to include(clear: true)
-+            end
-+          end
-+        end
-+      end
-+
-+      # TODO: other options?
-+    end
-+
-+    describe ".add_group" do
-+      before do
-+        allow(groups).to receive(:add)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::ADD_GROUP)
-+        subject.add_group(:foo)
-+      end
-+
-+      it "adds a group" do
-+        group = instance_double("Guard::Group")
-+        expect(groups).to receive(:add).with(:foo, bar: 3).and_return(group)
-+        expect(subject.add_group(:foo, bar: 3)).to eq(group)
-+      end
-+    end
-+
-+    describe ".add_plugin" do
-+      before do
-+        allow(plugins).to receive(:add)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::ADD_PLUGIN)
-+        subject.add_plugin(:foo)
-+      end
-+
-+      it "adds a plugin" do
-+        plugin = instance_double("Guard::Plugin")
-+        expect(plugins).to receive(:add).with(:foo, bar: 3).and_return(plugin)
-+        expect(subject.add_plugin(:foo, bar: 3)).to be(plugin)
-+      end
-+    end
-+
-+    describe ".group" do
-+      let(:array) { instance_double(Array) }
-+
-+      before do
-+        allow(groups).to receive(:all).with(:foo).and_return(array)
-+        allow(array).to receive(:first)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::GROUP)
-+        subject.group(:foo)
-+      end
-+
-+      it "provides a similar implementation" do
-+        group = instance_double("Guard::Group")
-+        expect(array).to receive(:first).and_return(group)
-+        expect(subject.group(:foo)).to be(group)
-+      end
-+    end
-+
-+    describe ".plugin" do
-+      let(:array) { instance_double(Array) }
-+      let(:plugin) { instance_double("Guard::Plugin") }
-+
-+      before do
-+        allow(plugins).to receive(:all).with(:foo).and_return(array)
-+        allow(array).to receive(:first).and_return(plugin)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::PLUGIN)
-+        subject.plugin(:foo)
-+      end
-+
-+      it "provides a similar implementation" do
-+        expect(subject.plugin(:foo)).to be(plugin)
-+      end
-+    end
-+
-+    describe ".groups" do
-+      let(:array) { instance_double(Array) }
-+
-+      before do
-+        allow(groups).to receive(:all).with(:foo).and_return(array)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::GROUPS)
-+        subject.groups(:foo)
-+      end
-+
-+      it "provides a similar implementation" do
-+        expect(subject.groups(:foo)).to be(array)
-+      end
-+    end
-+
-+    describe ".plugins" do
-+      let(:array) { instance_double(Array) }
-+
-+      before do
-+        allow(plugins).to receive(:all).with(:foo).and_return(array)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::PLUGINS)
-+        subject.plugins(:foo)
-+      end
-+
-+      it "provides a similar implementation" do
-+        expect(subject.plugins(:foo)).to be(array)
-+      end
-+    end
-+
-+    describe ".scope" do
-+      let(:hash) { instance_double(Hash) }
-+
-+      before do
-+        allow(scope).to receive(:to_hash).and_return(hash)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::SCOPE)
-+        subject.scope
-+      end
-+
-+      it "provides a similar implementation" do
-+        expect(subject.scope).to be(hash)
-+      end
-+    end
-+
-+    describe ".scope=" do
-+      before do
-+        allow(scope).to receive(:from_interactor).with(foo: :bar)
-+      end
-+
-+      it "show deprecation warning" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guard::ClassMethods::SCOPE_ASSIGN)
-+        subject.scope = { foo: :bar }
-+      end
-+
-+      it "provides a similar implementation" do
-+        expect(scope).to receive(:from_interactor).with(foo: :bar)
-+        subject.scope = { foo: :bar }
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/deprecated/guardfile_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/deprecated/guardfile_spec.rb
-@@ -0,0 +1,93 @@
-+require "guard/config"
-+
-+unless Guard::Config.new.strict?
-+
-+  require "guard/deprecated/guardfile"
-+
-+  RSpec.describe Guard::Deprecated::Guardfile do
-+    subject do
-+      module TestModule; end.tap { |mod| described_class.add_deprecated(mod) }
-+    end
-+
-+    let(:generator) { instance_double("Guard::Guardfile::Generator") }
-+
-+    before do
-+      allow(Guard::UI).to receive(:deprecation)
-+    end
-+
-+    describe ".create_guardfile" do
-+      before do
-+        allow(File).to receive(:exist?).with("Guardfile").and_return(false)
-+        template = Guard::Guardfile::Generator::GUARDFILE_TEMPLATE
-+        allow(FileUtils).to receive(:cp).with(template, "Guardfile")
-+
-+        allow(Guard::Guardfile::Generator).to receive(:new).
-+          and_return(generator)
-+
-+        allow(generator).to receive(:create_guardfile)
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guardfile::ClassMethods::CREATE_GUARDFILE)
-+
-+        subject.create_guardfile
-+      end
-+
-+      it "delegates to Guard::Guardfile::Generator" do
-+        expect(Guard::Guardfile::Generator).to receive(:new).
-+          with(foo: "bar") { generator }
-+
-+        expect(generator).to receive(:create_guardfile)
-+
-+        subject.create_guardfile(foo: "bar")
-+      end
-+    end
-+
-+    describe ".initialize_template" do
-+      before do
-+        expect(Guard::Guardfile::Generator).to receive(:new) do
-+          generator
-+        end
-+
-+        allow(generator).to receive(:initialize_template)
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Guardfile::ClassMethods::INITIALIZE_TEMPLATE)
-+
-+        subject.initialize_template("rspec")
-+      end
-+
-+      it "delegates to Guard::Guardfile::Generator" do
-+        expect(generator).to receive(:initialize_template).with("rspec")
-+
-+        subject.initialize_template("rspec")
-+      end
-+    end
-+
-+    describe ".initialize_all_templates" do
-+      before do
-+        expect(Guard::Guardfile::Generator).to receive(:new) do
-+          generator
-+        end
-+
-+        allow(generator).to receive(:initialize_all_templates)
-+      end
-+
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(described_class::ClassMethods::INITIALIZE_ALL_TEMPLATES)
-+
-+        subject.initialize_all_templates
-+      end
-+
-+      it "delegates to Guard::Guardfile::Generator" do
-+        expect(generator).to receive(:initialize_all_templates)
-+
-+        subject.initialize_all_templates
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/deprecated/watcher_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/deprecated/watcher_spec.rb
-@@ -0,0 +1,49 @@
-+require "guard/config"
-+
-+unless Guard::Config.new.strict?
-+
-+  require "guard/deprecated/watcher"
-+  require "guard/guardfile/evaluator"
-+
-+  RSpec.describe Guard::Deprecated::Watcher do
-+    let(:session) { instance_double("Guard::Internals::Session") }
-+
-+    subject do
-+      module TestModule; end.tap { |mod| described_class.add_deprecated(mod) }
-+    end
-+
-+    let(:evaluator) { instance_double("Guard::Guardfile::Evaluator") }
-+    let(:options) { { guardfile: "foo" } }
-+
-+    let(:state) { instance_double("Guard::Internals::State") }
-+
-+    before do
-+      allow(session).to receive(:evaluator_options).and_return(options)
-+      allow(state).to receive(:session).and_return(session)
-+      allow(Guard).to receive(:state).and_return(state)
-+
-+      allow(evaluator).to receive(:guardfile_path).
-+        and_return(File.expand_path("foo"))
-+
-+      allow(::Guard::Guardfile::Evaluator).to receive(:new).with(options).
-+        and_return(evaluator)
-+
-+      allow(Guard::UI).to receive(:deprecation)
-+    end
-+
-+    describe ".match_guardfile?" do
-+      it "displays a deprecation warning to the user" do
-+        expect(Guard::UI).to receive(:deprecation).
-+          with(Guard::Deprecated::Watcher::ClassMethods::MATCH_GUARDFILE)
-+
-+        files = %w(foo bar)
-+        subject.match_guardfile?(files)
-+      end
-+
-+      it "matches against current guardfile" do
-+        expect(subject.match_guardfile?(%w(foo bar))).to be(true)
-+        expect(subject.match_guardfile?(%w(bar))).to be(false)
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/dsl_describer_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/dsl_describer_spec.rb
-@@ -0,0 +1,164 @@
-+# encoding: utf-8
-+require "guard/plugin"
-+require "guard/dsl_describer"
-+require "formatador"
-+
-+RSpec.describe Guard::DslDescriber do
-+  let(:interactor) { instance_double(Guard::Interactor) }
-+  let(:env) { double("ENV") }
-+
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+  let(:groups) { instance_double("Guard::Internals::Groups") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+
-+  before do
-+    allow(session).to receive(:groups).and_return(groups)
-+    allow(session).to receive(:plugins).and_return(plugins)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(env).to receive(:[]).with("GUARD_NOTIFY_PID")
-+    allow(env).to receive(:[]).with("GUARD_NOTIFY")
-+    allow(env).to receive(:[]).with("GUARD_NOTIFIERS")
-+    allow(env).to receive(:[]=).with("GUARD_NOTIFIERS", anything)
-+
-+    allow(Guard::Notifier).to receive(:turn_on)
-+
-+    stub_const "Guard::Test", class_double("Guard::Plugin")
-+    stub_const "Guard::Another", class_double("Guard::Plugin")
-+
-+    @output = ""
-+
-+    # Strip escape sequences
-+    allow(STDOUT).to receive(:tty?).and_return(false)
-+
-+    # Capture formatador output
-+    Thread.current[:formatador] = Formatador.new
-+    allow(Thread.current[:formatador]).to receive(:print) do |msg|
-+      @output << msg
-+    end
-+  end
-+
-+  describe "#list" do
-+    let(:result) do
-+      <<-OUTPUT
-+  +---------+-----------+
-+  | Plugin  | Guardfile |
-+  +---------+-----------+
-+  | Another | ✔         |
-+  | Even    | ✘         |
-+  | More    | ✘         |
-+  | Test    | ✔         |
-+  +---------+-----------+
-+      OUTPUT
-+    end
-+
-+    let(:another) { instance_double("Guard::Plugin", title: "Another") }
-+    let(:test) { instance_double("Guard::Plugin", title: "Test") }
-+
-+    before do
-+      allow(plugins).to receive(:all).with("another").and_return([another])
-+      allow(plugins).to receive(:all).with("test").and_return([test])
-+      allow(plugins).to receive(:all).with("even").and_return([])
-+      allow(plugins).to receive(:all).with("more").and_return([])
-+
-+      allow(Guard::PluginUtil).to receive(:plugin_names) do
-+        %w(test another even more)
-+      end
-+    end
-+
-+    it "lists the available Guards declared as strings or symbols" do
-+      subject.list
-+      expect(@output).to eq result
-+    end
-+  end
-+
-+  describe ".show" do
-+    let(:result) do
-+      <<-OUTPUT
-+  +---------+---------+--------+-------+
-+  | Group   | Plugin  | Option | Value |
-+  +---------+---------+--------+-------+
-+  | Default | Test    | a      | :b    |
-+  |         |         | c      | :d    |
-+  +---------+---------+--------+-------+
-+  | A       | Test    | x      | 1     |
-+  |         |         | y      | 2     |
-+  +---------+---------+--------+-------+
-+  | B       | Another |        |       |
-+  +---------+---------+--------+-------+
-+      OUTPUT
-+    end
-+
-+    before do
-+      allow(groups).to receive(:all).and_return [
-+        instance_double("Guard::Group", name: :default, title: "Default"),
-+        instance_double("Guard::Group", name: :a, title: "A"),
-+        instance_double("Guard::Group", name: :b, title: "B"),
-+      ]
-+
-+      allow(plugins).to receive(:all).with(group: :default) do
-+        options = { a: :b, c: :d }
-+        [instance_double("Guard::Plugin", title: "Test", options: options)]
-+      end
-+
-+      allow(plugins).to receive(:all).with(group: :a) do
-+        options = { x: 1, y: 2 }
-+        [instance_double("Guard::Plugin", title: "Test", options: options)]
-+      end
-+
-+      allow(plugins).to receive(:all).with(group: :b).and_return [
-+        instance_double("Guard::Plugin", title: "Another", options: [])
-+      ]
-+    end
-+
-+    it "shows the Guards and their options" do
-+      subject.show
-+      expect(@output).to eq result
-+    end
-+  end
-+
-+  describe ".notifiers" do
-+    let(:result) do
-+      <<-OUTPUT
-+  +----------------+-----------+------+--------+-------+
-+  | Name           | Available | Used | Option | Value |
-+  +----------------+-----------+------+--------+-------+
-+  | gntp           | ✔         | ✔    | sticky | true  |
-+  +----------------+-----------+------+--------+-------+
-+  | terminal_title | ✘         | ✘    |        |       |
-+  +----------------+-----------+------+--------+-------+
-+      OUTPUT
-+    end
-+
-+    before do
-+      allow(Guard::Notifier).to receive(:supported).and_return(
-+        gntp: ::Notiffany::Notifier::GNTP,
-+        terminal_title: ::Notiffany::Notifier::TerminalTitle
-+      )
-+
-+      allow(Guard::Notifier).to receive(:connect).once.ordered
-+      allow(Guard::Notifier).to receive(:detected).
-+        and_return([{ name: :gntp, options: { sticky: true } }])
-+
-+      allow(Guard::Notifier).to receive(:disconnect).once.ordered
-+    end
-+
-+    it "properly connects and disconnects" do
-+      expect(Guard::Notifier).to receive(:connect).once.ordered
-+      expect(::Guard::Notifier).to receive(:detected).once.ordered.and_return [
-+        { name: :gntp, options: { sticky: true } }
-+      ]
-+
-+      expect(Guard::Notifier).to receive(:disconnect).once.ordered
-+
-+      subject.notifiers
-+    end
-+
-+    it "shows the notifiers and their options" do
-+      subject.notifiers
-+      expect(@output).to eq result
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/dsl_reader_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/dsl_reader_spec.rb
-@@ -0,0 +1,58 @@
-+require "guard/dsl_reader"
-+
-+RSpec.describe Guard::DslReader, exclude_stubs: [Guard::Dsl] do
-+  methods = %w(
-+    initialize guard notification interactor group watch callback
-+    ignore ignore! logger scope directories clearing
-+  ).map(&:to_sym)
-+
-+  methods.each do |meth|
-+    describe "\##{meth} signature" do
-+      it "matches base signature" do
-+        expected = Guard::Dsl.instance_method(meth).arity
-+        expect(subject.method(meth).arity).to eq(expected)
-+      end
-+    end
-+  end
-+
-+  describe "guard" do
-+    context "when it is a String" do
-+      let(:name) { "foo" }
-+      it "works without errors" do
-+        expect { subject.guard(name, bar: :baz) }.to_not raise_error
-+      end
-+
-+      it "reports the name as a String" do
-+        subject.guard("foo", bar: :baz)
-+        expect(subject.plugin_names).to eq(%w(foo))
-+      end
-+    end
-+
-+    context "when it is a Symbol" do
-+      let(:name) { :foo }
-+      it "works without errors" do
-+        expect { subject.guard(name, bar: :baz) }.to_not raise_error
-+      end
-+
-+      it "reports the name as a String" do
-+        subject.guard(name, bar: :baz)
-+        expect(subject.plugin_names).to eq(%w(foo))
-+      end
-+    end
-+  end
-+
-+  describe "plugin_names" do
-+    it "returns encountered names" do
-+      subject.guard("foo", bar: :baz)
-+      subject.guard("bar", bar: :baz)
-+      subject.guard("baz", bar: :baz)
-+      expect(subject.plugin_names).to eq(%w(foo bar baz))
-+    end
-+  end
-+
-+  describe "notification" do
-+    it "handles arguments without errors" do
-+      expect { subject.notification(:off) }.to_not raise_error
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/dsl_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/dsl_spec.rb
-@@ -0,0 +1,671 @@
-+require "guard/plugin"
-+
-+require "guard/dsl"
-+
-+RSpec.describe Guard::Dsl do
-+  let(:ui_config) { instance_double("Guard::UI::Config") }
-+
-+  let(:guardfile_evaluator) { instance_double(Guard::Guardfile::Evaluator) }
-+  let(:interactor) { instance_double(Guard::Interactor) }
-+  let(:listener) { instance_double("Listen::Listener") }
-+
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+  let(:groups) { instance_double("Guard::Internals::Groups") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+
-+  let(:evaluator) do
-+    proc do |contents|
-+      Guard::Dsl.new.evaluate(contents, "", 1)
-+    end
-+  end
-+
-+  before do
-+    stub_user_guard_rb
-+    stub_const "Guard::Foo", instance_double(Guard::Plugin)
-+    stub_const "Guard::Bar", instance_double(Guard::Plugin)
-+    stub_const "Guard::Baz", instance_double(Guard::Plugin)
-+    allow(Guard::Notifier).to receive(:turn_on)
-+    allow(Guard::Interactor).to receive(:new).and_return(interactor)
-+
-+    allow(state).to receive(:scope).and_return(scope)
-+    allow(session).to receive(:plugins).and_return(plugins)
-+    allow(session).to receive(:groups).and_return(groups)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    # For backtrace cleanup
-+    allow(ENV).to receive(:[]).with("GEM_HOME").and_call_original
-+    allow(ENV).to receive(:[]).with("GEM_PATH").and_call_original
-+
-+    allow(Guard::UI::Config).to receive(:new).and_return(ui_config)
-+  end
-+
-+  describe "#ignore" do
-+    context "with ignore regexps" do
-+      let(:contents) { "ignore %r{^foo}, /bar/" }
-+
-+      it "adds ignored regexps to the listener" do
-+        expect(session).to receive(:guardfile_ignore=).with([/^foo/, /bar/])
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with multiple ignore calls" do
-+      let(:contents) { "ignore(/foo/); ignore(/bar/)" }
-+
-+      it "adds all ignored regexps to the listener" do
-+        expect(session).to receive(:guardfile_ignore=).with([/foo/]).once
-+        expect(session).to receive(:guardfile_ignore=).with([/bar/]).once
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  describe "#ignore!" do
-+    context "when ignoring only foo* and *bar*" do
-+      let(:contents) { "ignore! %r{^foo}, /bar/" }
-+
-+      it "replaces listener regexps" do
-+        expect(session).to receive(:guardfile_ignore_bang=).
-+          with([[/^foo/, /bar/]])
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "when ignoring *.txt and *.zip and ignoring! only foo*" do
-+      let(:contents) { "ignore! %r{.txt$}, /.*\\.zip/\n ignore! %r{^foo}" }
-+
-+      it "replaces listener ignores, but keeps ignore! ignores" do
-+        allow(session).to receive(:guardfile_ignore_bang=).
-+          with([[/.txt$/, /.*\.zip/]])
-+
-+        expect(session).to receive(:guardfile_ignore_bang=).
-+          with([[/.txt$/, /.*\.zip/], [/^foo/]])
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  # TODO: remove this hack (after deprecating filter)
-+  def method_for(klass, meth)
-+    klass.instance_method(meth)
-+  end
-+
-+  # TODO: deprecated #filter
-+  describe "#filter alias method" do
-+    subject { method_for(described_class, :filter) }
-+    it { is_expected.to eq(method_for(described_class, :ignore)) }
-+  end
-+
-+  # TODO: deprecated #filter
-+  describe "#filter! alias method" do
-+    subject { method_for(described_class, :filter!) }
-+    it { is_expected.to eq(method_for(described_class, :ignore!)) }
-+  end
-+
-+  describe "#notification" do
-+    context "when notification" do
-+      let(:contents) { "notification :growl" }
-+
-+      it "adds a notification to the notifier" do
-+        expect(session).to receive(:guardfile_notification=).with(growl: {})
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with multiple notifications" do
-+      let(:contents) do
-+        "notification :growl\nnotification :ruby_gntp, host: '192.168.1.5'"
-+      end
-+
-+      it "adds multiple notifiers" do
-+        expect(session).to receive(:guardfile_notification=).with(growl: {})
-+        expect(session).to receive(:guardfile_notification=).with(
-+          ruby_gntp: { host: "192.168.1.5" }
-+        )
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  describe "#interactor" do
-+    context "with interactor :off" do
-+      let(:contents) { "interactor :off" }
-+      it "disables the interactions with :off" do
-+        expect(Guard::Interactor).to receive(:enabled=).with(false)
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with interactor options" do
-+      let(:contents) { 'interactor option1: \'a\', option2: 123' }
-+      it "passes the options to the interactor" do
-+        expect(Guard::Interactor).to receive(:options=).
-+          with(option1: "a", option2: 123)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  describe "#group" do
-+    context "no plugins in group" do
-+      let(:contents) { "group :w" }
-+
-+      it "displays an error" do
-+        expect(::Guard::UI).to receive(:error).
-+          with("No Guard plugins found in the group 'w',"\
-+               " please add at least one.")
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "group named :all" do
-+      let(:contents) { "group :all" }
-+
-+      it "raises an error" do
-+        expect { evaluator.call(contents) }.
-+          to raise_error(
-+            Guard::Dsl::Error,
-+            /'all' is not an allowed group name!/
-+          )
-+      end
-+    end
-+
-+    context 'group named "all"' do
-+      let(:contents) { "group 'all'" }
-+
-+      it "raises an error" do
-+        expect { evaluator.call(contents) }.
-+          to raise_error(
-+            Guard::Dsl::Error,
-+            /'all' is not an allowed group name!/
-+          )
-+      end
-+    end
-+
-+    context "with a valid guardfile" do
-+      let(:contents) { valid_guardfile_string }
-+
-+      it "evaluates all groups" do
-+        expect(groups).to receive(:add).with(:w, {})
-+        expect(groups).to receive(:add).with(:y, {})
-+        expect(groups).to receive(:add).with(:x, halt_on_fail: true)
-+
-+        expect(plugins).to receive(:add).
-+          with(:pow, watchers: [], callbacks: [], group: :default)
-+
-+        expect(plugins).to receive(:add).
-+          with(:test, watchers: [], callbacks: [], group: :w)
-+
-+        expect(plugins).to receive(:add).
-+          with(:rspec, watchers: [], callbacks: [], group: :x).twice
-+
-+        expect(plugins).to receive(:add).
-+          with(:less, watchers: [], callbacks: [], group: :y)
-+
-+        expect(session).to receive(:guardfile_notification=).with(growl: {})
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with multiple names" do
-+      let(:contents) { "group :foo, :bar do; end" }
-+      it "adds all given groups" do
-+        expect(groups).to receive(:add).with(:foo, {})
-+        expect(groups).to receive(:add).with(:bar, {})
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  describe "#guard" do
-+    context "with single-quoted name" do
-+      let(:contents) { 'guard \'test\'' }
-+
-+      it "loads a guard specified as a quoted string from the DSL" do
-+        expect(plugins).to receive(:add).
-+          with("test", watchers: [], callbacks: [], group: :default)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with double-quoted name" do
-+      let(:contents) { 'guard "test"' }
-+
-+      it "loads a guard specified as a double quoted string from the DSL" do
-+        expect(plugins).to receive(:add).
-+          with("test", watchers: [], callbacks: [], group: :default)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with symbol for name" do
-+      let(:contents) { "guard :test" }
-+
-+      it "loads a guard specified as a symbol from the DSL" do
-+        expect(plugins).to receive(:add).
-+          with(:test, watchers: [], callbacks: [], group: :default)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with name as symbol in parens" do
-+      let(:contents) { "guard(:test)" }
-+
-+      it "adds the plugin" do
-+        expect(plugins).to receive(:add).
-+          with(:test, watchers: [], callbacks: [], group: :default)
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with options" do
-+      let(:contents) { 'guard \'test\', opt_a: 1, opt_b: \'fancy\'' }
-+
-+      it "passes options to plugin" do
-+        options = {
-+          watchers: [],
-+          callbacks: [],
-+          opt_a: 1,
-+          opt_b: "fancy",
-+          group: :default
-+        }
-+
-+        expect(plugins).to receive(:add).with("test", options)
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with groups" do
-+      let(:contents) { "group :foo do; group :bar do; guard :test; end; end" }
-+
-+      it "adds plugin with group info" do
-+        expect(groups).to receive(:add).with(:foo, {})
-+        expect(groups).to receive(:add).with(:bar, {})
-+        expect(plugins).to receive(:add).
-+          with(:test, watchers: [], callbacks: [], group: :bar)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with plugins in custom and default groups" do
-+      let(:contents) do
-+        "group :foo do; group :bar do; guard :test; end; end; guard :rspec"
-+      end
-+
-+      it "assigns plugins to correct groups" do
-+        expect(groups).to receive(:add).with(:foo, {})
-+        expect(groups).to receive(:add).with(:bar, {})
-+
-+        expect(plugins).to receive(:add).
-+          with(:test, watchers: [], callbacks: [], group: :bar)
-+
-+        expect(plugins).to receive(:add).
-+          with(:rspec, watchers: [], callbacks: [], group: :default)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  describe "#watch" do
-+    # TODO: this is testing too much
-+    context "with watchers" do
-+      let(:watcher_a) do
-+        instance_double("Guard::Watcher", pattern: "a", action: proc { "b" })
-+      end
-+
-+      let(:watcher_c) do
-+        instance_double("Guard::Watcher", pattern: "c", action: nil)
-+      end
-+
-+      let(:contents) do
-+        '
-+        guard :dummy do
-+           watch(\'a\') { \'b\' }
-+           watch(\'c\')
-+        end'
-+      end
-+
-+      it "should receive watchers when specified" do
-+        call_params = {
-+          watchers: [anything, anything],
-+          callbacks: [],
-+          group: :default
-+        }
-+
-+        expect(plugins).to receive(:add).
-+          with(:dummy, call_params) do |_, options|
-+          expect(options[:watchers].size).to eq 2
-+          expect(options[:watchers][0].pattern).to eq "a"
-+          expect(options[:watchers][0].action.call).to eq proc { "b" }.call
-+          expect(options[:watchers][1].pattern).to eq "c"
-+          expect(options[:watchers][1].action).to be_nil
-+        end
-+
-+        allow(Guard::Watcher).to receive(:new).with("a", anything).
-+          and_return(watcher_a)
-+
-+        allow(Guard::Watcher).to receive(:new).with("c", nil).
-+          and_return(watcher_c)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with watch in main scope" do
-+      let(:contents) { 'watch(\'a\')' }
-+      let(:watcher) do
-+        instance_double("Guard::Watcher", pattern: "a", action: nil)
-+      end
-+
-+      it "should create an implicit no-op guard when outside a guard block" do
-+        plugin_options = {
-+          watchers: [anything],
-+          callbacks: [],
-+          group: :default
-+        }
-+
-+        expect(plugins).to receive(:add).
-+          with(:plugin, plugin_options) do |_, options|
-+          expect(options[:watchers].size).to eq 1
-+          expect(options[:watchers][0].pattern).to eq "a"
-+          expect(options[:watchers][0].action).to be_nil
-+        end
-+
-+        allow(Guard::Watcher).to receive(:new).with("a", nil).
-+          and_return(watcher)
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  describe "#callback" do
-+    context "with " do
-+      let(:contents) do
-+        '
-+        guard :rspec do
-+
-+          callback(:start_end) do |plugin, event, args|
-+            "#{plugin.title} executed \'#{event}\' hook with #{args}!"
-+          end
-+
-+          callback(MyCustomCallback, [:start_begin, :run_all_begin])
-+        end'
-+      end
-+
-+      it "creates callbacks for the guard" do
-+        class MyCustomCallback
-+          def self.call(_plugin, _event, _args)
-+            # do nothing
-+          end
-+        end
-+
-+        params = {
-+          watchers: [],
-+          callbacks: [anything, anything],
-+          group: :default
-+        }
-+
-+        expect(plugins).to receive(:add).with(:rspec, params) do |_, opt|
-+          # TODO: this whole block is too verbose, tests too many things at
-+          # once and needs refactoring
-+
-+          expect(opt[:callbacks].size).to eq 2
-+
-+          callback_0 = opt[:callbacks][0]
-+
-+          expect(callback_0[:events]).to eq :start_end
-+
-+          plugin = instance_double("Guard::Plugin", title: "RSpec")
-+          result = callback_0[:listener].call(plugin, :start_end, "foo")
-+
-+          expect(result).to eq 'RSpec executed \'start_end\' hook'\
-+            " with foo!"
-+
-+          callback_1 = opt[:callbacks][1]
-+          expect(callback_1[:events]).to eq [:start_begin, :run_all_begin]
-+          expect(callback_1[:listener]).to eq MyCustomCallback
-+        end
-+
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "without a guard block" do
-+      let(:contents) do
-+        '
-+        callback(:start_end) do |plugin, event, args|
-+          "#{plugin} executed \'#{event}\' hook with #{args}!"
-+        end
-+
-+        callback(MyCustomCallback, [:start_begin, :run_all_begin])'
-+      end
-+
-+      it "fails" do
-+        expect { evaluator.call(contents) }.to raise_error(/guard block/i)
-+      end
-+    end
-+  end
-+
-+  describe "#logger" do
-+    before do
-+      Guard::UI.options = nil
-+      allow(ui_config).to receive(:merge!)
-+    end
-+
-+    after do
-+      Guard::UI.reset_logger
-+      Guard::UI.options = nil
-+    end
-+
-+    describe "options" do
-+      let(:contents) { "" }
-+
-+      before do
-+        evaluator.call(contents)
-+      end
-+
-+      subject { ui_config }
-+
-+      context "with logger level :errror" do
-+        let(:contents) { "logger level: :error" }
-+        it { is_expected.to have_received(:merge!).with(level: :error) }
-+      end
-+
-+      context "with logger level 'errror'" do
-+        let(:contents) { 'logger level: \'error\'' }
-+        it { is_expected.to have_received(:merge!).with(level: :error) }
-+      end
-+
-+      context "with logger template" do
-+        let(:contents) { 'logger template: \':message - :severity\'' }
-+        it do
-+          is_expected.to have_received(:merge!).
-+            with(template: ":message - :severity")
-+        end
-+      end
-+
-+      context "with a logger time format" do
-+        let(:contents) { 'logger time_format: \'%Y\'' }
-+        it { is_expected.to have_received(:merge!).with(time_format: "%Y") }
-+      end
-+
-+      context "with a logger only filter from a symbol" do
-+        let(:contents) { "logger only: :cucumber" }
-+        it { is_expected.to have_received(:merge!).with(only: /cucumber/i) }
-+      end
-+
-+      context "with logger only filter from a string" do
-+        let(:contents) { 'logger only: \'jasmine\'' }
-+        it { is_expected.to have_received(:merge!).with(only: /jasmine/i) }
-+      end
-+
-+      context "with logger only filter from an array of symbols and string" do
-+        let(:contents) { 'logger only: [:rspec, \'cucumber\']' }
-+        it do
-+          is_expected.to have_received(:merge!).
-+            with(only: /rspec|cucumber/i)
-+        end
-+      end
-+
-+      context "with logger except filter from a symbol" do
-+        let(:contents) { "logger except: :jasmine" }
-+        it { is_expected.to have_received(:merge!).with(except: /jasmine/i) }
-+      end
-+
-+      context "with logger except filter from a string" do
-+        let(:contents) { 'logger except: \'jasmine\'' }
-+        it { is_expected.to have_received(:merge!).with(except: /jasmine/i) }
-+      end
-+
-+      context "with logger except filter from array of symbols and string" do
-+        let(:contents) { 'logger except: [:rspec, \'cucumber\', :jasmine]' }
-+        it do
-+          is_expected.to have_received(:merge!).
-+            with(except: /rspec|cucumber|jasmine/i)
-+        end
-+      end
-+    end
-+
-+    context "with invalid options" do
-+      context "for the log level" do
-+        let(:contents) { "logger level: :baz" }
-+
-+        it "shows a warning" do
-+          expect(Guard::UI).to receive(:warning).
-+            with "Invalid log level `baz` ignored."\
-+            " Please use either :debug, :info, :warn or :error."
-+
-+          evaluator.call(contents)
-+        end
-+
-+        it "does not set the invalid value" do
-+          expect(ui_config).to receive(:merge!).with({})
-+          evaluator.call(contents)
-+        end
-+      end
-+
-+      context "when having both the :only and :except options" do
-+        let(:contents) { "logger only: :jasmine, except: :rspec" }
-+
-+        it "shows a warning" do
-+          expect(Guard::UI).to receive(:warning).
-+            with "You cannot specify the logger options"\
-+            " :only and :except at the same time."
-+          evaluator.call(contents)
-+        end
-+
-+        it "removes the options" do
-+          expect(ui_config).to receive(:merge!).with({})
-+          evaluator.call(contents)
-+        end
-+      end
-+    end
-+  end
-+
-+  describe "#scope" do
-+    context "with any parameters" do
-+      let(:contents) { "scope plugins: [:foo, :bar]" }
-+
-+      it "sets the guardfile's default scope" do
-+        expect(session).to receive(:guardfile_scope).with(plugins: [:foo, :bar])
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  describe "#directories" do
-+    context "with valid directories" do
-+      let(:contents) { "directories %w(foo bar)" }
-+      before do
-+        allow(Dir).to receive(:exist?).with("foo").and_return(true)
-+        allow(Dir).to receive(:exist?).with("bar").and_return(true)
-+      end
-+
-+      it "sets the watchdirs to given values" do
-+        expect(session).to receive(:watchdirs=).with(%w(foo bar))
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with no parameters" do
-+      let(:contents) { "directories []" }
-+
-+      it "sets the watchdirs to empty" do
-+        expect(session).to receive(:watchdirs=).with([])
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with non-existing directory" do
-+      let(:contents) { "directories ['foo']" }
-+
-+      before do
-+        allow(Dir).to receive(:exist?).with("foo").and_return(false)
-+      end
-+
-+      it "fails with an error" do
-+        expect(session).to_not receive(:watchdirs=)
-+        expect do
-+          evaluator.call(contents)
-+        end.to raise_error(Guard::Dsl::Error, /Directory "foo" does not exist!/)
-+      end
-+    end
-+  end
-+
-+  describe "#clear" do
-+    context "with clear :off" do
-+      let(:contents) { "clearing :off" }
-+      it "disables clearing the screen after every task" do
-+        expect(session).to receive(:clearing).with(false)
-+        evaluator.call(contents)
-+      end
-+    end
-+
-+    context "with clear :on" do
-+      let(:contents) { "clearing :on" }
-+      it "enabled clearing the screen after every task" do
-+        expect(session).to receive(:clearing).with(true)
-+        evaluator.call(contents)
-+      end
-+    end
-+  end
-+
-+  private
-+
-+  def valid_guardfile_string
-+    '
-+    notification :growl
-+
-+    guard :pow
-+
-+    group :w do
-+      guard :test
-+    end
-+
-+    group :x, halt_on_fail: true do
-+      guard :rspec
-+      guard :rspec
-+    end
-+
-+    group :y do
-+      guard :less
-+    end
-+    '
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/group_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/group_spec.rb
-@@ -0,0 +1,34 @@
-+require "guard/group"
-+
-+RSpec.describe Guard::Group do
-+  subject { described_class.new(name, options) }
-+
-+  let(:name) { :foo }
-+  let(:options) { {} }
-+
-+  describe "#name" do
-+    specify { expect(subject.name).to eq :foo }
-+
-+    context "when initialized from a string" do
-+      let(:name) { "foo" }
-+      specify { expect(subject.name).to eq :foo }
-+    end
-+  end
-+
-+  describe "#options" do
-+    context "when provided" do
-+      let(:options) { { halt_on_fail: true } }
-+      specify { expect(subject.options).to eq options }
-+    end
-+  end
-+
-+  describe "#title" do
-+    specify { expect(subject.title).to eq "Foo" }
-+  end
-+
-+  describe "#to_s" do
-+    specify do
-+      expect(subject.to_s).to eq "#<Guard::Group @name=foo @options={}>"
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/guardfile/evaluator_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/guardfile/evaluator_spec.rb
-@@ -0,0 +1,220 @@
-+require "guard/guardfile/evaluator"
-+
-+# TODO: shouldn't be necessary
-+require "guard"
-+
-+RSpec.describe Guard::Guardfile::Evaluator do
-+  let(:options) { {} }
-+  subject { described_class.new(options) }
-+
-+  let!(:local_guardfile) { (Pathname.pwd + "Guardfile").to_s }
-+  let!(:home_guardfile) { (Pathname("~").expand_path + ".Guardfile").to_s }
-+  let!(:home_config) { (Pathname("~").expand_path + ".guard.rb").to_s }
-+
-+  let(:valid_guardfile_string) { "group :foo; do guard :bar; end; end; " }
-+
-+  let(:dsl) { instance_double("Guard::Dsl") }
-+
-+  let(:rel_guardfile) do
-+    Pathname("../relative_path_to_Guardfile").expand_path.to_s
-+  end
-+
-+  before do
-+    allow(Guard::Interactor).to receive(:new).with(false)
-+    allow(Guard::Dsl).to receive(:new).and_return(dsl)
-+    allow(dsl).to receive(:instance_eval)
-+  end
-+
-+  describe ".evaluate" do
-+    describe "error cases" do
-+      context "with an invalid Guardfile" do
-+        let(:options) { { contents: "guard :foo Bad Guardfile" } }
-+
-+        it "displays an error message and raises original exception" do
-+          stub_user_guard_rb
-+
-+          allow(dsl).to receive(:evaluate).
-+            and_raise(Guard::Dsl::Error,
-+                      "Invalid Guardfile, original error is:")
-+
-+          expect { subject.evaluate }.to raise_error(Guard::Dsl::Error)
-+        end
-+      end
-+
-+      context "with no Guardfile at all" do
-+        it "displays an error message and exits" do
-+          stub_guardfile
-+          stub_user_guardfile
-+          stub_user_project_guardfile
-+
-+          expect { subject.evaluate }.
-+            to raise_error(Guard::Guardfile::Evaluator::NoGuardfileError)
-+        end
-+      end
-+
-+      context "with a problem reading a Guardfile" do
-+        let(:path) { File.expand_path("Guardfile") }
-+
-+        before do
-+          stub_user_project_guardfile
-+          stub_guardfile(" ") do
-+            fail Errno::EACCES.new("permission error")
-+          end
-+        end
-+
-+        it "displays an error message and exits" do
-+          expect(Guard::UI).to receive(:error).with(/^Error reading file/)
-+          expect { subject.evaluate }.to raise_error(SystemExit)
-+        end
-+      end
-+
-+      context "with empty Guardfile content" do
-+        let(:options) { { contents: "" } }
-+
-+        it "displays an error message about no plugins" do
-+          stub_user_guard_rb
-+          stub_guardfile(" ")
-+          allow(dsl).to receive(:evaluate).with("", "", 1)
-+
-+          expect { subject.evaluate }.
-+            to raise_error(Guard::Guardfile::Evaluator::NoPluginsError)
-+        end
-+      end
-+
-+      context "when provided :contents is nil" do
-+        before do
-+          # Anything
-+          stub_guardfile("guard :foo")
-+
-+          stub_user_guard_rb
-+          stub_user_project_guardfile
-+          stub_user_guardfile
-+        end
-+
-+        it "does not raise error and skip it" do
-+          allow(dsl).to receive(:evaluate).with("guard :foo", anything, 1)
-+
-+          expect(Guard::UI).to_not receive(:error)
-+          expect do
-+            described_class.new(contents: nil).evaluate
-+          end.to_not raise_error
-+        end
-+      end
-+
-+      context "with a non-existing Guardfile given" do
-+        let(:non_existing_path) { "/non/existing/path/to/Guardfile" }
-+        let(:options) { { guardfile: non_existing_path } }
-+
-+        before do
-+          stub_file(non_existing_path)
-+        end
-+
-+        it "raises error" do
-+          expect { subject.evaluate }.
-+            to raise_error(Guard::Guardfile::Evaluator::NoCustomGuardfile)
-+        end
-+      end
-+    end
-+
-+    describe "selection of the Guardfile data contents" do
-+      context "with a valid :contents option" do
-+        before do
-+          stub_user_guard_rb
-+          allow(dsl).to receive(:evaluate)
-+        end
-+
-+        context "with inline content and other Guardfiles available" do
-+          let(:inline_code) { "guard :foo" }
-+          let(:options) do
-+            {
-+              contents: inline_code,
-+              guardfile: "/abc/Guardfile"
-+            }
-+          end
-+
-+          before do
-+            stub_file("/abc/Guardfile", "guard :bar")
-+            stub_guardfile("guard :baz")
-+            stub_user_guardfile("guard :buz")
-+          end
-+
-+          it "gives ultimate precedence to inline content" do
-+            expect(dsl).to receive(:evaluate).with(inline_code, "", 1)
-+            subject.evaluate
-+          end
-+        end
-+      end
-+
-+      context "with the :guardfile option" do
-+        let(:options) { { guardfile: "../relative_path_to_Guardfile" } }
-+
-+        before do
-+          stub_file(File.expand_path("../relative_path_to_Guardfile"),
-+                    valid_guardfile_string)
-+          allow(dsl).to receive(:evaluate).
-+            with(valid_guardfile_string, anything, 1)
-+        end
-+      end
-+    end
-+  end
-+
-+  describe "#inline?" do
-+    before do
-+      allow(dsl).to receive(:evaluate)
-+      stub_guardfile("guard :bar")
-+      stub_user_guard_rb
-+      subject.evaluate
-+    end
-+
-+    context "when content is provided" do
-+      let(:options) { { guardfile_contents: "guard :foo" } }
-+      it { is_expected.to be_inline }
-+    end
-+
-+    context "when no content is provided" do
-+      let(:options) { {} }
-+      it { is_expected.to_not be_inline }
-+    end
-+  end
-+
-+  describe ".guardfile_include?" do
-+    subject do
-+      evaluator = described_class.new(options)
-+      evaluator.evaluate
-+      evaluator
-+    end
-+
-+    let(:dsl_reader) { instance_double(Guard::DslReader) }
-+
-+    before do
-+      allow(dsl).to receive(:evaluate)
-+      allow(Guard::DslReader).to receive(:new).and_return(dsl_reader)
-+      allow(dsl_reader).to receive(:evaluate)
-+      stub_user_guard_rb
-+    end
-+
-+    context "when plugin is present" do
-+      let(:options) { { contents: 'guard "test" {watch("c")}' } }
-+
-+      it "returns true" do
-+        allow(dsl_reader).
-+          to receive(:evaluate).with('guard "test" {watch("c")}', "", 1)
-+
-+        allow(dsl_reader).to receive(:plugin_names).and_return(["test"])
-+        expect(subject).to be_guardfile_include("test")
-+      end
-+    end
-+
-+    context "when plugin is not present" do
-+      let(:options) { { contents: 'guard "other" {watch("c")}' } }
-+
-+      it "returns false" do
-+        allow(dsl_reader).
-+          to receive(:evaluate).with('guard "test" {watch("c")}', "", 1)
-+
-+        allow(dsl_reader).to receive(:plugin_names).and_return(["other"])
-+        expect(subject).to_not be_guardfile_include("test")
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/guardfile/generator_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/guardfile/generator_spec.rb
-@@ -0,0 +1,141 @@
-+require "guard/guardfile/generator"
-+
-+RSpec.describe Guard::Guardfile::Generator do
-+  let(:plugin_util) { instance_double("Guard::PluginUtil") }
-+  let(:guardfile_generator) { described_class.new }
-+
-+  it "has a valid Guardfile template" do
-+    allow(File).to receive(:exist?).
-+      with(described_class::GUARDFILE_TEMPLATE).and_call_original
-+
-+    expect(File.exist?(described_class::GUARDFILE_TEMPLATE)).to be_truthy
-+  end
-+
-+  describe "#create_guardfile" do
-+    context "with an existing Guardfile" do
-+      before do
-+        allow_any_instance_of(Pathname).to receive(:exist?).and_return(true)
-+      end
-+
-+      it "does not copy the Guardfile template or notify the user" do
-+        expect(::Guard::UI).to_not receive(:info)
-+        expect(FileUtils).to_not receive(:cp)
-+        begin
-+          subject.create_guardfile
-+        rescue SystemExit
-+        end
-+      end
-+
-+      it "does not display information" do
-+        expect(::Guard::UI).to_not receive(:info)
-+        begin
-+          subject.create_guardfile
-+        rescue SystemExit
-+        end
-+      end
-+
-+      it "displays an error message" do
-+        expect(::Guard::UI).to receive(:error).
-+          with(%r{Guardfile already exists at .*/Guardfile})
-+        begin
-+          subject.create_guardfile
-+        rescue SystemExit
-+        end
-+      end
-+
-+      it "aborts" do
-+        expect { subject.create_guardfile }.to raise_error(SystemExit)
-+      end
-+    end
-+
-+    context "without an existing Guardfile" do
-+      before do
-+        allow_any_instance_of(Pathname).to receive(:exist?).and_return(false)
-+        allow(FileUtils).to receive(:cp)
-+      end
-+
-+      it "does not display any kind of error or abort" do
-+        expect(::Guard::UI).to_not receive(:error)
-+        expect(described_class).to_not receive(:abort)
-+        described_class.new.create_guardfile
-+      end
-+
-+      it "copies the Guardfile template and notifies the user" do
-+        expect(::Guard::UI).to receive(:info)
-+        expect(FileUtils).to receive(:cp)
-+
-+        described_class.new.create_guardfile
-+      end
-+    end
-+  end
-+
-+  describe "#initialize_template" do
-+    context "with an installed Guard implementation" do
-+      before do
-+        expect(Guard::PluginUtil).to receive(:new) { plugin_util }
-+
-+        expect(plugin_util).to receive(:plugin_class) do
-+          double("Guard::Foo").as_null_object
-+        end
-+      end
-+
-+      it "initializes the Guard" do
-+        expect(plugin_util).to receive(:add_to_guardfile)
-+        described_class.new.initialize_template("foo")
-+      end
-+    end
-+
-+    context "with a user defined template" do
-+      let(:template) { File.join(described_class::HOME_TEMPLATES, "/bar") }
-+
-+      it "copies the Guardfile template and initializes the Guard" do
-+        expect(IO).to receive(:read).
-+          with(template).and_return "Template content"
-+
-+        expected = "\nTemplate content\n"
-+
-+        expect(IO).to receive(:binwrite).
-+          with("Guardfile", expected, open_args: ["a"])
-+
-+        allow(plugin_util).to receive(:plugin_class).with(fail_gracefully: true)
-+
-+        allow(Guard::PluginUtil).to receive(:new).with("bar").
-+          and_return(plugin_util)
-+
-+        described_class.new.initialize_template("bar")
-+      end
-+    end
-+
-+    context "when the passed guard can't be found" do
-+      before do
-+        expect(::Guard::PluginUtil).to receive(:new) { plugin_util }
-+        allow(plugin_util).to receive(:plugin_class) { nil }
-+        path = File.expand_path("~/.guard/templates/foo")
-+        expect(IO).to receive(:read).with(path) do
-+          fail Errno::ENOENT
-+        end
-+      end
-+
-+      it "notifies the user about the problem" do
-+        expect { described_class.new.initialize_template("foo") }.
-+          to raise_error(Guard::Guardfile::Generator::Error)
-+      end
-+    end
-+  end
-+
-+  describe "#initialize_all_templates" do
-+    let(:plugins) { %w(rspec spork phpunit) }
-+
-+    before do
-+      expect(::Guard::PluginUtil).to receive(:plugin_names) { plugins }
-+    end
-+
-+    it "calls Guard.initialize_template on all installed plugins" do
-+      plugins.each do |g|
-+        expect(subject).to receive(:initialize_template).with(g)
-+      end
-+
-+      subject.initialize_all_templates
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/interactor_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/interactor_spec.rb
-@@ -0,0 +1,166 @@
-+require "guard/interactor"
-+
-+# TODO: this shouldn't be necessary
-+require "guard/jobs/pry_wrapper"
-+require "guard/jobs/sleep"
-+
-+RSpec.describe Guard::Interactor do
-+  let!(:pry_interactor) { instance_double("Guard::Jobs::PryWrapper") }
-+  let!(:sleep_interactor) { instance_double("Guard::Jobs::Sleep") }
-+  let(:pry_class) { class_double("Guard::Jobs::PryWrapper") }
-+  let(:sleep_class) { class_double("Guard::Jobs::Sleep") }
-+
-+  before do
-+    stub_const("Guard::Jobs::PryWrapper", pry_class)
-+    stub_const("Guard::Jobs::Sleep", sleep_class)
-+
-+    allow(Guard::Jobs::PryWrapper).to receive(:new).and_return(pry_interactor)
-+    allow(Guard::Jobs::Sleep).to receive(:new).and_return(sleep_interactor)
-+
-+    @interactor_enabled = described_class.enabled?
-+    described_class.enabled = nil
-+  end
-+
-+  after { described_class.enabled = @interactor_enabled }
-+
-+  describe ".enabled & .enabled=" do
-+    it "returns true by default" do
-+      expect(described_class).to be_enabled
-+    end
-+
-+    context "interactor not enabled" do
-+      before { described_class.enabled = false }
-+
-+      it "returns false" do
-+        expect(described_class).to_not be_enabled
-+      end
-+    end
-+  end
-+
-+  describe ".options & .options=" do
-+    before { described_class.options = nil }
-+
-+    it "returns {} by default" do
-+      expect(described_class.options).to eq({})
-+    end
-+
-+    context "options set to { foo: :bar }" do
-+      before { described_class.options = { foo: :bar } }
-+
-+      it "returns { foo: :bar }" do
-+        expect(described_class.options).to eq(foo: :bar)
-+      end
-+    end
-+  end
-+
-+  context "when enabled" do
-+    before { described_class.enabled = true }
-+
-+    describe "#foreground" do
-+      it "starts Pry" do
-+        expect(pry_interactor).to receive(:foreground)
-+        subject.foreground
-+      end
-+    end
-+
-+    describe "#background" do
-+      it "hides Pry" do
-+        expect(pry_interactor).to receive(:background)
-+        subject.background
-+      end
-+    end
-+
-+    describe "#handle_interrupt" do
-+      it "interrupts Pry" do
-+        expect(pry_interactor).to receive(:handle_interrupt)
-+        subject.handle_interrupt
-+      end
-+    end
-+  end
-+
-+  context "when disabled" do
-+    before { described_class.enabled = false }
-+
-+    describe "#foreground" do
-+      it "sleeps" do
-+        expect(sleep_interactor).to receive(:foreground)
-+        subject.foreground
-+      end
-+    end
-+
-+    describe "#background" do
-+      it "wakes up from sleep" do
-+        expect(sleep_interactor).to receive(:background)
-+        subject.background
-+      end
-+    end
-+
-+    describe "#handle_interrupt" do
-+      it "interrupts sleep" do
-+        expect(sleep_interactor).to receive(:handle_interrupt)
-+        subject.handle_interrupt
-+      end
-+    end
-+  end
-+
-+  describe "job selection" do
-+    subject do
-+      Guard::Interactor.new(no_interactions)
-+      Guard::Interactor
-+    end
-+
-+    before do
-+      Guard::Interactor.enabled = dsl_enabled
-+    end
-+
-+    context "when enabled from the DSL" do
-+      let(:dsl_enabled) { true }
-+
-+      context "when enabled from the commandline" do
-+        let(:no_interactions) { false }
-+        it "uses only pry" do
-+          expect(pry_class).to receive(:new)
-+          expect(sleep_class).to_not receive(:new)
-+          subject
-+        end
-+        it { is_expected.to be_enabled }
-+      end
-+
-+      context "when disabled from the commandline" do
-+        let(:no_interactions) { true }
-+        it "uses only sleeper" do
-+          expect(pry_class).to_not receive(:new)
-+          expect(sleep_class).to receive(:new)
-+          subject
-+        end
-+
-+        # TODO: this is both a useless case and incorrect value
-+        it { is_expected.to be_enabled }
-+      end
-+    end
-+
-+    context "when disabled from the DSL" do
-+      let(:dsl_enabled) { false }
-+
-+      context "when enabled from the commandline" do
-+        let(:no_interactions) { false }
-+        it "uses only sleeper" do
-+          expect(pry_class).to_not receive(:new)
-+          expect(sleep_class).to receive(:new)
-+          subject
-+        end
-+        it { is_expected.to_not be_enabled }
-+      end
-+
-+      context "when disabled from the commandline" do
-+        let(:no_interactions) { true }
-+        it "uses only sleeper" do
-+          expect(pry_class).to_not receive(:new)
-+          expect(sleep_class).to receive(:new)
-+          subject
-+        end
-+        it { is_expected.to_not be_enabled }
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/debugging_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/debugging_spec.rb
-@@ -0,0 +1,112 @@
-+require "guard/internals/debugging"
-+
-+RSpec.describe Guard::Internals::Debugging do
-+  let(:null) { IO::NULL }
-+  let(:ui) { class_double(::Guard::UI) }
-+  let(:tracing) { class_spy(::Guard::Internals::Tracing) }
-+
-+  before do
-+    stub_const("::Guard::Internals::Tracing", tracing)
-+    stub_const("::Guard::UI", ui)
-+    allow(ui).to receive(:debug)
-+    allow(ui).to receive(:level=)
-+    allow(Thread).to receive(:abort_on_exception=)
-+  end
-+
-+  after do
-+    described_class.send(:_reset)
-+  end
-+
-+  describe "#start" do
-+    it "traces Kernel.system" do
-+      expect(tracing).to receive(:trace).with(Kernel, :system) do |*_, &block|
-+        expect(ui).to receive(:debug).with("Command execution: foo")
-+        block.call "foo"
-+      end
-+      described_class.start
-+    end
-+
-+    it "traces Kernel.`" do
-+      expect(tracing).to receive(:trace).with(Kernel, :`) do |*_, &block|
-+        expect(ui).to receive(:debug).with("Command execution: foo")
-+        block.call("foo")
-+      end
-+
-+      described_class.start
-+    end
-+
-+    it "traces Open3.popen3" do
-+      expect(tracing).to receive(:trace).with(Open3, :popen3) do |*_, &block|
-+        expect(ui).to receive(:debug).with("Command execution: foo")
-+        block.call("foo")
-+      end
-+
-+      described_class.start
-+    end
-+
-+    it "traces Kernel.spawn" do
-+      expect(tracing).to receive(:trace).with(Kernel, :spawn) do |*_, &block|
-+        expect(ui).to receive(:debug).with("Command execution: foo")
-+        block.call("foo")
-+      end
-+
-+      described_class.start
-+    end
-+
-+    context "when not started" do
-+      before { described_class.start }
-+
-+      it "sets logger to debug" do
-+        expect(ui).to have_received(:level=).with(Logger::DEBUG)
-+      end
-+
-+      it "makes threads abort on exceptions" do
-+        expect(Thread).to have_received(:abort_on_exception=).with(true)
-+      end
-+    end
-+
-+    context "when already started" do
-+      before do
-+        allow(tracing).to receive(:trace)
-+        described_class.start
-+      end
-+
-+      it "does not set log level" do
-+        expect(ui).to_not receive(:level=)
-+        described_class.start
-+      end
-+    end
-+  end
-+
-+  describe "#stop" do
-+    context "when already started" do
-+      before do
-+        described_class.start
-+        described_class.stop
-+      end
-+
-+      it "sets logger level to info" do
-+        expect(ui).to have_received(:level=).with(Logger::INFO)
-+      end
-+
-+      it "untraces Kernel.system" do
-+        expect(tracing).to have_received(:untrace).with(Kernel, :system)
-+      end
-+
-+      it "untraces Kernel.`" do
-+        expect(tracing).to have_received(:untrace).with(Kernel, :`)
-+      end
-+
-+      it "untraces Open3.popen3" do
-+        expect(tracing).to have_received(:untrace).with(Kernel, :popen3)
-+      end
-+    end
-+
-+    context "when not started" do
-+      it "does not set logger level" do
-+        described_class.stop
-+        expect(ui).to_not have_received(:level=)
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/groups_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/groups_spec.rb
-@@ -0,0 +1,121 @@
-+require "guard/internals/groups"
-+
-+RSpec.describe Guard::Internals::Groups do
-+  describe "#all" do
-+    let(:common) { instance_double("Guard::Group", name: :common) }
-+    let(:default) { instance_double("Guard::Group", name: :default) }
-+
-+    before do
-+      allow(Guard::Group).to receive(:new).with(:common).and_return(common)
-+      allow(Guard::Group).to receive(:new).with(:default).and_return(default)
-+    end
-+
-+    context "with only default groups" do
-+      it "initializes the groups" do
-+        expect(subject.all.map(&:name)).to eq [:common, :default]
-+      end
-+    end
-+
-+    context "with existing groups" do
-+      let(:frontend) { instance_double("Guard::Group", name: :frontend) }
-+      let(:backend) { instance_double("Guard::Group", name: :backend) }
-+
-+      before do
-+        allow(Guard::Group).to receive(:new).with(:frontend, {}).
-+          and_return(frontend)
-+
-+        allow(Guard::Group).to receive(:new).with(:backend, {}).
-+          and_return(backend)
-+
-+        subject.add(:frontend)
-+        subject.add(:backend)
-+      end
-+
-+      context "with no arguments" do
-+        let(:args) { [] }
-+        it "returns all groups" do
-+          expect(subject.all(*args)).to eq [common, default, frontend, backend]
-+        end
-+      end
-+
-+      context "with a string argument" do
-+        it "returns an array of groups if plugins are found" do
-+          expect(subject.all("backend")).to eq [backend]
-+        end
-+      end
-+
-+      context "with a symbol argument matching a group" do
-+        it "returns an array of groups if plugins are found" do
-+          expect(subject.all(:backend)).to eq [backend]
-+        end
-+      end
-+
-+      context "with a symbol argument not matching a group" do
-+        it "returns an empty array when no group is found" do
-+          expect(subject.all(:foo)).to be_empty
-+        end
-+      end
-+
-+      context "with a regexp argument matching a group" do
-+        it "returns an array of groups" do
-+          expect(subject.all(/^back/)).to eq [backend]
-+        end
-+      end
-+
-+      context "with a regexp argument not matching a group" do
-+        it "returns an empty array when no group is found" do
-+          expect(subject.all(/back$/)).to be_empty
-+        end
-+      end
-+    end
-+  end
-+
-+  # TOOD: test adding with options
-+  describe "#add" do
-+    let(:common) { instance_double("Guard::Group", name: :common) }
-+    let(:default) { instance_double("Guard::Group", name: :default) }
-+
-+    before do
-+      allow(Guard::Group).to receive(:new).with(:common).and_return(common)
-+      allow(Guard::Group).to receive(:new).with(:default).and_return(default)
-+    end
-+
-+    context "with existing groups" do
-+      let(:frontend) { instance_double("Guard::Group", name: :frontend) }
-+      let(:backend) { instance_double("Guard::Group", name: :backend) }
-+
-+      before do
-+        allow(Guard::Group).to receive(:new).with("frontend", {}).
-+          and_return(frontend)
-+
-+        subject.add("frontend")
-+      end
-+
-+      it "add the given group" do
-+        subject.add("frontend")
-+        expect(subject.all).to match_array([common, default, frontend])
-+      end
-+
-+      it "add the given group with options" do
-+        subject.add("frontend", foo: :bar)
-+        expect(subject.all).to match_array([common, default, frontend])
-+      end
-+
-+      # TODO: what if group is added multiple times with different options?
-+
-+      context "with an existing group" do
-+        before { subject.add("frontend") }
-+
-+        it "does not add duplicate groups when name is a string" do
-+          subject.add("frontend")
-+          expect(subject.all).to match_array([common, default, frontend])
-+        end
-+
-+        it "does not add duplicate groups when name is a symbol" do
-+          subject.add(:frontend)
-+          expect(subject.all).to match_array([common, default, frontend])
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/plugins_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/plugins_spec.rb
-@@ -0,0 +1,138 @@
-+require "guard/internals/plugins"
-+
-+RSpec.describe Guard::Internals::Plugins do
-+  def stub_plugin(name, group)
-+    instance_double("Guard::Plugin", name: name, group: group)
-+  end
-+
-+  # TODO: all this is crazy
-+  let(:frontend) { instance_double("Guard::Group", name: :frontend) }
-+  let(:backend) { instance_double("Guard::Group", name: :backend) }
-+
-+  let(:foo_bar_frontend) { stub_plugin("foobar", frontend) }
-+  let(:foo_baz_frontend) { stub_plugin("foobaz", frontend) }
-+  let(:foo_bar_backend) { stub_plugin("foobar", backend) }
-+  let(:foo_baz_backend) { stub_plugin("foobaz", backend) }
-+
-+  let(:pu_foobar) { instance_double("Guard::PluginUtil") }
-+  let(:pu_foobaz) { instance_double("Guard::PluginUtil") }
-+
-+  before do
-+    allow(Guard::PluginUtil).to receive(:new).with("foobar").
-+      and_return(pu_foobar)
-+
-+    allow(Guard::PluginUtil).to receive(:new).with("foobaz").
-+      and_return(pu_foobaz)
-+
-+    allow(pu_foobar).to receive(:initialize_plugin).with(group: "frontend").
-+      and_return(foo_bar_frontend)
-+
-+    allow(pu_foobaz).to receive(:initialize_plugin).with(group: "frontend").
-+      and_return(foo_baz_frontend)
-+
-+    allow(pu_foobar).to receive(:initialize_plugin).with(group: "backend").
-+      and_return(foo_bar_backend)
-+
-+    allow(pu_foobaz).to receive(:initialize_plugin).with(group: "backend").
-+      and_return(foo_baz_backend)
-+  end
-+
-+  describe "#all" do
-+    before do
-+      subject.add("foobar", group: "frontend")
-+      subject.add("foobaz", group: "frontend")
-+      subject.add("foobar", group: "backend")
-+      subject.add("foobaz", group: "backend")
-+    end
-+
-+    context "with no arguments" do
-+      let(:args) { [] }
-+      it "returns all plugins" do
-+        expect(subject.all(*args)).to eq [
-+          foo_bar_frontend,
-+          foo_baz_frontend,
-+          foo_bar_backend,
-+          foo_baz_backend
-+        ]
-+      end
-+    end
-+
-+    context "find a plugin by as string" do
-+      it "returns an array of plugins if plugins are found" do
-+        expect(subject.all("foo-bar")).
-+          to match_array([foo_bar_backend, foo_bar_frontend])
-+      end
-+    end
-+
-+    context "find a plugin by as symbol" do
-+      it "returns an array of plugins if plugins are found" do
-+        expect(subject.all(:'foo-bar')).
-+          to match_array([foo_bar_backend, foo_bar_frontend])
-+      end
-+
-+      it "returns an empty array when no plugin is found" do
-+        expect(subject.all("foo-foo")).to be_empty
-+      end
-+    end
-+
-+    context "find plugins matching a regexp" do
-+      it "returns an array of plugins if plugins are found" do
-+        expect(subject.all(/^foobar/)).
-+          to match_array([foo_bar_backend, foo_bar_frontend])
-+      end
-+
-+      it "returns an empty array when no plugin is found" do
-+        expect(subject.all(/foo$/)).to be_empty
-+      end
-+    end
-+
-+    context "find plugins by their group as a string" do
-+      it "returns an array of plugins if plugins are found" do
-+        expect(subject.all(group: "backend")).
-+          to eq [foo_bar_backend, foo_baz_backend]
-+      end
-+    end
-+
-+    context "find plugins by their group as a symbol" do
-+      it "returns an array of plugins if plugins are found" do
-+        expect(subject.all(group: :frontend)).
-+          to eq [foo_bar_frontend, foo_baz_frontend]
-+      end
-+
-+      it "returns an empty array when no plugin is found" do
-+        expect(subject.all(group: :unknown)).to be_empty
-+      end
-+    end
-+
-+    context "find plugins by their group & name" do
-+      it "returns an array of plugins if plugins are found" do
-+        expect(subject.all(group: "backend", name: "foo-bar")).
-+          to eq [foo_bar_backend]
-+      end
-+
-+      it "returns an empty array when no plugin is found" do
-+        expect(subject.all(group: :unknown, name: :'foo-baz')).
-+          to be_empty
-+      end
-+    end
-+  end
-+
-+  describe "#remove" do
-+    before do
-+      subject.add("foobar", group: "frontend")
-+      subject.add("foobaz", group: "frontend")
-+      subject.add("foobar", group: "backend")
-+      subject.add("foobaz", group: "backend")
-+    end
-+
-+    it "removes given plugin" do
-+      subject.remove(foo_bar_frontend)
-+
-+      expect(subject.all).to match_array [
-+        foo_baz_frontend,
-+        foo_bar_backend,
-+        foo_baz_backend
-+      ]
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/scope_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/scope_spec.rb
-@@ -0,0 +1,93 @@
-+require "guard/internals/scope"
-+
-+RSpec.describe Guard::Internals::Scope do
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+
-+  let(:groups) { instance_double("Guard::Internals::Groups") }
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+
-+  let(:foo_plugin) { instance_double("Guard::Plugin", name: :foo) }
-+  let(:bar_plugin) { instance_double("Guard::Plugin", name: :bar) }
-+  let(:baz_plugin) { instance_double("Guard::Plugin", name: :baz) }
-+
-+  let(:foo_group) { instance_double("Guard::Group", name: :foo) }
-+  let(:bar_group) { instance_double("Guard::Group", name: :bar) }
-+  let(:baz_group) { instance_double("Guard::Group", name: :baz) }
-+
-+  before do
-+    allow(groups).to receive(:all).with("foo").and_return([foo_group])
-+    allow(groups).to receive(:all).with("bar").and_return([bar_group])
-+    allow(groups).to receive(:all).with("baz").and_return([baz_group])
-+    allow(groups).to receive(:all).with(:baz).and_return([baz_group])
-+
-+    allow(plugins).to receive(:all).with("foo").and_return([foo_plugin])
-+    allow(plugins).to receive(:all).with("bar").and_return([bar_plugin])
-+    allow(plugins).to receive(:all).with("baz").and_return([baz_plugin])
-+    allow(plugins).to receive(:all).with(:baz).and_return([baz_plugin])
-+
-+    allow(session).to receive(:cmdline_plugins).and_return([])
-+    allow(session).to receive(:cmdline_groups).and_return([])
-+    allow(session).to receive(:groups).and_return(groups)
-+    allow(session).to receive(:plugins).and_return(plugins)
-+
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(session).to receive(:guardfile_plugin_scope).and_return([])
-+    allow(session).to receive(:guardfile_group_scope).and_return([])
-+  end
-+
-+  # TODO: move to Session?
-+  describe "#to_hash" do
-+    [:group, :plugin].each do |scope|
-+      describe scope.inspect do
-+        let(:hash) do
-+          subject.to_hash[:"#{scope}s"].map(&:name).map(&:to_s)
-+        end
-+
-+        # NOTE: interactor returns objects
-+        context "when set from interactor" do
-+          before do
-+            stub_obj = send("baz_#{scope}")
-+            subject.from_interactor(:"#{scope}s" => stub_obj)
-+          end
-+
-+          it "uses interactor scope" do
-+            expect(hash).to contain_exactly("baz")
-+          end
-+        end
-+
-+        context "when not set in interactor" do
-+          context "when set in commandline" do
-+            before do
-+              allow(session).to receive(:"cmdline_#{scope}s").
-+                and_return(%w(baz))
-+            end
-+
-+            it "uses commandline scope" do
-+              expect(hash).to contain_exactly("baz")
-+            end
-+          end
-+
-+          context "when not set in commandline" do
-+            context "when set in Guardfile" do
-+              before do
-+                allow(session).to receive(:"guardfile_#{scope}_scope").
-+                  and_return(%w(baz))
-+              end
-+
-+              it "uses guardfile scope" do
-+                expect(hash).to contain_exactly("baz")
-+              end
-+            end
-+          end
-+        end
-+      end
-+    end
-+  end
-+
-+  describe "#titles" do
-+    pending
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/session_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/session_spec.rb
-@@ -0,0 +1,282 @@
-+require "guard/internals/session"
-+
-+RSpec.describe Guard::Internals::Session do
-+  let(:options) { {} }
-+  subject { described_class.new(options) }
-+
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+  let(:groups) { instance_double("Guard::Internals::Plugins") }
-+
-+  before do
-+    allow(Guard::Internals::Plugins).to receive(:new).and_return(plugins)
-+    allow(Guard::Internals::Groups).to receive(:new).and_return(groups)
-+  end
-+
-+  describe "#initialize" do
-+    describe "#listener_args" do
-+      subject { described_class.new(options).listener_args }
-+
-+      context "with a single watchdir" do
-+        let(:options) { { watchdir: ["/usr"] } }
-+        let(:dir) { Gem.win_platform? ? "C:/usr" : "/usr" }
-+        it { is_expected.to eq [:to, dir, {}] }
-+      end
-+
-+      context "with multiple watchdirs" do
-+        let(:options) { { watchdir: ["/usr", "/bin"] } }
-+        let(:dir1) { Gem.win_platform? ? "C:/usr" : "/usr" }
-+        let(:dir2) { Gem.win_platform? ? "C:/bin" : "/bin" }
-+        it { is_expected.to eq [:to, dir1, dir2, {}] }
-+      end
-+
-+      context "with force_polling option" do
-+        let(:options) { { force_polling: true } }
-+        it { is_expected.to eq [:to, Dir.pwd, force_polling: true] }
-+      end
-+
-+      context "with latency option" do
-+        let(:options) { { latency: 1.5 } }
-+        it { is_expected.to eq [:to, Dir.pwd, latency: 1.5] }
-+      end
-+    end
-+
-+    context "with the plugin option" do
-+      let(:options) do
-+        {
-+          plugin: %w(cucumber jasmine),
-+          guardfile_contents: "guard :jasmine do; end; "\
-+          "guard :cucumber do; end; guard :coffeescript do; end"
-+        }
-+      end
-+
-+      let(:jasmine) { instance_double("Guard::Plugin") }
-+      let(:cucumber) { instance_double("Guard::Plugin") }
-+      let(:coffeescript) { instance_double("Guard::Plugin") }
-+
-+      before do
-+        stub_const "Guard::Jasmine", jasmine
-+        stub_const "Guard::Cucumber", cucumber
-+        stub_const "Guard::CoffeeScript", coffeescript
-+      end
-+
-+      it "initializes the plugin scope" do
-+        allow(plugins).to receive(:add).with("cucumber", {}).
-+          and_return(cucumber)
-+
-+        allow(plugins).to receive(:add).with("jasmine", {}).
-+          and_return(jasmine)
-+
-+        expect(subject.cmdline_plugins).to match_array(%w(cucumber jasmine))
-+      end
-+    end
-+
-+    context "with the group option" do
-+      let(:options) do
-+        {
-+          group: %w(backend frontend),
-+          guardfile_contents: "group :backend do; end; "\
-+          "group :frontend do; end; group :excluded do; end"
-+        }
-+      end
-+
-+      before do
-+        g3 = instance_double("Guard::Group", name: :backend, options: {})
-+        g4 = instance_double("Guard::Group", name: :frontend, options: {})
-+        allow(Guard::Group).to receive(:new).with("backend", {}).and_return(g3)
-+        allow(Guard::Group).to receive(:new).with("frontend", {}).and_return(g4)
-+      end
-+
-+      it "initializes the group scope" do
-+        expect(subject.cmdline_groups).to match_array(%w(backend frontend))
-+      end
-+    end
-+  end
-+
-+  describe "#clearing" do
-+    context "when not set" do
-+      context "when clearing is not set from commandline" do
-+        it { is_expected.to_not be_clearing }
-+      end
-+
-+      context "when clearing is set from commandline" do
-+        let(:options) { { clear: false } }
-+        it { is_expected.to_not be_clearing }
-+      end
-+    end
-+
-+    context "when set from guardfile" do
-+      context "when set to :on" do
-+        before { subject.clearing(true) }
-+        it { is_expected.to be_clearing }
-+      end
-+
-+      context "when set to :off" do
-+        before { subject.clearing(false) }
-+        it { is_expected.to_not be_clearing }
-+      end
-+    end
-+  end
-+
-+  describe "#guardfile_ignore=" do
-+    context "when set from guardfile" do
-+      before { subject.guardfile_ignore = [/foo/] }
-+      specify { expect(subject.guardfile_ignore).to eq([/foo/]) }
-+    end
-+
-+    context "when set multiple times from guardfile" do
-+      before do
-+        subject.guardfile_ignore = [/foo/]
-+        subject.guardfile_ignore = [/bar/]
-+      end
-+      specify { expect(subject.guardfile_ignore).to eq([/foo/, /bar/]) }
-+    end
-+
-+    context "when unset" do
-+      specify { expect(subject.guardfile_ignore).to eq([]) }
-+    end
-+  end
-+
-+  describe "#guardfile_ignore_bang=" do
-+    context "when set from guardfile" do
-+      before { subject.guardfile_ignore_bang = [/foo/] }
-+      specify { expect(subject.guardfile_ignore_bang).to eq([/foo/]) }
-+    end
-+
-+    context "when unset" do
-+      specify { expect(subject.guardfile_ignore_bang).to eq([]) }
-+    end
-+  end
-+
-+  describe "#guardfile_scope" do
-+    before do
-+      subject.guardfile_scope(scope)
-+    end
-+
-+    context "with a groups scope" do
-+      let(:scope) { { groups: [:foo] } }
-+      it "sets the groups" do
-+        expect(subject.guardfile_group_scope).to eq([:foo])
-+      end
-+    end
-+
-+    context "with a group scope" do
-+      let(:scope) { { group: [:foo] } }
-+      it "sets the groups" do
-+        expect(subject.guardfile_group_scope).to eq([:foo])
-+      end
-+    end
-+
-+    context "with a plugin scope" do
-+      let(:scope) { { plugin: [:foo] } }
-+      it "sets the plugins" do
-+        expect(subject.guardfile_plugin_scope).to eq([:foo])
-+      end
-+    end
-+
-+    context "with a plugins scope" do
-+      let(:scope) { { plugins: [:foo] } }
-+      it "sets the plugins" do
-+        expect(subject.guardfile_plugin_scope).to eq([:foo])
-+      end
-+    end
-+  end
-+
-+  describe ".convert_scope" do
-+    let(:foo) { instance_double("Guard::Plugin", name: "foo") }
-+    let(:bar) { instance_double("Guard::Plugin", name: "bar") }
-+    let(:backend) { instance_double("Guard::Group", name: "backend") }
-+    let(:frontend) { instance_double("Guard::Group", name: "frontend") }
-+
-+    before do
-+      stub_const "Guard::Foo", class_double("Guard::Plugin")
-+      stub_const "Guard::Bar", class_double("Guard::Plugin")
-+
-+      allow(plugins).to receive(:all).with("backend").and_return([])
-+      allow(plugins).to receive(:all).with("frontend").and_return([])
-+      allow(plugins).to receive(:all).with("foo").and_return([foo])
-+      allow(plugins).to receive(:all).with("bar").and_return([bar])
-+      allow(plugins).to receive(:all).with("unknown").and_return([])
-+      allow(plugins).to receive(:all).with("scope").and_return([])
-+
-+      allow(groups).to receive(:all).with("backend").and_return([backend])
-+      allow(groups).to receive(:all).with("frontend").and_return([frontend])
-+      allow(groups).to receive(:all).with("unknown").and_return([])
-+      allow(groups).to receive(:all).with("scope").and_return([])
-+    end
-+
-+    it "returns a group scope" do
-+      scopes, = subject.convert_scope %w(backend)
-+      expect(scopes).to eq(groups: [backend], plugins: [])
-+      scopes, = subject.convert_scope %w(frontend)
-+      expect(scopes).to eq(groups: [frontend], plugins: [])
-+    end
-+
-+    it "returns a plugin scope" do
-+      scopes, = subject.convert_scope %w(foo)
-+      expect(scopes).to eq(plugins: [foo], groups: [])
-+      scopes, = subject.convert_scope %w(bar)
-+      expect(scopes).to eq(plugins: [bar], groups: [])
-+    end
-+
-+    it "returns multiple group scopes" do
-+      scopes, = subject.convert_scope %w(backend frontend)
-+      expected = { groups: [backend, frontend], plugins: [] }
-+      expect(scopes).to eq(expected)
-+    end
-+
-+    it "returns multiple plugin scopes" do
-+      scopes, = subject.convert_scope %w(foo bar)
-+      expect(scopes).to eq(plugins: [foo, bar], groups: [])
-+    end
-+
-+    it "returns a plugin and group scope" do
-+      scopes, = subject.convert_scope %w(foo backend)
-+      expect(scopes).to eq(plugins: [foo], groups: [backend])
-+    end
-+
-+    it "returns the unkown scopes" do
-+      _, unknown = subject.convert_scope %w(unknown scope)
-+      expect(unknown).to eq %w(unknown scope)
-+    end
-+  end
-+
-+  describe "#guardfile_notification=" do
-+    context "when set from guardfile" do
-+      before do
-+        subject.guardfile_notification = { foo: { bar: :baz } }
-+      end
-+
-+      specify do
-+        expect(subject.notify_options).to eq(
-+          notify: true,
-+          notifiers: {
-+            foo: { bar: :baz }
-+          }
-+        )
-+      end
-+    end
-+
-+    context "when set multiple times from guardfile" do
-+      before do
-+        subject.guardfile_notification = { foo: { param: 1 } }
-+        subject.guardfile_notification = { bar: { param: 2 } }
-+      end
-+
-+      it "merges results" do
-+        expect(subject.notify_options).to eq(
-+          notify: true,
-+          notifiers: {
-+            foo: { param: 1 },
-+            bar: { param: 2 }
-+          }
-+        )
-+      end
-+    end
-+
-+    context "when unset" do
-+      specify do
-+        expect(subject.notify_options).to eq(notify: true, notifiers: {})
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/state_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/state_spec.rb
-@@ -0,0 +1,45 @@
-+require "guard/internals/state"
-+
-+RSpec.describe Guard::Internals::State do
-+  let(:options) { {} }
-+  subject { described_class.new(options) }
-+
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+  let(:groups) { instance_double("Guard::Internals::Groups") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+
-+  before do
-+    allow(Guard::Internals::Session).to receive(:new).and_return(session)
-+    allow(Guard::Internals::Scope).to receive(:new).and_return(scope)
-+    allow(session).to receive(:debug?).and_return(false)
-+    allow(session).to receive(:plugins).and_return(plugins)
-+    allow(session).to receive(:groups).and_return(groups)
-+  end
-+
-+  describe "#initialize" do
-+    describe "debugging" do
-+      let(:options) { { debug: debug } }
-+      before do
-+        allow(session).to receive(:debug?).and_return(debug)
-+        expect(Guard::Internals::Session).to receive(:new).with(debug: debug)
-+      end
-+
-+      context "when debug is set to true" do
-+        let(:debug) { true }
-+        it "sets up debugging" do
-+          expect(Guard::Internals::Debugging).to receive(:start)
-+          subject
-+        end
-+      end
-+
-+      context "when debug is set to false" do
-+        let(:debug) { false }
-+        it "does not set up debugging" do
-+          expect(Guard::Internals::Debugging).to_not receive(:start)
-+          subject
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/tracing_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/tracing_spec.rb
-@@ -0,0 +1,113 @@
-+require "guard/internals/tracing"
-+
-+RSpec.describe Guard::Internals::Tracing do
-+  let(:null) { IO::NULL }
-+
-+  # NOTE: Calling system() is different from calling Kernel.system()
-+  #
-+  # We can capture system() calls by stubbing Kernel.system, but to capture
-+  # Kernel.system() calls, we need to stub the module's metaclass methods.
-+  #
-+  # Stubbing just Kernel.system isn't "deep" enough, but not only that,
-+  # we don't want to stub here, we want to TEST the stubbing
-+  #
-+  describe "Module method tracing" do
-+    let(:result) { Kernel.send(meth, *args) }
-+    subject { result }
-+
-+    let(:callback) { double("callback", call: true) }
-+
-+    # Since we can't stub the C code in Ruby, only "right" way to test this is:
-+    # actually call a real command and compare the output
-+    before { allow(Kernel).to receive(meth).and_call_original }
-+
-+    context "when tracing" do
-+      before do
-+        described_class.trace(Kernel, meth) { |*args| callback.call(*args) }
-+        subject
-+      end
-+
-+      after { described_class.untrace(Kernel, meth) }
-+
-+      context "with no command arguments" do
-+        let(:args) { ["echo >#{null}"] }
-+
-+        context "when #system" do
-+          let(:meth) { "system" }
-+
-+          it { is_expected.to eq(true) }
-+
-+          it "outputs command" do
-+            expect(callback).to have_received(:call).with("echo >#{null}")
-+          end
-+        end
-+
-+        context "when backticks" do
-+          let(:meth) { :` }
-+
-+          it { is_expected.to eq("") }
-+
-+          it "outputs command" do
-+            expect(callback).to have_received(:call).with("echo >#{null}")
-+          end
-+        end
-+      end
-+
-+      context "with command arguments" do
-+        let(:args) { %w(true 123) }
-+
-+        context "when #system" do
-+          let(:meth) { "system" }
-+
-+          it { is_expected.to eq(true) }
-+
-+          it "outputs command arguments" do
-+            expect(callback).to have_received(:call).with("true", "123")
-+          end
-+        end
-+      end
-+    end
-+
-+    context "when not tracing" do
-+      before { subject }
-+
-+      context "with no command arguments" do
-+        let(:args) { ["echo test > #{null}"] }
-+
-+        context "when #system" do
-+          let(:meth) { :system }
-+
-+          it { is_expected.to eq(true) }
-+
-+          it "does not output anything" do
-+            expect(callback).to_not have_received(:call)
-+          end
-+        end
-+
-+        context "when backticks" do
-+          let(:meth) { :` }
-+
-+          it { is_expected.to eq("") }
-+
-+          it "does not output anything" do
-+            expect(callback).to_not have_received(:call)
-+          end
-+        end
-+      end
-+
-+      context "with command arguments" do
-+        let(:args) { %w(true 123) }
-+
-+        context "when #system" do
-+          let(:meth) { :system }
-+
-+          it { is_expected.to eq(true) }
-+
-+          it "does not output anything" do
-+            expect(callback).to_not have_received(:call)
-+          end
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/internals/traps_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/internals/traps_spec.rb
-@@ -0,0 +1,34 @@
-+require "guard/internals/traps"
-+
-+RSpec.describe Guard::Internals::Traps do
-+  describe ".handle" do
-+    let(:signal_class) { class_double(Signal) }
-+
-+    before do
-+      stub_const("Signal", signal_class)
-+    end
-+
-+    context "with a supported signal name" do
-+      let(:signal) { "USR1" }
-+
-+      it "sets up a handler" do
-+        allow(Signal).to receive(:list).and_return("USR1" => 10)
-+        allow(Signal).to receive(:trap).with(signal) do |_, &block|
-+          block.call
-+        end
-+
-+        expect { |b| described_class.handle(signal, &b) }.to yield_control
-+      end
-+    end
-+
-+    context "with an unsupported signal name" do
-+      let(:signal) { "ABCD" }
-+
-+      it "does not set a handler" do
-+        allow(Signal).to receive(:list).and_return("KILL" => 9)
-+        expect(Signal).to_not receive(:trap)
-+        described_class.handle(signal)
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/jobs/pry_wrapper_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/jobs/pry_wrapper_spec.rb
-@@ -0,0 +1,183 @@
-+require "guard/jobs/pry_wrapper"
-+
-+RSpec.describe Guard::Jobs::PryWrapper do
-+  subject { described_class.new({}) }
-+  let(:listener) { instance_double("Listen::Listener") }
-+  let(:pry_config) { double("pry_config") }
-+  let(:pry_history) { double("pry_history") }
-+  let(:pry_commands) { double("pry_commands") }
-+  let(:pry_hooks) { double("pry_hooks") }
-+  let(:terminal_settings) { instance_double("Guard::Jobs::TerminalSettings") }
-+
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+  let(:groups) { instance_double("Guard::Internals::Groups") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+
-+  before do
-+    # TODO: this are here to mock out Pry completely
-+    allow(pry_config).to receive(:prompt=)
-+    allow(pry_config).to receive(:should_load_rc=)
-+    allow(pry_config).to receive(:should_load_local_rc=)
-+    allow(pry_config).to receive(:hooks).and_return(pry_hooks)
-+    allow(pry_config).to receive(:history).and_return(pry_history)
-+    allow(pry_config).to receive(:commands).and_return(pry_commands)
-+    allow(pry_history).to receive(:file=)
-+    allow(pry_commands).to receive(:alias_command)
-+    allow(pry_commands).to receive(:create_command)
-+    allow(pry_commands).to receive(:command)
-+    allow(pry_commands).to receive(:block_command)
-+    allow(pry_hooks).to receive(:add_hook)
-+
-+    allow(Guard).to receive(:listener).and_return(listener)
-+    allow(Pry).to receive(:config).and_return(pry_config)
-+    allow(Shellany::Sheller).to receive(:run).with(*%w(hash stty)) { false }
-+
-+    allow(groups).to receive(:all).and_return([])
-+    allow(session).to receive(:groups).and_return(groups)
-+
-+    allow(plugins).to receive(:all).and_return([])
-+    allow(session).to receive(:plugins).and_return(plugins)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(state).to receive(:scope).and_return(scope)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(Guard::Commands::All).to receive(:import)
-+    allow(Guard::Commands::Change).to receive(:import)
-+    allow(Guard::Commands::Reload).to receive(:import)
-+    allow(Guard::Commands::Pause).to receive(:import)
-+    allow(Guard::Commands::Notification).to receive(:import)
-+    allow(Guard::Commands::Show).to receive(:import)
-+    allow(Guard::Commands::Scope).to receive(:import)
-+
-+    allow(Guard::Jobs::TerminalSettings).to receive(:new).
-+      and_return(terminal_settings)
-+
-+    allow(terminal_settings).to receive(:configurable?).and_return(false)
-+    allow(terminal_settings).to receive(:save)
-+    allow(terminal_settings).to receive(:restore)
-+  end
-+
-+  describe "#foreground" do
-+    before do
-+      allow(Pry).to receive(:start) do
-+        # sleep for a long time (anything > 0.6)
-+        sleep 2
-+      end
-+    end
-+
-+    after do
-+      subject.background
-+    end
-+
-+    it "waits for Pry thread to finish" do
-+      was_alive = false
-+
-+      Thread.new do
-+        sleep 0.1
-+        was_alive = subject.send(:thread).alive?
-+        subject.background
-+      end
-+
-+      subject.foreground # blocks
-+      expect(was_alive).to be
-+    end
-+
-+    it "prevents the Pry thread from being killed too quickly" do
-+      start = Time.now.to_f
-+
-+      Thread.new do
-+        sleep 0.1
-+        subject.background
-+      end
-+
-+      subject.foreground # blocks
-+      killed_moment = Time.now.to_f
-+
-+      expect(killed_moment - start).to be > 0.5
-+    end
-+
-+    it "return :stopped when brought into background" do
-+      Thread.new do
-+        sleep 0.1
-+        subject.background
-+      end
-+
-+      expect(subject.foreground).to be(:stopped)
-+    end
-+  end
-+
-+  describe "#background" do
-+    before do
-+      allow(Pry).to receive(:start) do
-+        # 0.5 is enough for Pry, so we use 0.4
-+        sleep 0.4
-+      end
-+    end
-+
-+    it "kills the Pry thread" do
-+      subject.foreground
-+      sleep 1 # give Pry 0.5 sec to boot
-+      subject.background
-+      sleep 0.25 # to let Pry get killed asynchronously
-+
-+      expect(subject.send(:thread)).to be_nil
-+    end
-+  end
-+
-+  describe "#_prompt(ending_char)" do
-+    let(:prompt) { subject.send(:_prompt, ">") }
-+
-+    before do
-+      allow(Shellany::Sheller).to receive(:run).with(*%w(hash stty)) { false }
-+      allow(scope).to receive(:titles).and_return(["all"])
-+
-+      allow(listener).to receive(:paused?).and_return(false)
-+
-+      expect(Pry).to receive(:view_clip).and_return("main")
-+    end
-+
-+    let(:pry) { instance_double(Pry, input_array: []) }
-+
-+    context "Guard is not paused" do
-+      it 'displays "guard"' do
-+        expect(prompt.call(double, 0, pry)).
-+          to eq "[0] guard(main)> "
-+      end
-+    end
-+
-+    context "Guard is paused" do
-+      before do
-+        allow(listener).to receive(:paused?).and_return(true)
-+      end
-+
-+      it 'displays "pause"' do
-+        expect(prompt.call(double, 0, pry)).
-+          to eq "[0] pause(main)> "
-+      end
-+    end
-+
-+    context "with a groups scope" do
-+      before do
-+        allow(scope).to receive(:titles).and_return(%w(Backend Frontend))
-+      end
-+
-+      it "displays the group scope title in the prompt" do
-+        expect(prompt.call(double, 0, pry)).
-+          to eq "[0] Backend,Frontend guard(main)> "
-+      end
-+    end
-+
-+    context "with a plugins scope" do
-+      before do
-+        allow(scope).to receive(:titles).and_return(%w(RSpec Ronn))
-+      end
-+
-+      it "displays the group scope title in the prompt" do
-+        result = prompt.call(double, 0, pry)
-+        expect(result).to eq "[0] RSpec,Ronn guard(main)> "
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/jobs/sleep_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/jobs/sleep_spec.rb
-@@ -0,0 +1,59 @@
-+require "guard/jobs/sleep"
-+
-+RSpec.describe Guard::Jobs::Sleep do
-+  subject { described_class.new({}) }
-+
-+  describe "#foreground" do
-+    it "sleeps" do
-+      status = "unknown"
-+
-+      Thread.new do
-+        sleep 0.1
-+        status = Thread.main.status
-+        subject.background
-+      end
-+
-+      subject.foreground
-+
-+      expect(status).to eq("sleep")
-+    end
-+
-+    it "returns :stopped when put to background" do
-+      Thread.new do
-+        sleep 0.1
-+        subject.background
-+      end
-+
-+      expect(subject.foreground).to eq(:stopped)
-+    end
-+  end
-+
-+  describe "#background" do
-+    it "wakes up main thread" do
-+      status = "unknown"
-+
-+      Thread.new do
-+        sleep 0.1 # give enough time for foreground to put main thread to sleep
-+
-+        subject.background
-+
-+        sleep 0.1 # cause test to fail every time (without busy loop below)
-+
-+        status = Thread.main.status
-+
-+        Thread.main.wakeup # to get "red" in TDD without hanging
-+      end
-+
-+      subject.foreground # go to sleep
-+
-+      # Keep main thread busy until above thread has a chance to get status
-+      begin
-+        value = 0
-+        Timeout.timeout(0.1) { loop { value += 1 } }
-+      rescue Timeout::Error
-+      end
-+
-+      expect(status).to eq("run")
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/notifier_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/notifier_spec.rb
-@@ -0,0 +1,81 @@
-+require "guard/notifier"
-+
-+RSpec.describe Guard::Notifier do
-+  subject { described_class }
-+  let(:notifier) { instance_double("Notiffany::Notifier") }
-+
-+  before do
-+    allow(Notiffany::Notifier).to receive(:new).and_return(notifier)
-+  end
-+
-+  after do
-+    Guard::Notifier.instance_variable_set(:@notifier, nil)
-+  end
-+
-+  describe "toggle_notification" do
-+    before do
-+      allow(notifier).to receive(:enabled?).and_return(true)
-+    end
-+
-+    context "with available notifiers" do
-+      context "when currently on" do
-+        before do
-+          allow(notifier).to receive(:active?).and_return(true)
-+          subject.connect
-+        end
-+
-+        it "suspends notifications" do
-+          expect(notifier).to receive(:turn_off)
-+          subject.toggle
-+        end
-+      end
-+
-+      context "when currently off" do
-+        before do
-+          subject.connect
-+          allow(notifier).to receive(:active?).and_return(false)
-+        end
-+
-+        it "resumes notifications" do
-+          expect(notifier).to receive(:turn_on)
-+          subject.toggle
-+        end
-+      end
-+    end
-+  end
-+
-+  describe ".notify" do
-+    before do
-+      subject.connect
-+      allow(notifier).to receive(:notify)
-+    end
-+
-+    context "with no options" do
-+      it "notifies" do
-+        expect(notifier).to receive(:notify).with("A", {})
-+        subject.notify("A")
-+      end
-+    end
-+
-+    context "with multiple parameters" do
-+      it "notifies" do
-+        expect(notifier).to receive(:notify).
-+          with("A", priority: 2, image: :failed)
-+        subject.notify("A", priority: 2, image: :failed)
-+      end
-+    end
-+
-+    context "with a runtime error" do
-+      before do
-+        allow(notifier).to receive(:notify).and_raise(RuntimeError, "an error")
-+      end
-+
-+      it "shows an error" do
-+        expect(Guard::UI).to receive(:error).
-+          with(/Notification failed for .+: an error/)
-+
-+        subject.notify("A", priority: 2, image: :failed)
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/options_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/options_spec.rb
-@@ -0,0 +1,31 @@
-+require "guard/options"
-+
-+RSpec.describe Guard::Options do
-+  describe ".initialize" do
-+    it "handles nil options" do
-+      expect { described_class.new(nil) }.to_not raise_error
-+    end
-+
-+    it "has indifferent access" do
-+      options = described_class.new({ foo: "bar" }, "foo2" => "baz")
-+
-+      expect(options[:foo]).to eq "bar"
-+      expect(options["foo"]).to eq "bar"
-+
-+      expect(options[:foo2]).to eq "baz"
-+      expect(options["foo2"]).to eq "baz"
-+    end
-+
-+    it "can be passed defaults" do
-+      options = described_class.new({}, foo: "bar")
-+
-+      expect(options[:foo]).to eq "bar"
-+    end
-+
-+    it "merges the sensible defaults to the given options" do
-+      options = described_class.new({ plugin: ["rspec"] }, plugin: ["test"])
-+
-+      expect(options[:plugin]).to eq ["rspec"]
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/plugin_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/plugin_spec.rb
-@@ -0,0 +1,235 @@
-+require "guard/plugin"
-+
-+require "guard/watcher"
-+
-+RSpec.describe Guard::Plugin do
-+  let(:default) { instance_double("Guard::Group") }
-+  let(:test) { instance_double("Guard::Group") }
-+
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:groups) { instance_double("Guard::Internals::Groups") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+
-+  before do
-+    allow(groups).to receive(:add).with(:default).and_return(default)
-+    allow(groups).to receive(:add).with(:test).and_return(test)
-+
-+    allow(session).to receive(:groups).and_return(groups)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+  end
-+
-+  # TODO: this should already be done in spec_helper!
-+  after do
-+    klass = described_class
-+    klass.instance_variables.each do |var|
-+      klass.instance_variable_set(var, nil)
-+    end
-+  end
-+
-+  describe "#initialize" do
-+    it "assigns the defined watchers" do
-+      watchers = [double("foo")]
-+      expect(Guard::Plugin.new(watchers: watchers).watchers).to eq watchers
-+    end
-+
-+    it "assigns the defined options" do
-+      options = { a: 1, b: 2 }
-+      expect(Guard::Plugin.new(options).options).to eq options
-+    end
-+
-+    context "with a group in the options" do
-+      it "assigns the given group" do
-+        expect(Guard::Plugin.new(group: :test).group).to eq test
-+      end
-+    end
-+
-+    context "without a group in the options" do
-+      it "assigns a default group" do
-+        allow(groups).to receive(:add).with(:default).and_return(default)
-+        expect(Guard::Plugin.new.group).to eq default
-+      end
-+    end
-+
-+    context "with a callback" do
-+      it "adds the callback" do
-+        block = instance_double(Proc)
-+        events = [:start_begin, :start_end]
-+        callbacks = [{ events: events, listener: block }]
-+        Guard::Plugin.new(callbacks: callbacks)
-+        expect(Guard::Plugin.callbacks.first[0][0].callbacks).to eq(callbacks)
-+      end
-+    end
-+  end
-+
-+  context "with a plugin instance" do
-+    subject do
-+      module Guard
-+        class DuMmy < Guard::Plugin
-+        end
-+      end
-+      Guard::DuMmy
-+    end
-+
-+    after do
-+      Guard.send(:remove_const, :DuMmy)
-+    end
-+
-+    describe ".non_namespaced_classname" do
-+      it "remove the Guard:: namespace" do
-+        expect(subject.non_namespaced_classname).to eq "DuMmy"
-+      end
-+    end
-+
-+    describe ".non_namespaced_name" do
-+      it "remove the Guard:: namespace and downcase" do
-+        expect(subject.non_namespaced_name).to eq "dummy"
-+      end
-+    end
-+
-+    describe ".template" do
-+      before do
-+        allow(File).to receive(:read)
-+      end
-+
-+      it "reads the default template" do
-+        expect(File).to receive(:read).
-+          with("/guard-dummy/lib/guard/dummy/templates/Guardfile") { true }
-+
-+        subject.template("/guard-dummy")
-+      end
-+    end
-+
-+    describe "#name" do
-+      it "outputs the short plugin name" do
-+        expect(subject.new.name).to eq "dummy"
-+      end
-+    end
-+
-+    describe "#title" do
-+      it "outputs the plugin title" do
-+        expect(subject.new.title).to eq "DuMmy"
-+      end
-+    end
-+
-+    describe "#to_s" do
-+      let(:default) { instance_double("Guard::Group", name: :default) }
-+
-+      it "output the short plugin name" do
-+        expect(subject.new.to_s).
-+          to match(/#<Guard::DuMmy @name=dummy .*>/)
-+      end
-+    end
-+  end
-+
-+  let(:listener) { instance_double(Proc, call: nil) }
-+
-+  describe ".add_callback" do
-+    let(:foo) { double("foo plugin") }
-+
-+    it "can add a run_on_modifications callback" do
-+      described_class.add_callback(
-+        listener,
-+        foo,
-+        :run_on_modifications_begin
-+      )
-+
-+      result = described_class.callbacks[[foo, :run_on_modifications_begin]]
-+      expect(result).to include(listener)
-+    end
-+
-+    it "can add multiple callbacks" do
-+      described_class.add_callback(listener, foo, [:event1, :event2])
-+
-+      result = described_class.callbacks[[foo, :event1]]
-+      expect(result).to include(listener)
-+
-+      result = described_class.callbacks[[foo, :event2]]
-+      expect(result).to include(listener)
-+    end
-+  end
-+
-+  describe ".notify" do
-+    let(:foo) { double("foo plugin") }
-+    let(:bar) { double("bar plugin") }
-+
-+    before do
-+      described_class.add_callback(listener, foo, :start_begin)
-+    end
-+
-+    it "sends :call to the given Guard class's start_begin callback" do
-+      expect(listener).to receive(:call).with(foo, :start_begin, "args")
-+      described_class.notify(foo, :start_begin, "args")
-+    end
-+
-+    it "sends :call to the given Guard class's start_begin callback" do
-+      expect(listener).to receive(:call).with(foo, :start_begin, "args")
-+      described_class.notify(foo, :start_begin, "args")
-+    end
-+
-+    it "runs only the given callbacks" do
-+      listener2 = double("listener2")
-+      described_class.add_callback(listener2, foo, :start_end)
-+      expect(listener2).to_not receive(:call).with(foo, :start_end)
-+      described_class.notify(foo, :start_begin)
-+    end
-+
-+    it "runs callbacks only for the guard given" do
-+      described_class.add_callback(listener, bar, :start_begin)
-+      expect(listener).to_not receive(:call).with(bar, :start_begin)
-+      described_class.notify(foo, :start_begin)
-+    end
-+  end
-+
-+  describe "#hook" do
-+    let(:foo) { double("foo plugin") }
-+
-+    before do
-+      described_class.add_callback(listener, foo, :start_begin)
-+    end
-+
-+    it "notifies the hooks" do
-+      class Foo < described_class
-+        def run_all
-+          hook :begin
-+          hook :end
-+        end
-+      end
-+
-+      foo = Foo.new
-+      expect(described_class).to receive(:notify).with(foo, :run_all_begin)
-+      expect(described_class).to receive(:notify).with(foo, :run_all_end)
-+      foo.run_all
-+    end
-+
-+    it "passes the hooks name" do
-+      class Foo < described_class
-+        def start
-+          hook "my_hook"
-+        end
-+      end
-+
-+      foo = Foo.new
-+      expect(described_class).to receive(:notify).with(foo, :my_hook)
-+      foo.start
-+    end
-+
-+    it "accepts extra arguments" do
-+      class Foo < described_class
-+        def stop
-+          hook :begin, "args"
-+          hook "special_sauce", "first_arg", "second_arg"
-+        end
-+      end
-+      foo = Foo.new
-+
-+      expect(described_class).to receive(:notify).
-+        with(foo, :stop_begin, "args")
-+
-+      expect(described_class).to receive(:notify).
-+        with(foo, :special_sauce, "first_arg", "second_arg")
-+
-+      foo.stop
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/plugin_util_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/plugin_util_spec.rb
-@@ -0,0 +1,303 @@
-+require "guard/plugin_util"
-+
-+require "guard/guardfile/evaluator"
-+
-+RSpec.describe Guard::PluginUtil do
-+  let(:guard_rspec_class) { class_double("Guard::Plugin") }
-+  let(:guard_rspec) { instance_double("Guard::Plugin") }
-+  let(:evaluator) { instance_double("Guard::Guardfile::Evaluator") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+
-+  before do
-+    allow(session).to receive(:evaluator_options).and_return({})
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+    allow(Guard::Guardfile::Evaluator).to receive(:new).and_return(evaluator)
-+  end
-+
-+  describe ".plugin_names" do
-+    before do
-+      spec = Gem::Specification
-+      gems = [
-+        instance_double(spec, name: "guard-myplugin"),
-+        instance_double(spec, name: "gem1", full_gem_path: "/gem1"),
-+        instance_double(spec, name: "gem2", full_gem_path: "/gem2"),
-+        instance_double(spec, name: "guard-compat"),
-+      ]
-+      allow(File).to receive(:exist?).
-+        with("/gem1/lib/guard/gem1.rb") { false }
-+
-+      allow(File).to receive(:exist?).
-+        with("/gem2/lib/guard/gem2.rb") { true }
-+
-+      gem = class_double(Gem::Specification)
-+      stub_const("Gem::Specification", gem)
-+      expect(Gem::Specification).to receive(:find_all) { gems }
-+    end
-+
-+    it "returns the list of guard gems" do
-+      expect(described_class.plugin_names).to include("myplugin")
-+    end
-+
-+    it "returns the list of embedded guard gems" do
-+      expect(described_class.plugin_names).to include("gem2")
-+    end
-+
-+    it "ignores guard-compat" do
-+      expect(described_class.plugin_names).to_not include("compat")
-+    end
-+  end
-+
-+  describe "#initialize" do
-+    it "accepts a name without guard-" do
-+      expect(described_class.new("rspec").name).to eq "rspec"
-+    end
-+
-+    it "accepts a name with guard-" do
-+      expect(described_class.new("guard-rspec").name).to eq "rspec"
-+    end
-+  end
-+
-+  describe "#initialize_plugin" do
-+    let(:plugin_util) { described_class.new("rspec") }
-+
-+    before do
-+      allow_any_instance_of(described_class).
-+        to receive(:plugin_class).
-+        and_return(guard_rspec_class)
-+    end
-+
-+    context "with a plugin inheriting from Guard::Plugin" do
-+      before do
-+        expect(guard_rspec_class).to receive(:superclass) { ::Guard::Plugin }
-+      end
-+
-+      it "instantiate the plugin using the new API" do
-+        options = { watchers: ["watcher"], group: "foo" }
-+        expect(guard_rspec_class).to receive(:new).with(options) { guard_rspec }
-+
-+        expect(plugin_util.initialize_plugin(options)).to eq guard_rspec
-+      end
-+    end
-+  end
-+
-+  describe "#plugin_location" do
-+    subject { described_class.new("rspec") }
-+
-+    it "returns the path of a Guard gem" do
-+      expect(Gem::Specification).to receive(:find_by_name).
-+        with("guard-rspec") { double(full_gem_path: "gems/guard-rspec") }
-+      expect(subject.plugin_location).to eq "gems/guard-rspec"
-+    end
-+  end
-+
-+  describe "#plugin_class" do
-+    after do
-+      # TODO: use RSpec's stub const
-+      consts = [:Classname,
-+                :DashedClassName,
-+                :UnderscoreClassName,
-+                :VSpec,
-+                :Inline]
-+
-+      consts.each do |const|
-+        begin
-+          Guard.send(:remove_const, const)
-+        rescue NameError
-+        end
-+      end
-+    end
-+
-+    it "reports an error if the class is not found" do
-+      expect(::Guard::UI).to receive(:error).with(/Could not load/)
-+      expect(::Guard::UI).to receive(:error).with(/Error is: cannot load/)
-+      expect(::Guard::UI).to receive(:error).with(/plugin_util.rb/)
-+
-+      plugin = described_class.new("notAGuardClass")
-+      allow(plugin).to receive(:require).with("guard/notaguardclass").
-+        and_raise(LoadError, "cannot load such file --")
-+
-+      plugin.plugin_class
-+    end
-+
-+    context "with a nested Guard class" do
-+      it "resolves the Guard class from string" do
-+        plugin = described_class.new("classname")
-+        expect(plugin).to receive(:require) do |classname|
-+          expect(classname).to eq "guard/classname"
-+          module Guard
-+            class Classname
-+            end
-+          end
-+        end
-+        expect(plugin.plugin_class).to eq Guard::Classname
-+      end
-+
-+      it "resolves the Guard class from symbol" do
-+        plugin = described_class.new(:classname)
-+        expect(plugin).to receive(:require) do |classname|
-+          expect(classname).to eq "guard/classname"
-+          module Guard
-+            class Classname
-+            end
-+          end
-+        end
-+        expect(plugin.plugin_class).to eq Guard::Classname
-+      end
-+    end
-+
-+    context "with a name with dashes" do
-+      it "returns the Guard class" do
-+        plugin = described_class.new("dashed-class-name")
-+        expect(plugin).to receive(:require) do |classname|
-+          expect(classname).to eq "guard/dashed-class-name"
-+          module Guard
-+            class DashedClassName
-+            end
-+          end
-+        end
-+        expect(plugin.plugin_class).to eq Guard::DashedClassName
-+      end
-+    end
-+
-+    context "with a name with underscores" do
-+      it "returns the Guard class" do
-+        plugin = described_class.new("underscore_class_name")
-+        expect(plugin).to receive(:require) do |classname|
-+          expect(classname).to eq "guard/underscore_class_name"
-+          module Guard
-+            class UnderscoreClassName
-+            end
-+          end
-+        end
-+        expect(plugin.plugin_class).to eq Guard::UnderscoreClassName
-+      end
-+    end
-+
-+    context "with a name like VSpec" do
-+      it "returns the Guard class" do
-+        plugin = described_class.new("vspec")
-+        mod = nil
-+        allow(plugin).to receive(:require) do |classname|
-+          expect(classname).to eq "guard/vspec"
-+          module Guard
-+            class VSpec
-+            end
-+          end
-+          mod = Guard::VSpec
-+        end
-+        expect(plugin.plugin_class).to eq mod
-+        expect(mod).to be
-+      end
-+    end
-+
-+    context "with an inline Guard class" do
-+      subject { described_class.new("inline") }
-+      let(:plugin_class) { class_double("Guard::Plugin") }
-+
-+      it "returns the Guard class" do
-+        allow(Guard).to receive(:constants).and_return([:Inline])
-+        allow(Guard).to receive(:const_get).with(:Inline).
-+          and_return(plugin_class)
-+
-+        expect(subject).to_not receive(:require)
-+        expect(subject.plugin_class).to eq plugin_class
-+      end
-+    end
-+
-+    context "when set to fail gracefully" do
-+      options = { fail_gracefully: true }
-+      subject { described_class.new("notAGuardClass") }
-+      it "does not print error messages on fail" do
-+        expect(::Guard::UI).to_not receive(:error)
-+        plugin = subject
-+        allow(plugin).to receive(:require).and_raise(LoadError)
-+        expect(subject.plugin_class(options)).to be_nil
-+      end
-+    end
-+  end
-+
-+  describe "#add_to_guardfile" do
-+    before do
-+      allow(Guard::Guardfile::Evaluator).to receive(:new).and_return(evaluator)
-+      allow(evaluator).to receive(:evaluate)
-+    end
-+
-+    context "when the Guard is already in the Guardfile" do
-+      before do
-+        allow(evaluator).to receive(:guardfile_include?) { true }
-+      end
-+
-+      it "shows an info message" do
-+        expect(::Guard::UI).to receive(:info).
-+          with "Guardfile already includes myguard guard"
-+
-+        described_class.new("myguard").add_to_guardfile
-+      end
-+    end
-+
-+    context "when Guardfile is empty" do
-+      let(:plugin_util) { described_class.new("myguard") }
-+      let(:plugin_class) { class_double("Guard::Plugin") }
-+      let(:location) { "/Users/me/projects/guard-myguard" }
-+      let(:gem_spec) { instance_double("Gem::Specification") }
-+      let(:io) { StringIO.new }
-+
-+      before do
-+        allow(evaluator).to receive(:evaluate).
-+          and_raise(Guard::Guardfile::Evaluator::NoPluginsError)
-+
-+        allow(gem_spec).to receive(:full_gem_path).and_return(location)
-+        allow(evaluator).to receive(:guardfile_include?) { false }
-+        allow(Guard).to receive(:constants).and_return([:MyGuard])
-+        allow(Guard).to receive(:const_get).with(:MyGuard).
-+          and_return(plugin_class)
-+
-+        allow(Gem::Specification).to receive(:find_by_name).
-+          with("guard-myguard").and_return(gem_spec)
-+
-+        allow(plugin_class).to receive(:template).with(location).
-+          and_return("Template content")
-+
-+        allow(File).to receive(:read).with("Guardfile") { "Guardfile content" }
-+        allow(File).to receive(:open).with("Guardfile", "wb").and_yield io
-+      end
-+
-+      it "appends the template to the Guardfile" do
-+        plugin_util.add_to_guardfile
-+        expect(io.string).to eq "Guardfile content\n\nTemplate content\n"
-+      end
-+    end
-+
-+    context "when the Guard is not in the Guardfile" do
-+      let(:plugin_util) { described_class.new("myguard") }
-+      let(:plugin_class) { class_double("Guard::Plugin") }
-+      let(:location) { "/Users/me/projects/guard-myguard" }
-+      let(:gem_spec) { instance_double("Gem::Specification") }
-+      let(:io) { StringIO.new }
-+
-+      before do
-+        allow(gem_spec).to receive(:full_gem_path).and_return(location)
-+        allow(evaluator).to receive(:guardfile_include?) { false }
-+        allow(Guard).to receive(:constants).and_return([:MyGuard])
-+        allow(Guard).to receive(:const_get).with(:MyGuard).
-+          and_return(plugin_class)
-+
-+        allow(Gem::Specification).to receive(:find_by_name).
-+          with("guard-myguard").and_return(gem_spec)
-+
-+        allow(plugin_class).to receive(:template).with(location).
-+          and_return("Template content")
-+
-+        allow(File).to receive(:read).with("Guardfile") { "Guardfile content" }
-+        allow(File).to receive(:open).with("Guardfile", "wb").and_yield io
-+      end
-+
-+      it "appends the template to the Guardfile" do
-+        plugin_util.add_to_guardfile
-+        expect(io.string).to eq "Guardfile content\n\nTemplate content\n"
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/runner_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/runner_spec.rb
-@@ -0,0 +1,439 @@
-+require "guard/runner"
-+
-+require "guard/plugin"
-+
-+RSpec.describe Guard::Runner do
-+  let(:ui_config) { instance_double("Guard::UI::Config") }
-+  let(:backend_group) do
-+    instance_double("Guard::Group", options: {}, name: :backend)
-+  end
-+
-+  let(:frontend_group) do
-+    instance_double("Guard::Group", options: {}, name: :frontend)
-+  end
-+
-+  let(:foo_plugin) { double("foo", group: backend_group, hook: nil) }
-+  let(:bar_plugin) { double("bar", group: frontend_group, hook: nil) }
-+  let(:baz_plugin) { double("baz", group: frontend_group, hook: nil) }
-+
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+
-+  before do
-+    allow(session).to receive(:plugins).and_return(plugins)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(state).to receive(:scope).and_return(scope)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    allow(Guard::UI::Config).to receive(:new).and_return(ui_config)
-+  end
-+
-+  before do
-+    Guard::UI.options = nil
-+  end
-+
-+  after do
-+    Guard::UI.reset_logger
-+    Guard::UI.options = nil
-+  end
-+
-+  describe "#run" do
-+    before do
-+      allow(scope).to receive(:grouped_plugins).with({}).
-+        and_return([[nil, [foo_plugin, bar_plugin, baz_plugin]]])
-+
-+      allow(ui_config).to receive(:with_progname).and_yield
-+    end
-+
-+    it "executes supervised task on all registered plugins implementing it" do
-+      [foo_plugin, bar_plugin].each do |plugin|
-+        expect(plugin).to receive(:my_hard_task)
-+      end
-+
-+      subject.run(:my_hard_task)
-+    end
-+
-+    it "marks an action as unit of work" do
-+      expect(Lumberjack).to receive(:unit_of_work)
-+      subject.run(:my_task)
-+    end
-+
-+    context "with interrupted task" do
-+      before do
-+        allow(foo_plugin).to receive(:failing).and_raise(Interrupt)
-+        # allow(Guard).to receive(:plugins).and_return([foo_plugin])
-+      end
-+
-+      it "catches the thrown symbol" do
-+        expect { subject.run(:failing) }.to_not throw_symbol(:task_has_failed)
-+      end
-+    end
-+
-+    context "with a scope" do
-+      let(:scope_hash) { { plugin: :bar } }
-+
-+      it "executes the supervised task on the specified plugin only" do
-+        expect(scope).to receive(:grouped_plugins).with(scope_hash).
-+          and_return([[nil, [bar_plugin]]])
-+
-+        expect(bar_plugin).to receive(:my_task)
-+        expect(foo_plugin).to_not receive(:my_task)
-+        expect(baz_plugin).to_not receive(:my_task)
-+
-+        subject.run(:my_task, scope_hash)
-+      end
-+    end
-+
-+    context "with no scope" do
-+      let(:scope_hash) { nil }
-+
-+      it "executes the supervised task using current scope" do
-+        expect(bar_plugin).to receive(:my_task)
-+        expect(foo_plugin).to receive(:my_task)
-+        expect(baz_plugin).to receive(:my_task)
-+
-+        subject.run(:my_task, scope_hash)
-+      end
-+    end
-+  end
-+
-+  describe "#run_on_changes" do
-+    let(:changes) { [[], [], []] }
-+    let(:watcher_module) { Guard::Watcher }
-+
-+    before do
-+      allow(watcher_module).to receive(:match_files) { [] }
-+      allow(Guard::UI).to receive(:clear)
-+
-+      allow(foo_plugin).to receive(:regular_without_arg) { fail "not stubbed" }
-+      allow(foo_plugin).to receive(:regular_with_arg) { fail "not stubbed" }
-+      allow(foo_plugin).to receive(:failing) { fail "not stubbed" }
-+
-+      # TODO: runner shouldn't have to know about these
-+      allow(foo_plugin).to receive(:run_on_modifications) { fail "not stubbed" }
-+      allow(foo_plugin).to receive(:run_on_change) { fail "not stubbed" }
-+      allow(foo_plugin).to receive(:run_on_additions) { fail "not stubbed" }
-+      allow(foo_plugin).to receive(:run_on_removals) { fail "not stubbed" }
-+      allow(foo_plugin).to receive(:run_on_deletion) { fail "not stubbed" }
-+
-+      allow(foo_plugin).to receive(:my_task)
-+      allow(bar_plugin).to receive(:my_task)
-+      allow(baz_plugin).to receive(:my_task)
-+
-+      allow(foo_plugin).to receive(:name).and_return("Foo")
-+
-+      allow(scope).to receive(:grouped_plugins) do |args|
-+        fail "stub me (#{args.inspect})!"
-+      end
-+
-+      # disable reevaluator
-+      allow(scope).to receive(:grouped_plugins).with(group: :common).
-+        and_return([[nil, []]])
-+
-+      # foo in default group
-+      allow(scope).to receive(:grouped_plugins).with(group: :default).
-+        and_return([[nil, [foo_plugin]]])
-+
-+      allow(scope).to receive(:grouped_plugins).with(no_args).
-+        and_return([[nil, [foo_plugin]]])
-+
-+      allow(ui_config).to receive(:with_progname).and_yield
-+    end
-+
-+    it "always calls UI.clearable" do
-+      expect(Guard::UI).to receive(:clearable)
-+      expect(scope).to receive(:grouped_plugins).with(no_args).
-+        and_return([[nil, [foo_plugin]]])
-+
-+      subject.run_on_changes(*changes)
-+    end
-+
-+    context "when clearable" do
-+      it "clear UI" do
-+        expect(Guard::UI).to receive(:clear)
-+        expect(scope).to receive(:grouped_plugins).with(no_args).
-+          and_return([[nil, [foo_plugin]]])
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+
-+    context "with no changes" do
-+      it "does not run any task" do
-+        %w(
-+          run_on_modifications
-+          run_on_change
-+          run_on_additions
-+          run_on_removals
-+          run_on_deletion
-+        ).each do |task|
-+          expect(foo_plugin).to_not receive(task.to_sym)
-+        end
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+
-+    context "with modified files but modified paths is empty" do
-+      let(:modified) { %w(file.txt image.png) }
-+
-+      before do
-+        changes[0] = modified
-+        expect(watcher_module).to receive(:match_files).once.
-+          with(foo_plugin, modified).and_return([])
-+
-+        # stub so respond_to? works
-+      end
-+
-+      it "does not call run anything" do
-+        expect(foo_plugin).to_not receive(:run_on_modifications)
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+
-+    context "with modified paths" do
-+      let(:modified) { %w(file.txt image.png) }
-+
-+      before do
-+        changes[0] = modified
-+        expect(watcher_module).to receive(:match_files).
-+          with(foo_plugin, modified).and_return(modified)
-+      end
-+
-+      it "executes the :run_first_task_found task" do
-+        expect(foo_plugin).to receive(:run_on_modifications).with(modified) {}
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+
-+    context "with added files but added paths is empty" do
-+      let(:added) { %w(file.txt image.png) }
-+
-+      before do
-+        changes[0] = added
-+        expect(watcher_module).to receive(:match_files).once.
-+          with(foo_plugin, added).and_return([])
-+      end
-+
-+      it "does not call run anything" do
-+        expect(foo_plugin).to_not receive(:run_on_additions)
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+
-+    context "with added paths" do
-+      let(:added) { %w(file.txt image.png) }
-+
-+      before do
-+        changes[1] = added
-+        expect(watcher_module).to receive(:match_files).
-+          with(foo_plugin, added).and_return(added)
-+      end
-+
-+      it "executes the :run_on_additions task" do
-+        expect(foo_plugin).to receive(:run_on_additions).with(added) {}
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+
-+    context "with non-matching removed paths" do
-+      let(:removed) { %w(file.txt image.png) }
-+
-+      before do
-+        changes[2] = removed
-+        expect(watcher_module).to receive(:match_files).once.
-+          with(foo_plugin, removed) { [] }
-+
-+        # stub so respond_to? works
-+        allow(foo_plugin).to receive(:run_on_removals)
-+      end
-+
-+      it "does not call tasks" do
-+        expect(foo_plugin).to_not receive(:run_on_removals)
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+
-+    context "with matching removed paths" do
-+      let(:removed) { %w(file.txt image.png) }
-+
-+      before do
-+        changes[2] = removed
-+        expect(watcher_module).to receive(:match_files).
-+          with(foo_plugin, removed) { removed }
-+      end
-+
-+      it "executes the :run_on_removals task" do
-+        expect(foo_plugin).to receive(:run_on_removals).with(removed) {}
-+        subject.run_on_changes(*changes)
-+      end
-+    end
-+  end
-+
-+  describe "#_supervise" do
-+    before do
-+      allow(ui_config).to receive(:with_progname).and_yield
-+    end
-+
-+    it "executes the task on the passed guard" do
-+      expect(foo_plugin).to receive(:my_task)
-+      subject.send(:_supervise, foo_plugin, :my_task)
-+    end
-+
-+    context "with a task that succeeds" do
-+      context "without any arguments" do
-+        before do
-+          allow(foo_plugin).to receive(:regular_without_arg) { true }
-+        end
-+
-+        it "does not remove the Guard" do
-+          expect(plugins).to_not receive(:remove)
-+          subject.send(:_supervise, foo_plugin, :regular_without_arg)
-+        end
-+
-+        it "returns the result of the task" do
-+          result = subject.send(:_supervise, foo_plugin, :regular_without_arg)
-+          expect(result).to be_truthy
-+        end
-+
-+        it "calls :begin and :end hooks" do
-+          expect(foo_plugin).to receive(:hook).
-+            with("regular_without_arg_begin")
-+
-+          expect(foo_plugin).to receive(:hook).
-+            with("regular_without_arg_end", true)
-+
-+          subject.send(:_supervise, foo_plugin, :regular_without_arg)
-+        end
-+
-+        it "passes the result of the supervised method to the :end hook" do
-+          expect(foo_plugin).to receive(:hook).
-+            with("regular_without_arg_begin")
-+
-+          expect(foo_plugin).to receive(:hook).
-+            with("regular_without_arg_end", true)
-+
-+          subject.send(:_supervise, foo_plugin, :regular_without_arg)
-+        end
-+      end
-+
-+      context "with arguments" do
-+        before do
-+          allow(foo_plugin).to receive(:regular_with_arg).
-+            with("given_path") { "I'm a success" }
-+        end
-+
-+        it "does not remove the Guard" do
-+          expect(plugins).to_not receive(:remove)
-+          subject.send(
-+            :_supervise,
-+            foo_plugin,
-+            :regular_with_arg,
-+            "given_path"
-+          )
-+        end
-+
-+        it "returns the result of the task" do
-+          result = subject.send(
-+            :_supervise,
-+            foo_plugin,
-+            :regular_with_arg,
-+            "given_path"
-+          )
-+
-+          expect(result).to eq "I'm a success"
-+        end
-+      end
-+    end
-+
-+    context "with a task that throws :task_has_failed" do
-+      before do
-+        allow(foo_plugin).to receive(:failing) { throw :task_has_failed }
-+      end
-+
-+      context "in a group" do
-+        context "with halt_on_fail: true" do
-+          before { backend_group.options[:halt_on_fail] = true }
-+
-+          it "throws :task_has_failed" do
-+            expect do
-+              subject.send(:_supervise, foo_plugin, :failing)
-+            end.to throw_symbol(:task_has_failed)
-+          end
-+        end
-+
-+        context "with halt_on_fail: false" do
-+          before { backend_group.options[:halt_on_fail] = false }
-+
-+          it "catches :task_has_failed" do
-+            expect do
-+              subject.send(:_supervise, foo_plugin, :failing)
-+            end.to_not throw_symbol(:task_has_failed)
-+          end
-+        end
-+      end
-+    end
-+
-+    context "with a task that raises an exception" do
-+      before do
-+        allow(foo_plugin).to receive(:failing) { fail "I break your system" }
-+        allow(plugins).to receive(:remove).with(foo_plugin)
-+      end
-+
-+      it "removes the Guard" do
-+        expect(plugins).to receive(:remove).with(foo_plugin) {}
-+        subject.send(:_supervise, foo_plugin, :failing)
-+      end
-+
-+      it "display an error to the user" do
-+        expect(::Guard::UI).to receive :error
-+        expect(::Guard::UI).to receive :info
-+
-+        subject.send(:_supervise, foo_plugin, :failing)
-+      end
-+
-+      it "returns the exception" do
-+        failing_result = subject.send(:_supervise, foo_plugin, :failing)
-+        expect(failing_result).to be_kind_of(Exception)
-+        expect(failing_result.message).to eq "I break your system"
-+      end
-+
-+      it "calls the default begin hook but not the default end hook" do
-+        expect(foo_plugin).to receive(:hook).with("failing_begin")
-+        expect(foo_plugin).to_not receive(:hook).with("failing_end")
-+        subject.send(:_supervise, foo_plugin, :failing)
-+      end
-+    end
-+  end
-+
-+  describe ".stopping_symbol_for" do
-+    let(:guard_plugin) { instance_double("Guard::Plugin") }
-+    let(:group) { instance_double("Guard::Group", title: "Foo") }
-+
-+    before do
-+      allow(guard_plugin).to receive(:group).and_return(group)
-+    end
-+
-+    context "for a group with :halt_on_fail" do
-+      before do
-+        allow(group).to receive(:options).and_return(halt_on_fail: true)
-+      end
-+
-+      it "returns :no_catch" do
-+        symbol = described_class.stopping_symbol_for(guard_plugin)
-+        expect(symbol).to eq :no_catch
-+      end
-+    end
-+
-+    context "for a group without :halt_on_fail" do
-+      before do
-+        allow(group).to receive(:options).and_return(halt_on_fail: false)
-+      end
-+
-+      it "returns :task_has_failed" do
-+        symbol = described_class.stopping_symbol_for(guard_plugin)
-+        expect(symbol).to eq :task_has_failed
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/terminal_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/terminal_spec.rb
-@@ -0,0 +1,65 @@
-+require "guard/terminal"
-+
-+RSpec.describe Guard::Terminal do
-+  subject { described_class }
-+  it { is_expected.to respond_to(:clear) }
-+
-+  let(:sheller) { class_double("Shellany::Sheller") }
-+
-+  before do
-+    stub_const("Shellany::Sheller", sheller)
-+  end
-+
-+  describe ".clear" do
-+    context "when on UNIX" do
-+      before { allow(Gem).to receive(:win_platform?).and_return(false) }
-+
-+      context "when the clear command exists" do
-+        let(:result) { [0, "\e[H\e[2J", ""] }
-+
-+        it "clears the screen using 'clear'" do
-+          expect(sheller).to receive(:system).with("printf '\33c\e[3J';").
-+            and_return(result)
-+          ::Guard::Terminal.clear
-+        end
-+      end
-+
-+      context "when the clear command fails" do
-+        let(:result) { [nil, nil, "Guard failed to run \"clear;\""] }
-+
-+        before do
-+          allow(sheller).to receive(:system).with("printf '\33c\e[3J';").
-+            and_return(result)
-+        end
-+
-+        it "fails" do
-+          expect { ::Guard::Terminal.clear }.
-+            to raise_error(Errno::ENOENT, /Guard failed to run "clear;"/)
-+        end
-+      end
-+    end
-+
-+    context "when on Windows" do
-+      before { allow(Gem).to receive(:win_platform?).and_return(true) }
-+
-+      it "clears the screen" do
-+        result = [0, "\f", ""]
-+        expect(sheller).to receive(:system).with("cls").and_return(result)
-+        ::Guard::Terminal.clear
-+      end
-+
-+      context "when the clear command fails" do
-+        let(:result) { [nil, nil, "Guard failed to run \"cls\""] }
-+
-+        before do
-+          allow(sheller).to receive(:system).with("cls").and_return(result)
-+        end
-+
-+        it "fails" do
-+          expect { ::Guard::Terminal.clear }.
-+            to raise_error(Errno::ENOENT, /Guard failed to run "cls"/)
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/ui/config_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/ui/config_spec.rb
-@@ -0,0 +1,73 @@
-+require "guard/ui/config"
-+
-+RSpec.describe Guard::UI::Config do
-+  describe "#device" do
-+    context "when not set" do
-+      context "when accessed as a method" do
-+        it "returns $stderr" do
-+          expect(subject.device).to be($stderr)
-+        end
-+      end
-+
-+      context "when accessed as a string" do
-+        it "returns $stderr" do
-+          expect(subject["device"]).to be($stderr)
-+        end
-+      end
-+
-+      context "when accessed as a symbol" do
-+        it "returns $stderr" do
-+          expect(subject[:device]).to be($stderr)
-+        end
-+      end
-+    end
-+  end
-+
-+  describe "#logger_config" do
-+    let(:options) { {} }
-+    subject { described_class.new(options) }
-+
-+    let(:logger_config) { instance_double("Guard::UI::Logger::Config") }
-+
-+    before do
-+      allow(Guard::UI::Logger::Config).to receive(:new).
-+        and_return(logger_config)
-+    end
-+
-+    context "with defaults" do
-+      it "provides a logger config" do
-+        expect(subject.logger_config).to be(logger_config)
-+      end
-+    end
-+
-+    context "with deprecated options set" do
-+      context "when set using a string" do
-+        subject { described_class.new('time_format': "foo") }
-+
-+        it "passes deprecated options to logger" do
-+          expect(Guard::UI::Logger::Config).to receive(:new).
-+            with(time_format: "foo")
-+          subject
-+        end
-+
-+        it "provides a logger config" do
-+          expect(subject.logger_config).to be(logger_config)
-+        end
-+      end
-+
-+      context "when set using a symbol" do
-+        let(:options) { { time_format: "foo" } }
-+
-+        it "passes deprecated options to logger" do
-+          expect(Guard::UI::Logger::Config).to receive(:new).
-+            with(time_format: "foo")
-+          subject
-+        end
-+
-+        it "provides a logger config" do
-+          expect(subject.logger_config).to be(logger_config)
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/ui/logger_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/ui/logger_spec.rb
-@@ -0,0 +1,22 @@
-+require "guard/ui/logger"
-+
-+RSpec.describe Guard::UI::Logger::Config do
-+  describe "defaults" do
-+    it "flushes device by default" do
-+      expect(subject[:flush_seconds]).to eq(0)
-+    end
-+  end
-+
-+  describe "#level=" do
-+    context "with a valid value" do
-+      before do
-+        subject.level = Logger::WARN
-+      end
-+
-+      it "stores the level" do
-+        expect(subject[:level]).to eq(Logger::WARN)
-+        expect(subject["level"]).to eq(Logger::WARN)
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/ui_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/ui_spec.rb
-@@ -0,0 +1,363 @@
-+require "guard/notifier"
-+
-+# NOTE: this is here so that no UI does not require anything,
-+# since it could be activated by guard plugins during development
-+# (it they are tested by other guard plugins)
-+#
-+# TODO: regardless, the dependency on Guard.state should be removed
-+#
-+require "guard/ui"
-+
-+require "guard/internals/session"
-+
-+RSpec.describe Guard::UI do
-+  let(:interactor) { instance_double("Guard::Interactor") }
-+  let(:logger) { instance_double("Lumberjack::Logger") }
-+  let(:config) { instance_double("Guard::UI::Config") }
-+  let(:logger_config) { instance_double("Guard::UI::Logger::Config") }
-+
-+  let(:terminal) { class_double("Guard::Terminal") }
-+
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+
-+  before do
-+    allow(state).to receive(:scope).and_return(scope)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard).to receive(:state).and_return(state)
-+
-+    stub_const("Guard::Terminal", terminal)
-+
-+    allow(Guard::Notifier).to receive(:turn_on) {}
-+
-+    allow(Lumberjack::Logger).to receive(:new).and_return(logger)
-+    allow(Guard::UI::Config).to receive(:new).and_return(config)
-+    allow(Guard::UI::Logger::Config).to receive(:new).and_return(logger_config)
-+
-+    # The spec helper stubs all UI classes, so other specs doesn't have
-+    # to explicit take care of it. We unstub and move the stubs one layer
-+    # down just for this spec.
-+    allow(Guard::UI).to receive(:info).and_call_original
-+    allow(Guard::UI).to receive(:warning).and_call_original
-+    allow(Guard::UI).to receive(:error).and_call_original
-+    allow(Guard::UI).to receive(:deprecation).and_call_original
-+    allow(Guard::UI).to receive(:debug).and_call_original
-+
-+    allow(logger).to receive(:info)
-+    allow(logger).to receive(:warn)
-+    allow(logger).to receive(:error)
-+    allow(logger).to receive(:debug)
-+
-+    allow(config).to receive(:device)
-+    allow(config).to receive(:only)
-+    allow(config).to receive(:except)
-+
-+    allow(config).to receive(:logger_config).and_return(logger_config)
-+
-+    allow($stderr).to receive(:print)
-+  end
-+
-+  before do
-+    Guard::UI.options = nil
-+  end
-+
-+  after do
-+    Guard::UI.reset_logger
-+    Guard::UI.options = nil
-+  end
-+
-+  describe ".logger" do
-+    before do
-+      allow(config).to receive(:device).and_return(device)
-+    end
-+
-+    context "with no logger set yet" do
-+      let(:device) { "foo.log" }
-+
-+      it "returns the logger instance" do
-+        expect(Guard::UI.logger).to be(logger)
-+      end
-+
-+      it "sets the logger device" do
-+        expect(Lumberjack::Logger).to receive(:new).
-+          with(device, logger_config)
-+
-+        Guard::UI.logger
-+      end
-+    end
-+  end
-+
-+  describe ".level=" do
-+    before do
-+      allow(logger).to receive(:level=)
-+      allow(logger_config).to receive(:level=)
-+    end
-+
-+    context "when logger is set up" do
-+      before { Guard::UI.logger }
-+
-+      it "sets the logger's level" do
-+        level = Logger::WARN
-+        expect(logger).to receive(:level=).with(level)
-+        Guard::UI.level = level
-+      end
-+
-+      it "sets the logger's config level" do
-+        level = Logger::WARN
-+        expect(logger_config).to receive(:level=).with(level)
-+        Guard::UI.level = level
-+      end
-+    end
-+
-+    context "when logger is not set up yet" do
-+      before { Guard::UI.reset_logger }
-+
-+      it "sets the logger's config level" do
-+        level = Logger::WARN
-+        expect(logger_config).to receive(:level=).with(level)
-+        Guard::UI.level = level
-+      end
-+
-+      it "does not autocreate the logger" do
-+        level = Logger::WARN
-+        expect(logger).to_not receive(:level=).with(level)
-+        Guard::UI.level = level
-+      end
-+    end
-+  end
-+
-+  describe ".options=" do
-+    let(:new_config) { instance_double("Guard::UI::Config") }
-+
-+    before do
-+      allow(Guard::UI::Config).to receive(:new).with(hi: :ho).
-+        and_return(new_config)
-+
-+      allow(new_config).to receive(:[]).with(:hi).and_return(:ho)
-+    end
-+
-+    it "sets the logger options" do
-+      Guard::UI.options = { hi: :ho }
-+      expect(Guard::UI.options[:hi]).to eq :ho
-+    end
-+  end
-+
-+  shared_examples_for "a logger method" do
-+    it "resets the line with the :reset option" do
-+      expect(Guard::UI).to receive :reset_line
-+      Guard::UI.send(ui_method, input, reset: true)
-+    end
-+
-+    it "logs the message with the given severity" do
-+      expect(logger).to receive(severity).with(output)
-+      Guard::UI.send(ui_method, input)
-+    end
-+
-+    context "with the :only option" do
-+      before { allow(config).to receive(:only).and_return(/A/) }
-+
-+      it "allows logging matching messages" do
-+        expect(logger).to receive(severity).with(output)
-+        Guard::UI.send(ui_method, input, plugin: "A")
-+      end
-+
-+      it "prevents logging other messages" do
-+        expect(logger).to_not receive(severity)
-+        Guard::UI.send(ui_method, input, plugin: "B")
-+      end
-+    end
-+
-+    context "with the :except option" do
-+      before { allow(config).to receive(:except).and_return(/A/) }
-+
-+      it "prevents logging matching messages" do
-+        expect(logger).to_not receive(severity)
-+        Guard::UI.send(ui_method, input, plugin: "A")
-+      end
-+
-+      it "allows logging other messages" do
-+        expect(logger).to receive(severity).with(output)
-+        Guard::UI.send(ui_method, input, plugin: "B")
-+      end
-+    end
-+  end
-+
-+  describe ".info" do
-+    it_behaves_like "a logger method" do
-+      let(:ui_method) { :info }
-+      let(:severity) { :info }
-+      let(:input) { "Info" }
-+      let(:output) { "Info" }
-+    end
-+  end
-+
-+  describe ".warning" do
-+    it_behaves_like "a logger method" do
-+      let(:ui_method) { :warning }
-+      let(:severity) { :warn }
-+      let(:input) { "Warning" }
-+      let(:output) { "\e[0;33mWarning\e[0m" }
-+    end
-+  end
-+
-+  describe ".error" do
-+    it_behaves_like "a logger method" do
-+      let(:ui_method) { :error }
-+      let(:severity) { :error }
-+      let(:input) { "Error" }
-+      let(:output) { "\e[0;31mError\e[0m" }
-+    end
-+  end
-+
-+  describe ".deprecation" do
-+    before do
-+      allow(ENV).to receive(:[]).with("GUARD_GEM_SILENCE_DEPRECATIONS").
-+        and_return(value)
-+    end
-+
-+    context "with GUARD_GEM_SILENCE_DEPRECATIONS set to 1" do
-+      let(:value) { "1" }
-+
-+      it "silences deprecations" do
-+        expect(Guard::UI.logger).to_not receive(:warn)
-+        Guard::UI.deprecation "Deprecator message"
-+      end
-+    end
-+
-+    context "with GUARD_GEM_SILENCE_DEPRECATIONS unset" do
-+      let(:value) { nil }
-+
-+      it_behaves_like "a logger method" do
-+        let(:ui_method) { :deprecation }
-+        let(:severity) { :warn }
-+        let(:input) { "Deprecated" }
-+        let(:output) do
-+          /^\e\[0;33mDeprecated\nDeprecation backtrace: .*\e\[0m$/m
-+        end
-+      end
-+    end
-+  end
-+
-+  describe ".debug" do
-+    it_behaves_like "a logger method" do
-+      let(:ui_method) { :debug }
-+      let(:severity) { :debug }
-+      let(:input) { "Debug" }
-+      let(:output) { "\e[0;33mDebug\e[0m" }
-+    end
-+  end
-+
-+  describe ".clear" do
-+    context "with UI set up and ready" do
-+      before do
-+        allow(session).to receive(:clear?).and_return(false)
-+        Guard::UI.reset_and_clear
-+      end
-+
-+      context "when clear option is disabled" do
-+        it "does not clear the output" do
-+          expect(terminal).to_not receive(:clear)
-+          Guard::UI.clear
-+        end
-+      end
-+
-+      context "when clear option is enabled" do
-+        before do
-+          allow(session).to receive(:clear?).and_return(true)
-+        end
-+
-+        context "when the screen is marked as needing clearing" do
-+          before { Guard::UI.clearable }
-+
-+          it "clears the output" do
-+            expect(terminal).to receive(:clear)
-+            Guard::UI.clear
-+          end
-+
-+          it "clears the output only once" do
-+            expect(terminal).to receive(:clear).once
-+            Guard::UI.clear
-+            Guard::UI.clear
-+          end
-+
-+          context "when the command fails" do
-+            before do
-+              allow(terminal).to receive(:clear).
-+                and_raise(Errno::ENOENT, "failed to run command")
-+            end
-+
-+            it "shows a warning" do
-+              expect(logger).to receive(:warn) do |arg|
-+                expect(arg).to match(/failed to run command/)
-+              end
-+              Guard::UI.clear
-+            end
-+          end
-+        end
-+
-+        context "when the screen has just been cleared" do
-+          before { Guard::UI.clear }
-+
-+          it "does not clear" do
-+            expect(terminal).to_not receive(:clear)
-+            Guard::UI.clear
-+          end
-+
-+          context "when forced" do
-+            let(:opts) { { force: true } }
-+
-+            it "clears the outputs if forced" do
-+              expect(terminal).to receive(:clear)
-+              Guard::UI.clear(opts)
-+            end
-+          end
-+        end
-+      end
-+    end
-+  end
-+
-+  describe ".action_with_scopes" do
-+    let(:rspec) { double("Rspec", title: "Rspec") }
-+    let(:jasmine) { double("Jasmine", title: "Jasmine") }
-+    let(:group) { instance_double("Guard::Group", title: "Frontend") }
-+
-+    context "with a plugins scope" do
-+      it "shows the plugin scoped action" do
-+        allow(scope).to receive(:titles).with(plugins: [rspec, jasmine]).
-+          and_return(%w(Rspec Jasmine))
-+
-+        expect(Guard::UI).to receive(:info).with("Reload Rspec, Jasmine")
-+        Guard::UI.action_with_scopes("Reload", plugins: [rspec, jasmine])
-+      end
-+    end
-+
-+    context "with a groups scope" do
-+      it "shows the group scoped action" do
-+        allow(scope).to receive(:titles).with(groups: [group]).
-+          and_return(%w(Frontend))
-+
-+        expect(Guard::UI).to receive(:info).with("Reload Frontend")
-+        Guard::UI.action_with_scopes("Reload", groups: [group])
-+      end
-+    end
-+
-+    context "without a scope" do
-+      context "with a global plugin scope" do
-+        it "shows the global plugin scoped action" do
-+          allow(scope).to receive(:titles).and_return(%w(Rspec Jasmine))
-+          expect(Guard::UI).to receive(:info).with("Reload Rspec, Jasmine")
-+          Guard::UI.action_with_scopes("Reload", {})
-+        end
-+      end
-+
-+      context "with a global group scope" do
-+        it "shows the global group scoped action" do
-+          allow(scope).to receive(:titles).and_return(%w(Frontend))
-+          expect(Guard::UI).to receive(:info).with("Reload Frontend")
-+          Guard::UI.action_with_scopes("Reload", {})
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/watcher/pattern/deprecated_regexp_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/watcher/pattern/deprecated_regexp_spec.rb
-@@ -0,0 +1,28 @@
-+require "guard/watcher/pattern/deprecated_regexp"
-+
-+RSpec.describe Guard::Watcher::Pattern::DeprecatedRegexp do
-+  describe ".deprecated?" do
-+    specify { expect(described_class.new("^spec_helper.rb")).to be_deprecated }
-+    specify { expect(described_class.new("spec_helper.rb$")).to be_deprecated }
-+  end
-+
-+  describe "Matcher returned by .convert" do
-+    let(:matcher) { Guard::Watcher::Pattern::Matcher }
-+
-+    before { allow(matcher).to receive(:new) }
-+
-+    {
-+      "^foo.rb" => /^foo.rb/,
-+      "foo.rb$" => /foo.rb$/,
-+      'foo\.rb' => /foo\.rb/,
-+      ".*rb" => /.*rb/,
-+    }.each do |pattern, regexp|
-+      context "with #{pattern}" do
-+        it "creates a Matcher with #{regexp}" do
-+          expect(matcher).to receive(:new).with(regexp)
-+          described_class.convert(pattern)
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/watcher/pattern/match_result_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/watcher/pattern/match_result_spec.rb
-@@ -0,0 +1,46 @@
-+require "guard/watcher/pattern/match_result"
-+
-+RSpec.describe Guard::Watcher::Pattern::MatchResult do
-+  let(:match_result) { double("match_data") }
-+  let(:original_value) { "foo/bar.rb" }
-+  subject { described_class.new(match_result, original_value) }
-+
-+  describe "#initialize" do
-+    context "with valid arguments" do
-+      it "does not fail" do
-+        expect { subject }.to_not raise_error
-+      end
-+    end
-+  end
-+
-+  describe "#[]" do
-+    context "with a valid match" do
-+      let(:match_result) { double("match_data", to_a: %w(foo bar baz)) }
-+
-+      context "when asked for the non-first item" do
-+        let(:index) { 1 }
-+        it "returns the value at given index" do
-+          expect(subject[index]).to eq("bar")
-+        end
-+      end
-+
-+      context "when asked for the first item" do
-+        let(:index) { 0 }
-+        it "returns the full original value" do
-+          expect(subject[index]).to eq("foo/bar.rb")
-+        end
-+      end
-+
-+      context "when asked for a name match via a symbol" do
-+        let(:index) { :foo }
-+        before do
-+          allow(match_result).to receive(:[]).with(:foo).and_return("baz")
-+        end
-+
-+        it "returns the value by name" do
-+          expect(subject[index]).to eq("baz")
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/watcher/pattern/matcher_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/watcher/pattern/matcher_spec.rb
-@@ -0,0 +1,82 @@
-+require "guard/watcher/pattern/matcher"
-+
-+RSpec.describe Guard::Watcher::Pattern::Matcher do
-+  subject { described_class.new(obj) }
-+  describe "#match" do
-+    let(:expected) { double("match_result") }
-+
-+    context "when constructed with valid matcher object" do
-+      let(:obj) { double("matcher") }
-+
-+      context "when matched against a Pathname" do
-+        before do
-+          allow(obj).to receive(:match).and_return(expected)
-+        end
-+        let(:filename) { Pathname("foo.rb") }
-+
-+        it "returns the match result" do
-+          expect(subject.match(filename)).to be(expected)
-+        end
-+
-+        it "passes the Pathname to the matcher" do
-+          allow(obj).to receive(:match).with(filename)
-+          subject.match(filename)
-+        end
-+      end
-+
-+      context "when matched against a String" do
-+        before do
-+          allow(obj).to receive(:match).and_return(expected)
-+        end
-+        let(:filename) { "foo.rb" }
-+
-+        it "returns the match result" do
-+          expect(subject.match(filename)).to be(expected)
-+        end
-+
-+        it "passes a Pathname to the matcher" do
-+          allow(obj).to receive(:match).with(Pathname(filename))
-+          subject.match(filename)
-+        end
-+      end
-+    end
-+  end
-+
-+  describe "integration" do
-+    describe "#match result" do
-+      subject { described_class.new(obj).match(filename) }
-+      context "when constructed with valid regexp" do
-+        let(:obj) { /foo.rb$/ }
-+
-+        context "when matched file is a string" do
-+          context "when filename matches" do
-+            let(:filename) { "foo.rb" }
-+            specify { expect(subject.to_a).to eq(["foo.rb"]) }
-+          end
-+
-+          context "when filename does not match" do
-+            let(:filename) { "bar.rb" }
-+            specify { expect(subject).to be_nil }
-+          end
-+        end
-+
-+        context "when matched file is an unclean Pathname" do
-+          context "when filename matches" do
-+            let(:filename) { Pathname("./foo.rb") }
-+            specify { expect(subject.to_a).to eq(["foo.rb"]) }
-+          end
-+
-+          context "when filename does not match" do
-+            let(:filename) { Pathname("./bar.rb") }
-+            specify { expect(subject).to be_nil }
-+          end
-+        end
-+
-+        context "when matched file contains a $" do
-+          let(:filename) { Pathname("lib$/foo.rb") }
-+          specify { expect(subject.to_a).to eq(["foo.rb"]) }
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/watcher/pattern/pathname_path_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/watcher/pattern/pathname_path_spec.rb
-@@ -0,0 +1,35 @@
-+require "guard/watcher/pattern/pathname_path"
-+
-+RSpec.describe Guard::Watcher::Pattern::PathnamePath do
-+  subject { described_class.new(path) }
-+  describe "#match result" do
-+    subject { described_class.new(path).match(filename) }
-+    context "when constructed with an unclean Pathname" do
-+      let(:path) { Pathname("./foo.rb") }
-+
-+      context "when matched file is a string" do
-+        context "when filename matches" do
-+          let(:filename) { "foo.rb" }
-+          specify { expect(subject).to eq([Pathname("foo.rb")]) }
-+        end
-+
-+        context "when filename does not match" do
-+          let(:filename) { "bar.rb" }
-+          specify { expect(subject).to be_nil }
-+        end
-+      end
-+
-+      context "when matched file is an unclean Pathname" do
-+        context "when filename matches" do
-+          let(:filename) { Pathname("./foo.rb") }
-+          specify { expect(subject).to eq([Pathname("foo.rb")]) }
-+        end
-+
-+        context "when filename does not match" do
-+          let(:filename) { Pathname("./bar.rb") }
-+          specify { expect(subject).to be_nil }
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/watcher/pattern/simple_path_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/watcher/pattern/simple_path_spec.rb
-@@ -0,0 +1,35 @@
-+require "guard/watcher/pattern/simple_path"
-+
-+RSpec.describe Guard::Watcher::Pattern::SimplePath do
-+  subject { described_class.new(path) }
-+
-+  describe "#match result" do
-+    context "when constructed with filename string" do
-+      let(:path) { "foo.rb" }
-+
-+      context "when matched file is a string" do
-+        context "when filename matches" do
-+          let(:filename) { "foo.rb" }
-+          specify { expect(subject.match(filename)).to eq(["foo.rb"]) }
-+        end
-+
-+        context "when filename does not match" do
-+          let(:filename) { "bar.rb" }
-+          specify { expect(subject.match(filename)).to be_nil }
-+        end
-+      end
-+
-+      context "when matched file is an unclean Pathname" do
-+        context "when filename matches" do
-+          let(:filename) { Pathname("./foo.rb") }
-+          specify { expect(subject.match(filename)).to eq(["foo.rb"]) }
-+        end
-+
-+        context "when filename does not match" do
-+          let(:filename) { Pathname("./bar.rb") }
-+          specify { expect(subject.match(filename)).to be_nil }
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/watcher/pattern_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/watcher/pattern_spec.rb
-@@ -0,0 +1,37 @@
-+require "guard/watcher/pattern"
-+
-+RSpec.describe Guard::Watcher::Pattern do
-+  describe ".create" do
-+    subject { described_class.create(pattern) }
-+
-+    context "when a string is given" do
-+      let(:pattern) { "foo.rb" }
-+      it { is_expected.to be_a(described_class::SimplePath) }
-+    end
-+
-+    context "when a Pathname is given" do
-+      let(:pattern) { Pathname("foo.rb") }
-+      it { is_expected.to be_a(described_class::PathnamePath) }
-+    end
-+
-+    context "when an regexp string is given" do
-+      let(:pattern) { "^foo.*$" }
-+      it { is_expected.to be_a(described_class::Matcher) }
-+      it "shows a warning" do
-+        expect(described_class::DeprecatedRegexp).
-+          to receive(:show_deprecation).with(pattern)
-+        subject
-+      end
-+    end
-+
-+    context "when a regexp is given" do
-+      let(:pattern) { /foo\.rb/ }
-+      it { is_expected.to be_a(described_class::Matcher) }
-+    end
-+
-+    context "when a custom matcher" do
-+      let(:pattern) { Class.new { def match; end } }
-+      it { is_expected.to be_a(described_class::Matcher) }
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard/watcher_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard/watcher_spec.rb
-@@ -0,0 +1,351 @@
-+require "guard/watcher"
-+
-+# TODO: shouldn't be needed
-+require "guard/guardfile/evaluator"
-+
-+RSpec.describe Guard::Watcher do
-+  let(:args) { [] }
-+  subject { described_class.new(*args) }
-+  describe "#initialize" do
-+    context "with no arguments" do
-+      let(:args) { [] }
-+      it "raises an error" do
-+        expect { subject }.to raise_error(ArgumentError)
-+      end
-+    end
-+
-+    context "with a pattern parameter" do
-+      let(:pattern) { ["spec_helper.rb"] }
-+      let(:args) { [pattern] }
-+
-+      it "creates a matcher" do
-+        expect(described_class::Pattern).to receive(:create).with(pattern)
-+        subject
-+      end
-+    end
-+  end
-+
-+  describe "#action" do
-+    it "sets the action to nothing by default" do
-+      expect(described_class.new(/spec_helper\.rb/).action).to be_nil
-+    end
-+
-+    it "sets the action to the supplied block" do
-+      action = ->(m) { "spec/#{m[1]}_spec.rb" }
-+      expect(described_class.new(%r{^lib/(.*).rb}, action).action).to eq action
-+    end
-+  end
-+
-+  describe ".match_files" do
-+    let(:plugin) { instance_double("Guard::Plugin", options: {}) }
-+
-+    def matched(files)
-+      described_class.match_files(plugin, files)
-+    end
-+
-+    context "without a watcher action" do
-+      before do
-+        allow(plugin).to receive(:watchers).
-+          and_return([described_class.new(pattern)])
-+      end
-+
-+      context "with a regex pattern" do
-+        let(:pattern) { /.*_spec\.rb/ }
-+        it "returns the paths that matches the regex" do
-+          expect(matched(%w(foo_spec.rb foo.rb))).to eq %w(foo_spec.rb)
-+        end
-+      end
-+
-+      context "with a string pattern" do
-+        let(:pattern) { "foo_spec.rb" }
-+        it "returns the path that matches the string" do
-+          expect(matched(%w(foo_spec.rb foo.rb))).to eq ["foo_spec.rb"]
-+        end
-+      end
-+    end
-+
-+    context "with a watcher action without parameter" do
-+      context "for a watcher that matches file strings" do
-+        before do
-+          klass = described_class
-+          allow(plugin).to receive(:watchers).and_return(
-+            [
-+              klass.new("spec_helper.rb", -> { "spec" }),
-+              klass.new("addition.rb", -> { 1 + 1 }),
-+              klass.new("hash.rb", -> { Hash[:foo, "bar"] }),
-+              klass.new("array.rb", -> { %w(foo bar) }),
-+              klass.new("blank.rb", -> { "" }),
-+              klass.new(/^uptime\.rb/, -> { "" })
-+            ]
-+          )
-+        end
-+
-+        it "returns a single file specified within the action" do
-+          expect(matched(%w(spec_helper.rb))).to eq ["spec"]
-+        end
-+
-+        it "returns multiple files specified within the action" do
-+          expect(matched(%w(hash.rb))).to eq %w(foo bar)
-+        end
-+
-+        it "combines files from results of different actions" do
-+          expect(matched(%w(spec_helper.rb array.rb))).to eq %w(spec foo bar)
-+        end
-+
-+        context "when action returns non-string or array of non-strings" do
-+          it "returns nothing" do
-+            expect(matched(%w(addition.rb))).to eq []
-+          end
-+        end
-+
-+        it "returns nothing if the action response is empty" do
-+          expect(matched(%w(blank.rb))).to eq []
-+        end
-+
-+        it "returns nothing if the action returns nothing" do
-+          expect(matched(%w(uptime.rb))).to eq []
-+        end
-+      end
-+
-+      context "for a watcher that matches information objects" do
-+        before do
-+          allow(plugin).to receive(:options).and_return(any_return: true)
-+
-+          klass = described_class
-+          allow(plugin).to receive(:watchers).and_return(
-+            [
-+              klass.new("spec_helper.rb", -> { "spec" }),
-+              klass.new("addition.rb", -> { 1 + 1 }),
-+              klass.new("hash.rb", -> { Hash[:foo, "bar"] }),
-+              klass.new("array.rb", -> { %w(foo bar) }),
-+              klass.new("blank.rb", -> { "" }),
-+              klass.new(/^uptime\.rb/, -> { "" })
-+            ]
-+          )
-+        end
-+
-+        it "returns a single file specified within the action" do
-+          expect(matched(%w(spec_helper.rb)).class).to be Array
-+          expect(matched(%w(spec_helper.rb))).to_not be_empty
-+        end
-+
-+        it "returns multiple files specified within the action" do
-+          expect(matched(%w(hash.rb))).to eq [{ foo: "bar" }]
-+        end
-+
-+        it "combines the results of different actions" do
-+          expect(matched(%w(spec_helper.rb array.rb))).
-+            to eq ["spec", %w(foo bar)]
-+        end
-+
-+        it "returns the evaluated addition argument in an array" do
-+          expect(matched(%w(addition.rb)).class).to be(Array)
-+          expect(matched(%w(addition.rb))[0]).to eq 2
-+        end
-+
-+        it "returns nothing if the action response is empty string" do
-+          expect(matched(%w(blank.rb))).to eq [""]
-+        end
-+
-+        it "returns nothing if the action returns empty string" do
-+          expect(matched(%w(uptime.rb))).to eq [""]
-+        end
-+      end
-+    end
-+
-+    context "with a watcher action that takes a parameter" do
-+      context "for a watcher that matches file strings" do
-+        before do
-+          klass = described_class
-+          allow(plugin).to receive(:watchers).and_return [
-+            klass.new(%r{lib/(.*)\.rb}, ->(m) { "spec/#{m[1]}_spec.rb" }),
-+            klass.new(/addition(.*)\.rb/, ->(_m) { 1 + 1 }),
-+            klass.new("hash.rb", ->(_m) { Hash[:foo, "bar"] }),
-+            klass.new(/array(.*)\.rb/, ->(_m) { %w(foo bar) }),
-+            klass.new(/blank(.*)\.rb/, ->(_m) { "" }),
-+            klass.new(/^uptime\.rb/, -> { "" })
-+          ]
-+        end
-+
-+        it "returns a substituted single file specified within the action" do
-+          expect(matched(%w(lib/foo.rb))).to eq ["spec/foo_spec.rb"]
-+        end
-+
-+        it "returns multiple files specified within the action" do
-+          expect(matched(%w(hash.rb))).to eq %w(foo bar)
-+        end
-+
-+        it "combines results of different actions" do
-+          expect(matched(%w(lib/foo.rb array.rb))).
-+            to eq %w(spec/foo_spec.rb foo bar)
-+        end
-+
-+        it "returns nothing if action returns non-string or non-string array" do
-+          expect(matched(%w(addition.rb))).to eq []
-+        end
-+
-+        it "returns nothing if the action response is empty" do
-+          expect(matched(%w(blank.rb))).to eq []
-+        end
-+
-+        it "returns nothing if the action returns nothing" do
-+          expect(matched(%w(uptime.rb))).to eq []
-+        end
-+      end
-+
-+      context "for a watcher that matches information objects" do
-+        before do
-+          allow(plugin).to receive(:options).and_return(any_return: true)
-+
-+          kl = described_class
-+          allow(plugin).to receive(:watchers).and_return(
-+            [
-+              kl.new(%r{lib/(.*)\.rb}, ->(m) { "spec/#{m[1]}_spec.rb" }),
-+              kl.new(/addition(.*)\.rb/, ->(m) { (1 + 1).to_s + m[0] }),
-+              kl.new("hash.rb", ->(m) { { foo: "bar", file_name: m[0] } }),
-+              kl.new(/array(.*)\.rb/, ->(m) { ["foo", "bar", m[0]] }),
-+              kl.new(/blank(.*)\.rb/, ->(_m) { "" }),
-+              kl.new(/^uptime\.rb/, -> { "" })
-+            ]
-+          )
-+        end
-+
-+        it "returns a substituted single file specified within the action" do
-+          expect(matched(%w(lib/foo.rb))).to eq %w(spec/foo_spec.rb)
-+        end
-+
-+        it "returns a hash specified within the action" do
-+          expect(matched(%w(hash.rb))).to eq [
-+            { foo: "bar", file_name: "hash.rb" }
-+          ]
-+        end
-+
-+        it "combinines results of different actions" do
-+          expect(matched(%w(lib/foo.rb array.rb))).
-+            to eq ["spec/foo_spec.rb", %w(foo bar array.rb)]
-+        end
-+
-+        it "returns the evaluated addition argument + the path" do
-+          expect(matched(%w(addition.rb))).to eq ["2addition.rb"]
-+        end
-+
-+        it "returns nothing if the action response is empty string" do
-+          expect(matched(%w(blank.rb))).to eq [""]
-+        end
-+
-+        it "returns nothing if the action returns is IO::NULL" do
-+          expect(matched(%w(uptime.rb))).to eq [""]
-+        end
-+      end
-+    end
-+
-+    context "with an exception that is raised" do
-+      before do
-+        allow(plugin).to receive(:watchers).and_return(
-+          [described_class.new("evil.rb", -> { fail "EVIL" })]
-+        )
-+      end
-+
-+      it "displays the error and backtrace" do
-+        expect(Guard::UI).to receive(:error) do |msg|
-+          expect(msg).to include("Problem with watch action!")
-+          expect(msg).to include("EVIL")
-+        end
-+
-+        described_class.match_files(plugin, ["evil.rb"])
-+      end
-+    end
-+
-+    context "for ambiguous watchers" do
-+      before do
-+        expect(plugin).to receive(:watchers).and_return [
-+          described_class.new("awesome_helper.rb", -> {}),
-+          described_class.new(/.+some_helper.rb/, -> { "foo.rb" }),
-+          described_class.new(/.+_helper.rb/, -> { "bar.rb" }),
-+        ]
-+      end
-+
-+      context "when the :first_match option is turned off" do
-+        before do
-+          allow(plugin).to receive(:options).and_return(first_match: false)
-+        end
-+
-+        it "returns multiple files by combining the results of the watchers" do
-+          expect(described_class.match_files(
-+                   plugin, ["awesome_helper.rb"]
-+          )).to eq(["foo.rb", "bar.rb"])
-+        end
-+      end
-+
-+      context "when the :first_match option is turned on" do
-+        before do
-+          plugin.options[:first_match] = true
-+        end
-+
-+        it "returns only the files from the first watcher" do
-+          expect(described_class.match_files(
-+                   plugin, ["awesome_helper.rb"]
-+          )).to eq(["foo.rb"])
-+        end
-+      end
-+    end
-+  end
-+
-+  describe "#match" do
-+    subject { described_class.new(pattern).match(file) }
-+
-+    let(:matcher) { instance_double(described_class::Pattern::Matcher) }
-+    let(:match) { instance_double(described_class::Pattern::MatchResult) }
-+
-+    before do
-+      allow(described_class::Pattern).to receive(:create).with(pattern).
-+        and_return(matcher)
-+
-+      allow(matcher).to receive(:match).with(pattern).
-+        and_return(match_data)
-+
-+      allow(described_class::Pattern::MatchResult).to receive(:new).
-+        with(match_data, file).and_return(match)
-+    end
-+
-+    context "with a valid pattern" do
-+      let(:pattern) { "foo.rb" }
-+      context "with a valid file name to match" do
-+        let(:file) { "foo.rb" }
-+        context "when matching is successful" do
-+          let(:match_data) { double("match data", to_a: ["foo"]) }
-+          it "returns the match result" do
-+            expect(subject).to be(match)
-+          end
-+        end
-+
-+        context "when matching is not successful" do
-+          let(:match_data) { nil }
-+          it "returns nil" do
-+            expect(subject).to be_nil
-+          end
-+        end
-+      end
-+    end
-+  end
-+
-+  describe "integration" do
-+    describe "#match" do
-+      subject { described_class.new(pattern) }
-+      context "with a named regexp pattern" do
-+        let(:pattern) { /(?<foo>.*)_spec\.rb/ }
-+
-+        context "with a watcher that matches a file" do
-+          specify do
-+            expect(subject.match("bar_spec.rb")[0]).to eq("bar_spec.rb")
-+            expect(subject.match("bar_spec.rb")[1]).to eq("bar")
-+          end
-+
-+          it "provides the match by name" do
-+            expect(subject.match("bar_spec.rb")[:foo]).to eq("bar")
-+          end
-+        end
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/lib/guard_spec.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/lib/guard_spec.rb
-@@ -0,0 +1,247 @@
-+require "guard"
-+
-+RSpec.describe Guard do
-+  # Initialize before Guard::Interactor const is stubbed
-+  let!(:interactor) { instance_double("Guard::Interactor") }
-+
-+  let(:guardfile) { File.expand_path("Guardfile") }
-+  let(:traps) { Guard::Internals::Traps }
-+
-+  let(:evaluator) { instance_double("Guard::Guardfile::Evaluator") }
-+
-+  let(:plugins) { instance_double("Guard::Internals::Plugins") }
-+  let(:scope) { instance_double("Guard::Internals::Scope") }
-+  let(:session) { instance_double("Guard::Internals::Session") }
-+  let(:state) { instance_double("Guard::Internals::State") }
-+  let(:queue) { instance_double("Guard::Internals::Queue") }
-+
-+  before do
-+    allow(Guard::Interactor).to receive(:new).and_return(interactor)
-+    allow(Guard::Guardfile::Evaluator).to receive(:new).and_return(evaluator)
-+
-+    allow(session).to receive(:debug?).and_return(false)
-+    allow(session).to receive(:plugins).and_return(plugins)
-+    allow(state).to receive(:session).and_return(session)
-+    allow(Guard::Internals::Session).to receive(:new).and_return(session)
-+    allow(Guard::Internals::Scope).to receive(:new).and_return(scope)
-+    allow(Guard::Internals::Queue).to receive(:new).and_return(queue)
-+  end
-+
-+  # TODO: setup has too many responsibilities
-+  describe ".setup" do
-+    subject { Guard.setup(options) }
-+
-+    let(:options) { { my_opts: true, guardfile: guardfile } }
-+
-+    let(:listener) { instance_double("Listen::Listener") }
-+
-+    before do
-+      allow(Listen).to receive(:to).with(Dir.pwd, {}) { listener }
-+
-+      stub_guardfile(" ")
-+      stub_user_guard_rb
-+
-+      g1 = instance_double("Guard::Group", name: :common, options: {})
-+      g2 = instance_double("Guard::Group", name: :default, options: {})
-+      allow(Guard::Group).to receive(:new).with(:common).and_return(g1)
-+      allow(Guard::Group).to receive(:new).with(:default).and_return(g2)
-+
-+      allow(evaluator).to receive(:inline?).and_return(false)
-+      allow(evaluator).to receive(:custom?).and_return(false)
-+      allow(evaluator).to receive(:evaluate)
-+      allow(Guard::Guardfile::Evaluator).to receive(:new).and_return(evaluator)
-+
-+      allow(Guard::Notifier).to receive(:connect)
-+
-+      allow(Guard::UI).to receive(:reset_and_clear)
-+      allow(plugins).to receive(:all).and_return([])
-+
-+      allow(session).to receive(:listener_args).and_return([:to, Dir.pwd, {}])
-+      allow(session).to receive(:evaluator_options).and_return({})
-+      allow(session).to receive(:cmdline_groups).and_return({})
-+      allow(session).to receive(:cmdline_plugins).and_return({})
-+      allow(session).to receive(:notify_options).and_return(notify: true)
-+      allow(session).to receive(:interactor_name).and_return(:foo)
-+      allow(session).to receive(:guardfile_ignore).and_return([])
-+      allow(session).to receive(:guardfile_ignore_bang).and_return([])
-+
-+      allow(listener).to receive(:ignore)
-+      allow(listener).to receive(:ignore!)
-+
-+      allow(Guard::Internals::State).to receive(:new).and_return(state)
-+    end
-+
-+    it "returns itself for chaining" do
-+      expect(subject).to be Guard
-+    end
-+
-+    it "initializes the listener" do
-+      allow(Listen).to receive(:to).
-+        with("/foo", latency: 2, wait_for_delay: 1).and_return(listener)
-+
-+      allow(session).to receive(:listener_args).and_return(
-+        [:to, "/foo", { latency: 2, wait_for_delay: 1 }]
-+      )
-+      subject
-+    end
-+
-+    it "initializes the interactor" do
-+      expect(Guard::Interactor).to receive(:new).with(false)
-+      subject
-+    end
-+
-+    context "trapping signals" do
-+      before do
-+        allow(traps).to receive(:handle)
-+      end
-+
-+      it "sets up USR1 trap for pausing" do
-+        expect(traps).to receive(:handle).with("USR1") { |_, &b| b.call }
-+        expect(Guard).to receive(:async_queue_add).
-+          with([:guard_pause, :paused])
-+        subject
-+      end
-+
-+      it "sets up USR2 trap for unpausing" do
-+        expect(traps).to receive(:handle).with("USR2") { |_, &b| b.call }
-+        expect(Guard).to receive(:async_queue_add).
-+          with([:guard_pause, :unpaused])
-+        subject
-+      end
-+
-+      it "sets up INT trap for cancelling or quitting interactor" do
-+        expect(traps).to receive(:handle).with("INT") { |_, &b| b.call }
-+        expect(interactor).to receive(:handle_interrupt)
-+        subject
-+      end
-+    end
-+
-+    it "evaluates the Guardfile" do
-+      expect(evaluator).to receive(:evaluate)
-+      allow(Guard::Guardfile::Evaluator).to receive(:new).and_return(evaluator)
-+
-+      subject
-+    end
-+
-+    describe "listener" do
-+      subject { listener }
-+
-+      context "with ignores 'ignore(/foo/)' and 'ignore!(/bar/)'" do
-+        before do
-+          allow(evaluator).to receive(:evaluate) do
-+            allow(session).to receive(:guardfile_ignore).and_return([/foo/])
-+            allow(session).to receive(:guardfile_ignore_bang).
-+              and_return([/bar/])
-+          end
-+          Guard.setup(options)
-+        end
-+
-+        it { is_expected.to have_received(:ignore).with([/foo/]) }
-+        it { is_expected.to have_received(:ignore!).with([/bar/]) }
-+      end
-+
-+      context "without ignores" do
-+        before { Guard.setup(options) }
-+        it { is_expected.to_not have_received(:ignore) }
-+        it { is_expected.to_not have_received(:ignore!) }
-+      end
-+    end
-+
-+    it "displays an error message when no guard are defined in Guardfile" do
-+      expect(Guard::UI).to receive(:error).
-+        with("No plugins found in Guardfile, please add at least one.")
-+
-+      subject
-+    end
-+
-+    it "connects to the notifier" do
-+      expect(Guard::Notifier).to receive(:connect).with(notify: true)
-+      subject
-+    end
-+
-+    context "with the group option" do
-+      let(:options) { { group: %w(frontend backend) } }
-+      it "passes options to session" do
-+        expect(Guard::Internals::State).to receive(:new).with(options)
-+        subject
-+      end
-+    end
-+
-+    context "with the plugin option" do
-+      let(:options) { { plugin: %w(cucumber jasmine) } }
-+      it "passes options to session" do
-+        expect(Guard::Internals::State).to receive(:new).with(options)
-+        subject
-+      end
-+    end
-+
-+    describe ".interactor" do
-+      subject { Guard::Interactor }
-+
-+      before do
-+        expect(session).to receive(:interactor_name).and_return(type)
-+        Guard.setup(options)
-+      end
-+
-+      context "with interactions enabled" do
-+        let(:type) { :pry_wrapper }
-+        let(:options) { { no_interactions: false } }
-+        it { is_expected.to have_received(:new).with(false) }
-+      end
-+
-+      context "with interactions disabled" do
-+        let(:type) { :sleep }
-+        let(:options) { { no_interactions: true } }
-+        it { is_expected.to have_received(:new).with(true) }
-+      end
-+    end
-+
-+    describe "UI" do
-+      subject { Guard::UI }
-+
-+      context "when clearing is configured" do
-+        before { Guard.setup(options) }
-+        it { is_expected.to have_received(:reset_and_clear) }
-+      end
-+    end
-+  end
-+
-+  describe "._relative_pathname" do
-+    subject { Guard.send(:_relative_pathname, raw_path) }
-+
-+    let(:pwd) { Pathname("/project") }
-+
-+    before { allow(Pathname).to receive(:pwd).and_return(pwd) }
-+
-+    context "with file in project directory" do
-+      let(:raw_path) { "/project/foo" }
-+      it { is_expected.to eq(Pathname("foo")) }
-+    end
-+
-+    context "with file within project" do
-+      let(:raw_path) { "/project/spec/models/foo_spec.rb" }
-+      it { is_expected.to eq(Pathname("spec/models/foo_spec.rb")) }
-+    end
-+
-+    context "with file in parent directory" do
-+      let(:raw_path) { "/foo" }
-+      it { is_expected.to eq(Pathname("../foo")) }
-+    end
-+
-+    context "with file on another drive (e.g. Windows)" do
-+      let(:raw_path) { "d:/project/foo" }
-+      let(:pathname) { instance_double(Pathname) }
-+
-+      before do
-+        allow_any_instance_of(Pathname).to receive(:relative_path_from).
-+          with(pwd).and_raise(ArgumentError)
-+      end
-+
-+      it { is_expected.to eq(Pathname.new("d:/project/foo")) }
-+    end
-+  end
-+
-+  describe "#relevant_changes?" do
-+    pending
-+  end
-+end
-Index: ruby-guard/spec/spec_helper.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/spec_helper.rb
-@@ -0,0 +1,290 @@
-+# This file was generated by the `rspec --init` command. Conventionally, all
-+# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
-+# The generated `.rspec` file contains `--require spec_helper` which will cause
-+# this file to always be loaded, without a need to explicitly require it in any
-+# files.
-+#
-+# Given that it is always loaded, you are encouraged to keep this file as
-+# light-weight as possible. Requiring heavyweight dependencies from this file
-+# will add to the boot time of your test suite on EVERY test run, even for an
-+# individual file that may not need all of that loaded. Instead, consider making
-+# a separate helper file that requires the additional dependencies and performs
-+# the additional setup, and require it from the spec files that actually need
-+# it.
-+#
-+# The `.rspec` file also contains a few flags that are not defaults but that
-+# users commonly want.
-+#
-+
-+require "fileutils"
-+
-+require "simplecov"
-+SimpleCov.start
-+
-+ENV["GUARD_SPECS_RUNNING"] = "1"
-+
-+path = "#{File.expand_path('..', __FILE__)}/support/**/*.rb"
-+Dir[path].each { |f| require f }
-+
-+# TODO: these shouldn't be necessary with proper specs
-+
-+def stub_guardfile(contents = nil, &block)
-+  stub_file(File.expand_path("Guardfile"), contents, &block)
-+end
-+
-+def stub_user_guardfile(contents = nil, &block)
-+  stub_file(File.expand_path("~/.Guardfile"), contents, &block)
-+end
-+
-+def stub_user_guard_rb(contents = nil, &block)
-+  stub_file(File.expand_path("~/.guard.rb"), contents, &block)
-+end
-+
-+def stub_user_project_guardfile(contents = nil, &block)
-+  stub_file(File.expand_path(".Guardfile"), contents, &block)
-+end
-+
-+def stub_mod(mod, excluded)
-+  mod.constants.each do |klass_name|
-+    klass = mod.const_get(klass_name)
-+    if klass.is_a?(Class)
-+      unless klass == described_class
-+        unless excluded.include?(klass)
-+          inst = instance_double(klass)
-+          allow(klass).to receive(:new).and_return(inst)
-+          # TODO: use object_double?
-+          class_double(klass.to_s).
-+            as_stubbed_const(transfer_nested_constants: true)
-+        end
-+      end
-+    elsif klass.is_a?(Module)
-+      stub_mod(klass, excluded)
-+    end
-+  end
-+end
-+
-+def stub_file(path, contents = nil, &block)
-+  exists = !contents.nil?
-+  allow(File).to receive(:exist?).with(path).and_return(exists)
-+  if exists
-+    if block.nil?
-+      allow(IO).to receive(:read).with(path).and_return(contents)
-+    else
-+      allow(IO).to receive(:read).with(path) do
-+        yield
-+      end
-+    end
-+  else
-+    allow(IO).to receive(:read).with(path) do
-+      fail Errno::ENOENT
-+    end
-+  end
-+end
-+
-+# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
-+RSpec.configure do |config|
-+  # rspec-expectations config goes here. You can use an alternate
-+  # assertion/expectation library such as wrong or the stdlib/minitest
-+  # assertions if you prefer.
-+  config.expect_with :rspec do |expectations|
-+    # This option will default to `true` in RSpec 4. It makes the `description`
-+    # and `failure_message` of custom matchers include text for helper methods
-+    # defined using `chain`, e.g.:
-+    # be_bigger_than(2).and_smaller_than(4).description
-+    #   # => "be bigger than 2 and smaller than 4"
-+    # ...rather than:
-+    #   # => "be bigger than 2"
-+    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
-+  end
-+
-+  # rspec-mocks config goes here. You can use an alternate test double
-+  # library (such as bogus or mocha) by changing the `mock_with` option here.
-+  config.mock_with :rspec do |mocks|
-+    # Prevents you from mocking or stubbing a method that does not exist on
-+    # a real object. This is generally recommended, and will default to
-+    # `true` in RSpec 4.
-+    mocks.verify_partial_doubles = true
-+  end
-+
-+  # The settings below are suggested to provide a good initial experience
-+  # with RSpec, but feel free to customize to your heart's content.
-+
-+  # These two settings work together to allow you to limit a spec run
-+  # to individual examples or groups you care about by tagging them with
-+  # `:focus` metadata. When nothing is tagged with `:focus`, all examples
-+  # get run.
-+  # config.filter_run :focus
-+  config.filter_run focus: ENV["CI"] != "true"
-+
-+  config.run_all_when_everything_filtered = true
-+
-+  # Limits the available syntax to the non-monkey patched syntax that is
-+  # recommended.
-+  #
-+  # For more details, see:
-+  #   - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
-+  #   - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
-+  #   - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
-+  config.disable_monkey_patching!
-+
-+  # This setting enables warnings. It's recommended, but in some cases may
-+  # be too noisy due to issues in dependencies.
-+  # config.warnings = true
-+
-+  # Many RSpec users commonly either run the entire suite or an individual
-+  # file, and it's useful to allow more verbose output when running an
-+  # individual spec file.
-+  if config.files_to_run.one?
-+    # Use the documentation formatter for detailed output,
-+    # unless a formatter has already been configured
-+    # (e.g. via a command-line flag).
-+    #
-+    # This is set in .rspec file
-+    # config.default_formatter = "doc"
-+  end
-+
-+  # Print the 10 slowest examples and example groups at the
-+  # end of the spec run, to help surface which specs are running
-+  # particularly slow.
-+  # config.profile_examples = 10
-+
-+  # Run specs in random order to surface order dependencies. If you find an
-+  # order dependency and want to debug it, you can fix the order by providing
-+  # the seed, which is printed after each run.
-+  #     --seed 1234
-+  config.order = :random
-+
-+  # Seed global randomization in this process using the `--seed` CLI option.
-+  # Setting this allows you to use `--seed` to deterministically reproduce
-+  # test failures related to randomization by passing the same `--seed` value
-+  # as the one that triggered the failure.
-+  Kernel.srand config.seed
-+
-+  config.raise_errors_for_deprecations!
-+
-+  config.mock_with :rspec do |mocks|
-+    mocks.verify_doubled_constant_names = true
-+    mocks.verify_partial_doubles = true
-+  end
-+
-+  config.before(:each) do |example|
-+    stub_const("FileUtils", class_double(FileUtils))
-+
-+    excluded = []
-+    excluded += Array(example.metadata[:exclude_stubs])
-+    excluded << Guard::Config if Guard.constants.include?(:Config)
-+    excluded << Guard::Options if Guard.constants.include?(:Options)
-+    excluded << Guard::Jobs::Base if Guard.constants.include?(:Jobs)
-+
-+    excluded << Guard::DuMmy if Guard.constants.include?(:DuMmy)
-+
-+    if Guard.constants.include?(:Notifier)
-+      if Guard::Notifier.constants.include?(:NotServer)
-+        excluded << Guard::Notifier::NotServer
-+      end
-+      if Guard::Notifier.constants.include?(:FooBar)
-+        excluded << Guard::Notifier::FooBar
-+      end
-+      if Guard::Notifier.constants.include?(:Base)
-+        excluded << Guard::Notifier::Base
-+      end
-+    end
-+
-+    modules = [Guard]
-+    modules << Listen if Object.const_defined?(:Listen)
-+    modules << Shellany if Object.const_defined?(:Shellany)
-+    modules << Notiffany if Object.const_defined?(:Notiffany)
-+    modules.each do |mod|
-+      stub_mod(mod, excluded)
-+    end
-+
-+    allow(ENV).to receive(:[]=) do |*args|
-+      abort "stub me: ENV[#{args.first}]= #{args.map(&:inspect)[1..-1] * ','}!"
-+    end
-+
-+    allow(ENV).to receive(:[]) do |*args|
-+      abort "stub me: ENV[#{args.first}]!"
-+    end
-+
-+    allow(ENV).to receive(:key?) do |*args|
-+      fail "stub me: ENV.key?(#{args.first})!"
-+    end
-+
-+    # NOTE: call original, so we can run tests depending on this variable
-+    allow(ENV).to receive(:[]).with("GUARD_STRICT").and_call_original
-+
-+    # FIXME: instead, properly stub PluginUtil in the evaluator specs!
-+    # and remove this!
-+    allow(ENV).to receive(:[]).with("SPEC_OPTS").and_call_original
-+
-+    # FIXME: properly stub out Pry instead of this!
-+    allow(ENV).to receive(:[]).with("ANSICON").and_call_original
-+    allow(ENV).to receive(:[]).with("TERM").and_call_original
-+
-+    # Needed for debugging
-+    allow(ENV).to receive(:[]).with("DISABLE_PRY").and_call_original
-+    allow(ENV).to receive(:[]).with("PRYRC").and_call_original
-+    allow(ENV).to receive(:[]).with("PAGER").and_call_original
-+
-+    # Workarounds for Cli inheriting from Thor
-+    allow(ENV).to receive(:[]).with("ANSICON").and_call_original
-+    allow(ENV).to receive(:[]).with("THOR_SHELL").and_call_original
-+    allow(ENV).to receive(:[]).with("GEM_SKIP").and_call_original
-+
-+    %w(read write exist?).each do |meth|
-+      allow(File).to receive(meth.to_sym).with(anything) do |*args, &_block|
-+        abort "stub me! (File.#{meth}(#{args.map(&:inspect).join(', ')}))"
-+      end
-+    end
-+
-+    %w(read write binwrite binread).each do |meth|
-+      allow(IO).to receive(meth.to_sym).with(anything) do |*args, &_block|
-+        abort "stub me! (IO.#{meth}(#{args.map(&:inspect).join(', ')}))"
-+      end
-+    end
-+
-+    %w(exist?).each do |meth|
-+      allow_any_instance_of(Pathname).
-+        to receive(meth.to_sym) do |*args, &_block|
-+        obj = args.first
-+        formatted_args = args[1..-1].map(&:inspect).join(", ")
-+        abort "stub me! (#{obj.inspect}##{meth}(#{formatted_args}))"
-+      end
-+    end
-+
-+    allow(Dir).to receive(:exist?).with(anything) do |*args, &_block|
-+      abort "stub me! (Dir#exist?(#{args.map(&:inspect) * ', '}))"
-+    end
-+
-+    if Guard.const_defined?("UI") && Guard::UI.respond_to?(:info)
-+      # Stub all UI methods, so no visible output appears for the UI class
-+      allow(Guard::UI).to receive(:info)
-+      allow(Guard::UI).to receive(:warning)
-+      allow(Guard::UI).to receive(:error)
-+      allow(Guard::UI).to receive(:debug)
-+      allow(Guard::UI).to receive(:deprecation)
-+    end
-+
-+    allow(Kernel).to receive(:system) do |*args|
-+      fail "stub for Kernel.system() called with: #{args.inspect}"
-+    end
-+
-+    # TODO: use metadata to stub out all used classes
-+    if Guard.const_defined?("Sheller")
-+      unless example.metadata[:sheller_specs]
-+        allow(Guard::Sheller).to receive(:run) do |*args|
-+          fail "stub for Sheller.run() called with: #{args.inspect}"
-+        end
-+      end
-+    end
-+  end
-+
-+  config.after(:each) do
-+    # Reset everything
-+    (Guard.constants + [Guard]).each do |klass|
-+      klass.instance_variables.each do |var|
-+        klass.instance_variable_set(var, nil)
-+      end
-+    end
-+  end
-+end
-Index: ruby-guard/spec/support/gems_helper.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/support/gems_helper.rb
-@@ -0,0 +1,20 @@
-+def growl_installed?
-+  require "growl"
-+  true
-+rescue LoadError
-+  false
-+end
-+
-+def libnotify_installed?
-+  require "libnotify"
-+  true
-+rescue LoadError
-+  false
-+end
-+
-+def rbnotifu_installed?
-+  require "rb-notifu"
-+  true
-+rescue LoadError
-+  false
-+end
-Index: ruby-guard/spec/support/platform_helper.rb
-===================================================================
---- /dev/null
-+++ ruby-guard/spec/support/platform_helper.rb
-@@ -0,0 +1,11 @@
-+def mac?
-+  RbConfig::CONFIG["target_os"] =~ /darwin/i
-+end
-+
-+def linux?
-+  RbConfig::CONFIG["target_os"] =~ /linux/i
-+end
-+
-+def windows?
-+  RbConfig::CONFIG["target_os"] =~ /mswin|mingw/i
-+end
diff --git a/debian/patches/series b/debian/patches/series
index ac1efd7..9095db0 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,3 @@
 do_not_use_gem_bin_path.patch
-add_specs.patch
 disable_simplecov.patch
 pending_examples.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-guard.git



More information about the Pkg-ruby-extras-commits mailing list