rspec-collection-matchers-1.1.2/0000755000175000017500000000000012565056022015575 5ustar jonasjonasrspec-collection-matchers-1.1.2/README.md0000644000175000017500000000357412565056022017065 0ustar jonasjonas# RSpec::CollectionMatchers [![Build Status](https://secure.travis-ci.org/rspec/rspec-collection_matchers.png?branch=master)](http://travis-ci.org/rspec/rspec-collection_matchers) RSpec::CollectionMatchers lets you express expected outcomes on collections of an object in an example. expect(account.shopping_cart).to have_exactly(3).items ## Install Add this line to your application's Gemfile: gem 'rspec-collection_matchers' And then execute: $ bundle Or install it yourself as: $ gem install rspec-collection_matchers ## Basic usage First of all, you need to require rspec-collection matchers. Add the following line to your `spec_helper.rb`: ```ruby require 'rspec/collection_matchers' ``` Using `rspec-collection_matchers` you can match the number of items in a collection directly, e.g.: ```ruby it 'matches number of items in a collection' do expect([1,2,3]).to have_at_least(3).items end ``` You can also match the number of items returned by a method on an object, e.g.: ```ruby class Cart def initialize(*products) @products = products end attr_reader :products end it 'matches number of items returned from a method' do cart = Cart.new('product a', 'product b') expect(cart).to have_at_most(2).products end ``` The last line of the example expresses an expected outcome: if `cart.products.size <= 2` then the example passes, otherwise it fails with a message like: expected at most 2 products, got 3 ## Available matchers ```ruby expect(collection).to have(n).items expect(collection).to have_exactly(n).items expect(collection).to have_at_most(n).items expect(collection).to have_at_least(n).items ``` ## See also * [http://github.com/rspec/rspec](http://github.com/rspec/rspec) * [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core) * [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations) rspec-collection-matchers-1.1.2/spec/0000755000175000017500000000000012565056022016527 5ustar jonasjonasrspec-collection-matchers-1.1.2/spec/rspec/0000755000175000017500000000000012565056022017643 5ustar jonasjonasrspec-collection-matchers-1.1.2/spec/rspec/collection_matchers/0000755000175000017500000000000012565056022023664 5ustar jonasjonasrspec-collection-matchers-1.1.2/spec/rspec/collection_matchers/rails_extensions_spec.rb0000644000175000017500000000523112565056022030615 0ustar jonasjonasrequire "spec_helper" require 'active_model' module RSpec::CollectionMatchers describe "Have extensions for rails" do describe "error_on" do it "provides a description including the name of what the error is on" do expect(have(1).error_on(:whatever).description).to eq "have 1 error on :whatever" end it "provides a failure message including the number actually given" do expect { expect([]).to have(1).error_on(:whatever) }.to raise_error("expected 1 error on :whatever, got 0") end end describe "errors_on" do it "provides a description including the name of what the error is on" do expect(have(2).errors_on(:whatever).description).to eq "have 2 errors on :whatever" end it "provides a failure message including the number actually given" do expect { expect([1]).to have(3).errors_on(:whatever) }.to raise_error("expected 3 errors on :whatever, got 1") end let(:klass) do Class.new do include ActiveModel::Validations end end it "calls valid?" do model = klass.new expect(model).to receive(:valid?) model.errors_on(:foo) end it "returns the errors on that attribute" do model = klass.new allow(model).to receive(:errors) do { :foo => ['a', 'b'] } end expect(model.errors_on(:foo)).to eq(['a','b']) end context "ActiveModel class that takes no arguments to valid?" do let(:klass) { Class.new do include ActiveModel::Validations def self.name "ActiveModelValidationsFake" end def valid? super end attr_accessor :name validates_presence_of :name end } context "with nil name" do it "has one error" do object = klass.new object.name = "" expect(object).to have(1).error_on(:name) end end context "with non-blank name" do it "has no error" do object = klass.new object.name = "Ywen" expect(object).to have(:no).error_on(:name) end end end end describe "have something other than error_on or errors_on" do it "has a standard rspec failure message" do expect { expect([1,2,3]).to have(2).elements }.to raise_error("expected 2 elements, got 3") end it "has a standard rspec description" do expect(have(2).elements.description).to eq "have 2 elements" end end end end rspec-collection-matchers-1.1.2/spec/rspec/collection_matchers/have_spec.rb0000644000175000017500000005441212565056022026154 0ustar jonasjonasrequire 'spec_helper' require 'stringio' describe "have matcher" do let(:inflector) do Class.new do def self.pluralize(string) string.to_s + 's' end end end before(:each) { stub_const("ActiveSupport::Inflector", inflector) } def create_collection_owner_with(n) owner = RSpec::Expectations::Helper::CollectionOwner.new (1..n).each do |number| owner.add_to_collection_with_length_method(number) owner.add_to_collection_with_size_method(number) owner.add_to_collection_with_count_method(number) end owner end describe "expect(...).to have(n).items" do it_behaves_like "an RSpec matcher", :valid_value => [1, 2], :invalid_value => [1] do let(:matcher) { have(2).items } end it "passes if target has a collection of items with n members" do owner = create_collection_owner_with(3) expect(owner).to have(3).items_in_collection_with_length_method expect(owner).to have(3).items_in_collection_with_size_method expect(owner).to have(3).items_in_collection_with_count_method end it "converts :no to 0" do owner = create_collection_owner_with(0) expect(owner).to have(:no).items_in_collection_with_length_method expect(owner).to have(:no).items_in_collection_with_size_method expect(owner).to have(:no).items_in_collection_with_count_method end it "converts a String argument to Integer" do owner = create_collection_owner_with(3) expect(owner).to have('3').items_in_collection_with_length_method expect(owner).to have('3').items_in_collection_with_size_method expect(owner).to have('3').items_in_collection_with_count_method end it "fails if target has a collection of items with < n members" do owner = create_collection_owner_with(3) expect { expect(owner).to have(4).items_in_collection_with_length_method }.to fail_with("expected 4 items_in_collection_with_length_method, got 3") expect { expect(owner).to have(4).items_in_collection_with_size_method }.to fail_with("expected 4 items_in_collection_with_size_method, got 3") expect { expect(owner).to have(4).items_in_collection_with_count_method }.to fail_with("expected 4 items_in_collection_with_count_method, got 3") end it "fails if target has a collection of items with > n members" do owner = create_collection_owner_with(3) expect { expect(owner).to have(2).items_in_collection_with_length_method }.to fail_with("expected 2 items_in_collection_with_length_method, got 3") expect { expect(owner).to have(2).items_in_collection_with_size_method }.to fail_with("expected 2 items_in_collection_with_size_method, got 3") expect { expect(owner).to have(2).items_in_collection_with_count_method }.to fail_with("expected 2 items_in_collection_with_count_method, got 3") end end describe 'expect(...).to have(1).item when ActiveSupport::Inflector is defined' do it 'pluralizes the collection name' do owner = create_collection_owner_with(1) expect(owner).to have(1).item end context "when ActiveSupport::Inflector is partially loaded without its inflectors" do it "does not pluralize the collection name" do stub_const("ActiveSupport::Inflector", Module.new) owner = create_collection_owner_with(1) expect { expect(owner).to have(1).item }.to raise_error(NoMethodError) end end end describe 'expect(...).to have(1).item when Inflector is defined' do before { stub_const("Inflector", inflector) } it 'pluralizes the collection name' do owner = create_collection_owner_with(1) expect(owner).to have(1).item end end describe "expect(...).to have(n).items where result responds to items but returns something other than a collection" do it "provides a meaningful error" do owner = Class.new do def items 1 end end.new expect do expect(owner).to have(3).items end.to raise_error("expected items to be a collection but it does not respond to #length, #size or #count") end it "provides a meaningful error" do owner = Class.new do def items Object.new end end.new expect do expect(owner).to have(3).items end.to raise_error("expected items to be a collection but it does not respond to #length, #size or #count") end end describe "expect(...).not_to have(n).items" do it "passes if target has a collection of items with < n members" do owner = create_collection_owner_with(3) expect(owner).not_to have(4).items_in_collection_with_length_method expect(owner).not_to have(4).items_in_collection_with_size_method expect(owner).not_to have(4).items_in_collection_with_count_method end it "passes if target has a collection of items with > n members" do owner = create_collection_owner_with(3) expect(owner).not_to have(2).items_in_collection_with_length_method expect(owner).not_to have(2).items_in_collection_with_size_method expect(owner).not_to have(2).items_in_collection_with_count_method end it "fails if target has a collection of items with n members" do owner = create_collection_owner_with(3) expect { expect(owner).not_to have(3).items_in_collection_with_length_method }.to fail_with("expected target not to have 3 items_in_collection_with_length_method, got 3") expect { expect(owner).not_to have(3).items_in_collection_with_size_method }.to fail_with("expected target not to have 3 items_in_collection_with_size_method, got 3") expect { expect(owner).not_to have(3).items_in_collection_with_count_method }.to fail_with("expected target not to have 3 items_in_collection_with_count_method, got 3") end end describe "expect(...).to have_exactly(n).items" do it "passes if target has a collection of items with n members" do owner = create_collection_owner_with(3) expect(owner).to have_exactly(3).items_in_collection_with_length_method expect(owner).to have_exactly(3).items_in_collection_with_size_method expect(owner).to have_exactly(3).items_in_collection_with_count_method end it "converts :no to 0" do owner = create_collection_owner_with(0) expect(owner).to have_exactly(:no).items_in_collection_with_length_method expect(owner).to have_exactly(:no).items_in_collection_with_size_method expect(owner).to have_exactly(:no).items_in_collection_with_count_method end it "fails if target has a collection of items with < n members" do owner = create_collection_owner_with(3) expect { expect(owner).to have_exactly(4).items_in_collection_with_length_method }.to fail_with("expected 4 items_in_collection_with_length_method, got 3") expect { expect(owner).to have_exactly(4).items_in_collection_with_size_method }.to fail_with("expected 4 items_in_collection_with_size_method, got 3") expect { expect(owner).to have_exactly(4).items_in_collection_with_count_method }.to fail_with("expected 4 items_in_collection_with_count_method, got 3") end it "fails if target has a collection of items with > n members" do owner = create_collection_owner_with(3) expect { expect(owner).to have_exactly(2).items_in_collection_with_length_method }.to fail_with("expected 2 items_in_collection_with_length_method, got 3") expect { expect(owner).to have_exactly(2).items_in_collection_with_size_method }.to fail_with("expected 2 items_in_collection_with_size_method, got 3") expect { expect(owner).to have_exactly(2).items_in_collection_with_count_method }.to fail_with("expected 2 items_in_collection_with_count_method, got 3") end end describe "expect(...).to have_at_least(n).items" do it "passes if target has a collection of items with n members" do owner = create_collection_owner_with(3) expect(owner).to have_at_least(3).items_in_collection_with_length_method expect(owner).to have_at_least(3).items_in_collection_with_size_method expect(owner).to have_at_least(3).items_in_collection_with_count_method end it "passes if target has a collection of items with > n members" do owner = create_collection_owner_with(3) expect(owner).to have_at_least(2).items_in_collection_with_length_method expect(owner).to have_at_least(2).items_in_collection_with_size_method expect(owner).to have_at_least(2).items_in_collection_with_count_method end it "fails if target has a collection of items with < n members" do owner = create_collection_owner_with(3) expect { expect(owner).to have_at_least(4).items_in_collection_with_length_method }.to fail_with("expected at least 4 items_in_collection_with_length_method, got 3") expect { expect(owner).to have_at_least(4).items_in_collection_with_size_method }.to fail_with("expected at least 4 items_in_collection_with_size_method, got 3") expect { expect(owner).to have_at_least(4).items_in_collection_with_count_method }.to fail_with("expected at least 4 items_in_collection_with_count_method, got 3") end it "provides educational negative failure messages" do #given owner = create_collection_owner_with(3) length_matcher = have_at_least(3).items_in_collection_with_length_method size_matcher = have_at_least(3).items_in_collection_with_size_method count_matcher = have_at_least(3).items_in_collection_with_count_method #when length_matcher.matches?(owner) size_matcher.matches?(owner) count_matcher.matches?(owner) #then expect(length_matcher.failure_message_for_should_not).to eq <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: expect(actual).not_to have_at_least(3).items_in_collection_with_length_method We recommend that you use this instead: expect(actual).to have_at_most(2).items_in_collection_with_length_method EOF expect(size_matcher.failure_message_for_should_not).to eq <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: expect(actual).not_to have_at_least(3).items_in_collection_with_size_method We recommend that you use this instead: expect(actual).to have_at_most(2).items_in_collection_with_size_method EOF expect(count_matcher.failure_message_for_should_not).to eq <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: expect(actual).not_to have_at_least(3).items_in_collection_with_count_method We recommend that you use this instead: expect(actual).to have_at_most(2).items_in_collection_with_count_method EOF end end describe "expect(...).to have_at_most(n).items" do it "passes if target has a collection of items with n members" do owner = create_collection_owner_with(3) expect(owner).to have_at_most(3).items_in_collection_with_length_method expect(owner).to have_at_most(3).items_in_collection_with_size_method expect(owner).to have_at_most(3).items_in_collection_with_count_method end it "fails if target has a collection of items with > n members" do owner = create_collection_owner_with(3) expect { expect(owner).to have_at_most(2).items_in_collection_with_length_method }.to fail_with("expected at most 2 items_in_collection_with_length_method, got 3") expect { expect(owner).to have_at_most(2).items_in_collection_with_size_method }.to fail_with("expected at most 2 items_in_collection_with_size_method, got 3") expect { expect(owner).to have_at_most(2).items_in_collection_with_count_method }.to fail_with("expected at most 2 items_in_collection_with_count_method, got 3") end it "passes if target has a collection of items with < n members" do owner = create_collection_owner_with(3) expect(owner).to have_at_most(4).items_in_collection_with_length_method expect(owner).to have_at_most(4).items_in_collection_with_size_method expect(owner).to have_at_most(4).items_in_collection_with_count_method end it "provides educational negative failure messages" do #given owner = create_collection_owner_with(3) length_matcher = have_at_most(3).items_in_collection_with_length_method size_matcher = have_at_most(3).items_in_collection_with_size_method count_matcher = have_at_most(3).items_in_collection_with_count_method #when length_matcher.matches?(owner) size_matcher.matches?(owner) count_matcher.matches?(owner) #then expect(length_matcher.failure_message_for_should_not).to eq <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: expect(actual).not_to have_at_most(3).items_in_collection_with_length_method We recommend that you use this instead: expect(actual).to have_at_least(4).items_in_collection_with_length_method EOF expect(size_matcher.failure_message_for_should_not).to eq <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: expect(actual).not_to have_at_most(3).items_in_collection_with_size_method We recommend that you use this instead: expect(actual).to have_at_least(4).items_in_collection_with_size_method EOF expect(count_matcher.failure_message_for_should_not).to eq <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: expect(actual).not_to have_at_most(3).items_in_collection_with_count_method We recommend that you use this instead: expect(actual).to have_at_least(4).items_in_collection_with_count_method EOF end end describe "have(n).items(args, block)" do it "passes args to target" do target = double("target") expect(target).to receive(:items).with("arg1","arg2").and_return([1,2,3]) expect(target).to have(3).items("arg1","arg2") end it "passes block to target" do target = double("target") block = Proc.new { 5 } expect(target).to receive(:items).with("arg1","arg2", block).and_return([1,2,3]) expect(target).to have(3).items("arg1","arg2", block) end end describe "have(n).items where target IS a collection" do it "references the number of items IN the collection" do expect([1,2,3]).to have(3).items end it "fails when the number of items IN the collection is not as expected" do expect { expect([1,2,3]).to have(7).items }.to fail_with("expected 7 items, got 3") end end describe "have(n).characters where target IS a String" do it "passes if the length is correct" do expect("this string").to have(11).characters end it "fails if the length is incorrect" do expect { expect("this string").to have(12).characters }.to fail_with("expected 12 characters, got 11") end end describe "have(n).things on an object which is not a collection nor contains one" do it "fails" do expect { expect(Object.new).to have(2).things }.to raise_error(NoMethodError) { |e| expect(e.name).to eq :things } end end describe "expectations compounded with RSpec::Matchers::Composable", :if => defined?(RSpec::Matchers::Composable) do context "using #and" do it "fails with relevant error when only first expectation fails" do expect { expect([1, 2, 3]).to be_falsey.and have(3).items }.to fail_matching "expected: falsey value" end it "fails with relevant error when only second expectation fails" do expect { expect([1, 2, 3]).to have(3).items.and be_falsey }.to fail_matching "expected: falsey value" end it "fails with relevant error when both expectations fail" do expect { expect([1, 2, 3]).to be_falsey.and have(0).items }.to fail_matching "...and:" end it "passes when both expectations are met" do expect([1, 2, 3]).to have(3).items.and be_truthy end end context "using #or" do it "fails with relevant error when neither expectation is met" do expect { expect([1, 2, 3]).to be_falsey.or have(0).items }.to fail_matching "...or:" end it "passes when only first expectation is met" do expect([1, 2, 3]).to have(3).items.or be_falsey end it "passes when only second expectation is met" do expect([1, 2, 3]).to be_falsey.or have(3).items end it "passes when both expectations are met" do expect([1, 2, 3]).to be_truthy.or have(3).items end end end describe RSpec::CollectionMatchers::Have, "for a collection owner that implements #send" do before(:each) do @collection = Object.new def @collection.floozles; [1,2] end def @collection.send; :sent; end end it "works in the straightforward case" do expect(@collection).to have(2).floozles end it "works when doing automatic pluralization" do expect(@collection).to have_at_least(1).floozle end it "blows up when the owner doesn't respond to that method" do expect { expect(@collection).to have(99).problems }.to raise_error(NoMethodError, /problems/) end it 'works when #send is defined directly on an array' do array = [1, 2] def array.send; :sent; end expect(array).to have(2).items end end if RUBY_VERSION >= '2.0' describe RSpec::CollectionMatchers::Have, "for an Enumerator whose size is nil but count is supplied" do let(:enumerator) { %w[a b c d].to_enum(:each) } it 'works fine' do expect(enumerator).to have(4).items end end end describe RSpec::CollectionMatchers::Have do it "has method_missing as private" do expect(described_class.private_instance_methods).to include_method(:method_missing) end it "does not respond_to? method_missing (because it's private)" do formatter = described_class.new(0, StringIO.new) expect(formatter).not_to respond_to(:method_missing) end describe "respond_to?" do before :each do @have = described_class.new(:foo) @a_method_which_have_defines = described_class.instance_methods.first @a_method_which_object_defines = Object.instance_methods.first end it "is true for a method which Have defines" do expect(@have).to respond_to(@a_method_which_have_defines) end it "is true for a method that it's superclass (Object) defines" do expect(@have).to respond_to(@a_method_which_object_defines) end it "is false for a method which neither Object nor nor Have defines" do expect(@have).not_to respond_to(:foo_bar_baz) end it "is false if the owner doesn't respond to the method" do have = described_class.new(99) expect(have).not_to respond_to(:problems) end it "is true if the owner responds to the method" do have = described_class.new(:a_symbol) expect(have).to respond_to(:to_sym) end end end context "description generation" do let(:team) do Class.new do def players [1,2,3] end end.new end describe "the have matcher" do it "generates its own description" do expect(team).to have(3).players expect(RSpec::Matchers.generated_description).to eq "should have 3 players" end end describe "the have_at_least matcher"do it "generates its own description" do expect(team).to have_at_least(2).players expect(RSpec::Matchers.generated_description).to eq "should have at least 2 players" end end describe "the have_at_most matcher" do it "generates its own description" do expect(team).to have_at_most(4).players expect(RSpec::Matchers.generated_description).to eq "should have at most 4 players" end end end end module RSpec module CollectionMatchers describe Syntax do describe "expression generation" do let(:target) { "foo" } let(:expectation) { "eq('bar')" } let(:positive_expect_example) { "expect(foo).to eq('bar')" } let(:positive_should_example) { "foo.should eq('bar')" } let(:negative_expect_example) { "expect(foo).not_to eq('bar')" } let(:negative_should_example) { "foo.should_not eq('bar')" } def positive_expression Syntax.positive_expression(target, expectation) end def negative_expression Syntax.negative_expression(target, expectation) end context "when only :expect is enabled", :uses_only_expect do before do expect(Expectations::Syntax.should_enabled?).to be_falsey expect(Expectations::Syntax.expect_enabled?).to be_truthy end it 'generates a positive expression using the expect syntax' do expect(positive_expression).to eq(positive_expect_example) end it 'generates a negative expression using the expect syntax' do expect(negative_expression).to eq(negative_expect_example) end end context "when both :should and :expect are enabled", :uses_should do before do expect(Expectations::Syntax.should_enabled?).to be_truthy expect(Expectations::Syntax.expect_enabled?).to be_truthy end it 'generates a positive expression using the expect syntax' do expect(positive_expression).to eq(positive_expect_example) end it 'generates a negative expression using the expect syntax' do expect(negative_expression).to eq(negative_expect_example) end end context "when only :should is enabled", :uses_only_should do before do Expectations::Syntax.should_enabled?.should be_truthy Expectations::Syntax.expect_enabled?.should be_falsey end it 'generates a positive expression using the expect syntax' do positive_expression.should eq(positive_should_example) end it 'generates a negative expression using the expect syntax' do negative_expression.should eq(negative_should_example) end end end end end end rspec-collection-matchers-1.1.2/spec/support/0000755000175000017500000000000012565056022020243 5ustar jonasjonasrspec-collection-matchers-1.1.2/spec/support/matchers.rb0000644000175000017500000000076712565056022022410 0ustar jonasjonasRSpec::Matchers.define :include_method do |expected| match do |actual| actual.map { |m| m.to_s }.include?(expected.to_s) end end module RSpec module Matchers def fail raise_error(RSpec::Expectations::ExpectationNotMetError) end def fail_with(message) raise_error(RSpec::Expectations::ExpectationNotMetError, message) end def fail_matching(message) raise_error(RSpec::Expectations::ExpectationNotMetError, /#{Regexp.escape(message)}/) end end end rspec-collection-matchers-1.1.2/spec/support/classes.rb0000644000175000017500000000313612565056022022230 0ustar jonasjonas# various classes used by the specs module RSpec module Expectations module Helper class CollectionWithSizeMethod def initialize; @list = []; end def size; @list.size; end def push(item); @list.push(item); end end class CollectionWithLengthMethod def initialize; @list = []; end def length; @list.size; end def push(item); @list.push(item); end end class CollectionWithCountMethod def initialize; @list = []; end def count; @list.count; end def push(item); @list.push(item); end end class CollectionOwner attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method, :items_in_collection_with_count_method def initialize @items_in_collection_with_size_method = CollectionWithSizeMethod.new @items_in_collection_with_length_method = CollectionWithLengthMethod.new @items_in_collection_with_count_method = CollectionWithCountMethod.new end def add_to_collection_with_size_method(item) @items_in_collection_with_size_method.push(item) end def add_to_collection_with_length_method(item) @items_in_collection_with_length_method.push(item) end def add_to_collection_with_count_method(item) @items_in_collection_with_count_method.push(item) end def items_for(arg) return [1, 2, 3] if arg == 'a' [1] end def items @items_in_collection_with_size_method end end end end end rspec-collection-matchers-1.1.2/spec/support/shared_examples.rb0000644000175000017500000000063412565056022023737 0ustar jonasjonasshared_examples_for "an RSpec matcher" do |options| let(:valid_value) { options.fetch(:valid_value) } let(:invalid_value) { options.fetch(:invalid_value) } it 'matches a valid value when using #== so it can be composed' do expect(matcher).to eq(valid_value) end it 'does not match an invalid value when using #== so it can be composed' do expect(matcher).not_to eq(invalid_value) end end rspec-collection-matchers-1.1.2/spec/spec_helper.rb0000644000175000017500000000324112565056022021345 0ustar jonasjonasrequire 'active_model' # to avoid deprecation warning: # [deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message. I18n.enforce_available_locales = false require 'rspec/collection_matchers' Dir['./spec/support/**/*'].each {|f| require f} RSpec.configure do |config| config.treat_symbols_as_metadata_keys_with_true_values = true if RSpec::Expectations::Version::STRING < "3.0" config.run_all_when_everything_filtered = true config.filter_run :focus config.order = 'random' config.expect_with :rspec do |rspec| rspec.syntax = :expect end config.mock_with :rspec do |rspec| rspec.syntax = :expect end end shared_context "with #should enabled", :uses_should do orig_syntax = nil before(:all) do orig_syntax = RSpec::Matchers.configuration.syntax RSpec::Matchers.configuration.syntax = [:expect, :should] end after(:all) do RSpec::Matchers.configuration.syntax = orig_syntax end end shared_context "with #should exclusively enabled", :uses_only_should do orig_syntax = nil before(:all) do orig_syntax = RSpec::Matchers.configuration.syntax RSpec::Matchers.configuration.syntax = :should end after(:all) do RSpec::Matchers.configuration.syntax = orig_syntax end end shared_context "with #expect exclusively enabled", :uses_only_expect do orig_syntax = nil before(:all) do orig_syntax = RSpec::Matchers.configuration.syntax RSpec::Matchers.configuration.syntax = :expect end after(:all) do RSpec::Matchers.configuration.syntax = orig_syntax end end rspec-collection-matchers-1.1.2/metadata.yml0000644000175000017500000000571112565056022020104 0ustar jonasjonas--- !ruby/object:Gem::Specification name: rspec-collection_matchers version: !ruby/object:Gem::Version version: 1.1.2 platform: ruby authors: - Hugo Baraúna autorequire: bindir: bin cert_chain: [] date: 2014-11-11 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: rspec-expectations requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.99.0.beta1 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.99.0.beta1 - !ruby/object:Gem::Dependency name: bundler requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.3' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.3' - !ruby/object:Gem::Dependency name: activemodel requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '3.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '3.0' description: Collection cardinality matchers, extracted from rspec-expectations email: - hugo.barauna@plataformatec.com.br executables: [] extensions: [] extra_rdoc_files: [] files: - ".gitignore" - ".rspec" - ".travis.yml" - Changelog.md - Gemfile - LICENSE.txt - README.md - Rakefile - features/have.feature - features/support/env.rb - lib/rspec/collection_matchers.rb - lib/rspec/collection_matchers/have.rb - lib/rspec/collection_matchers/matchers.rb - lib/rspec/collection_matchers/rails_extensions.rb - lib/rspec/collection_matchers/version.rb - rspec-collection_matchers.gemspec - script/test_all - spec/rspec/collection_matchers/have_spec.rb - spec/rspec/collection_matchers/rails_extensions_spec.rb - spec/spec_helper.rb - spec/support/classes.rb - spec/support/matchers.rb - spec/support/shared_examples.rb homepage: https://github.com/rspec/rspec-collection_matchers licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: rspec-collection_matchers-1.1.2 test_files: - features/have.feature - features/support/env.rb - spec/rspec/collection_matchers/have_spec.rb - spec/rspec/collection_matchers/rails_extensions_spec.rb - spec/spec_helper.rb - spec/support/classes.rb - spec/support/matchers.rb - spec/support/shared_examples.rb rspec-collection-matchers-1.1.2/.gitignore0000644000175000017500000000021612565056022017564 0ustar jonasjonas*.sw? .DS_Store coverage* rdoc pkg doc tmp rerun.txt Gemfile.lock .bundle *.rbc .yardoc bin .rbx Gemfile-custom bundle .rspec-local Guardfile rspec-collection-matchers-1.1.2/lib/0000755000175000017500000000000012565056022016343 5ustar jonasjonasrspec-collection-matchers-1.1.2/lib/rspec/0000755000175000017500000000000012565056022017457 5ustar jonasjonasrspec-collection-matchers-1.1.2/lib/rspec/collection_matchers/0000755000175000017500000000000012565056022023500 5ustar jonasjonasrspec-collection-matchers-1.1.2/lib/rspec/collection_matchers/matchers.rb0000644000175000017500000000357712565056022025647 0ustar jonasjonasrequire 'rspec/matchers' module RSpec module Matchers # Passes if receiver is a collection with the submitted number of items OR # if the receiver OWNS a collection with the submitted number of items. # # If the receiver OWNS the collection, you must use the name of the # collection. So if a `Team` instance has a collection named `#players`, # you must use that name to set the expectation. # # If the receiver IS the collection, you can use any name you like for # `named_collection`. We'd recommend using either "elements", "members", or # "items" as these are all standard ways of describing the things IN a # collection. # # This also works for Strings, letting you set expectations about their # lengths. # # @example # # # Passes if team.players.size == 11 # expect(team).to have(11).players # # # Passes if [1,2,3].length == 3 # expect([1,2,3]).to have(3).items #"items" is pure sugar # # # Passes if ['a', 'b', 'c'].count == 3 # expect([1,2,3]).to have(3).items #"items" is pure sugar # # # Passes if "this string".length == 11 # expect("this string").to have(11).characters #"characters" is pure sugar def have(n) RSpec::CollectionMatchers::Have.new(n) end alias :have_exactly :have # Exactly like have() with >=. # # @example # expect("this").to have_at_least(3).letters # # ### Warning: # # `expect(..).not_to have_at_least` is not supported def have_at_least(n) RSpec::CollectionMatchers::Have.new(n, :at_least) end # Exactly like have() with <=. # # @example # expect("this").to have_at_most(4).letters # # ### Warning: # # `expect(..).not_to have_at_most` is not supported def have_at_most(n) RSpec::CollectionMatchers::Have.new(n, :at_most) end end end rspec-collection-matchers-1.1.2/lib/rspec/collection_matchers/have.rb0000644000175000017500000001502612565056022024754 0ustar jonasjonasmodule RSpec module CollectionMatchers class Have include RSpec::Matchers::Composable unless RSpec::Expectations::Version::STRING.to_f < 3.0 QUERY_METHODS = [:size, :length, :count].freeze IGNORED_CLASSES = [Integer].freeze def initialize(expected, relativity=:exactly) @expected = case expected when :no then 0 when String then expected.to_i else expected end @relativity = relativity @actual = @collection_name = @plural_collection_name = nil end def relativities @relativities ||= { :exactly => "", :at_least => "at least ", :at_most => "at most " } end def matches?(collection_or_owner) collection = determine_collection(collection_or_owner) case collection when enumerator_class for query_method in QUERY_METHODS next unless collection.respond_to?(query_method) @actual = collection.__send__(query_method) break unless @actual.nil? end raise not_a_collection if @actual.nil? else query_method = determine_query_method(collection) raise not_a_collection if !query_method || is_ignored_class?(collection) @actual = collection.__send__(query_method) end case @relativity when :at_least then @actual >= @expected when :at_most then @actual <= @expected else @actual == @expected end end alias == matches? def determine_collection(collection_or_owner) if collection_or_owner.respond_to?(@collection_name) collection_or_owner.__send__(@collection_name, *@args, &@block) elsif (@plural_collection_name && collection_or_owner.respond_to?(@plural_collection_name)) collection_or_owner.__send__(@plural_collection_name, *@args, &@block) elsif determine_query_method(collection_or_owner) collection_or_owner else collection_or_owner.__send__(@collection_name, *@args, &@block) end end def determine_query_method(collection) QUERY_METHODS.detect {|m| collection.respond_to?(m)} end def is_ignored_class?(collection) IGNORED_CLASSES.any? {|klass| klass === collection} end def not_a_collection "expected #{@collection_name} to be a collection but it does not respond to #length, #size or #count" end def failure_message return errors_on_message(:expected, ", got #{@actual}") if is_errors_on? "expected #{relative_expectation} #{@collection_name}, got #{@actual}" end alias failure_message_for_should failure_message def failure_message_when_negated if @relativity == :exactly return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}" elsif @relativity == :at_most return <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: #{Syntax.negative_expression("actual", "have_at_most(#{@expected}).#{@collection_name}")} We recommend that you use this instead: #{Syntax.positive_expression("actual", "have_at_least(#{@expected + 1}).#{@collection_name}")} EOF elsif @relativity == :at_least return <<-EOF Isn't life confusing enough? Instead of having to figure out the meaning of this: #{Syntax.negative_expression("actual", "have_at_least(#{@expected}).#{@collection_name}")} We recommend that you use this instead: #{Syntax.positive_expression("actual", "have_at_most(#{@expected - 1}).#{@collection_name}")} EOF end end alias failure_message_for_should_not failure_message_when_negated def description return errors_on_message(:have) if is_errors_on? "have #{relative_expectation} #{@collection_name}" end def respond_to?(m) @expected.respond_to?(m) || super end private def method_missing(method, *args, &block) @collection_name = method if inflector = (defined?(ActiveSupport::Inflector) && ActiveSupport::Inflector.respond_to?(:pluralize) ? ActiveSupport::Inflector : (defined?(Inflector) ? Inflector : nil)) @plural_collection_name = inflector.pluralize(method.to_s) end @args = args @block = block self end def relative_expectation "#{relativities[@relativity]}#{@expected}" end def enumerator_class RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator end def is_errors_on? [:errors_on, :error_on].include? @collection_name end def errors_on_message(prefix, suffix = nil) "#{prefix} #{relative_expectation} #{@collection_name.to_s.gsub('_', ' ')} :#{@args[0]}#{suffix}" end end module Syntax # @api private # Generates a positive expectation expression. def self.positive_expression(target_expression, matcher_expression) expression_generator.positive_expression(target_expression, matcher_expression) end # @api private # Generates a negative expectation expression. def self.negative_expression(target_expression, matcher_expression) expression_generator.negative_expression(target_expression, matcher_expression) end # @api private # Selects which expression generator to use based on the configured syntax. def self.expression_generator if RSpec::Expectations::Syntax.expect_enabled? ExpectExpressionGenerator else ShouldExpressionGenerator end end # @api private # Generates expectation expressions for the `should` syntax. module ShouldExpressionGenerator def self.positive_expression(target_expression, matcher_expression) "#{target_expression}.should #{matcher_expression}" end def self.negative_expression(target_expression, matcher_expression) "#{target_expression}.should_not #{matcher_expression}" end end # @api private # Generates expectation expressions for the `expect` syntax. module ExpectExpressionGenerator def self.positive_expression(target_expression, matcher_expression) "expect(#{target_expression}).to #{matcher_expression}" end def self.negative_expression(target_expression, matcher_expression) "expect(#{target_expression}).not_to #{matcher_expression}" end end end end end rspec-collection-matchers-1.1.2/lib/rspec/collection_matchers/version.rb0000644000175000017500000000011112565056022025503 0ustar jonasjonasmodule RSpec module CollectionMatchers VERSION = "1.1.2" end end rspec-collection-matchers-1.1.2/lib/rspec/collection_matchers/rails_extensions.rb0000644000175000017500000000163112565056022027417 0ustar jonasjonasif defined?(::ActiveModel) module ::ActiveModel::Validations # Extension to enhance `to have` on AR Model instances. Calls # model.valid? in order to prepare the object's errors object. Accepts # a :context option to specify the validation context. # # You can also use this to specify the content of the error messages. # # @example # # expect(model).to have(:no).errors_on(:attribute) # expect(model).to have(1).error_on(:attribute) # expect(model).to have(n).errors_on(:attribute) # expect(model).to have(n).errors_on(:attribute, :context => :create) # # expect(model.errors_on(:attribute)).to include("can't be blank") def errors_on(attribute, options = {}) valid_args = [options[:context]].compact self.valid?(*valid_args) [self.errors[attribute]].flatten.compact end alias :error_on :errors_on end end rspec-collection-matchers-1.1.2/lib/rspec/collection_matchers.rb0000644000175000017500000000032312565056022024023 0ustar jonasjonasrequire 'rspec/expectations' require 'rspec/collection_matchers/version' require 'rspec/collection_matchers/matchers' require 'rspec/collection_matchers/have' require 'rspec/collection_matchers/rails_extensions'rspec-collection-matchers-1.1.2/LICENSE.txt0000644000175000017500000000232112565056022017416 0ustar jonasjonas(The MIT License) Copyright (c) 2013 Hugo Barauna Copyright (c) 2012 David Chelimsky, Myron Marston Copyright (c) 2006 David Chelimsky, The RSpec Development Team Copyright (c) 2005 Steven Baker MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rspec-collection-matchers-1.1.2/Gemfile0000644000175000017500000000237012565056022017072 0ustar jonasjonassource 'https://rubygems.org' gemspec %w[rspec rspec-core rspec-expectations rspec-mocks].each do |lib| library_path = File.expand_path("../../#{lib}", __FILE__) if File.exist?(library_path) gem lib, :path => library_path else gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => ENV.fetch('BRANCH',"master") end end # only the master branch is supported on rspec-support gem "rspec-support", :git => "git://github.com/rspec/rspec-support.git" gem "cucumber", "~> 1.1.9" gem "aruba", "~> 0.5" gem "rake", "~> 10.0.0" version_file = File.expand_path("../.rails-version", __FILE__) rails_gem_args = case version = ENV['RAILS_VERSION'] || (File.exist?(version_file) && File.read(version_file).chomp) when /master/ { :git => "git://github.com/rails/rails.git" } when /stable$/ { :git => "git://github.com/rails/rails.git", :branch => version } when nil, false, "" if RUBY_VERSION < '1.9.3' # Rails 4+ requires 1.9.3+, so on earlier versions default to the last 3.x release. "3.2.17" else "4.0.4" end else version end gem "activesupport", *rails_gem_args gem "activemodel", *rails_gem_args platform :rbx do gem 'rubysl' end eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom') rspec-collection-matchers-1.1.2/features/0000755000175000017500000000000012565056022017413 5ustar jonasjonasrspec-collection-matchers-1.1.2/features/have.feature0000644000175000017500000000746312565056022021725 0ustar jonasjonasFeature: have(n).items matcher RSpec provides several matchers that make it easy to set expectations about the size of a collection. There are three basic forms: ```ruby collection.should have(x).items collection.should have_at_least(x).items collection.should have_at_most(x).items ``` In addition, #have_exactly is provided as an alias to #have. These work on any collection-like object--the object just needs to respond to #size or #length (or both). When the matcher is called directly on a collection object, the #items call is pure syntactic sugar. You can use anything you want here. These are equivalent: ```ruby collection.should have(x).items collection.should have(x).things ``` You can also use this matcher on a non-collection object that returns a collection from one of its methods. For example, Dir#entries returns an array, so you could set an expectation using the following: ```ruby Dir.new("my/directory").should have(7).entries ``` Scenario: have(x).items on a collection Given a file named "have_items_spec.rb" with: """ruby require 'rspec/collection_matchers' describe [1, 2, 3] do it { should have(3).items } it { should_not have(2).items } it { should_not have(4).items } it { should have_exactly(3).items } it { should_not have_exactly(2).items } it { should_not have_exactly(4).items } it { should have_at_least(2).items } it { should have_at_most(4).items } # deliberate failures it { should_not have(3).items } it { should have(2).items } it { should have(4).items } it { should_not have_exactly(3).items } it { should have_exactly(2).items } it { should have_exactly(4).items } it { should have_at_least(4).items } it { should have_at_most(2).items } end """ When I run `rspec have_items_spec.rb` Then the output should contain "16 examples, 8 failures" And the output should contain "expected target not to have 3 items, got 3" And the output should contain "expected 2 items, got 3" And the output should contain "expected 4 items, got 3" And the output should contain "expected at least 4 items, got 3" And the output should contain "expected at most 2 items, got 3" Scenario: have(x).words on a String when String#words is defined Given a file named "have_words_spec.rb" with: """ruby require 'rspec/collection_matchers' class String def words split(' ') end end describe "a sentence with some words" do it { should have(5).words } it { should_not have(4).words } it { should_not have(6).words } it { should have_exactly(5).words } it { should_not have_exactly(4).words } it { should_not have_exactly(6).words } it { should have_at_least(4).words } it { should have_at_most(6).words } # deliberate failures it { should_not have(5).words } it { should have(4).words } it { should have(6).words } it { should_not have_exactly(5).words } it { should have_exactly(4).words } it { should have_exactly(6).words } it { should have_at_least(6).words } it { should have_at_most(4).words } end """ When I run `rspec have_words_spec.rb` Then the output should contain "16 examples, 8 failures" And the output should contain "expected target not to have 5 words, got 5" And the output should contain "expected 4 words, got 5" And the output should contain "expected 6 words, got 5" And the output should contain "expected at least 6 words, got 5" And the output should contain "expected at most 4 words, got 5" rspec-collection-matchers-1.1.2/features/support/0000755000175000017500000000000012565056022021127 5ustar jonasjonasrspec-collection-matchers-1.1.2/features/support/env.rb0000644000175000017500000000104512565056022022244 0ustar jonasjonasrequire 'aruba/cucumber' Before do if RUBY_PLATFORM =~ /java/ @aruba_timeout_seconds = 30 else @aruba_timeout_seconds = 10 end end Aruba.configure do |config| config.before_cmd do |cmd| set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived end end if RUBY_PLATFORM == 'java' Aruba.configure do |config| config.before_cmd do |cmd| set_env('RBXOPT', "-Xint=true #{ENV['RBXOPT']}") # disable JIT since these processes are so short lived end end if defined?(Rubinius) rspec-collection-matchers-1.1.2/script/0000755000175000017500000000000012565056022017101 5ustar jonasjonasrspec-collection-matchers-1.1.2/script/test_all0000755000175000017500000000147512565056022020645 0ustar jonasjonas#!/bin/bash set -e -x # idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html export JRUBY_OPTS='-X-C' # disable JIT since these processes are so short lived # force jRuby to use client mode JVM or a compilation mode thats as close as possible, # idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1' echo "Running rspec specs" bin/rspec spec --format progress --profile echo "Running cucumber specs" # TODO: it would be nice to figure out how to run the cukes w/o the overhead of # bundler, but just running `bin/cucumber` can fail due to the fact that it # shells out (via aruba) and executes `rspec`--which can pick up the wrong # rspec version if we're not running with bundler. bundle exec cucumber rspec-collection-matchers-1.1.2/Changelog.md0000644000175000017500000000243512565056022020012 0ustar jonasjonas### Development ### 1.1.2 / 2014-11-11 [full changelog](http://github.com/rspec/rspec-collection_matchers/compare/v1.1.1...v1.1.2) Bug Fixes: * Fix bug of uninitialized constant RSpec::Expectations (Related to #20) ### 1.1.1 / 2014-11-10 [full changelog](http://github.com/rspec/rspec-collection_matchers/compare/v1.1.0...v1.1.1) Bug Fixes: * Remove virtual dependency on rspec-core (Thanks @jscheid for reporting that, #20) ### 1.1.0 / 2014-11-10 [full changelog](http://github.com/rspec/rspec-collection_matchers/compare/v1.0.0...v1.1.0) Enhancements: * Make matchers composable on RSpec 3 and above. (Johnson Denen, #19) ### 1.0.0 / 2014-06-09 [full changelog](http://github.com/rspec/rspec-collection_matchers/compare/v0.0.4...v1.0.0) ### 0.0.4 / 2014-04-24 [full changelog](http://github.com/rspec/rspec-collection_matchers/compare/v0.0.3...v0.0.4) Enhancements: * Add Rails extension `have(n).errors_on(:whatever)` (Bradley Schaefer) ### 0.0.3 / 2014-02-16 [full changelog](http://github.com/rspec/rspec-collection_matchers/compare/v0.0.2...v0.0.3) Enhancements: * Update to latest RSpec 3 matcher API. (Myron Marston) Bug Fixes: * Raise an error when you attempt to use matcher against an `Integer` which previously would have incorrectly used a `#size` of 8. (Kassio Borges) rspec-collection-matchers-1.1.2/rspec-collection_matchers.gemspec0000644000175000017500000000211712565056022024276 0ustar jonasjonas# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'rspec/collection_matchers/version' Gem::Specification.new do |spec| spec.name = "rspec-collection_matchers" spec.version = RSpec::CollectionMatchers::VERSION spec.authors = ["Hugo Baraúna"] spec.email = ["hugo.barauna@plataformatec.com.br"] spec.summary = "rspec-collection_matchers-#{RSpec::CollectionMatchers::VERSION}" spec.description = "Collection cardinality matchers, extracted from rspec-expectations" spec.homepage = "https://github.com/rspec/rspec-collection_matchers" spec.license = "MIT" spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(spec|features)/}) spec.require_paths = ["lib"] spec.add_runtime_dependency "rspec-expectations", ">= 2.99.0.beta1" spec.add_development_dependency "bundler", "~> 1.3" spec.add_development_dependency "activemodel", ">= 3.0" end rspec-collection-matchers-1.1.2/.rspec0000644000175000017500000000003712565056022016712 0ustar jonasjonas--format documentation --color rspec-collection-matchers-1.1.2/.travis.yml0000644000175000017500000000040512565056022017705 0ustar jonasjonaslanguage: ruby script: "script/test_all" bundler_args: "--standalone --binstubs --without documentation" rvm: - 2.1.0 - 2.0.0 - 1.9.3 - 1.9.2 - 1.8.7 - ree - jruby-19mode - jruby-18mode - rbx env: - BRANCH=master - BRANCH=2-99-maintenance rspec-collection-matchers-1.1.2/Rakefile0000644000175000017500000000052112565056022017240 0ustar jonasjonasrequire "bundler" Bundler.setup Bundler::GemHelper.install_tasks require "rake" require "rspec/core/rake_task" require "rspec/core/version" require "cucumber/rake/task" Cucumber::Rake::Task.new(:cucumber) desc "Run all examples" RSpec::Core::RakeTask.new(:spec) do |t| t.ruby_opts = %w[-w] end task :default => [:spec, :cucumber]