nobrainer-rspec 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []