gorillib 0.0.8 → 0.1.0

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