minitest-sequel 0.3.1 → 0.4.0

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.
data/Rakefile CHANGED
@@ -1,33 +1,25 @@
1
- OSX = RUBY_PLATFORM.match(/darwin/)
1
+ # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rake/testtask"
3
+ require 'bundler/gem_tasks'
4
+ require 'rubocop/rake_task'
5
+ require 'rake/testtask'
6
+
7
+ RuboCop::RakeTask.new
5
8
 
6
9
  Rake::TestTask.new(:spec) do |t|
7
- ENV["TESTOPTS"] = "--color"
8
- t.libs << "spec"
9
- t.libs << "lib"
10
+ t.libs << 'spec'
11
+ t.libs << 'lib'
12
+ t.options = '--rg'
10
13
  t.test_files = FileList['spec/**/*_spec.rb']
11
14
  end
12
15
 
13
- task :default => :spec
14
- task :test => :spec
16
+ task default: %i[rubocop coverage]
15
17
 
16
- desc "Run specs with coverage"
17
- task :coverage do
18
- ENV["COVERAGE"] = "1"
19
- Rake::Task["spec"].invoke
20
- `open coverage/index.html` if OSX
21
- end
18
+ desc 'alias for spec task'
19
+ task test: :spec
22
20
 
23
-
24
- desc "Run Rubocop report"
25
- task :rubocop do
26
- res = `which rubocop`
27
- if res != ""
28
- `rubocop -f html -o ./rubocop/report.html lib/`
29
- `open rubocop/report.html` if OSX
30
- else
31
- puts "\nERROR: 'rubocop' gem is not installed or available. Please install with 'gem install rubocop'."
32
- end
21
+ desc 'Run specs with coverage'
22
+ task :coverage do
23
+ ENV['COVERAGE'] = '1'
24
+ Rake::Task['spec'].invoke
33
25
  end
@@ -1,182 +1,372 @@
1
- require "minitest/sequel"
2
-
3
- # reopening to add association functionality
4
- module Minitest::Assertions
5
-
6
- # Test for a :one_to_one association for the current model
7
- #
8
- # let(:m) { Post.first }
9
- #
10
- # it { assert_association_one_to_one(m, :first_comment, { class: :Comment, order: :id }) }
11
- # it { m.must_have_one_to_one_association(:first_comment, { class: :Comment, order: :id }) }
12
- #
13
- def assert_association_one_to_one(obj, attribute, opts = {}, msg = nil)
14
- assert_association(obj.class, :one_to_one, attribute, opts, msg)
15
- end
1
+ # frozen_string_literal: false
16
2
 
17
- # Test for a :one_to_many association for the current model
18
- #
19
- # let(:m) { Post.first }
20
- #
21
- # it { assert_association_one_to_many(m, :comments) }
22
- # it { m.must_have_one_to_many_association(:comments) }
23
- #
24
- def assert_association_one_to_many(obj, attribute, opts = {}, msg = nil)
25
- assert_association(obj.class, :one_to_many, attribute, opts, msg)
26
- end
3
+ require 'minitest/assertions'
4
+ require 'minitest/spec'
27
5
 
28
- # Test for a :many_to_one association for the current model
29
- #
30
- # let(:m) { Post.first }
31
- #
32
- # it { assert_association_many_to_one(m, :author) }
33
- # it { m.must_have_many_to_one_association(:author) }
34
- #
35
- def assert_association_many_to_one(obj, attribute, opts = {}, msg = nil)
36
- assert_association(obj.class, :many_to_one, attribute, opts, msg)
37
- end
6
+ # reopening to add validations functionality
7
+ module Minitest
8
+ # add support for Assert syntax
9
+ module Assertions
10
+ # Test for a :one_to_one association for the current model
11
+ #
12
+ # This method asserts that the given object has a one-to-one association
13
+ # with the specified attribute and options.
14
+ #
15
+ # @param obj [Object] The object to test the association on
16
+ # @param attribute [Symbol] The name of the association
17
+ # @param opts [Hash] Additional options for the association (default: {})
18
+ # @param msg [String] Custom error message (optional)
19
+ #
20
+ # @example Testing a one-to-one association
21
+ # let(:post) { Post.first }
22
+ #
23
+ # it "has a one-to-one association with first_comment" do
24
+ # assert_association_one_to_one(post, :first_comment, { class: :Comment, order: :id })
25
+ # end
26
+ #
27
+ # @example Using expectation syntax
28
+ # it "has a one-to-one association with first_comment" do
29
+ # post.must_have_one_to_one_association(:first_comment, { class: :Comment, order: :id })
30
+ # end
31
+ #
32
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
33
+ #
34
+ def assert_association_one_to_one(obj, attribute, opts = {}, msg = nil)
35
+ assert_association(obj.class, :one_to_one, attribute, opts, msg)
36
+ end
38
37
 
