halibut 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|