gorillib 0.0.8 → 0.1.0

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.
Files changed (64) hide show
  1. data/CHANGELOG.textile +6 -0
  2. data/README.textile +34 -11
  3. data/VERSION +1 -1
  4. data/gorillib.gemspec +63 -5
  5. data/lib/gorillib/enumerable/sum.rb +2 -2
  6. data/lib/gorillib/hash/compact.rb +2 -29
  7. data/lib/gorillib/hash/deep_compact.rb +2 -12
  8. data/lib/gorillib/hash/deep_dup.rb +4 -0
  9. data/lib/gorillib/hash/deep_merge.rb +2 -14
  10. data/lib/gorillib/hash/indifferent_access.rb +207 -0
  11. data/lib/gorillib/hash/keys.rb +2 -40
  12. data/lib/gorillib/hash/reverse_merge.rb +2 -24
  13. data/lib/gorillib/hash/slice.rb +2 -51
  14. data/lib/gorillib/hash/tree_merge.rb +4 -0
  15. data/lib/gorillib/hashlike.rb +824 -0
  16. data/lib/gorillib/hashlike/compact.rb +60 -0
  17. data/lib/gorillib/hashlike/deep_compact.rb +18 -0
  18. data/lib/gorillib/hashlike/deep_dup.rb +15 -0
  19. data/lib/gorillib/hashlike/deep_merge.rb +20 -0
  20. data/lib/gorillib/hashlike/hashlike_via_accessors.rb +169 -0
  21. data/lib/gorillib/hashlike/keys.rb +59 -0
  22. data/lib/gorillib/hashlike/reverse_merge.rb +31 -0
  23. data/lib/gorillib/hashlike/slice.rb +67 -0
  24. data/lib/gorillib/hashlike/tree_merge.rb +76 -0
  25. data/lib/gorillib/metaprogramming/mattr_accessor.rb +1 -1
  26. data/lib/gorillib/receiver.rb +315 -0
  27. data/lib/gorillib/receiver/active_model_shim.rb +19 -0
  28. data/lib/gorillib/receiver/acts_as_hash.rb +191 -0
  29. data/lib/gorillib/receiver/acts_as_loadable.rb +42 -0
  30. data/lib/gorillib/receiver/tree_diff.rb +74 -0
  31. data/lib/gorillib/receiver/validations.rb +30 -0
  32. data/lib/gorillib/struct/acts_as_hash.rb +108 -0
  33. data/lib/gorillib/struct/hashlike_iteration.rb +0 -0
  34. data/notes/fancy_hashes_and_receivers.textile +120 -0
  35. data/notes/hash_rdocs.textile +97 -0
  36. data/spec/hash/deep_merge_spec.rb +0 -2
  37. data/spec/hash/indifferent_access_spec.rb +391 -0
  38. data/spec/hash/slice_spec.rb +35 -12
  39. data/spec/hashlike/behave_same_as_hash_spec.rb +105 -0
  40. data/spec/hashlike/hashlike_behavior_spec.rb +824 -0
  41. data/spec/hashlike/hashlike_via_accessors_fuzzing_spec.rb +37 -0
  42. data/spec/hashlike/hashlike_via_accessors_spec.rb +262 -0
  43. data/spec/hashlike_spec.rb +302 -0
  44. data/spec/metaprogramming/aliasing_spec.rb +3 -0
  45. data/spec/metaprogramming/cattr_accessor_spec.rb +2 -0
  46. data/spec/metaprogramming/class_attribute_spec.rb +2 -0
  47. data/spec/metaprogramming/delegation_spec.rb +2 -0
  48. data/spec/metaprogramming/mattr_accessor_spec.rb +2 -0
  49. data/spec/metaprogramming/singleton_class_spec.rb +3 -0
  50. data/spec/receiver/acts_as_hash_spec.rb +286 -0
  51. data/spec/receiver_spec.rb +478 -0
  52. data/spec/spec_helper.rb +11 -6
  53. data/spec/string/truncate_spec.rb +1 -0
  54. data/spec/struct/acts_as_hash_fuzz_spec.rb +67 -0
  55. data/spec/struct/acts_as_hash_spec.rb +426 -0
  56. data/spec/support/hashlike_fuzzing_helper.rb +127 -0
  57. data/spec/support/hashlike_helper.rb +75 -0
  58. data/spec/support/hashlike_struct_helper.rb +37 -0
  59. data/spec/support/hashlike_via_delegation.rb +30 -0
  60. data/spec/support/matchers/be_array_eql.rb +12 -0
  61. data/spec/support/matchers/be_hash_eql.rb +14 -0
  62. data/spec/support/matchers/enumerate_method.rb +10 -0
  63. data/spec/support/matchers/evaluate_to_true.rb +5 -0
  64. metadata +62 -4