39
- # Test for a :many_to_many association for the current model
40
- #
41
- # let(:m) { Post.first }
42
- #
43
- # it { assert_association_many_to_many(m, :tags) }
44
- # it { m.must_have_many_to_many_association(:tags) }
45
- #
46
- def assert_association_many_to_many(obj, attribute, opts = {}, msg = nil)
47
- assert_association(obj.class, :many_to_many, attribute, opts, msg)
48
- end
38
+ # Test for a :one_to_many association for the current model
39
+ #
40
+ # This method asserts that the given object has a one-to-many association
41
+ # with the specified attribute and options.
42
+ #
43
+ # @param obj [Object] The object to test the association on
44
+ # @param attribute [Symbol] The name of the association
45
+ # @param opts [Hash] Additional options for the association (default: {})
46
+ # @param msg [String] Custom error message (optional)
47
+ #
48
+ # @example Testing a one-to-many association
49
+ # let(:post) { Post.first }
50
+ #
51
+ # it "has a one-to-many association with comments" do
52
+ # assert_association_one_to_many(post, :comments)
53
+ # end
54
+ #
55
+ # @example Using expectation syntax
56
+ # it "has a one-to-many association with comments" do
57
+ # post.must_have_one_to_many_association(:comments)
58
+ # end
59
+ #
60
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
61
+ #
62
+ def assert_association_one_to_many(obj, attribute, opts = {}, msg = nil)
63
+ assert_association(obj.class, :one_to_many, attribute, opts, msg)
64
+ end
49
65
 
50
- # Test for associations for the current model by passing the :association_type
51
- #
52
- # it { assert_association(Post, :many_to_many, :tags) }
53
- #
54
- def assert_association(klass, association_type, attribute, opts = {}, msg = nil)
55
- msg = msg.nil? ? "" : "#{msg}\n"
56
- msg << "Expected #{klass.inspect} to have a #{association_type.inspect}"
57
- msg << " association #{attribute.inspect}"
58
- assoc = klass.association_reflection(attribute) || {}
59
- if assoc.empty?
60
- msg << " but no association '#{attribute.inspect}' was found"
61
- arr = []
62
- klass.associations.each do |a|
63
- o = klass.association_reflection(a)
64
- if o[:type] == :many_to_many
65
- arr << {
66
- attribute: o[:name],
67
- type: o[:type],
68
- class: o[:class_name].to_s,
69
- join_table: o[:join_table],
70
- left_keys: o[:left_keys],
71
- right_keys: o[:right_keys]
72
- }
73
- else
74
- arr << {
75
- attribute: o[:name],
76
- type: o[:type],
77
- class: o[:class_name].to_s,
78
- keys: o[:keys]
79
- }
80
- end
81
- end
82
- msg << " - \navailable associations are: [ #{arr.join(', ')} ]\n"
83
- assert(false, msg)
84
- else
85
- matching = assoc[:type] == association_type
86
- err_msg = []
87
- conf_msg = []
88
- opts.each do |key, value|
89
- conf_msg << { key => value }
90
- if assoc[key] != value
91
- err_msg << { key => assoc[key].to_s }
92
- matching = false
93
- end
94
- end
95
- msg << " with given options: #{conf_msg.join(', ')} but should be #{err_msg.join(', ')}"
96
- assert(matching, msg)
66
+ # Test for a :many_to_one association for the current model
67
+ #
68
+ # This method asserts that the given object has a many-to-one association
69
+ # with the specified attribute and options.
70
+ #
71
+ # @param obj [Object] The object to test the association on
72
+ # @param attribute [Symbol] The name of the association
73
+ # @param opts [Hash] Additional options for the association (default: {})
74
+ # @param msg [String] Custom error message (optional)
75
+ #
76
+ # @example Testing a many-to-one association
77
+ # let(:comment) { Comment.first }
78
+ #
79
+ # it "has a many-to-one association with post" do
80
+ # assert_association_many_to_one(comment, :post)
81
+ # end
82
+ #
83
+ # @example Using expectation syntax
84
+ # it "has a many-to-one association with post" do
85
+ # comment.must_have_many_to_one_association(:post)
86
+ # end
87
+ #
88
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
89
+ #
90
+ def assert_association_many_to_one(obj, attribute, opts = {}, msg = nil)
91
+ assert_association(obj.class, :many_to_one, attribute, opts, msg)
97
92
  end
