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.
- data/CHANGELOG.textile +6 -0
- data/README.textile +34 -11
- data/VERSION +1 -1
- data/gorillib.gemspec +63 -5
- data/lib/gorillib/enumerable/sum.rb +2 -2
- data/lib/gorillib/hash/compact.rb +2 -29
- data/lib/gorillib/hash/deep_compact.rb +2 -12
- data/lib/gorillib/hash/deep_dup.rb +4 -0
- data/lib/gorillib/hash/deep_merge.rb +2 -14
- data/lib/gorillib/hash/indifferent_access.rb +207 -0
- data/lib/gorillib/hash/keys.rb +2 -40
- data/lib/gorillib/hash/reverse_merge.rb +2 -24
- data/lib/gorillib/hash/slice.rb +2 -51
- data/lib/gorillib/hash/tree_merge.rb +4 -0
- data/lib/gorillib/hashlike.rb +824 -0
- data/lib/gorillib/hashlike/compact.rb +60 -0
- data/lib/gorillib/hashlike/deep_compact.rb +18 -0
- data/lib/gorillib/hashlike/deep_dup.rb +15 -0
- data/lib/gorillib/hashlike/deep_merge.rb +20 -0
- data/lib/gorillib/hashlike/hashlike_via_accessors.rb +169 -0
- data/lib/gorillib/hashlike/keys.rb +59 -0
- data/lib/gorillib/hashlike/reverse_merge.rb +31 -0
- data/lib/gorillib/hashlike/slice.rb +67 -0
- data/lib/gorillib/hashlike/tree_merge.rb +76 -0
- data/lib/gorillib/metaprogramming/mattr_accessor.rb +1 -1
- data/lib/gorillib/receiver.rb +315 -0
- data/lib/gorillib/receiver/active_model_shim.rb +19 -0
- data/lib/gorillib/receiver/acts_as_hash.rb +191 -0
- data/lib/gorillib/receiver/acts_as_loadable.rb +42 -0
- data/lib/gorillib/receiver/tree_diff.rb +74 -0
- data/lib/gorillib/receiver/validations.rb +30 -0
- data/lib/gorillib/struct/acts_as_hash.rb +108 -0
- data/lib/gorillib/struct/hashlike_iteration.rb +0 -0
- data/notes/fancy_hashes_and_receivers.textile +120 -0
- data/notes/hash_rdocs.textile +97 -0
- data/spec/hash/deep_merge_spec.rb +0 -2
- data/spec/hash/indifferent_access_spec.rb +391 -0
- data/spec/hash/slice_spec.rb +35 -12
- data/spec/hashlike/behave_same_as_hash_spec.rb +105 -0
- data/spec/hashlike/hashlike_behavior_spec.rb +824 -0
- data/spec/hashlike/hashlike_via_accessors_fuzzing_spec.rb +37 -0
- data/spec/hashlike/hashlike_via_accessors_spec.rb +262 -0
- data/spec/hashlike_spec.rb +302 -0
- data/spec/metaprogramming/aliasing_spec.rb +3 -0
- data/spec/metaprogramming/cattr_accessor_spec.rb +2 -0
- data/spec/metaprogramming/class_attribute_spec.rb +2 -0
- data/spec/metaprogramming/delegation_spec.rb +2 -0
- data/spec/metaprogramming/mattr_accessor_spec.rb +2 -0
- data/spec/metaprogramming/singleton_class_spec.rb +3 -0
- data/spec/receiver/acts_as_hash_spec.rb +286 -0
- data/spec/receiver_spec.rb +478 -0
- data/spec/spec_helper.rb +11 -6
- data/spec/string/truncate_spec.rb +1 -0
- data/spec/struct/acts_as_hash_fuzz_spec.rb +67 -0
- data/spec/struct/acts_as_hash_spec.rb +426 -0
- data/spec/support/hashlike_fuzzing_helper.rb +127 -0
- data/spec/support/hashlike_helper.rb +75 -0
- data/spec/support/hashlike_struct_helper.rb +37 -0
- data/spec/support/hashlike_via_delegation.rb +30 -0
- data/spec/support/matchers/be_array_eql.rb +12 -0
- data/spec/support/matchers/be_hash_eql.rb +14 -0
- data/spec/support/matchers/enumerate_method.rb +10 -0
- data/spec/support/matchers/evaluate_to_true.rb +5 -0
- 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,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,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
|
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-
|
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:
|
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
|