rspec-sleeping_king_studios 1.0.0.rc.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +323 -0
  4. data/lib/rspec/sleeping_king_studios.rb +5 -0
  5. data/lib/rspec/sleeping_king_studios/matchers.rb +5 -0
  6. data/lib/rspec/sleeping_king_studios/matchers/active_model.rb +5 -0
  7. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb +219 -0
  8. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation.rb +60 -0
  9. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/message_expectation.rb +17 -0
  10. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/require.rb +7 -0
  11. data/lib/rspec/sleeping_king_studios/matchers/active_model/require.rb +8 -0
  12. data/lib/rspec/sleeping_king_studios/matchers/base_matcher.rb +43 -0
  13. data/lib/rspec/sleeping_king_studios/matchers/built_in.rb +5 -0
  14. data/lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb +68 -0
  15. data/lib/rspec/sleeping_king_studios/matchers/built_in/include.rb +92 -0
  16. data/lib/rspec/sleeping_king_studios/matchers/built_in/require.rb +7 -0
  17. data/lib/rspec/sleeping_king_studios/matchers/built_in/respond_to.rb +187 -0
  18. data/lib/rspec/sleeping_king_studios/matchers/core.rb +5 -0
  19. data/lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb +41 -0
  20. data/lib/rspec/sleeping_king_studios/matchers/core/construct.rb +138 -0
  21. data/lib/rspec/sleeping_king_studios/matchers/core/have_property.rb +84 -0
  22. data/lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb +76 -0
  23. data/lib/rspec/sleeping_king_studios/matchers/core/have_writer.rb +101 -0
  24. data/lib/rspec/sleeping_king_studios/matchers/core/require.rb +7 -0
  25. data/lib/rspec/sleeping_king_studios/matchers/meta.rb +5 -0
  26. data/lib/rspec/sleeping_king_studios/matchers/meta/fail_with_actual.rb +142 -0
  27. data/lib/rspec/sleeping_king_studios/matchers/meta/pass_with_actual.rb +96 -0
  28. data/lib/rspec/sleeping_king_studios/matchers/meta/require.rb +7 -0
  29. data/lib/rspec/sleeping_king_studios/matchers/require.rb +12 -0
  30. data/lib/rspec/sleeping_king_studios/matchers/shared/match_parameters.rb +69 -0
  31. data/lib/rspec/sleeping_king_studios/matchers/shared/require.rb +7 -0
  32. data/lib/rspec/sleeping_king_studios/mocks/custom_double.rb +13 -0
  33. data/lib/rspec/sleeping_king_studios/require.rb +7 -0
  34. data/lib/rspec/sleeping_king_studios/version.rb +7 -0
  35. metadata +151 -0