98
- end
99
93
 
94
+ # Test for a :many_to_many association for the current model
95
+ #
96
+ # This method asserts that the given object has a many-to-many association
97
+ # with the specified attribute and options.
98
+ #
99
+ # @param obj [Object] The object to test the association on
100
+ # @param attribute [Symbol] The name of the association
101
+ # @param opts [Hash] Additional options for the association (default: {})
102
+ # @param msg [String] Custom error message (optional)
103
+ #
104
+ # @example Testing a many-to-many association
105
+ # let(:post) { Post.first }
106
+ #
107
+ # it "has a many-to-many association with tags" do
108
+ # assert_association_many_to_many(post, :tags)
109
+ # end
110
+ #
111
+ # @example Using expectation syntax
112
+ # it "has a many-to-many association with tags" do
113
+ # post.must_have_many_to_many_association(:tags)
114
+ # end
115
+ #
116
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
117
+ #
118
+ def assert_association_many_to_many(obj, attribute, opts = {}, msg = nil)
119
+ assert_association(obj.class, :many_to_many, attribute, opts, msg)
120
+ end
100
121
 
101
- # Test to ensure there is no :one_to_one association for the current model
102
- #
103
- # let(:m) { Post.first }
104
- #
105
- # it { refute_association_one_to_one(m, :first_comment, { class: :Comment, order: :id }) }
106
- # it { m.must_have_one_to_one_association(:first_comment, { class: :Comment, order: :id }) }
107
- #
108
- def refute_association_one_to_one(obj, attribute, msg = nil)
109
- refute_association(obj.class, :one_to_one, attribute, msg)
110
- end
122
+ # Test for associations for the current model by passing the :association_type
123
+ #
124
+ # This method asserts that the given class has an association of the specified type
125
+ # with the given attribute and options.
126
+ #
127
+ # @param klass [Class] The class to test the association on
128
+ # @param association_type [Symbol] The type of association to check for (e.g., :many_to_many)
129
+ # @param attribute [Symbol] The name of the association
130
+ # @param opts [Hash] Additional options for the association (default: {})
131
+ # @param msg [String] Custom error message (optional)
132
+ #
133
+ # @example Testing a many-to-many association
134
+ # it "has a many-to-many association with tags" do
135
+ # assert_association(Post, :many_to_many, :tags)
136
+ # end
137
+ #
138
+ # @example Testing an association with options
139
+ # it "has a one-to-many association with comments" do
140
+ # assert_association(Post, :one_to_many, :comments, { class: 'Comment', key: :post_id })
141
+ # end
142
+ #
143
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
144
+ #
145
+ # rubocop:disable Metrics/*
146
+ def assert_association(klass, association_type, attribute, opts = {}, msg = nil)
147
+ # Initialize error message
148
+ msg = msg.nil? ? '' : "#{msg}\n"
149
+ msg << "Expected #{klass} to have a #{association_type.inspect}"
150
+ msg << " association #{attribute.inspect}"
111
151
 
