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