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.
- data/lib/qualitysmith_extensions/colored/toggleability.rb +5 -5
- data/lib/qualitysmith_extensions/module/bool_attr_accessor.rb +99 -16
- data/lib/qualitysmith_extensions/module/guard_method.rb +68 -64
- data/lib/qualitysmith_extensions/test/difference_highlighting.rb +100 -54
- metadata +2 -9
- data/lib/qualitysmith_extensions/module.bak/alias_method.rb +0 -6
- data/lib/qualitysmith_extensions/module.bak/attribute_accessors.rb +0 -46
- data/lib/qualitysmith_extensions/module.bak/bool_attr_accessor.rb +0 -334
- data/lib/qualitysmith_extensions/module.bak/create_setter.rb +0 -9
- data/lib/qualitysmith_extensions/module.bak/guard_method.rb +0 -309
- data/lib/qualitysmith_extensions/module.bak/includable_once.rb +0 -10
- data/lib/qualitysmith_extensions/module.bak/mattr_tester.rb +0 -235
@@ -12,10 +12,10 @@ gem 'colored'
|
|
12
12
|
require 'colored'
|
13
13
|
gem 'facets'
|
14
14
|
require 'facets/core/module/alias_method_chain'
|
15
|
-
gem 'qualitysmith_extensions', '>=0.0.
|
15
|
+
gem 'qualitysmith_extensions', '>=0.0.28'
|
16
16
|
require 'qualitysmith_extensions/object/send_if'
|
17
17
|
require 'qualitysmith_extensions/string/each_char_with_index'
|
18
|
-
require 'qualitysmith_extensions/module/
|
18
|
+
require 'qualitysmith_extensions/module/bool_attr_accessor'
|
19
19
|
require 'qualitysmith_extensions/module/guard_method'
|
20
20
|
require 'qualitysmith_extensions/colored/toggleability'
|
21
21
|
|
@@ -66,8 +66,7 @@ module Test
|
|
66
66
|
module Assertions
|
67
67
|
class AssertionMessage
|
68
68
|
@@inspect_strings = false
|
69
|
-
|
70
|
-
mguard_method :inspect_strings!, :@@inspect_strings, :disable_inspect_strings!
|
69
|
+
mguard_method :inspect_strings!, :@@inspect_strings
|
71
70
|
|
72
71
|
# The problem with the original convert() is that it always called #inspect on strings... which is fine if you really
|
73
72
|
# want to see all those \n's and such. But not so great if you want to visually compare the strings. And if you have
|
@@ -89,6 +88,15 @@ module Test
|
|
89
88
|
end
|
90
89
|
alias_method_chain :convert, :option_to_not_use_inspect_for_strings
|
91
90
|
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
module Test
|
96
|
+
module Unit
|
97
|
+
module Assertions
|
98
|
+
@@use_assert_equal_with_highlight = nil
|
99
|
+
mguard_method :use_assert_equal_with_highlight!, :@@use_assert_equal_with_highlight
|
92
100
|
|
93
101
|
# Rather than showing the expected and the actual and asking the user to painstakingly compare the two and figure out the
|
94
102
|
# commonalities and differences himself, this method will highlight the differences for the user (in color), so that they
|
@@ -107,55 +115,75 @@ module Test
|
|
107
115
|
# Difference in method signature from assert_equal_without_difference_highlighting:
|
108
116
|
# * last argument is a hash (+options+) rather than message=nil, since I don't see the use in passing in a message if
|
109
117
|
# the default message can be made useful enough.
|
110
|
-
# * If you really want to pass in a message, use
|
118
|
+
# * If you really want to pass in a message, use <tt>:message => 'my message'</tt>
|
111
119
|
#
|
112
|
-
#
|
120
|
+
# By default, highlighting is only used when one or both of the strings being compared is long/multiline. You can override the default with the <tt>:higlight</tt> option:
|
121
|
+
# assert_equal 'really long string', 'another really long string', :highlight => true
|
122
|
+
# You can turn it on for all assert_equal assertions by calling
|
123
|
+
# Test::Unit::Assertions::use_assert_equal_with_highlight!
|
124
|
+
# Or you can just turn it on or off for the duration of a block only:
|
125
|
+
# Test::Unit::Assertions::use_assert_equal_with_highlight! do
|
126
|
+
# assert_equal 'really long string', 'another really long string'
|
127
|
+
# end
|
113
128
|
#
|
114
|
-
# Spaces are displayed with an underline so that they are actually visible on the screen.
|
115
|
-
# *
|
116
|
-
|
129
|
+
# * Spaces are displayed with an underline so that they are actually visible on the screen.
|
130
|
+
# * Newlines are displayed as the text '\n' followed by an actual newline.
|
131
|
+
#
|
132
|
+
# Advanced:
|
133
|
+
# * If you want everything to be escaped (so you can see the color *codes* instead of the color itself, for example), use :inspect_strings => true
|
134
|
+
#
|
135
|
+
def assert_equal_with_highlighting(expected, actual, options = {})
|
117
136
|
message = options.delete(:message) || nil
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
137
|
+
highlight = options.delete(:highlight)
|
138
|
+
|
139
|
+
Assertions.send_unless(highlight.nil?, :use_assert_equal_with_highlight!, highlight) do
|
140
|
+
|
141
|
+
if String===expected and String===actual and expected!=actual and
|
142
|
+
(Assertions.use_assert_equal_with_highlight? || [expected.length, actual.length].max > 80 || [expected, actual].any? {|a| a.include?("\n")}) and
|
143
|
+
!(Assertions.use_assert_equal_with_highlight? == false)
|
144
|
+
expected_with_highlighting = ''
|
145
|
+
actual_with_highlighting = ''
|
146
|
+
full_message = nil
|
147
|
+
String.color_on! do
|
148
|
+
longest_string = [expected, actual].max {|a, b| a.length <=> b.length}
|
149
|
+
longest_string.each_char_with_index do |i, exp|
|
150
|
+
exp = expected[i] ? expected[i].chr : nil
|
151
|
+
act = actual[i] ? actual[i].chr : nil
|
152
|
+
if act.nil?
|
153
|
+
expected_with_highlighting << exp.highlight_unique
|
154
|
+
actual_with_highlighting << ' '.highlight_absence
|
155
|
+
elsif exp.nil?
|
156
|
+
expected_with_highlighting << ' '.highlight_absence
|
157
|
+
actual_with_highlighting << act.highlight_unique
|
158
|
+
|
159
|
+
elsif exp != act
|
160
|
+
expected_with_highlighting << exp.highlight_difference
|
161
|
+
actual_with_highlighting << act.highlight_difference
|
162
|
+
else
|
163
|
+
expected_with_highlighting << exp.highlight_commonality
|
164
|
+
actual_with_highlighting << exp.highlight_commonality
|
165
|
+
end
|
143
166
|
|
144
|
-
|
145
|
-
|
167
|
+
end
|
168
|
+
full_message = build_message(message, <<End, expected_with_highlighting, actual_with_highlighting)
|
146
169
|
#{(' '*50 + ' Expected: ' + ' '*50).blue.on_white }
|
147
170
|
?
|
148
171
|
#{(' '*50 + ' But was: ' + ' '*50).yellow.on_red }
|
149
172
|
?
|
150
173
|
End
|
174
|
+
end
|
175
|
+
AssertionMessage.inspect_strings!(options.delete(:inspect_strings) || false) do
|
176
|
+
assert_block(full_message) { expected == actual }
|
177
|
+
end
|
178
|
+
else
|
179
|
+
assert_equal_without_highlighting(expected, actual, message)
|
151
180
|
end
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
alias_method_chain :assert_equal, :difference_highlighting
|
181
|
+
|
182
|
+
end # use_assert_equal_with_highlight!
|
183
|
+
|
184
|
+
end # def assert_equal_with_highlighting
|
185
|
+
alias_method :assert_equal_with_difference_highlighting, :assert_equal_with_highlighting
|
186
|
+
alias_method_chain :assert_equal, :highlighting
|
159
187
|
|
160
188
|
end
|
161
189
|
end
|
@@ -176,9 +204,13 @@ end
|
|
176
204
|
#
|
177
205
|
=begin test
|
178
206
|
require 'test/unit'
|
207
|
+
#Test::Unit::Assertions::use_assert_equal_with_highlight!
|
208
|
+
|
209
|
+
# :todo: Currently these (intentionally failing) tests are just manual and require visual inspection. If possible it would be
|
210
|
+
# nice to capture the output of the failure and make an assertion against that. But I'm not sure how to do that...
|
179
211
|
|
180
212
|
class TheTest < Test::Unit::TestCase
|
181
|
-
def
|
213
|
+
def test01_single_character_difference
|
182
214
|
assert_equal <<End, <<End
|
183
215
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat mi. In sagittis, augue non eleifend sodales, arcu urna congue sapien, aliquet molestie pede urna sit amet dolor. Etiam diam. Vestibulum ornare, felis et porta faucibus, magna sapien vulputate arcu, vel facilisis lectus ipsum et ipsum.
|
184
216
|
|
@@ -190,22 +222,22 @@ Vivamus massa odio, lacinia eu, euismod vitae, lobortis eu, erat. Duis tincidunt
|
|
190
222
|
End
|
191
223
|
end
|
192
224
|
|
193
|
-
def
|
225
|
+
def test02_difference_in_control_characters
|
194
226
|
assert_equal "Lorem ipsum dolor sit amet,\nconsectetuer adipiscing elit.\nSed feugiat mi.",
|
195
|
-
"Lorem ipsum_dolor sit amet, consectetuer\tadipiscing elit.\n\rSed feugiat mi."
|
227
|
+
"Lorem ipsum_dolor sit amet, consectetuer\tadipiscing elit.\n\rSed feugiat mi.", :highlight => true
|
196
228
|
end
|
197
229
|
|
198
|
-
def
|
199
|
-
assert_equal '1234567890', '123'
|
230
|
+
def test03_expected_is_longer
|
231
|
+
assert_equal '1234567890', '123', :highlight => true
|
200
232
|
end
|
201
233
|
|
202
|
-
def
|
203
|
-
assert_equal '123', '1234567890'
|
234
|
+
def test04_actual_is_longer
|
235
|
+
assert_equal '123', '1234567890', :highlight => true
|
204
236
|
end
|
205
237
|
|
206
238
|
# Use the ones above this line as screenshot material...
|
207
239
|
|
208
|
-
def
|
240
|
+
def test05_one_is_much_longer
|
209
241
|
assert_equal <<End, <<End
|
210
242
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat mi. In sagittis, augue non eleifend sodales, arcu urna congue sapien, aliquet molestie pede urna sit amet dolor. Etiam diam. Vestibulum ornare, felis et porta faucibus, magna sapien vulputate arcu, vel facilisis lectus ipsum et ipsum. Sed dictum, dolor suscipit malesuada pharetra, orci augue lobortis lectus, porta porta magna magna ut dui. Duis viverra enim sed felis. Mauris semper volutpat pede. Integer lectus lorem, lacinia in, iaculis ut, euismod non, nulla. Nunc non libero eget diam congue ornare. Nunc dictum tellus sed turpis. Sed venenatis, pede non ultricies pharetra, dolor felis malesuada nisl, id imperdiet lorem dui vel velit.
|
211
243
|
End
|
@@ -213,7 +245,7 @@ Lorem ipsum dolor sit amet
|
|
213
245
|
End
|
214
246
|
end
|
215
247
|
|
216
|
-
def
|
248
|
+
def test06_only_minor_single_character_differences_but_then_it_gets_out_of_sync
|
217
249
|
assert_equal <<End, <<End
|
218
250
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat mi. In sagittis, augue non eleifend sodales, arcu urna congue sapien.
|
219
251
|
|
@@ -224,7 +256,8 @@ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat mi. In sag
|
|
224
256
|
Vivamus massa odio, lacinia eu, euismod vitae, lobortis eu, erat. Duis tincidunt, neque ac tincidunt convallis, nibh tellus sodales eros, ut tristique nunc purus in urna. Nullam semper. Fusce quis augue ut metus interdum congue. Duis id dolor eu mi pellentesque sagittis. Quisque imperdiet orci a odio.
|
225
257
|
End
|
226
258
|
end
|
227
|
-
|
259
|
+
|
260
|
+
def test07_underscores_versus_underlines
|
228
261
|
assert_equal <<End, <<End
|
229
262
|
If you look really closely, you'll see that underscores are a brighter color (bold), while spaces appear somewhaat faded, less visible:
|
230
263
|
___[Underscores]___[Underscores] [Spaces] _ _ _ _ _ [Mix]
|
@@ -234,9 +267,22 @@ If you look really closely, you'll see that underscores are a brighter color (bo
|
|
234
267
|
End
|
235
268
|
end
|
236
269
|
|
237
|
-
def
|
270
|
+
def test08_inspect_strings_true
|
238
271
|
assert_equal '1234567890', '123', :inspect_strings => true
|
239
272
|
end
|
273
|
+
def test09_inspect_highlight_false
|
274
|
+
assert_equal '1234567890', '123', :highlight => false
|
275
|
+
end
|
276
|
+
def test10_highlight_false
|
277
|
+
Test::Unit::Assertions::use_assert_equal_with_highlight! false do
|
278
|
+
assert_equal 'really long string', 'another really long string'
|
279
|
+
end
|
280
|
+
end
|
281
|
+
def test11_highlight_true
|
282
|
+
Test::Unit::Assertions::use_assert_equal_with_highlight! do
|
283
|
+
assert_equal 'really long string', 'another really long string'
|
284
|
+
end
|
285
|
+
end
|
240
286
|
|
241
287
|
end
|
242
288
|
=end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: qualitysmith_extensions
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-04-
|
6
|
+
version: 0.0.29
|
7
|
+
date: 2007-04-30 00:00:00 -07:00
|
8
8
|
summary: A collection of reusable Ruby methods developed by QualitySmith.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -53,13 +53,6 @@ files:
|
|
53
53
|
- lib/qualitysmith_extensions/kernel/backtrace.rb
|
54
54
|
- lib/qualitysmith_extensions/kernel/capture_output.rb
|
55
55
|
- lib/qualitysmith_extensions/kernel/trap_chain.rb
|
56
|
-
- lib/qualitysmith_extensions/module.bak/guard_method.rb
|
57
|
-
- lib/qualitysmith_extensions/module.bak/alias_method.rb
|
58
|
-
- lib/qualitysmith_extensions/module.bak/includable_once.rb
|
59
|
-
- lib/qualitysmith_extensions/module.bak/mattr_tester.rb
|
60
|
-
- lib/qualitysmith_extensions/module.bak/create_setter.rb
|
61
|
-
- lib/qualitysmith_extensions/module.bak/attribute_accessors.rb
|
62
|
-
- lib/qualitysmith_extensions/module.bak/bool_attr_accessor.rb
|
63
56
|
- lib/qualitysmith_extensions/dir/each_child.rb
|
64
57
|
- lib/qualitysmith_extensions/object/singleton_send.rb
|
65
58
|
- lib/qualitysmith_extensions/object/mcall.rb
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# Copied from ActiveSupport because I couldn't get the ones in Facets to work...
|
2
|
-
|
3
|
-
# Extends the module object with module and instance accessors for class attributes,
|
4
|
-
# just like the native attr* accessors for instance attributes.
|
5
|
-
class Module # :nodoc:
|
6
|
-
def mattr_reader(*syms)
|
7
|
-
syms.each do |sym|
|
8
|
-
class_eval(<<-EOS, __FILE__, __LINE__+1)
|
9
|
-
unless defined? @@#{sym}
|
10
|
-
@@#{sym} = nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.#{sym}
|
14
|
-
@@#{sym}
|
15
|
-
end
|
16
|
-
|
17
|
-
def #{sym}
|
18
|
-
@@#{sym}
|
19
|
-
end
|
20
|
-
EOS
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def mattr_writer(*syms)
|
25
|
-
syms.each do |sym|
|
26
|
-
class_eval(<<-EOS, __FILE__, __LINE__+1)
|
27
|
-
unless defined? @@#{sym}
|
28
|
-
@@#{sym} = nil
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.#{sym}=(obj)
|
32
|
-
@@#{sym} = obj
|
33
|
-
end
|
34
|
-
|
35
|
-
def #{sym}=(obj)
|
36
|
-
@@#{sym} = obj
|
37
|
-
end
|
38
|
-
EOS
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def mattr_accessor(*syms)
|
43
|
-
mattr_reader(*syms)
|
44
|
-
mattr_writer(*syms)
|
45
|
-
end
|
46
|
-
end
|
@@ -1,334 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Author:: Thomas Sawyer, Tyler Rick
|
3
|
-
# Copyright:: Copyright (c) Thomas Sawyer, probably, since this is a derivative work
|
4
|
-
# License:: Ruby License
|
5
|
-
# Submit to Facets?:: Yes
|
6
|
-
# Developer notes::
|
7
|
-
# * Based on /usr/lib/ruby/gems/1.8/gems/facets-1.8.54/lib/facets/core/module/attr_tester.rb
|
8
|
-
# * Hey Thomas, don't you think Module#attr_tester should only create the read-only a? method and have another method that creates the writer (like there how we have attr_reader, _writer, and _accessor?) ? "tester" does not imply "setter" in my mind...
|
9
|
-
# * I'm going to rename this one to bool_attr_accessor, which calls both bool_attr_reader and bool_attr_writer
|
10
|
-
# * Then you also have the option to use bool_attr_reader and bool_attr_writer separately if you so desire.
|
11
|
-
# * Other changes made:
|
12
|
-
# * Changed it so that if you call a!(false) it would actually set @a to false rather than leaving it unchanged. (I assume that was a bug.)
|
13
|
-
#++
|
14
|
-
|
15
|
-
|
16
|
-
class Module
|
17
|
-
|
18
|
-
# This creates two methods for each given variable name. One is used to test
|
19
|
-
# the attribute and the other is used to set or toggle it.
|
20
|
-
#
|
21
|
-
# bool_attr_accessor :a
|
22
|
-
#
|
23
|
-
# is equivalent to
|
24
|
-
#
|
25
|
-
# def a?
|
26
|
-
# @a ? true : @a
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# def a!(switch=Exception)
|
30
|
-
# if switch == Exception
|
31
|
-
# @a = !@a
|
32
|
-
# else
|
33
|
-
# @a = switch ? true : false
|
34
|
-
# self
|
35
|
-
# end
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# Examples:
|
39
|
-
# x = Klass.new
|
40
|
-
# x.a! true # sets @a to true
|
41
|
-
# x.a! # toggles @a, so that it ends up being false
|
42
|
-
# x.a! # toggles @a, so that it ends up being true
|
43
|
-
# x.a! false # sets @a to false
|
44
|
-
#
|
45
|
-
def bool_attr_accessor(*args)
|
46
|
-
|
47
|
-
make = {}
|
48
|
-
args.each { |a|
|
49
|
-
make["#{a}?".to_sym] = %{
|
50
|
-
def #{a}?(true_value=true)
|
51
|
-
@#{a} ? true_value : @#{a}
|
52
|
-
end
|
53
|
-
}
|
54
|
-
make["#{a}!".to_sym] = %{
|
55
|
-
def #{a}!(switch=Exception)
|
56
|
-
if switch == Exception
|
57
|
-
@#{a} = !@#{a}
|
58
|
-
else
|
59
|
-
@#{a} = switch ? true : false
|
60
|
-
# used to be @#{a} instead of false in Facets version
|
61
|
-
self
|
62
|
-
end
|
63
|
-
end
|
64
|
-
}
|
65
|
-
}
|
66
|
-
module_eval make.values.join("\n"), __FILE__, __LINE__
|
67
|
-
|
68
|
-
make.keys
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
class Module
|
74
|
-
# This creates two methods for each given variable name. One is used to test
|
75
|
-
# the attribute and the other is used to set or toggle it.
|
76
|
-
#
|
77
|
-
# bool_attr_accessor :a
|
78
|
-
#
|
79
|
-
# is equivalent to
|
80
|
-
#
|
81
|
-
# def self.a?
|
82
|
-
# @@a ? true : @@a
|
83
|
-
# end
|
84
|
-
#
|
85
|
-
# def self.a!(switch=Exception)
|
86
|
-
# if switch == Exception
|
87
|
-
# @@a = !@@a
|
88
|
-
# else
|
89
|
-
# @@a = switch ? true : false
|
90
|
-
# self
|
91
|
-
# end
|
92
|
-
# end
|
93
|
-
#
|
94
|
-
# Works for both classes and modules.
|
95
|
-
#
|
96
|
-
def mbool_attr_accessor(*args)
|
97
|
-
|
98
|
-
make = {}
|
99
|
-
args.each { |a|
|
100
|
-
# Initialize it first so that we won't have any NameErrors.
|
101
|
-
module_eval %{ @@#{a} = nil if !defined?(@@#{a}) }, __FILE__, __LINE__
|
102
|
-
|
103
|
-
make["#{a}?".to_sym] = %{
|
104
|
-
def self.#{a}?(true_value=true)
|
105
|
-
@@#{a} ? true_value : @@#{a}
|
106
|
-
end
|
107
|
-
}
|
108
|
-
make["#{a}!".to_sym] = %{
|
109
|
-
def self.#{a}!(switch=Exception)
|
110
|
-
if switch == Exception
|
111
|
-
@@#{a} = !@@#{a}
|
112
|
-
else
|
113
|
-
@@#{a} = switch ? true : false
|
114
|
-
self
|
115
|
-
end
|
116
|
-
end
|
117
|
-
}
|
118
|
-
}
|
119
|
-
module_eval make.values.join("\n"), __FILE__, __LINE__
|
120
|
-
|
121
|
-
make.keys
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
# _____ _
|
128
|
-
# |_ _|__ ___| |_
|
129
|
-
# | |/ _ \/ __| __|
|
130
|
-
# | | __/\__ \ |_
|
131
|
-
# |_|\___||___/\__|
|
132
|
-
#
|
133
|
-
=begin test
|
134
|
-
require 'test/unit'
|
135
|
-
require 'rubygems'
|
136
|
-
require 'qualitysmith_extensions/object/ignore_access'
|
137
|
-
require 'set'
|
138
|
-
|
139
|
-
# Test that it works for *instances*
|
140
|
-
class TestBoolAttr < Test::Unit::TestCase
|
141
|
-
def setup
|
142
|
-
@x = C.new
|
143
|
-
end
|
144
|
-
|
145
|
-
class C
|
146
|
-
bool_attr_accessor :a
|
147
|
-
end
|
148
|
-
|
149
|
-
class C_for_default_is_nil
|
150
|
-
bool_attr_accessor :a
|
151
|
-
end
|
152
|
-
|
153
|
-
def test1_default_is_nil
|
154
|
-
assert_equal nil, C_for_default_is_nil.new.a?
|
155
|
-
end
|
156
|
-
|
157
|
-
def test2_toggle
|
158
|
-
assert_equal nil, @x.a?
|
159
|
-
@x.a!
|
160
|
-
assert_equal true, @x.a?
|
161
|
-
@x.a!
|
162
|
-
assert_equal false, @x.a?
|
163
|
-
end
|
164
|
-
|
165
|
-
def test3_setter
|
166
|
-
@x.a! true
|
167
|
-
@x.a! true
|
168
|
-
assert_equal true, @x.a?
|
169
|
-
|
170
|
-
@x.a! false
|
171
|
-
assert_equal false, @x.a?
|
172
|
-
end
|
173
|
-
def test4_sets_to_boolean_even_if_try_to_set_to_other_type
|
174
|
-
@x.a! "whatever"
|
175
|
-
assert_equal true, @x.a? # Still returns a boolean even though we tried to set it to a string.
|
176
|
-
|
177
|
-
@x.a! nil
|
178
|
-
assert_equal false, @x.a? # Still returns a boolean even though we tried to set it to nil.
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
# Test that it works for *modules*
|
183
|
-
class TestForModules < Test::Unit::TestCase
|
184
|
-
|
185
|
-
class M_for_default_is_nil
|
186
|
-
mbool_attr_accessor :a
|
187
|
-
end
|
188
|
-
def test1_default_is_nil
|
189
|
-
assert_equal nil, M_for_default_is_nil.a?
|
190
|
-
end
|
191
|
-
|
192
|
-
module M
|
193
|
-
mbool_attr_accessor :a
|
194
|
-
end
|
195
|
-
def test2_toggle
|
196
|
-
assert_equal nil, M.a?
|
197
|
-
M.a!
|
198
|
-
assert_equal true, M.a?
|
199
|
-
M.a!
|
200
|
-
assert_equal false, M.a?
|
201
|
-
end
|
202
|
-
def test3_setter
|
203
|
-
M.a! true
|
204
|
-
M.a! true
|
205
|
-
assert_equal true, M.a?
|
206
|
-
|
207
|
-
M.a! false
|
208
|
-
assert_equal false, M.a?
|
209
|
-
end
|
210
|
-
def test4_sets_to_boolean_even_if_try_to_set_to_other_type
|
211
|
-
M.a! "whatever"
|
212
|
-
assert_equal true, M.a? # Still returns a boolean even though we tried to set it to a string.
|
213
|
-
|
214
|
-
M.a! nil
|
215
|
-
assert_equal false, M.a? # Still returns a boolean even though we tried to set it to nil.
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
# Test that it also works for *classes*
|
220
|
-
class TestForClasses < Test::Unit::TestCase
|
221
|
-
|
222
|
-
class C_for_default_is_nil
|
223
|
-
mbool_attr_accessor :a
|
224
|
-
end
|
225
|
-
def test1_default_is_nil
|
226
|
-
assert_equal nil, C_for_default_is_nil.a?
|
227
|
-
end
|
228
|
-
|
229
|
-
class C
|
230
|
-
mbool_attr_accessor :a
|
231
|
-
end
|
232
|
-
|
233
|
-
def test2_toggle
|
234
|
-
C.access.class_variable_set :@@a, false
|
235
|
-
assert_equal false, C.a? # otherwise would have been nil
|
236
|
-
C.a!
|
237
|
-
assert_equal true, C.a?
|
238
|
-
C.a!
|
239
|
-
assert_equal false, C.a?
|
240
|
-
|
241
|
-
assert_equal ["@_ignore_access_functor"], C.instance_variables
|
242
|
-
assert_equal ["@@a"], C.class_variables
|
243
|
-
end
|
244
|
-
|
245
|
-
def test3_setter
|
246
|
-
C.a! true
|
247
|
-
C.a! true
|
248
|
-
assert_equal true, C.a?
|
249
|
-
|
250
|
-
C.a! false
|
251
|
-
assert_equal false, C.a?
|
252
|
-
end
|
253
|
-
def test4_sets_to_boolean_even_if_try_to_set_to_other_type
|
254
|
-
C.a! "whatever"
|
255
|
-
assert_equal true, C.a? # Still returns a boolean even though we tried to set it to a string.
|
256
|
-
|
257
|
-
C.a! nil
|
258
|
-
assert_equal false, C.a? # Still returns a boolean even though we tried to set it to nil.
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
|
263
|
-
# Observation: You can also the normal bool_attr_accessor in conjunction with class << self.
|
264
|
-
# The methods generated seem to *behave* in the same way. Both techniques allow you to query the class, C.a?
|
265
|
-
# The only difference is in which *variables* are use to store the state:
|
266
|
-
# * class << self and the normal bool_attr_accessor:
|
267
|
-
# Stores the state in an instance variable for the *class*: @a
|
268
|
-
# * mbool_attr_accessor:
|
269
|
-
# Stores the state in a *class* variable: @@a
|
270
|
-
#
|
271
|
-
# Can someone explain to me the difference between class variables and instance variables of a class?
|
272
|
-
# It seems silly (confusing even!) to have both of them!
|
273
|
-
#
|
274
|
-
# My best explanation is that the fact that we can even *have* instance variables of a class does *not* mean it's a good idea
|
275
|
-
# to use them. It simply means that Matz made the language with as few arbitrary restrictions as possible. He made it
|
276
|
-
# technically *possible* to do a lot of things that it is probably not good practice to do... And one of those things is
|
277
|
-
# using instance variables of classes to store state information for that class.
|
278
|
-
#
|
279
|
-
# What do you think class variables are for? Exactly that! There's a *reason* we have both @a and @@a variables -- to
|
280
|
-
# *differentiate* between the two kinds of variables and keep programmers sane. So please don't blur the distinction and
|
281
|
-
# use the @a-type variable to do the job that @@a-type variables are for.
|
282
|
-
#
|
283
|
-
# Or am I missing something here?
|
284
|
-
#
|
285
|
-
class TestWith_class_self_and_plain_bool_attr_accessor < Test::Unit::TestCase
|
286
|
-
|
287
|
-
class C_for_default_is_nil
|
288
|
-
class << self
|
289
|
-
bool_attr_accessor :a
|
290
|
-
end
|
291
|
-
end
|
292
|
-
def test1_default_is_nil
|
293
|
-
assert_equal nil, C_for_default_is_nil.a?
|
294
|
-
end
|
295
|
-
|
296
|
-
class C
|
297
|
-
class << self
|
298
|
-
bool_attr_accessor :a
|
299
|
-
end
|
300
|
-
end
|
301
|
-
# This is where I spotted a class that uses this technique:
|
302
|
-
# * Test::Unit::Assertions::AssertionMessage
|
303
|
-
|
304
|
-
def test_2_toggle
|
305
|
-
assert_equal false, C.a? # Why isn't it nil like it is for the instance use case of bool_attr_accessor?
|
306
|
-
C.a!
|
307
|
-
assert_equal true, C.a?
|
308
|
-
C.a!
|
309
|
-
assert_equal false, C.a?
|
310
|
-
|
311
|
-
assert_equal ["@a"], C.instance_variables
|
312
|
-
assert_equal [], C.new.instance_variables # @a is an instance variable of the *class* *not* objects of the class -- weird!
|
313
|
-
assert_equal [], C.class_variables
|
314
|
-
end
|
315
|
-
|
316
|
-
def test3_setter
|
317
|
-
C.a! true
|
318
|
-
C.a! true
|
319
|
-
assert_equal true, C.a?
|
320
|
-
|
321
|
-
C.a! false
|
322
|
-
assert_equal false, C.a?
|
323
|
-
end
|
324
|
-
def test4_sets_to_boolean_even_if_try_to_set_to_other_type
|
325
|
-
C.a! "whatever"
|
326
|
-
assert_equal true, C.a? # Still returns a boolean even though we tried to set it to a string.
|
327
|
-
|
328
|
-
C.a! nil
|
329
|
-
assert_equal false, C.a? # Still returns a boolean even though we tried to set it to nil.
|
330
|
-
end
|
331
|
-
|
332
|
-
end
|
333
|
-
=end
|
334
|
-
|