gorillib 0.0.2
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/LICENSE.textile +81 -0
- data/README.textile +153 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/fiddle/hubahuba.rb +62 -0
- data/gorillib.gemspec +142 -0
- data/lib/gorillib/array/compact_blank.rb +17 -0
- data/lib/gorillib/array/extract_options.rb +29 -0
- data/lib/gorillib/base.rb +7 -0
- data/lib/gorillib/datetime/flat.rb +29 -0
- data/lib/gorillib/datetime/parse.rb +21 -0
- data/lib/gorillib/enumerable/sum.rb +38 -0
- data/lib/gorillib/hash/compact.rb +31 -0
- data/lib/gorillib/hash/deep_merge.rb +16 -0
- data/lib/gorillib/hash/keys.rb +42 -0
- data/lib/gorillib/hash/reverse_merge.rb +26 -0
- data/lib/gorillib/hash/slice.rb +53 -0
- data/lib/gorillib/hash/zip.rb +10 -0
- data/lib/gorillib/logger/log.rb +14 -0
- data/lib/gorillib/metaprogramming/aliasing.rb +43 -0
- data/lib/gorillib/metaprogramming/cattr_accessor.rb +79 -0
- data/lib/gorillib/metaprogramming/class_attribute.rb +90 -0
- data/lib/gorillib/metaprogramming/delegation.rb +146 -0
- data/lib/gorillib/metaprogramming/mattr_accessor.rb +61 -0
- data/lib/gorillib/metaprogramming/remove_method.rb +11 -0
- data/lib/gorillib/metaprogramming/singleton_class.rb +8 -0
- data/lib/gorillib/object/blank.rb +89 -0
- data/lib/gorillib/some.rb +12 -0
- data/lib/gorillib/string/constantize.rb +21 -0
- data/lib/gorillib/string/human.rb +52 -0
- data/lib/gorillib/string/inflections.rb +78 -0
- data/lib/gorillib/string/truncate.rb +33 -0
- data/lib/gorillib.rb +1 -0
- data/spec/blank_spec.rb +86 -0
- data/spec/gorillib_spec.rb +7 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/spec_tasks.rake +15 -0
- data/test/abstract_unit.rb +25 -0
- data/test/array/compact_blank_test.rb +33 -0
- data/test/array/extract_options_test.rb +39 -0
- data/test/datetime/flat_test.rb +0 -0
- data/test/datetime/parse_test.rb +0 -0
- data/test/enumerable/sum_test.rb +50 -0
- data/test/hash/compact_test.rb +38 -0
- data/test/hash/deep_merge_test.rb +30 -0
- data/test/hash/keys_test.rb +110 -0
- data/test/hash/reverse_merge_test.rb +20 -0
- data/test/hash/slice_test.rb +47 -0
- data/test/hash/zip_test.rb +0 -0
- data/test/logger/log_test.rb +0 -0
- data/test/metaprogramming/aliasing_test.rb +188 -0
- data/test/metaprogramming/cattr_accessor_test.rb +38 -0
- data/test/metaprogramming/class_attribute_test.rb +73 -0
- data/test/metaprogramming/delegation_test.rb +166 -0
- data/test/metaprogramming/mattr_accessor_test.rb +40 -0
- data/test/metaprogramming/singleton_class_test.rb +9 -0
- data/test/object/blank_test.rb +22 -0
- data/test/string/constantize_test.rb +30 -0
- data/test/string/human_test.rb +65 -0
- data/test/string/inflections_test.rb +57 -0
- data/test/string/inflector_test_cases.rb +50 -0
- data/test/string/truncate_test.rb +37 -0
- metadata +199 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/hash/keys'
|
3
|
+
|
4
|
+
class HashSymbolizeKeysTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class IndifferentHash < HashWithIndifferentAccess
|
7
|
+
end
|
8
|
+
|
9
|
+
class SubclassingArray < Array
|
10
|
+
end
|
11
|
+
|
12
|
+
class SubclassingHash < Hash
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def setup
|
17
|
+
@strings = { 'a' => 1, 'b' => 2 }
|
18
|
+
@symbols = { :a => 1, :b => 2 }
|
19
|
+
@mixed = { :a => 1, 'b' => 2 }
|
20
|
+
@fixnums = { 0 => 1, 1 => 2 }
|
21
|
+
if RUBY_VERSION < '1.9.0'
|
22
|
+
@illegal_symbols = { "\0" => 1, "" => 2, [] => 3 }
|
23
|
+
else
|
24
|
+
@illegal_symbols = { [] => 3 }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_methods
|
29
|
+
h = {}
|
30
|
+
assert_respond_to h, :symbolize_keys
|
31
|
+
assert_respond_to h, :symbolize_keys!
|
32
|
+
assert_respond_to h, :stringify_keys
|
33
|
+
assert_respond_to h, :stringify_keys!
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_symbolize_keys
|
37
|
+
assert_equal @symbols, @symbols.symbolize_keys
|
38
|
+
assert_equal @symbols, @strings.symbolize_keys
|
39
|
+
assert_equal @symbols, @mixed.symbolize_keys
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_symbolize_keys!
|
43
|
+
assert_equal @symbols, @symbols.dup.symbolize_keys!
|
44
|
+
assert_equal @symbols, @strings.dup.symbolize_keys!
|
45
|
+
assert_equal @symbols, @mixed.dup.symbolize_keys!
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_symbolize_keys_preserves_keys_that_cant_be_symbolized
|
49
|
+
assert_equal @illegal_symbols, @illegal_symbols.symbolize_keys
|
50
|
+
assert_equal @illegal_symbols, @illegal_symbols.dup.symbolize_keys!
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_symbolize_keys_preserves_fixnum_keys
|
54
|
+
assert_equal @fixnums, @fixnums.symbolize_keys
|
55
|
+
assert_equal @fixnums, @fixnums.dup.symbolize_keys!
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_stringify_keys
|
59
|
+
assert_equal @strings, @symbols.stringify_keys
|
60
|
+
assert_equal @strings, @strings.stringify_keys
|
61
|
+
assert_equal @strings, @mixed.stringify_keys
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_stringify_keys!
|
65
|
+
assert_equal @strings, @symbols.dup.stringify_keys!
|
66
|
+
assert_equal @strings, @strings.dup.stringify_keys!
|
67
|
+
assert_equal @strings, @mixed.dup.stringify_keys!
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_symbolize_keys_for_hash_with_indifferent_access
|
71
|
+
assert_instance_of Hash, @symbols.with_indifferent_access.symbolize_keys
|
72
|
+
assert_equal @symbols, @symbols.with_indifferent_access.symbolize_keys
|
73
|
+
assert_equal @symbols, @strings.with_indifferent_access.symbolize_keys
|
74
|
+
assert_equal @symbols, @mixed.with_indifferent_access.symbolize_keys
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_symbolize_keys_bang_for_hash_with_indifferent_access
|
78
|
+
assert_raise(NoMethodError) { @symbols.with_indifferent_access.dup.symbolize_keys! }
|
79
|
+
assert_raise(NoMethodError) { @strings.with_indifferent_access.dup.symbolize_keys! }
|
80
|
+
assert_raise(NoMethodError) { @mixed.with_indifferent_access.dup.symbolize_keys! }
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_symbolize_keys_preserves_keys_that_cant_be_symbolized_for_hash_with_indifferent_access
|
84
|
+
assert_equal @illegal_symbols, @illegal_symbols.with_indifferent_access.symbolize_keys
|
85
|
+
assert_raise(NoMethodError) { @illegal_symbols.with_indifferent_access.dup.symbolize_keys! }
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_symbolize_keys_preserves_fixnum_keys_for_hash_with_indifferent_access
|
89
|
+
assert_equal @fixnums, @fixnums.with_indifferent_access.symbolize_keys
|
90
|
+
assert_raise(NoMethodError) { @fixnums.with_indifferent_access.dup.symbolize_keys! }
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_hash_subclass
|
94
|
+
flash = { "foo" => SubclassingHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access
|
95
|
+
assert_kind_of SubclassingHash, flash["foo"]
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_assert_valid_keys
|
99
|
+
assert_nothing_raised do
|
100
|
+
{ :failure => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny ])
|
101
|
+
{ :failure => "stuff", :funny => "business" }.assert_valid_keys(:failure, :funny)
|
102
|
+
end
|
103
|
+
|
104
|
+
assert_raise(ArgumentError, "Unknown key: failore") do
|
105
|
+
{ :failore => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny ])
|
106
|
+
{ :failore => "stuff", :funny => "business" }.assert_valid_keys(:failure, :funny)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/hash/reverse_merge'
|
3
|
+
|
4
|
+
class HashReverseMergeTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_reverse_merge
|
7
|
+
defaults = { :a => "x", :b => "y", :c => 10 }.freeze
|
8
|
+
options = { :a => 1, :b => 2 }
|
9
|
+
expected = { :a => 1, :b => 2, :c => 10 }
|
10
|
+
|
11
|
+
# Should merge defaults into options, creating a new hash.
|
12
|
+
assert_equal expected, options.reverse_merge(defaults)
|
13
|
+
assert_not_equal expected, options
|
14
|
+
|
15
|
+
# Should merge! defaults into options, replacing options.
|
16
|
+
merged = options.dup
|
17
|
+
assert_equal expected, merged.reverse_merge!(defaults)
|
18
|
+
assert_equal expected, merged
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/hash/slice'
|
3
|
+
|
4
|
+
class HashSliceTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_slice
|
7
|
+
original = { :a => 'x', :b => 'y', :c => 10 }
|
8
|
+
expected = { :a => 'x', :b => 'y' }
|
9
|
+
|
10
|
+
# Should return a new hash with only the given keys.
|
11
|
+
assert_equal expected, original.slice(:a, :b)
|
12
|
+
assert_not_equal expected, original
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_slice_inplace
|
16
|
+
original = { :a => 'x', :b => 'y', :c => 10 }
|
17
|
+
expected = { :c => 10 }
|
18
|
+
|
19
|
+
# Should replace the hash with only the given keys.
|
20
|
+
assert_equal expected, original.slice!(:a, :b)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_slice_with_an_array_key
|
24
|
+
original = { :a => 'x', :b => 'y', :c => 10, [:a, :b] => "an array key" }
|
25
|
+
expected = { [:a, :b] => "an array key", :c => 10 }
|
26
|
+
|
27
|
+
# Should return a new hash with only the given keys when given an array key.
|
28
|
+
assert_equal expected, original.slice([:a, :b], :c)
|
29
|
+
assert_not_equal expected, original
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_slice_inplace_with_an_array_key
|
33
|
+
original = { :a => 'x', :b => 'y', :c => 10, [:a, :b] => "an array key" }
|
34
|
+
expected = { :a => 'x', :b => 'y' }
|
35
|
+
|
36
|
+
# Should replace the hash with only the given keys when given an array key.
|
37
|
+
assert_equal expected, original.slice!([:a, :b], :c)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_slice_with_splatted_keys
|
41
|
+
original = { :a => 'x', :b => 'y', :c => 10, [:a, :b] => "an array key" }
|
42
|
+
expected = { :a => 'x', :b => "y" }
|
43
|
+
|
44
|
+
# Should grab each of the splatted keys.
|
45
|
+
assert_equal expected, original.slice(*[:a, :b])
|
46
|
+
end
|
47
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/aliasing'
|
3
|
+
|
4
|
+
module BarMethodAliaser
|
5
|
+
def self.included(foo_class)
|
6
|
+
foo_class.class_eval do
|
7
|
+
include BarMethods
|
8
|
+
alias_method_chain :bar, :baz
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module BarMethods
|
14
|
+
def bar_with_baz
|
15
|
+
bar_without_baz << '_with_baz'
|
16
|
+
end
|
17
|
+
|
18
|
+
def quux_with_baz!
|
19
|
+
quux_without_baz! << '_with_baz'
|
20
|
+
end
|
21
|
+
|
22
|
+
def quux_with_baz?
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def quux_with_baz=(v)
|
27
|
+
send(:quux_without_baz=, v) << '_with_baz'
|
28
|
+
end
|
29
|
+
|
30
|
+
def duck_with_orange
|
31
|
+
duck_without_orange << '_with_orange'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class MethodAliasingTest < Test::Unit::TestCase
|
36
|
+
def setup
|
37
|
+
Object.const_set :FooClassWithBarMethod, Class.new { def bar() 'bar' end }
|
38
|
+
@instance = FooClassWithBarMethod.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def teardown
|
42
|
+
Object.instance_eval { remove_const :FooClassWithBarMethod }
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_alias_method_chain
|
46
|
+
assert @instance.respond_to?(:bar)
|
47
|
+
feature_aliases = [:bar_with_baz, :bar_without_baz]
|
48
|
+
|
49
|
+
feature_aliases.each do |method|
|
50
|
+
assert !@instance.respond_to?(method)
|
51
|
+
end
|
52
|
+
|
53
|
+
assert_equal 'bar', @instance.bar
|
54
|
+
|
55
|
+
FooClassWithBarMethod.class_eval { include BarMethodAliaser }
|
56
|
+
|
57
|
+
feature_aliases.each do |method|
|
58
|
+
assert_respond_to @instance, method
|
59
|
+
end
|
60
|
+
|
61
|
+
assert_equal 'bar_with_baz', @instance.bar
|
62
|
+
assert_equal 'bar', @instance.bar_without_baz
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_alias_method_chain_with_punctuation_method
|
66
|
+
FooClassWithBarMethod.class_eval do
|
67
|
+
def quux!; 'quux' end
|
68
|
+
end
|
69
|
+
|
70
|
+
assert !@instance.respond_to?(:quux_with_baz!)
|
71
|
+
FooClassWithBarMethod.class_eval do
|
72
|
+
include BarMethodAliaser
|
73
|
+
alias_method_chain :quux!, :baz
|
74
|
+
end
|
75
|
+
assert_respond_to @instance, :quux_with_baz!
|
76
|
+
|
77
|
+
assert_equal 'quux_with_baz', @instance.quux!
|
78
|
+
assert_equal 'quux', @instance.quux_without_baz!
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_alias_method_chain_with_same_names_between_predicates_and_bang_methods
|
82
|
+
FooClassWithBarMethod.class_eval do
|
83
|
+
def quux!; 'quux!' end
|
84
|
+
def quux?; true end
|
85
|
+
def quux=(v); 'quux=' end
|
86
|
+
end
|
87
|
+
|
88
|
+
assert !@instance.respond_to?(:quux_with_baz!)
|
89
|
+
assert !@instance.respond_to?(:quux_with_baz?)
|
90
|
+
assert !@instance.respond_to?(:quux_with_baz=)
|
91
|
+
|
92
|
+
FooClassWithBarMethod.class_eval { include BarMethodAliaser }
|
93
|
+
assert_respond_to @instance, :quux_with_baz!
|
94
|
+
assert_respond_to @instance, :quux_with_baz?
|
95
|
+
assert_respond_to @instance, :quux_with_baz=
|
96
|
+
|
97
|
+
|
98
|
+
FooClassWithBarMethod.alias_method_chain :quux!, :baz
|
99
|
+
assert_equal 'quux!_with_baz', @instance.quux!
|
100
|
+
assert_equal 'quux!', @instance.quux_without_baz!
|
101
|
+
|
102
|
+
FooClassWithBarMethod.alias_method_chain :quux?, :baz
|
103
|
+
assert_equal false, @instance.quux?
|
104
|
+
assert_equal true, @instance.quux_without_baz?
|
105
|
+
|
106
|
+
FooClassWithBarMethod.alias_method_chain :quux=, :baz
|
107
|
+
assert_equal 'quux=_with_baz', @instance.send(:quux=, 1234)
|
108
|
+
assert_equal 'quux=', @instance.send(:quux_without_baz=, 1234)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_alias_method_chain_with_feature_punctuation
|
112
|
+
FooClassWithBarMethod.class_eval do
|
113
|
+
def quux; 'quux' end
|
114
|
+
def quux?; 'quux?' end
|
115
|
+
include BarMethodAliaser
|
116
|
+
alias_method_chain :quux, :baz!
|
117
|
+
end
|
118
|
+
|
119
|
+
assert_nothing_raised do
|
120
|
+
assert_equal 'quux_with_baz', @instance.quux_with_baz!
|
121
|
+
end
|
122
|
+
|
123
|
+
assert_raise(NameError) do
|
124
|
+
FooClassWithBarMethod.alias_method_chain :quux?, :baz!
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_alias_method_chain_yields_target_and_punctuation
|
129
|
+
args = nil
|
130
|
+
|
131
|
+
FooClassWithBarMethod.class_eval do
|
132
|
+
def quux?; end
|
133
|
+
include BarMethods
|
134
|
+
|
135
|
+
FooClassWithBarMethod.alias_method_chain :quux?, :baz do |target, punctuation|
|
136
|
+
args = [target, punctuation]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
assert_not_nil args
|
141
|
+
assert_equal 'quux', args[0]
|
142
|
+
assert_equal '?', args[1]
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_alias_method_chain_preserves_private_method_status
|
146
|
+
FooClassWithBarMethod.class_eval do
|
147
|
+
def duck; 'duck' end
|
148
|
+
include BarMethodAliaser
|
149
|
+
private :duck
|
150
|
+
alias_method_chain :duck, :orange
|
151
|
+
end
|
152
|
+
|
153
|
+
assert_raise NoMethodError do
|
154
|
+
@instance.duck
|
155
|
+
end
|
156
|
+
|
157
|
+
assert_equal 'duck_with_orange', @instance.instance_eval { duck }
|
158
|
+
assert FooClassWithBarMethod.private_method_defined?(:duck)
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_alias_method_chain_preserves_protected_method_status
|
162
|
+
FooClassWithBarMethod.class_eval do
|
163
|
+
def duck; 'duck' end
|
164
|
+
include BarMethodAliaser
|
165
|
+
protected :duck
|
166
|
+
alias_method_chain :duck, :orange
|
167
|
+
end
|
168
|
+
|
169
|
+
assert_raise NoMethodError do
|
170
|
+
@instance.duck
|
171
|
+
end
|
172
|
+
|
173
|
+
assert_equal 'duck_with_orange', @instance.instance_eval { duck }
|
174
|
+
assert FooClassWithBarMethod.protected_method_defined?(:duck)
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_alias_method_chain_preserves_public_method_status
|
178
|
+
FooClassWithBarMethod.class_eval do
|
179
|
+
def duck; 'duck' end
|
180
|
+
include BarMethodAliaser
|
181
|
+
public :duck
|
182
|
+
alias_method_chain :duck, :orange
|
183
|
+
end
|
184
|
+
|
185
|
+
assert_equal 'duck_with_orange', @instance.duck
|
186
|
+
assert FooClassWithBarMethod.public_method_defined?(:duck)
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/metaprogramming/cattr_accessor'
|
3
|
+
|
4
|
+
class ClassAttributeAccessorTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@class = Class.new do
|
7
|
+
cattr_accessor :foo
|
8
|
+
cattr_accessor :bar, :instance_writer => false
|
9
|
+
cattr_reader :shaq, :instance_reader => false
|
10
|
+
end
|
11
|
+
@object = @class.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_should_use_mattr_default
|
15
|
+
assert_nil @class.foo
|
16
|
+
assert_nil @object.foo
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_set_mattr_value
|
20
|
+
@class.foo = :test
|
21
|
+
assert_equal :test, @object.foo
|
22
|
+
|
23
|
+
@object.foo = :test2
|
24
|
+
assert_equal :test2, @class.foo
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_not_create_instance_writer
|
28
|
+
assert_respond_to @class, :foo
|
29
|
+
assert_respond_to @class, :foo=
|
30
|
+
assert_respond_to @object, :bar
|
31
|
+
assert !@object.respond_to?(:bar=)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_should_not_create_instance_reader
|
35
|
+
assert_respond_to @class, :shaq
|
36
|
+
assert !@object.respond_to?(:shaq)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/metaprogramming/class_attribute'
|
3
|
+
|
4
|
+
class ClassAttributeTest < ActiveSupport::TestCase
|
5
|
+
def setup
|
6
|
+
@klass = Class.new { class_attribute :setting }
|
7
|
+
@sub = Class.new(@klass)
|
8
|
+
end
|
9
|
+
|
10
|
+
test 'defaults to nil' do
|
11
|
+
assert_nil @klass.setting
|
12
|
+
assert_nil @sub.setting
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'inheritable' do
|
16
|
+
@klass.setting = 1
|
17
|
+
assert_equal 1, @sub.setting
|
18
|
+
end
|
19
|
+
|
20
|
+
test 'overridable' do
|
21
|
+
@sub.setting = 1
|
22
|
+
assert_nil @klass.setting
|
23
|
+
|
24
|
+
@klass.setting = 2
|
25
|
+
assert_equal 1, @sub.setting
|
26
|
+
|
27
|
+
assert_equal 1, Class.new(@sub).setting
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'query method' do
|
31
|
+
assert_equal false, @klass.setting?
|
32
|
+
@klass.setting = 1
|
33
|
+
assert_equal true, @klass.setting?
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'instance reader delegates to class' do
|
37
|
+
assert_nil @klass.new.setting
|
38
|
+
|
39
|
+
@klass.setting = 1
|
40
|
+
assert_equal 1, @klass.new.setting
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'instance override' do
|
44
|
+
object = @klass.new
|
45
|
+
object.setting = 1
|
46
|
+
assert_nil @klass.setting
|
47
|
+
@klass.setting = 2
|
48
|
+
assert_equal 1, object.setting
|
49
|
+
end
|
50
|
+
|
51
|
+
test 'instance query' do
|
52
|
+
object = @klass.new
|
53
|
+
assert_equal false, object.setting?
|
54
|
+
object.setting = 1
|
55
|
+
assert_equal true, object.setting?
|
56
|
+
end
|
57
|
+
|
58
|
+
test 'disabling instance writer' do
|
59
|
+
object = Class.new { class_attribute :setting, :instance_writer => false }.new
|
60
|
+
assert_raise(NoMethodError) { object.setting = 'boom' }
|
61
|
+
end
|
62
|
+
|
63
|
+
test 'works well with singleton classes' do
|
64
|
+
object = @klass.new
|
65
|
+
object.singleton_class.setting = 'foo'
|
66
|
+
assert_equal 'foo', object.setting
|
67
|
+
end
|
68
|
+
|
69
|
+
test 'setter returns set value' do
|
70
|
+
val = @klass.send(:setting=, 1)
|
71
|
+
assert_equal 1, val
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/delegation'
|
3
|
+
|
4
|
+
module One
|
5
|
+
Constant1 = "Hello World"
|
6
|
+
Constant2 = "What\'s up?"
|
7
|
+
end
|
8
|
+
|
9
|
+
class Ab
|
10
|
+
include One
|
11
|
+
Constant1 = "Hello World" # Will have different object id than One::Constant1
|
12
|
+
Constant3 = "Goodbye World"
|
13
|
+
end
|
14
|
+
|
15
|
+
module Xy
|
16
|
+
class Bc
|
17
|
+
include One
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Yz
|
22
|
+
module Zy
|
23
|
+
class Cd
|
24
|
+
include One
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Somewhere = Struct.new(:street, :city)
|
30
|
+
|
31
|
+
Someone = Struct.new(:name, :place) do
|
32
|
+
delegate :street, :city, :to_f, :to => :place
|
33
|
+
delegate :upcase, :to => "place.city"
|
34
|
+
end
|
35
|
+
|
36
|
+
Invoice = Struct.new(:client) do
|
37
|
+
delegate :street, :city, :name, :to => :client, :prefix => true
|
38
|
+
delegate :street, :city, :name, :to => :client, :prefix => :customer
|
39
|
+
end
|
40
|
+
|
41
|
+
Project = Struct.new(:description, :person) do
|
42
|
+
delegate :name, :to => :person, :allow_nil => true
|
43
|
+
delegate :to_f, :to => :description, :allow_nil => true
|
44
|
+
end
|
45
|
+
|
46
|
+
Developer = Struct.new(:client) do
|
47
|
+
delegate :name, :to => :client, :prefix => nil
|
48
|
+
end
|
49
|
+
|
50
|
+
Tester = Struct.new(:client) do
|
51
|
+
delegate :name, :to => :client, :prefix => false
|
52
|
+
end
|
53
|
+
|
54
|
+
class Name
|
55
|
+
delegate :upcase, :to => :@full_name
|
56
|
+
|
57
|
+
def initialize(first, last)
|
58
|
+
@full_name = "#{first} #{last}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class ModuleTest < Test::Unit::TestCase
|
63
|
+
def setup
|
64
|
+
@david = Someone.new("David", Somewhere.new("Paulina", "Chicago"))
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_delegation_to_methods
|
68
|
+
assert_equal "Paulina", @david.street
|
69
|
+
assert_equal "Chicago", @david.city
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_delegation_down_hierarchy
|
73
|
+
assert_equal "CHICAGO", @david.upcase
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_delegation_to_instance_variable
|
77
|
+
david = Name.new("David", "Hansson")
|
78
|
+
assert_equal "DAVID HANSSON", david.upcase
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_missing_delegation_target
|
82
|
+
assert_raise(ArgumentError) do
|
83
|
+
Name.send :delegate, :nowhere
|
84
|
+
end
|
85
|
+
assert_raise(ArgumentError) do
|
86
|
+
Name.send :delegate, :noplace, :tos => :hollywood
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_delegation_prefix
|
91
|
+
invoice = Invoice.new(@david)
|
92
|
+
assert_equal invoice.client_name, "David"
|
93
|
+
assert_equal invoice.client_street, "Paulina"
|
94
|
+
assert_equal invoice.client_city, "Chicago"
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_delegation_custom_prefix
|
98
|
+
invoice = Invoice.new(@david)
|
99
|
+
assert_equal invoice.customer_name, "David"
|
100
|
+
assert_equal invoice.customer_street, "Paulina"
|
101
|
+
assert_equal invoice.customer_city, "Chicago"
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_delegation_prefix_with_nil_or_false
|
105
|
+
assert_equal Developer.new(@david).name, "David"
|
106
|
+
assert_equal Tester.new(@david).name, "David"
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_delegation_prefix_with_instance_variable
|
110
|
+
assert_raise ArgumentError do
|
111
|
+
Class.new do
|
112
|
+
def initialize(client)
|
113
|
+
@client = client
|
114
|
+
end
|
115
|
+
delegate :name, :address, :to => :@client, :prefix => true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_delegation_with_allow_nil
|
121
|
+
rails = Project.new("Rails", Someone.new("David"))
|
122
|
+
assert_equal rails.name, "David"
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_delegation_with_allow_nil_and_nil_value
|
126
|
+
rails = Project.new("Rails")
|
127
|
+
assert_nil rails.name
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_delegation_with_allow_nil_and_nil_value_and_prefix
|
131
|
+
Project.class_eval do
|
132
|
+
delegate :name, :to => :person, :allow_nil => true, :prefix => true
|
133
|
+
end
|
134
|
+
rails = Project.new("Rails")
|
135
|
+
assert_nil rails.person_name
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_delegation_without_allow_nil_and_nil_value
|
139
|
+
david = Someone.new("David")
|
140
|
+
assert_raise(RuntimeError) { david.street }
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_delegation_to_method_that_exists_on_nil
|
144
|
+
nil_person = Someone.new(nil)
|
145
|
+
assert_equal 0.0, nil_person.to_f
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_delegation_to_method_that_exists_on_nil_when_allowing_nil
|
149
|
+
nil_project = Project.new(nil)
|
150
|
+
assert_equal 0.0, nil_project.to_f
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_delegation_does_not_raise_error_when_removing_singleton_instance_methods
|
154
|
+
parent = Class.new do
|
155
|
+
def self.parent_method; end
|
156
|
+
end
|
157
|
+
|
158
|
+
assert_nothing_raised do
|
159
|
+
Class.new(parent) do
|
160
|
+
class << self
|
161
|
+
delegate :parent_method, :to => :superclass
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../abstract_unit'
|
2
|
+
require 'gorillib/metaprogramming/cattr_accessor'
|
3
|
+
|
4
|
+
class ModuleAttributeAccessorTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
m = @module = Module.new do
|
7
|
+
mattr_accessor :foo
|
8
|
+
mattr_accessor :bar, :instance_writer => false
|
9
|
+
mattr_reader :shaq, :instance_reader => false
|
10
|
+
end
|
11
|
+
@class = Class.new
|
12
|
+
@class.instance_eval { include m }
|
13
|
+
@object = @class.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_use_mattr_default
|
17
|
+
assert_nil @module.foo
|
18
|
+
assert_nil @object.foo
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_set_mattr_value
|
22
|
+
@module.foo = :test
|
23
|
+
assert_equal :test, @object.foo
|
24
|
+
|
25
|
+
@object.foo = :test2
|
26
|
+
assert_equal :test2, @module.foo
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_should_not_create_instance_writer
|
30
|
+
assert_respond_to @module, :foo
|
31
|
+
assert_respond_to @module, :foo=
|
32
|
+
assert_respond_to @object, :bar
|
33
|
+
assert !@object.respond_to?(:bar=)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_not_create_instance_reader
|
37
|
+
assert_respond_to @module, :shaq
|
38
|
+
assert !@object.respond_to?(:shaq)
|
39
|
+
end
|
40
|
+
end
|