motion-expect 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/lib/motion-expect.rb +9 -0
- data/lib/motion-expect/bacon_context.rb +4 -0
- data/lib/motion-expect/exceptions.rb +4 -0
- data/lib/motion-expect/expectation.rb +37 -0
- data/lib/motion-expect/fail_message_renderer.rb +100 -0
- data/lib/motion-expect/matcher/be.rb +11 -0
- data/lib/motion-expect/matcher/be_false.rb +12 -0
- data/lib/motion-expect/matcher/be_generic.rb +7 -0
- data/lib/motion-expect/matcher/be_nil.rb +11 -0
- data/lib/motion-expect/matcher/be_true.rb +11 -0
- data/lib/motion-expect/matcher/be_within.rb +21 -0
- data/lib/motion-expect/matcher/change.rb +28 -0
- data/lib/motion-expect/matcher/end_with.rb +15 -0
- data/lib/motion-expect/matcher/eq.rb +11 -0
- data/lib/motion-expect/matcher/eql.rb +9 -0
- data/lib/motion-expect/matcher/have_generic.rb +16 -0
- data/lib/motion-expect/matcher/have_items.rb +22 -0
- data/lib/motion-expect/matcher/include.rb +15 -0
- data/lib/motion-expect/matcher/match.rb +11 -0
- data/lib/motion-expect/matcher/match_array.rb +21 -0
- data/lib/motion-expect/matcher/matchers.rb +91 -0
- data/lib/motion-expect/matcher/raise_error.rb +31 -0
- data/lib/motion-expect/matcher/respond_to.rb +28 -0
- data/lib/motion-expect/matcher/satisfy.rb +15 -0
- data/lib/motion-expect/matcher/single_method.rb +22 -0
- data/lib/motion-expect/matcher/start_with.rb +15 -0
- data/motion-expect.gemspec +22 -0
- data/run-tests.sh +3 -0
- data/spec_app/.repl_history +0 -0
- data/spec_app/Gemfile +5 -0
- data/spec_app/Rakefile +15 -0
- data/spec_app/app/app_delegate.rb +5 -0
- data/spec_app/resources/Default-568h@2x.png +0 -0
- data/spec_app/spec/helpers/bacon_context.rb +5 -0
- data/spec_app/spec/matchers/be_false_spec.rb +22 -0
- data/spec_app/spec/matchers/be_generic_spec.rb +28 -0
- data/spec_app/spec/matchers/be_nil_spec.rb +22 -0
- data/spec_app/spec/matchers/be_true_spec.rb +22 -0
- data/spec_app/spec/matchers/be_within_spec.rb +21 -0
- data/spec_app/spec/matchers/change_spec.rb +44 -0
- data/spec_app/spec/matchers/end_with_spec.rb +13 -0
- data/spec_app/spec/matchers/equality_spec.rb +37 -0
- data/spec_app/spec/matchers/have_generic_spec.rb +26 -0
- data/spec_app/spec/matchers/have_items_spec.rb +17 -0
- data/spec_app/spec/matchers/include_spec.rb +32 -0
- data/spec_app/spec/matchers/match_array_spec.rb +22 -0
- data/spec_app/spec/matchers/match_spec.rb +21 -0
- data/spec_app/spec/matchers/raise_error_spec.rb +65 -0
- data/spec_app/spec/matchers/respond_to_spec.rb +30 -0
- data/spec_app/spec/matchers/satisfy_spec.rb +17 -0
- data/spec_app/spec/matchers/start_with_spec.rb +13 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 31eee27b240ba338e3267efd2a74d3080f28d4d4
|
4
|
+
data.tar.gz: 0f4b4aba9cdc883561ec08a601d0594a34e9755e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3205d44d297e65cb9eec6d8359b6947dd77fe26c6804d8e23f63767f021760232da6dfeb0fe401b8a64d76ef5400a826adcaefbc855d9df18f46d6f6b6f6e972
|
7
|
+
data.tar.gz: 19428d3b5ee5a9afa6b06f814e52d4acee7a19948cac739ca177feee50e56454136b85701378ed02336efc3d96d18eaa140f6ea58dd8906f6252f082a13d0d2e
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ignacio Piantanida
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
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.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# MotionExpect [![Build Status](https://travis-ci.org/rubymotion-community/motion-expect.svg?branch=master)](https://travis-ci.org/rubymotion-community/motion-expect) [![Code Climate](https://codeclimate.com/github/rubymotion-community/motion-expect.png)](https://codeclimate.com/github/rubymotion-community/motion-expect)
|
2
|
+
|
3
|
+
Bring [RSpec 3.0 expect syntax](https://www.relishapp.com/rspec/rspec-expectations/v/3-0/docs/built-in-matchers) to RubyMotion's MacBacon.
|
4
|
+
```ruby
|
5
|
+
expect(view("Tap me")).not_to be_hidden
|
6
|
+
```
|
7
|
+
|
8
|
+
Expect syntax allows a cleaner implementation because it doesn't need to monkey-patch the Object class to install the `should` method.
|
9
|
+
|
10
|
+
# Installation
|
11
|
+
```
|
12
|
+
gem install motion-expect
|
13
|
+
|
14
|
+
# or in Gemfile
|
15
|
+
gem 'motion-expect'
|
16
|
+
```
|
17
|
+
|
18
|
+
# Usage
|
19
|
+
This gem ports most of the built-in matchers found in [RSpec 3.0](https://www.relishapp.com/rspec/rspec-expectations/v/3-0/docs/built-in-matchers)
|
20
|
+
|
21
|
+
**A full list of matchers examples can be found in the [sample app specs.](spec_app/spec/matchers)**
|
22
|
+
|
23
|
+
Examples:
|
24
|
+
```ruby
|
25
|
+
expect(nil).to be_nil
|
26
|
+
expect(true).not_to be_false
|
27
|
+
|
28
|
+
expect("super").to end_with("per")
|
29
|
+
expect{ 1/0 }.to raise_error(ZeroDivisionError)
|
30
|
+
expect{ raise ArgumentError.new("with a message") }.to raise_error(ArgumentError, /message/)
|
31
|
+
expect([1,2,3]).to have(3).items
|
32
|
+
expect("string").to respond_to(:upcase)
|
33
|
+
```
|
34
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,9 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
Motion::Project::App.setup do |app|
|
6
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'motion-expect/**/*.rb')).sort.reverse.each do |file|
|
7
|
+
app.spec_files << file
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module MotionExpect
|
2
|
+
class Expectation
|
3
|
+
module BaconContext
|
4
|
+
def expect(subject = nil, &block)
|
5
|
+
Expectation.new(subject, &block)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(subject, &subject_block)
|
10
|
+
@subject = subject
|
11
|
+
@subject_block = subject_block
|
12
|
+
end
|
13
|
+
|
14
|
+
def to(matcher)
|
15
|
+
fail(matcher, false) unless matcher_passes(matcher)
|
16
|
+
assert
|
17
|
+
end
|
18
|
+
|
19
|
+
def not_to(matcher)
|
20
|
+
fail(matcher, true) if matcher_passes(matcher)
|
21
|
+
assert
|
22
|
+
end
|
23
|
+
alias_method :to_not, :not_to
|
24
|
+
|
25
|
+
def matcher_passes(matcher)
|
26
|
+
matcher.matches?(@subject, &@subject_block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def fail(matcher, negated)
|
30
|
+
raise matcher.fail!(@subject, negated, &@subject_block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert
|
34
|
+
true.should == true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module MotionExpect
|
2
|
+
class FailMessageRenderer
|
3
|
+
def self.expectation(negated)
|
4
|
+
"#{negated ? " not" : ""} expected"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.message_for_be_false(negated, subject)
|
8
|
+
"#{subject.inspect}#{expectation(negated)} to be false"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.message_for_be_true(negated, subject)
|
12
|
+
"#{subject.inspect}#{expectation(negated)} to be true"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.message_for_be_nil(negated, subject)
|
16
|
+
"#{subject.inspect}#{expectation(negated)} to be nil"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.message_for_be(negated, subject, method_name, values)
|
20
|
+
message = "#{subject.inspect} ##{method_name}"
|
21
|
+
message += "(#{values.map(&:inspect).join(', ')})" unless values.empty?
|
22
|
+
message += "#{expectation(negated)} to return true"
|
23
|
+
message
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.message_for_be_within(negated, subject, range, center_value)
|
27
|
+
"#{subject.inspect}#{expectation(negated)} to be within #{range} of #{center_value}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.message_for_change(negated, change_amount, value_diff)
|
31
|
+
message = "Block#{expectation(negated)} to change value"
|
32
|
+
message += " by #{change_amount}" if change_amount
|
33
|
+
message += " but changed by #{value_diff}" if change_amount && !negated
|
34
|
+
message
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.message_for_end_with(negated, subject, end_string)
|
38
|
+
"#{subject.inspect}#{expectation(negated)} to end with #{end_string.inspect}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.message_for_start_with(negated, subject, start_string)
|
42
|
+
"#{subject.inspect}#{expectation(negated)} to start with #{start_string.inspect}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.message_for_be_equal(negated, subject, value)
|
46
|
+
"#{subject.inspect}#{expectation(negated)} to be same object as #{value.inspect}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.message_for_be_eq(negated, subject, value)
|
50
|
+
"#{subject.inspect}#{expectation(negated)} to be == to #{value.inspect}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.message_for_have_generic(negated, subject, method_name, values)
|
54
|
+
message = "#{subject.inspect} #has_#{method_name}?"
|
55
|
+
message += "(#{values.map(&:inspect).join(', ')})" unless values.empty?
|
56
|
+
message += "#{expectation(negated)} to return true"
|
57
|
+
message
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.message_for_have_items(negated, subject, expected_number_of_items, actual_number_of_items, key_type_name)
|
61
|
+
message = "#{subject.inspect}#{expectation(negated)} to have #{expected_number_of_items} #{key_type_name}"
|
62
|
+
message += " but had #{actual_number_of_items}" unless negated
|
63
|
+
message
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.message_for_include(negated, subject, values)
|
67
|
+
values_message = values.size == 1 ? values.first : values
|
68
|
+
message = "#{subject.inspect}#{expectation(negated)} to include #{values_message.inspect}"
|
69
|
+
message
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.message_for_match_array(negated, subject_array, expected_array)
|
73
|
+
message = "#{subject_array.inspect}#{expectation(negated)} to match array"
|
74
|
+
message += " #{expected_array.inspect}"
|
75
|
+
message
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.message_for_match(negated, subject, match)
|
79
|
+
"#{subject.inspect}#{expectation(negated)} to match #{match.inspect}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.message_for_raise_error(negated, show_class, error_class, show_message, error_message, rescued_exception)
|
83
|
+
message = "Block#{expectation(negated)} to raise error"
|
84
|
+
message += " of type #{error_class}" if show_class
|
85
|
+
message += " with message matching #{error_message.inspect}" if show_message
|
86
|
+
message += " but was #{rescued_exception.inspect}" if rescued_exception && !negated
|
87
|
+
message
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.message_for_respond_to(negated, subject, method_name, number_of_args)
|
91
|
+
message = "#{subject.inspect}#{expectation(negated)} to respond to ##{method_name}"
|
92
|
+
message += " with #{number_of_args} arguments" if number_of_args
|
93
|
+
message
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.message_for_satisfy(negated)
|
97
|
+
"Block#{expectation(negated)} to satisfy condition"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MotionExpect; module Matcher
|
2
|
+
class BeWithin
|
3
|
+
def initialize(range)
|
4
|
+
@range = range
|
5
|
+
end
|
6
|
+
|
7
|
+
def of(center_value)
|
8
|
+
@center_value = center_value
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(subject)
|
13
|
+
raise InvalidMatcher.new("be_within matcher incomplete. Missing .of value") unless @center_value
|
14
|
+
(subject - @center_value).abs <= @range
|
15
|
+
end
|
16
|
+
|
17
|
+
def fail!(subject, negated)
|
18
|
+
raise FailedExpectation.new(FailMessageRenderer.message_for_be_within(negated, subject, @range, @center_value))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end; end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MotionExpect; module Matcher
|
2
|
+
class Change
|
3
|
+
def initialize(change_block)
|
4
|
+
@change_block = change_block
|
5
|
+
end
|
6
|
+
|
7
|
+
def by(amount)
|
8
|
+
@change_amount = amount
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(subject, &expectation_block)
|
13
|
+
old_value = @change_block.call
|
14
|
+
expectation_block.call
|
15
|
+
new_value = @change_block.call
|
16
|
+
if @change_amount
|
17
|
+
@value_diff = new_value - old_value
|
18
|
+
@value_diff == @change_amount
|
19
|
+
else
|
20
|
+
new_value != old_value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def fail!(subject, negated)
|
25
|
+
raise FailedExpectation.new(FailMessageRenderer.message_for_change(negated, @change_amount, @value_diff))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end; end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MotionExpect; module Matcher
|
2
|
+
class EndWith
|
3
|
+
def initialize(end_string)
|
4
|
+
@end_string = end_string
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(subject)
|
8
|
+
subject[-@end_string.size..-1] == @end_string
|
9
|
+
end
|
10
|
+
|
11
|
+
def fail!(subject, negated)
|
12
|
+
raise FailedExpectation.new(FailMessageRenderer.message_for_end_with(negated, subject, @end_string))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end; end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module MotionExpect; module Matcher
|
2
|
+
class HaveGeneric
|
3
|
+
def initialize(method_name, *args)
|
4
|
+
@method_name = method_name
|
5
|
+
@args = args
|
6
|
+
end
|
7
|
+
|
8
|
+
def matches?(subject)
|
9
|
+
subject.send("has_#{@method_name}?", *@args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def fail!(subject, negated)
|
13
|
+
raise FailedExpectation.new(FailMessageRenderer.message_for_have_generic(negated, subject, @method_name, @args))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end; end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MotionExpect; module Matcher
|
2
|
+
class HaveItems
|
3
|
+
def initialize(number_of_items)
|
4
|
+
@number_of_items = number_of_items
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(value)
|
8
|
+
value.size == @number_of_items
|
9
|
+
end
|
10
|
+
|
11
|
+
[:items, :item, :keys, :values].each do |key_type_name|
|
12
|
+
define_method(key_type_name) do
|
13
|
+
@key_type_name = key_type_name
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def fail!(subject, negated)
|
19
|
+
raise FailedExpectation.new(FailMessageRenderer.message_for_have_items(negated, subject, @number_of_items, subject.size, @key_type_name))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end; end
|