expected 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '0954ddfccf5072455413c702650c98e39ccdbd72a1db7806463598e5c6c0e52b'
4
+ data.tar.gz: c41841fcb0cfcfde9dfff9c1c27445f88c10a168254c965ea681a0e62676ee0c
5
+ SHA512:
6
+ metadata.gz: a6cf5251016d8d3f9b36af9ac429a0e9c8f433ee4c03b687a438e339d84361c913df7b63f6779597b49f0fb675ca4998c9da8a066e1371458ad04c1dff3675b5
7
+ data.tar.gz: bb7461e7f4e02295962c7b52288e86a710bf72f93f7a6ab4129eb29a8f9b7d27a66c50c95eea4b0d8681d0ed620b95f0237cf02818b5c5fda5de1e30f81f82c7
@@ -0,0 +1,22 @@
1
+ Copyright 2019 Taylor Yelverton
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,94 @@
1
+ # Expected: RSpec Matchers - Extended [![Gem Version][version-badge]][rubygems] [![Total Downloads][downloads-total]][rubygems] [![Downloads][downloads-badge]][rubygems]
2
+
3
+ [version-badge]: https://img.shields.io/gem/v/expected.svg
4
+ [rubygems]: https://rubygems.org/gems/expected
5
+ [downloads-total]: https://img.shields.io/gem/dt/expected.svg
6
+ [downloads-badge]: https://img.shields.io/gem/dtv/expected.svg
7
+
8
+ Adds several simple matchers to RSpec
9
+
10
+
11
+
12
+ ## Installation
13
+
14
+ ### Add to Gemfile
15
+ ```ruby
16
+ group :test do
17
+ gem 'expected'
18
+ end
19
+ ```
20
+
21
+ ### Add to RSpec
22
+ Add the following to your projects `spec/rails_helper.rb` for Rails apps, or `spec/spec_helper.rb for non-Rails apps.
23
+ ```ruby
24
+ Expected.configure do |config|
25
+ end
26
+ ```
27
+
28
+
29
+
30
+
31
+
32
+ ## Usage
33
+
34
+
35
+
36
+ ### `inherit_from`
37
+ Used to test inheritance
38
+
39
+ ```ruby
40
+ # Test if the subject inherits from the supplied Class
41
+ it { is_expected.to inherit_from(SomeClass) }
42
+ ```
43
+
44
+
45
+
46
+ ### `have_constant`
47
+ Used to test constants
48
+
49
+ ```ruby
50
+ # Test if a constant exists
51
+ it { is_expected.to have_constant(:FOO) }
52
+
53
+ # Test if a constant has a specific value
54
+ it { is_expected.to have_constant(:FOO).with_value("bar") }
55
+
56
+ # Test if a constant's value is a specific type
57
+ it { is_expected.to have_constant(:FOO).of_type(String) }
58
+ ```
59
+
60
+
61
+
62
+ ### `have_attr_reader`
63
+ Used to test inclusion of `attr_reader :attribute`
64
+
65
+ ```ruby
66
+ # Test if the subject has `attr_reader :attribute`
67
+ it { is_expected.to have_attr_reader(:attribute) }
68
+ ```
69
+
70
+
71
+
72
+ ### `have_attr_writer`
73
+ Used to test inclusion of `attr_writer :attribute`
74
+
75
+ ```ruby
76
+ # Test if the subject has `attr_writer :attribute`
77
+ it { is_expected.to have_attr_writer(:attribute) }
78
+ ```
79
+
80
+
81
+
82
+ ### `have_attr_accessor`
83
+ Used to test inclusion of `attr_accessor :attribute`
84
+
85
+ ```ruby
86
+ # Test if the subject has `attr_accessor :attribute`
87
+ it { is_expected.to have_attr_accessor(:attribute) }
88
+ ```
89
+
90
+
91
+
92
+ ## License
93
+ Expected is copyright © 2019-2020 Taylor Yelverton.
94
+ It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Container Module
4
+ module Expected
5
+
6
+ end
7
+
8
+ require 'active_support/hash_with_indifferent_access'
9
+ require 'active_support/core_ext/hash/indifferent_access'
10
+
11
+ require 'expected/version'
12
+ require 'expected/configuration'
13
+ require 'expected/matchers'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nodoc:
4
+ module Expected
5
+ class << self
6
+
7
+ # Configure the library
8
+ # @yield [Configuration]
9
+ def configure
10
+ yield configuration
11
+ end
12
+
13
+ # Memoized {Configuration}
14
+ # @return [Configuration]
15
+ def configuration
16
+ @configuration ||= Configuration.new
17
+ end
18
+
19
+ end
20
+
21
+ # Configuration class
22
+ class Configuration
23
+ end
24
+
25
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expected
4
+ # Matchers container
5
+ module Matchers
6
+ end
7
+ end
8
+
9
+ require 'expected/matchers/have_constant'
10
+ require 'expected/matchers/inherit_from'
11
+ require 'expected/matchers/have_attr_reader'
12
+ require 'expected/matchers/have_attr_writer'
13
+ require 'expected/matchers/have_attr_accessor'
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Expected
6
+ # :nodoc:
7
+ module Matchers
8
+
9
+ # Used to test inclusion of `attr_accessor :attribute` on the subject
10
+ # @param attribute [String, Symbol]
11
+ # @return [HaveAttrAccessorMatcher]
12
+ #
13
+ # @example Test if the subject has `attr_accessor :attribute`
14
+ # it { is_expected.to have_attr_accessor(:some_attribute) }
15
+ #
16
+ def have_attr_accessor(attribute) # rubocop:disable Naming/PredicateName
17
+ HaveAttrAccessorMatcher.new(attribute)
18
+ end
19
+
20
+ # Class used by {#have_constant}
21
+ class HaveAttrAccessorMatcher
22
+ attr_reader :attribute, :subject, :has_attr_reader, :has_attr_writer
23
+
24
+ # @param attribute [String, Symbol] The attribute the {#subject} is expected to have an attr_accessor for
25
+ def initialize(attribute)
26
+ unless attribute.is_a?(String) || attribute.is_a?(Symbol)
27
+ raise 'HaveAttrAccessorMatcher attribute must be a String or Symbol'
28
+ end
29
+ @attribute = attribute.to_sym
30
+ @has_attr_reader = HaveAttrReaderMatcher.new(attribute)
31
+ @has_attr_writer = HaveAttrWriterMatcher.new(attribute)
32
+ end
33
+
34
+ # Run the test
35
+ # @param subject The thing to test against
36
+ # @return [True] If the test passes
37
+ # @return [False] if the test fails
38
+ def matches?(subject)
39
+ self.subject = subject
40
+ matches_attr_reader? && matches_attr_writer?
41
+ end
42
+
43
+ # @return [String]
44
+ def failure_message
45
+ "Expected #{expectation} (#{@failure})"
46
+ end
47
+
48
+ # @return [String]
49
+ def failure_message_when_negated
50
+ "Did not expect #{expectation}"
51
+ end
52
+
53
+ # @return [String]
54
+ def description
55
+ "have_attr_accessor: `#{attribute}`"
56
+ end
57
+
58
+ private
59
+
60
+ # The thing to test against
61
+ # @return [Class, Module]
62
+ def subject=(subject) # rubocop:disable Style/TrivialAccessors
63
+ @subject = subject
64
+ end
65
+
66
+ def matches_attr_reader?
67
+ ret = has_attr_reader.matches?(subject)
68
+ msg = has_attr_reader.instance_variable_get(:@failure)
69
+ @failure = msg if msg
70
+ ret
71
+ end
72
+
73
+ def matches_attr_writer?
74
+ ret = has_attr_writer.matches?(subject)
75
+ msg = has_attr_writer.instance_variable_get(:@failure)
76
+ @failure = msg if msg
77
+ ret
78
+ end
79
+
80
+ # @return String
81
+ def expectation
82
+ "<#{subject}> to have attr_accessor `#{attribute}`"
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Expected
6
+ # :nodoc:
7
+ module Matchers
8
+
9
+ # Used to test inclusion of `attr_reader :attribute` on the subject
10
+ # @param attribute [String, Symbol]
11
+ # @return [HaveAttrReaderMatcher]
12
+ #
13
+ # @example Test if the subject has `attr_reader :attribute`
14
+ # it { is_expected.to have_attr_reader(:some_attribute) }
15
+ #
16
+ def have_attr_reader(attribute) # rubocop:disable Naming/PredicateName
17
+ HaveAttrReaderMatcher.new(attribute)
18
+ end
19
+
20
+ # Class used by {#have_constant}
21
+ class HaveAttrReaderMatcher
22
+ attr_reader :attribute, :subject
23
+
24
+ # @param attribute [String, Symbol] The attribute the {#subject} is expected to have an attr_reader for
25
+ def initialize(attribute)
26
+ unless attribute.is_a?(String) || attribute.is_a?(Symbol)
27
+ raise 'HaveAttrReaderMatcher attribute must be a String or Symbol'
28
+ end
29
+ @attribute = attribute.to_sym
30
+ end
31
+
32
+ # Run the test
33
+ # @param subject The thing to test against
34
+ # @return [True] If the test passes
35
+ # @return [False] if the test fails
36
+ def matches?(subject)
37
+ self.subject = subject
38
+ method? &&
39
+ returns_correct_value?
40
+ end
41
+
42
+ # @return [String]
43
+ def failure_message
44
+ "Expected #{expectation} (#{@failure})"
45
+ end
46
+
47
+ # @return [String]
48
+ def failure_message_when_negated
49
+ "Did not expect #{expectation}"
50
+ end
51
+
52
+ # @return [String]
53
+ def description
54
+ "have_attr_reader: `#{attribute}`"
55
+ end
56
+
57
+ private
58
+
59
+ # The thing to test against
60
+ # @return [Class, Module]
61
+ def subject=(subject)
62
+ @original_subject = subject
63
+ @subject = subject.instance_of?(Class) ? subject.allocate : subject
64
+ end
65
+
66
+ # @return [Symbol]
67
+ def attribute_ivar
68
+ @attribute_ivar ||= :"@#{attribute}"
69
+ end
70
+
71
+ def method?
72
+ if subject.respond_to? attribute
73
+ true
74
+ else
75
+ @failure = "no method `#{attribute}`"
76
+ false
77
+ end
78
+ end
79
+
80
+ def returns_correct_value? # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
81
+ has_original_val = subject.instance_variable_defined?(attribute_ivar)
82
+ original_val = subject.instance_variable_get(attribute_ivar)
83
+ test_val = SecureRandom.hex
84
+ subject.instance_variable_set(attribute_ivar, test_val)
85
+ ret = if subject.send(attribute) == test_val
86
+ true
87
+ else
88
+ @failure = "method `#{attribute}` did not return the value of #{attribute_ivar}"
89
+ false
90
+ end
91
+ subject.instance_variable_set(attribute_ivar, original_val) if has_original_val
92
+ ret
93
+ end
94
+
95
+ # @return String
96
+ def expectation
97
+ "<#{@original_subject}> to have attr_reader `#{attribute}`"
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Expected
6
+ # :nodoc:
7
+ module Matchers
8
+
9
+ # Used to test inclusion of `attr_writer :attribute` on the subject
10
+ # @param attribute [String, Symbol]
11
+ # @return [HaveAttrWriterMatcher]
12
+ #
13
+ # @example Test if the subject has `attr_writer :attribute`
14
+ # it { is_expected.to have_attr_writer(:some_attribute) }
15
+ #
16
+ def have_attr_writer(attribute) # rubocop:disable Naming/PredicateName
17
+ HaveAttrWriterMatcher.new(attribute)
18
+ end
19
+
20
+ # Class used by {#have_constant}
21
+ class HaveAttrWriterMatcher
22
+ attr_reader :attribute, :subject
23
+
24
+ # @param attribute [String, Symbol] The attribute the {#subject} is expected to have an attr_writer for
25
+ def initialize(attribute)
26
+ unless attribute.is_a?(String) || attribute.is_a?(Symbol)
27
+ raise 'HaveAttrWriterMatcher attribute must be a String or Symbol'
28
+ end
29
+ @attribute = attribute.to_sym
30
+ end
31
+
32
+ # Run the test
33
+ # @param subject The thing to test against
34
+ # @return [True] If the test passes
35
+ # @return [False] if the test fails
36
+ def matches?(subject)
37
+ self.subject = subject
38
+ method? &&
39
+ sets_correct_value?
40
+ end
41
+
42
+ # @return [String]
43
+ def failure_message
44
+ "Expected #{expectation} (#{@failure})"
45
+ end
46
+
47
+ # @return [String]
48
+ def failure_message_when_negated
49
+ "Did not expect #{expectation}"
50
+ end
51
+
52
+ # @return [String]
53
+ def description
54
+ "have_attr_writer: `#{attribute}`"
55
+ end
56
+
57
+ private
58
+
59
+ # The thing to test against
60
+ # @return [Class, Module]
61
+ def subject=(subject)
62
+ @original_subject = subject
63
+ @subject = subject.instance_of?(Class) ? subject.allocate : subject
64
+ end
65
+
66
+ # @return [Symbol]
67
+ def attribute_ivar
68
+ @attribute_ivar ||= :"@#{attribute}"
69
+ end
70
+
71
+ # @return [Symbol]
72
+ def method_name
73
+ @method_name ||= :"#{attribute}="
74
+ end
75
+
76
+ def method?
77
+ if subject.respond_to? method_name
78
+ true
79
+ else
80
+ @failure = "no method `#{method_name}`"
81
+ false
82
+ end
83
+ end
84
+
85
+ def sets_correct_value? # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
86
+ has_original_val = subject.instance_variable_defined?(attribute_ivar)
87
+ original_val = subject.instance_variable_get(attribute_ivar)
88
+ test_val = SecureRandom.hex
89
+ subject.send(method_name, test_val)
90
+ ret = if subject.instance_variable_get(attribute_ivar) == test_val
91
+ true
92
+ else
93
+ @failure = "method `#{method_name}` did not set the value of #{attribute_ivar}"
94
+ false
95
+ end
96
+ subject.instance_variable_set(attribute_ivar, original_val) if has_original_val
97
+ ret
98
+ end
99
+
100
+ # @return String
101
+ def expectation
102
+ "<#{@original_subject}> to have attr_writer `#{attribute}`"
103
+ end
104
+
105
+ end
106
+
107
+ end
108
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expected
4
+ # :nodoc:
5
+ module Matchers
6
+
7
+ # Used to test constants
8
+ # @param name [String, Symbol]
9
+ # @return [HaveConstantMatcher]
10
+ #
11
+ # @example Test if a constant exists
12
+ # it { is_expected.to have_constant(:FOO) }
13
+ #
14
+ # @example Test if a constant has a specific value
15
+ # it { is_expected.to have_constant(:FOO).with_value("bar") }
16
+ #
17
+ # @example Test if a constant's value is a specific type
18
+ # it { is_expected.to have_constant(:FOO).of_type(String) }
19
+ #
20
+ def have_constant(name) # rubocop:disable Naming/PredicateName
21
+ HaveConstantMatcher.new(name)
22
+ end
23
+
24
+ # Class used by {#have_constant}
25
+ class HaveConstantMatcher
26
+ attr_reader :name, :subject
27
+
28
+ # @raise If the provided name is not a {String} or {Symbol}
29
+ # @param name [String, Symbol] The name of the constant
30
+ def initialize(name)
31
+ unless name.is_a?(String) || name.is_a?(Symbol)
32
+ raise 'HaveConstantMatcher constant name must be a String or Symbol'
33
+ end
34
+ @name = name
35
+ end
36
+
37
+ # Sets the expected value of the constant
38
+ # @param value The expected value of the constant
39
+ # @return [self]
40
+ def with_value(value)
41
+ options[:value] = value
42
+ self
43
+ end
44
+
45
+ # Sets the expected type of the constant's value
46
+ # @param type [Module, Class] The expected type of the constant's value
47
+ # @return [self]
48
+ def of_type(type)
49
+ options[:type] = type
50
+ self
51
+ end
52
+
53
+ # Run the test
54
+ # @param subject The thing to test against
55
+ # @return [True] If the test passes
56
+ # @return [False] if the test fails
57
+ def matches?(subject)
58
+ self.subject = subject
59
+ constant_exists? &&
60
+ correct_type? &&
61
+ correct_value?
62
+ end
63
+
64
+ # @return [String]
65
+ def failure_message
66
+ "Expected #{expectation} (#{@failure})"
67
+ end
68
+
69
+ # @return [String]
70
+ def failure_message_when_negated
71
+ "Did not expect #{expectation}"
72
+ end
73
+
74
+ # @return [String]
75
+ def description
76
+ description = "have_constant: #{name}"
77
+ description += " of_type => #{options[:type].inspect}" if options.key? :type
78
+ description += " with_value => #{options[:value].inspect}" if options.key? :value
79
+ description
80
+ end
81
+
82
+ private
83
+
84
+ # @return [Hash]
85
+ def options
86
+ @options ||= {}.with_indifferent_access
87
+ end
88
+
89
+ # The thing to test against
90
+ # @return [Class, Module]
91
+ def subject=(subject)
92
+ @subject = subject.instance_of?(Class) || subject.is_a?(Module) ? subject : subject.class
93
+ end
94
+
95
+ # Check if the {#subject} has the constant
96
+ # @return Boolean
97
+ def constant_exists?
98
+ if subject.const_defined? name
99
+ true
100
+ else
101
+ @failure = 'missing constant'
102
+ false
103
+ end
104
+ end
105
+
106
+ # Check if the constants value is the correct type, specified from {#of_type}
107
+ # @return Boolean
108
+ def correct_type?
109
+ return true unless options.key? :type
110
+ value = subject.const_get(name)
111
+ if value.is_a? options[:type]
112
+ true
113
+ else
114
+ @failure = "type was <#{value.class}>"
115
+ false
116
+ end
117
+ end
118
+
119
+ # Check if the constants value is correct, specified from {#with_value}
120
+ # @return Boolean
121
+ def correct_value?
122
+ return true unless options.key? :value
123
+ value = subject.const_get(name)
124
+ if value == options[:value]
125
+ true
126
+ else
127
+ @failure = "value was #{value.inspect}"
128
+ false
129
+ end
130
+ end
131
+
132
+ # @return String
133
+ def expectation
134
+ expectation = "<#{subject}> to have a constant named #{name}"
135
+ expectation += " with a type of <#{options[:type]}>" if options[:type]
136
+ expectation += " with a value of #{options[:value].inspect}" if options[:value]
137
+ expectation
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expected
4
+ # :nodoc:
5
+ module Matchers
6
+
7
+ # Used to test inheritance
8
+ # @param expected_ancestor [Class]
9
+ # @return [InheritFromMatcher]
10
+ #
11
+ # @example Test if the subject inherits from the supplied Class
12
+ # it { is_expected.to inherit_from(SomeClass) }
13
+ #
14
+ def inherit_from(expected_ancestor)
15
+ InheritFromMatcher.new(expected_ancestor)
16
+ end
17
+
18
+ # Class used by {#have_constant}
19
+ class InheritFromMatcher
20
+ attr_reader :expected_ancestor, :subject
21
+
22
+ # @param expected_ancestor [Class] The ancestor the {#subject} is expected to inherit from
23
+ def initialize(expected_ancestor)
24
+ @expected_ancestor = expected_ancestor
25
+ end
26
+
27
+ # Run the test
28
+ # @param subject The thing to test against
29
+ # @return [True] If the test passes
30
+ # @return [False] if the test fails
31
+ def matches?(subject)
32
+ self.subject = subject
33
+ self.subject.ancestors.include? expected_ancestor
34
+ end
35
+
36
+ # @return [String]
37
+ def failure_message
38
+ "Expected #{expectation}"
39
+ end
40
+
41
+ # @return [String]
42
+ def failure_message_when_negated
43
+ "Did not expect #{expectation}"
44
+ end
45
+
46
+ # @return [String]
47
+ def description
48
+ "inherit_from: <#{expected_ancestor.inspect}>"
49
+ end
50
+
51
+ private
52
+
53
+ # The thing to test against
54
+ # @return [Class, Module]
55
+ def subject=(subject)
56
+ @subject = subject.instance_of?(Class) || subject.is_a?(Module) ? subject : subject.class
57
+ end
58
+
59
+ # @return String
60
+ def expectation
61
+ "<#{subject.inspect}> to inherit from <#{expected_ancestor.inspect}>"
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expected
4
+
5
+ # Contains version information
6
+ module Version
7
+ MAJOR = 1
8
+ MINOR = 0
9
+ PATCH = 0
10
+
11
+ end
12
+
13
+ VERSION = [
14
+ Version::MAJOR,
15
+ Version::MINOR,
16
+ Version::PATCH,
17
+ ].join('.').freeze
18
+
19
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: expected
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Taylor Yelverton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.0
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 5.0.0
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ description: RSpec's missing matchers
34
+ email: rubygems@yelvert.io
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - MIT-LICENSE
40
+ - README.md
41
+ - lib/expected.rb
42
+ - lib/expected/configuration.rb
43
+ - lib/expected/matchers.rb
44
+ - lib/expected/matchers/have_attr_accessor.rb
45
+ - lib/expected/matchers/have_attr_reader.rb
46
+ - lib/expected/matchers/have_attr_writer.rb
47
+ - lib/expected/matchers/have_constant.rb
48
+ - lib/expected/matchers/inherit_from.rb
49
+ - lib/expected/version.rb
50
+ homepage: https://github.com/yelvert/expected
51
+ licenses:
52
+ - MIT
53
+ metadata:
54
+ bug_tracker_uri: https://github.com/yelvert/expected/issues
55
+ changelog_uri: https://github.com/yelvert/expected/commits/master
56
+ documentation_uri: https://github.com/yelvert/expected/wiki
57
+ homepage_uri: https://github.com/yelvert/expected
58
+ source_code_uri: https://github.com/yelvert/expected
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 2.4.0
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubygems_version: 3.0.4
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: RSpec's missing matchers
78
+ test_files: []