@@ -0,0 +1,37 @@
1
+ # require File.dirname(__FILE__)+'/../spec_helper'
2
+ # require GORILLIB_ROOT_DIR('spec/support/hashlike_fuzzing_helper')
3
+ # require 'gorillib/hashlike'
4
+ # require 'gorillib/hashlike/hashlike_via_accessors'
5
+ #
6
+ # class UsingHashlikeViaAccessors
7
+ # include Gorillib::Hashlike::HashlikeViaAccessors
8
+ # include Gorillib::Hashlike
9
+ #
10
+ # attr_accessor :a, :b, :c, :nil_val, :false_val, :z
11
+ #
12
+ # # We override these just to be able to compare exceptions.
13
+ # def to_s()
14
+ # '{' + [:a, :b, :c, :nil_val, :false_val, :z].map{|k| [k, self[k]].join('=>') }.join(',') + '}'
15
+ # end
16
+ # def ==(other_hash)
17
+ # (length == other_hash.length) && all?{|k,v| v == other_hash[k] }
18
+ # end
19
+ # end
20
+ #
21
+ #
22
+ # describe Gorillib::Hashlike::HashlikeViaAccessors do
23
+ # include HashlikeFuzzingHelper
24
+ #
25
+ #
26
+ # before do
27
+ # @total = 0
28
+ # hsh = { :a => 3, :b => 4, :c => nil, :nil_val => nil, :false_val => false, :z => nil }
29
+ # @hsh_symk = hsh.dup
30
+ # @hsh_strk = {} ; hsh.each{|k,v| @hsh_strk[k.to_s] = v }
31
+ # @hsh_wia = hsh.with_indifferent_access
32
+ # @hshlike = InternalHash.new.merge(hsh)
33
+ #
34
+ # p [@hshlike]
35
+ # end
36
+ #
37
+ # end
@@ -0,0 +1,262 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/hashlike'
3
+ require 'gorillib/hashlike/hashlike_via_accessors'
4
+ require GORILLIB_ROOT_DIR('spec/support/hashlike_via_delegation')
5
+ require GORILLIB_ROOT_DIR('spec/support/hashlike_helper')
6
+ require GORILLIB_ROOT_DIR('spec/hashlike/hashlike_behavior_spec')
7
+
8
+ class SimpleHashlikeViaAccessors
9
+ attr_accessor :a, :b, :c, :nil_val, :false_val, :new_key
10
+ include Gorillib::Hashlike::HashlikeViaAccessors
11
+ include Gorillib::Hashlike
12
+ end
13
+
14
+ describe Gorillib::Hashlike::HashlikeViaAccessors do
15
+
16
+ before do
17
+ @hshlike = SimpleHashlikeViaAccessors.new.merge(HashlikeHelper::HASH_TO_TEST_HL_V_A.dup)
18
+ @empty_hshlike = SimpleHashlikeViaAccessors.new
19
+ @hshlike_with_array_vals = SimpleHashlikeViaAccessors.new.merge(HashlikeHelper::BASE_HSH_WITH_ARRAY_VALS.dup)
20
+ #
21
+ @hshlike_subklass = Class.new(SimpleHashlikeViaAccessors)
22
+ @hshlike_subklass_inst = @hshlike_subklass.new.merge(HashlikeHelper::BASE_HSH.dup)
23
+ end
24
+
25
+
26
+ # ===========================================================================
27
+ #
28
+ # Fundamental behavior
29
+
30
+ describe '#[] and #[]= and #store' do
31
+ it_should_behave_like :hashlike_store_and_retrieve
32
+ it_should_behave_like :references_string_and_symbol_keys_equivalently
33
+ it 'reject unknown keys' do
34
+ lambda{ @hshlike[:fnord] = 69 }.should raise_error NoMethodError, /undefined method `fnord=' for/
35
+ lambda{ @hshlike[:fnord] }.should raise_error NoMethodError, /undefined method `fnord' for/
36
+ @hshlike.delete(:fnord).should be_nil
37
+ end
38
+ it 'accepts defined but unset keys' do
39
+ @hshlike[:new_key].should be_nil
40
+ @hshlike[:new_key] = 69
41
+ @hshlike[:new_key].should == 69
42
+ end
43
+ it 'does not allow nil, Object, or other non-stringy keys' do
44
+ lambda{ @hshlike[300] = :i_haz_num }.should raise_error(ArgumentError, "Keys for SimpleHashlikeViaAccessors must be symbols, strings or respond to #to_sym")
45
+ lambda{ @hshlike[nil] = :i_haz_nil }.should raise_error(ArgumentError, "Keys for SimpleHashlikeViaAccessors must be symbols, strings or respond to #to_sym")
46
+ obj = Object.new
47
+ lambda{ @hshlike[obj] = :i_haz_obj }.should raise_error(ArgumentError, "Keys for SimpleHashlikeViaAccessors must be symbols, strings or respond to #to_sym")
48
+ def obj.to_sym() :c ; end
49
+ @hshlike[obj] = :i_haz_obj
50
+ @hshlike[obj].should == :i_haz_obj
51
+ end
52
+ end
53
+
54
+ describe '#delete' do
55
+ it_should_behave_like :hashlike_delete
56
+ end
57
+
58
+ describe '#keys' do
59
+ it_should_behave_like :hashlike_keys
60
+ end
61
+
62
+ # ===========================================================================
63
+ #
64
+ # Iteration
65
+
66
+ describe '#each_pair' do
67
+ describe 'with block' do
68
+ it_should_behave_like :each_pair_on_stringlike_keys, :each_pair
69
+ end
70
+ it_should_behave_like :with_no_block_returns_enumerator, :each_pair
71
+ end
72
+
73
+ describe '#each' do
74
+ describe 'with block' do
75
+ it_should_behave_like :each_pair_on_stringlike_keys, :each
76
+ end
77
+ it_should_behave_like :with_no_block_returns_enumerator, :each
78
+ end
79
+
80
+ describe '#each_key' do
81
+ describe 'with block' do
82
+ it_should_behave_like :each_key_on_stringlike_keys
83
+ end
84
+ it_should_behave_like :with_no_block_returns_enumerator, :each_key
85
+ end
86
+
87
+ describe '#each_value' do
88
+ describe 'with block' do
89
+ it_should_behave_like :each_value_on_stringlike_keys
90
+ end
91
+ it_should_behave_like :with_no_block_returns_enumerator, :each_value
92
+ end
93
+
94
+ # ===========================================================================
95
+ #
96
+ # Retrieval and Membership
97
+
98
+ describe '#values' do
99
+ it_should_behave_like :hashlike_values
100
+ end
101
+
102
+ describe '#values_at' do
103
+ it_should_behave_like :hashlike_values_at_or_of, :values_at
104
+ end
105
+
106
+ describe '#values_of' do
107
+ it_should_behave_like :hashlike_values_at_or_of, :values_of
108
+ end
109
+
110
+ describe '#length' do
111
+ it_should_behave_like :hashlike_length, :length
112
+ end
113
+
114
+ describe '#size' do
115
+ it_should_behave_like :hashlike_length, :size
116
+ end
117
+
118
+ describe '#has_key?' do
119
+ it_should_behave_like :hashlike_has_key?, :has_key?
120
+ it_should_behave_like :hashlike_has_key_string_and_symbol_equivalent, :has_key?
121
+ end
122
+
123
+ describe '#include?' do
124
+ it_should_behave_like :hashlike_has_key?, :include?
125
+ it_should_behave_like :hashlike_has_key_string_and_symbol_equivalent, :include?
126
+ end
127
+
128
+ describe '#key?' do
129
+ it_should_behave_like :hashlike_has_key?, :key?
130
+ it_should_behave_like :hashlike_has_key_string_and_symbol_equivalent, :key?
131
+ end
132
+
133
+ describe '#member?' do
134
+ it_should_behave_like :hashlike_has_key?, :member?
135
+ it_should_behave_like :hashlike_has_key_string_and_symbol_equivalent, :member?
136
+ end
137
+
138
+ describe '#has_value?' do
139
+ it_should_behave_like :hashlike_has_value?, :has_value?
140
+ end
141
+
142
+ describe '#value?' do
143
+ it_should_behave_like :hashlike_has_value?, :value?
144
+ end
145
+
146
+ describe '#fetch' do
147
+ it_should_behave_like :hashlike_fetch
148
+ end
149
+
150
+ describe '#key' do
151
+ it_should_behave_like :hashlike_key
152
+ end
153
+
154
+ describe '#assoc' do
155
+ it_should_behave_like :hashlike_assoc
156
+ end
157
+
158
+ describe '#rassoc' do
159
+ it_should_behave_like :hashlike_rassoc
160
+ end
161
+
162
+ describe '#empty?' do
163
+ it_should_behave_like :hashlike_empty?
164
+ end
165
+
166
+ # ===========================================================================
167
+ #
168
+ # Update, merge!, merge
169
+
170
+ describe 'update' do
171
+ it_should_behave_like :merging_method, :update
172
+ it_should_behave_like :merging_method_with_normal_keys, :update
173
+ it_should_behave_like :merging_method_inplace, :update
174
+ end
175
+
176
+ describe '#merge!' do
177
+ it_should_behave_like :merging_method, :merge!
178
+ it_should_behave_like :merging_method_with_normal_keys, :merge!
179
+ it_should_behave_like :merging_method_inplace, :merge!
180
+ end
181
+
182
+ describe '#merge' do
183
+ it_should_behave_like :merging_method, :merge
184
+ it_should_behave_like :merging_method_with_normal_keys, :merge
185
+ it_should_behave_like :merging_method_returning_new, :merge
186
+ end
187
+
188
+ # ===========================================================================
189
+ #
190
+ # Filters
191
+
192
+ describe '#reject!' do
193
+ it_should_behave_like :hashlike_filter, :reject!
194
+ it_should_behave_like :rejection_filter, :reject!
195
+ it_should_behave_like :filter_modifies_self_returns_nil_if_unchanged, :reject!, false
196
+ end
197
+
198
+ describe '#select!' do
199
+ it_should_behave_like :hashlike_filter, :select!
200
+ it_should_behave_like :selection_filter, :select!
201
+ it_should_behave_like :filter_modifies_self_returns_nil_if_unchanged, :select!, true
202
+ end
203
+
204
+ describe '#delete_if' do
205
+ it_should_behave_like :hashlike_filter, :delete_if
206
+ it_should_behave_like :rejection_filter, :delete_if
207
+ it_should_behave_like :filter_modifies_self_returns_self, :delete_if, false
208
+ end
209
+
210
+ describe '#keep_if' do
211
+ it_should_behave_like :hashlike_filter, :keep_if
212
+ it_should_behave_like :selection_filter, :keep_if
213
+ it_should_behave_like :filter_modifies_self_returns_self, :keep_if, true
214
+ end
215
+
216
+ describe '#reject' do
217
+ it_should_behave_like :hashlike_filter, :select
218
+ it_should_behave_like :selection_filter, :select
219
+ it_should_behave_like :filter_does_not_modify_self_returns_same_class, :reject, false
220
+ end
221
+
222
+ describe '#select' do
223
+ it_should_behave_like :hashlike_filter, :select
224
+ it_should_behave_like :selection_filter, :select
225
+ it_should_behave_like :filter_does_not_modify_self_returns_same_class, :select, true
226
+ end
227
+
228
+ describe '#clear' do
229
+ it_should_behave_like :hashlike_clear
230
+ end
231
+
232
+ # ===========================================================================
233
+ #
234
+ # Conversion
235
+
236
+ describe '#to_hash' do
237
+ it_should_behave_like :hashlike_to_hash
238
+ end
239
+
240
+ describe '#invert' do
241
+ it_should_behave_like :hashlike_invert
242
+ end
243
+
244
+ describe '#flatten' do
245
+ it_should_behave_like :hashlike_flatten
246
+ end
247
+
248
+ # ===========================================================================
249
+ #
250
+ # Sanity check
251
+
252
+ it 'built test objects correctly' do
253
+ @hshlike_subklass .should < @hshlike.class
254
+ @hshlike_subklass .should_not == @hshlike.class
255
+ @hshlike_subklass_inst .should be_a(SimpleHashlikeViaAccessors)
256
+ @hshlike_subklass_inst .should be_a(@hshlike_subklass)
257
+ @hshlike_subklass_inst .should_not be_an_instance_of(SimpleHashlikeViaAccessors)
258
+ @hshlike .should_not be_a(@hshlike_subklass)
259
+ @hshlike .should be_an_instance_of(SimpleHashlikeViaAccessors)
260
+ end
261
+
262
+ end
@@ -0,0 +1,302 @@
1
+ require File.expand_path(File.dirname(__FILE__)+'/spec_helper')
2
+ require 'gorillib/hashlike'
3
+ require GORILLIB_ROOT_DIR('spec/support/hashlike_via_delegation')
4
+ require GORILLIB_ROOT_DIR('spec/support/hashlike_helper')
5
+ require GORILLIB_ROOT_DIR('spec/hashlike/hashlike_behavior_spec')
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+ describe Gorillib::Hashlike do
14
+
15
+ before do
16
+ @hshlike = InternalHash.new.merge(HashlikeHelper::BASE_HSH.dup)
17
+ @empty_hshlike = InternalHash.new
18
+ @hshlike_with_array_keys = InternalHash.new.merge(HashlikeHelper::BASE_HSH_WITH_ARRAY_KEYS.dup)
19
+ @hshlike_with_array_vals = InternalHash.new.merge(HashlikeHelper::BASE_HSH_WITH_ARRAY_VALS.dup)
20
+ #
21
+ @hshlike_subklass = Class.new(InternalHash)
22
+ @hshlike_subklass_inst = @hshlike_subklass.new.merge(HashlikeHelper::BASE_HSH.dup)
23
+ end
24
+
25
+ # ===========================================================================
26
+ #
27
+ # Fundamental behavior
28
+
29
+ describe '#[] and #[]= and #store' do
30
+ it_should_behave_like :hashlike_store_and_retrieve
31
+ it_should_behave_like :references_complex_keys
32
+ it_should_behave_like :accepts_arbitrary_keys
33
+ end
34
+
35
+ describe '#delete' do
36
+ it_should_behave_like :hashlike_delete
37
+ end
38
+
39
+ describe '#keys' do
40
+ it_should_behave_like :hashlike_keys
41
+ end
42
+
43
+ # ===========================================================================
44
+ #
45
+ # Iteration
46
+
47
+ describe '#each_pair' do
48
+ describe 'with block' do
49
+ it_should_behave_like :each_pair_on_stringlike_keys, :each_pair
50
+ it_should_behave_like :each_pair_on_complex_keys, :each_pair
51
+ end
52
+ it_should_behave_like :with_no_block_returns_enumerator, :each_pair
53
+ end
54
+
55
+ describe '#each' do
56
+ describe 'with block' do
57
+ it_should_behave_like :each_pair_on_stringlike_keys, :each
58
+ it_should_behave_like :each_pair_on_complex_keys, :each
59
+ end
60
+ it_should_behave_like :with_no_block_returns_enumerator, :each
61
+ end
62
+
63
+ describe '#each_key' do
64
+ describe 'with block' do
65
+ it_should_behave_like :each_key_on_stringlike_keys
66
+ it_should_behave_like :each_key_on_complex_keys
67
+ end
68
+ it_should_behave_like :with_no_block_returns_enumerator, :each_key
69
+ end
70
+
71
+ describe '#each_value' do
72
+ describe 'with block' do
73
+ it_should_behave_like :each_value_on_stringlike_keys
74
+ end
75
+ it_should_behave_like :with_no_block_returns_enumerator, :each_value
76
+ end
77
+
78
+ # ===========================================================================
79
+ #
80
+ # Retrieval and Membership
81
+
82
+ describe '#values' do
83
+ it_should_behave_like :hashlike_values
84
+ end
85
+
86
+ describe '#values_at' do
87
+ it_should_behave_like :hashlike_values_at_or_of, :values_at
88
+ end
89
+
90
+ describe '#values_of' do
91
+ it_should_behave_like :hashlike_values_at_or_of, :values_of
92
+ end
93
+
94
+ describe '#length' do
95
+ it_should_behave_like :hashlike_length, :length
96
+ end
97
+
98
+ describe '#size' do
99
+ it_should_behave_like :hashlike_length, :size
100
+ end
101
+
102
+ describe '#has_key?' do
103
+ it_should_behave_like :hashlike_has_key?, :has_key?
104
+ it_should_behave_like :hashlike_has_key_on_complex_keys, :has_key?
105
+ end
106
+
107
+ describe '#include?' do
108
+ it_should_behave_like :hashlike_has_key?, :include?
109
+ it_should_behave_like :hashlike_has_key_on_complex_keys, :include?
110
+ end
111
+
112
+ describe '#key?' do
113
+ it_should_behave_like :hashlike_has_key?, :key?
114
+ it_should_behave_like :hashlike_has_key_on_complex_keys, :key?
115
+ end
116
+
117
+ describe '#member?' do
118
+ it_should_behave_like :hashlike_has_key?, :member?
119
+ it_should_behave_like :hashlike_has_key_on_complex_keys, :member?
120
+ end
121
+
122
+ describe '#has_value?' do
123
+ it_should_behave_like :hashlike_has_value?, :has_value?
124
+ it_should_behave_like :hashlike_has_value_on_complex_keys, :has_value?
125
+ end
126
+
127
+ describe '#value?' do
128
+ it_should_behave_like :hashlike_has_value?, :value?
129
+ it_should_behave_like :hashlike_has_value_on_complex_keys, :value?
130
+ end
131
+
132
+ describe '#fetch' do
133
+ it_should_behave_like :hashlike_fetch
134
+ end
135
+
136
+ describe '#key' do
137
+ it_should_behave_like :hashlike_key
138
+ end
139
+
140
+ describe '#assoc' do
141
+ it_should_behave_like :hashlike_assoc
142
+ end
143
+
144
+ describe '#rassoc' do
145
+ it_should_behave_like :hashlike_rassoc
146
+ end
147
+
148
+ describe '#empty?' do
149
+ it_should_behave_like :hashlike_empty?
150
+ end
151
+
152
+ # ===========================================================================
153
+ #
154
+ # Update, merge!, merge
155
+
156
+ describe 'update' do
157
+ it_should_behave_like :merging_method, :update
158
+ it_should_behave_like :merging_method_with_normal_keys, :update
159
+ it_should_behave_like :merging_method_inplace, :update
160
+ end
161
+
162
+ describe '#merge!' do
163
+ it_should_behave_like :merging_method, :merge!
164
+ it_should_behave_like :merging_method_with_normal_keys, :merge!
165
+ it_should_behave_like :merging_method_inplace, :merge!
166
+ end
167
+
168
+ describe '#merge' do
169
+ it_should_behave_like :merging_method, :merge
170
+ it_should_behave_like :merging_method_with_normal_keys, :merge
171
+ it_should_behave_like :merging_method_returning_new, :merge
172
+ end
173
+
174
+ # ===========================================================================
175
+ #
176
+ # Filters
177
+
178
+ describe '#reject!' do
179
+ it_should_behave_like :hashlike_filter, :reject!
180
+ it_should_behave_like :rejection_filter, :reject!
181
+ it_should_behave_like :filter_modifies_self_returns_nil_if_unchanged, :reject!, false
182
+ end
183
+
184
+ describe '#select!' do
185
+ it_should_behave_like :hashlike_filter, :select!
186
+ it_should_behave_like :selection_filter, :select!
187
+ it_should_behave_like :filter_modifies_self_returns_nil_if_unchanged, :select!, true
188
+ end
189
+
190
+ describe '#delete_if' do
191
+ it_should_behave_like :hashlike_filter, :delete_if
192
+ it_should_behave_like :rejection_filter, :delete_if
193
+ it_should_behave_like :filter_modifies_self_returns_self, :delete_if, false
194
+ end
195
+
196
+ describe '#keep_if' do
197
+ it_should_behave_like :hashlike_filter, :keep_if
198
+ it_should_behave_like :selection_filter, :keep_if
199
+ it_should_behave_like :filter_modifies_self_returns_self, :keep_if, true
200
+ end
201
+
202
+ describe '#reject' do
203
+ it_should_behave_like :hashlike_filter, :select
204
+ it_should_behave_like :selection_filter, :select
205
+ it_should_behave_like :filter_does_not_modify_self_returns_same_class, :reject, false
206
+ end
207
+
208
+ describe '#select' do
209
+ it_should_behave_like :hashlike_filter, :select
210
+ it_should_behave_like :selection_filter, :select
211
+ it_should_behave_like :filter_does_not_modify_self_returns_same_class, :select, true
212
+ end
213
+
214
+ describe '#clear' do
215
+ it_should_behave_like :hashlike_clear
216
+ end
217
+
218
+ # ===========================================================================
219
+ #
220
+ # Conversion
221
+
222
+ describe '#to_hash' do
223
+ it_should_behave_like :hashlike_to_hash
224
+ end
225
+
226
+ describe '#invert' do
227
+ it_should_behave_like :hashlike_invert
228
+ end
229
+
230
+ describe '#flatten' do
231
+ it_should_behave_like :hashlike_flatten
232
+ end
233
+
234
+ # ===========================================================================
235
+ #
236
+ # Method Decoration
237
+
238
+ describe 'including Hashlike' do
239
+ module CollidesWithEnumerable ; def map() 3 ; end ; def keys(); [] ; end ; end
240
+ it 'includes enumerable by default' do
241
+ foo_class = Class.new(Object) do
242
+ include CollidesWithEnumerable
243
+ include Gorillib::Hashlike
244
+ end
245
+ #
246
+ foo_class.should include(Enumerable)
247
+ # Enumerable's map method won
248
+ foo_class.new.first.should be_nil
249
+ end
250
+ it 'does not include enumerable if already included' do
251
+ foo_class = Class.new(Object) do
252
+ include Enumerable
253
+ include CollidesWithEnumerable
254
+ include Gorillib::Hashlike
255
+ end
256
+ #
257
+ foo_class.should include(Enumerable)
258
+ # Enumerable wasn't reincluded, so CollidesWithEnumerable's 'map method won
259
+ foo_class.new.map.should == 3
260
+ end
261
+ it 'defines iterator by default' do
262
+ foo_class = Class.new(Object) do
263
+ include Gorillib::Hashlike
264
+ end
265
+ foo_class.should include(Gorillib::Hashlike::EnumerateFromKeys)
266
+ [:each, :each_pair, :length, :values, :values_at].each{|meth| foo_class.should be_method_defined(meth) }
267
+ end
268
+ it 'does not define iterators if #each_pair is already defined' do
269
+ foo_class = Class.new(Object) do
270
+ def each_pair() 3 ; end
271
+ def length() 3 ; end
272
+ include Gorillib::Hashlike
273
+ end
274
+ foo_class.should_not include(Gorillib::Hashlike::EnumerateFromKeys)
275
+ foo_class .should be_method_defined(:each_pair)
276
+ [:each, :values, :values_at].each{|meth| foo_class.should_not be_method_defined(meth) }
277
+ end
278
+ it 'does not implement the default, rehash, replace, compare_by or shift families of methods' do
279
+ ({}.methods.map(&:to_sym) -
280
+ (@hshlike.methods.map(&:to_sym) +
281
+ HashlikeHelper::OMITTED_METHODS_FROM_HASH +
282
+ HashlikeHelper::FANCY_HASHLIKE_METHODS
283
+ )
284
+ ).should == []
285
+ end
286
+ end # including Hashlike
287
+
288
+ # ===========================================================================
289
+ #
290
+ # Sanity check
291
+
292
+ it 'built test objects correctly' do
293
+ @hshlike_subklass .should < @hshlike.class
294
+ @hshlike_subklass .should_not == @hshlike.class
295
+ @hshlike_subklass_inst .should be_a(InternalHash)
296
+ @hshlike_subklass_inst .should be_a(@hshlike_subklass)
297
+ @hshlike_subklass_inst .should_not be_an_instance_of(InternalHash)
298
+ @hshlike .should_not be_a(@hshlike_subklass)
299
+ @hshlike .should be_an_instance_of(InternalHash)
300
+ end
301
+
302
+ end