qualitysmith_extensions 0.0.24 → 0.0.29

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.
@@ -23,7 +23,7 @@ class String
23
23
  end
24
24
  end
25
25
  alias_method_chain :colorize, :toggleability
26
- mguard_method :color_on!, :@@colorize_enabled, :color_off!
26
+ mguard_method :color_on!, :@@colorize_enabled
27
27
 
28
28
  end unless String.instance_methods.include?('colorize_with_toggleability')
29
29
 
@@ -38,18 +38,18 @@ end unless String.instance_methods.include?('colorize_with_toggleability')
38
38
  require 'test/unit'
39
39
 
40
40
  class TheTest < Test::Unit::TestCase
41
- def test_color_on!
41
+ def test_color_on
42
42
  String.color_on!
43
43
  assert_equal "\e[31mfoo\e[0m", 'foo'.red
44
44
  end
45
- def test_color_off!
46
- String.color_off!
45
+ def test_color_off
46
+ String.color_on! false
47
47
  assert_equal "foo", 'foo'.red
48
48
  end
49
49
  def test_color_off_with_block
50
50
  String.color_on!
51
51
  assert_equal "\e[31mfoo\e[0m", 'foo'.red
52
- String.color_off! do
52
+ String.color_on! false do
53
53
  assert_equal "foo", 'foo'.red
54
54
  end
55
55
  assert_equal "\e[31mfoo\e[0m", 'foo'.red
@@ -37,6 +37,8 @@ class Module
37
37
  # x.a? # => true
38
38
  #
39
39
  def bool_attr_reader(*args)
40
+ options = (if args.last.is_a?(Hash) then args.pop else {} end) # These options aren't used here, per se, but it allows us to have bool_attr_accessor pass along same args to both bool_attr_reader and bool_attr_setter.
41
+
40
42
  make = {}
