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,127 @@
1
+ require 'stringio'
2
+
3
+ ::Enumerator = Enumerable::Enumerator if (RUBY_VERSION < '1.9') && (not defined?(::Enumerator))
4
+
5
+ module HashlikeFuzzingHelper
6
+
7
+ #
8
+ # Fuzz testing for hashlike behavior. This throws a whole bunch of
9
+ #
10
+ #
11
+
12
+ HASH_TO_TEST_FULLY_HASHLIKE = {
13
+ :a => 100, :b => 200, :c => 300,
14
+ :nil_val => nil, :false_val => false, :true_val => true, :arr_val => [1,2,3],
15
+ [1, 2, [3, 4]] => [1, [2, 3, [4, 5, 6]]],
16
+ nil => :has_nil_key, false => :has_false_key, Object.new => :has_dummy_key,
17
+ }.freeze
18
+
19
+ #
20
+ # Inputs to throw at it
21
+ #
22
+
23
+ STRING_2X_PROC = Proc.new{|k| k.to_s * 2 }
24
+ TOTAL_K_PROC = Proc.new{|k| @total += self[k].to_i }
25
+ TOTAL_V_PROC = Proc.new{|v| @total += v.to_i }
26
+ TOTAL_KV_PROC = Proc.new{|k,v| @total += v.to_i }
27
+ VAL_GTE_4_PROC = Proc.new{|k,v| v.respond_to?(:to_i) && v.to_i >= 4 }
28
+ VAL_GTE_0_PROC = Proc.new{|k,v| v.respond_to?(:to_i) && v && v.to_i >= 0 }
29
+ VAL_GTE_1E6_PROC = Proc.new{|k,v| v.respond_to?(:to_i) && v && v.to_i >= 1e6 }
30
+
31
+ INPUTS_FOR_ALL_HASHLIKES = [
32
+ [], [:a], [:b], [:z], [0], [1], [2], [100], [-1],
33
+ [:a, :b], [:a, 30], [:b, 50], [:z, :a], [:c, 70],
34
+ [TOTAL_KV_PROC], [TOTAL_K_PROC], [TOTAL_V_PROC],
35
+ [:a, STRING_2X_PROC], [:z, STRING_2X_PROC], [:z, 100, STRING_2X_PROC],
36
+ [:a, :b, :z], [:a, :b, :a, :c, :a],
37
+ [VAL_GTE_4_PROC], [VAL_GTE_0_PROC], [VAL_GTE_1E6_PROC],
38
+ ]
39
+
40
+ INPUTS_WHEN_INDIFFERENT_ACCESS = [
41
+ ['a'], [:a], ['z'], [:z],
42
+ [:a, :b], [:a, 'b'], ['a', 'b'], [:a, :z], [:z, :a], ['z', :a],
43
+ ['a', STRING_2X_PROC], ['z', STRING_2X_PROC], ['a', 100, STRING_2X_PROC],
44
+ [:b, 50], ['b', 50],
45
+ [:a, 'b', :z],
46
+ ]
47
+
48
+ INPUTS_WHEN_ARBITRARY_KEYS_ALLOWED = [
49
+ [], ['a'], ['b'], ['z'], [1], [0], [nil], [false], [''], [Object.new], [ [] ],
50
+ ['a', 'b'], ['a', 30], ['b', 50], ['z', 'a'], [nil, 60], [:c, 70], [Object.new, 70], [ [], [] ],
51
+ ['a', 'b', 'z'], ['a', 'b', 'a', :c, 'a'],
52
+ [[1, 2, [3, 4]]], [[1, [2, 3, [4, 5, 6]]]]
53
+ ]
54
+
55
+ INPUTS_WHEN_FULLY_HASHLIKE = INPUTS_FOR_ALL_HASHLIKES + INPUTS_WHEN_ARBITRARY_KEYS_ALLOWED + INPUTS_WHEN_INDIFFERENT_ACCESS
56
+
57
+ #
58
+ # Hacky methods to do comparison
59
+ #
60
+
61
+ def send_to obj, meth, input
62
+ if input.last.is_a?(Proc)
63
+ input, block = [input[0..-2], input.last]
64
+ obj.send(meth, *input, &block)
65
+ else
66
+ obj.send(meth, *input)
67
+ end
68
+ end
69
+
70
+ # workaround: some errors have slightly different strings than Hash does
71
+ def err_regex err
72
+ err_str = err.to_s
73
+ err_str = Regexp.escape(err_str)
74
+ if err.is_a?(TypeError)
75
+ err_str.gsub!(/nil/, '(nil|NilClass)')
76
+ err_str.gsub!(/false/, '(false|FalseClass)')
77
+ elsif err.is_a?(ArgumentError)
78
+ err_str.gsub!(/arguments(\\ )*\\\(/, 'arguments\s*\(')
79
+ err_str.gsub!(/for\\ (\d\\\.\\\.\d)/, 'for [\d\.]+')
80
+ end
81
+ Regexp.new(err_str)
82
+ end
83
+
84
+ def behaves_the_same obj_1, obj_2, method_to_test, input
85
+ input.unshift(1) if [:cycle, :partition].include?(method_to_test) && input.last.is_a?(Proc)
86
+
87
+ # Hash in 1.8.7 behaves differently when arity mismatched to method
88
+ if ((RUBY_VERSION < '1.9') &&
89
+ [:reject!, :delete_if, :each_pair, :select, :reject].include?(method_to_test) &&
90
+ input.last.is_a?(Proc) && (input.last.arity == 1))
91
+ return
92
+ end
93
+
94
+ old_stderr = $stderr
95
+ $stderr = StringIO.new('', 'w')
96
+ obj_1.should_receive(:warn){|str| stderr_output << str }.at_most(:once)
97
+ begin
98
+ expected = send_to(obj_1, method_to_test, input)
99
+ rescue Exception => e
100
+ expected = e
101
+ end
102
+ expected_stderr = $stderr.string
103
+
104
+ $stderr = StringIO.new('', 'w')
105
+ obj_1.should_receive(:warn){|str| stderr_output << str }.at_most(:once)
106
+ case expected
107
+ when Exception
108
+ lambda{ send_to(obj_2, method_to_test, input) }.should raise_error(expected.class, err_regex(expected))
109
+ when Enumerator
110
+ actual = send_to(obj_2, method_to_test, input)
111
+ actual.should be_a(Enumerator)
112
+ actual.inspect.gsub(/[\"\:]/, '').gsub(/0x[a-f\d]+/,'').should == expected.inspect.gsub(/[\"\:]/, '').gsub(/0x[a-f\d]+/,'')
113
+ else # run the method
114
+ actual = send_to(obj_2, method_to_test, input)
115
+ if expected.is_a?(Hash) && (RUBY_VERSION < '1.9')
116
+ actual.should be_hash_eql(expected)
117
+ elsif expected.is_a?(Array) && (RUBY_VERSION < '1.9')
118
+ actual.should be_array_eql(expected)
119
+ else
120
+ actual.should == expected
121
+ end
122
+ end
123
+ $stderr.string.sub(/.*\.rb:\d+:(?:in `send\w*':)? /, '').should == expected_stderr.sub(/.*\.rb:\d+:(?:in `send\w*':)? /, '')
124
+ $stderr = old_stderr
125
+ end
126
+
127
+ end
@@ -0,0 +1,75 @@
1
+ class ::Hash
2
+ alias_method(:key, :index) unless method_defined?(:key)
3
+ alias_method(:values_of, :values_at) unless method_defined?(:values_of)
4
+ end
5
+
6
+ module HashlikeHelper
7
+
8
+ BASE_HSH = { :a => 100, :b => 200, :c => 300, :nil_val => nil, :false_val => false }.freeze
9
+ HASH_TO_TEST_HASHLIKE_STRUCT = { :a => 100, :b => 200, :c => 300, :nil_val => nil, :false_val => false, :new_key => nil, }.freeze
10
+ BASE_HSH_WITH_ARRAY_VALS = { :a => [100,111], :b => 200, :c => [1, [2, 3, [4, 5, 6]]] }.freeze
11
+ BASE_HSH_WITH_ARRAY_KEYS = {[:a,:aa] => 100, :b => 200, [:c,:cc] => [300,333], [1, 2, [3, 4]] => [1, [2, 3, [4, 5, 6]]] }.freeze
12
+
13
+ HASH_TO_TEST_HL_V_A = { :a => 100, :b => 200, :c => 300, :nil_val => nil, :false_val => false }.freeze
14
+
15
+ #
16
+ # Methods from Hash
17
+ #
18
+
19
+ # Test for all Hashlikes
20
+ HASHLIKE_METHODS = [
21
+ # defined by class
22
+ :[], :[]=, :delete, :keys,
23
+ # typically defined via EnumerateFromKeys, but Struct does its own thing
24
+ :each, :each_pair, :values, :values_at, :values_of, :length,
25
+ # defined by hashlike using above
26
+ :each_key, :each_value, :has_key?, :has_value?, :fetch, :key, :assoc,
27
+ :rassoc, :empty?, :update, :merge, :reject!, :reject, :select!, :select,
28
+ :delete_if, :keep_if, :clear, :to_hash, :invert, :flatten,
29
+ # aliases to the appropriate method
30
+ :store, :include?, :key?, :member?, :size, :value?, :merge!,
31
+ ]
32
+
33
+ if RUBY_VERSION < '1.9'
34
+ HASH_METHODS_MISSING_FROM_VERSION = [:flatten, :keep_if, :select!, :select, :rassoc, :assoc]
35
+ else
36
+ HASH_METHODS_MISSING_FROM_VERSION = []
37
+ end
38
+
39
+ # Should define specs for all of these
40
+ METHODS_TO_TEST = HASHLIKE_METHODS + Enumerable.public_instance_methods.map(&:to_sym) - HASH_METHODS_MISSING_FROM_VERSION
41
+
42
+ # *Only* these basic methods on hash should be missing from a Hashlike
43
+ OMITTED_METHODS_FROM_HASH = [
44
+ # not implemented in hashlike
45
+ :compare_by_identity, :compare_by_identity?,
46
+ :default, :default=, :default_proc, :default_proc=,
47
+ :rehash, :replace, :shift,
48
+ # obsolete
49
+ :index, :indexes, :indices,
50
+ ]
51
+
52
+ # fancy hash methods possibly require'd in other specs
53
+ FANCY_HASHLIKE_METHODS = [
54
+ :assert_valid_keys,
55
+ :nested_under_indifferent_access,
56
+ :stringify_keys, :stringify_keys!, :symbolize_keys, :symbolize_keys!,
57
+ :with_indifferent_access, :yaml_initialize
58
+ ]
59
+ FANCY_HASHLIKE_METHODS.each{|meth| OMITTED_METHODS_FROM_HASH << meth }
60
+
61
+ # ENUMERABLE_METHODS = [
62
+ # :each_cons, :each_entry, :each_slice, :each_with_index, :each_with_object,
63
+ # :entries, :to_a, :map, :collect, :collect_concat, :group_by, :flat_map,
64
+ # :inject, :reduce, :chunk, :reverse_each, :slice_before, :drop, :drop_while,
65
+ # :take, :take_while, :detect, :find, :find_all, :find_index, :grep,
66
+ # :all?, :any?, :none?, :one?, :first, :count, :zip, :max, :max_by, :min,
67
+ # :min_by, :minmax, :minmax_by, :sort, :sort_by,
68
+ # :cycle, :partition,
69
+ # ]
70
+ #
71
+ # p Enumerable.public_instance_methods.map(&:to_sym) - ENUMERABLE_METHODS
72
+ # p ENUMERABLE_METHODS - Enumerable.public_instance_methods.map(&:to_sym)
73
+ # extra: [:member?, :enum_slice, :reject, :select, :include?, :enum_cons, :enum_with_index]
74
+ # missing: [:each_entry, :each_with_object, :collect_concat, :flat_map, :chunk, :slice_before]
75
+ end
@@ -0,0 +1,37 @@
1
+ StructUsingHashlike = Struct.new(:a, :b, :c, :nil_val, :false_val, :new_key) do
2
+ include Gorillib::Hashlike
3
+ include Gorillib::Struct::ActsAsHash
4
+
5
+ def to_s ; to_hash.to_s ; end
6
+ def inspect ; to_s ; end
7
+
8
+ # compares so nil key is same as missing key
9
+ def ==(othr)
10
+ self.each_pair{|k,v| return false unless (v == othr[k]) }
11
+ othr.each_pair{|k,v| return false unless (v == self[k]) }
12
+ true
13
+ end
14
+ end
15
+
16
+ module HashlikeFuzzingHelper
17
+ SPECIAL_CASES_FOR_HASHLIKE_STRUCT = Hash.new({}).merge({
18
+ :[] => [
19
+ [0], [1], [2], [100], [-1], # numeric keys are interpreted as positional args
20
+ [:z], ['z'], # Struct doesn't allow access to undefined keys
21
+ [:z, STRING_2X_PROC],
22
+ ['z', STRING_2X_PROC],
23
+ [:z, 100, STRING_2X_PROC],
24
+ ],
25
+ :[]= => [
26
+ [:z, :a], ['z', :a], # Struct doesn't allow access to undefined keys
27
+ [:z, 100, STRING_2X_PROC],
28
+ ],
29
+ :store => [
30
+ [:z, :a], ['z', :a], # Struct doesn't allow access to undefined keys
31
+ [:z, 100, STRING_2X_PROC],
32
+ ],
33
+ :each_pair => [
34
+ [TOTAL_V_PROC], # Struct behaves differently on arity 1
35
+ ],
36
+ })
37
+ end
@@ -0,0 +1,30 @@
1
+ #
2
+ # A minimal implementation of a Hashlike for testing
3
+ #
4
+ # Delegates the basic 4 methods Hashlike expects ([], []=, delete, keys) to an
5
+ # actual hash.
6
+ #
7
+ class InternalHash < Object
8
+
9
+ include Gorillib::Hashlike
10
+
11
+ attr_reader :myhsh
12
+ def initialize
13
+ @myhsh = {}
14
+ end
15
+ def [](*args,&blk) @myhsh.[](*args, &blk) ; end
16
+ def []=(*args,&blk) @myhsh.[]=(*args, &blk) ; end
17
+ def delete(*args,&blk) @myhsh.delete(*args, &blk) ; end
18
+ def keys(*args,&blk) @myhsh.keys(*args, &blk) ; end
19
+
20
+ def dup
21
+ d = super
22
+ d.instance_variable_set("@myhsh", @myhsh.dup)
23
+ d
24
+ end
25
+
26
+ def hash_eql?(other_hsh)
27
+ other_hsh = other_hsh.myhsh if other_hsh.is_a?(self.class)
28
+ @myhsh == other_hsh
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ RSpec::Matchers.define(:be_array_eql) do |other_arr|
2
+ diffable
3
+ if RUBY_VERSION < '1.9'
4
+ match do |obj|
5
+ obj.sort_by(&:inspect) == other_arr.sort_by(&:inspect)
6
+ end
7
+ else
8
+ match do |obj|
9
+ obj == other_arr
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ RSpec::Matchers.define(:be_hash_eql) do |othr|
2
+ diffable
3
+ match do |obj|
4
+ if obj.respond_to?(:hash_eql?)
5
+ obj.hash_eql?(othr)
6
+ else
7
+ # same = (obj.length == othr.length)
8
+ same = true
9
+ ( othr.each_pair{|k,v| same &&= (v == obj[k]) } &&
10
+ obj .each_pair{|k,v| same &&= (v == othr[k]) })
11
+ same
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ RSpec::Matchers.define(:enumerate_method) do |obj, meth|
2
+ match do |enum|
3
+ if RUBY_VERSION < '1.9'
4
+ enum.is_a?(Enumerable::Enumerator)
5
+ else
6
+ enum.is_a?(Enumerator) &&
7
+ (enum.inspect == "#<Enumerator: #{obj.inspect}:#{meth}>")
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define(:evaluate_to_true) do |meth, *args|
2
+ match{|obj| obj.send(meth, *args) == true }
3
+ failure_message_for_should{|obj| "expected #{obj.inspect} to #{meth} #{args.join(",")}"}
4
+ failure_message_for_should_not{|obj| "expected #{obj.inspect} to not #{meth} #{args.join(",")}"}
5
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: gorillib
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.8
5
+ version: 0.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Infochimps
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-20 00:00:00 -05:00
13
+ date: 2011-06-07 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -203,17 +203,29 @@ files:
203
203
  - lib/gorillib/array/deep_compact.rb
204
204
  - lib/gorillib/array/extract_options.rb
205
205
  - lib/gorillib/base.rb
206
- - lib/gorillib/datetime/#flat.rb#
207
206
  - lib/gorillib/datetime/flat.rb
208
207
  - lib/gorillib/datetime/parse.rb
209
208
  - lib/gorillib/enumerable/sum.rb
210
209
  - lib/gorillib/hash/compact.rb
211
210
  - lib/gorillib/hash/deep_compact.rb
211
+ - lib/gorillib/hash/deep_dup.rb
212
212
  - lib/gorillib/hash/deep_merge.rb
213
+ - lib/gorillib/hash/indifferent_access.rb
213
214
  - lib/gorillib/hash/keys.rb
214
215
  - lib/gorillib/hash/reverse_merge.rb
215
216
  - lib/gorillib/hash/slice.rb
217
+ - lib/gorillib/hash/tree_merge.rb
216
218
  - lib/gorillib/hash/zip.rb
219
+ - lib/gorillib/hashlike.rb
220
+ - lib/gorillib/hashlike/compact.rb
221
+ - lib/gorillib/hashlike/deep_compact.rb
222
+ - lib/gorillib/hashlike/deep_dup.rb
223
+ - lib/gorillib/hashlike/deep_merge.rb
224
+ - lib/gorillib/hashlike/hashlike_via_accessors.rb
225
+ - lib/gorillib/hashlike/keys.rb
226
+ - lib/gorillib/hashlike/reverse_merge.rb
227
+ - lib/gorillib/hashlike/slice.rb
228
+ - lib/gorillib/hashlike/tree_merge.rb
217
229
  - lib/gorillib/logger/log.rb
218
230
  - lib/gorillib/metaprogramming/aliasing.rb
219
231
  - lib/gorillib/metaprogramming/cattr_accessor.rb
@@ -226,11 +238,21 @@ files:
226
238
  - lib/gorillib/object/blank.rb
227
239
  - lib/gorillib/object/try.rb
228
240
  - lib/gorillib/object/try_dup.rb
241
+ - lib/gorillib/receiver.rb
242
+ - lib/gorillib/receiver/active_model_shim.rb
243
+ - lib/gorillib/receiver/acts_as_hash.rb
244
+ - lib/gorillib/receiver/acts_as_loadable.rb
245
+ - lib/gorillib/receiver/tree_diff.rb
246
+ - lib/gorillib/receiver/validations.rb
229
247
  - lib/gorillib/some.rb
230
248
  - lib/gorillib/string/constantize.rb
231
249
  - lib/gorillib/string/human.rb
232
250
  - lib/gorillib/string/inflections.rb
233
251
  - lib/gorillib/string/truncate.rb
252
+ - lib/gorillib/struct/acts_as_hash.rb
253
+ - lib/gorillib/struct/hashlike_iteration.rb
254
+ - notes/fancy_hashes_and_receivers.textile
255
+ - notes/hash_rdocs.textile
234
256
  - spec/array/compact_blank_spec.rb
235
257
  - spec/array/extract_options_spec.rb
236
258
  - spec/datetime/flat_spec.rb
@@ -239,10 +261,16 @@ files:
239
261
  - spec/hash/compact_spec.rb
240
262
  - spec/hash/deep_compact_spec.rb
241
263
  - spec/hash/deep_merge_spec.rb
264
+ - spec/hash/indifferent_access_spec.rb
242
265
  - spec/hash/keys_spec.rb
243
266
  - spec/hash/reverse_merge_spec.rb
244
267
  - spec/hash/slice_spec.rb
245
268
  - spec/hash/zip_spec.rb
269
+ - spec/hashlike/behave_same_as_hash_spec.rb
270
+ - spec/hashlike/hashlike_behavior_spec.rb
271
+ - spec/hashlike/hashlike_via_accessors_fuzzing_spec.rb
272
+ - spec/hashlike/hashlike_via_accessors_spec.rb
273
+ - spec/hashlike_spec.rb
246
274
  - spec/logger/log_spec.rb
247
275
  - spec/metaprogramming/aliasing_spec.rb
248
276
  - spec/metaprogramming/cattr_accessor_spec.rb
@@ -254,13 +282,25 @@ files:
254
282
  - spec/object/blank_spec.rb
255
283
  - spec/object/try_dup_spec.rb
256
284
  - spec/object/try_spec.rb
285
+ - spec/receiver/acts_as_hash_spec.rb
286
+ - spec/receiver_spec.rb
257
287
  - spec/spec_helper.rb
258
288
  - spec/string/constantize_spec.rb
259
289
  - spec/string/human_spec.rb
260
290
  - spec/string/inflections_spec.rb
261
291
  - spec/string/inflector_test_cases.rb
262
292
  - spec/string/truncate_spec.rb
293
+ - spec/struct/acts_as_hash_fuzz_spec.rb
294
+ - spec/struct/acts_as_hash_spec.rb
295
+ - spec/support/hashlike_fuzzing_helper.rb
296
+ - spec/support/hashlike_helper.rb
297
+ - spec/support/hashlike_struct_helper.rb
298
+ - spec/support/hashlike_via_delegation.rb
263
299
  - spec/support/kcode_test_helper.rb
300
+ - spec/support/matchers/be_array_eql.rb
301
+ - spec/support/matchers/be_hash_eql.rb
302
+ - spec/support/matchers/enumerate_method.rb
303
+ - spec/support/matchers/evaluate_to_true.rb
264
304
  has_rdoc: true
265
305
  homepage: http://infochimps.com/labs
266
306
  licenses:
@@ -275,7 +315,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
275
315
  requirements:
276
316
  - - ">="
277
317
  - !ruby/object:Gem::Version
278
- hash: 991802759410469185
318
+ hash: 973162575614506299
279
319
  segments:
280
320
  - 0
281
321
  version: "0"
@@ -301,10 +341,16 @@ test_files:
301
341
  - spec/hash/compact_spec.rb
302
342
  - spec/hash/deep_compact_spec.rb
303
343
  - spec/hash/deep_merge_spec.rb
344
+ - spec/hash/indifferent_access_spec.rb
304
345
  - spec/hash/keys_spec.rb
305
346
  - spec/hash/reverse_merge_spec.rb
306
347
  - spec/hash/slice_spec.rb
307
348
  - spec/hash/zip_spec.rb
349
+ - spec/hashlike/behave_same_as_hash_spec.rb
350
+ - spec/hashlike/hashlike_behavior_spec.rb
351
+ - spec/hashlike/hashlike_via_accessors_fuzzing_spec.rb
352
+ - spec/hashlike/hashlike_via_accessors_spec.rb
353
+ - spec/hashlike_spec.rb
308
354
  - spec/logger/log_spec.rb
309
355
  - spec/metaprogramming/aliasing_spec.rb
310
356
  - spec/metaprogramming/cattr_accessor_spec.rb
@@ -316,10 +362,22 @@ test_files:
316
362
  - spec/object/blank_spec.rb
317
363
  - spec/object/try_dup_spec.rb
318
364
  - spec/object/try_spec.rb
365
+ - spec/receiver/acts_as_hash_spec.rb
366
+ - spec/receiver_spec.rb
319
367
  - spec/spec_helper.rb
320
368
  - spec/string/constantize_spec.rb
321
369
  - spec/string/human_spec.rb
322
370
  - spec/string/inflections_spec.rb
323
371
  - spec/string/inflector_test_cases.rb
324
372
  - spec/string/truncate_spec.rb
373
+ - spec/struct/acts_as_hash_fuzz_spec.rb
374
+ - spec/struct/acts_as_hash_spec.rb
375
+ - spec/support/hashlike_fuzzing_helper.rb
376
+ - spec/support/hashlike_helper.rb
377
+ - spec/support/hashlike_struct_helper.rb
378
+ - spec/support/hashlike_via_delegation.rb
325
379
  - spec/support/kcode_test_helper.rb
380
+ - spec/support/matchers/be_array_eql.rb
381
+ - spec/support/matchers/be_hash_eql.rb
382
+ - spec/support/matchers/enumerate_method.rb
383
+ - spec/support/matchers/evaluate_to_true.rb