From d854184744a70d1786e65a3a4bbd6429988b7f00 Mon Sep 17 00:00:00 2001 From: Gabe Berke-Williams and Josh Clayton Date: Fri, 16 Sep 2011 17:25:00 -0400 Subject: [PATCH] Refactor Kumade::Packager This moves the logic of each of the packagers into their own classes, introduces a PackagerList class that maintains all the various packagers, and improves tests around the packager. --- features/kumade_executable.feature | 9 +- features/kumade_without_jammit.feature | 4 +- kumade.gemspec | 1 + lib/kumade.rb | 5 + lib/kumade/deployer.rb | 2 +- lib/kumade/packager.rb | 92 ++--- lib/kumade/packager_list.rb | 29 ++ lib/kumade/packagers/jammit_packager.rb | 20 + lib/kumade/packagers/more_packager.rb | 20 + lib/kumade/packagers/noop_packager.rb | 14 + lib/kumade/rake_task_runner.rb | 30 ++ spec/kumade/deployer_spec.rb | 17 +- spec/kumade/packager_list_spec.rb | 31 ++ spec/kumade/packager_spec.rb | 347 ++++-------------- spec/kumade/packagers/jammit_packager_spec.rb | 27 ++ spec/kumade/packagers/more_packager_spec.rb | 37 ++ spec/kumade/packagers/noop_packager_spec.rb | 9 + spec/kumade/rake_task_runner_spec.rb | 77 ++++ spec/spec_helper.rb | 2 +- spec/support/define_constant.rb | 41 +++ spec/support/shared_examples/packager.rb | 6 + 21 files changed, 465 insertions(+), 355 deletions(-) create mode 100644 lib/kumade/packager_list.rb create mode 100644 lib/kumade/packagers/jammit_packager.rb create mode 100644 lib/kumade/packagers/more_packager.rb create mode 100644 lib/kumade/packagers/noop_packager.rb create mode 100644 lib/kumade/rake_task_runner.rb create mode 100644 spec/kumade/packager_list_spec.rb create mode 100644 spec/kumade/packagers/jammit_packager_spec.rb create mode 100644 spec/kumade/packagers/more_packager_spec.rb create mode 100644 spec/kumade/packagers/noop_packager_spec.rb create mode 100644 spec/kumade/rake_task_runner_spec.rb create mode 100644 spec/support/define_constant.rb create mode 100644 spec/support/shared_examples/packager.rb diff --git a/features/kumade_executable.feature b/features/kumade_executable.feature index e73072c..40d45fc 100644 --- a/features/kumade_executable.feature +++ b/features/kumade_executable.feature @@ -21,7 +21,7 @@ Feature: Kumade executable And the output should contain: """ ==> Git repo is clean - ==> Packaged assets with Jammit + ==> Packaged with Kumade::JammitPackager run git push origin master ==> Pushed master -> origin run git branch deploy @@ -31,7 +31,7 @@ Feature: Kumade executable run git checkout master && git branch -D deploy ==> Deployed to: pretend-staging """ - But the output should not contain "==> Packaged assets with More" + But the output should not contain "==> Packaged with Kumade::MorePackager" Scenario: Default environment is staging When I run kumade with "-p" @@ -52,7 +52,7 @@ Feature: Kumade executable Then the output should contain: """ ==> Git repo is clean - ==> Packaged assets with Jammit + ==> Packaged with Kumade::JammitPackager run git push origin new_branch ==> Pushed new_branch -> origin run git branch deploy @@ -95,4 +95,5 @@ Feature: Kumade executable end """ When I run kumade with "pretend-staging -p" - Then the output should match /kumade:before_asset_compilation.*Packaged assets with Jammit/ + Then the output should contain "kumade:before_asset_compilation" + And the output should contain "==> Packaged with Kumade::JammitPackager" diff --git a/features/kumade_without_jammit.feature b/features/kumade_without_jammit.feature index de11b08..3d5b6e8 100644 --- a/features/kumade_without_jammit.feature +++ b/features/kumade_without_jammit.feature @@ -23,7 +23,7 @@ Feature: Kumade without jammit end """ When I run kumade with "pretend-staging" - Then the output should contain "Running kumade:before_asset_compilation task" + Then the output should contain "Running rake task: kumade:before_asset_compilation" And the output should contain "Hi!" Scenario: Don't run rake task in pretend mode @@ -36,5 +36,5 @@ Feature: Kumade without jammit end """ When I run kumade with "pretend-staging -p" - Then the output should contain "Running kumade:before_asset_compilation task" + Then the output should contain "Running rake task: kumade:before_asset_compilation" And the output should not contain "Hi!" diff --git a/kumade.gemspec b/kumade.gemspec index 886c143..35239e4 100644 --- a/kumade.gemspec +++ b/kumade.gemspec @@ -26,5 +26,6 @@ Gem::Specification.new do |s| s.add_development_dependency('cucumber', '~> 1.0.2') s.add_development_dependency('aruba', '~> 0.4.3') s.add_development_dependency('jammit', '~> 0.6.3') + s.add_development_dependency('less', '~> 2.0') s.add_development_dependency('bourne') end diff --git a/lib/kumade.rb b/lib/kumade.rb index 7314bc9..21eda2c 100644 --- a/lib/kumade.rb +++ b/lib/kumade.rb @@ -8,6 +8,11 @@ module Kumade autoload :Configuration, "kumade/configuration" autoload :Heroku, "kumade/heroku" autoload :Packager, "kumade/packager" + autoload :MorePackager, "kumade/packagers/more_packager" + autoload :JammitPackager, "kumade/packagers/jammit_packager" + autoload :NoopPackager, "kumade/packagers/noop_packager" + autoload :PackagerList, "kumade/packager_list" + autoload :RakeTaskRunner, "kumade/rake_task_runner" def self.configuration @@configuration ||= Configuration.new diff --git a/lib/kumade/deployer.rb b/lib/kumade/deployer.rb index 2a231cc..867f650 100644 --- a/lib/kumade/deployer.rb +++ b/lib/kumade/deployer.rb @@ -32,7 +32,7 @@ def pre_deploy end def package_assets - packager.run + @packager.run end def sync_github diff --git a/lib/kumade/packager.rb b/lib/kumade/packager.rb index 8a7438c..755da41 100644 --- a/lib/kumade/packager.rb +++ b/lib/kumade/packager.rb @@ -1,94 +1,46 @@ module Kumade class Packager < Base - attr_reader :git - - def initialize(git) + def initialize(git, packager = Packager.available_packager) super() - @git = git + @packager = packager + @git = git end def run - invoke_custom_task if custom_task? - package_with_jammit if jammit_installed? - package_with_more if more_installed? + precompile_assets + package end - def invoke_custom_task - success "Running kumade:before_asset_compilation task" - Rake::Task["kumade:before_asset_compilation"].invoke unless Kumade.configuration.pretending? + def self.available_packager + Kumade::PackagerList.new.first end - def custom_task? - load("Rakefile") if File.exist?("Rakefile") - Rake::Task.task_defined?("kumade:before_asset_compilation") - end + private - def package_with_jammit - begin - success_message = "Packaged assets with Jammit" + def precompile_assets + RakeTaskRunner.new("kumade:before_asset_compilation", self).invoke + end - if Kumade.configuration.pretending? - success(success_message) - else - Jammit.package! + def package + return success(success_message) if Kumade.configuration.pretending? + begin + @packager.package + if @git.dirty? + git_add_and_commit_all_assets_in(@packager.assets_path) success(success_message) - git_add_and_commit_all_assets_in(jammit_assets_path) end - rescue => jammit_error - error("Error: #{jammit_error.class}: #{jammit_error.message}") + rescue => packager_exception + error("Error: #{packager_exception.class}: #{packager_exception.message}") end end - def package_with_more - success_message = "Packaged assets with More" - if Kumade.configuration.pretending? - success(success_message) - else - begin - run "bundle exec rake more:generate" - if git.dirty? - success(success_message) - git_add_and_commit_all_assets_in(more_assets_path) - end - rescue => more_error - error("Error: #{more_error.class}: #{more_error.message}") - end - end + def success_message + "Packaged with #{@packager.name}" end def git_add_and_commit_all_assets_in(dir) - git.add_and_commit_all_in(dir, Kumade::Heroku::DEPLOY_BRANCH, 'Compiled assets', "Added and committed all assets", "couldn't commit assets") - end - - def jammit_assets_path - File.join(Jammit::PUBLIC_ROOT, Jammit.package_path) - end - - def more_assets_path - File.join('public', ::Less::More.destination_path) - end - - def jammit_installed? - @jammit_installed ||= - (defined?(Jammit) || - begin - require 'jammit' - true - rescue LoadError - false - end) - end - - def more_installed? - @more_installed ||= - (defined?(Less::More) || - begin - require 'less/more' - true - rescue LoadError - false - end) + @git.add_and_commit_all_in(dir, Kumade::Heroku::DEPLOY_BRANCH, 'Compiled assets', "Added and committed all assets", "couldn't commit assets") end end end diff --git a/lib/kumade/packager_list.rb b/lib/kumade/packager_list.rb new file mode 100644 index 0000000..cb1bdad --- /dev/null +++ b/lib/kumade/packager_list.rb @@ -0,0 +1,29 @@ +module Kumade + class PackagerList + include Enumerable + + PACKAGERS = [MorePackager, JammitPackager] + + def initialize + @packagers = build_packagers_list + end + + def each(&block) + @packagers.each(&block) + end + + private + + def build_packagers_list + if installed_packagers.any? + installed_packagers + else + [NoopPackager] + end + end + + def installed_packagers + PACKAGERS.select(&:installed?) + end + end +end diff --git a/lib/kumade/packagers/jammit_packager.rb b/lib/kumade/packagers/jammit_packager.rb new file mode 100644 index 0000000..57c7225 --- /dev/null +++ b/lib/kumade/packagers/jammit_packager.rb @@ -0,0 +1,20 @@ +begin + require "jammit" +rescue LoadError +end + +module Kumade + class JammitPackager + def self.assets_path + File.join(Jammit::PUBLIC_ROOT, Jammit.package_path) + end + + def self.installed? + !!defined?(Jammit) + end + + def self.package + Jammit.package! + end + end +end diff --git a/lib/kumade/packagers/more_packager.rb b/lib/kumade/packagers/more_packager.rb new file mode 100644 index 0000000..7bf7740 --- /dev/null +++ b/lib/kumade/packagers/more_packager.rb @@ -0,0 +1,20 @@ +begin + require "less/more" +rescue LoadError +end + +module Kumade + class MorePackager + def self.assets_path + File.join("public", ::Less::More.destination_path) + end + + def self.installed? + !!defined?(Less::More) + end + + def self.package + ::Less::More.generate_all + end + end +end diff --git a/lib/kumade/packagers/noop_packager.rb b/lib/kumade/packagers/noop_packager.rb new file mode 100644 index 0000000..071bb0c --- /dev/null +++ b/lib/kumade/packagers/noop_packager.rb @@ -0,0 +1,14 @@ +module Kumade + class NoopPackager + def self.assets_path + "" + end + + def self.package + end + + def self.installed? + false + end + end +end diff --git a/lib/kumade/rake_task_runner.rb b/lib/kumade/rake_task_runner.rb new file mode 100644 index 0000000..64f6199 --- /dev/null +++ b/lib/kumade/rake_task_runner.rb @@ -0,0 +1,30 @@ +module Kumade + class RakeTaskRunner + def initialize(task_name, runner) + @task_name = task_name + @runner = runner + end + + def invoke + return unless task_defined? + + @runner.success("Running rake task: #{@task_name}") + Rake::Task[@task_name].invoke if task_should_be_run? + end + + private + + def task_defined? + load_rakefile + Rake::Task.task_defined?(@task_name) + end + + def task_should_be_run? + !Kumade.configuration.pretending? + end + + def load_rakefile + load("Rakefile") if File.exist?("Rakefile") + end + end +end diff --git a/spec/kumade/deployer_spec.rb b/spec/kumade/deployer_spec.rb index aca5570..e7695d6 100644 --- a/spec/kumade/deployer_spec.rb +++ b/spec/kumade/deployer_spec.rb @@ -1,7 +1,5 @@ require 'spec_helper' -require 'jammit' - describe Kumade::Deployer, "#pre_deploy" do let(:git) { subject.git } @@ -114,3 +112,18 @@ end end end + +describe Kumade::Deployer, "packaging" do + let(:git) { stub("git", :current_branch => "awesome", :delete => true) } + let(:packager) { stub("packager", :run => true) } + + before do + Kumade::Git.stubs(:new => git) + Kumade::Packager.stubs(:new => packager) + end + + it "builds the correct packager" do + subject.deploy + Kumade::Packager.should have_received(:new).with(git) + end +end diff --git a/spec/kumade/packager_list_spec.rb b/spec/kumade/packager_list_spec.rb new file mode 100644 index 0000000..25605e6 --- /dev/null +++ b/spec/kumade/packager_list_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Kumade::PackagerList, "detecting packages" do + it "returns an array containing the Jammit packager if Jammit is installed" do + Kumade::JammitPackager.stubs(:installed? => true) + Kumade::MorePackager.stubs(:installed? => false) + + Kumade::PackagerList.new.to_a.should == [Kumade::JammitPackager] + end + + it "returns an array containing the More packager if More is installed" do + Kumade::JammitPackager.stubs(:installed? => false) + Kumade::MorePackager.stubs(:installed? => true) + + Kumade::PackagerList.new.to_a.should == [Kumade::MorePackager] + end + + it "returns multiple packagers if they are installed" do + Kumade::JammitPackager.stubs(:installed? => true) + Kumade::MorePackager.stubs(:installed? => true) + + Kumade::PackagerList.new.to_a.should =~ [Kumade::JammitPackager, Kumade::MorePackager] + end + + it "returns an array containing the no-op packager if no other packagers are found" do + Kumade::JammitPackager.stubs(:installed? => false) + Kumade::MorePackager.stubs(:installed? => false) + + Kumade::PackagerList.new.to_a.should == [Kumade::NoopPackager] + end +end diff --git a/spec/kumade/packager_spec.rb b/spec/kumade/packager_spec.rb index b3e35d2..8d0808d 100644 --- a/spec/kumade/packager_spec.rb +++ b/spec/kumade/packager_spec.rb @@ -1,318 +1,115 @@ require 'spec_helper' -require 'jammit' +describe Kumade::Packager, ".available_packager" do + let(:packager_1) { "1st packager" } + let(:packager_2) { "2nd packager" } -shared_context "with a fake Git" do - let(:git) { stub() } - subject { Kumade::Packager.new(git) } -end - -describe Kumade::Packager, "#run" do - include_context "with a fake Git" - - before do - subject.stubs(:package_with_jammit) - end - - context "with Jammit installed" do - it "calls package_with_jammit" do - subject.run - - subject.should have_received(:package_with_jammit) - end - end - - context "with Jammit not installed" do - before { subject.stubs(:jammit_installed? => false) } - - it "does not call package_with_jammit" do - subject.run - - subject.should_not have_received(:package_with_jammit) - end - end - - context "with More installed" do - before do - subject.stubs(:jammit_installed? => false) - subject.stubs(:more_installed? => true) - subject.stubs(:package_with_more) - end - - it "calls package_with_more" do - subject.run - - subject.should have_received(:package_with_more) - end - end - - context "with More not installed" do - before do - subject.stubs(:jammit_installed? => false) - subject.stubs(:more_installed? => false) - end - - it "does not call package_with_more" do - subject.run - - subject.should_not have_received(:package_with_more) - end - end - - context "with custom rake task installed" do - before do - subject.stubs(:jammit_installed? => false, - :more_installed? => false, - :invoke_custom_task => nil, - :custom_task? => true) - end - - it "invokes custom task" do - subject.run - - subject.should have_received(:invoke_custom_task) - end + it "returns the first available packager" do + Kumade::PackagerList.stubs(:new => [packager_1, packager_2]) + Kumade::Packager.available_packager.should == packager_1 end - context "with custom rake task not installed" do - before do - subject.stubs(:jammit_installed? => false, - :more_installed? => false, - :invoke_custom_task => nil, - :custom_task? => false) - end - - it "does not invoke custom task" do - subject.run - - subject.should_not have_received(:invoke_custom_task) - end + it "returns nil if no packagers are availabke" do + Kumade::PackagerList.stubs(:new => []) + Kumade::Packager.available_packager.should be_nil end end -describe Kumade::Packager, "#invoke_custom_task" do - include_context "with a fake Git" - - let(:task) { stub('kumade:before_asset_compilation task', :invoke => nil) } +describe Kumade::Packager, "#run" do + let(:git) { stub("git", :dirty? => true, :add_and_commit_all_in => true) } + let(:packager) { stub("packager", :name => "MyPackager", :package => true, :assets_path => 'fake_assets_path') } + let(:rake_task_runner) { stub("RakeTaskRunner", :invoke => true) } before do - subject.stubs(:say) - Rake::Task.stubs(:[] => task) + Kumade::RakeTaskRunner.stubs(:new => rake_task_runner) + subject.stubs(:success => nil, :error => nil) end - it "calls deploy task" do - Rake::Task.expects(:[]).with("kumade:before_asset_compilation").returns(task) + subject { Kumade::Packager.new(git, packager) } - subject.invoke_custom_task - - task.should have_received(:invoke) + it "precompiles assets" do + subject.run + Kumade::RakeTaskRunner.should have_received(:new).with("kumade:before_asset_compilation", subject) + rake_task_runner.should have_received(:invoke) end -end -describe Kumade::Packager, "#custom_task?" do - include_context "with a fake Git" + context "when packaging with a packager" do + context "when pretending" do + before do + Kumade.configuration.pretending = true + end - before do - Rake::Task.clear - end + it "prints a success message" do + subject.run + subject.should have_received(:success).with("Packaged with MyPackager") + end - it "returns true if it task found" do - namespace :kumade do - task :before_asset_compilation do + it "does not package" do + subject.run + packager.should have_received(:package).never end end - subject.custom_task?.should be_true - end - - it "returns false if task not found" do - subject.custom_task?.should be_false - end -end - -describe Kumade::Packager, "#package_with_jammit" do - include_context "with a fake Git" - - before do - subject.stubs(:git_add_and_commit_all_assets_in) - subject.stubs(:success) - subject.stubs(:error) - Jammit.stubs(:package!) - end - - it "calls Jammit.package!" do - subject.package_with_jammit - - Jammit.should have_received(:package!).once - end - - context "with updated assets" do - before { subject.git.stubs(:dirty? => true) } - - it "prints the correct message" do - subject.package_with_jammit + context "when not pretending" do + before do + Kumade.configuration.pretending = false + end - subject.should have_received(:success).with("Packaged assets with Jammit") - end + it "prints a success message" do + subject.run + subject.should have_received(:success).with("Packaged with MyPackager") + end - it "calls git_add_and_commit_all_assets_in" do - subject.stubs(:jammit_assets_path => 'jammit-assets') - subject.expects(:git_add_and_commit_all_assets_in). - with('jammit-assets'). - returns(true) + it "packages" do + subject.run + packager.should have_received(:package).once + end - subject.package_with_jammit + it "prints an error if an exception is raised" do + packager.stubs(:package).raises(RuntimeError.new("my specific error")) + subject.run + subject.should have_received(:error).with("Error: RuntimeError: my specific error") + end end end - it "prints an error if packaging failed" do - Jammit.expects(:package!).raises(Jammit::MissingConfiguration.new("random Jammit error")) - - subject.package_with_jammit - - subject.should have_received(:error).with("Error: Jammit::MissingConfiguration: random Jammit error") - end -end - -describe Kumade::Packager, "#package_with_more" do - include_context "with a fake Git" - - before do - subject.stubs(:git_add_and_commit_all_assets_in => true, - :more_assets_path => 'assets') - subject.stubs(:say) - end - - it "calls the more:generate task" do - git.expects(:dirty?).returns(true) - subject.expects(:run).with("bundle exec rake more:generate") - subject.package_with_more - end - - context "with changed assets" do + context "when packaging and the repository becomes dirty" do before do + Kumade.configuration.pretending = false git.stubs(:dirty? => true) end - it "prints a success message" do - subject.stubs(:run).with("bundle exec rake more:generate") - subject.expects(:success).with("Packaged assets with More") - - subject.package_with_more - end - - it "calls git_add_and_commit_all_assets_in if assets were added" do - subject.stubs(:more_assets_path => 'blerg') - subject.stubs(:run).with("bundle exec rake more:generate") - subject.expects(:git_add_and_commit_all_assets_in). - with('blerg'). - returns(true) - - subject.package_with_more - end - end - - context "with no changed assets" do - it "prints no message" do - subject.stubs(:run).with("bundle exec rake more:generate") - subject.stubs(:git => mock(:dirty? => false)) - subject.expects(:say).never - - subject.package_with_more - end - - it "does not call git_add_and_commit_all_more_assets" do - subject.stubs(:run).with("bundle exec rake more:generate") - subject.stubs(:git => mock(:dirty? => false)) - subject.expects(:git_add_and_commit_all_assets_in).never - - subject.package_with_more + it "performs a commit" do + subject.run + git.should have_received(:add_and_commit_all_in). + with(packager.assets_path, + Kumade::Heroku::DEPLOY_BRANCH, + 'Compiled assets', + "Added and committed all assets", + "couldn't commit assets") end - end - - it "prints an error if packaging failed" do - subject.stubs(:run).with("bundle exec rake more:generate").raises("blerg") - subject.expects(:error).with("Error: RuntimeError: blerg") - - subject.package_with_more - end -end - -describe Kumade::Packager, "#git_add_and_commit_all_assets_in" do - include_context "with a fake Git" - - it "should call git.add_and_commit_all_in" do - git.expects(:add_and_commit_all_in).with("dir", 'deploy', 'Compiled assets', "Added and committed all assets", "couldn't commit assets") - subject.git_add_and_commit_all_assets_in("dir") - end -end - -describe Kumade::Packager, "#jammit_assets_path" do - let(:git) { stub() } - let(:packager) { Kumade::Packager.new(git) } - - before do - Jammit.stubs(:package_path).returns('blerg') - end - - subject { packager.jammit_assets_path } - - it { should == File.join(Jammit::PUBLIC_ROOT, 'blerg') } -end - -describe Kumade::Packager, "#more_assets_path" do - include_context "with a fake Git" - - it "returns the correct asset path" do - module ::Less - class More - def self.destination_path - 'blerg' - end - end + it "prints the success message after committing" do + git.stubs(:add_and_commit_all_in).raises(RuntimeError.new("something broke")) + subject.run + subject.should have_received(:success).never end - subject.more_assets_path.should == 'public/blerg' end -end - -describe Kumade::Packager, "#jammit_installed?" do - include_context "with a fake Git" - - it "returns true because it's loaded by the Gemfile" do - subject.jammit_installed?.should be_true - end - - it "returns false if jammit is not installed" do - subject.jammit_installed?.should be_true - end -end - -describe Kumade::Packager, "#more_installed?" do - include_context "with a fake Git" - context "when More is not installed" do + context "when packaging and the repository is not dirty" do before do - if defined?(Less) - Object.send(:remove_const, :Less) - end - end - - it "returns false" do - subject.more_installed?.should be_false + Kumade.configuration.pretending = false + git.stubs(:dirty? => false) end - end - context "when More is installed" do - before do - module Less - class More - end - end + it "does not print a success message" do + subject.run + subject.should have_received(:success).never end - it "returns true" do - subject.more_installed?.should be_true + it "doesn't perform a commit" do + subject.run + git.should have_received(:add_and_commit_all_in).never end end end diff --git a/spec/kumade/packagers/jammit_packager_spec.rb b/spec/kumade/packagers/jammit_packager_spec.rb new file mode 100644 index 0000000..cb05343 --- /dev/null +++ b/spec/kumade/packagers/jammit_packager_spec.rb @@ -0,0 +1,27 @@ +require "spec_helper" + +require "jammit" + +describe Kumade::JammitPackager do + subject { Kumade::JammitPackager } + + it_should_behave_like "packager" + + its(:assets_path) { should == File.join(Jammit::PUBLIC_ROOT, Jammit.package_path) } + + it "knows how to package itself" do + ::Jammit.stubs(:package!) + subject.package + ::Jammit.should have_received(:package!).once + end + + context "when Jammit is defined" do + before { Jammit } + it { should be_installed } + end + + context "when Jammit is not defined" do + before { Object.send(:remove_const, :Jammit) } + it { should_not be_installed } + end +end diff --git a/spec/kumade/packagers/more_packager_spec.rb b/spec/kumade/packagers/more_packager_spec.rb new file mode 100644 index 0000000..6185dba --- /dev/null +++ b/spec/kumade/packagers/more_packager_spec.rb @@ -0,0 +1,37 @@ +require "spec_helper" + +require "less" + +describe Kumade::MorePackager do + subject { Kumade::MorePackager } + + before do + define_constant "Less::More" do + def self.destination_path + "awesome_destination" + end + end + end + + it_should_behave_like "packager" + + its(:assets_path) { should == File.join('public', ::Less::More.destination_path) } + + it "knows how to package itself" do + Less::More.stubs(:generate_all) + + subject.package + + Less::More.should have_received(:generate_all).once + end + + context "when More is defined" do + before { Less::More } + it { should be_installed } + end + + context "when Less::More is not defined" do + before { Less.send(:remove_const, :More) } + it { should_not be_installed } + end +end diff --git a/spec/kumade/packagers/noop_packager_spec.rb b/spec/kumade/packagers/noop_packager_spec.rb new file mode 100644 index 0000000..5224411 --- /dev/null +++ b/spec/kumade/packagers/noop_packager_spec.rb @@ -0,0 +1,9 @@ +require "spec_helper" + +describe Kumade::NoopPackager do + subject { Kumade::NoopPackager } + + it_should_behave_like "packager" + + its(:assets_path) { should == "" } +end diff --git a/spec/kumade/rake_task_runner_spec.rb b/spec/kumade/rake_task_runner_spec.rb new file mode 100644 index 0000000..6f39e1e --- /dev/null +++ b/spec/kumade/rake_task_runner_spec.rb @@ -0,0 +1,77 @@ +require "spec_helper" + +describe Kumade::RakeTaskRunner do + let(:runner) { stub("runner", :success => true) } + + context "when the task doesn't exist" do + subject { Kumade::RakeTaskRunner.new("bogus:task", runner) } + + it "does not notify the user that the task was run successfully" do + subject.invoke + runner.should have_received(:success).never + end + end + + context "when Rakefile exists" do + subject { Kumade::RakeTaskRunner.new("bogus:task", runner) } + + before do + File.stubs(:exist?).with("Rakefile").returns(true) + end + + it "loads the Rakefile" do + subject.stubs(:load).with("Rakefile") + subject.invoke + subject.should have_received(:load).with("Rakefile") + end + end + + context "when the task exists" do + let(:task_name) { "kumade:test:custom_task_name" } + let(:invoked_task) { stub("invoked", :invoke! => false) } + + before do + Rake::Task.define_task task_name do + invoked_task.invoke! + end + end + + after do + Rake::Task[task_name].reenable + end + + subject { Kumade::RakeTaskRunner.new(task_name, runner) } + + context "when pretending" do + before do + Kumade.configuration.pretending = true + end + + it "notifies the user that the task was run successfully" do + subject.invoke + runner.should have_received(:success).with("Running rake task: #{task_name}") + end + + it "does not invoke the task" do + subject.invoke + invoked_task.should have_received(:invoke!).never + end + end + + context "when not pretending" do + before do + Kumade.configuration.pretending = false + end + + it "notifies the user that the task was run successfully" do + subject.invoke + runner.should have_received(:success).with("Running rake task: #{task_name}") + end + + it "invokes the task" do + subject.invoke + invoked_task.should have_received(:invoke!).once + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9c7ab65..4745c95 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -21,7 +21,7 @@ def remove_remote(remote_name) spec_dir = Pathname.new(File.expand_path(File.dirname(__FILE__))) -Dir[spec_dir.join('support', '**')].each {|f| require File.expand_path(f) } +Dir[spec_dir.join('support', '**', "*.rb")].each {|f| require File.expand_path(f) } RSpec.configure do |config| config.mock_with :mocha diff --git a/spec/support/define_constant.rb b/spec/support/define_constant.rb new file mode 100644 index 0000000..387374c --- /dev/null +++ b/spec/support/define_constant.rb @@ -0,0 +1,41 @@ +module DefineConstant + def define_constant(path, base = Object, &block) + namespace, class_name = *constant_path(path) + klass = Class.new(base) + namespace.const_set(class_name, klass) + klass.class_eval(&block) if block_given? + @defined_constants << path + klass + end + + def clear_generated_constants + @defined_constants.reverse.each do |path| + namespace, class_name = *constant_path(path) + if namespace.const_defined?(class_name) + namespace.send(:remove_const, class_name) + end + end + + @defined_constants.clear + end + + private + + def constant_path(constant_name) + names = constant_name.split('::') + class_name = names.pop + namespace = names.inject(Object) { |result, name| result.const_get(name) } + [namespace, class_name] + end +end + +RSpec.configure do |config| + config.include DefineConstant + config.before do + @defined_constants = [] + end + + config.after do + clear_generated_constants + end +end diff --git a/spec/support/shared_examples/packager.rb b/spec/support/shared_examples/packager.rb new file mode 100644 index 0000000..6963cda --- /dev/null +++ b/spec/support/shared_examples/packager.rb @@ -0,0 +1,6 @@ +share_examples_for "packager" do + its(:assets_path) { should_not be_nil } + + it { should respond_to(:installed?) } + it { should respond_to(:package) } +end