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.
@@ -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
- collection.links << opts.merge({rel: rel, href: href})
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: href}.tap do |item|
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: item_builder.data}) if item_builder.data.length > 0
28
- item.merge!({links: item_builder.links}) if item_builder.links.length > 0
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: href, rel: rel}.tap do |query|
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: prompt}) if prompt != ''
38
- query.merge!({data: query_builder.data}) if query_builder.data.length > 0
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 = Hash.new.tap do |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: template_builder.data}) if template_builder.data.length > 0
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: value}) if value != ''
62
- data.merge!({prompt: prompt}) if 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: href, rel: rel}.tap do |link|
69
- link.merge!({name: name}) if name != ''
70
- link.merge!({prompt: prompt}) if prompt != ''
71
- link.merge!({render: render}) if 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: name}.tap do |data|
85
- data.merge!({value: value}) if value != ''
86
- data.merge!({prompt: prompt}) if 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: name}.tap do |data|
100
- data.merge!({value: value}) if value != ''
101
- data.merge!({prompt: prompt}) if 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 :links, :items, :queries, :template, :version, :error
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
@@ -1,3 +1,3 @@
1
1
  module CollectionJSON
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  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[:data].length.should eq(2)
73
- response.items.first[:links].length.should eq(2)
74
- response.items.first[:href].class.should eq(String)
75
- response.template[:data].length.should eq(4)
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[:href].should eq("/friends/search")
78
- response.queries.first[:data].length.should eq(1)
79
- response.queries.first[:data].first[:name].should eq('search')
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['href'].should eq("http://www.example.org/m.rowe")
109
- @collection.items.first['data'].count.should eq(1)
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.2
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-16 00:00:00.000000000 Z
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: &70288977749200 !ruby/object:Gem::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: *70288977749200
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