minitest-sequel 0.3.2 → 0.4.0

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