rspec-collection_matchers 0.0.1.pre → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1bd9e9e6cead5be254467961d97df52cfdae0316
4
+ data.tar.gz: e36762e51754850cbec1da1f81cc3d0237187dfa
5
+ SHA512:
6
+ metadata.gz: e32cdb9c067ada99bdf5357a7aab08fe0ab014db5c54821ea53da740ed5764aec7db13ae2bdace551855f7b0854945642240c1f6fbe77cbff6a1853956414187
7
+ data.tar.gz: 0a0934bac819f8a0b17031de14c0d56e43e77dd25ba77fc0b371f9d053560530d0b5f195115837a3a83151a58557b188aab5a1e4705caaed850d727b44d6cb22
data/.gitignore CHANGED
@@ -1,17 +1,18 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
1
+ *.sw?
2
+ .DS_Store
3
+ coverage*
13
4
  rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
5
+ pkg
6
+ doc
17
7
  tmp
8
+ rerun.txt
9
+ Gemfile.lock
10
+ .bundle
11
+ *.rbc
12
+ .yardoc
13
+ bin
14
+ .rbx
15
+ Gemfile-custom
16
+ bundle
17
+ .rspec-local
18
+ Guardfile
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ script: "script/test_all"
3
+ bundler_args: "--standalone --binstubs --without documentation"
4
+ rvm:
5
+ - 1.8.7
6
+ - 1.9.2
7
+ - 1.9.3
8
+ - ree
9
+ - jruby-18mode
10
+ - jruby-19mode
11
+ - rbx-18mode
12
+ - rbx-19mode
13
+ - 2.0.0
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: rbx-19mode
17
+ - rvm: rbx-18mode
data/Gemfile CHANGED
@@ -1,4 +1,18 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in rspec-collection_matchers.gemspec
4
3
  gemspec
4
+
5
+ %w[rspec rspec-core rspec-expectations rspec-mocks].each do |lib|
6
+ library_path = File.expand_path("../../#{lib}", __FILE__)
7
+ if File.exist?(library_path)
8
+ gem lib, :path => library_path
9
+ else
10
+ gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => "2-99-maintenance"
11
+ end
12
+ end
13
+
14
+ gem "cucumber", "~> 1.1.9"
15
+ gem "aruba", "~> 0.5"
16
+ gem "rake", "~> 10.0.0"
17
+
18
+ eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom')
data/LICENSE.txt CHANGED
@@ -1,4 +1,9 @@
1
- Copyright (c) 2013 Myron Marston
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2013 Hugo Barauna
4
+ Copyright (c) 2012 David Chelimsky, Myron Marston
5
+ Copyright (c) 2006 David Chelimsky, The RSpec Development Team
6
+ Copyright (c) 2005 Steven Baker
2
7
 
3
8
  MIT License
4
9
 
@@ -19,4 +24,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
24
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
25
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
26
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
- # Rspec::CollectionMatchers
1
+ # RSpec::CollectionMatchers [![Build Status](https://secure.travis-ci.org/rspec/rspec-collection_matchers.png?branch=master)](http://travis-ci.org/rspec/rspec-collection_matchers)
2
2
 
3
- TODO: Write a gem description
3
+ RSpec::CollectionMatchers lets you express expected outcomes on collections
4
+ of an object in an example.
4
5
 
5
- ## Installation
6
+ expect(account.shopping_cart).to have_exactly(3).items
7
+
8
+ ## Install
6
9
 
7
10
  Add this line to your application's Gemfile:
8
11
 
@@ -16,14 +19,49 @@ Or install it yourself as:
16
19
 
17
20
  $ gem install rspec-collection_matchers
18
21
 
19
- ## Usage
22
+ ## Basic usage
23
+
24
+ Using `rspec-collection_matchers` you can match the number of items in a
25
+ collection directly, e.g.:
26
+
27
+ ```ruby
28
+ it 'matches number of items in a collection' do
29
+ expect([1,2,3]).to have_at_least(3).items
30
+ end
31
+ ```
32
+
33
+ You can also match the number of items returned by a method on an object, e.g.:
34
+
35
+ ```ruby
36
+ class Cart
37
+ def initialize(*products)
38
+ @products = products
39
+ end
40
+ attr_reader :products
41
+ end
42
+
43
+ it 'matches number of items returned from a method' do
44
+ cart = Cart.new('product a', 'product b')
45
+ expect(cart).to have_at_most(2).products
46
+ end
47
+ ```
48
+
49
+ The last line of the example expresses an expected outcome:
50
+ if `cart.products.size <= 2` then the example passes, otherwise it fails with a message like:
51
+
52
+ expected at most 2 products, got 3
53
+
54
+ ## Available matchers
20
55
 
21
- TODO: Write usage instructions here
56
+ ```ruby
57
+ expect(collection).to have(n).items
58
+ expect(collection).to have_exactly(n).items
59
+ expect(collection).to have_at_most(n).items
60
+ expect(collection).to have_at_least(n).items
61
+ ```
22
62
 
