fun_with_testing 0.0.4 → 0.0.10
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.
- checksums.yaml +5 -13
- data/CHANGELOG.markdown +38 -0
- data/Gemfile +33 -11
- data/README.rdoc +3 -6
- data/Rakefile +38 -17
- data/VERSION +1 -1
- data/lib/fun_with/testing/assertions/basics.rb +250 -138
- data/lib/fun_with/testing/assertions_test_case.rb +67 -0
- data/lib/fun_with/testing/assertions_test_mocker.rb +15 -0
- data/lib/fun_with/testing/test_case.rb +1 -71
- data/lib/fun_with/testing/test_case_extensions.rb +47 -0
- data/lib/fun_with/testing/verbosity_methods.rb +33 -0
- data/lib/fun_with_testing.rb +16 -18
- data/test/helper.rb +3 -37
- data/test/test_assertions.rb +609 -14
- data/test/test_fun_with_testing.rb +3 -7
- data/test/test_verbosity.rb +2 -1
- metadata +19 -134
- data/lib/fun_with/testing/assertions/active_record.rb +0 -108
- data/lib/fun_with/testing/assertions/fun_with_files.rb +0 -109
- data/test/test_test_mode.rb +0 -28
|
@@ -1,200 +1,312 @@
|
|
|
1
|
+
# A namespace module that acts as an umbrella for a
|
|
2
|
+
# collection of gems I'm maintaining. (rdoc)
|
|
3
|
+
#
|
|
4
|
+
# I seem to be trying to write an entire ecosystem
|
|
5
|
+
# single-handed. It's not going well.
|
|
1
6
|
module FunWith
|
|
7
|
+
|
|
8
|
+
# A gem that adds a collection of custom assertions to a test suite.
|
|
9
|
+
#
|
|
10
|
+
# Also includes some infrastructure for testing the assertions themselves.
|
|
11
|
+
#
|
|
12
|
+
# Other FunWith- gems will contain extensions with their own custom assertions.
|
|
13
|
+
# For example, FunWith::Files adds in things like `assert_directory()`, etc.
|
|
2
14
|
module Testing
|
|
15
|
+
|
|
16
|
+
# Modules full of custom assertions should go under this namespace.
|
|
3
17
|
module Assertions
|
|
4
18
|
module Basics
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
19
|
+
# Interesting thing about message() : returns a proc that, when called, returns
|
|
20
|
+
# the message string. I don't quite understand why it's done that way, but
|
|
21
|
+
# to add a line to an existing msg proc, do `msg = message(msg){"line to add..."}`
|
|
22
|
+
|
|
23
|
+
def assert_not_zero( actual, msg = nil )
|
|
24
|
+
msg = message(msg) { "Expected #{mu_pp(actual)} to not be zero" }
|
|
25
|
+
assert actual != 0, msg
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
alias :refute_zero :assert_not_zero
|
|
29
|
+
|
|
30
|
+
def assert_zero( actual, msg = nil )
|
|
31
|
+
msg = message(msg) { "should be zero, not <#{mu_pp(actual)}>" }
|
|
32
|
+
assert actual == 0, msg
|
|
11
33
|
end
|
|
12
34
|
|
|
13
|
-
def
|
|
14
|
-
|
|
35
|
+
def assert_one( actual, msg = nil )
|
|
36
|
+
msg = message(msg) { "should be 1, not <#{mu_pp(actual)}>" }
|
|
37
|
+
assert actual == 1, msg
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def assert_not_one( actual, msg = nil )
|
|
41
|
+
msg = message(msg) { "should be 1, not <#{mu_pp(actual)}>" }
|
|
42
|
+
assert actual != 1, msg
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
alias :refute_one :assert_not_one
|
|
46
|
+
|
|
47
|
+
def assert_negative( actual, msg = nil )
|
|
48
|
+
msg = message(msg) { "should be negative, not <#{mu_pp(actual)}>" }
|
|
49
|
+
assert actual < 0, msg
|
|
50
|
+
end
|
|
15
51
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
52
|
+
def assert_not_negative( actual, msg = nil )
|
|
53
|
+
msg = message(msg) { "should NOT be negative, (actual) <#{mu_pp(actual)}>" }
|
|
54
|
+
assert actual >= 0, msg
|
|
19
55
|
end
|
|
56
|
+
|
|
57
|
+
alias :refute_negative :assert_not_negative
|
|
20
58
|
|
|
21
|
-
def
|
|
22
|
-
|
|
59
|
+
def assert_positive( actual, msg = nil )
|
|
60
|
+
msg = message(msg) { "should be positive, not <#{mu_pp(actual)}>" }
|
|
61
|
+
assert actual > 0, msg
|
|
62
|
+
end
|
|
23
63
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
64
|
+
def assert_not_positive( actual, msg = nil )
|
|
65
|
+
msg = message(msg) { "should NOT be positive, (actual) <#{mu_pp(actual)}>" }
|
|
66
|
+
assert actual <= 0, msg
|
|
27
67
|
end
|
|
28
68
|
|
|
29
|
-
|
|
30
|
-
message = build_message(message, "should be negative, not <#{actual}>")
|
|
69
|
+
alias :refute_positive :assert_not_positive
|
|
31
70
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
71
|
+
def assert_true( actual, msg = nil )
|
|
72
|
+
msg = message(msg) { "should be true (TrueClass), not <#{mu_pp(actual)}>" }
|
|
73
|
+
assert actual == true, msg
|
|
35
74
|
end
|
|
36
75
|
|
|
37
|
-
def
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
76
|
+
def refute_true( actual, msg = nil )
|
|
77
|
+
msg = message(msg) { "shouldn't be true (TrueClass)" }
|
|
78
|
+
assert actual != true, msg
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# rejects anything but an actual false, instance of the FalseClass
|
|
82
|
+
def assert_false( actual, msg = nil )
|
|
83
|
+
msg = message(msg) { "should be false (instance of FalseClass), not <#{mu_pp(actual)}>" }
|
|
84
|
+
assert actual == false, msg
|
|
42
85
|
end
|
|
43
86
|
|
|
44
|
-
def
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
actual == false
|
|
48
|
-
end
|
|
87
|
+
def refute_false( actual, msg = nil )
|
|
88
|
+
msg = message(msg) { "shouldn't be false" }
|
|
89
|
+
assert actual != false, msg
|
|
49
90
|
end
|
|
50
91
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
safe_assert_block message do
|
|
55
|
-
actual == nil
|
|
56
|
-
end
|
|
92
|
+
def assert_nil( actual, msg = nil )
|
|
93
|
+
msg = message(msg) { "should be nil, not <#{mu_pp(actual)}>" }
|
|
94
|
+
assert actual == nil, msg
|
|
57
95
|
end
|
|
58
96
|
|
|
59
|
-
def assert_not_nil( actual,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
actual != nil
|
|
63
|
-
end
|
|
97
|
+
def assert_not_nil( actual, msg = nil )
|
|
98
|
+
msg = message(msg) { "should not be nil" }
|
|
99
|
+
assert actual != nil, msg
|
|
64
100
|
end
|
|
65
101
|
|
|
66
102
|
alias :refute_nil :assert_not_nil
|
|
67
103
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
full_message = build_message(message, "<?> does not respond to :blank? method.", obj)
|
|
73
|
-
end
|
|
104
|
+
def assert_responds_to_blank( obj, message = nil )
|
|
105
|
+
msg = message(msg){
|
|
106
|
+
"<#{mu_pp(obj)}> does not respond to :blank? or :fwf_blank? methods."
|
|
107
|
+
}
|
|
74
108
|
|
|
75
|
-
|
|
76
|
-
obj.respond_to?(:blank?) && obj.blank?
|
|
77
|
-
end
|
|
109
|
+
assert obj.respond_to?(:blank?) || obj.respond_to?( :fwf_blank? ), msg
|
|
78
110
|
end
|
|
79
|
-
|
|
80
|
-
def
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
string.include?(regexp_or_string)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
111
|
+
|
|
112
|
+
def assert_blank( obj, msg = nil )
|
|
113
|
+
assert_responds_to_blank( obj )
|
|
114
|
+
|
|
115
|
+
msg = message(msg) { "#{mu_pp(obj)} should be blank." }
|
|
116
|
+
|
|
117
|
+
assert( (obj.respond_to?(:blank?) && obj.blank?) || (obj.respond_to?(:fwf_blank?) && obj.fwf_blank?), msg )
|
|
89
118
|
end
|
|
90
119
|
|
|
91
|
-
def
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
120
|
+
def assert_matches( string, regexp_or_string, msg = nil)
|
|
121
|
+
msg = message(msg) { "<#{mu_pp(string)}> should match regex <#{mu_pp(regexp_or_string)}>" }
|
|
122
|
+
|
|
123
|
+
if regexp_or_string.is_a?(Regexp)
|
|
124
|
+
assert string.match(regexp_or_string), msg
|
|
125
|
+
elsif regexp_or_string.is_a?(String)
|
|
126
|
+
assert string.include?(regexp_or_string), msg
|
|
127
|
+
else
|
|
128
|
+
raise ArgumentError.new( "assert_matches takes a regular expression or string as second argument, not #{regexp_or_string}(#{regexp_or_string.class})")
|
|
95
129
|
end
|
|
130
|
+
|
|
131
|
+
true
|
|
96
132
|
end
|
|
97
133
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# or
|
|
106
|
-
# order = assert_assigns(:order)
|
|
107
|
-
def assert_assigns(*args)
|
|
108
|
-
symbols_assigned = []
|
|
109
|
-
symbols_not_assigned = []
|
|
110
|
-
|
|
111
|
-
for sym in args
|
|
112
|
-
((assigns(sym) != nil)? symbols_assigned : symbols_not_assigned) << sym
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
message = build_message("", "The following variables should have been assigned values by the controller: <?>", symbols_not_assigned.map{|s| "@#{s.to_s}"}.join(", "))
|
|
116
|
-
|
|
117
|
-
safe_assert_block message do
|
|
118
|
-
symbols_not_assigned.length == 0
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
if symbols_assigned.length == 1
|
|
122
|
-
assigns(symbols_assigned.first)
|
|
134
|
+
def assert_doesnt_match( string, regexp_or_string, msg = nil)
|
|
135
|
+
msg = message(msg) { "<#{mu_pp(string)}> should NOT match string/regex <#{mu_pp(regexp_or_string)}>" }
|
|
136
|
+
|
|
137
|
+
if regexp_or_string.is_a?(Regexp)
|
|
138
|
+
assert_nil string.match(regexp_or_string), msg
|
|
139
|
+
elsif regexp_or_string.is_a?(String)
|
|
140
|
+
refute string.include?(regexp_or_string), msg
|
|
123
141
|
else
|
|
124
|
-
|
|
142
|
+
raise ArgumentError.new( "assert_doesnt_match takes a regular expression or string as second argument, not #{regexp_or_string}(#{regexp_or_string.class})")
|
|
125
143
|
end
|
|
144
|
+
|
|
145
|
+
true
|
|
126
146
|
end
|
|
147
|
+
|
|
148
|
+
alias :refute_matches :assert_doesnt_match
|
|
127
149
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
|
|
151
|
+
def assert_greater_than( reference_value, amount, msg = nil )
|
|
152
|
+
msg = message(msg){
|
|
153
|
+
"second argument <#{mu_pp(amount)}> should be greater than reference value <#{mu_pp(reference_value)}>"
|
|
154
|
+
}
|
|
132
155
|
|
|
133
|
-
|
|
134
|
-
amount > reference_value
|
|
135
|
-
end
|
|
156
|
+
assert amount > reference_value, msg
|
|
136
157
|
end
|
|
137
158
|
|
|
138
159
|
# read as "assert less than 5, <test value>"
|
|
139
|
-
def assert_less_than( reference_value, amount,
|
|
140
|
-
|
|
160
|
+
def assert_less_than( reference_value, amount, msg = nil )
|
|
161
|
+
msg = message(msg){
|
|
162
|
+
"second argument <#{mu_pp(amount)} should be less than reference value <#{mu_pp(reference_value)}>"
|
|
163
|
+
}
|
|
141
164
|
|
|
142
|
-
|
|
143
|
-
amount < reference_value
|
|
144
|
-
end
|
|
165
|
+
assert amount < reference_value, msg
|
|
145
166
|
end
|
|
146
167
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
168
|
+
def assert_at_least( reference_value, amount, msg = nil )
|
|
169
|
+
msg = message(msg) { "Value must be at least #{reference_value}. #{mu_pp(amount)} is too small." }
|
|
170
|
+
|
|
171
|
+
assert( amount >= reference_value, msg )
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def assert_at_most( reference_value, amount, msg = nil )
|
|
175
|
+
msg = message(msg) { "Value can be at most #{reference_value}. #{mu_pp(amount)} is too large." }
|
|
176
|
+
|
|
177
|
+
assert( amount <= reference_value, msg )
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# I think "assert_delta_in_range" already does this for floats
|
|
181
|
+
def assert_times_are_close( t1, t2, window = 1, msg = nil)
|
|
182
|
+
msg = message(msg) { "times should be within #{mu_pp(window)} second of each other." }
|
|
183
|
+
assert (t1 - t2).abs <= window
|
|
154
184
|
end
|
|
155
185
|
|
|
156
|
-
def assert_equal_length( expected, actual,
|
|
157
|
-
|
|
186
|
+
def assert_equal_length( expected, actual, msg = nil )
|
|
187
|
+
assert_respond_to expected, :length, message(nil){ "#{mu_pp(expected)} (expected value) doesn't respond to length()." }
|
|
188
|
+
assert_respond_to actual, :length, message(nil){ "#{mu_pp(actual)} (actual value) doesn't respond to length()." }
|
|
189
|
+
|
|
190
|
+
msg = message(msg){
|
|
191
|
+
"items should be of equal length: expected length: <#{mu_pp(expected.length)}>, actual length: <#{mu_pp(actual.length)}>"
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
assert_equal expected.length, actual.length, msg
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def assert_unequal_length( expected, actual, msg = nil )
|
|
198
|
+
msg = message(msg){
|
|
199
|
+
"items should be of equal length: expected: <#{mu_pp(expected.length)}>, actual: <#{mu_pp(actual.length)}>"
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
assert_respond_to expected, :length, message(nil){ "#{mu_pp(expected)} (expected value) doesn't respond to length()." }
|
|
203
|
+
assert_respond_to actual, :length, message(nil){ "#{mu_pp(actual)} (actual value) doesn't respond to length()." }
|
|
204
|
+
|
|
205
|
+
assert_equal expected.length, actual.length, message
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
alias :refute_equal_length :assert_unequal_length
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# `expected` can be a numeric range
|
|
212
|
+
def assert_length( expected, actual, msg = nil )
|
|
158
213
|
|
|
159
|
-
|
|
160
|
-
|
|
214
|
+
no_response_msg = message(nil){ "<#{mu_pp(actual)}> doesn't respond to .length()" }
|
|
215
|
+
|
|
216
|
+
assert_respond_to actual, :length, no_response_msg
|
|
217
|
+
|
|
218
|
+
case expected
|
|
219
|
+
when Range
|
|
220
|
+
msg = message(msg){
|
|
221
|
+
"<#{mu_pp(actual)}> has a length of #{mu_pp(actual.length)}. Length must be between <#{mu_pp(expected.min)}> and <#{mu_pp(expected.max)}>"
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
assert_at_least expected.min, actual.length, msg
|
|
225
|
+
assert_at_most expected.max, actual.length, msg
|
|
226
|
+
when Integer
|
|
227
|
+
msg = message(msg){ "<#{mu_pp(actual)}> has a length of <#{mu_pp(actual.length)}>. Expected length was <#{mu_pp(expected)}>" }
|
|
228
|
+
assert_equal( expected, actual.length, msg )
|
|
229
|
+
else
|
|
230
|
+
flunk( "Bad reference value (first argument: #{expected.inspect}) to assert_length" )
|
|
161
231
|
end
|
|
162
232
|
end
|
|
233
|
+
|
|
234
|
+
# Tries the given methods on both objects, reports on differing results
|
|
235
|
+
# Doesn't take a custom message. Methods given must take zero arguments.
|
|
236
|
+
def assert_equality_of_methods( expected, actual, *methods )
|
|
237
|
+
failed = false
|
|
238
|
+
|
|
239
|
+
results_msg = {}
|
|
240
|
+
results_msg[:expected] = "The following methods were not equal: \nExpected: #{mu_pp(expected)}"
|
|
241
|
+
results_msg[:actual] = "\n--------------------\nActual: #{mu_pp(actual)}"
|
|
242
|
+
|
|
163
243
|
|
|
164
|
-
def assert_equality_of_methods(*args)
|
|
165
|
-
expected = args[0]
|
|
166
|
-
actual = args[1]
|
|
167
|
-
methods = args[2..-1].flatten
|
|
168
|
-
message = "The following methods were not equal: "
|
|
169
|
-
|
|
170
|
-
unequal = []
|
|
171
|
-
|
|
172
244
|
for method in methods
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
245
|
+
no_error_on_method = true
|
|
246
|
+
responses = {}
|
|
247
|
+
|
|
248
|
+
for obj, response_sym in [[expected, :expected], [actual, :actual]]
|
|
249
|
+
responses[response_sym] = begin
|
|
250
|
+
obj.send( method )
|
|
251
|
+
rescue StandardError => e
|
|
252
|
+
e
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
if responses[response_sym].is_a?( StandardError )
|
|
256
|
+
failed = true
|
|
257
|
+
no_error_on_method = false
|
|
258
|
+
results_msg[response_sym] << "\n\t#{method}(): ERROR: #{responses[response_sym].class} #{responses[response_sym].message}"
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
if responses[:expected] != responses[:actual] && no_error_on_method
|
|
263
|
+
failed = true
|
|
264
|
+
|
|
265
|
+
for response_sym in [:expected, :actual]
|
|
266
|
+
results_msg[response_sym] << "\n\t#{method}(): #{responses[response_sym].inspect}"
|
|
267
|
+
end
|
|
178
268
|
end
|
|
179
269
|
end
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
assert !failed, results_msg[:expected] + results_msg[:actual]
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def assert_has_instance_method( object, instance_method, msg = nil )
|
|
276
|
+
msg = message(msg){ "object #{mu_pp(object)} should respond to #{instance_method.inspect}" }
|
|
277
|
+
assert object.instance_methods.include?( instance_method ), msg
|
|
184
278
|
end
|
|
185
279
|
|
|
186
|
-
def
|
|
187
|
-
|
|
188
|
-
|
|
280
|
+
def assert_nothing_raised( msg = nil, &block )
|
|
281
|
+
begin
|
|
282
|
+
yield if block_given?
|
|
283
|
+
assert true
|
|
284
|
+
rescue Exception => e
|
|
285
|
+
msg = message(msg){ "block should not raise a #{mu_pp(e.class)} (message: #{e.message})"}
|
|
286
|
+
assert false, msg
|
|
189
287
|
end
|
|
190
288
|
end
|
|
191
289
|
|
|
192
|
-
def
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
290
|
+
def assert_constant_defined( const, msg = nil )
|
|
291
|
+
begin
|
|
292
|
+
Object.const_get( const )
|
|
293
|
+
assert true
|
|
294
|
+
rescue NameError
|
|
295
|
+
assert false, message(msg){ "expected constant is not defined: #{const}" }
|
|
196
296
|
end
|
|
197
297
|
end
|
|
298
|
+
|
|
299
|
+
# Which order makes more sense for the arguments
|
|
300
|
+
# Assert that the first argument includes the module specified in the second argument
|
|
301
|
+
def assert_includes_module( mod_or_class, mod, msg = nil )
|
|
302
|
+
# Make sure we've been passed the proper sort of objects
|
|
303
|
+
assert mod_or_class.respond_to?( :included_modules, "#{mod_or_class} doesn't respond to included_modules()" )
|
|
304
|
+
raise ArgumentError.new( "#{mod} is not a module" ) unless mod.kind_of?( Module )
|
|
305
|
+
|
|
306
|
+
msg = message(msg){ "#{mod_or_class} should have included module #{mod}" }
|
|
307
|
+
|
|
308
|
+
assert mod_or_class.included_modules.include?(mod), msg
|
|
309
|
+
end
|
|
198
310
|
end
|
|
199
311
|
end
|
|
200
312
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module FunWith
|
|
2
|
+
module Testing
|
|
3
|
+
# Class is designed specifically for testing custom assertions.
|
|
4
|
+
# See test/test_assertions.rb for how it's supposed to work.
|
|
5
|
+
class AssertionsTestCase < FunWith::Testing::TestCase
|
|
6
|
+
def self.fwt_install_mock_safe_assert_block
|
|
7
|
+
include AssertionTestMocker
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# After @case_class is created, you can include the methods you want to test
|
|
11
|
+
#
|
|
12
|
+
def extended_test_case( &block )
|
|
13
|
+
@case_class = Class.new( FunWith::Testing::AssertionsTestCase )
|
|
14
|
+
|
|
15
|
+
# Unhook from some of the test harness stuff to
|
|
16
|
+
# make it possible to run the assertion methods
|
|
17
|
+
# without causing the test suite to topple over.
|
|
18
|
+
@case_class.fwt_install_mock_safe_assert_block
|
|
19
|
+
|
|
20
|
+
@case = @case_class.new( "MockUnitTest" ) # what does name arg do?
|
|
21
|
+
|
|
22
|
+
assert @case_class.methods.include?( :_should )
|
|
23
|
+
assert @case_class.methods.include?( :_context )
|
|
24
|
+
# assert @case.methods.include?( :in_test_mode? )
|
|
25
|
+
|
|
26
|
+
yield if block_given?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def must_flunk( &block )
|
|
30
|
+
assert_raises( Minitest::Assertion ) do
|
|
31
|
+
if block_given?
|
|
32
|
+
yield
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def yep( *args, &block )
|
|
38
|
+
assert @case.send( @current_method_sym, *args, &block )
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def nope( *args, &block )
|
|
42
|
+
must_flunk do
|
|
43
|
+
@case.send( @current_method_sym, *args, &block )
|
|
44
|
+
|
|
45
|
+
# shouldn't get here
|
|
46
|
+
puts "should fail: #{@current_method_sym}( #{ args.map(&:inspect).join(", ")})"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
def oops( *args )
|
|
52
|
+
assert_raises( StandardError ) do
|
|
53
|
+
@case.send( @current_method_sym, *args, &block )
|
|
54
|
+
|
|
55
|
+
# should not get here
|
|
56
|
+
puts "should cause error: #{@current_method_sym}( #{ args.map(&:inspect).join(", ")})"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def testing_method( m, &block )
|
|
61
|
+
@current_method_sym = m
|
|
62
|
+
yield
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module FunWith
|
|
2
|
+
module Testing
|
|
3
|
+
module AssertionTestMocker
|
|
4
|
+
# Any subclass of Test::Unit::TestCase seems to automatically hook into the test suite.
|
|
5
|
+
# Therefore, calling a test to see if it returns false makes the suite fail. Including
|
|
6
|
+
# to this class instead prevents that.
|
|
7
|
+
#
|
|
8
|
+
# I may need to more closely mimic Test::Unit::TestCase
|
|
9
|
+
# in order to test messages properly.
|
|
10
|
+
def safe_assert_block( *args, &block )
|
|
11
|
+
yield
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -1,77 +1,7 @@
|
|
|
1
1
|
module FunWith
|
|
2
2
|
module Testing
|
|
3
3
|
class TestCase < Minitest::Test
|
|
4
|
-
|
|
5
|
-
# gem is being tested, but this really wasn't it.
|
|
6
|
-
#
|
|
7
|
-
# Okay, that was stupid. The point was to allow verbosity to be specified in the gem's code,
|
|
8
|
-
# not just in the test suite. What would that be... MyGem.test_mode? MyGem.verbose_gem? MyGem.say
|
|
9
|
-
def self.gem_to_test( gem_const = nil, test_mode = true )
|
|
10
|
-
if @fwt_gem_to_test
|
|
11
|
-
return @fwt_gem_to_test
|
|
12
|
-
elsif self.superclass.respond_to?( :gem_to_test )
|
|
13
|
-
self.superclass.gem_to_test
|
|
14
|
-
else
|
|
15
|
-
nil
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def self.gem_to_test=( gem_const )
|
|
20
|
-
@fwt_gem_to_test = gem_const
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def self.set_test_mode( mode = true )
|
|
24
|
-
self.const_set( :FWT_TEST_MODE, mode )
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Originally named test_mode?(), but Test::Unit::TestCase picked up on the fact that it started with "test"
|
|
28
|
-
# and tried to run it as a test in its own right
|
|
29
|
-
def self.in_test_mode?
|
|
30
|
-
return self::FWT_TEST_MODE if self.constants.include?( :FWT_TEST_MODE )
|
|
31
|
-
return self.superclass.in_test_mode? if self.superclass.respond_to?(:in_test_mode?)
|
|
32
|
-
return false
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def in_test_mode?
|
|
36
|
-
self.class.in_test_mode?
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def self.set_verbose( mode = true )
|
|
40
|
-
self.const_set( :FWT_TEST_VERBOSITY, mode )
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def self.verbose?
|
|
44
|
-
return self::FWT_TEST_VERBOSITY if self.constants.include?( :FWT_TEST_VERBOSITY )
|
|
45
|
-
return self.superclass.verbose? if self.superclass.respond_to?(:verbose)
|
|
46
|
-
return false
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def verbose?
|
|
50
|
-
self.class.verbose?
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def puts_if_verbose( msg, stream = $stdout )
|
|
54
|
-
stream.puts( msg ) if self.verbose?
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Convenience methods for disappearing a set of tests. Useful for focusing on one or two tests.
|
|
58
|
-
def self._context(*args, &block)
|
|
59
|
-
puts "<<< WARNING >>> IGNORING TEST SET #{args.inspect}. Remove leading _ from '_context()' to reactivate."
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def self._should(*args, &block)
|
|
63
|
-
puts "<<< WARNING >>> IGNORING TEST #{args.inspect}. Remove leading _ from '_should()' to reactivate."
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def test_gem_validity
|
|
67
|
-
if jem = self.class.gem_to_test
|
|
68
|
-
assert_equal [], jem.validate_gem
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def build_message( *args )
|
|
73
|
-
args.map(&:inspect).join(" ")
|
|
74
|
-
end
|
|
4
|
+
extend TestCaseExtensions
|
|
75
5
|
end
|
|
76
6
|
end
|
|
77
7
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module FunWith
|
|
2
|
+
module Testing
|
|
3
|
+
module TestCaseExtensions
|
|
4
|
+
def install_verbosity
|
|
5
|
+
include VerbosityMethods
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def install_test_mode
|
|
9
|
+
include TestModeMethods
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def install_basic_assertions
|
|
13
|
+
include Assertions::Basics
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# assumes the gem has a test/factories folder, just requir's everything
|
|
17
|
+
# from that directory.
|
|
18
|
+
def add_factorybot_support
|
|
19
|
+
unless defined?( FactoryBot )
|
|
20
|
+
begin
|
|
21
|
+
require 'factory_bot'
|
|
22
|
+
rescue LoadError
|
|
23
|
+
puts "Error: FactoryBot support requested, but FactoryBot could not be loaded. make sure the factory_bot gem is listed in your Gemfile, then run `bundle install`."
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
FactoryBot.find_definitions if defined?( FactoryBot ) # loads factories, test/factories, and spec/factories if they exist (directory or .rb file)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Convenience methods for disappearing a set of tests. Useful for focusing on one or two tests.
|
|
31
|
+
def _context(*args, &block)
|
|
32
|
+
puts "<<< WARNING >>> IGNORING TEST SET #{args.inspect}. Remove leading _ from '_context()' to reactivate."
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def _should(*args, &block)
|
|
36
|
+
puts "<<< WARNING >>> IGNORING TEST #{args.inspect}. Remove leading _ from '_should()' to reactivate."
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def _test(*args, &block)
|
|
40
|
+
puts "<<< WARNING >>> IGNORING TEST #{args.inspect}. Remove leading _ from '_test()' to reactivate."
|
|
41
|
+
end
|
|
42
|
+
# def build_message( *args )
|
|
43
|
+
# args.map(&:inspect).join(" ")
|
|
44
|
+
# end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|