motion-expect 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG.md +4 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +34 -0
  8. data/Rakefile +1 -0
  9. data/lib/motion-expect.rb +9 -0
  10. data/lib/motion-expect/bacon_context.rb +4 -0
  11. data/lib/motion-expect/exceptions.rb +4 -0
  12. data/lib/motion-expect/expectation.rb +37 -0
  13. data/lib/motion-expect/fail_message_renderer.rb +100 -0
  14. data/lib/motion-expect/matcher/be.rb +11 -0
  15. data/lib/motion-expect/matcher/be_false.rb +12 -0
  16. data/lib/motion-expect/matcher/be_generic.rb +7 -0
  17. data/lib/motion-expect/matcher/be_nil.rb +11 -0
  18. data/lib/motion-expect/matcher/be_true.rb +11 -0
  19. data/lib/motion-expect/matcher/be_within.rb +21 -0
  20. data/lib/motion-expect/matcher/change.rb +28 -0
  21. data/lib/motion-expect/matcher/end_with.rb +15 -0
  22. data/lib/motion-expect/matcher/eq.rb +11 -0
  23. data/lib/motion-expect/matcher/eql.rb +9 -0
  24. data/lib/motion-expect/matcher/have_generic.rb +16 -0
  25. data/lib/motion-expect/matcher/have_items.rb +22 -0
  26. data/lib/motion-expect/matcher/include.rb +15 -0
  27. data/lib/motion-expect/matcher/match.rb +11 -0
  28. data/lib/motion-expect/matcher/match_array.rb +21 -0
  29. data/lib/motion-expect/matcher/matchers.rb +91 -0
  30. data/lib/motion-expect/matcher/raise_error.rb +31 -0
  31. data/lib/motion-expect/matcher/respond_to.rb +28 -0
  32. data/lib/motion-expect/matcher/satisfy.rb +15 -0
  33. data/lib/motion-expect/matcher/single_method.rb +22 -0
  34. data/lib/motion-expect/matcher/start_with.rb +15 -0
  35. data/motion-expect.gemspec +22 -0
  36. data/run-tests.sh +3 -0
  37. data/spec_app/.repl_history +0 -0
  38. data/spec_app/Gemfile +5 -0
  39. data/spec_app/Rakefile +15 -0
  40. data/spec_app/app/app_delegate.rb +5 -0
  41. data/spec_app/resources/Default-568h@2x.png +0 -0
  42. data/spec_app/spec/helpers/bacon_context.rb +5 -0
  43. data/spec_app/spec/matchers/be_false_spec.rb +22 -0
  44. data/spec_app/spec/matchers/be_generic_spec.rb +28 -0
  45. data/spec_app/spec/matchers/be_nil_spec.rb +22 -0
  46. data/spec_app/spec/matchers/be_true_spec.rb +22 -0
  47. data/spec_app/spec/matchers/be_within_spec.rb +21 -0
  48. data/spec_app/spec/matchers/change_spec.rb +44 -0
  49. data/spec_app/spec/matchers/end_with_spec.rb +13 -0
  50. data/spec_app/spec/matchers/equality_spec.rb +37 -0
  51. data/spec_app/spec/matchers/have_generic_spec.rb +26 -0
  52. data/spec_app/spec/matchers/have_items_spec.rb +17 -0
  53. data/spec_app/spec/matchers/include_spec.rb +32 -0
  54. data/spec_app/spec/matchers/match_array_spec.rb +22 -0
  55. data/spec_app/spec/matchers/match_spec.rb +21 -0
  56. data/spec_app/spec/matchers/raise_error_spec.rb +65 -0
  57. data/spec_app/spec/matchers/respond_to_spec.rb +30 -0
  58. data/spec_app/spec/matchers/satisfy_spec.rb +17 -0
  59. data/spec_app/spec/matchers/start_with_spec.rb +13 -0
  60. metadata +131 -0
@@ -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
@@ -0,0 +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
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ spec_app/build/*
@@ -0,0 +1,8 @@
1
+ language: objective-c
2
+ before_install:
3
+ - (ruby --version)
4
+ - (motion --version)
5
+ - sudo chown -R travis ~/Library/RubyMotion
6
+ - mkdir -p ~/Library/RubyMotion/build
7
+ - sudo motion update
8
+ script: "./run-tests.sh"
@@ -0,0 +1,4 @@
1
+ [2.0.0]
2
+
3
+ - Renamed gem to motion-expect (based on discussion with original owner - https://github.com/ijpiantanida/bacon-expect/issues/4)
4
+ - Updated for RubyMotion 6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in motion-expect.gemspec
4
+ gemspec
@@ -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.
@@ -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
+
@@ -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,4 @@
1
+ class Bacon::Context
2
+ include MotionExpect::Expectation::BaconContext
3
+ include MotionExpect::Matcher::BaconContext
4
+ end
@@ -0,0 +1,4 @@
1
+ module MotionExpect
2
+ class FailedExpectation < RuntimeError; end
3
+ class InvalidMatcher < RuntimeError; end
4
+ 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,11 @@
1
+ module MotionExpect; module Matcher
2
+ class Be < SingleMethod
3
+ def initialize(value)
4
+ super(:equal?, value)
5
+ end
6
+
7
+ def fail_message(subject, negated)
8
+ FailMessageRenderer.message_for_be_equal(negated, subject, @values.first)
9
+ end
10
+ end
11
+ end; end
@@ -0,0 +1,12 @@
1
+ module MotionExpect; module Matcher
2
+ class BeFalse
3
+ def matches?(value)
4
+ !value
5
+ end
6
+
7
+ def fail!(subject, negated)
8
+ message = FailMessageRenderer.message_for_be_false(negated, subject)
9
+ raise FailedExpectation.new(message)
10
+ end
11
+ end
12
+ end; end
@@ -0,0 +1,7 @@
1
+ module MotionExpect; module Matcher
2
+ class BeGeneric < SingleMethod
3
+ def initialize(method_name, *values)
4
+ super("#{method_name}?", *values)
5
+ end
6
+ end
7
+ end; end
@@ -0,0 +1,11 @@
1
+ module MotionExpect; module Matcher
2
+ class BeNil
3
+ def matches?(value)
4
+ value == nil
5
+ end
6
+
7
+ def fail!(subject, negated)
8
+ raise FailedExpectation.new(FailMessageRenderer.message_for_be_nil(negated, subject))
9
+ end
10
+ end
11
+ end; end
@@ -0,0 +1,11 @@
1
+ module MotionExpect; module Matcher
2
+ class BeTrue
3
+ def matches?(value)
4
+ value == true
5
+ end
6
+
7
+ def fail!(subject, negated)
8
+ raise FailedExpectation.new(FailMessageRenderer.message_for_be_true(negated, subject))
9
+ end
10
+ end
11
+ end; 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,11 @@
1
+ module MotionExpect; module Matcher
2
+ class Eq < SingleMethod
3
+ def initialize(value)
4
+ super(:==, value)
5
+ end
6
+
7
+ def fail_message(subject, negated)
8
+ FailMessageRenderer.message_for_be_eq(negated, subject, @values.first)
9
+ end
10
+ end
11
+ end; end
@@ -0,0 +1,9 @@
1
+ module MotionExpect
2
+ module Matcher
3
+ class Eql < SingleMethod
4
+ def initialize(value)
5
+ super(:eql?, value)
6
+ end
7
+ end
8
+ end
9
+ 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