112
- # Test to ensure there is no :one_to_many association for the current model
113
- #
114
- # let(:m) { Post.first }
115
- #
116
- # it { refute_association_one_to_many(m, :comments) }
117
- # it { m.must_have_one_to_many_association(:comments) }
118
- #
119
- def refute_association_one_to_many(obj, attribute, msg = nil)
120
- refute_association(obj.class, :one_to_many, attribute, msg)
121
- end
152
+ # Get association reflection or empty hash if not found
153
+ assoc = klass.association_reflection(attribute) || {}
122
154
 
123
- # Test to ensure there is no :many_to_one association for the current model
124
- #
125
- # let(:m) { Post.first }
126
- #
127
- # it { refute_association_many_to_one(m, :author) }
128
- # it { m.must_have_many_to_one_association(:author) }
129
- #
130
- def refute_association_many_to_one(obj, attribute, msg = nil)
131
- refute_association(obj.class, :many_to_one, attribute, msg)
132
- end
155
+ if assoc.empty?
156
+ # Association not found, prepare error message with available associations
157
+ msg << ", but no association '#{attribute.inspect}' was found"
158
+ arr = []
159
+ klass.associations.each do |a|
160
+ o = klass.association_reflection(a)
161
+ arr << if o[:type] == :many_to_many
162
+ # Prepare info for many-to-many association
163
+ {
164
+ attribute: o[:name],
165
+ type: o[:type],
166
+ class: o[:class_name].to_s,
167
+ join_table: o[:join_table],
168
+ left_keys: o[:left_keys],
169
+ right_keys: o[:right_keys]
170
+ }
171
+ else
172
+ # Prepare info for other association types
173
+ {
174
+ attribute: o[:name],
175
+ type: o[:type],
176
+ class: o[:class_name].to_s,
177
+ keys: o[:keys]
178
+ }
179
+ end
180
+ end
181
+ # /klass.associations.each
133
182
 
134
- # Test to ensure there is no :many_to_many association for the current model
135
- #
136
- # let(:m) { Post.first }
137
- #
138
- # it { refute_association_many_to_many(m, :tags) }
139
- # it { m.must_have_many_to_many_association(:tags) }
140
- #
141
- def refute_association_many_to_many(obj, attribute, msg = nil)
142
- refute_association(obj.class, :many_to_many, attribute, msg)
143
- end
183
+ msg << " - \navailable associations are: [ #{arr.join(', ')} ]\n"
184
+ assert(false, msg)
185
+ else
186
+ # Association found, check if it matches the expected type
187
+ matching = assoc[:type] == association_type
188
+ err_msg = []
189
+ conf_msg = []
190
+
191
+ # Check each option against the association
192
+ opts.each do |key, value|
193
+ conf_msg << { key => value }
194
+ if assoc[key] != value
195
+ err_msg << { key => assoc[key].to_s }
196
+ matching = false
197
+ end
198
+ end
199
+
200
+ # Prepare error message with mismatched options
201
+ msg << " with given options: #{conf_msg.join(', ')} but should be #{err_msg.join(', ')}"
202
+ assert(matching, msg)
203
+ end
204
+ end
205
+ # rubocop:enable Metrics/*
144
206
 
