dish 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +53 -1
- data/lib/dish/ext/array.rb +2 -2
- data/lib/dish/ext/hash.rb +2 -2
- data/lib/dish/helper.rb +3 -3
- data/lib/dish/plate.rb +37 -19
- data/lib/dish/version.rb +1 -1
- data/test/coercion_test.rb +63 -0
- data/test/dish_test.rb +16 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f491f4e6dd55335d75c28db8a8cbfc68f5ef445e
|
4
|
+
data.tar.gz: 56472250206b5de7862205d6074fcb3233cb1bc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c652e54b74c3d55db537774ccace1a900fc89a74bfb88f3d12d88474e8226167da3c1cd840823813e5de60c11146f46811ccacea444d0554b7048b041fb247a1
|
7
|
+
data.tar.gz: fcc7e13e2b51c93012f6b0058a0f1dfd81c0f52cece0e6a7686b994b3295aac6f442d045fc06eca52bb7efbaadac1390f3f1f9d2cfc52f641691916041530316
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -41,7 +41,7 @@ And you're good to go.
|
|
41
41
|
|
42
42
|
Note: If you're using Dish with the BubbleWrap JSON module, please see below.
|
43
43
|
|
44
|
-
|
44
|
+
## Example
|
45
45
|
|
46
46
|
hash = {
|
47
47
|
title: "My Title",
|
@@ -61,6 +61,58 @@ Note: If you're using Dish with the BubbleWrap JSON module, please see below.
|
|
61
61
|
book.other # => nil
|
62
62
|
book.other? # => false
|
63
63
|
|
64
|
+
## Coercion
|
65
|
+
|
66
|
+
Values can automatically be coerced, for example into a custom `Dish` object or a `Time`, for example if you have an `updated_at` in the source.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
class Author < Dish::Plate; end
|
70
|
+
|
71
|
+
class Product < Dish::Plate
|
72
|
+
coerce :updated_at, -> (value) { Time.parse(value) }
|
73
|
+
coerce :authors, Author
|
74
|
+
end
|
75
|
+
|
76
|
+
source_products = [
|
77
|
+
{
|
78
|
+
title: "Test Product",
|
79
|
+
updated_at: "2013-01-28 13:23:11",
|
80
|
+
authors: [
|
81
|
+
{ id: 1, name: "First Author" },
|
82
|
+
{ id: 2, name: "Second Author" }
|
83
|
+
]
|
84
|
+
},
|
85
|
+
{
|
86
|
+
title: "Second Product",
|
87
|
+
updated_at: "2012-07-11 19:54:07",
|
88
|
+
authors: [
|
89
|
+
{ id: 1, name: "Third Author" },
|
90
|
+
{ id: 2, name: "Fourth Author" }
|
91
|
+
]
|
92
|
+
}
|
93
|
+
]
|
94
|
+
|
95
|
+
products = Dish(source_products, Product)
|
96
|
+
products.first.updated_at # => instance of Time (2013-01-28 13:23:11)
|
97
|
+
products.first.authors.first # => instance of Author
|
98
|
+
|
99
|
+
# If you required "dish/ext", you can also:
|
100
|
+
products = source_products.to_dish(Product)
|
101
|
+
|
102
|
+
# The above example uses an array. You can do the same directly on a hash:
|
103
|
+
hash = { title: "My Product", updated_at: "2014-01-15 09:12:45" }
|
104
|
+
product = Dish(hash, Product) # => instance of Product
|
105
|
+
product = hash.to_dish(Product) # => instance of Product when using "dish/ext"
|
106
|
+
```
|
107
|
+
|
108
|
+
This is inspired by [Hashie](https://github.com/intridea/hashie)'s coercion methods.
|
109
|
+
|
110
|
+
Have fun!
|
111
|
+
|
112
|
+
## Accessing the original hash
|
113
|
+
|
114
|
+
You can use the `as_hash` method for accessing the original hash.
|
115
|
+
|
64
116
|
## Notes
|
65
117
|
|
66
118
|
### Using with the BubbleWrap JSON module
|
data/lib/dish/ext/array.rb
CHANGED
data/lib/dish/ext/hash.rb
CHANGED
data/lib/dish/helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
def Dish(hash_or_array)
|
1
|
+
def Dish(hash_or_array, klass = Dish::Plate)
|
2
2
|
case hash_or_array
|
3
|
-
when Hash then
|
4
|
-
when Array then hash_or_array.map { |v| Dish(v) }
|
3
|
+
when Hash then klass.new(hash_or_array)
|
4
|
+
when Array then hash_or_array.map { |v| Dish(v, klass) }
|
5
5
|
else hash_or_array
|
6
6
|
end
|
7
7
|
end
|
data/lib/dish/plate.rb
CHANGED
@@ -1,43 +1,61 @@
|
|
1
1
|
module Dish
|
2
2
|
class Plate
|
3
|
+
class << self
|
4
|
+
def coercions
|
5
|
+
@coercions ||= Hash.new(Plate)
|
6
|
+
end
|
7
|
+
|
8
|
+
def coerce(key, klass_or_proc)
|
9
|
+
coercions[key.to_s] = klass_or_proc
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
3
13
|
def initialize(hash)
|
4
|
-
@
|
14
|
+
@_original_hash = Hash[hash.map { |k, v| [k.to_s, v] }]
|
5
15
|
end
|
6
16
|
|
7
17
|
def method_missing(method, *args, &block)
|
8
18
|
method = method.to_s
|
9
19
|
if method.end_with?("?")
|
10
20
|
key = method[0..-2]
|
11
|
-
|
21
|
+
_check_for_presence(key)
|
12
22
|
else
|
13
|
-
|
23
|
+
_get_value(method)
|
14
24
|
end
|
15
25
|
end
|
16
26
|
|
27
|
+
def as_hash
|
28
|
+
@_original_hash
|
29
|
+
end
|
30
|
+
|
17
31
|
private
|
18
32
|
|
19
|
-
attr_reader :
|
33
|
+
attr_reader :_original_hash
|
20
34
|
|
21
|
-
def
|
22
|
-
value =
|
23
|
-
|
35
|
+
def _get_value(key)
|
36
|
+
value = _original_hash[key]
|
37
|
+
_convert_value(value, self.class.coercions[key])
|
24
38
|
end
|
25
39
|
|
26
|
-
def
|
27
|
-
!!
|
40
|
+
def _check_for_presence(key)
|
41
|
+
!!_get_value(key)
|
28
42
|
end
|
29
43
|
|
30
|
-
def
|
44
|
+
def _convert_value(value, coercion)
|
31
45
|
case value
|
32
|
-
when
|
33
|
-
when
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
46
|
+
when Array then value.map { |v| _convert_value(v, coercion) }
|
47
|
+
when Hash
|
48
|
+
if coercion.is_a?(Proc)
|
49
|
+
coercion.call(value)
|
50
|
+
else
|
51
|
+
coercion.new(value)
|
52
|
+
end
|
53
|
+
else
|
54
|
+
if coercion.is_a?(Proc)
|
55
|
+
coercion.call(value)
|
56
|
+
else
|
57
|
+
value
|
58
|
+
end
|
41
59
|
end
|
42
60
|
end
|
43
61
|
end
|
data/lib/dish/version.rb
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class DishTest < Test::Unit::TestCase
|
4
|
+
def test_coercion
|
5
|
+
product = Dish(api_response.first, Product)
|
6
|
+
|
7
|
+
assert_equal Time.new(2013, 1, 28, 13, 23, 11), product.updated_at
|
8
|
+
assert product.authors.all? { |a| a.is_a? Author }
|
9
|
+
assert_equal ["First Author", "Second Author"], product.authors.map(&:name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_hash_helper_coercion
|
13
|
+
product = api_response.first.to_dish(Product)
|
14
|
+
|
15
|
+
assert_equal Time.new(2013, 1, 28, 13, 23, 11), product.updated_at
|
16
|
+
assert product.authors.all? { |a| a.is_a? Author }
|
17
|
+
assert_equal ["First Author", "Second Author"], product.authors.map(&:name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_array_coercion
|
21
|
+
products = Dish(api_response, Product)
|
22
|
+
|
23
|
+
assert products.all? { |p| p.is_a?(Product) }
|
24
|
+
assert products.map(&:authors).flatten.all? { |a| a.is_a?(Author) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_array_helper_coercion
|
28
|
+
products = api_response.to_dish(Product)
|
29
|
+
|
30
|
+
assert products.all? { |p| p.is_a?(Product) }
|
31
|
+
assert products.map(&:authors).flatten.all? { |a| a.is_a?(Author) }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
class Author < Dish::Plate; end
|
37
|
+
|
38
|
+
class Product < Dish::Plate
|
39
|
+
coerce :updated_at, -> (value) { Time.parse(value) }
|
40
|
+
coerce :authors, Author
|
41
|
+
end
|
42
|
+
|
43
|
+
def api_response
|
44
|
+
[
|
45
|
+
{
|
46
|
+
title: "Test Product",
|
47
|
+
updated_at: "2013-01-28 13:23:11",
|
48
|
+
authors: [
|
49
|
+
{ id: 1, name: "First Author" },
|
50
|
+
{ id: 2, name: "Second Author" }
|
51
|
+
]
|
52
|
+
},
|
53
|
+
{
|
54
|
+
title: "Second Product",
|
55
|
+
updated_at: "2012-07-11 19:54:07",
|
56
|
+
authors: [
|
57
|
+
{ id: 1, name: "Third Author" },
|
58
|
+
{ id: 2, name: "Fourth Author" }
|
59
|
+
]
|
60
|
+
}
|
61
|
+
]
|
62
|
+
end
|
63
|
+
end
|
data/test/dish_test.rb
CHANGED
@@ -67,6 +67,22 @@ class DishTest < Test::Unit::TestCase
|
|
67
67
|
assert_nil Dish(nil)
|
68
68
|
end
|
69
69
|
|
70
|
+
def test_as_hash
|
71
|
+
hash = {
|
72
|
+
"a" => "a",
|
73
|
+
"b" => "b",
|
74
|
+
"c" => {
|
75
|
+
"1" => 1,
|
76
|
+
"2" => 2
|
77
|
+
}
|
78
|
+
}
|
79
|
+
dish = Dish(hash)
|
80
|
+
c_hash = dish.c.as_hash
|
81
|
+
assert_equal "Hash", dish.c.as_hash.class.to_s
|
82
|
+
assert_equal hash["c"]["1"], c_hash["1"]
|
83
|
+
assert_equal hash["c"]["2"], c_hash["2"]
|
84
|
+
end
|
85
|
+
|
70
86
|
def test_hash_ext
|
71
87
|
hash = { a: 1, b: 2 }
|
72
88
|
dish = hash.to_dish
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lasse Bunk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -48,6 +48,7 @@ extra_rdoc_files: []
|
|
48
48
|
files:
|
49
49
|
- ".gitignore"
|
50
50
|
- ".travis.yml"
|
51
|
+
- CHANGELOG.md
|
51
52
|
- Gemfile
|
52
53
|
- LICENSE.txt
|
53
54
|
- README.md
|
@@ -61,6 +62,7 @@ files:
|
|
61
62
|
- lib/dish/motion.rb
|
62
63
|
- lib/dish/plate.rb
|
63
64
|
- lib/dish/version.rb
|
65
|
+
- test/coercion_test.rb
|
64
66
|
- test/dish_test.rb
|
65
67
|
- test/test_helper.rb
|
66
68
|
homepage: https://github.com/lassebunk/dish
|
@@ -88,5 +90,6 @@ signing_key:
|
|
88
90
|
specification_version: 4
|
89
91
|
summary: Super simple conversion of hashes to plain Ruby objects
|
90
92
|
test_files:
|
93
|
+
- test/coercion_test.rb
|
91
94
|
- test/dish_test.rb
|
92
95
|
- test/test_helper.rb
|