dish 0.0.4 → 0.0.5
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 +13 -0
- data/README.md +33 -28
- data/lib/dish/plate.rb +40 -6
- data/lib/dish/version.rb +1 -1
- data/test/coercion_test.rb +17 -0
- data/test/deprecated_test.rb +13 -0
- data/test/dish_test.rb +42 -4
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc7f03afd4235d643f705eb69e4090e957e976a4
|
4
|
+
data.tar.gz: 515e6465bb10f1abf86469cd3fdc0774c659c9b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1a8a91507d2d016656d74065e3fafb57843e8abbab074830384f7443b36dd4400c3f0c52060995006c2d65514731063440e500e574ef0c3393554688f29fed2
|
7
|
+
data.tar.gz: c575c4f366a7d8f7c2f5e19f1659b0189447f66560d3bd2b707c1406c6418d05a12acf93db7fdb5fdcb267be5bfce4a0d2625fadaf9fe8949903aa7711d28ae0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.0.5
|
4
|
+
|
5
|
+
* Supports setting values via `some_dish_object.key = 'value'`.
|
6
|
+
* Values are now cached after their first conversion. This improves performance when calling the same methods repeatedly.
|
7
|
+
* Available keys are returned by the `methods` method on a Dish object.
|
8
|
+
* `as_hash` is deprecated and renamed to `to_h`.
|
9
|
+
* Supports converting the Dish object to json via `to_json`.
|
10
|
+
* `respond_to?` and `respond_to_missing?` now works correctly.
|
11
|
+
|
12
|
+
## 0.0.4
|
13
|
+
|
14
|
+
* Implements `respond_to_missing?`.
|
15
|
+
|
3
16
|
## 0.0.3
|
4
17
|
|
5
18
|
* Adds coercion. See the readme for details.
|
data/README.md
CHANGED
@@ -40,27 +40,28 @@ Then run:
|
|
40
40
|
|
41
41
|
And you're good to go.
|
42
42
|
|
43
|
-
|
43
|
+
**NOTE:** If you're using Dish with the BubbleWrap JSON module, please see below.
|
44
44
|
|
45
45
|
## Example
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
46
|
+
```ruby
|
47
|
+
hash = {
|
48
|
+
title: "My Title",
|
49
|
+
authors: [
|
50
|
+
{ id: 1, name: "Mike Anderson" },
|
51
|
+
{ id: 2, name: "Well D." }
|
52
|
+
],
|
53
|
+
active: false
|
54
|
+
}
|
55
|
+
|
56
|
+
book = Dish(hash) # or hash.to_dish if you required "dish/ext"
|
57
|
+
book.title # => "My Title"
|
58
|
+
book.authors.length # => 2
|
59
|
+
book.authors[1].name # => "Well D."
|
60
|
+
book.title? # => true
|
61
|
+
book.active? # => false
|
62
|
+
book.other # => nil
|
63
|
+
book.other? # => false
|
64
|
+
```
|
64
65
|
|
65
66
|
## Coercion
|
66
67
|
|
@@ -110,25 +111,29 @@ This is inspired by [Hashie](https://github.com/intridea/hashie)'s coercion meth
|
|
110
111
|
|
111
112
|
Have fun!
|
112
113
|
|
113
|
-
##
|
114
|
+
## Converting back to Ruby/JSON objects
|
115
|
+
|
116
|
+
You can use the `Dish::Plate#to_h` method for accessing the original hash. In addition `Dish::Plate#to_json` can be used for marshaling JSON if you are using RubyMotion (`NSJSONSerialization` is used) or have required [the "json" Ruby stdlib](http://www.ruby-doc.org/stdlib/libdoc/json/rdoc/JSON.html).
|
114
117
|
|
115
|
-
|
118
|
+
**NOTE:** Previously `Dish::Plate#to_h` was called `Dish::Plate#as_hash`. The `Dish::Plate#as_hash` method is now deprecated.
|
116
119
|
|
117
120
|
## Notes
|
118
121
|
|
119
122
|
### Using with the BubbleWrap JSON module
|
120
123
|
|
121
124
|
When you use the [BubbleWrap](https://github.com/rubymotion/BubbleWrap) gem to parse JSON into a hash, you can't use the
|
122
|
-
`to_dish` methods directly because the `BW::JSON` module returns some sort of hash that hasn't got the methods from the real hash. I'm
|
125
|
+
`Hash#to_dish` methods directly because the `BW::JSON` module returns some sort of hash that hasn't got the methods from the real hash. I'm
|
123
126
|
fixing this, but in the meanwhile you can achieve the same result by doing this:
|
124
127
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
+
```ruby
|
129
|
+
BW::HTTP.get("http://path.to/api/books/2") do |response|
|
130
|
+
json = BW::JSON.parse(response.body.to_s)
|
131
|
+
book = Dish(json) # This is the actual conversion
|
128
132
|
|
129
|
-
|
130
|
-
|
131
|
-
|
133
|
+
title_label.text = book.title
|
134
|
+
author_label.text = book.authors.map(&:name).join(", ")
|
135
|
+
end
|
136
|
+
```
|
132
137
|
|
133
138
|
## Contributing
|
134
139
|
|
data/lib/dish/plate.rb
CHANGED
@@ -12,13 +12,16 @@ module Dish
|
|
12
12
|
|
13
13
|
def initialize(hash)
|
14
14
|
@_original_hash = Hash[hash.map { |k, v| [k.to_s, v] }]
|
15
|
+
@_value_cache = {}
|
15
16
|
end
|
16
17
|
|
17
18
|
def method_missing(method, *args, &block)
|
18
19
|
method = method.to_s
|
20
|
+
key = method[0..-2]
|
19
21
|
if method.end_with?("?")
|
20
|
-
key
|
21
|
-
|
22
|
+
!!_get_value(key)
|
23
|
+
elsif method.end_with? '='
|
24
|
+
_set_value(key, args.first)
|
22
25
|
else
|
23
26
|
_get_value(method)
|
24
27
|
end
|
@@ -28,21 +31,52 @@ module Dish
|
|
28
31
|
_check_for_presence(method.to_s) || super
|
29
32
|
end
|
30
33
|
|
31
|
-
def
|
34
|
+
def to_h
|
32
35
|
@_original_hash
|
33
36
|
end
|
34
37
|
|
38
|
+
def as_hash
|
39
|
+
# TODO: Add the version number where this was deprecated?
|
40
|
+
warn 'Dish::Plate#as_hash has been deprecated. Use Dish::Plate#to_h.'
|
41
|
+
to_h
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_json(*args)
|
45
|
+
# If we're using RubyMotion #to_json isn't available like with Ruby's JSON stdlib
|
46
|
+
if defined?(Motion::Project::Config)
|
47
|
+
# From BubbleWrap: https://github.com/rubymotion/BubbleWrap/blob/master/motion/core/json.rb#L30-L32
|
48
|
+
NSJSONSerialization.dataWithJSONObject(to_h, options: 0, error: nil).to_str
|
49
|
+
elsif defined?(JSON)
|
50
|
+
to_h.to_json(*args)
|
51
|
+
else
|
52
|
+
raise "#{self.class}#to_json depends on Hash#to_json. Try again after using `require 'json'`."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def methods(regular = true)
|
57
|
+
valid_keys = to_h.keys.map(&:to_sym)
|
58
|
+
valid_keys + super
|
59
|
+
end
|
60
|
+
|
35
61
|
private
|
36
62
|
|
37
63
|
attr_reader :_original_hash
|
38
64
|
|
39
65
|
def _get_value(key)
|
40
66
|
value = _original_hash[key]
|
41
|
-
_convert_value(value, self.class.coercions[key])
|
67
|
+
@_value_cache[_cache_key(value)] ||= _convert_value(value, self.class.coercions[key])
|
42
68
|
end
|
43
69
|
|
70
|
+
def _cache_key(value)
|
71
|
+
[value.object_id, @_original_hash.hash].join('')
|
72
|
+
end
|
73
|
+
|
74
|
+
def _set_value(key, value)
|
75
|
+
@_original_hash[key] = value
|
76
|
+
end
|
77
|
+
|
44
78
|
def _check_for_presence(key)
|
45
|
-
|
79
|
+
_original_hash.key?(key)
|
46
80
|
end
|
47
81
|
|
48
82
|
def _convert_value(value, coercion)
|
@@ -63,4 +97,4 @@ module Dish
|
|
63
97
|
end
|
64
98
|
end
|
65
99
|
end
|
66
|
-
end
|
100
|
+
end
|
data/lib/dish/version.rb
CHANGED
data/test/coercion_test.rb
CHANGED
@@ -32,6 +32,23 @@ class DishTest < Test::Unit::TestCase
|
|
32
32
|
assert products.map(&:authors).flatten.all? { |a| a.is_a?(Author) }
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_coercion_caching
|
36
|
+
products = api_response.to_dish(Product)
|
37
|
+
|
38
|
+
assert_equal products.first.authors.first.object_id, products.first.authors.first.object_id
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_coercion_cache_busting
|
42
|
+
products = api_response.to_dish(Product)
|
43
|
+
|
44
|
+
author = products.first.authors.first
|
45
|
+
assert_equal author.name, products.first.authors.first.name
|
46
|
+
|
47
|
+
products.first.to_h['authors'].first['name'] = 'Johnny Cache'
|
48
|
+
|
49
|
+
assert_not_equal author.name, products.first.authors.first.name
|
50
|
+
end
|
51
|
+
|
35
52
|
private
|
36
53
|
|
37
54
|
class Author < Dish::Plate; end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class DeprecatedTest < Test::Unit::TestCase
|
4
|
+
def test_deprecated_as_hash
|
5
|
+
p = Dish({ a: 1, b: 2 })
|
6
|
+
|
7
|
+
out, err = capture_io do
|
8
|
+
assert_equal({ "a" => 1, "b" => 2}, p.as_hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
assert_match /Dish::Plate#as_hash has been deprecated\./, err
|
12
|
+
end
|
13
|
+
end
|
data/test/dish_test.rb
CHANGED
@@ -24,7 +24,7 @@ class DishTest < Test::Unit::TestCase
|
|
24
24
|
assert_respond_to book, :authors
|
25
25
|
refute_respond_to book, :doesnotexist
|
26
26
|
assert_nothing_raised do
|
27
|
-
|
27
|
+
book.method(:title)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -73,7 +73,7 @@ class DishTest < Test::Unit::TestCase
|
|
73
73
|
assert_nil Dish(nil)
|
74
74
|
end
|
75
75
|
|
76
|
-
def
|
76
|
+
def test_to_h
|
77
77
|
hash = {
|
78
78
|
"a" => "a",
|
79
79
|
"b" => "b",
|
@@ -83,8 +83,8 @@ class DishTest < Test::Unit::TestCase
|
|
83
83
|
}
|
84
84
|
}
|
85
85
|
dish = Dish(hash)
|
86
|
-
c_hash = dish.c.
|
87
|
-
assert_equal "Hash", dish.c.
|
86
|
+
c_hash = dish.c.to_h
|
87
|
+
assert_equal "Hash", dish.c.to_h.class.to_s
|
88
88
|
assert_equal hash["c"]["1"], c_hash["1"]
|
89
89
|
assert_equal hash["c"]["2"], c_hash["2"]
|
90
90
|
end
|
@@ -107,4 +107,42 @@ class DishTest < Test::Unit::TestCase
|
|
107
107
|
assert_instance_of Dish::Plate, d
|
108
108
|
end
|
109
109
|
end
|
110
|
+
|
111
|
+
def test_respond_to
|
112
|
+
hash = { a: 1, b: true, c: false, d: nil }
|
113
|
+
dish = Dish(hash)
|
114
|
+
|
115
|
+
hash.each do |key, _|
|
116
|
+
assert_respond_to dish, key
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_set_value
|
121
|
+
hash = { a: 1, b: 2, c: false }
|
122
|
+
dish = Dish(hash)
|
123
|
+
|
124
|
+
dish.a = "other value"
|
125
|
+
assert_equal "other value", dish.a
|
126
|
+
|
127
|
+
dish.b = nil
|
128
|
+
assert_equal nil, dish.b
|
129
|
+
assert_equal false, dish.b?
|
130
|
+
|
131
|
+
dish.c = true
|
132
|
+
assert_equal true, dish.c
|
133
|
+
assert_equal true, dish.c?
|
134
|
+
|
135
|
+
dish.d = "new value"
|
136
|
+
assert_equal "new value", dish.d
|
137
|
+
|
138
|
+
assert_equal({ "a" => "other value", "b" => nil, "c" => true, "d" => "new value" },
|
139
|
+
dish.to_h)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_methods
|
143
|
+
hash = { a: 1, b: 2 }
|
144
|
+
dish = Dish(hash)
|
145
|
+
|
146
|
+
assert_equal [:a, :b], dish.methods[0..1]
|
147
|
+
end
|
110
148
|
end
|
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.5
|
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-
|
11
|
+
date: 2014-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- lib/dish/plate.rb
|
64
64
|
- lib/dish/version.rb
|
65
65
|
- test/coercion_test.rb
|
66
|
+
- test/deprecated_test.rb
|
66
67
|
- test/dish_test.rb
|
67
68
|
- test/test_helper.rb
|
68
69
|
homepage: https://github.com/lassebunk/dish
|
@@ -91,5 +92,6 @@ specification_version: 4
|
|
91
92
|
summary: Super simple conversion of hashes to plain Ruby objects
|
92
93
|
test_files:
|
93
94
|
- test/coercion_test.rb
|
95
|
+
- test/deprecated_test.rb
|
94
96
|
- test/dish_test.rb
|
95
97
|
- test/test_helper.rb
|