145
- # Test to ensure the current model does NOT have an association by type :association_type
146
- #
147
- # it { refute_association(Post, :many_to_many, :tags) }
148
- #
149
- def refute_association(klass, association_type, attribute, msg = nil)
150
- msg = msg.nil? ? "" : "#{msg}\n"
151
- msg << "Expected #{klass.inspect} to NOT have a #{association_type.inspect}"
152
- msg << " association #{attribute.inspect}"
153
- assoc = klass.association_reflection(attribute) || {}
154
-
155
- if assoc.empty?
156
- assert(true, msg)
157
- else
158
- matching = false if assoc[:type] == association_type
159
- msg << ", but such an association was found"
160
- assert(matching, msg)
207
+ # Test to ensure there is no :one_to_one association for the current model
208
+ #
209
+ # This method asserts that the given object does not have a one-to-one association
210
+ # with the specified attribute.
211
+ #
212
+ # @param obj [Object] The object to test the association on
213
+ # @param attribute [Symbol] The name of the association
214
+ # @param msg [String] Custom error message (optional)
215
+ #
216
+ # @example Testing that an object does not have a one-to-one association
217
+ # let(:post) { Post.first }
218
+ #
219
+ # it "does not have a one-to-one association with first_comment" do
220
+ # refute_association_one_to_one(post, :first_comment)
221
+ # end
222
+ #
223
+ # @example Using expectation syntax
224
+ # it "does not have a one-to-one association with first_comment" do
225
+ # post.wont_have_one_to_one_association(:first_comment)
226
+ # end
227
+ #
228
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
229
+ #
230
+ def refute_association_one_to_one(obj, attribute, msg = nil)
231
+ refute_association(obj.class, :one_to_one, attribute, msg)
161
232
  end
162
- end
163
233
 
164
- end
234
+ # Test to ensure there is no :one_to_many association for the current model
235
+ #
236
+ # This method asserts that the given object does not have a one-to-many association
237
+ # with the specified attribute.
238
+ #
239
+ # @param obj [Object] The object to test the association on
240
+ # @param attribute [Symbol] The name of the association
241
+ # @param msg [String] Custom error message (optional)
242
+ #
243
+ # @example Testing that an object does not have a one-to-many association
244
+ # let(:post) { Post.first }
245
+ #
246
+ # it "does not have a one-to-many association with comments" do
247
+ # refute_association_one_to_many(post, :comments)
248
+ # end
249
+ #
250
+ # @example Using expectation syntax
251
+ # it "does not have a one-to-many association with comments" do
252
+ # post.wont_have_one_to_many_association(:comments)
253
+ # end
254
+ #
255
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
256
+ #
257
+ def refute_association_one_to_many(obj, attribute, msg = nil)
258
+ refute_association(obj.class, :one_to_many, attribute, msg)
259
+ end
260
+
261
+ # Test to ensure there is no :many_to_one association for the current model
262
+ #
263
+ # This method asserts that the given object does not have a many-to-one association
264
+ # with the specified attribute.
265
+ #
266
+ # @param obj [Object] The object to test the association on
267
+ # @param attribute [Symbol] The name of the association
268
+ # @param msg [String] Custom error message (optional)
269
+ #
270
+ # @example Testing that an object does not have a many-to-one association
271
+ # let(:comment) { Comment.first }
272
+ #
273
+ # it "does not have a many-to-one association with post" do
274
+ # refute_association_many_to_one(comment, :post)
275
+ # end
276
+ #
277
+ # @example Using expectation syntax
278
+ # it "does not have a many-to-one association with post" do
279
+ # comment.wont_have_many_to_one_association(:post)
280
+ # end
281
+ #
282
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
283
+ #
284
+ def refute_association_many_to_one(obj, attribute, msg = nil)
285
+ refute_association(obj.class, :many_to_one, attribute, msg)
286
+ end
165
287
 
288
+ # Test to ensure there is no :many_to_many association for the current model
289
+ #
290
+ # This method asserts that the given object does not have a many-to-many association
291
+ # with the specified attribute.
292
+ #
293
+ # @param obj [Object] The object to test the association on
294
+ # @param attribute [Symbol] The name of the association
295
+ # @param msg [String] Custom error message (optional)
296
+ #
297
+ # @example Testing that an object does not have a many-to-many association
298
+ # let(:post) { Post.first }
299
+ #
300
+ # it "does not have a many-to-many association with tags" do
301
+ # refute_association_many_to_many(post, :tags)
302
+ # end
303
+ #
304
+ # @example Using expectation syntax
305
+ # it "does not have a many-to-many association with tags" do
306
+ # post.wont_have_many_to_many_association(:tags)
307
+ # end
308
+ #
309
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
310
+ #
311
+ def refute_association_many_to_many(obj, attribute, msg = nil)
312
+ refute_association(obj.class, :many_to_many, attribute, msg)
313
+ end
166
314
 
