halibut 0.1.0 → 0.2.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/.gitignore +4 -1
- data/.gitmodules +3 -0
- data/.travis.yml +4 -4
- data/Gemfile +2 -2
- data/Gemfile.travis +11 -0
- data/README.md +83 -34
- data/Rakefile +2 -2
- data/TODO +2 -0
- data/halibut.gemspec +16 -11
- data/lib/halibut.rb +15 -3
- data/lib/halibut/adapter/json.rb +72 -0
- data/lib/halibut/adapter/xml.rb +88 -0
- data/lib/halibut/builder.rb +75 -0
- data/lib/halibut/hal/link.rb +81 -0
- data/lib/halibut/hal/resource.rb +74 -0
- data/lib/halibut/link_relation.rb +29 -0
- data/lib/halibut/relation_map.rb +24 -23
- data/lib/halibut/version.rb +1 -2
- data/spec/adapter/json_spec.rb +72 -0
- data/spec/adapter/xml_spec.rb +50 -0
- data/spec/builder_spec.rb +185 -0
- data/spec/fixtures/serialize.json +1 -1
- data/spec/link_relation_spec.rb +43 -0
- data/spec/link_spec.rb +13 -11
- data/spec/relation_map_spec.rb +7 -6
- data/spec/resource_spec.rb +23 -53
- data/spec/spec_helper.rb +4 -2
- metadata +78 -15
- data/lib/halibut/link.rb +0 -56
- data/lib/halibut/resource.rb +0 -94
@@ -0,0 +1,81 @@
|
|
1
|
+
module Halibut::HAL
|
2
|
+
# This class represents a HAL Link object.
|
3
|
+
#
|
4
|
+
# spec spec spec.
|
5
|
+
class Link
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
attr_reader :href
|
9
|
+
|
10
|
+
def_delegators :@options, :templated, :templated?, :type,
|
11
|
+
:name, :profile, :title, :hreflang
|
12
|
+
# Returns an instance of a HAL Link object
|
13
|
+
#
|
14
|
+
# @param [String] href URI or URI Template
|
15
|
+
# @param [Boolean] templated true if URI Template or false otherwise
|
16
|
+
# @param [Hash] opts Options: type, name, profile, title, hreflang
|
17
|
+
#
|
18
|
+
# @return [Halibut::HAL::Link] HAL Link object
|
19
|
+
def initialize(href, opts={})
|
20
|
+
@href = href
|
21
|
+
@options = Options.new opts
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the Link as a Hash
|
25
|
+
#
|
26
|
+
# @return [Hash] hash from Link Object
|
27
|
+
def to_hash
|
28
|
+
{ 'href' => href }.merge @options
|
29
|
+
end
|
30
|
+
|
31
|
+
def ==(other)
|
32
|
+
@href == other.href && @options == other.options
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
attr_reader :options
|
37
|
+
|
38
|
+
private
|
39
|
+
class Options
|
40
|
+
attr_reader :templated, :type, :name,
|
41
|
+
:profile, :title, :hreflang
|
42
|
+
|
43
|
+
def initialize opts
|
44
|
+
@templated = opts[:templated] || opts['templated']
|
45
|
+
@type = opts[:type] || opts['type']
|
46
|
+
@name = opts[:name] || opts['name']
|
47
|
+
@profile = opts[:profile] || opts['profile']
|
48
|
+
@title = opts[:title] || opts['title']
|
49
|
+
@hreflang = opts[:hreflang] || opts['hreflang']
|
50
|
+
end
|
51
|
+
|
52
|
+
# Tells us if the href of the associated link is templated.
|
53
|
+
#
|
54
|
+
# The reason for not returning @templated directly is that all of the
|
55
|
+
# options are optional, thus nil could be returned instead of a boolean.
|
56
|
+
#
|
57
|
+
# @return [true, false] whether the href is a templated uri or not.
|
58
|
+
def templated?
|
59
|
+
@templated || false
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_hash
|
63
|
+
instance_variables.each_with_object({}) do |name, output|
|
64
|
+
next if (ivar = instance_variable_get(name)).nil?
|
65
|
+
|
66
|
+
output[name[1..-1]] = ivar
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def ==(other)
|
71
|
+
templated == other.templated &&
|
72
|
+
type == other.type &&
|
73
|
+
name == other.name &&
|
74
|
+
profile == other.profile &&
|
75
|
+
title == other.title &&
|
76
|
+
hreflang == other.hreflang
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Halibut::HAL
|
2
|
+
|
3
|
+
# This class represents a HAL Resource object.
|
4
|
+
#
|
5
|
+
# spec spec spec
|
6
|
+
class Resource
|
7
|
+
attr_reader :properties, :links, :embedded
|
8
|
+
|
9
|
+
# TDK
|
10
|
+
#
|
11
|
+
# @param [String] href Link that will be added to the self relation.
|
12
|
+
def initialize(href=nil)
|
13
|
+
@links = Halibut::RelationMap.new
|
14
|
+
@embedded = Halibut::RelationMap.new
|
15
|
+
@properties = {}
|
16
|
+
|
17
|
+
add_link('self', href) if href
|
18
|
+
end
|
19
|
+
|
20
|
+
# TDK
|
21
|
+
#
|
22
|
+
# @param [Object] property the key
|
23
|
+
# @param [Object] value the value
|
24
|
+
def set_property(property, value)
|
25
|
+
@properties[property] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the value of a property in the resource
|
29
|
+
#
|
30
|
+
# @param [String] property property
|
31
|
+
def get_property property
|
32
|
+
@properties[property]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Adds link to relation
|
36
|
+
#
|
37
|
+
# @param [String] relation relation
|
38
|
+
# @param [String] href href
|
39
|
+
# @param [true, false] templated templated
|
40
|
+
# @param [Hash] opts options: name, type, hreflang
|
41
|
+
def add_link(relation, href, opts={})
|
42
|
+
@links.add relation, Link.new(href, opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Embeds resource in relation
|
46
|
+
#
|
47
|
+
# @param [String] relation relation
|
48
|
+
# @param [Resource] resource resource to embed
|
49
|
+
def embed_resource(relation, resource)
|
50
|
+
@embedded.add relation, resource
|
51
|
+
end
|
52
|
+
|
53
|
+
# Hash representation of the resource.
|
54
|
+
# Will ommit links and embedded keys if they're empty
|
55
|
+
#
|
56
|
+
# @return [Hash] hash representation of the resource
|
57
|
+
def to_hash
|
58
|
+
{}.merge(@properties).tap do |h|
|
59
|
+
h['_links'] = {}.merge @links unless @links.empty?
|
60
|
+
h['_embedded'] = {}.merge @embedded unless @embedded.empty?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Compares two resources.
|
65
|
+
#
|
66
|
+
# @param [Halibut::HAL::Resource] other Resource to compare to
|
67
|
+
# @return [true, false] Result of the comparison
|
68
|
+
def ==(other)
|
69
|
+
@properties == other.properties &&
|
70
|
+
@links == other.links &&
|
71
|
+
@embedded == other.embedded
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Halibut
|
2
|
+
|
3
|
+
# Domain object that represents a Relation
|
4
|
+
#
|
5
|
+
# spec spec spec.
|
6
|
+
class LinkRelation
|
7
|
+
attr_accessor :name, :curie
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
splits = name.to_s.split(":")
|
11
|
+
|
12
|
+
splits.size < 2 ? @name = splits.first : (@curie, @name = splits)
|
13
|
+
end
|
14
|
+
|
15
|
+
def eql?(other)
|
16
|
+
hash == other.hash
|
17
|
+
end
|
18
|
+
|
19
|
+
def hash
|
20
|
+
instance_variables.hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
@curie and "#{@curie}:#{@name}" or @name
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/halibut/relation_map.rb
CHANGED
@@ -1,39 +1,40 @@
|
|
1
1
|
module Halibut
|
2
2
|
|
3
|
+
# This is an abstract map with behaviour specific to HAL.
|
4
|
+
#
|
5
|
+
# spec spec spec
|
3
6
|
class RelationMap
|
4
|
-
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :@relations, :[], :empty?, :==
|
10
|
+
|
5
11
|
def initialize
|
6
12
|
@relations = {}
|
7
13
|
end
|
8
|
-
|
14
|
+
|
15
|
+
# Adds an object to a relation.
|
16
|
+
#
|
17
|
+
# @param [String] relation relation that the object belongs to
|
18
|
+
# @param [Object] item the object to add to the relation
|
9
19
|
def add(relation, item)
|
10
|
-
@relations[relation] = []
|
11
|
-
|
12
|
-
@relations[relation] << item
|
13
|
-
end
|
14
|
-
|
15
|
-
def [](relation)
|
16
|
-
@relations[relation]
|
17
|
-
end
|
18
|
-
|
19
|
-
def empty?
|
20
|
-
@relations.empty?
|
20
|
+
@relations[relation] = @relations[relation].to_a << item
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
|
+
# Returns a hash corresponding to the object.
|
24
|
+
#
|
25
|
+
# RelationMap doens't just return @relations because it needs to convert
|
26
|
+
# correctly when a relation only has a single item.
|
27
|
+
#
|
28
|
+
# @return [Hash] relation map in hash format
|
23
29
|
def to_hash
|
24
|
-
|
30
|
+
@relations.each_with_object({}) do |pair, obj|
|
25
31
|
key, *value = pair.flatten
|
26
|
-
|
32
|
+
|
33
|
+
key = key.to_s
|
34
|
+
|
27
35
|
obj[key] = value.map &:to_hash
|
28
36
|
obj[key].length == 1 and obj[key] = obj[key].first
|
29
37
|
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def ==(other)
|
34
|
-
@relations == other.instance_variable_get(:@relations)
|
35
38
|
end
|
36
|
-
|
37
39
|
end
|
38
|
-
|
39
40
|
end
|
data/lib/halibut/version.rb
CHANGED
@@ -0,0 +1,72 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
read_files = ->() {
|
4
|
+
Dir.tap {|it| it.chdir('spec/test-resources/src/main/resources') } \
|
5
|
+
.glob('*.json') \
|
6
|
+
.map {|f| File.read f }
|
7
|
+
}
|
8
|
+
|
9
|
+
describe Halibut::Adapter::JSON do
|
10
|
+
|
11
|
+
it "serializes to JSON" do
|
12
|
+
resource = Halibut::HAL::Resource.new("http://example.com")
|
13
|
+
subject = Halibut::Adapter::JSON.dump resource
|
14
|
+
json = load_json "simple"
|
15
|
+
|
16
|
+
MultiJson.load(subject).must_equal MultiJson.load(json)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "deserializes from JSON" do
|
20
|
+
subject = Halibut::Adapter::JSON.load(load_json "serialize")
|
21
|
+
|
22
|
+
order = Halibut::HAL::Resource.new "/orders/123"
|
23
|
+
order.set_property "total", 30.00
|
24
|
+
order.set_property "currency", "USD"
|
25
|
+
order.set_property "status", "shipped"
|
26
|
+
|
27
|
+
resource = Halibut::HAL::Resource.new "/orders"
|
28
|
+
resource.add_link "find", "/orders{?id}", templated: true
|
29
|
+
resource.add_link "next", "/orders/1", "name" => 'hotdog'
|
30
|
+
resource.add_link "next", "/orders/9"
|
31
|
+
resource.set_property "currentlyProcessing", 14
|
32
|
+
resource.set_property "shippedToday", 20
|
33
|
+
resource.embed_resource "orders", order
|
34
|
+
|
35
|
+
subject.must_equal resource
|
36
|
+
end
|
37
|
+
|
38
|
+
it "provides to_json helper" do
|
39
|
+
json = Halibut::Adapter::JSON.load(load_json "serialize")
|
40
|
+
json = Halibut::Adapter::JSON.dump(json)
|
41
|
+
|
42
|
+
order = Halibut::HAL::Resource.new "/orders/123"
|
43
|
+
order.set_property "total", 30.00
|
44
|
+
order.set_property "currency", "USD"
|
45
|
+
order.set_property "status", "shipped"
|
46
|
+
|
47
|
+
resource = Halibut::HAL::Resource.new "/orders"
|
48
|
+
resource.add_link "find", "/orders{?id}", templated: true
|
49
|
+
resource.add_link "next", "/orders/1", "name" => 'hotdog'
|
50
|
+
resource.add_link "next", "/orders/9"
|
51
|
+
resource.set_property "currentlyProcessing", 14
|
52
|
+
resource.set_property "shippedToday", 20
|
53
|
+
resource.embed_resource "orders", order
|
54
|
+
|
55
|
+
resource.to_json.wont_equal json
|
56
|
+
resource.extend Halibut::Adapter::JSON
|
57
|
+
resource.to_json.must_equal json
|
58
|
+
end
|
59
|
+
|
60
|
+
it "tests against test-resources" do
|
61
|
+
files = read_files[]
|
62
|
+
|
63
|
+
refilled = files.map {|f| MultiJson.load f }
|
64
|
+
resources = files.map {|f| Halibut::Adapter::JSON.load f }.map &:to_hash
|
65
|
+
|
66
|
+
zipped = refilled.zip resources
|
67
|
+
zipped.each do |json, hal|
|
68
|
+
json.must_equal hal
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
read_files = ->() {
|
5
|
+
Dir.tap {|it| it.chdir('spec/test-resources/src/main/resources') } \
|
6
|
+
.glob('*.xml') \
|
7
|
+
.map {|f| File.read f }
|
8
|
+
}
|
9
|
+
|
10
|
+
|
11
|
+
describe Halibut::Adapter::XML do
|
12
|
+
|
13
|
+
it "serializes to XML" do
|
14
|
+
skip "To Be Implemented"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "deserializes from XML" do
|
18
|
+
# skip "Test is failing god knows why."
|
19
|
+
builder = Halibut::Builder.new 'https://example.com/api/customer/123456' do
|
20
|
+
property 'age', "33"
|
21
|
+
property 'expired', "false"
|
22
|
+
property 'id', "123456"
|
23
|
+
property 'name', 'Example Resource'
|
24
|
+
property 'nullprop', ""
|
25
|
+
property 'optional', "true"
|
26
|
+
|
27
|
+
relation 'curie' do
|
28
|
+
link 'https://example.com/apidocs/accounts', name: 'ns'
|
29
|
+
link 'https://example.com/apidocs/roles', name: 'role'
|
30
|
+
end
|
31
|
+
link 'ns:parent', 'https://example.com/api/customer/1234', name: 'bob',
|
32
|
+
title: 'The Parent',
|
33
|
+
hreflang: 'en'
|
34
|
+
link 'ns:users', 'https://example.com/api/customer/123456?users'
|
35
|
+
end.resource
|
36
|
+
|
37
|
+
xml = load_resource('exampleWithNullProperty.xml')
|
38
|
+
|
39
|
+
deserialized = Halibut::Adapter::XML.load(xml)
|
40
|
+
deserialized.must_equal builder, diff(deserialized.to_hash, builder.to_hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "provides to_xml helper" do
|
44
|
+
skip "To Be Implemented"
|
45
|
+
|
46
|
+
xml = Halibut::Adapter::XML.load(load_resource 'exampleWithNullProperty.xml')
|
47
|
+
xml = Halibut::Adapter::XML.dump(xml)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
require 'hash'
|
5
|
+
|
6
|
+
describe Halibut::Builder do
|
7
|
+
describe "Empty resource" do
|
8
|
+
it "builds empty resource with no self link" do
|
9
|
+
builder = Halibut::Builder.new
|
10
|
+
resource = Halibut::HAL::Resource.new
|
11
|
+
|
12
|
+
builder.resource.must_equal resource
|
13
|
+
end
|
14
|
+
|
15
|
+
it "builds empty resource with self link" do
|
16
|
+
builder = Halibut::Builder.new 'default'
|
17
|
+
resource = Halibut::HAL::Resource.new 'default'
|
18
|
+
|
19
|
+
builder.resource.must_equal resource
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "Properties" do
|
24
|
+
it "builds resource with a single property" do
|
25
|
+
builder = Halibut::Builder.new do
|
26
|
+
property 'foo', 'bar'
|
27
|
+
end
|
28
|
+
|
29
|
+
resource = Halibut::HAL::Resource.new
|
30
|
+
resource.set_property 'foo', 'bar'
|
31
|
+
|
32
|
+
builder.resource.properties['foo'].must_equal 'bar'
|
33
|
+
builder.resource.must_equal resource, diff(builder.resource.to_hash, resource.to_hash)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "builds resource with several properties" do
|
37
|
+
builder = Halibut::Builder.new do
|
38
|
+
property 'foo', 'bar'
|
39
|
+
property 'baz', 'quux'
|
40
|
+
property 'medals', { gold: 1, silver: 5, bronze: 10 }
|
41
|
+
end
|
42
|
+
|
43
|
+
resource = Halibut::HAL::Resource.new
|
44
|
+
resource.set_property 'foo', 'bar'
|
45
|
+
resource.set_property 'baz', 'quux'
|
46
|
+
resource.set_property 'medals', { gold: 1, silver: 5, bronze: 10 }
|
47
|
+
|
48
|
+
builder.resource.properties['foo'].must_equal 'bar'
|
49
|
+
builder.resource.properties['baz'].must_equal 'quux'
|
50
|
+
builder.resource.properties['medals'].must_equal({ gold: 1, silver: 5, bronze: 10 })
|
51
|
+
|
52
|
+
builder.resource.must_equal resource, diff(builder.resource.to_hash, resource.to_hash)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "Links" do
|
58
|
+
it "builds resource with a single links per relation" do
|
59
|
+
builder = Halibut::Builder.new do
|
60
|
+
link 'cs:broms', '/broms/1'
|
61
|
+
link 'cs:search', '/search{?broms,noms}', templated: true
|
62
|
+
end
|
63
|
+
|
64
|
+
resource = Halibut::HAL::Resource.new
|
65
|
+
resource.add_link 'cs:broms', '/broms/1'
|
66
|
+
resource.add_link 'cs:search', '/search{?broms,noms}', templated: true
|
67
|
+
|
68
|
+
resource.must_equal builder.resource, diff(builder.resource.to_hash, resource.to_hash)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "builds resource with multiple links per relation" do
|
72
|
+
builder = Halibut::Builder.new do
|
73
|
+
link 'cs:broms', '/broms/1'
|
74
|
+
link 'cs:broms', '/broms/2'
|
75
|
+
link 'cs:search', '/search{?broms,noms}', templated: true
|
76
|
+
end
|
77
|
+
|
78
|
+
resource = Halibut::HAL::Resource.new
|
79
|
+
resource.add_link 'cs:broms', '/broms/1'
|
80
|
+
resource.add_link 'cs:broms', '/broms/2'
|
81
|
+
resource.add_link 'cs:search', '/search{?broms,noms}', templated: true
|
82
|
+
|
83
|
+
resource.must_equal builder.resource, diff(builder.resource.to_hash, resource.to_hash)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "Embedded resources" do
|
88
|
+
it "builds resource with a single resource per relation" do
|
89
|
+
builder = Halibut::Builder.new do
|
90
|
+
resource 'games', '/game/1' do
|
91
|
+
property :name, 'Crash Bandicoot'
|
92
|
+
property :console, 'PlayStation'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
game = Halibut::HAL::Resource.new '/game/1'
|
97
|
+
game.set_property(:name, 'Crash Bandicoot')
|
98
|
+
game.set_property(:console, 'PlayStation')
|
99
|
+
|
100
|
+
resource = Halibut::HAL::Resource.new
|
101
|
+
resource.embed_resource('games', game)
|
102
|
+
|
103
|
+
builder.resource.must_equal resource, diff(builder.resource.to_hash, resource.to_hash)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "builds resource with multiple resourcer per relation" do
|
107
|
+
builder = Halibut::Builder.new do
|
108
|
+
resource 'games', '/game/1' do
|
109
|
+
property :name, 'Crash Bandicoot'
|
110
|
+
property :console, 'PlayStation'
|
111
|
+
end
|
112
|
+
resource 'games', '/game/2' do
|
113
|
+
property :name, 'Super Mario Land'
|
114
|
+
property :console, 'Game Boy'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
game1 = Halibut::HAL::Resource.new '/game/1'
|
119
|
+
game1.set_property(:name, 'Crash Bandicoot')
|
120
|
+
game1.set_property(:console, 'PlayStation')
|
121
|
+
|
122
|
+
game2 = Halibut::HAL::Resource.new '/game/2'
|
123
|
+
game2.set_property(:name, 'Super Mario Land')
|
124
|
+
game2.set_property(:console, 'Game Boy')
|
125
|
+
|
126
|
+
resource = Halibut::HAL::Resource.new
|
127
|
+
resource.embed_resource('games', game1)
|
128
|
+
resource.embed_resource('games', game2)
|
129
|
+
|
130
|
+
builder.resource.must_equal resource, diff(builder.resource.to_hash, resource.to_hash)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "Relation helper" do
|
135
|
+
it "builds resource using relation DSL" do
|
136
|
+
builder = Halibut::Builder.new do
|
137
|
+
relation 'games' do
|
138
|
+
link '/games/1'
|
139
|
+
link '/games/2'
|
140
|
+
link '/games/3'
|
141
|
+
end
|
142
|
+
link 'next', '/games/next'
|
143
|
+
relation 'users' do
|
144
|
+
resource '/users/1' do
|
145
|
+
property :name, "foo"
|
146
|
+
property :nick, "bar"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
user = Halibut::HAL::Resource.new '/users/1'
|
152
|
+
user.set_property :name, "foo"
|
153
|
+
user.set_property :nick, "bar"
|
154
|
+
|
155
|
+
resource = Halibut::HAL::Resource.new
|
156
|
+
resource.add_link 'games', '/games/1'
|
157
|
+
resource.add_link 'games', '/games/2'
|
158
|
+
resource.add_link 'games', '/games/3'
|
159
|
+
resource.add_link 'next', '/games/next'
|
160
|
+
resource.embed_resource 'users', user
|
161
|
+
|
162
|
+
builder.resource.must_equal resource, diff(builder.resource.to_hash, resource.to_hash)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "Namespace helper" do
|
167
|
+
let(:name) { 'cs' }
|
168
|
+
let(:href) { 'http://cs-api.herokuapp.com/rels/{rel}' }
|
169
|
+
|
170
|
+
it "builds resource using curie DSL" do
|
171
|
+
builder = Halibut::Builder.new do
|
172
|
+
namespace 'cs', 'http://cs-api.herokuapp.com/rels/{rel}'
|
173
|
+
end
|
174
|
+
|
175
|
+
builder = Halibut::Builder.new
|
176
|
+
builder.namespace 'cs', 'http://cs-api.herokuapp.com/rels/{rel}'
|
177
|
+
|
178
|
+
curie = builder.resource.links['curie'].first
|
179
|
+
|
180
|
+
curie.name.must_equal name
|
181
|
+
curie.href.must_equal href
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|