collection-json 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.
- data/lib/collection-json.rb +2 -0
- data/lib/collection-json/attributes/data.rb +16 -0
- data/lib/collection-json/attributes/error.rb +16 -0
- data/lib/collection-json/attributes/item.rb +29 -0
- data/lib/collection-json/attributes/link.rb +22 -0
- data/lib/collection-json/attributes/query.rb +48 -0
- data/lib/collection-json/attributes/template.rb +30 -0
- data/lib/collection-json/builder.rb +24 -21
- data/lib/collection-json/collection.rb +27 -1
- data/lib/collection-json/version.rb +1 -1
- data/spec/collection-json/attributes/template_spec.rb +32 -0
- data/spec/collection-json_spec.rb +17 -9
- metadata +12 -4
data/lib/collection-json.rb
CHANGED
@@ -6,6 +6,8 @@ require "collection-json/builder"
|
|
6
6
|
COLLECTION_JSON_VERSION = "1.0"
|
7
7
|
ROOT_NODE = 'collection'
|
8
8
|
|
9
|
+
VALID_LINK_ATTRIBUTES = %w{href rel name render prompt}.map(&:to_sym)
|
10
|
+
|
9
11
|
module CollectionJSON
|
10
12
|
def self.generate_for(href, &block)
|
11
13
|
response = Collection.new(href)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CollectionJSON
|
2
|
+
class Data < Hash
|
3
|
+
def self.from_hash(hash)
|
4
|
+
self.new.merge! hash
|
5
|
+
end
|
6
|
+
|
7
|
+
def name; self['name']; end
|
8
|
+
def name=(value); self['name'] = value; end
|
9
|
+
|
10
|
+
def value; self['value']; end
|
11
|
+
def value=(value); self['value'] = value; end
|
12
|
+
|
13
|
+
def prompt; self['prompt']; end
|
14
|
+
def prompt=(value); self['prompt'] = value; end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CollectionJSON
|
2
|
+
class Error < Hash
|
3
|
+
def self.from_hash(hash)
|
4
|
+
self.new.merge! hash
|
5
|
+
end
|
6
|
+
|
7
|
+
def title; self['title']; end
|
8
|
+
def title=(value); self['title'] = value; end
|
9
|
+
|
10
|
+
def code; self['code']; end
|
11
|
+
def code=(value); self['code'] = value; end
|
12
|
+
|
13
|
+
def message; self['message']; end
|
14
|
+
def message=(value); self['message'] = value; end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'link'
|
2
|
+
require_relative 'data'
|
3
|
+
|
4
|
+
module CollectionJSON
|
5
|
+
class Item < Hash
|
6
|
+
def self.from_hash(hash)
|
7
|
+
self.new.merge! hash
|
8
|
+
end
|
9
|
+
|
10
|
+
def href; self['href']; end
|
11
|
+
def href=(value); self['href'] = value; end
|
12
|
+
|
13
|
+
def links
|
14
|
+
self['links'].map {|link| Link.from_hash(link)}
|
15
|
+
end
|
16
|
+
|
17
|
+
def links=(array)
|
18
|
+
self['links'] = array
|
19
|
+
end
|
20
|
+
|
21
|
+
def data
|
22
|
+
self['data'].map {|data| Data.from_hash(data)}
|
23
|
+
end
|
24
|
+
|
25
|
+
def data=(array)
|
26
|
+
self['data'] = array
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CollectionJSON
|
2
|
+
class Link < Hash
|
3
|
+
def self.from_hash(hash)
|
4
|
+
self.new.merge! hash
|
5
|
+
end
|
6
|
+
|
7
|
+
def href; self['href']; end
|
8
|
+
def href=(value); self['href'] = value; end
|
9
|
+
|
10
|
+
def rel; self['rel']; end
|
11
|
+
def rel=(value); self['rel'] = value; end
|
12
|
+
|
13
|
+
def name; self['name']; end
|
14
|
+
def name=(value); self['name'] = value; end
|
15
|
+
|
16
|
+
def render; self['render']; end
|
17
|
+
def render=(value); self['render'] = value; end
|
18
|
+
|
19
|
+
def prompt; self['prompt']; end
|
20
|
+
def prompt=(value); self['prompt'] = value; end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative 'data'
|
2
|
+
|
3
|
+
module CollectionJSON
|
4
|
+
class Query < Hash
|
5
|
+
def self.from_hash(hash)
|
6
|
+
self.new.merge! hash
|
7
|
+
end
|
8
|
+
|
9
|
+
def href; self['href']; end
|
10
|
+
def href=(value); self['href'] = value; end
|
11
|
+
|
12
|
+
def rel; self['rel']; end
|
13
|
+
def rel=(value); self['rel'] = value; end
|
14
|
+
|
15
|
+
def name; self['name']; end
|
16
|
+
def name=(value); self['name'] = value; end
|
17
|
+
|
18
|
+
def prompt; self['prompt']; end
|
19
|
+
def prompt=(value); self['prompt'] = value; end
|
20
|
+
|
21
|
+
def data
|
22
|
+
self['data'].map {|data| Data.from_hash(data)}
|
23
|
+
end
|
24
|
+
|
25
|
+
def data=(array)
|
26
|
+
self['data'] = array
|
27
|
+
end
|
28
|
+
|
29
|
+
def build(params = {})
|
30
|
+
URI(href).tap do |uri|
|
31
|
+
uri.query = add_query_params(uri.query || '', params)
|
32
|
+
end.to_s.gsub(/\?$/, '')
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def add_query_params(query, params)
|
37
|
+
query << params.keys.inject('') do |query, key|
|
38
|
+
query.tap do |query_string|
|
39
|
+
unless data.map(&name).include?(key)
|
40
|
+
query << '&' unless key == params.keys.first
|
41
|
+
query << CGI.escape(key.to_s)
|
42
|
+
query << "=#{CGI.escape(params[key].to_s)}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'data'
|
2
|
+
|
3
|
+
module CollectionJSON
|
4
|
+
class Template < Hash
|
5
|
+
def self.from_hash(hash)
|
6
|
+
self.new.merge! hash
|
7
|
+
end
|
8
|
+
|
9
|
+
def data
|
10
|
+
self['data'].map {|data| Data.from_hash(data)}
|
11
|
+
end
|
12
|
+
|
13
|
+
def data=(array)
|
14
|
+
self['data'] = array
|
15
|
+
end
|
16
|
+
|
17
|
+
def build(params = {})
|
18
|
+
self.dup.tap do |result|
|
19
|
+
result.data.each do |data|
|
20
|
+
data.select! {|k,v| %w{name value}.include?(k)}
|
21
|
+
data.value = params[data.name] if params[data.name]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_json(*args)
|
27
|
+
{template: Hash.new.merge!(self)}.to_json(args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -16,34 +16,37 @@ module CollectionJSON
|
|
16
16
|
|
17
17
|
def add_link(href, rel, opts = {})
|
18
18
|
href = CollectionJSON.add_host(href)
|
19
|
-
|
19
|
+
|
20
|
+
opts.select! {|k,v| VALID_LINK_ATTRIBUTES.include? k}
|
21
|
+
opts.merge!({'rel' => rel, 'href' => href})
|
22
|
+
collection.links << Link.from_hash(opts)
|
20
23
|
end
|
21
24
|
|
22
25
|
def add_item(href, data = [], links = [], &block)
|
23
26
|
href = CollectionJSON.add_host(href)
|
24
|
-
collection.items << {href
|
27
|
+
collection.items << Item.from_hash({'href' => href}).tap do |item|
|
25
28
|
item_builder = ItemBuilder.new(data, links)
|
26
29
|
yield(item_builder) if block_given?
|
27
|
-
item.merge!({data
|
28
|
-
item.merge!({links
|
30
|
+
item.merge!({'data' => item_builder.data}) if item_builder.data.length > 0
|
31
|
+
item.merge!({'links' => item_builder.links}) if item_builder.links.length > 0
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
32
35
|
def add_query(href, rel, prompt = '', data = [], &block)
|
33
36
|
href = CollectionJSON.add_host(href)
|
34
|
-
collection.queries << {href
|
37
|
+
collection.queries << Query.from_hash({'href' => href, 'rel' => rel}).tap do |query|
|
35
38
|
query_builder = QueryBuilder.new(data)
|
36
39
|
yield(query_builder) if block_given?
|
37
|
-
query.merge!({prompt
|
38
|
-
query.merge!({data
|
40
|
+
query.merge!({'prompt' => prompt}) if prompt != ''
|
41
|
+
query.merge!({'data' => query_builder.data}) if query_builder.data.length > 0
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
42
45
|
def set_template(data = [], &block)
|
43
|
-
collection.template =
|
46
|
+
collection.template = Template.new.tap do |template|
|
44
47
|
template_builder = TemplateBuilder.new(data)
|
45
48
|
yield(template_builder) if block_given?
|
46
|
-
template.merge!({data
|
49
|
+
template.merge!({'data' => template_builder.data}) if template_builder.data.length > 0
|
47
50
|
end
|
48
51
|
end
|
49
52
|
end
|
@@ -58,17 +61,17 @@ module CollectionJSON
|
|
58
61
|
|
59
62
|
def add_data(name, value = '', prompt = '')
|
60
63
|
data << {name: name}.tap do |data|
|
61
|
-
data.merge!({value
|
62
|
-
data.merge!({prompt
|
64
|
+
data.merge!({'value' => value}) if value != ''
|
65
|
+
data.merge!({'prompt' => prompt}) if prompt != ''
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
66
69
|
def add_link(href, rel, name = '', prompt = '', render = '')
|
67
70
|
href = CollectionJSON.add_host(href)
|
68
|
-
links << {href
|
69
|
-
link.merge!({name
|
70
|
-
link.merge!({prompt
|
71
|
-
link.merge!({render
|
71
|
+
links << Link.from_hash({'href' => href, 'rel' => rel}).tap do |link|
|
72
|
+
link.merge!({'name' => name}) if name != ''
|
73
|
+
link.merge!({'prompt' => prompt}) if prompt != ''
|
74
|
+
link.merge!({'render' => render}) if render != ''
|
72
75
|
end
|
73
76
|
end
|
74
77
|
end
|
@@ -81,9 +84,9 @@ module CollectionJSON
|
|
81
84
|
end
|
82
85
|
|
83
86
|
def add_data(name, value = '', prompt = '')
|
84
|
-
data << {name
|
85
|
-
data.merge!({value
|
86
|
-
data.merge!({prompt
|
87
|
+
data << Data.from_hash({'name' => name}).tap do |data|
|
88
|
+
data.merge!({'value' => value}) if value != ''
|
89
|
+
data.merge!({'prompt' => prompt}) if prompt != ''
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
@@ -96,9 +99,9 @@ module CollectionJSON
|
|
96
99
|
end
|
97
100
|
|
98
101
|
def add_data(name, value = '', prompt = '')
|
99
|
-
data << {name
|
100
|
-
data.merge!({value
|
101
|
-
data.merge!({prompt
|
102
|
+
data << Data.from_hash({'name' => name}).tap do |data|
|
103
|
+
data.merge!({'value' => value}) if value != ''
|
104
|
+
data.merge!({'prompt' => prompt}) if prompt != ''
|
102
105
|
end
|
103
106
|
end
|
104
107
|
end
|
@@ -1,7 +1,13 @@
|
|
1
|
+
require_relative 'attributes/link'
|
2
|
+
require_relative 'attributes/item'
|
3
|
+
require_relative 'attributes/query'
|
4
|
+
require_relative 'attributes/error'
|
5
|
+
require_relative 'attributes/template'
|
6
|
+
|
1
7
|
module CollectionJSON
|
2
8
|
class Collection
|
3
9
|
attr_reader :href, :links, :items, :queries, :template, :version, :error
|
4
|
-
attr_writer :
|
10
|
+
attr_writer :version
|
5
11
|
|
6
12
|
def self.from_hash(hash)
|
7
13
|
self.new(hash[ROOT_NODE]['href']).tap do |collection|
|
@@ -23,6 +29,26 @@ module CollectionJSON
|
|
23
29
|
@template = nil
|
24
30
|
end
|
25
31
|
|
32
|
+
def items=(array)
|
33
|
+
@items = array.map {|item| Item.from_hash(item)}
|
34
|
+
end
|
35
|
+
|
36
|
+
def links=(array)
|
37
|
+
@links = array.map {|link| Link.from_hash(link)}
|
38
|
+
end
|
39
|
+
|
40
|
+
def queries=(array)
|
41
|
+
@queries = array.map {|query| Query.from_hash(query)}
|
42
|
+
end
|
43
|
+
|
44
|
+
def template=(template)
|
45
|
+
@template = Template.from_hash(template)
|
46
|
+
end
|
47
|
+
|
48
|
+
def error=(error)
|
49
|
+
@error = Error.from_hash(error)
|
50
|
+
end
|
51
|
+
|
26
52
|
def collection
|
27
53
|
{ROOT_NODE => body}
|
28
54
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'collection-json/attributes/template'
|
3
|
+
|
4
|
+
describe CollectionJSON::Template do
|
5
|
+
before(:all) do
|
6
|
+
@hash = {
|
7
|
+
'data' => [
|
8
|
+
{
|
9
|
+
'name' => 'full-name',
|
10
|
+
'prompt' => 'Full name'
|
11
|
+
},
|
12
|
+
{
|
13
|
+
'name' => 'email',
|
14
|
+
'prompt' => 'Email'
|
15
|
+
}
|
16
|
+
]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
describe :build do
|
21
|
+
it 'should build correctly' do
|
22
|
+
template = CollectionJSON::Template.from_hash(@hash)
|
23
|
+
result = template.build({
|
24
|
+
'email' => 'test@example.com',
|
25
|
+
'full-name' => 'Test Example'
|
26
|
+
})
|
27
|
+
json = result.to_json
|
28
|
+
hash = JSON.parse(json)
|
29
|
+
hash['template']['data'].length.should eq(2)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -68,15 +68,16 @@ describe CollectionJSON do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
response.href.should eq('/friends/')
|
71
|
+
response.links.first.href.should eq("/friends/rss")
|
71
72
|
response.items.length.should eq(3)
|
72
|
-
response.items.first
|
73
|
-
response.items.first
|
74
|
-
response.items.first
|
75
|
-
response.template
|
73
|
+
response.items.first.data.length.should eq(2)
|
74
|
+
response.items.first.links.length.should eq(2)
|
75
|
+
response.items.first.href.class.should eq(String)
|
76
|
+
response.template.data.length.should eq(4)
|
76
77
|
response.queries.length.should eq(1)
|
77
|
-
response.queries.first
|
78
|
-
response.queries.first
|
79
|
-
response.queries.first
|
78
|
+
response.queries.first.href.should eq("/friends/search")
|
79
|
+
response.queries.first.data.length.should eq(1)
|
80
|
+
response.queries.first.data.first.name.should eq('search')
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
@@ -84,6 +85,9 @@ describe CollectionJSON do
|
|
84
85
|
before(:all) do
|
85
86
|
json = '{"collection": {
|
86
87
|
"href": "http://www.example.org/friends",
|
88
|
+
"links": [
|
89
|
+
{"rel": "feed", "href": "http://www.example.org/friends.rss"}
|
90
|
+
],
|
87
91
|
"items": [
|
88
92
|
{
|
89
93
|
"href": "http://www.example.org/m.rowe",
|
@@ -105,12 +109,16 @@ describe CollectionJSON do
|
|
105
109
|
end
|
106
110
|
|
107
111
|
it 'should handle the nested attributes' do
|
108
|
-
@collection.items.first
|
109
|
-
@collection.items.first
|
112
|
+
@collection.items.first.href.should eq("http://www.example.org/m.rowe")
|
113
|
+
@collection.items.first.data.count.should eq(1)
|
110
114
|
end
|
111
115
|
|
112
116
|
it 'should be able to be reserialized' do
|
113
117
|
@collection.to_json.class.should eq(String)
|
114
118
|
end
|
119
|
+
|
120
|
+
it 'should have the correct link' do
|
121
|
+
@collection.links.first.href.should eq("http://www.example.org/friends.rss")
|
122
|
+
end
|
115
123
|
end
|
116
124
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collection-json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70212414111720 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70212414111720
|
25
25
|
description: Lightweight gem for building Collection+JSON responses.
|
26
26
|
email:
|
27
27
|
- sebastian@uprise.co.nz
|
@@ -35,9 +35,16 @@ files:
|
|
35
35
|
- Rakefile
|
36
36
|
- collection-json.gemspec
|
37
37
|
- lib/collection-json.rb
|
38
|
+
- lib/collection-json/attributes/data.rb
|
39
|
+
- lib/collection-json/attributes/error.rb
|
40
|
+
- lib/collection-json/attributes/item.rb
|
41
|
+
- lib/collection-json/attributes/link.rb
|
42
|
+
- lib/collection-json/attributes/query.rb
|
43
|
+
- lib/collection-json/attributes/template.rb
|
38
44
|
- lib/collection-json/builder.rb
|
39
45
|
- lib/collection-json/collection.rb
|
40
46
|
- lib/collection-json/version.rb
|
47
|
+
- spec/collection-json/attributes/template_spec.rb
|
41
48
|
- spec/collection-json_spec.rb
|
42
49
|
- spec/spec_helper.rb
|
43
50
|
homepage: https://github.com/sebastianedwards/collection-json
|
@@ -65,5 +72,6 @@ signing_key:
|
|
65
72
|
specification_version: 3
|
66
73
|
summary: Builds Collection+JSON responses.
|
67
74
|
test_files:
|
75
|
+
- spec/collection-json/attributes/template_spec.rb
|
68
76
|
- spec/collection-json_spec.rb
|
69
77
|
- spec/spec_helper.rb
|