halibut 0.2.0 → 0.3.0
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/Guardfile +5 -5
- data/README.md +5 -1
- data/halibut.gemspec +0 -1
- data/lib/halibut.rb +2 -3
- data/lib/halibut/adapter/json.rb +5 -5
- data/lib/halibut/adapter/xml.rb +19 -21
- data/lib/halibut/builder.rb +45 -4
- data/lib/halibut/hal/link.rb +62 -13
- data/lib/halibut/hal/resource.rb +77 -9
- data/lib/halibut/relation_map.rb +9 -1
- data/lib/halibut/version.rb +2 -1
- data/spec/adapter/xml_spec.rb +0 -1
- data/spec/resource_spec.rb +42 -5
- metadata +2 -2
data/Guardfile
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
4
|
guard 'bundler' do
|
5
|
-
watch('Gemfile')
|
5
|
+
# watch('Gemfile')
|
6
6
|
# Uncomment next line if Gemfile contain `gemspec' command
|
7
|
-
watch(/^.+\.gemspec/)
|
7
|
+
# watch(/^.+\.gemspec/)
|
8
8
|
end
|
9
9
|
|
10
10
|
guard 'minitest' do
|
@@ -21,10 +21,10 @@ guard 'minitest' do
|
|
21
21
|
# Rails 3.2
|
22
22
|
# watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/controllers/#{m[1]}_test.rb" }
|
23
23
|
# watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
|
24
|
-
# watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
|
25
|
-
|
24
|
+
# watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
|
25
|
+
|
26
26
|
# Rails
|
27
27
|
# watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/functional/#{m[1]}_test.rb" }
|
28
28
|
# watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
|
29
|
-
# watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
|
29
|
+
# watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
|
30
30
|
end
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
# Halibut
|
1
|
+
# Halibut [](http://coderwall.com/locks)
|
2
|
+
|
3
|
+
[](https://codeclimate.com/github/locks/halibut)
|
4
|
+
[](https://travis-ci.org/locks/halibut)
|
5
|
+
[](https://gemnasium.com/locks/halibut)
|
2
6
|
|
3
7
|
Halibut is a tiny gem that makes it easier to deal with the [HAL](http://stateless.co/hal_specification.html) format.
|
4
8
|
|
data/halibut.gemspec
CHANGED
data/lib/halibut.rb
CHANGED
@@ -2,8 +2,7 @@ require "halibut/version"
|
|
2
2
|
|
3
3
|
# Halibut is the main namespace
|
4
4
|
module Halibut
|
5
|
-
autoload :Builder,
|
6
|
-
|
5
|
+
autoload :Builder, 'halibut/builder'
|
7
6
|
autoload :RelationMap, 'halibut/relation_map'
|
8
7
|
end
|
9
8
|
|
@@ -16,6 +15,6 @@ end
|
|
16
15
|
|
17
16
|
# Halibut::HAL contains the domain objects that reflect the HAL specs.
|
18
17
|
module Halibut::HAL
|
19
|
-
autoload :Link,
|
18
|
+
autoload :Link, 'halibut/hal/link'
|
20
19
|
autoload :Resource, 'halibut/hal/resource'
|
21
20
|
end
|
data/lib/halibut/adapter/json.rb
CHANGED
@@ -3,10 +3,6 @@ require 'multi_json'
|
|
3
3
|
module Halibut::Adapter
|
4
4
|
|
5
5
|
module JSON
|
6
|
-
def self.extended(base)
|
7
|
-
base.extend InstanceMethods
|
8
|
-
end
|
9
|
-
|
10
6
|
def self.load(json)
|
11
7
|
ResourceExtractor.new(json).resource
|
12
8
|
end
|
@@ -16,6 +12,10 @@ module Halibut::Adapter
|
|
16
12
|
end
|
17
13
|
|
18
14
|
private
|
15
|
+
def self.extended(base)
|
16
|
+
base.extend InstanceMethods
|
17
|
+
end
|
18
|
+
|
19
19
|
module InstanceMethods
|
20
20
|
def to_json
|
21
21
|
MultiJson.dump self.to_hash
|
@@ -61,7 +61,7 @@ module Halibut::Adapter
|
|
61
61
|
def extract_resources(resources)
|
62
62
|
resources.each do |relation,values|
|
63
63
|
embeds = ([] << values).flatten
|
64
|
-
|
64
|
+
|
65
65
|
embeds.map {|embed| MultiJson.dump embed }
|
66
66
|
.map {|embed| Halibut::Adapter::JSON.load embed }
|
67
67
|
.each {|embed| @halibut.embed_resource(relation, embed) }
|
data/lib/halibut/adapter/xml.rb
CHANGED
@@ -3,31 +3,34 @@ require 'nokogiri'
|
|
3
3
|
module Halibut::Adapter
|
4
4
|
|
5
5
|
module XML
|
6
|
-
def self.extended(base)
|
7
|
-
base.extend InstanceMethods
|
8
|
-
end
|
9
|
-
|
10
6
|
def self.load(xml)
|
11
7
|
ResourceExtractor.new(xml).resource
|
12
8
|
end
|
13
9
|
|
14
10
|
def self.dump(resource)
|
11
|
+
raise NotImplementedError
|
15
12
|
end
|
16
13
|
|
17
14
|
private
|
15
|
+
def self.extended(base)
|
16
|
+
base.extend InstanceMethods
|
17
|
+
end
|
18
|
+
|
18
19
|
module InstanceMethods
|
19
20
|
def to_xml
|
21
|
+
raise NotImplementedError
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
class ResourceExtractor
|
26
|
+
|
27
|
+
attr_reader :resource
|
28
|
+
|
24
29
|
def initialize(xml)
|
25
30
|
xml = Nokogiri::XML(xml)
|
26
31
|
|
27
32
|
@document = xml.root
|
28
|
-
@
|
29
|
-
|
30
|
-
# binding.pry
|
33
|
+
@resource = Halibut::HAL::Resource.new extract_self_link
|
31
34
|
|
32
35
|
extract_curie
|
33
36
|
extract_properties
|
@@ -35,10 +38,6 @@ module Halibut::Adapter
|
|
35
38
|
extract_resources
|
36
39
|
end
|
37
40
|
|
38
|
-
def resource
|
39
|
-
@halibut
|
40
|
-
end
|
41
|
-
|
42
41
|
private
|
43
42
|
def extract_self_link
|
44
43
|
@document.attr 'href'
|
@@ -48,7 +47,7 @@ module Halibut::Adapter
|
|
48
47
|
@document.namespace_scopes
|
49
48
|
.reject {|ns| ns.prefix.eql? 'xsi' }
|
50
49
|
.each do |ns|
|
51
|
-
@
|
50
|
+
@resource.add_link 'curie', ns.href, name: ns.prefix
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
@@ -56,7 +55,7 @@ module Halibut::Adapter
|
|
56
55
|
properties = @document.xpath '/resource/*[not(self::link) and not(self::resource)]'
|
57
56
|
|
58
57
|
properties.each do |property|
|
59
|
-
@
|
58
|
+
@resource.set_property property.name, property.content
|
60
59
|
end
|
61
60
|
end
|
62
61
|
|
@@ -64,25 +63,24 @@ module Halibut::Adapter
|
|
64
63
|
links = @document.xpath('/resource/link')
|
65
64
|
|
66
65
|
links.each do |link|
|
67
|
-
@
|
68
|
-
|
69
|
-
|
66
|
+
@resource.add_link link['rel'],
|
67
|
+
link['href'],
|
68
|
+
extract_link_options(link)
|
70
69
|
end
|
71
70
|
end
|
72
71
|
|
73
72
|
# In case there are no options on the link, it returns an empty hash
|
74
73
|
def extract_link_options(link)
|
75
|
-
link.
|
76
|
-
|
77
|
-
.reduce(:merge) || {}
|
74
|
+
Hash[link.reject {|(key)| key.eql? 'rel' }
|
75
|
+
.reject {|(key)| key.eql? 'href' }]
|
78
76
|
end
|
79
77
|
|
80
78
|
def extract_resources
|
81
79
|
@document.xpath('/resource/resource')
|
82
80
|
.map {|r| [] << r['rel'] << ResourceExtractor.new(r.to_xml).resource }
|
83
|
-
.each {|rel,res| @
|
81
|
+
.each {|rel,res| @resource.embed_resource rel, res }
|
84
82
|
end
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
88
|
-
end
|
86
|
+
end
|
data/lib/halibut/builder.rb
CHANGED
@@ -4,8 +4,14 @@ module Halibut
|
|
4
4
|
|
5
5
|
# Builder provides a very thin wrapper around creating a HAL resource.
|
6
6
|
class Builder
|
7
|
-
attr_accessor :resource
|
8
7
|
|
8
|
+
# The HAL resource built
|
9
|
+
attr_reader :resource
|
10
|
+
|
11
|
+
#
|
12
|
+
#
|
13
|
+
# @param [String] href
|
14
|
+
# @param [Proc] blk
|
9
15
|
def initialize(href=nil, &blk)
|
10
16
|
@resource = Halibut::HAL::Resource.new href
|
11
17
|
|
@@ -21,6 +27,10 @@ module Halibut
|
|
21
27
|
end
|
22
28
|
|
23
29
|
private
|
30
|
+
|
31
|
+
# This is the root context of Halibut::Builder.
|
32
|
+
#
|
33
|
+
#
|
24
34
|
class RootContext
|
25
35
|
extend Forwardable
|
26
36
|
|
@@ -33,8 +43,23 @@ module Halibut
|
|
33
43
|
instance_eval(&blk) if block_given?
|
34
44
|
end
|
35
45
|
|
46
|
+
# Adds a namespace to the resource.
|
47
|
+
#
|
48
|
+
# A namespace is a conceptual abstraction of CURIE links.
|
49
|
+
# Since the client of the library doesn't need to handle CURIE links
|
50
|
+
# directly because they're just for dereferencing link relations, no
|
51
|
+
# CURIE links are presented.
|
52
|
+
#
|
53
|
+
# resource = Halibut::Builder.new do
|
54
|
+
# namespace :john, 'http://appleseed.com'
|
55
|
+
# end.resource
|
56
|
+
# resource.namespace(:john).href
|
57
|
+
# # => "http://appleseed.com"
|
58
|
+
#
|
59
|
+
# @param [String,Symbol] name name of the namespace
|
60
|
+
# @param [String] href URI of the namespace
|
36
61
|
def namespace(name, href)
|
37
|
-
@resource.
|
62
|
+
@resource.add_namespace(name, href)
|
38
63
|
end
|
39
64
|
|
40
65
|
def resource(rel, href=nil, &blk)
|
@@ -43,6 +68,23 @@ module Halibut
|
|
43
68
|
@resource.embed_resource(rel, embedded.resource)
|
44
69
|
end
|
45
70
|
|
71
|
+
# Adds links or resources to a relation.
|
72
|
+
#
|
73
|
+
# Relation allows the user to specify links, or resources, per relation,
|
74
|
+
# instead of individually.
|
75
|
+
# This feature was introduced as an attempt to reduce repeating the
|
76
|
+
# relation per link/resource, and thus reducing typos.
|
77
|
+
#
|
78
|
+
# resource = Halibut::Builder.new do
|
79
|
+
# relation :john do
|
80
|
+
# link 'http://appleseed.com/john'
|
81
|
+
# end
|
82
|
+
# end.resource
|
83
|
+
# resource.links[:john].first.href
|
84
|
+
#
|
85
|
+
# @param [String,Symbol] rel
|
86
|
+
# @param [Proc] blk Instructions to be executed in the relation
|
87
|
+
# context
|
46
88
|
def relation(rel, &blk)
|
47
89
|
RelationContext.new(@resource, rel, &blk)
|
48
90
|
end
|
@@ -58,7 +100,6 @@ module Halibut
|
|
58
100
|
instance_eval(&blk) if block_given?
|
59
101
|
end
|
60
102
|
|
61
|
-
private
|
62
103
|
def link(href, opts={})
|
63
104
|
@resource.add_link(@rel, href, opts)
|
64
105
|
end
|
@@ -72,4 +113,4 @@ module Halibut
|
|
72
113
|
|
73
114
|
end
|
74
115
|
|
75
|
-
end
|
116
|
+
end
|
data/lib/halibut/hal/link.rb
CHANGED
@@ -5,29 +5,56 @@ module Halibut::HAL
|
|
5
5
|
class Link
|
6
6
|
extend Forwardable
|
7
7
|
|
8
|
+
# The URI associated with this link.
|
8
9
|
attr_reader :href
|
9
10
|
|
10
11
|
def_delegators :@options, :templated, :templated?, :type,
|
11
12
|
:name, :profile, :title, :hreflang
|
13
|
+
|
12
14
|
# Returns an instance of a HAL Link object
|
13
15
|
#
|
16
|
+
# # link with no options
|
17
|
+
# link = Link.new('http://homeopathy.org')
|
18
|
+
#
|
19
|
+
# # link with name and type options
|
20
|
+
# link = Link.new('http://homeopathy.org', name: 'Homeopath'
|
21
|
+
# , type: 'text/html')
|
22
|
+
#
|
23
|
+
# If you pass an options that is not one of the reserved link properties
|
24
|
+
# as defined by the spec, they are dropped.
|
25
|
+
# It should possibly raise an error, hafta think about it.
|
26
|
+
#
|
14
27
|
# @param [String] href URI or URI Template
|
15
|
-
# @param [Boolean] templated true if URI Template or false otherwise
|
16
28
|
# @param [Hash] opts Options: type, name, profile, title, hreflang
|
17
29
|
#
|
18
30
|
# @return [Halibut::HAL::Link] HAL Link object
|
19
31
|
def initialize(href, opts={})
|
20
|
-
@href
|
32
|
+
@href = href
|
21
33
|
@options = Options.new opts
|
22
34
|
end
|
23
35
|
|
24
|
-
#
|
36
|
+
# Simply returns a hash of the href and the options that are not empty.
|
37
|
+
#
|
38
|
+
# link = Link.new('/links', name: 'Links')
|
39
|
+
# link.to_hash
|
40
|
+
# # => { "href" => "/links", "name" => "links" }
|
25
41
|
#
|
26
42
|
# @return [Hash] hash from Link Object
|
27
43
|
def to_hash
|
28
44
|
{ 'href' => href }.merge @options
|
29
45
|
end
|
30
46
|
|
47
|
+
# Generic comparison method.
|
48
|
+
#
|
49
|
+
# Two objects are the same if they have the same href and the same options.
|
50
|
+
#
|
51
|
+
# link_one = Link.new('/link', name: 'One', type: 'text/html')
|
52
|
+
# link_two = Link.new('/link', name: 'One', type: 'text/html')
|
53
|
+
# link_one == link_two
|
54
|
+
# # => true
|
55
|
+
#
|
56
|
+
# @param [Link] other Link object to compare to
|
57
|
+
# @return [true,false] return of the comparison of the two objects
|
31
58
|
def ==(other)
|
32
59
|
@href == other.href && @options == other.options
|
33
60
|
end
|
@@ -36,6 +63,15 @@ module Halibut::HAL
|
|
36
63
|
attr_reader :options
|
37
64
|
|
38
65
|
private
|
66
|
+
# Options reifies the various optional properties of a link, as per the
|
67
|
+
# spec.
|
68
|
+
#
|
69
|
+
# hash = { name: 'John le Carré', templated: true }
|
70
|
+
# opts = Options.new(hash)
|
71
|
+
# opts.name # => John le Carré
|
72
|
+
# opts['name'] # => John le Carré
|
73
|
+
# opts[:name] # => John le Carré
|
74
|
+
#
|
39
75
|
class Options
|
40
76
|
attr_reader :templated, :type, :name,
|
41
77
|
:profile, :title, :hreflang
|
@@ -59,23 +95,36 @@ module Halibut::HAL
|
|
59
95
|
@templated || false
|
60
96
|
end
|
61
97
|
|
98
|
+
# When converting to a hash, options that weren't set (.nil? == true) are
|
99
|
+
# kept out.
|
100
|
+
#
|
101
|
+
# This might have some implications, as it does not 'serialiaze' options
|
102
|
+
# that were explicitely set to nil. On the other hand, one can argue that
|
103
|
+
# if they were explicitly set to nil, then they shouldn't show up anyway.
|
62
104
|
def to_hash
|
63
|
-
instance_variables.each_with_object({}) do |
|
64
|
-
|
105
|
+
instance_variables.each_with_object({}) do |ivar, hash|
|
106
|
+
name = ivar.to_s.reverse.chomp("@").reverse
|
107
|
+
value = instance_variable_get(ivar)
|
65
108
|
|
66
|
-
|
109
|
+
next if value.nil?
|
110
|
+
|
111
|
+
hash[name] = value
|
67
112
|
end
|
68
113
|
end
|
69
114
|
|
115
|
+
# Straight forward comparison between two Options objects.
|
116
|
+
#
|
117
|
+
# opts_one = Options.new(name: 'Link', templated: true)
|
118
|
+
# opts_two = Options.new(name: 'Link', templated: true)
|
119
|
+
# opts_one == opts_two
|
120
|
+
# # => true
|
121
|
+
#
|
122
|
+
# @param [Options] other Options object to compare to.
|
123
|
+
# @return [true,false] whether these two objects are equivalent or not.
|
70
124
|
def ==(other)
|
71
|
-
|
72
|
-
type == other.type &&
|
73
|
-
name == other.name &&
|
74
|
-
profile == other.profile &&
|
75
|
-
title == other.title &&
|
76
|
-
hreflang == other.hreflang
|
125
|
+
to_hash == other.to_hash
|
77
126
|
end
|
78
127
|
end
|
79
128
|
end
|
80
129
|
|
81
|
-
end
|
130
|
+
end
|
data/lib/halibut/hal/resource.rb
CHANGED
@@ -4,12 +4,38 @@ module Halibut::HAL
|
|
4
4
|
#
|
5
5
|
# spec spec spec
|
6
6
|
class Resource
|
7
|
-
attr_reader :properties, :links, :embedded
|
8
7
|
|
9
|
-
#
|
8
|
+
# All the properties set in this resource
|
9
|
+
attr_reader :properties
|
10
|
+
|
11
|
+
# A collection of links, grouped by relation
|
12
|
+
attr_reader :links
|
13
|
+
|
14
|
+
# A collection of embedded resources, grouped by relation.
|
15
|
+
attr_reader :embedded
|
16
|
+
|
17
|
+
# A collection of namespaces defined in the document
|
18
|
+
attr_reader :namespace
|
19
|
+
|
20
|
+
# Initialize a new Resource.
|
21
|
+
#
|
22
|
+
# As defined in the spec, the resource SHOULD have a self link, but it
|
23
|
+
# isn't required.
|
24
|
+
# Also optionally, I'm toying with the idea of being able to pass in
|
25
|
+
# properties, links and embedded resources as parameters to this method,
|
26
|
+
# like suggested in https://github.com/locks/halibut/issues/1.
|
27
|
+
#
|
28
|
+
# # Resource without self link (e.g. POSTing a new resource)
|
29
|
+
# resource = Halibut::HAL::Resource.new
|
30
|
+
# resource.set_property :name, 'Halibut Rules'
|
31
|
+
# resource.set_property :winner, 'Tiger Blood'
|
32
|
+
#
|
33
|
+
# # Resource with a self link
|
34
|
+
# resource = Halibut::HAL::Resource.new
|
10
35
|
#
|
11
36
|
# @param [String] href Link that will be added to the self relation.
|
12
|
-
def initialize(href=nil)
|
37
|
+
def initialize(href=nil, properties={}, links={}, embedded={})
|
38
|
+
@namespaces = Halibut::RelationMap.new
|
13
39
|
@links = Halibut::RelationMap.new
|
14
40
|
@embedded = Halibut::RelationMap.new
|
15
41
|
@properties = {}
|
@@ -17,7 +43,28 @@ module Halibut::HAL
|
|
17
43
|
add_link('self', href) if href
|
18
44
|
end
|
19
45
|
|
20
|
-
#
|
46
|
+
# Returns the self link of the resource.
|
47
|
+
#
|
48
|
+
# @return [String,nil] the self link of the resource
|
49
|
+
def href
|
50
|
+
@links.fetch('self', []).map(&:href).first
|
51
|
+
end
|
52
|
+
|
53
|
+
def namespace(name)
|
54
|
+
@links['curie'].select {|ns| ns.name == name }.first
|
55
|
+
end
|
56
|
+
alias_method :ns, :namespace
|
57
|
+
|
58
|
+
def namespaces
|
59
|
+
@links['curie']
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sets a property in the resource.
|
63
|
+
#
|
64
|
+
# resource = Halibut::HAL::Resource.new
|
65
|
+
# resource.set_property :name, 'FooBar'
|
66
|
+
# resource.property :name
|
67
|
+
# # => "FooBar"
|
21
68
|
#
|
22
69
|
# @param [Object] property the key
|
23
70
|
# @param [Object] value the value
|
@@ -27,17 +74,38 @@ module Halibut::HAL
|
|
27
74
|
|
28
75
|
# Returns the value of a property in the resource
|
29
76
|
#
|
77
|
+
# resource = Halibut::HAL::Resource.new
|
78
|
+
# resource.set_property :name, 'FooBar'
|
79
|
+
# resource.property :name
|
80
|
+
# # => "FooBar"
|
81
|
+
#
|
30
82
|
# @param [String] property property
|
31
|
-
def
|
32
|
-
@properties
|
83
|
+
def property(property)
|
84
|
+
@properties.fetch(property, nil)
|
33
85
|
end
|
34
86
|
|
35
|
-
# Adds
|
87
|
+
# Adds a namespace to the resource.
|
88
|
+
#
|
89
|
+
# @param [String] name The name of the namespace
|
90
|
+
# @param [String] href The templated URI of the namespace
|
91
|
+
def add_namespace(name, href)
|
92
|
+
@links.add 'curie', Link.new(href, templated: true, name: name)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Adds link to relation.
|
96
|
+
#
|
97
|
+
# resource = Halibut::HAL::Resource.new
|
98
|
+
# resource.add_link 'next', '/resource/2', name: 'Foo'
|
99
|
+
# link = resource.links['next'].first
|
100
|
+
# link.href
|
101
|
+
# # => "/resource/2"
|
102
|
+
# link.name
|
103
|
+
# # => "Foo"
|
36
104
|
#
|
37
105
|
# @param [String] relation relation
|
38
106
|
# @param [String] href href
|
39
|
-
# @param [
|
40
|
-
#
|
107
|
+
# @param [Hash] opts options: templated, type, name, profile,
|
108
|
+
# title, hreflang
|
41
109
|
def add_link(relation, href, opts={})
|
42
110
|
@links.add relation, Link.new(href, opts)
|
43
111
|
end
|
data/lib/halibut/relation_map.rb
CHANGED
@@ -6,7 +6,7 @@ module Halibut
|
|
6
6
|
class RelationMap
|
7
7
|
extend Forwardable
|
8
8
|
|
9
|
-
def_delegators :@relations, :[], :empty?,
|
9
|
+
def_delegators :@relations, :[], :empty?, :==, :fetch
|
10
10
|
|
11
11
|
def initialize
|
12
12
|
@relations = {}
|
@@ -14,6 +14,14 @@ module Halibut
|
|
14
14
|
|
15
15
|
# Adds an object to a relation.
|
16
16
|
#
|
17
|
+
# relations = RelationMap.new
|
18
|
+
# relations.add 'self', Link.new('/resource/1')
|
19
|
+
# relations['self']
|
20
|
+
# # => [#<Halibut::HAL::Link:0x007fa0ca5b92b8 @href=\"/resource/1\",
|
21
|
+
# @options=#<Halibut::HAL::Link::Options:0x007fa0ca5b9240
|
22
|
+
# @templated=nil, @type=nil, @name=nil, @profile=nil,
|
23
|
+
# @title=nil, @hreflang=nil>>]
|
24
|
+
#
|
17
25
|
# @param [String] relation relation that the object belongs to
|
18
26
|
# @param [Object] item the object to add to the relation
|
19
27
|
def add(relation, item)
|
data/lib/halibut/version.rb
CHANGED
data/spec/adapter/xml_spec.rb
CHANGED
data/spec/resource_spec.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require_relative 'spec_helper'
|
2
2
|
|
3
3
|
describe Halibut::HAL::Resource do
|
4
|
+
subject { Halibut::HAL::Resource.new }
|
4
5
|
let(:templated_uri) { "http://example.com/{path}{?query}" }
|
5
6
|
let(:normal_uri) { "http://example.com" }
|
6
7
|
|
7
8
|
describe "Properties" do
|
8
|
-
subject { Halibut::HAL::Resource.new }
|
9
|
-
|
10
9
|
it "set property" do
|
11
10
|
subject.set_property "property", "value"
|
12
11
|
|
@@ -16,7 +15,7 @@ describe Halibut::HAL::Resource do
|
|
16
15
|
it "read property" do
|
17
16
|
subject.set_property "property", "value"
|
18
17
|
|
19
|
-
subject.
|
18
|
+
subject.property('property').must_equal "value"
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
@@ -24,8 +23,8 @@ describe Halibut::HAL::Resource do
|
|
24
23
|
|
25
24
|
describe "self link" do
|
26
25
|
it "no default" do
|
27
|
-
|
28
|
-
|
26
|
+
subject.links.must_be_empty
|
27
|
+
subject.href.must_be_nil
|
29
28
|
end
|
30
29
|
|
31
30
|
it "default" do
|
@@ -33,9 +32,47 @@ describe Halibut::HAL::Resource do
|
|
33
32
|
|
34
33
|
resource.links.wont_be_empty
|
35
34
|
resource.links['self'].first.href.must_equal normal_uri
|
35
|
+
resource.href.must_equal normal_uri
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
it "adds link to resource" do
|
40
|
+
subject.links.must_be_empty
|
41
|
+
|
42
|
+
subject.add_link 'lol', normal_uri
|
43
|
+
subject.links['lol'].first.href.must_equal normal_uri
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "Namespaces" do
|
49
|
+
let(:href) { 'http://relations.com/{rel}' }
|
50
|
+
|
51
|
+
it "has a single namespace" do
|
52
|
+
subject.add_namespace 'lol', href
|
53
|
+
|
54
|
+
subject.namespaces.size.must_equal 1
|
55
|
+
subject.namespaces.first.must_equal subject.namespace('lol')
|
56
|
+
|
57
|
+
subject.namespace('lol').must_be :templated?
|
58
|
+
subject.namespace('lol').href.must_equal href
|
59
|
+
subject.namespace('lol').name.must_equal 'lol'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "has multiple namespaces" do
|
63
|
+
subject.add_namespace 'lol', "http://lol.com/{rel}"
|
64
|
+
subject.add_namespace 'lmao', "http://lmao.com/{rel}"
|
65
|
+
|
66
|
+
subject.namespaces.size.must_equal 2
|
67
|
+
|
68
|
+
subject.namespace('lol').must_be :templated?
|
69
|
+
subject.namespace('lol').href.must_equal 'http://lol.com/{rel}'
|
70
|
+
subject.namespace('lol').name.must_equal 'lol'
|
71
|
+
|
72
|
+
subject.namespace('lmao').must_be :templated?
|
73
|
+
subject.namespace('lmao').href.must_equal 'http://lmao.com/{rel}'
|
74
|
+
subject.namespace('lmao').name.must_equal 'lmao'
|
75
|
+
end
|
39
76
|
end
|
40
77
|
|
41
78
|
describe "Embedded resources" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: halibut
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|