qualitysmith_extensions 0.0.24 → 0.0.29

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