41
43
  args.each { |a|
42
44
  make["#{a}?".to_sym] = %{
@@ -74,7 +76,13 @@ class Module
74
76
  # x.a! # toggles @a, so that it ends up being true
75
77
  # x.a! false # sets @a to false
76
78
  #
79
+ # Use <tt>:allow_nil</tt> if you want it to be a tri-state flag -- that is, if you need to be able to set it to +nil+ as well as true and false.
80
+ # bool_attr_setter :a, :b, :allow_nil => true
81
+ # x.a! nil # sets @a to nil
82
+ #
77
83
  def bool_attr_setter(*args)
84
+ options = (if args.last.is_a?(Hash) then args.pop else {} end)
85
+
78
86
  make = {}
79
87
  args.each { |a|
80
88
  make["#{a}!".to_sym] = %{
@@ -82,8 +90,11 @@ class Module
82
90
  if switch == Exception
83
91
  @#{a} = !@#{a}
84
92
  else
85
- @#{a} = switch ? true : false
86
- # used to be @#{a} instead of false in Facets version
93
+ #{
94
+ options[:allow_nil] ?
95
+ "@#{a} = switch ? true : switch" :
96
+ "@#{a} = switch ? true : false"
97
+ }
87
98
  self
88
99
  end
89
100
  end
@@ -134,6 +145,8 @@ class Module
134
145
  # Works for both classes and modules.
135
146
  #
136
147
  def mbool_attr_reader(*args)
148
+ options = (if args.last.is_a?(Hash) then args.pop else {} end) # These options aren't used here, per se, but it allows us to have bool_attr_accessor pass along same args to both bool_attr_reader and bool_attr_setter.
149
+
137
150
  make = {}
138
151
  args.each { |a|
139
152
  make["#{a}?".to_sym] = %{
@@ -163,7 +176,13 @@ class Module
163
176
  #
164
177
  # Works for both classes and modules.
165
178
  #
179
+ # Use <tt>:allow_nil</tt> if you want it to be a tri-state flag -- that is, if you need to be able to set it to +nil+ as well as true and false.
180
+ # mbool_attr_setter :a, :b, :allow_nil => true
181
+ # C.a! nil # sets @@a to nil
182
+ #
166
183
  def mbool_attr_setter(*args)
184
+ options = (if args.last.is_a?(Hash) then args.pop else {} end)
185
+
167
186
  make = {}
168
187
  args.each { |a|
169
188
  # Initialize it first so that we won't have any NameErrors.
@@ -174,7 +193,11 @@ class Module
174
193
  if switch == Exception
175
194
  @@#{a} = !@@#{a}
176
195
  else
177
- @@#{a} = switch ? true : false
196
+ #{
197
+ options[:allow_nil] ?
198
+ "@@#{a} = switch ? true : switch" :
199
+ "@@#{a} = switch ? true : false"
200
+ }
178
201
  self
179
202
  end
180
203
  end
@@ -196,8 +219,8 @@ class Module
196
219
  # Works for both classes and modules.
197
220
  #
198
221
  def mbool_attr_accessor(*args)
199
- mbool_attr_reader :a
200
- mbool_attr_setter :a
222
+ mbool_attr_reader *args
223
+ mbool_attr_setter *args
201
224
  end
202
225
  end
203
226
 
@@ -214,24 +237,22 @@ require 'test/unit'
214
237
  require 'rubygems'
215
238
  require 'qualitysmith_extensions/object/ignore_access'
216
239
 
240
+ #---------------------------------------------------------------------------------------------------
217
241
  # Test that it works for *instances*
218
242
  class TestBoolAttr < Test::Unit::TestCase
219
- def setup
220
- @x = C.new
221
- end
222
243
 
223
- class C_for_default_is_nil
244
+ class C
224
245
  bool_attr_accessor :a, :b
225
246
  end
226
247
 
227
- # Also tests that it can create multiple accessors at once.
228
- def test1_default_is_nil
229
- assert_equal nil, C_for_default_is_nil.new.a?
230
- assert_equal nil, C_for_default_is_nil.new.b?
248
+ def setup
249
+ @x = C.new
231
250
  end
232
251
 
233
- class C
234
- bool_attr_accessor :a
252
+ # Also tests that it can create multiple accessors at once.
253
+ def test1_default_is_nil
254
+ assert_equal nil, C.new.a?
255
+ assert_equal nil, C.new.b?
235
256
  end
236
257
 
237
258
  def test2_toggle
@@ -257,8 +278,43 @@ class TestBoolAttr < Test::Unit::TestCase
257
278
  @x.a! nil
258
279
  assert_equal false, @x.a? # Still returns a boolean even though we tried to set it to nil.
259
280
  end
281
+
260
282
  end
261
283
 
284
+ class TestBoolAttr_AllowNil < Test::Unit::TestCase
285
+
286
+ class C
287
+ bool_attr_accessor :a, :b, :allow_nil => true
288
+ end
289
+
290
+ def setup
291
+ @x = C.new
292
+ end
293
+
294
+ def test1_default_is_nil
295
+ assert_equal nil, C.new.a?
296
+ assert_equal nil, C.new.b?
297
+ end
298
+
299
+ def test2_for_nilability
300
+ @x.a! "whatever"
301
+ assert_equal true, @x.a? # Still returns a boolean even though we tried to set it to a string.
302
+
303
+ @x.a! nil
304
+ assert_equal nil, @x.a? # Lets us set it to nil!
305
+ #assert_equal true, @x.a?(nil) # Testing the "is it nil?" question.
306
+ assert_equal true, @x.a?.nil? # Testing the "is it nil?" question.
307
+
308
+
309
+ @x.a! false
310
+ assert_equal false, @x.a? # Lets us set it to false!
311
+ assert_equal true, @x.a? == false # Testing the "is it false?" question.
312
+ end
313
+ end
314
+
315
+
316
+
317
+ #---------------------------------------------------------------------------------------------------
262
318
  # Test that it works for *modules*
263
319
  class TestForModules < Test::Unit::TestCase
264
320
 
@@ -295,7 +351,34 @@ class TestForModules < Test::Unit::TestCase
295
351
  assert_equal false, M.a? # Still returns a boolean even though we tried to set it to nil.
296
352
  end
297
353
  end
354
+ class TestForModules_AllowNil < Test::Unit::TestCase
355
+
356
+ module M
357
+ mbool_attr_accessor :a, :b, :allow_nil => true
358
+ end
359
+
360
+ def test1_default_is_nil
361
+ assert_equal nil, M.a?
362
+ assert_equal nil, M.b?
363
+ end
364
+
365
+ def test2_for_nilability
366
+ M.a! "whatever"
367
+ assert_equal true, M.a? # Still returns a boolean even though we tried to set it to a string.
368
+
369
+ M.a! nil
370
+ assert_equal nil, M.a? # Lets us set it to nil!
371
+ #assert_equal true, M.a?(nil) # Testing the "is it nil?" question.
372
+ assert_equal true, M.a?.nil? # Testing the "is it nil?" question.
373
+
374
+
375
+ M.a! false
376
+ assert_equal false, M.a? # Lets us set it to false!
377
+ assert_equal true, M.a? == false # Testing the "is it false?" question.
378
+ end
379
+ end
298
380
 
381
+ #---------------------------------------------------------------------------------------------------
299
382
  # Test that it also works for *classes*
300
383
  class TestForClasses < Test::Unit::TestCase
301
384
 
@@ -341,7 +424,7 @@ end
341
424
 
342
425
 
343
426
  # Observation: You can also the normal bool_attr_accessor in conjunction with class << self.
344
- # The methods generated seem to *behave* in the same way. Both techniques allow you to query the class, C.a?
427
+ # The methods generated seem to *behave* in the same way. Both techniques allow you to query the class (C.a?).
345
428
  # The only difference is in which *variables* are use to store the state:
346
429
  # * class << self and the normal bool_attr_accessor:
347
430
  # Stores the state in an instance variable for the *class*: @a
@@ -13,9 +13,11 @@
13
13
 
14
14
  require 'rubygems'
15
15
  require 'qualitysmith_extensions/module/attribute_accessors'
16
- require 'qualitysmith_extensions/module/mattr_tester'
17
- require 'qualitysmith_extensions/module/attr_tester'
16
+ require 'facets/core/kernel/require_local'
17
+ require_local 'bool_attr_accessor'
18
+ #require 'qualitysmith_extensions/module/bool_attr_accessor'
18
19
  require 'qualitysmith_extensions/symbol/match'
20
+ require 'qualitysmith_extensions/class/class_methods'
19
21
 
20
22
 
21
23
  class Module
@@ -32,53 +34,38 @@ class Module
32
34
  # end # Causes @stupid_stuff_disabled to be set back to false
33
35
  # # Okay, a, you can resume doing stupid stuff again...
34
36
  #
35
- # If you also want a guard method that *disables* the flag rather than *enabling* it, simply pass in the desired name of this
36
- # "unguard" method as the value of the +unguard_method_name+ argument.
37
- # class A
38
- # guard_method :guard_the_fruit!, :@guarding_the_fruit, :stop_guarding_the_fruit!
39
- # end
40
- #
41
- # Examples of unguard methods:
42
- # mguard_method :color_on!, :@@color_enabled, :color_off!
43
- # mguard_method :without_benchmarking, :@@benchmarking_disabled, :with_benchmarking
37
+ # If you want your guard method to *disable* the flag rather than *enable* it, simply pass false to the guard method.
44
38
  #
45
39
  # These calls can be nested however you wish:
46
40
  # a.guard_the_fruit! do
47
- # a.stop_guarding_the_fruit! do
41
+ # a.guard_the_fruit!(false) do
48
42
  # assert_equal false, a.guarding_the_fruit?
49
43
  # end
50
44
  # assert_equal true, a.guarding_the_fruit?
51
45
  # end
52
46
  #
53
47
  # You can also use the guard methods as normal flag setter/clearer methods by simply not passing a block to it. Hence
54
- # a.guard_the_fruit!
48
+ # a.guard_the_fruit!
55
49
  # will simply set @guarding_the_fruit to true, and
56
- # a.stop_guarding_the_fruit!
50
+ # a.guard_the_fruit!(false)
57
51
  # will set @guarding_the_fruit to false.
58
52
  #
59
- def guard_method(guard_method_name, guard_variable, unguard_method_name = nil)
53
+ def guard_method(guard_method_name, guard_variable)
60
54
  raise ArgumentError.new("Expected an instance variable name but got #{guard_variable}") if guard_variable !~ /^@([\w_]+)$/
61
55
  guard_variable.to_s =~ /^@([\w_]+)$/ # Why didn't the regexp above set $1 ??
62
56
  class_eval do
63
- attr_tester $1.to_sym
57
+ bool_attr_accessor $1.to_sym
64
58
  end
65
59
  module_eval <<-End, __FILE__, __LINE__+1
66
- def #{guard_method_name}(new_value = nil, &block)
67
- old_guard_state, #{guard_variable} = #{guard_variable}, true
60
+ def #{guard_method_name}(new_value = true, &block)
61
+ old_guard_state, #{guard_variable} = #{guard_variable}, new_value
68
62
  if block_given?
69
- returning = yield
70
- #{guard_variable} = old_guard_state
71
- returning
72
- end
73
- end
74
- End
75
- module_eval <<-End, __FILE__, __LINE__+1 unless unguard_method_name.nil?
76
- def #{unguard_method_name}(new_value = nil, &block)
77
- old_guard_state, #{guard_variable} = #{guard_variable}, false
78
- if block_given?
79
- returning = yield
80
- #{guard_variable} = old_guard_state
81
- returning
63
+ begin
64
+ returning = yield
65
+ ensure
66
+ #{guard_variable} = old_guard_state
67
+ returning
68
+ end
82
69
  end
83
70
  end
84
71
  End
@@ -90,32 +77,24 @@ class Module
90
77
  #
91
78
  # Example:
92
79
  # mguard_method :guard_the_fruit!, :@@guarding_the_fruit
93
- def mguard_method(guard_method_name, guard_variable, unguard_method_name = nil)
80
+ # mguard_method :use_assert_equal_with_highlight!, :@@always_use_assert_equal_with_highlight
81
+ def mguard_method(guard_method_name, guard_variable)
94
82
  raise ArgumentError.new("Expected a class variable name but got #{guard_variable}") if guard_variable !~ /^@@[\w_]+$/
95
83
  guard_variable.to_s =~ /^@@([\w_]+)$/
96
84
  class_eval do
97
- mattr_tester $1.to_sym
85
+ mbool_attr_accessor $1.to_sym
98
86
  end
99
87
  module_eval <<-End, __FILE__, __LINE__+1
100
88
  class << self
101
- def #{guard_method_name}(new_value = nil, &block)
102
- old_guard_state, #{guard_variable} = #{guard_variable}, true
89
+ def #{guard_method_name}(new_value = true, &block)
90
+ old_guard_state, #{guard_variable} = #{guard_variable}, new_value
103
91
  if block_given?
104
- returning = yield
105
- #{guard_variable} = old_guard_state
106
- returning
107
- end
108
- end
109
- end
110
- End
111
- module_eval <<-End, __FILE__, __LINE__+1 unless unguard_method_name.nil?
112
- class << self
113
- def #{unguard_method_name}(new_value = nil, &block)
114
- old_guard_state, #{guard_variable} = #{guard_variable}, false
115
- if block_given?
116
- returning = yield
117
- #{guard_variable} = old_guard_state
118
- returning
92
+ begin
93
+ returning = yield
94
+ ensure
95
+ #{guard_variable} = old_guard_state
96
+ returning
97
+ end
119
98
  end
120
99
  end
121
100
  end
@@ -159,11 +138,24 @@ class GuardMethodTest_Simple < Test::Unit::TestCase
159
138
  def test_return_value
160
139
  assert_equal 'special return value', A.new.guard_the_fruit! { 'special return value' }
161
140
  end
141
+
142
+ def try_to_return_prematurely(a)
143
+ a.guard_the_fruit! do
144
+ assert_equal true, a.guarding_the_fruit?
145
+ return 'prematurely'
146
+ end
147
+ end
148
+ def test_guard_method_for_block_that_tries_to_return_prematurely
149
+ a = A.new
150
+ assert_equal nil, a.guarding_the_fruit?
151
+ try_to_return_prematurely(a)
152
+ assert_equal nil, a.guarding_the_fruit?
153
+ end
162
154
  end
163
155
 
164
- class GuardMethodTest_WithUnguard < Test::Unit::TestCase
156
+ class GuardMethodTest_WithUnguard < Test::Unit::TestCase # (By "unguard" here I mean passing false to the guard method...)
165
157
  class A
166
- guard_method :guard_the_fruit!, :@guarding_the_fruit, :stop_guarding_the_fruit!
158
+ guard_method :guard_the_fruit!, :@guarding_the_fruit
167
159
  end
168
160
  def test_guard_method
169
161
  a = A.new
@@ -172,7 +164,7 @@ class GuardMethodTest_WithUnguard < Test::Unit::TestCase
172
164
  a.guard_the_fruit! do
173
165
  assert_equal true, a.guarding_the_fruit?
174
166
 
175
- a.stop_guarding_the_fruit! do
167
+ a.guard_the_fruit! false do
176
168
  assert_equal false, a.guarding_the_fruit?
177
169
  a.guard_the_fruit! do
178
170
  assert_equal true, a.guarding_the_fruit?
@@ -193,11 +185,11 @@ class GuardMethodTest_WithUnguard < Test::Unit::TestCase
193
185
  a.guard_the_fruit!
194
186
  assert_equal true, a.guarding_the_fruit?
195
187
 
196
- a.stop_guarding_the_fruit! do
188
+ a.guarding_the_fruit? do
197
189
  assert_equal false, a.guarding_the_fruit?
198
190
  a.guard_the_fruit! do
199
191
  assert_equal true, a.guarding_the_fruit?
200
- a.stop_guarding_the_fruit!
192
+ a.guard_the_fruit! false
201
193
  assert_equal false, a.guarding_the_fruit?
202
194
  a.guard_the_fruit!
203
195
  assert_equal true, a.guarding_the_fruit?
@@ -210,9 +202,9 @@ class GuardMethodTest_WithUnguard < Test::Unit::TestCase
210
202
 
211
203
  def test_return_value
212
204
  assert_equal nil, A.new.guard_the_fruit!
213
- assert_equal nil, A.new.stop_guarding_the_fruit!
214
- assert_equal 'special return value', A.new.guard_the_fruit! { 'special return value' }
215
- assert_equal 'special return value', A.new.stop_guarding_the_fruit! { 'special return value' }
205
+ assert_equal nil, A.new.guard_the_fruit!(false)
206
+ assert_equal 'special return value', A.new.guard_the_fruit! { 'special return value' }
207
+ assert_equal 'special return value', A.new.guard_the_fruit!(false) { 'special return value' }
216
208
  end
217
209
  end
218
210
 
@@ -249,11 +241,23 @@ class MGuardMethodTest_Simple < Test::Unit::TestCase
249
241
  def test_return_value
250
242
  assert_equal 'special return value', B.guard_the_fruit! { 'special return value' }
251
243
  end
244
+
245
+ def try_to_return_prematurely
246
+ B.guard_the_fruit! do
247
+ assert_equal true, B.guarding_the_fruit?
248
+ return 'prematurely'
249
+ end
250
+ end
251
+ def test_guard_method_for_block_that_tries_to_return_prematurely
252
+ assert_equal nil, B.guarding_the_fruit?
253
+ try_to_return_prematurely
254
+ assert_equal nil, B.guarding_the_fruit?
255
+ end
252
256
  end
253
257
 
254
258
  class MGuardMethodTest_WithUnguard < Test::Unit::TestCase
255
259
  class B
256
- mguard_method :guard_the_fruit!, :@@guarding_the_fruit, :stop_guarding_the_fruit!
260
+ mguard_method :guard_the_fruit!, :@@guarding_the_fruit
257
261
  end
258
262
  def test_guard_method
259
263
  assert_equal nil, B.guarding_the_fruit?
@@ -261,7 +265,7 @@ class MGuardMethodTest_WithUnguard < Test::Unit::TestCase
261
265
  B.guard_the_fruit! do
262
266
  assert_equal true, B.guarding_the_fruit?
263
267
 
264
- B.stop_guarding_the_fruit! do
268
+ B.guard_the_fruit!(false) do
265
269
  assert_equal false, B.guarding_the_fruit?
266
270
  B.guard_the_fruit! do
267
271
  assert_equal true, B.guarding_the_fruit?
@@ -281,11 +285,11 @@ class MGuardMethodTest_WithUnguard < Test::Unit::TestCase
281
285
  B.guard_the_fruit!
282
286
  assert_equal true, B.guarding_the_fruit?
283
287
 
284
- B.stop_guarding_the_fruit! do
288
+ B.guard_the_fruit!(false) do
285
289
  assert_equal false, B.guarding_the_fruit?
286
290
  B.guard_the_fruit! do
287
291
  assert_equal true, B.guarding_the_fruit?
288
- B.stop_guarding_the_fruit!
292
+ B.guard_the_fruit!(false)
289
293
  assert_equal false, B.guarding_the_fruit?
290
294
  B.guard_the_fruit!
291
295
  assert_equal true, B.guarding_the_fruit?
@@ -298,9 +302,9 @@ class MGuardMethodTest_WithUnguard < Test::Unit::TestCase
298
302
 
299
303
  def test_return_value
300
304
  assert_equal nil, B.guard_the_fruit!
301
- assert_equal nil, B.stop_guarding_the_fruit!
305
+ assert_equal nil, B.guard_the_fruit!(false)
302
306
  assert_equal 'special return value', B.guard_the_fruit! { 'special return value' }
303
- assert_equal 'special return value', B.stop_guarding_the_fruit! { 'special return value' }
307
+ assert_equal 'special return value', B.guard_the_fruit!(false) { 'special return value' }
304
308
  end
305
309
  end
306
310
  # End duplication