reactive_support 0.4.0.beta3 → 0.5.0.beta

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe11b1fd5e03c2c900cb98199ab88a1021ccec3d
4
- data.tar.gz: 30b5b284b8e8002f14d35ba3fbc27e97f63db263
3
+ metadata.gz: e484324b27a831addea4d4f31a5a4343219dae84
4
+ data.tar.gz: 69b6a58c8ab40a915a92f6f2f87da0719edf918a
5
5
  SHA512:
6
- metadata.gz: 5fc1a35572ccdf4905584c078fb81897e13ac270355c934a75997c09af7fc7db1e8533ecded5a1b50ea9d4a4aa2e5625343335c9ab69d54d9da9edccf45ed4fa
7
- data.tar.gz: 70b173a264c284d70033ec7d67d3eb96ca7d12d6535de6c03de2c674782b80d17f80a8acec548c78394335bfabfdae693117b0468cb8684459a14bca0602fa6c
6
+ metadata.gz: 273d1eaf8a1db8b34e9b0e71dc08fd8af31ef0d6d4f4fa408d53d37d87e3e49a2e84bc8b17a51c459bf5458958fbbf662f8d4ad6f5c8a929a1d6bcb7dce9562c
7
+ data.tar.gz: c114dca660f79679fdb6a59ac7d6ca866c6a9806cf76492f88aa6a7ff1d307fa88f936272eec3b2f493d5f21e0f675abc346c8828a0aaa8bb64ed9b32d9757f5
@@ -0,0 +1 @@
1
+ Dir['./lib/reactive_support/core_ext/array/*.rb'].each {|f| require f }
@@ -0,0 +1,154 @@
1
+ # This file adds the +#transform_keys+, +#transform_keys!+,
2
+ # +#stringify_keys+, +#stringify_keys!+, +#symbolize_keys+, and
3
+ # +#symbolize_keys! methods to Ruby's core +Hash+ class. These
4
+ # methods modify the hash's keys according to given parameters,
5
+ # or create a duplicate with keys modified in this way.
6
+
7
+ # Ruby's core Hash class. See documentation for version
8
+ # 2.1.5[http://ruby-doc.org/core-2.1.5/Hash.html],
9
+ # 2.0.0[http://ruby-doc.org/core-2.0.0/Hash.html], or
10
+ # 1.9.3[http://ruby-doc.org/core-1.9.3/Hash.html].
11
+
12
+ class Hash
13
+
14
+ # The +#assert_valid_keys method validates that all keys in a hash
15
+ # match +*valid_keys+, raising an ArgumentError if the keys don't
16
+ # match. Note that, as usual, symbols and strings are treated as
17
+ # distinct.
18
+ #
19
+ # Examples:
20
+ # {:foo => 'bar'}.assert_valid_keys(:foo) # => true
21
+ # {:foo => 'bar'}.assert_valid_keys(:foo, :baz) # => true
22
+ # {:foo => 'bar'}.assert_valid_keys(:baz) # => ArgumentError
23
+ # {:foo => 'bar'}.assert_valid_keys('foo') # => ArgumentError
24
+
25
+ def assert_valid_keys(*valid_keys)
26
+ valid_keys.flatten!
27
+ each_key do |key|
28
+ unless valid_keys.include?(key)
29
+ raise ArgumentError.new("Unknown key: #{key.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
30
+ end
31
+ end
32
+ end
33
+
34
+ # The +#stringify_keys+ method returns a hash identical to the calling
35
+ # hash, but with symbol keys turned into strings. It is non-destructive;
36
+ # the original hash is still available after it is called.
37
+ #
38
+ # Although this method was formerly a part of ActiveSupport, it was
39
+ # already deprected by the time ReactiveSupport was introduced. For
40
+ # that reason, it is being included as part of ReactiveExtensions.
41
+ #
42
+ # Examples:
43
+ # orig = { :foo => 'bar' }
44
+ # dup = orig.stringify_keys
45
+ #
46
+ # orig #=> { :foo => 'bar' }
47
+ # dup #=> { 'foo' => 'bar' }
48
+
49
+ def stringify_keys
50
+ transform_keys &:to_s
51
+ end
52
+
53
+ # The +#stringify_keys!+ method converts symbol hash keys into strings.
54
+ # It is a destructive method; the original hash is changed when this
55
+ # method is called.
56
+ #
57
+ # Although this method was formerly a part of ActiveSupport, it was already
58
+ # deprecated by the time ReactiveSupport was introduced. For that reason,
59
+ # it is being included as part of ReactiveExtensions.
60
+ #
61
+ # Examples:
62
+ # orig = { :foo => 'bar' }
63
+ # orig.symbolize_keys!
64
+ #
65
+ # orig #=> { 'foo' => 'bar' }
66
+
67
+ def stringify_keys!
68
+ transform_keys! &:to_s
69
+ end
70
+
71
+ # The +#symbolize_keys+ method returns a hash identical to the calling
72
+ # hash but with string keys turned into symbols. It is non-destructive;
73
+ # the original hash is still available after it is called.
74
+ #
75
+ # Although this method was formerly a part of ActiveSupport, it was
76
+ # already deprecated by the time ReactiveSupport was introduced. For
77
+ # that reason, it is being included as part of ReactiveExtensions.
78
+ #
79
+ # Examples:
80
+ # orig = { 'foo' => 'bar' }
81
+ # dup = orig.symbolize_keys
82
+ #
83
+ # orig #=> { 'foo' => 'bar' }
84
+ # dup #=> { :foo => 'bar' }
85
+
86
+ def symbolize_keys
87
+ transform_keys {|key| key.to_sym }
88
+ end
89
+
90
+ # The +#symbolize_keys!+ method converts string hash keys into symbols.
91
+ # It is a destructive method; the original hash is changed when this
92
+ # method is called.
93
+ #
94
+ # Although this method was formerly a part of ActiveSupport, it was already
95
+ # deprecated by the time ReactiveSupport was introduced. For that reason,
96
+ # it is being included as part of ReactiveExtensions.
97
+ #
98
+ # Examples:
99
+ # orig = { 'foo' => 'bar' }
100
+ # orig.symbolize_keys!
101
+ #
102
+ # orig #=> { :foo => 'bar' }
103
+
104
+ def symbolize_keys!
105
+ transform_keys! {|key| key.to_sym }
106
+ end
107
+
108
+ # The +#transform_keys+ method returns a new hash with all keys transformed
109
+ # in accordance with the given +block+. The +#transform_keys+ method is
110
+ # non-destructive; the original hash will still be available after it is
111
+ # called.
112
+ #
113
+ # If no block is given, the method returns an enumerator.
114
+ #
115
+ # Example:
116
+ # hash = { :foo => 'bar' }
117
+ # hash.transform_keys {|key| key.to_s.upcase } # => { 'FOO' => 'bar' }
118
+ # hash.transform_keys # => #<Enumerator: {:foo=>"bar"}:transform_keys>
119
+ # hash # => { :foo => 'bar' }
120
+
121
+ def transform_keys(&block)
122
+ return enum_for(:transform_keys) unless block_given?
123
+ dup = self.class.new
124
+
125
+ each_key do |key|
126
+ dup[yield key] = self[key]
127
+ end
128
+
129
+ dup
130
+ end
131
+
132
+ # The +#transform_keys!+ method transforms all of the calling hash's keys
133
+ # in accordance with the given +block+. The +#transform_keys!+ method is
134
+ # destructive; the original hash will be changed in place after it is
135
+ # called.
136
+ #
137
+ # If no block is given, the method returns an enumerator.
138
+ #
139
+ # Example:
140
+ # hash = { :foo => 'bar' }
141
+ # hash.transform_keys! {|key| key.to_s.upcase } # => { 'FOO' => 'bar' }
142
+ # hash.transform_keys! # => #<Enumerator: {:foo=>"bar"}:transform_keys!>
143
+ # hash # => { 'FOO' => 'bar' }
144
+
145
+ def transform_keys!(&block)
146
+ return enum_for(:transform_keys) unless block_given?
147
+
148
+ keys.each do |key|
149
+ self[yield key] = delete(key)
150
+ end
151
+
152
+ self
153
+ end
154
+ end
@@ -0,0 +1 @@
1
+ Dir['./lib/reactive_support/core_ext/hash/*.rb'].each {|f| require f }
@@ -1,3 +1,5 @@
1
+ require 'reactive_support/core_ext/object/duplicable'
2
+
1
3
  # Ruby's core Object class. See documentation for version
2
4
  # 2.1.3[http://ruby-doc.org/core-2.1.3/Object.html],
3
5
  # 2.0.0[http://ruby-doc.org/core-2.1.3/Object.html], or
@@ -0,0 +1 @@
1
+ Dir['./lib/reactive_support/core_ext/object/*.rb'].each {|f| require f }
@@ -0,0 +1 @@
1
+ Dir['./lib/reactive_support/core_ext/**/*.rb'].each {|f| require f }
@@ -1,5 +1,4 @@
1
- Dir['./lib/reactive_support/core_ext/**/*.rb'].each {|f| require f }
2
- Dir['./lib/reactive_support/extensions/**/*.rb'].each {|f| require f }
1
+ Dir['./lib/reactive_support/*.rb'].each {|f| require f }
3
2
 
4
3
  # The ReactiveSupport module implements methods from ActiveSupport. It can be
5
4
  # included in Ruby's +Object+ class by adding +require 'reactive_support'+ to
@@ -8,6 +7,7 @@ Dir['./lib/reactive_support/extensions/**/*.rb'].each {|f| require f }
8
7
  #
9
8
  # In this example, ReactiveSupport's #try method is called on an array:
10
9
  # require 'reactive_support'
10
+ # require 'reactive_support/core_ext/array/try'
11
11
  #
12
12
  # arr = %w(foo, bar, baz)
13
13
  # arr.try(:join, '.')
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
 
9
9
  s.name = 'reactive_support'
10
10
  s.version = ReactiveSupport.gem_version
11
- s.date = '2014-11-27'
11
+ s.date = '2014-11-28'
12
12
 
13
13
  s.description = "ActiveSupport methods re-implemented independently of the Rails ecosystem"
14
14
  s.summary = "ReactiveSupport provides useful ActiveSupport methods in a gem that is simple, stable, agnostic, and transparent."
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
 
19
19
  # = MANIFEST =
20
20
  s.files = ReactiveSupport.files
21
- s.require_path = 'lib'
21
+ s.require_paths = ['lib']
22
22
  # = MANIFEST =
23
23
 
24
24
  s.test_files = s.files.select {|path| path =~ /^spec\/.*.rb/ }
data/spec/hash_spec.rb ADDED
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hash do
4
+ let(:hash) { { :foo => 'bar', :baz => 'qux' } }
5
+
6
+ describe 'assert_valid_keys' do
7
+ context 'all keys are valid' do
8
+ it 'returns the hash' do
9
+ expect(hash.assert_valid_keys(:foo, :baz)).to eql hash
10
+ end
11
+
12
+ it 'doesn\'t raise an error' do
13
+ expect{ hash.assert_valid_keys(:foo, :baz) }.not_to raise_error
14
+ end
15
+ end
16
+
17
+ context 'keys are a subset of valid keys' do
18
+ it 'returns the hash' do
19
+ expect(hash.assert_valid_keys(:foo, :bar, :baz)).to eql hash
20
+ end
21
+
22
+ it 'doesn\'t raise an error' do
23
+ expect{ hash.assert_valid_keys(:foo, :bar, :baz) }.not_to raise_error
24
+ end
25
+ end
26
+
27
+ context 'keys are wrong type' do
28
+ it 'raises an ArgumentError' do
29
+ expect{ hash.assert_valid_keys(:foo, 'baz') }.to raise_error(ArgumentError)
30
+ end
31
+ end
32
+
33
+ context 'invalid keys are present' do
34
+ it 'raises an ArgumentError' do
35
+ expect{ hash.assert_valid_keys(:foo, 'baz') }.to raise_error(ArgumentError)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe 'stringify_keys' do
41
+ it 'turns symbol keys into strings' do
42
+ expect(hash.stringify_keys).to eql({'foo' => 'bar', 'baz' => 'qux'})
43
+ end
44
+
45
+ it 'maintains the original hash' do
46
+ expect { hash.stringify_keys }.not_to change(hash, :keys)
47
+ end
48
+ end
49
+
50
+ describe 'stringify_keys!' do
51
+ it 'turns symbol keys into strings' do
52
+ expect(hash.stringify_keys!).to eql({'foo' => 'bar', 'baz' => 'qux'})
53
+ end
54
+
55
+ it 'overwrites the original hash' do
56
+ expect { hash.stringify_keys! }.to change(hash, :keys)
57
+ end
58
+ end
59
+
60
+ describe 'symbolize_keys' do
61
+ let(:hash) { {'foo' => 'bar' } }
62
+
63
+ it 'turns string keys into symbols' do
64
+ expect(hash.symbolize_keys).to eql({:foo => 'bar'})
65
+ end
66
+
67
+ it 'maintains the original hash' do
68
+ expect { hash.symbolize_keys }.not_to change(hash, :keys)
69
+ end
70
+ end
71
+
72
+ describe 'symbolize_keys!' do
73
+ let(:hash) { {'foo' => 'bar' } }
74
+
75
+ it 'turns string keys into symbols' do
76
+ expect(hash.symbolize_keys!).to eql({:foo => 'bar'})
77
+ end
78
+
79
+ it 'overwrites the original hash' do
80
+ expect{ hash.symbolize_keys! }.to change(hash, :keys)
81
+ end
82
+ end
83
+
84
+ describe 'transform_keys' do
85
+ it 'changes keys according to a block' do
86
+ transformed = hash.transform_keys {|key| key.to_s.upcase }
87
+ expect(transformed).to eql({'FOO' => 'bar', 'BAZ' => 'qux'})
88
+ end
89
+
90
+ it 'is non-destructive' do
91
+ expect{ hash.transform_keys {|key| key.to_s.upcase } }.not_to change(hash, :keys)
92
+ end
93
+
94
+ context 'no block given' do
95
+ it 'returns an enumerator' do
96
+ expect(hash.transform_keys).to be_an(Enumerator)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe 'transform_keys!' do
102
+ it 'changes keys according to a block' do
103
+ transformed = hash.transform_keys! {|key| key.to_s.upcase }
104
+ expect(transformed).to eql({'FOO' => 'bar', 'BAZ' => 'qux'})
105
+ end
106
+
107
+ it 'is destructive' do
108
+ expect{ hash.transform_keys! {|key| key.to_s.upcase } }.to change(hash, :keys)
109
+ end
110
+
111
+ context 'no block given' do
112
+ it 'returns an enum' do
113
+ expect(hash.transform_keys!).to be_an(Enumerator)
114
+ end
115
+ end
116
+ end
117
+ end
data/version.rb CHANGED
@@ -5,9 +5,9 @@ module ReactiveSupport
5
5
 
6
6
  module Version
7
7
  MAJOR = '0'
8
- MINOR = '4'
8
+ MINOR = '5'
9
9
  PATCH = '0'
10
- PRE = 'beta3'
10
+ PRE = 'beta'
11
11
 
12
12
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.').chomp('.')
13
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reactive_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.beta3
4
+ version: 0.5.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Scheider
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-27 00:00:00.000000000 Z
11
+ date: 2014-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -76,7 +76,12 @@ extra_rdoc_files:
76
76
  - LICENSE
77
77
  files:
78
78
  - "./lib/reactive_support.rb"
79
+ - "./lib/reactive_support/core_ext.rb"
80
+ - "./lib/reactive_support/core_ext/array.rb"
79
81
  - "./lib/reactive_support/core_ext/array/access.rb"
82
+ - "./lib/reactive_support/core_ext/hash.rb"
83
+ - "./lib/reactive_support/core_ext/hash/keys.rb"
84
+ - "./lib/reactive_support/core_ext/object.rb"
80
85
  - "./lib/reactive_support/core_ext/object/blank.rb"
81
86
  - "./lib/reactive_support/core_ext/object/deep_dup.rb"
82
87
  - "./lib/reactive_support/core_ext/object/duplicable.rb"
@@ -84,13 +89,8 @@ files:
84
89
  - "./lib/reactive_support/core_ext/object/inclusion.rb"
85
90
  - "./lib/reactive_support/core_ext/object/instance_variables.rb"
86
91
  - "./lib/reactive_support/core_ext/object/try.rb"
87
- - "./lib/reactive_support/extensions/array_extensions.rb"
88
- - "./lib/reactive_support/extensions/hash_extensions.rb"
89
- - "./lib/reactive_support/extensions/object_extensions.rb"
90
- - "./lib/reactive_support/extensions/proc_extensions.rb"
91
- - "./lib/reactive_support/extensions/reactive_extensions.rb"
92
92
  - "./spec/array_spec.rb"
93
- - "./spec/reactive_extensions_spec.rb"
93
+ - "./spec/hash_spec.rb"
94
94
  - "./spec/reactive_support_spec.rb"
95
95
  - "./spec/spec_helper.rb"
96
96
  - CONTRIBUTING.md
@@ -1,51 +0,0 @@
1
- class Array
2
-
3
- # The +#scope+ method is called on an array of hashes. It returns a sub-array
4
- # including only hashes for which the value at a given +key+ is among the given +values+.
5
- # The +#scope+ method is non-destructive; the original array will remain intact
6
- # after it is called. The +#scope+ method is known to work for string or symbol
7
- # keys. It should work for other data type keys as well.
8
- #
9
- # Example:
10
- # array = [
11
- # { name: 'Jean-Paul Sartre', nationality: 'French' },
12
- # { name: 'Bertrand Russell', nationality: 'English' },
13
- # { name: 'Ludwig Wittgenstein', nationality: 'Austrian' },
14
- # { name: 'Albert Camus', nationality: 'French' }
15
- # ]
16
- #
17
- # array.scope(:nationality, 'French')
18
- # # => [
19
- # { name: 'Jean-Paul Sartre', nationality: 'French' },
20
- # { name: 'Albert Camus', nationality: 'French' }
21
- # ]
22
-
23
- def scope(key, *values)
24
- self.select {|hash| hash[key].in?(values) }
25
- end
26
-
27
- # The +#where_not+ method is called on an array of hashes. It returns a sub-array
28
- # including only hashes for which the value at a given +key+ is not among the
29
- # given +values+. It is the inverse of the +#scope+ method. The +#where_not+ method
30
- # is non-destructive; the original array will remain intact after it is called. The
31
- # +#where_not+ method is known to work for string or symbol keys. It should work for
32
- # other data types as well.
33
- #
34
- # Example:
35
- # array = [
36
- # { name: 'Jean-Paul Sartre', nationality: 'French' },
37
- # { name: 'Bertrand Russell', nationality: 'English' },
38
- # { name: 'Ludwig Wittgenstein', nationality: 'Austrian' },
39
- # { name: 'Albert Camus', nationality: 'French' }
40
- # ]
41
- #
42
- # array.where_not(:nationality, 'French')
43
- # # => [
44
- # { name: 'Bertrand Russell', nationality: 'English' },
45
- # { name: 'Ludwig Wittgenstein', nationality: 'English' }
46
- # ]
47
-
48
- def where_not(key, *values)
49
- self.reject {|hash| hash[key].in?(values) }
50
- end
51
- end
@@ -1,135 +0,0 @@
1
- class Hash
2
-
3
- # The +#clean+ method returns a hash identical to the calling hash but
4
- # with the given +*keys+, if present, removed. If all the keys in the
5
- # hash are given as arguments, an empty hash is returned. The +#clean+
6
- # method is non-destructive; the original hash is still available after
7
- # it is called. It does have a destructive form, +#clean!+.
8
- #
9
- # Examples:
10
- # hash = {:foo => 'bar'}
11
- # hash.clean(:baz) # => {:foo => 'bar'}
12
- # hash.clean(:foo) # => {}
13
- # hash # => {:foo => 'bar'}
14
- #
15
- # Examples with multiple arguments:
16
- # hash = { 'foo' => 'bar', 'baz' => 'qux', => :norf => 'raboof' }
17
- # hash.clean('foo', :norf) # => {'baz' => 'qux'}
18
- # hash # => { 'foo' => 'bar', 'baz' => 'qux', :norf => 'raboof' }
19
-
20
- def clean(*keys)
21
- self.reject {|k,v| k.in?(keys) }
22
- end
23
-
24
- # The +#clean!+ method returns a hash identical to the calling hash but
25
- # with the given +*keys+, if present, removed. If all the keys in the
26
- # hash are given as arguments, an empty hash is returned. The +#clean!+
27
- # method is non-destructive; the original hash is still available after
28
- # it is called. It does have a non-destructive form, +#clean+.
29
- #
30
- # Examples where hash is not changed:
31
- # hash = {:foo => 'bar'}
32
- # hash.clean!(:baz) # => {:foo => 'bar'}
33
- # hash # => {:foo => 'bar'}
34
- #
35
- # Examples where hash is changed:
36
- # hash = {'foo' => 'bar'}
37
- # hash.clean!(:foo) # => {}
38
- # hash # => {}
39
- #
40
- # Examples with multiple arguments:
41
- # hash = { 'foo' => 'bar', 'baz' => 'qux', => :norf => 'raboof' }
42
- # hash.clean('foo', :norf) # => {'baz' => 'qux'}
43
- # hash # => {'baz' => 'qux'}
44
-
45
- def clean!(*keys)
46
- self.reject! {|k,v| k.in?(keys) }
47
- self
48
- end
49
-
50
- # The +#symbolize_keys+ method returns a hash identical to the calling
51
- # hash but with string keys turned into symbols. It is non-destructive;
52
- # the original hash is still available after it is called.
53
- #
54
- # Although this method was formerly a part of ActiveSupport, it was
55
- # already deprecated by the time ReactiveSupport was introduced. For
56
- # that reason, it is being included as part of ReactiveExtensions.
57
- #
58
- # Examples:
59
- # orig = { 'foo' => 'bar' }
60
- # dup = orig.symbolize_keys
61
- #
62
- # orig #=> { 'foo' => 'bar' }
63
- # dup #=> { :foo => 'bar' }
64
-
65
- def symbolize_keys
66
- dup = {}
67
- self.each {|k, v| dup[k.to_sym] = v }
68
- dup
69
- end
70
-
71
- # The +#symbolize_keys!+ method converts string hash keys into symbols.
72
- # It is a destructive method; the original hash is changed when this
73
- # method is called.
74
- #
75
- # Although this method was formerly a part of ActiveSupport, it was already
76
- # deprecated by the time ReactiveSupport was introduced. For that reason,
77
- # it is being included as part of ReactiveExtensions.
78
- #
79
- # Examples:
80
- # orig = { 'foo' => 'bar' }
81
- # orig.symbolize_keys!
82
- #
83
- # orig #=> { :foo => 'bar' }
84
-
85
- def symbolize_keys!
86
- keys.each do |key|
87
- self[(key.to_sym rescue key) || key] = delete(key)
88
- end
89
-
90
- self
91
- end
92
-
93
- # The +#stringify_keys+ method returns a hash identical to the calling
94
- # hash, but with symbol keys turned into strings. It is non-destructive;
95
- # the original hash is still available after it is called.
96
- #
97
- # Although this method was formerly a part of ActiveSupport, it was
98
- # already deprected by the time ReactiveSupport was introduced. For
99
- # that reason, it is being included as part of ReactiveExtensions.
100
- #
101
- # Examples:
102
- # orig = { :foo => 'bar' }
103
- # dup = orig.stringify_keys
104
- #
105
- # orig #=> { :foo => 'bar' }
106
- # dup #=> { 'foo' => 'bar' }
107
-
108
- def stringify_keys
109
- dup = {}
110
- self.each {|k, v| dup[k.to_s] = v }
111
- dup
112
- end
113
-
114
- # The +#stringify_keys!+ method converts symbol hash keys into strings.
115
- # It is a destructive method; the original hash is changed when this
116
- # method is called.
117
- #
118
- # Although this method was formerly a part of ActiveSupport, it was already
119
- # deprecated by the time ReactiveSupport was introduced. For that reason,
120
- # it is being included as part of ReactiveExtensions.
121
- #
122
- # Examples:
123
- # orig = { :foo => 'bar' }
124
- # orig.symbolize_keys!
125
- #
126
- # orig #=> { 'foo' => 'bar' }
127
-
128
- def stringify_keys!
129
- keys.each do |key|
130
- self[(key.to_s rescue key) || key] = delete(key)
131
- end
132
-
133
- self
134
- end
135
- end
@@ -1,48 +0,0 @@
1
- class Object
2
-
3
- # The +#try_rescue+ method extends ReactiveSupport's +#try+ method so it
4
- # rescues NoMethodErrors and TypeErrors as well as returning +nil+ when
5
- # called on a +nil+ value.
6
- #
7
- # Like the +#try+ method, +#try_rescue+ takes 1 or more arguments. The first
8
- # argument is the method to be called on the calling object, passed as a
9
- # symbol. The others are zero or more arguments that will be passed through to
10
- # that method, and +&block+ is an optional block that will be similarly passed through.
11
- #
12
- # Example of usage identical to +#try+:
13
- # nil.try(:map) {|a| a.to_s } # => nil
14
- # nil.try_rescue(:map) {|a| a.to_s } # => nil
15
- #
16
- # Example of usage calling a method that is not defined on the calling object:
17
- # 10.try(:to_h) # => TypeError
18
- # 10.try_rescue(:to_h) # => nil
19
- #
20
- # Example of usage with invalid arguments:
21
- # %w(foo, bar, baz).try(:join, [:hello, :world]) # => TypeError
22
- # %w(foo, bar, baz).try_rescue(:join, [:hello, :world]) # => nil
23
-
24
- def try_rescue(*args, &block)
25
- self.try(*args, &block) rescue nil
26
- end
27
- end
28
-
29
- # The +#try_rescue+ method extends ReactiveSupport's +#try+ method so it rescues
30
- # NoMethodErrors and TypeErrors as well as returning +nil+ when called on a +nil+
31
- # value.
32
- #
33
- # Like the +#try+ method, +#try_rescue+ takes 1 or more arguments. The first argument
34
- # is the method to be called on the calling object, passed as a symbol. The others
35
- # are zero or more arguments that will be passed through to that method, and an
36
- # optional block to be likewise passed through.
37
- #
38
- # When called on NilClass, +#try_rescue+ always returns nil.
39
- #
40
- # Example:
41
- # foo = nil
42
- # foo.try_rescue(:has_key?, :bar) # => nil
43
-
44
- class NilClass
45
- def try_rescue(*args, &block)
46
- nil
47
- end
48
- end
@@ -1,29 +0,0 @@
1
- # Ruby's core Proc class. See documentation for version
2
- # 2.1.5[http://ruby-doc.org/core-2.1.5/Proc.html],
3
- # 2.0.0[http://ruby-doc.org/core-2.0.0/Proc.html], or
4
- # 1.9.3[http://ruby-doc.org/core-1.9.3/Proc.html].
5
-
6
- class Proc
7
-
8
- # The +#raises_error?+ method checks whether an exception is raised
9
- # when the calling Proc is called with the given +*args+.
10
- #
11
- # The +#raises_error?+ method does not actually create lasting changes
12
- # to objects or variables; it only checks whether an exception would be
13
- # raised if the Proc were called with the given +*args+.
14
- #
15
- # Basic examples:
16
- # proc = Proc.new {|q| 1.quo(q) }
17
- # proc.raises_error?(2) # => false
18
- # proc.raises_error?(0) # => true
19
- #
20
- # Examples with destructive proc:
21
- # hash = {:foo => :bar}
22
- # proc = Proc.new {|hash| hash.reject! {|k,v| k === :foo } }
23
- # proc.raises_error?(hash) # => false
24
- # hash # => {:foo => :bar}
25
-
26
- def raises_error?(*args)
27
- (!self.call(*args.deep_dup)) rescue true
28
- end
29
- end
@@ -1,12 +0,0 @@
1
-
2
- # The ReactiveExtensions module consists of methods I wish ActiveSupport provided.
3
- # These methods do not adhere to the ActiveSupport API. If you wish to include
4
- # them in your project, you will need to put this in your main project file:
5
- # require 'reactive_support/extensions'
6
- #
7
- # ReactiveExtensions includes ReactiveSupport, so you will need to remove any
8
- # requires for ReactiveSupport as it will raise a SystemStackError.
9
-
10
- module ReactiveExtensions
11
- Dir['./lib/reactive_support/extensions/*.rb'].each {|f| require f }
12
- end
@@ -1,246 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ReactiveExtensions do
4
- describe '#try_rescue method' do
5
- context 'when self is nil' do
6
- it 'returns nil' do
7
- expect(nil.try_rescue(:collect) {|i| i + 2 }).to eql nil
8
- end
9
- end
10
-
11
- context 'when the method can be executed successfully' do
12
- it 'calls the method' do
13
- expect('foo'.try_rescue(:upcase)).to eql 'FOO'
14
- end
15
- end
16
-
17
- context 'when a NoMethodError is raised' do
18
- it 'returns nil' do
19
- expect(('foo').try_rescue(:bar)).to eql nil
20
- end
21
- end
22
- end
23
-
24
- describe 'array methods' do
25
- let(:sartre) { { 'name' => 'Jean-Paul Sartre', 'nationality' => 'French' } }
26
- let(:russell) { { 'name' => 'Bertrand Russell', 'nationality' => 'English' } }
27
- let(:wittgenstein) { { 'name' => 'Ludwig Wittgenstein', 'nationality' => 'Austrian' } }
28
- let(:camus) { { 'name' => 'Albert Camus', 'nationality' => 'French' } }
29
- let(:array) { [sartre, russell, wittgenstein, camus] }
30
-
31
- describe 'array #scope method' do
32
- context 'symbol keys' do
33
- context 'single value' do
34
- it 'returns scoped hashes' do
35
- array.each {|hash| hash.symbolize_keys! }
36
- expect(array.scope(:nationality, 'French')).to eql([sartre, camus])
37
- end
38
- end
39
-
40
- context 'multiple values' do
41
- it 'returns scoped hashes' do
42
- array.each {|hash| hash.symbolize_keys! }
43
- expect(array.scope(:nationality, 'French', 'English')).to eql([sartre, russell, camus])
44
- end
45
- end
46
- end
47
-
48
- context 'string keys' do
49
- context 'single value' do
50
- it 'returns scoped hashes' do
51
- expect(array.scope('nationality', 'French')).to eql([sartre, camus])
52
- end
53
- end
54
-
55
- context 'multiple values' do
56
- it 'returns scoped hashes' do
57
- expect(array.scope('nationality', 'French', 'English')).to eql([sartre, russell, camus])
58
- end
59
- end
60
- end
61
- end
62
-
63
- describe 'array #where_not method' do
64
- context 'symbol keys' do
65
- context 'single value' do
66
- it 'returns scoped hashes' do
67
- array.each {|hash| hash.symbolize_keys! }
68
- expect(array.where_not(:nationality, 'French')).to eql([russell, wittgenstein])
69
- end
70
- end
71
-
72
- context 'multiple values' do
73
- it 'returns scoped hashes' do
74
- array.each {|hash| hash.symbolize_keys! }
75
- expect(array.where_not(:nationality, 'French', 'English')).to eql([wittgenstein])
76
- end
77
- end
78
- end
79
-
80
- context 'string keys' do
81
- context 'single value' do
82
- it 'returns scoped hashes' do
83
- expect(array.where_not('nationality', 'French')).to eql([russell, wittgenstein])
84
- end
85
- end
86
-
87
- context 'multiple values' do
88
- it 'returns scoped hashes' do
89
- expect(array.where_not('nationality', 'French', 'English')).to eql([wittgenstein])
90
- end
91
- end
92
- end
93
- end
94
- end
95
-
96
- describe 'hash methods' do
97
- describe 'symbolize_keys' do
98
- it 'turns string keys into symbols' do
99
- expect({'foo' => 'bar'}.symbolize_keys).to eql({:foo => 'bar'})
100
- end
101
-
102
- it 'maintains the original hash' do
103
- hash = { 'foo' => 'bar' }
104
- expect { hash.symbolize_keys }.not_to change(hash, :keys)
105
- end
106
- end
107
-
108
- describe 'symbolize_keys!' do
109
- it 'turns string keys into symbols' do
110
- expect({'foo' => 'bar'}.symbolize_keys!).to eql({:foo => 'bar'})
111
- end
112
-
113
- it 'overwrites the original hash' do
114
- hash = { 'foo' => 'bar' }
115
- expect { hash.symbolize_keys! }.to change(hash, :keys)
116
- end
117
- end
118
-
119
- describe 'stringify_keys' do
120
- it 'turns symbol keys into strings' do
121
- expect({foo: 'bar'}.stringify_keys).to eql({'foo' => 'bar'})
122
- end
123
-
124
- it 'maintains the original hash' do
125
- hash = { foo: 'bar' }
126
- expect { hash.stringify_keys }.not_to change(hash, :keys)
127
- end
128
- end
129
-
130
- describe 'stringify_keys!' do
131
- it 'turns symbol keys into strings' do
132
- expect({foo: 'bar'}.stringify_keys!).to eql({'foo' => 'bar'})
133
- end
134
-
135
- it 'overwrites the original hash' do
136
- hash = { foo: 'bar' }
137
- expect { hash.stringify_keys! }.to change(hash, :keys)
138
- end
139
- end
140
-
141
- describe 'clean' do
142
- context 'when no cleaning is needed' do
143
- it 'returns the original hash' do
144
- expect({:foo => 'bar'}.clean(:baz)). to eql({:foo => 'bar'})
145
- end
146
-
147
- it 'doesn\'t raise an error' do
148
- expect{ {:foo => 'bar'}.clean(:baz) }.not_to raise_error
149
- end
150
- end
151
-
152
- context 'when there are some keys to clean' do
153
- it 'removes specified keys' do
154
- expect({:foo => 'bar', :baz => 'qux'}.clean(:baz)).to eql({:foo => 'bar'})
155
- end
156
-
157
- it 'doesn\'t change the original hash' do
158
- hash = {:foo => 'bar', :baz => 'qux', 'norf' => 'raboof'}
159
- expect{ hash.clean(:baz, 'norf') }.not_to change(hash, :keys)
160
- end
161
- end
162
-
163
- context 'when all keys must be cleaned' do
164
- it 'returns an empty hash' do
165
- expect({:foo => 'bar'}.clean(:foo)).to eql({})
166
- end
167
-
168
- it 'doesn\'t change the original hash' do
169
- hash = {:foo => 'bar'}
170
- expect{ hash.clean(:foo) }.not_to change(hash, :keys)
171
- end
172
- end
173
- end
174
-
175
- describe 'clean!' do
176
- context 'when no cleaning is needed' do
177
- it 'returns the original hash' do
178
- expect({:foo => 'bar'}.clean!(:baz)). to eql({:foo => 'bar'})
179
- end
180
-
181
- it 'doesn\'t raise an error' do
182
- expect{ {:foo => 'bar'}.clean(:baz) }.not_to raise_error
183
- end
184
- end
185
-
186
- context 'when there are some keys to clean' do
187
- it 'removes specified keys' do
188
- expect({:foo => 'bar', :baz => 'qux'}.clean!(:baz)).to eql({:foo => 'bar'})
189
- end
190
-
191
- it 'changes the original hash' do
192
- hash = {:foo => 'bar', :baz => 'qux', 'norf' => 'raboof'}
193
- expect{ hash.clean!(:baz, 'norf') }.to change(hash, :keys)
194
- end
195
-
196
- it 'returns the hash' do
197
- hash = {:foo => 'bar', :baz => 'qux'}
198
- expect(hash.clean!(:baz)).to eql hash
199
- end
200
- end
201
-
202
- context 'when all keys must be cleaned' do
203
- it 'returns an empty hash' do
204
- expect({:foo => 'bar'}.clean!(:foo)).to eql({})
205
- end
206
-
207
- it 'changes the original hash' do
208
- hash = {:foo => 'bar'}
209
- expect{ hash.clean!(:foo) }.to change(hash, :keys)
210
- end
211
-
212
- it 'returns the hash' do
213
- hash = {:foo => 'bar'}
214
- expect(hash.clean!(:foo)).to eql hash
215
- end
216
- end
217
- end
218
- end
219
-
220
- describe 'proc methods' do
221
- describe 'raises_error?' do
222
- let(:proc) { Proc.new {|quotient| 1.quo(quotient) } }
223
-
224
- context 'when an error is raised' do
225
- it 'returns true' do
226
- expect(proc.raises_error?(0)).to be true
227
- end
228
-
229
- it 'handles the exception' do
230
- expect{ proc.raises_error?(0) }.not_to raise_error
231
- end
232
- end
233
-
234
- context 'when no error is raised' do
235
- it 'returns false' do
236
- expect(proc.raises_error?(2)).to be false
237
- end
238
-
239
- it 'doesn\'t change objects' do
240
- h, p = {:foo => :bar}, Proc.new {|hash| hash.reject! {|k,v| k === :foo } }
241
- expect{ p.raises_error?(h) }.not_to change(h, :length)
242
- end
243
- end
244
- end
245
- end
246
- end