23
- ## Contributing
63
+ ## See also
24
64
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
65
+ * [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
66
+ * [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)
67
+ * [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations)
data/Rakefile CHANGED
@@ -1 +1,18 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler"
2
+ Bundler.setup
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require "rake"
6
+
7
+ require "rspec/core/rake_task"
8
+ require "rspec/core/version"
9
+
10
+ require "cucumber/rake/task"
11
+ Cucumber::Rake::Task.new(:cucumber)
12
+
13
+ desc "Run all examples"
14
+ RSpec::Core::RakeTask.new(:spec) do |t|
15
+ t.ruby_opts = %w[-w]
16
+ end
17
+
18
+ task :default => [:spec, :cucumber]
@@ -0,0 +1,113 @@
1
+ Feature: have(n).items matcher
2
+
3
+ RSpec provides several matchers that make it easy to set expectations about the
4
+ size of a collection. There are three basic forms:
5
+
6
+ ```ruby
7
+ collection.should have(x).items
8
+ collection.should have_at_least(x).items
9
+ collection.should have_at_most(x).items
10
+ ```
11
+
12
+ In addition, #have_exactly is provided as an alias to #have.
13
+
14
+ These work on any collection-like object--the object just needs to respond to #size
15
+ or #length (or both). When the matcher is called directly on a collection object,
16
+ the #items call is pure syntactic sugar. You can use anything you want here. These
17
+ are equivalent:
18
+
19
+ ```ruby
20
+ collection.should have(x).items
21
+ collection.should have(x).things
22
+ ```
23
+
24
+ You can also use this matcher on a non-collection object that returns a collection
25
+ from one of its methods. For example, Dir#entries returns an array, so you could
26
+ set an expectation using the following:
27
+
28
+ ```ruby
29
+ Dir.new("my/directory").should have(7).entries
30
+ ```
31
+
32
+ Scenario: have(x).items on a collection
33
+ Given a file named "have_items_spec.rb" with:
34
+ """ruby
35
+ require 'rspec/collection_matchers'
36
+
37
+ describe [1, 2, 3] do
38
+ it { should have(3).items }
39
+ it { should_not have(2).items }
40
+ it { should_not have(4).items }
41
+
42
+ it { should have_exactly(3).items }
43
+ it { should_not have_exactly(2).items }
44
+ it { should_not have_exactly(4).items }
45
+
46
+ it { should have_at_least(2).items }
47
+ it { should have_at_most(4).items }
48
+
49
+ # deliberate failures
50
+ it { should_not have(3).items }
51
+ it { should have(2).items }
52
+ it { should have(4).items }
53
+
54
+ it { should_not have_exactly(3).items }
55
+ it { should have_exactly(2).items }
56
+ it { should have_exactly(4).items }
57
+
58
+ it { should have_at_least(4).items }
59
+ it { should have_at_most(2).items }
60
+ end
61
+ """
62
+ When I run `rspec have_items_spec.rb`
63
+ Then the output should contain "16 examples, 8 failures"
64
+ And the output should contain "expected target not to have 3 items, got 3"
65
+ And the output should contain "expected 2 items, got 3"
66
+ And the output should contain "expected 4 items, got 3"
67
+ And the output should contain "expected at least 4 items, got 3"
68
+ And the output should contain "expected at most 2 items, got 3"
69
+
70
+ Scenario: have(x).words on a String when String#words is defined
71
+ Given a file named "have_words_spec.rb" with:
72
+ """ruby
73
+ require 'rspec/collection_matchers'
74
+
75
+ class String
76
+ def words
77
+ split(' ')
78
+ end
79
+ end
80
+
81
+ describe "a sentence with some words" do
82
+ it { should have(5).words }
83
+ it { should_not have(4).words }
84
+ it { should_not have(6).words }
85
+
86
+ it { should have_exactly(5).words }
87
+ it { should_not have_exactly(4).words }
88
+ it { should_not have_exactly(6).words }
89
+
90
+ it { should have_at_least(4).words }
91
+ it { should have_at_most(6).words }
92
+
93
+ # deliberate failures
94
+ it { should_not have(5).words }
95
+ it { should have(4).words }
96
+ it { should have(6).words }
97
+
98
+ it { should_not have_exactly(5).words }
99
+ it { should have_exactly(4).words }
100
+ it { should have_exactly(6).words }
101
+
102
+ it { should have_at_least(6).words }
103
+ it { should have_at_most(4).words }
104
+ end
105
+ """
106
+ When I run `rspec have_words_spec.rb`
107
+ Then the output should contain "16 examples, 8 failures"
108
+ And the output should contain "expected target not to have 5 words, got 5"
109
+ And the output should contain "expected 4 words, got 5"
110
+ And the output should contain "expected 6 words, got 5"
111
+ And the output should contain "expected at least 6 words, got 5"
112
+ And the output should contain "expected at most 4 words, got 5"
113
+
@@ -0,0 +1,21 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ if RUBY_PLATFORM =~ /java/
5
+ @aruba_timeout_seconds = 30
6
+ else
7
+ @aruba_timeout_seconds = 10
8
+ end
9
+ end
10
+
11
+ Aruba.configure do |config|
12
+ config.before_cmd do |cmd|
13
+ set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived
14
+ end
15
+ end if RUBY_PLATFORM == 'java'
16
+
17
+ Aruba.configure do |config|
18
+ config.before_cmd do |cmd|
19
+ set_env('RBXOPT', "-Xint=true #{ENV['RBXOPT']}") # disable JIT since these processes are so short lived
20
+ end
21
+ end if defined?(Rubinius)
@@ -0,0 +1,3 @@
1
+ require 'rspec/collection_matchers/version'
2
+ require 'rspec/collection_matchers/matchers'
3
+ require 'rspec/collection_matchers/have'
@@ -0,0 +1,122 @@
1
+ module RSpec
2
+ module CollectionMatchers
3
+ class Have
4
+ QUERY_METHODS = [:size, :length, :count].freeze
5
+
6
+ def initialize(expected, relativity=:exactly)
7
+ @expected = case expected
8
+ when :no then 0
9
+ when String then expected.to_i
10
+ else expected
11
+ end
12
+ @relativity = relativity
13
+ @actual = @collection_name = @plural_collection_name = nil
14
+ end
15
+
16
+ def relativities
17
+ @relativities ||= {
18
+ :exactly => "",
19
+ :at_least => "at least ",
20
+ :at_most => "at most "
21
+ }
22
+ end
23
+
24
+ def matches?(collection_or_owner)
25
+ collection = determine_collection(collection_or_owner)
26
+ case collection
27
+ when enumerator_class
28
+ for query_method in QUERY_METHODS
29
+ next unless collection.respond_to?(query_method)
30
+ @actual = collection.__send__(query_method)
31
+ break unless @actual.nil?
32
+ end
33
+ raise not_a_collection if @actual.nil?
34
+ else
35
+ query_method = determine_query_method(collection)
36
+ raise not_a_collection unless query_method
37
+ @actual = collection.__send__(query_method)
38
+ end
39
+ case @relativity
40
+ when :at_least then @actual >= @expected
41
+ when :at_most then @actual <= @expected
42
+ else @actual == @expected
43
+ end
44
+ end
45
+ alias == matches?
46
+
47
+ def determine_collection(collection_or_owner)
48
+ if collection_or_owner.respond_to?(@collection_name)
49
+ collection_or_owner.__send__(@collection_name, *@args, &@block)
50
+ elsif (@plural_collection_name && collection_or_owner.respond_to?(@plural_collection_name))
51
+ collection_or_owner.__send__(@plural_collection_name, *@args, &@block)
52
+ elsif determine_query_method(collection_or_owner)
53
+ collection_or_owner
54
+ else
55
+ collection_or_owner.__send__(@collection_name, *@args, &@block)
56
+ end
57
+ end
58
+
59
+ def determine_query_method(collection)
60
+ QUERY_METHODS.detect {|m| collection.respond_to?(m)}
61
+ end
62
+
63
+ def not_a_collection
64
+ "expected #{@collection_name} to be a collection but it does not respond to #length, #size or #count"
65
+ end
66
+
67
+ def failure_message_for_should
68
+ "expected #{relative_expectation} #{@collection_name}, got #{@actual}"
69
+ end
70
+
71
+ def failure_message_for_should_not
72
+ if @relativity == :exactly
73
+ return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}"
74
+ elsif @relativity == :at_most
75
+ return <<-EOF
76
+ Isn't life confusing enough?
77
+ Instead of having to figure out the meaning of this:
78
+ #{Expectations::Syntax.negative_expression("actual", "have_at_most(#{@expected}).#{@collection_name}")}
79
+ We recommend that you use this instead:
80
+ #{Expectations::Syntax.positive_expression("actual", "have_at_least(#{@expected + 1}).#{@collection_name}")}
81
+ EOF
82
+ elsif @relativity == :at_least
83
+ return <<-EOF
84
+ Isn't life confusing enough?
85
+ Instead of having to figure out the meaning of this:
86
+ #{Expectations::Syntax.negative_expression("actual", "have_at_least(#{@expected}).#{@collection_name}")}
87
+ We recommend that you use this instead:
88
+ #{Expectations::Syntax.positive_expression("actual", "have_at_most(#{@expected - 1}).#{@collection_name}")}
89
+ EOF
90
+ end
91
+ end
92
+
93
+ def description
94
+ "have #{relative_expectation} #{@collection_name}"
95
+ end
96
+
97
+ def respond_to?(m)
98
+ @expected.respond_to?(m) || super
99
+ end
100
+
101
+ private
102
+
103
+ def method_missing(method, *args, &block)
104
+ @collection_name = method
105
+ if inflector = (defined?(ActiveSupport::Inflector) && ActiveSupport::Inflector.respond_to?(:pluralize) ? ActiveSupport::Inflector : (defined?(Inflector) ? Inflector : nil))
106
+ @plural_collection_name = inflector.pluralize(method.to_s)
107
+ end
108
+ @args = args
109
+ @block = block
110
+ self
111
+ end
112
+
113
+ def relative_expectation
114
+ "#{relativities[@relativity]}#{@expected}"
115
+ end
116
+
117
+ def enumerator_class
118
+ RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator
119
+ end
120
+ end
121
+ end
122
+ end