@@ -0,0 +1,5 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core.rb
2
+
3
+ Dir[File.join File.dirname(__FILE__), 'core', '*.rb'].each do |file|
4
+ require file
5
+ end # end each
@@ -0,0 +1,41 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core/require'
5
+
6
+ module RSpec::SleepingKingStudios::Matchers::Core
7
+ # Matcher for testing whether an object is true or false.
8
+ #
9
+ # @since 1.0.0
10
+ class BeBooleanMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
11
+ # Checks if the object is true or false.
12
+ #
13
+ # @param [Object] actual the object to check
14
+ #
15
+ # @return [Boolean] true if the object is true or false, otherwise false
16
+ def matches? actual
17
+ super
18
+
19
+ true === actual || false === actual
20
+ end # method matches?
21
+
22
+ # @see BaseMatcher#failure_message_for_should
23
+ def failure_message_for_should
24
+ "expected #{@actual.inspect} to be true or false"
25
+ end # method failure_message_for_should
26
+
27
+ # @see BaseMatcher#failure_message_for_should_not
28
+ def failure_message_for_should_not
29
+ "expected #{@actual.inspect} not to be true or false"
30
+ end # method failure_message_for_should_not
31
+ end # class
32
+ end # module
33
+
34
+ module RSpec::SleepingKingStudios::Matchers
35
+ # @see RSpec::SleepingKingStudios::Matchers::Core::BeBooleanMatcher#matches?
36
+ def be_boolean
37
+ RSpec::SleepingKingStudios::Matchers::Core::BeBooleanMatcher.new
38
+ end # method be_boolean
39
+
40
+ alias_method :be_bool, :be_boolean
41
+ end # module
@@ -0,0 +1,138 @@
1
+ # spec/rspec/sleeping_king_studios/matchers/core/construct.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core/require'
5
+
6
+ require 'rspec/sleeping_king_studios/matchers/shared/match_parameters'
7
+
8
+ module RSpec::SleepingKingStudios::Matchers::Core
9
+ # Matcher for checking whether an object can be constructed via #new and
10
+ # #initialize, and the parameters accepted by #initialize.
11
+ #
12
+ # @since 1.0.0
13
+ class ConstructMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
14
+ include RSpec::SleepingKingStudios::Matchers::Shared::MatchParameters
15
+
16
+ # Checks if the object responds to :new. If so, allocates an instance and
17
+ # checks the parameters expected by #initialize against the expected
18
+ # parameters, if any.
19
+ #
20
+ # @param [Object] actual the object to check
21
+ #
22
+ # @return [Boolean] true if the object responds to :new and accepts the
23
+ # specified parameters for #initialize; otherwise false
24
+ def matches? actual
25
+ @actual = actual
26
+ @failing_method_reasons = {}
27
+ @actual.respond_to?(:new) &&
28
+ matches_arity?(actual) &&
29
+ matches_keywords?(actual)
30
+ end # method matches?
31
+
32
+ # Adds a parameter count expectation and/or one or more keyword
33
+ # expectations (Ruby 2.0 only).
34
+ #
35
+ # @param [Integer, Range, nil] count the number of expected parameters; can
36
+ # be an integer, a range, or nil (parameter count is ignored)
37
+ # @param [Array<String, Symbol>] keywords list of keyword arguments
38
+ # accepted by the method
39
+ #
40
+ # @return [ConstructMatcher] self
41
+ def with count = nil, *keywords
42
+ @expected_arity = count unless count.nil?
43
+ @expected_keywords = keywords
44
+ self
45
+ end # method with
46
+
47
+ # Convenience method for more fluent specs. Does nothing and returns self.
48
+ #
49
+ # @return [ConstructMatcher] self
50
+ def arguments
51
+ self
52
+ end # method arguments
53
+
54
+ # @see BaseMatcher#failure_message_for_should
55
+ def failure_message_for_should
56
+ message = "expected #{@actual.inspect} to construct"
57
+ message << " with arguments:\n#{format_errors}" if @actual.respond_to?(:new)
58
+ message
59
+ end # method failure_message_for_should
60
+
61
+ # @see BaseMatcher#failure_message_for_should_not
62
+ def failure_message_for_should_not
63
+ message = "expected #{@actual.inspect} not to construct"
64
+ unless (formatted = format_expected_arguments).empty?
65
+ message << " with #{formatted}"
66
+ end # unless
67
+ message
68
+ end # method failure_message_for_should_not
69
+
70
+ private
71
+
72
+ def matches_arity? actual
73
+ return true unless @expected_arity
74
+
75
+ if result = check_method_arity(actual.allocate.method(:initialize), @expected_arity)
76
+ @failing_method_reasons.update result
77
+ return false
78
+ end # if
79
+
80
+ true
81
+ end # method matches_arity?
82
+
83
+ def matches_keywords? actual
84
+ return true unless @expected_keywords
85
+
86
+ if result = check_method_keywords(actual.allocate.method(:initialize), @expected_keywords)
87
+ @failing_method_reasons.update result
88
+ return false
89
+ end # if
90
+
91
+ true
92
+ end # method matches_keywords?
93
+
94
+ def format_expected_arguments
95
+ messages = []
96
+
97
+ if !@expected_arity.nil?
98
+ messages << "#{@expected_arity.inspect} argument#{1 == @expected_arity ? "" : "s"}"
99
+ end # if
100
+
101
+ if !(@expected_keywords.nil? || @expected_keywords.empty?)
102
+ messages << "keywords #{@expected_keywords.map(&:inspect).join(", ")}"
103
+ end # if
104
+
105
+ case messages.count
106
+ when 0..1
107
+ messages.join(", ")
108
+ when 2
109
+ "#{messages[0]} and #{messages[1]}"
110
+ else
111
+ "#{messages[1..-1].join(", ")}, and #{messages[0]}"
112
+ end # case
113
+ end # method format_expected_arguments
114
+
115
+ def format_errors
116
+ reasons, messages = @failing_method_reasons, []
117
+
118
+ if hsh = reasons.fetch(:not_enough_args, false)
119
+ messages << " expected at least #{hsh[:count]} arguments, but received #{hsh[:arity]}"
120
+ elsif hsh = reasons.fetch(:too_many_args, false)
121
+ messages << " expected at most #{hsh[:count]} arguments, but received #{hsh[:arity]}"
122
+ end # if-elsif
123
+
124
+ if ary = reasons.fetch(:unexpected_keywords, false)
125
+ messages << " unexpected keywords #{ary.map(&:inspect).join(", ")}"
126
+ end # if
127
+
128
+ messages.join "\n"
129
+ end # method format_errors
130
+ end # class
131
+ end # module
132
+
133
+ module RSpec::SleepingKingStudios::Matchers
134
+ # @see RSpec::SleepingKingStudios::Matchers::Core::ConstructMatcher#matches?
135
+ def construct
136
+ RSpec::SleepingKingStudios::Matchers::Core::ConstructMatcher.new
137
+ end # method construct
138
+ end # module
@@ -0,0 +1,84 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/have_property.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core/require'
5
+
6
+ module RSpec::SleepingKingStudios::Matchers::Core
7
+ # Matcher for testing whether an object has a specific property, e.g.
8
+ # responds to :property and :property= and :property= updates the value of
9
+ # :property.
10
+ #
11
+ # @since 1.0.0
12
+ class HavePropertyMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
13
+ # @param [String, Symbol] expected the property to check for on the actual
14
+ # object
15
+ def initialize expected
16
+ super
17
+ @expected = expected.intern
18
+ end # method initialize
19
+
20
+ # Checks if the object responds to :expected and :expected=. Additionally,
21
+ # if a value expectation is set, assigns the value via :expected= and
22
+ # compares the subsequent value of :expected to the specified value.
23
+ #
24
+ # @param [Object] actual the object to check
25
+ #
26
+ # @return [Boolean] true if the object responds to :expected and
27
+ # :expected= and matches the value expectation (if any); otherwise false
28
+ def matches? actual
29
+ super
30
+
31
+ @match_reader = @actual.respond_to? @expected
32
+ @match_writer = @actual.respond_to? :"#{@expected}="
33
+
34
+ return false unless @match_reader && @match_writer
35
+
36
+ if @value_set
37
+ @actual.send :"#{@expected}=", @value
38
+ return false unless @actual.send(@expected) == @value
39
+ end # if
40
+
41
+ true
42
+ end # method matches?
43
+
44
+ # Sets a value expectation. The matcher will set the object's value to the
45
+ # specified value using :property=, then compare the value from :property
46
+ # with the specified value.
47
+ #
48
+ # @params [Object] value the value to set and then compare
49
+ #
50
+ # @return [HavePropertyMatcher] self
51
+ def with value
52
+ @value = value
53
+ @value_set = true
54
+ self
55
+ end # method with
56
+
57
+ # @see BaseMatcher#failure_message_for_should
58
+ def failure_message_for_should
59
+ methods = []
60
+ methods << ":#{@expected}" unless @match_reader
61
+ methods << ":#{@expected}=" unless @match_writer
62
+
63
+ return "expected #{@actual.inspect} to respond to #{methods.join " and "}" unless methods.empty?
64
+
65
+ "unexpected value for #{@actual.inspect}\##{@expected}" +
66
+ "\n expected: #{@value.inspect}" +
67
+ "\n got: #{@actual.send(@expected).inspect}"
68
+ end # failure_message_for_should
69
+
70
+ # @see BaseMatcher#failure_message_for_should_not
71
+ def failure_message_for_should_not
72
+ message = "expected #{@actual.inspect} not to respond to :#{@expected} or :#{@expected}="
73
+ message << " with value #{@value.inspect}" if @value_set
74
+ message
75
+ end # failure_message_for_should_not
76
+ end # class
77
+ end # module
78
+
79
+ module RSpec::SleepingKingStudios::Matchers
80
+ # @see RSpec::SleepingKingStudios::Matchers::Core::HavePropertyMatcher#matches?
81
+ def have_property expected
82
+ RSpec::SleepingKingStudios::Matchers::Core::HavePropertyMatcher.new expected
83
+ end # method have_property
84
+ end # module
@@ -0,0 +1,76 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core/require'
5
+
6
+ module RSpec::SleepingKingStudios::Matchers::Core
7
+ # Matcher for testing whether an object has a specific property reader, e.g.
8
+ # responds to :property.
9
+ #
10
+ # @since 1.0.0
11
+ class HaveReaderMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
12
+ # @param [String, Symbol] expected the property to check for on the actual
13
+ # object
14
+ def initialize expected
15
+ super
16
+ @expected = expected.intern
17
+ end # method initialize
18
+
19
+ # Checks if the object responds to :expected. Additionally, if a value
20
+ # expectation is set, compares the value of :expected to the specified
21
+ # value.
22
+ #
23
+ # @param [Object] actual the object to check
24
+ #
25
+ # @return [Boolean] true if the object responds to :expected and matches
26
+ # the value expectation (if any); otherwise false
27
+ def matches? actual
28
+ super
29
+
30
+ return false unless @match_reader = @actual.respond_to?(@expected)
31
+
32
+ if @value_set
33
+ return false unless @match_value = @actual.send(@expected) == @value
34
+ end # if
35
+
36
+ true
37
+ end # method matches?
38
+
39
+ # Sets a value expectation. The matcher will compare the value from
40
+ # :property with the specified value.
41
+ #
42
+ # @params [Object] value the value to compare
43
+ #
44
+ # @return [HaveReaderMatcher] self
45
+ def with value
46
+ @value = value
47
+ @value_set = true
48
+ self
49
+ end # method with
50
+
51
+ # @see BaseMatcher#failure_message_for_should
52
+ def failure_message_for_should
53
+ unless @match_reader
54
+ return "expected #{@actual} to respond to #{@expected.inspect}"
55
+ end # unless
56
+
57
+ "unexpected value for #{@actual}\##{@expected}\n" +
58
+ " expected: #{@value.inspect}\n" +
59
+ " got: #{@actual.send(@expected).inspect}"
60
+ end # method failure_message_for_should
61
+
62
+ # @see BaseMatcher#failure_message_for_should_not
63
+ def failure_message_for_should_not
64
+ message = "expected #{@actual} not to respond to #{@expected.inspect}"
65
+ message << " with value #{@value.inspect}" if @value_set
66
+ message
67
+ end # method failure_message_for_should
68
+ end # class
69
+ end # module
70
+
71
+ module RSpec::SleepingKingStudios::Matchers
72
+ # @see RSpec::SleepingKingStudios::Matchers::Core::HaveReaderMatcher#matches?
73
+ def have_reader expected
74
+ RSpec::SleepingKingStudios::Matchers::Core::HaveReaderMatcher.new expected
75
+ end # method have_reader
76
+ end # module
@@ -0,0 +1,101 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/have_mutator.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core/require'
5
+
6
+ module RSpec::SleepingKingStudios::Matchers::Core
7
+ # Matcher for testing whether an object has a specific property writer, e.g.
8
+ # responds to :property= and updates the state.
9
+ #
10
+ # @since 1.0.0
11
+ class HaveWriterMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
12
+ # @param [String, Symbol] expected the property to check for on the actual
13
+ # object
14
+ def initialize expected
15
+ super
16
+ @expected = expected.to_s.gsub(/=$/,'').intern
17
+ end # method initialize
18
+
19
+ # Checks if the object responds to :expected=. Additionally, if a value
20
+ # expectation is set, assigns the value via :expected= and compares the
21
+ # subsequent value to the specified value using :expected or the block
22
+ # provided to #with.
23
+ #
24
+ # @param [Object] actual the object to check
25
+ #
26
+ # @return [Boolean] true if the object responds to :expected= and matches
27
+ # the value expectation (if any); otherwise false
28
+ def matches? actual
29
+ super
30
+
31
+ return false unless @match_writer = @actual.respond_to?(:"#{@expected}=")
32
+
33
+ if @value_set
34
+ @actual.send :"#{@expected}=", @value
35
+
36
+ if @value_block.respond_to?(:call)
37
+ return false unless @value == (@actual_value = @actual.instance_eval(&@value_block))
38
+ elsif @actual.respond_to?(@expected)
39
+ return false unless @value == (@actual_value = @actual.send(@expected))
40
+ else
41
+ return false
42
+ end # if-elsif
43
+ end # if
44
+
45
+ true
46
+ end # method matches?
47
+
48
+ # Sets a value expectation. The matcher will set the object's value to the
49
+ # specified value using :property=, then compare the value from :property
50
+ # with the specified value. If a block is provided, the actual object
51
+ # evaluates the block and the value is compared to the specified value
52
+ # instead of using :property.
53
+ #
54
+ # @params [Object] value the value to compare
55
+ #
56
+ # @yield if a block is provided, the block is used to check the value after
57
+ # setting :property= instead of using :property.
58
+ #
59
+ # @example Using :property to check the value
60
+ # expect(instance).to have_writer(:foo).with(42)
61
+ #
62
+ # @example Using a block to check the valuye
63
+ # expect(instance).to have_writer(:bar).with(42) { self.getBar() }
64
+ #
65
+ # @return [HaveWriterMatcher] self
66
+ def with value, &block
67
+ @value = value
68
+ @value_set = true
69
+ @value_block = block
70
+ self
71
+ end # method with
72
+
73
+ # @see BaseMatcher#failure_message_for_should
74
+ def failure_message_for_should
75
+ return "expected #{@actual.inspect} to respond to #{@expected.inspect}=" unless @match_writer
76
+
77
+ unless @actual.respond_to?(@expected) || @value_block.respond_to?(:call)
78
+ return "unable to test #{@expected.inspect}= because #{@actual} does " +
79
+ "not respond to #{@expected.inspect}; try adding a test block to #with"
80
+ end # unless
81
+
82
+ return "unexpected value for #{@actual.inspect}#foo=\n" +
83
+ " expected: #{@value.inspect}\n" +
84
+ " got: #{@actual_value.inspect}"
85
+ end # method failure_message_for_should
86
+
87
+ # @see BaseMatcher#failure_message_for_should_not
88
+ def failure_message_for_should_not
89
+ message = "expected #{@actual} not to respond to #{@expected.inspect}="
90
+ message << " with value #{@value.inspect}" if @value_set && @match_writer
91
+ message
92
+ end # method failure_message_for_should
93
+ end # class
94
+ end # module
95
+
96
+ module RSpec::SleepingKingStudios::Matchers
97
+ # @see RSpec::SleepingKingStudios::Matchers::Core::HaveWriterMatcher#matches?
98
+ def have_writer expected
99
+ RSpec::SleepingKingStudios::Matchers::Core::HaveWriterMatcher.new expected
100
+ end # method have_writer
101
+ end # module