roaster 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/lib/roaster/decorator.rb +13 -0
- data/lib/roaster/json_api.rb +32 -21
- data/lib/roaster/request.rb +2 -2
- data/lib/roaster/version.rb +1 -1
- data/roaster.gemspec +1 -0
- data/test/mappings/album.rb +2 -0
- data/test/mappings/track.rb +1 -1
- data/test/test_helper.rb +1 -0
- data/test/wut_test.rb +50 -4
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7edd1920bcea40877ce475c8342562ba9af1a184
|
4
|
+
data.tar.gz: ee99be23ae5e17e5f9f836ac3a4b71fb26347ccc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb3235f615b1d0efadcca5de7e1174e3196698f7b942d6ee80f751e1a5d2b4d42ff4ac20d5e36692545b6fbb2c5e266510e76c48c9db6c45e85426efbee39529
|
7
|
+
data.tar.gz: b803b241de1e0ace8de2aa1b1ff4ca55370e56f1099b036a9a569ad69a059ae558bc78ca84bb0d793a781cdf0669cb99925ef56d8f2478b5d273edf2c515945a
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
roaster (0.0.
|
4
|
+
roaster (0.0.5)
|
5
5
|
activerecord (~> 4.1)
|
6
6
|
activesupport (~> 4.1)
|
7
7
|
representable (~> 2.0.4)
|
@@ -36,6 +36,7 @@ GEM
|
|
36
36
|
activesupport (>= 3.0.0)
|
37
37
|
i18n (0.6.11)
|
38
38
|
json (1.8.1)
|
39
|
+
json_expressions (0.8.3)
|
39
40
|
mini_portile (0.6.0)
|
40
41
|
minitest (5.4.1)
|
41
42
|
multi_json (1.10.1)
|
@@ -61,6 +62,7 @@ DEPENDENCIES
|
|
61
62
|
byebug (~> 3.4)
|
62
63
|
database_cleaner (~> 1.3)
|
63
64
|
factory_girl (~> 4.4)
|
65
|
+
json_expressions
|
64
66
|
minitest (~> 5.1)
|
65
67
|
rake (~> 10.3)
|
66
68
|
roaster!
|
data/lib/roaster/decorator.rb
CHANGED
@@ -11,6 +11,19 @@ module Roaster
|
|
11
11
|
|
12
12
|
class << self
|
13
13
|
|
14
|
+
def has_one(name)
|
15
|
+
representable_attrs[:_has_one] ||= []
|
16
|
+
property name
|
17
|
+
representable_attrs[:_has_one].push({key: name.to_s + '_id', name: name.to_s})
|
18
|
+
end
|
19
|
+
|
20
|
+
#PING: Overriding build_definition is maybe required
|
21
|
+
def has_many(name)
|
22
|
+
representable_attrs[:_has_many] ||= []
|
23
|
+
collection name
|
24
|
+
representable_attrs[:_has_many].push({key: name.to_s.singularize + '_ids', name: name.to_s})
|
25
|
+
end
|
26
|
+
|
14
27
|
def can_filter_by(*attrs)
|
15
28
|
representable_attrs[:_filterable_attributes] ||= []
|
16
29
|
representable_attrs[:_filterable_attributes].push(*attrs.map(&:to_sym)).uniq!
|
data/lib/roaster/json_api.rb
CHANGED
@@ -6,30 +6,18 @@ require 'representable/bindings/hash_bindings'
|
|
6
6
|
module Roaster
|
7
7
|
module JsonApi
|
8
8
|
|
9
|
-
class
|
10
|
-
|
11
|
-
|
12
|
-
def serialize(value)
|
13
|
-
super
|
9
|
+
class CollectionBinding < Representable::Hash::PropertyBinding
|
10
|
+
def self.build_for(definition, *args)
|
11
|
+
self.new(definition, *args)
|
14
12
|
end
|
15
13
|
|
16
|
-
def
|
14
|
+
def serialize(value)
|
17
15
|
@mapping_class = @definition[:extend].instance_variable_get('@value')
|
18
16
|
collection = value.collect { |item|
|
19
|
-
|
17
|
+
super(item)
|
20
18
|
}
|
21
19
|
{ @mapping_class.get_resource_name => collection }
|
22
20
|
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class CollectionBinding < Binding
|
26
|
-
def self.build_for(definition, *args)
|
27
|
-
self.new(definition, *args)
|
28
|
-
end
|
29
|
-
|
30
|
-
def serialize(value)
|
31
|
-
serialize_collection(value)
|
32
|
-
end
|
33
21
|
|
34
22
|
# TODO
|
35
23
|
# def deserialize(fragment)
|
@@ -41,11 +29,34 @@ module Roaster
|
|
41
29
|
include Representable::JSON
|
42
30
|
|
43
31
|
def to_hash(option)
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
|
33
|
+
roaster_type = option[:roaster]
|
34
|
+
links = {}
|
35
|
+
|
36
|
+
representable_attrs[:_has_one].each do |link|
|
37
|
+
representable_attrs[:definitions].delete(link[:name].to_s)
|
38
|
+
links[link[:name]] = @represented[link[:key]].to_s
|
39
|
+
end unless representable_attrs[:_has_one].nil?
|
40
|
+
|
41
|
+
|
42
|
+
representable_attrs[:_has_many].each do |link|
|
43
|
+
representable_attrs[:definitions].delete(link[:name].to_s)
|
44
|
+
links[link[:name]] = @represented.send(link[:key]).map(&:to_s) || []
|
45
|
+
end unless representable_attrs[:_has_many].nil?
|
46
|
+
|
47
|
+
if roaster_type.nil?
|
48
|
+
resource_id.to_s
|
47
49
|
else
|
48
|
-
{
|
50
|
+
sup = {'id' => resource_id.to_s }
|
51
|
+
sup.merge!({'links' => links }) unless links.empty?
|
52
|
+
case roaster_type
|
53
|
+
when :resource
|
54
|
+
{
|
55
|
+
self.class.get_resource_name => sup.merge(super(option))
|
56
|
+
}
|
57
|
+
when :collection
|
58
|
+
sup.merge(super(option))
|
59
|
+
end
|
49
60
|
end
|
50
61
|
end
|
51
62
|
|
data/lib/roaster/request.rb
CHANGED
@@ -63,9 +63,9 @@ module Roaster
|
|
63
63
|
|
64
64
|
def represent(data)
|
65
65
|
if @query.target.resource_ids.size == 1
|
66
|
-
@mapping_class.prepare(data.first).to_hash({
|
66
|
+
@mapping_class.prepare(data.first).to_hash({roaster: :resource})
|
67
67
|
elsif data.respond_to?(:each)
|
68
|
-
@mapping_class.for_collection.prepare(data).to_hash({}, Roaster::JsonApi::CollectionBinding)
|
68
|
+
@mapping_class.for_collection.prepare(data).to_hash({roaster: :collection}, Roaster::JsonApi::CollectionBinding)
|
69
69
|
else
|
70
70
|
# TODO: HANDLE ERROR ?
|
71
71
|
byebug
|
data/lib/roaster/version.rb
CHANGED
data/roaster.gemspec
CHANGED
data/test/mappings/album.rb
CHANGED
data/test/mappings/track.rb
CHANGED
data/test/test_helper.rb
CHANGED
data/test/wut_test.rb
CHANGED
@@ -48,27 +48,36 @@ class PoniesTest < MiniTest::Test
|
|
48
48
|
target = build_target(:albums, 1)
|
49
49
|
rq = build_request(:read, target: target)
|
50
50
|
res = rq.execute
|
51
|
-
assert_equal({'albums'=>{'id'=>'1', 'title'=>'Animals'}}, res)
|
51
|
+
assert_equal({'albums'=>{'id'=>'1', 'links'=>{'tracks'=>[]}, 'title'=>'Animals'}}, res)
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_ponies
|
55
55
|
rq = build_request(:read)
|
56
56
|
res = rq.execute
|
57
|
-
assert_equal({'albums' => [
|
57
|
+
assert_equal({'albums' => [
|
58
|
+
{'id' => '1', 'links'=>{'tracks'=>[]}, 'title' => 'Animals'},
|
59
|
+
{'id' => '2', 'links'=>{'tracks'=>[]}, 'title' => 'The Wall'},
|
60
|
+
{'id' => '3', 'links'=>{'tracks'=>[]}, 'title' => 'Meddle'},
|
61
|
+
{'id' => '4', 'links'=>{'tracks'=>['1', '2', '3']}, 'title' => 'Wages of Sin'}]}, res)
|
58
62
|
end
|
59
63
|
|
60
64
|
def test_sorted_ponies
|
61
65
|
params = {sort: :title}
|
62
66
|
rq = build_request(:read, params: params)
|
63
67
|
res = rq.execute
|
64
|
-
assert_equal({'albums' => [
|
68
|
+
assert_equal({'albums' => [
|
69
|
+
{'id' => '1', 'links'=>{'tracks'=>[]}, 'title' => 'Animals'},
|
70
|
+
{'id' => '3', 'links'=>{'tracks'=>[]}, 'title' => 'Meddle'},
|
71
|
+
{'id' => '2', 'links'=>{'tracks'=>[]}, 'title' => 'The Wall'},
|
72
|
+
{'id' => '4', 'links'=>{'tracks'=>['1', '2', '3']}, 'title' => 'Wages of Sin'}]},
|
73
|
+
res)
|
65
74
|
end
|
66
75
|
|
67
76
|
def test_simple_filtered_ponies
|
68
77
|
params = {title: 'Animals'}
|
69
78
|
rq = build_request(:read, params: params)
|
70
79
|
res = rq.execute
|
71
|
-
assert_equal({'albums' => [{'id' => '1', 'title' => 'Animals'}]}, res)
|
80
|
+
assert_equal({'albums' => [{'id' => '1', 'links'=>{'tracks'=>[]}, 'title' => 'Animals'}]}, res)
|
72
81
|
end
|
73
82
|
|
74
83
|
#TODO: Make this one pass !
|
@@ -178,6 +187,43 @@ class PoniesTest < MiniTest::Test
|
|
178
187
|
assert_equal 'Megadeth', album.band.name
|
179
188
|
end
|
180
189
|
|
190
|
+
def test_read_has_one_links
|
191
|
+
album = FactoryGirl.create :album, title: 'Ride the Lightning'
|
192
|
+
track = FactoryGirl.create :track, title: 'Fight Fire With Fire', album: album
|
193
|
+
target = build_target(:track, track)
|
194
|
+
rq = build_request(:read, target: target)
|
195
|
+
res = rq.execute
|
196
|
+
assert_json_match({
|
197
|
+
tracks: {
|
198
|
+
id: '4',
|
199
|
+
links: {
|
200
|
+
album: '5'
|
201
|
+
},
|
202
|
+
title: 'Fight Fire With Fire',
|
203
|
+
}}, res)
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_read_has_many_links
|
207
|
+
track_1 = FactoryGirl.create :track, title: 'Fight Fire With Fire'
|
208
|
+
# Track 2 omitted because it has the same title as the album
|
209
|
+
track_3 = FactoryGirl.create :track, title: 'For Whom The Bell Tolls'
|
210
|
+
track_4 = FactoryGirl.create :track, title: 'Fade to Black'
|
211
|
+
album = FactoryGirl.create :album, title: 'Ride the Lightning', tracks: [track_1, track_3, track_4]
|
212
|
+
# byebug
|
213
|
+
target = build_target(:album, album)
|
214
|
+
rq = build_request(:read, target: target)
|
215
|
+
res = rq.execute
|
216
|
+
assert_json_match({
|
217
|
+
albums: {
|
218
|
+
id: '5',
|
219
|
+
links: {
|
220
|
+
tracks: [track_1.id.to_s, track_3.id.to_s, track_4.id.to_s]
|
221
|
+
},
|
222
|
+
title: 'Ride the Lightning',
|
223
|
+
}}, res)
|
224
|
+
end
|
225
|
+
|
226
|
+
|
181
227
|
def test_update_to_many_relationship
|
182
228
|
track_1 = FactoryGirl.create :track, title: 'Fight Fire With Fire'
|
183
229
|
# Track 2 omitted because it has the same title as the album
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Albeza
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-09-
|
12
|
+
date: 2014-09-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: representable
|
@@ -137,6 +137,20 @@ dependencies:
|
|
137
137
|
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '3.4'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: json_expressions
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
140
154
|
description: Model/JSONAPI mapping
|
141
155
|
email:
|
142
156
|
- n.albeza@gmail.com
|