nobrainer-rspec 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NoBrainer
4
+ module Matchers
5
+ module Validations
6
+ class ValidateLengthOfMatcher < HaveValidationMatcher
7
+ def initialize(name)
8
+ super(name, :length)
9
+ end
10
+
11
+ def with_maximum(value)
12
+ @maximum = value
13
+ self
14
+ end
15
+ alias less_than with_maximum
16
+
17
+ def with_minimum(value)
18
+ @minimum = value
19
+ self
20
+ end
21
+ alias greater_than with_minimum
22
+
23
+ def within(value)
24
+ @within = value
25
+ self
26
+ end
27
+ alias in within
28
+
29
+ def as_exactly(value)
30
+ @is = value
31
+ self
32
+ end
33
+ alias is as_exactly
34
+
35
+ def matches?(actual)
36
+ return false unless @result = super(actual)
37
+
38
+ check_maximum if @maximum
39
+ check_minimum if @minimum
40
+ check_range if @within
41
+ check_exact if @is
42
+
43
+ @result
44
+ end
45
+
46
+ def description
47
+ options_desc = []
48
+ options_desc << "with minimum of #{@minimum}" if @minimum
49
+ options_desc << "with maximum of #{@maximum}" if @maximum
50
+ options_desc << "within the range of #{@within}" if @within
51
+ options_desc << "as exactly #{@is}" if @is
52
+ "#{super} #{options_desc.to_sentence}"
53
+ end
54
+
55
+ private
56
+
57
+ def check_maximum
58
+ if actual_max.nil?
59
+ @negative_result_message += ' with no maximum'
60
+ @result = false
61
+ elsif actual_max == @maximum
62
+ @positive_result_message += " with maximum of #{@maximum}"
63
+ else
64
+ @negative_result_message += " with maximum of #{actual_max}"
65
+ @result = false
66
+ end
67
+ end
68
+
69
+ def check_minimum
70
+ if actual_min.nil?
71
+ @negative_result_message += ' with no minimum'
72
+ @result = false
73
+ elsif actual_min == @minimum
74
+ @positive_result_message += " with minimum of #{@minimum}"
75
+ else
76
+ @negative_result_message += " with minimum of #{actual_min}"
77
+ @result = false
78
+ end
79
+ end
80
+
81
+ def check_range
82
+ min, max = @within.minmax
83
+ if !actual_min.nil? && actual_max.nil?
84
+ @negative_result_message += " with no minimum but with maximum of #{actual_max}"
85
+ @result = false
86
+ elsif actual_min.nil? && !actual_max.nil?
87
+ @negative_result_message += " with minimum_of #{actual_min} but no maximum"
88
+ @result = false
89
+ elsif actual_min.nil? && actual_max.nil?
90
+ @negative_result_message += ' with no minimum and maximum'
91
+ @result = false
92
+ elsif actual_min == min && actual_max == max
93
+ @positive_result_message += " within the range of #{@within.inspect}"
94
+ else
95
+ @negative_result_message += " within the range of #{(actual_min..actual_max).inspect}"
96
+ @result = false
97
+ end
98
+ end
99
+
100
+ def check_exact
101
+ if actual_is == @is
102
+ @positive_result_message += " as exactly #{@is}"
103
+ else
104
+ @negative_result_message += " as exactly #{actual_is}"
105
+ @result = false
106
+ end
107
+ end
108
+
109
+ def actual_is
110
+ actual_is = @validator.options[:is]
111
+ end
112
+
113
+ def actual_min
114
+ @validator.options[:minimum] || (@validator.options[:in] || @validator.options[:within]).try(&:min)
115
+ end
116
+
117
+ def actual_max
118
+ @validator.options[:maximum] || (@validator.options[:in] || @validator.options[:within]).try(&:max)
119
+ end
120
+ end
121
+
122
+ def validate_length_of(field)
123
+ ValidateLengthOfMatcher.new(field)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NoBrainer
4
+ module Matchers
5
+ module Validations
6
+ class ValidateNumericalityOfMatcher < HaveValidationMatcher
7
+ ALLOWED_OPTIONS =
8
+ %i[
9
+ allow_nil
10
+ equal_to
11
+ even
12
+ greater_than
13
+ greater_than_or_equal_to
14
+ less_than
15
+ less_than_or_equal_to
16
+ nil
17
+ odd
18
+ only_integer
19
+ ].freeze
20
+
21
+ def initialize(field)
22
+ super(field, :numericality)
23
+ @options = {}
24
+ end
25
+
26
+ def to_allow(options)
27
+ options[:equal_to] = options if options.is_a?(Numeric)
28
+ options[:allow_nil] = options.delete(:nil) if options.key?(:nil)
29
+
30
+ if !options.is_a?(Hash) || options.empty? || (options.keys - ALLOWED_OPTIONS).any?
31
+ message =
32
+ 'validate_numericality_of#to_allow requires a Hash parameter containing' \
33
+ "any of the following keys: #{ALLOWED_OPTIONS.map(&:inspect).join(', ')}"
34
+ raise ArgumentError, message
35
+ end
36
+
37
+ @options.merge!(options)
38
+ self
39
+ end
40
+
41
+ def matches?(actual)
42
+ return false unless result = super(actual)
43
+
44
+ @options.each do |comparator, expected_value|
45
+ result &= (@validator.options[comparator] == expected_value)
46
+ end
47
+
48
+ @positive_result_message += options_message(@validator.options)
49
+ @negative_result_message += options_message(@validator.options)
50
+ result
51
+ end
52
+
53
+ def description
54
+ "#{super}#{options_message(@options)}"
55
+ end
56
+
57
+ protected
58
+
59
+ def options_message(options)
60
+ type_msg = []
61
+ comp_msg = []
62
+ options.each_pair do |key, value|
63
+ case key
64
+ when :allow_nil
65
+ when :only_integer
66
+ type_msg << 'integer' if value
67
+ when :odd, :even
68
+ type_msg << "#{key}-numbered" if value
69
+ else
70
+ comp_msg << "#{key.to_s.tr('_', ' ')} #{value.inspect}"
71
+ end
72
+ end
73
+ allow_nil = (options[:allow_nil] ? 'nil' : 'non-nil') if options.key?(:allow_nil)
74
+ ['', 'allowing', allow_nil, type_msg.any? ? type_msg.to_sentence : nil, 'values', comp_msg.any? ? comp_msg.to_sentence : nil].compact.join(' ')
75
+ end
76
+
77
+ def method_missing(m, *args, &block)
78
+ if ALLOWED_OPTIONS.include?(m.to_sym)
79
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 1)" if args.length > 1
80
+ send :to_allow, m.to_sym => args.first
81
+ else
82
+ super
83
+ end
84
+ end
85
+ end
86
+
87
+ def validate_numericality_of(field)
88
+ ValidateNumericalityOfMatcher.new(field)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NoBrainer
4
+ module Matchers
5
+ module Validations
6
+ def validate_presence_of(field)
7
+ HaveValidationMatcher.new(field, :presence)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NoBrainer
4
+ module Matchers
5
+ module Validations
6
+ class ValidateUniquenessOfMatcher < HaveValidationMatcher
7
+ def initialize(field)
8
+ super(field, :uniqueness)
9
+ end
10
+
11
+ def scoped_to(*scope)
12
+ @scope = [scope].flatten.map(&:to_sym)
13
+ self
14
+ end
15
+ alias scoped_on scoped_to
16
+
17
+ def matches?(actual)
18
+ return false unless @result = super(actual)
19
+
20
+ check_scope if @scope
21
+
22
+ @result
23
+ end
24
+
25
+ def description
26
+ options_desc = []
27
+ options_desc << " scoped to #{@scope.inspect}" if @scope
28
+ "#{super}#{options_desc.to_sentence}"
29
+ end
30
+
31
+ private
32
+
33
+ def check_scope
34
+ message = " scope to #{@validator.options[:scope]}"
35
+ if @validator.options[:scope]
36
+ if [@validator.options[:scope] || ''].flatten.map(&:to_sym) == @scope
37
+ @positive_result_message += message
38
+ else
39
+ @negative_result_message += message
40
+ end
41
+ else
42
+ @negative_result_message += ' without a scope'
43
+ @result = false
44
+ end
45
+ end
46
+ end
47
+
48
+ def validate_uniqueness_of(field)
49
+ ValidateUniquenessOfMatcher.new(field)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1 @@
1
+ require 'nobrainer/rspec'
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+
5
+ require 'nobrainer'
6
+ require 'rspec/core'
7
+ require 'rspec/expectations'
8
+ require 'rspec/mocks'
9
+
10
+ require 'matchers/associations'
11
+ require 'matchers/be_nobrainer_document'
12
+ require 'matchers/have_field'
13
+ require 'matchers/have_index_for'
14
+ require 'matchers/have_timestamps'
15
+ require 'matchers/validations'
16
+ require 'matchers/validations/acceptance_of'
17
+ require 'matchers/validations/confirmation_of'
18
+ require 'matchers/validations/exclusion_of'
19
+ require 'matchers/validations/format_of'
20
+ require 'matchers/validations/inclusion_of'
21
+ require 'matchers/validations/length_of'
22
+ require 'matchers/validations/numericality_of'
23
+ require 'matchers/validations/presence_of'
24
+ require 'matchers/validations/uniqueness_of'
25
+
26
+ module NoBrainer
27
+ module Matchers
28
+ include NoBrainer::Matchers::Associations
29
+ include NoBrainer::Matchers::Validations
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NoBrainer
4
+ module RSpec
5
+ VERSION = '1.0.1'
6
+ end
7
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
4
+
5
+ require 'nobrainer/rspec/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'nobrainer-rspec'
9
+ spec.version = NoBrainer::RSpec::VERSION
10
+ spec.platform = Gem::Platform::RUBY
11
+ spec.authors = ['Guillaume Hain']
12
+ spec.email = ['zedtux@zedroot.org']
13
+ spec.homepage = 'https://gitlab.com/zedtux/nobrainer-rspec'
14
+ spec.summary = 'RSpec matchers for Nobrainer'
15
+ spec.description = 'RSpec matches for Nobrainer models, including ' \
16
+ 'association and validation matchers.'
17
+ spec.license = 'MIT'
18
+
19
+ spec.required_ruby_version = '>= 2.2'
20
+
21
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
22
+ spec.metadata['homepage_uri'] = spec.homepage
23
+ spec.metadata['source_code_uri'] = spec.homepage
24
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/-/blob/master/CHANGELOG.md"
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{
28
+ ^(test|spec|features)/|
29
+ \.gitlab-ci.yml|
30
+ \.rspec|
31
+ \.gitignore|
32
+ Earthfile|
33
+ Dockerfile|
34
+ docker-compose.yml
35
+ }x)
36
+ end
37
+ spec.bindir = 'exe'
38
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
39
+ spec.require_paths = ['lib']
40
+
41
+ spec.add_dependency 'nobrainer'
42
+ spec.add_dependency 'rspec-core', '~> 3.3'
43
+ spec.add_dependency 'rspec-expectations', '~> 3.3'
44
+ spec.add_dependency 'rspec-mocks', '~> 3.3'
45
+ spec.add_development_dependency 'appraisal', '~> 2.2'
46
+ spec.add_development_dependency 'rake', '~> 10.0'
47
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nobrainer-rspec
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Guillaume Hain
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nobrainer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-expectations
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-mocks
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: appraisal
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ description: RSpec matches for Nobrainer models, including association and validation
98
+ matchers.
99
+ email:
100
+ - zedtux@zedroot.org
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - CHANGELOG.md
106
+ - Gemfile
107
+ - LICENSE
108
+ - README.md
109
+ - Rakefile
110
+ - bin/console
111
+ - bin/setup
112
+ - lib/matchers/associations.rb
113
+ - lib/matchers/be_nobrainer_document.rb
114
+ - lib/matchers/have_field.rb
115
+ - lib/matchers/have_index_for.rb
116
+ - lib/matchers/have_timestamps.rb
117
+ - lib/matchers/validations.rb
118
+ - lib/matchers/validations/acceptance_of.rb
119
+ - lib/matchers/validations/confirmation_of.rb
120
+ - lib/matchers/validations/exclusion_of.rb
121
+ - lib/matchers/validations/format_of.rb
122
+ - lib/matchers/validations/inclusion_of.rb
123
+ - lib/matchers/validations/length_of.rb
124
+ - lib/matchers/validations/numericality_of.rb
125
+ - lib/matchers/validations/presence_of.rb
126
+ - lib/matchers/validations/uniqueness_of.rb
127
+ - lib/nobrainer-rspec.rb
128
+ - lib/nobrainer/rspec.rb
129
+ - lib/nobrainer/rspec/version.rb
130
+ - nobrainer-rspec.gemspec
131
+ homepage: https://gitlab.com/zedtux/nobrainer-rspec
132
+ licenses:
133
+ - MIT
134
+ metadata:
135
+ allowed_push_host: https://rubygems.org
136
+ homepage_uri: https://gitlab.com/zedtux/nobrainer-rspec
137
+ source_code_uri: https://gitlab.com/zedtux/nobrainer-rspec
138
+ changelog_uri: https://gitlab.com/zedtux/nobrainer-rspec/-/blob/master/CHANGELOG.md
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '2.2'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubygems_version: 3.1.4
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: RSpec matchers for Nobrainer
158
+ test_files: []