167
- # add support for Spec syntax
168
- module Minitest::Expectations
315
+ # Test to ensure the current model does NOT have an association by type :association_type
316
+ #
317
+ # This method asserts that the given class does not have an association of the specified type
318
+ # with the given attribute.
319
+ #
320
+ # @param klass [Class] The class to test the association on
321
+ # @param association_type [Symbol] The type of association to check for (e.g., :many_to_many)
322
+ # @param attribute [Symbol] The name of the association
323
+ # @param msg [String] Custom error message (optional)
324
+ #
325
+ # @example Testing that a class does not have a many-to-many association
326
+ # it "does not have a many-to-many association with tags" do
327
+ # refute_association(Post, :many_to_many, :tags)
328
+ # end
329
+ #
330
+ # @example Using expectation syntax
331
+ # it "does not have a many-to-many association with tags" do
332
+ # Post.wont_have_association(:many_to_many, :tags)
333
+ # end
334
+ #
335
+ # @return [Boolean] true if the assertion passes, raises an error otherwise
336
+ #
337
+ # rubocop:disable Metrics/MethodLength
338
+ def refute_association(klass, association_type, attribute, msg = nil)
339
+ msg = msg.nil? ? '' : "#{msg}\n"
340
+ msg << "Expected #{klass.inspect} to NOT have a #{association_type.inspect}"
341
+ msg << " association #{attribute.inspect}"
342
+ assoc = klass.association_reflection(attribute) || {}
169
343
 
170
- infect_an_assertion :assert_association, :must_have_association, :reverse
171
- infect_an_assertion :assert_association_one_to_one, :must_have_one_to_one_association, :reverse
172
- infect_an_assertion :assert_association_one_to_many, :must_have_one_to_many_association, :reverse
173
- infect_an_assertion :assert_association_many_to_one, :must_have_many_to_one_association, :reverse
174
- infect_an_assertion :assert_association_many_to_many, :must_have_many_to_many_association, :reverse
344
+ if assoc.empty?
345
+ assert(true, msg)
346
+ else
347
+ matching = false if assoc[:type] == association_type
348
+ msg << ', but such an association was found'
349
+ assert(matching, msg)
350
+ end
351
+ end
352
+ # rubocop:enable Metrics/MethodLength
353
+ end
354
+ # /module Assertions
175
355
 
176
- infect_an_assertion :refute_association, :wont_have_association, :reverse
177
- infect_an_assertion :refute_association_one_to_one, :wont_have_one_to_one_association, :reverse
178
- infect_an_assertion :refute_association_one_to_many, :wont_have_one_to_many_association, :reverse
179
- infect_an_assertion :refute_association_many_to_one, :wont_have_many_to_one_association, :reverse
180
- infect_an_assertion :refute_association_many_to_many, :wont_have_many_to_many_association, :reverse
356
+ # add support for Spec syntax
357
+ # rubocop:disable Layout/LineLength
358
+ module Expectations
359
+ infect_an_assertion :assert_association, :must_have_association, :reverse
360
+ infect_an_assertion :assert_association_one_to_one, :must_have_one_to_one_association, :reverse
361
+ infect_an_assertion :assert_association_one_to_many, :must_have_one_to_many_association, :reverse
362
+ infect_an_assertion :assert_association_many_to_one, :must_have_many_to_one_association, :reverse
363
+ infect_an_assertion :assert_association_many_to_many, :must_have_many_to_many_association, :reverse
181
364
 
365
+ infect_an_assertion :refute_association, :wont_have_association, :reverse
366
+ infect_an_assertion :refute_association_one_to_one, :wont_have_one_to_one_association, :reverse
367
+ infect_an_assertion :refute_association_one_to_many, :wont_have_one_to_many_association, :reverse
368
+ infect_an_assertion :refute_association_many_to_one, :wont_have_many_to_one_association, :reverse
369
+ infect_an_assertion :refute_association_many_to_many, :wont_have_many_to_many_association, :reverse
370
+ end
371
+ # rubocop:enable Layout/LineLength
182
372
  end