halibut 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTE5OTFlZmM2MWFlYmVmNTgyZDE5ZDBjYTlkMTY3ZjZkNGZkZjI1Zg==
5
+ data.tar.gz: !binary |-
6
+ NTc2NDIzNWUwMzhhZjMwYzkyNjg1NTFlMzYxZTg2M2JmOTZiZDE4OA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ OGYxZTU0OTljZGJjMjdiYTM2MjU3YWVjYTRhMWVmZWI1ZDljZjc4NTIwYWI2
10
+ ZGZmMTg4NzJmNjRjMmQyYTdhNGM0MTlmNjRhNTc1NDg0NmQxYzJkZGEzZTVk
11
+ YTJiOTcwMjFjYWRlNDVmNzU5OTcyMWQ2MDE1ZDBjMzExOTA5M2U=
12
+ data.tar.gz: !binary |-
13
+ MDMzZjk4NGI5MmE2MjZlYjdmOWI4MDA4MjExM2JiNzJhYjdkZDE3NmQ1MWU4
14
+ MTM0NWNkZTFjNmZhYTdmNzYzNTM4NjVjMzFlMWZjODk3YzcxYTcyN2I2MTc5
15
+ MzU4ZGE4Y2NkYTAyNTVjMTNlZDU1MDkwZTM0YmM2ZDUyMDQwZTA=
data/.travis.yml CHANGED
@@ -1,10 +1,9 @@
1
1
  language: ruby
2
2
  bundler_args: --without testing
3
3
  rvm:
4
- - 1.9.2
5
4
  - 1.9.3
5
+ - 2.0.0
6
6
  - ruby-head
7
7
  - jruby-19mode
8
8
  - jruby-head
9
- - rbx-19mode
10
-
9
+ - rbx-2.1.1
data/Gemfile CHANGED
@@ -1,20 +1,15 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in halibut.gemspec
4
4
  gemspec
5
5
 
6
6
  group :travis do
7
7
  gem "rake"
8
+ gem "coveralls"
8
9
  end
9
10
 
10
11
  group :testing do
11
- gem "guard"
12
-
13
12
  gem "pry", ">= 0.9.10"
14
- gem "pry-doc"
15
- gem "pry-stack_explorer"
16
- gem "pry-coolline", "0.1.5"
17
- gem "pry-rescue", "0.13"
18
13
 
19
14
  gem "guard"
20
15
  gem "guard-bundler"
@@ -22,4 +17,14 @@ group :testing do
22
17
 
23
18
  gem "rb-fsevent"
24
19
  gem "terminal-notifier-guard"
25
- end
20
+ end
21
+
22
+ group :script do
23
+ gem "rest-client"
24
+ end
25
+
26
+ platforms 'rbx' do
27
+ gem 'rubysl'
28
+ gem 'rubinius-coverage'
29
+ gem 'rubysl-test-unit'
30
+ end
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
- # Halibut [![endorse](http://api.coderwall.com/locks/endorsecount.png)](http://coderwall.com/locks)
1
+ # Halibut [![endorse](http://api.coderwall.com/locks/endorsecount.png)](http://coderwall.com/locks) [![Stories in Ready](http://badge.waffle.io/locks/halibut.png)](http://waffle.io/locks/halibut)
2
2
 
3
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/locks/halibut)
4
- [![Build Status](https://secure.travis-ci.org/locks/halibut.png?branch=master)](https://travis-ci.org/locks/halibut)
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/halibut.png)](http://badge.fury.io/rb/halibut)
5
+ [![Build Status](https://secure.travis-ci.org/locks/halibut.png?branch=master)](https://travis-ci.org/locks/halibut)
6
+ [![Coverage Status](https://coveralls.io/repos/locks/halibut/badge.png?branch=master)](https://coveralls.io/r/locks/halibut)
5
7
  [![Dependency Status](https://gemnasium.com/locks/halibut.png)](https://gemnasium.com/locks/halibut)
8
+ [![Code Climate](https://codeclimate.com/github/locks/halibut.png)](https://codeclimate.com/github/locks/halibut)
6
9
 
7
10
  Halibut is a tiny gem that makes it easier to deal with the [HAL](http://stateless.co/hal_specification.html) format.
8
11
 
@@ -37,12 +40,12 @@ There are three ways to get a resource with halibut: manual, Builder, and JSON.
37
40
  require 'halibut'
38
41
 
39
42
  # manually creating a resource
40
- order = Halibut::HAL::Resource.new "/orders/123"
43
+ order = Halibut::Core::Resource.new "/orders/123"
41
44
  order.set_property "total", 30.00
42
45
  order.set_property "currency", "USD"
43
46
  order.set_property "status", "shipped"
44
47
 
45
- resource = Halibut::HAL::Resource.new "/orders"
48
+ resource = Halibut::Core::Resource.new "/orders"
46
49
  resource.add_link "find", "/orders{?id}", templated: true
47
50
  resource.add_link "next", "/orders/1", "name" => 'hotdog'
48
51
  resource.add_link "next", "/orders/9"
@@ -104,17 +107,6 @@ Halibut::Adapter::JSON.dump resource
104
107
  resource = Halibut::Adapter::JSON.load 'resource.json'
105
108
  ```
106
109
 
107
- ### XML
108
- ```ruby
109
- require 'halibut/adapter/xml'
110
-
111
- # converting to XML
112
- # Coming soon…
113
-
114
- # creating a resource from XML
115
- resource = Halibut::Adapter::XML.load 'resource.xml'
116
- ```
117
-
118
110
  ## Contributing
119
111
 
120
112
  1. Fork it
data/halibut.gemspec CHANGED
@@ -15,13 +15,13 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Halibut::VERSION
17
17
 
18
- gem.required_ruby_version = '~> 1.9.3'
18
+ gem.required_ruby_version = '>= 1.9.3'
19
19
 
20
20
  gem.add_dependency "multi_json"
21
- gem.add_dependency "nokogiri"
22
21
  gem.add_dependency "addressable"
23
22
 
24
23
  # this version of minitest adds parallelization
24
+ gem.add_development_dependency "rake"
25
25
  gem.add_development_dependency "minitest", ">= 4.2"
26
26
  gem.add_development_dependency "hash-differ"
27
27
 
data/lib/halibut.rb CHANGED
@@ -2,19 +2,17 @@ require "halibut/version"
2
2
 
3
3
  # Halibut is the main namespace
4
4
  module Halibut
5
- autoload :Builder, 'halibut/builder'
6
- autoload :RelationMap, 'halibut/relation_map'
5
+ autoload :Builder, 'halibut/builder'
6
+ autoload :Document, 'halibut/document'
7
7
  end
8
8
 
9
9
  # The Adapter namespace contains classes that aid in the
10
10
  # mapping of HAL Resources into a specific format.
11
11
  module Halibut::Adapter
12
12
  autoload :JSON, 'halibut/adapter/json'
13
- autoload :XML, 'halibut/adapter/xml'
14
13
  end
15
14
 
16
- # Halibut::HAL contains the domain objects that reflect the HAL specs.
17
- module Halibut::HAL
18
- autoload :Link, 'halibut/hal/link'
19
- autoload :Resource, 'halibut/hal/resource'
15
+ # Halibut::Core contains the domain objects that reflect the HAL specs.
16
+ module Halibut::Core
17
+ autoload :Resource, 'halibut/core/resource'
20
18
  end
@@ -1,5 +1,7 @@
1
1
  require 'multi_json'
2
2
 
3
+ require 'halibut/core'
4
+
3
5
  module Halibut::Adapter
4
6
 
5
7
  module JSON
@@ -24,16 +26,12 @@ module Halibut::Adapter
24
26
 
25
27
  class ResourceExtractor
26
28
  def initialize(json)
27
- @halibut = Halibut::HAL::Resource.new
28
- json = MultiJson.load(json)
29
-
30
- links = json.delete '_links'
31
- resources = json.delete '_embedded'
32
- properties = json
29
+ @halibut = Halibut::Core::Resource.new
30
+ @json = MultiJson.load(json)
33
31
 
34
- properties and extract_properties properties
35
- links and extract_links links
36
- resources and extract_resources resources
32
+ extract_properties
33
+ extract_links
34
+ extract_embedded_resources
37
35
  end
38
36
 
39
37
  def resource
@@ -41,24 +39,31 @@ module Halibut::Adapter
41
39
  end
42
40
 
43
41
  private
44
- def extract_properties(properties)
42
+ def extract_properties
43
+ properties = @json.reject {|k,v| k == '_links' }
44
+ .reject {|k,v| k == '_embedded' }
45
+
45
46
  properties.each_pair do |property, value|
46
47
  @halibut.set_property(property, value)
47
48
  end
48
49
  end
49
50
 
50
- def extract_links(links)
51
+ def extract_links
52
+ links = @json.fetch('_links', [])
53
+
51
54
  links.each do |relation,values|
52
- links = ([] << values).flatten
55
+ link = ([] << values).flatten
53
56
 
54
- links.each do |attrs|
57
+ link.each do |attrs|
55
58
  href = attrs.delete 'href'
56
59
  @halibut.add_link(relation, href, attrs)
57
60
  end
58
61
  end
59
62
  end
60
63
 
61
- def extract_resources(resources)
64
+ def extract_embedded_resources
65
+ resources = @json.fetch('_embedded', [])
66
+
62
67
  resources.each do |relation,values|
63
68
  embeds = ([] << values).flatten
64
69
 
@@ -69,4 +74,4 @@ module Halibut::Adapter
69
74
  end
70
75
  end
71
76
  end
72
- end
77
+ end
@@ -1,41 +1,32 @@
1
- require 'halibut/hal/resource'
1
+ require 'halibut/core/resource'
2
2
 
3
3
  module Halibut
4
4
 
5
5
  # Builder provides a very thin wrapper around creating a HAL resource.
6
6
  class Builder
7
7
 
8
- # The HAL resource built
9
- attr_reader :resource
10
-
11
8
  #
12
9
  #
13
10
  # @param [String] href
14
11
  # @param [Proc] blk
15
12
  def initialize(href=nil, &blk)
16
- @resource = Halibut::HAL::Resource.new href
13
+ @resource = Halibut::Core::Resource.new href
17
14
 
18
15
  RootContext.new(@resource, &blk)
19
16
  end
20
17
 
21
- def respond_to?(meth, *args)
22
- RootContext.new(@resource).respond_to? meth
23
- end
24
-
25
- def method_missing meth, *args
26
- RootContext.new(@resource).send meth, *args
18
+ # Returns the resource built.
19
+ #
20
+ # @return [Halibut::Core::Resource] resource built with the DSL
21
+ def resource
22
+ @resource
27
23
  end
28
24
 
29
25
  private
30
-
31
26
  # This is the root context of Halibut::Builder.
32
27
  #
33
28
  #
34
29
  class RootContext
35
- extend Forwardable
36
-
37
- def_delegator :@resource, :set_property, :property
38
- def_delegator :@resource, :add_link, :link
39
30
 
40
31
  def initialize(resource, &blk)
41
32
  @resource = resource
@@ -43,6 +34,26 @@ module Halibut
43
34
  instance_eval(&blk) if block_given?
44
35
  end
45
36
 
37
+ # Sets a property on the resource.
38
+ # Will overwrite any same-named existing property.
39
+ #
40
+ # @param [String] name name of the property
41
+ # @param [String] value value of the property
42
+ # @return [Halibut::Core::resource] resource with property set
43
+ def property(name, value)
44
+ @resource.set_property name, value
45
+ end
46
+
47
+ # Adds a link to the respection relation of the resource.
48
+ #
49
+ # @param [String] relation relation to which link will be added
50
+ # @param [String] href URI of the link
51
+ # @param [Hash] options Link optional parameters: templated, hreflang, etc
52
+ # @return [Halibut::Core::Resource] resource with the link added
53
+ def link(relation, href, options={})
54
+ @resource.add_link relation, href, options
55
+ end
56
+
46
57
  # Adds a namespace to the resource.
47
58
  #
48
59
  # A namespace is a conceptual abstraction of CURIE links.
@@ -62,6 +73,11 @@ module Halibut
62
73
  @resource.add_namespace(name, href)
63
74
  end
64
75
 
76
+ # Adds an embedded resource.
77
+ #
78
+ # @param [String] rel Embedded resource relation to the parent resource
79
+ # @param [String] href URI to the resource itself
80
+ # @param [Proc] blk Instructions to construct the embedded resource
65
81
  def resource(rel, href=nil, &blk)
66
82
  embedded = Halibut::Builder.new(href, &blk)
67
83
 
@@ -88,7 +104,6 @@ module Halibut
88
104
  def relation(rel, &blk)
89
105
  RelationContext.new(@resource, rel, &blk)
90
106
  end
91
-
92
107
  end
93
108
 
94
109
  class RelationContext
@@ -101,7 +116,7 @@ module Halibut
101
116
  end
102
117
 
103
118
  def link(href, opts={})
104
- @resource.add_link(@rel, href, opts)
119
+ @resource.tap {|obj| obj.add_link(@rel, href, opts) }
105
120
  end
106
121
 
107
122
  def resource(href=nil, &blk)
@@ -112,5 +127,4 @@ module Halibut
112
127
  end
113
128
 
114
129
  end
115
-
116
- end
130
+ end
@@ -0,0 +1,6 @@
1
+ module Halibut
2
+ module Core
3
+ autoload :Resource, 'halibut/core/resource'
4
+ autoload :Link, 'halibut/core/link'
5
+ end
6
+ end
@@ -1,4 +1,4 @@
1
- module Halibut::HAL
1
+ module Halibut::Core
2
2
  # This class represents a HAL Link object.
3
3
  #
4
4
  # spec spec spec.
@@ -27,7 +27,7 @@ module Halibut::HAL
27
27
  # @param [String] href URI or URI Template
28
28
  # @param [Hash] opts Options: type, name, profile, title, hreflang
29
29
  #
30
- # @return [Halibut::HAL::Link] HAL Link object
30
+ # @return [Halibut::Core::Link] HAL Link object
31
31
  def initialize(href, opts={})
32
32
  @href = href
33
33
  @options = Options.new opts
@@ -64,7 +64,7 @@ module Halibut::HAL
64
64
 
65
65
  private
66
66
  # Options reifies the various optional properties of a link, as per the
67
- # spec.
67
+ # spec: templated, type, name, profile, title, hreflang.
68
68
  #
69
69
  # hash = { name: 'John le Carré', templated: true }
70
70
  # opts = Options.new(hash)
@@ -77,6 +77,8 @@ module Halibut::HAL
77
77
  :profile, :title, :hreflang
78
78
 
79
79
  def initialize opts
80
+ string_options = Helpers::stringify_keys(opts)
81
+
80
82
  @templated = opts[:templated] || opts['templated']
81
83
  @type = opts[:type] || opts['type']
82
84
  @name = opts[:name] || opts['name']
@@ -124,6 +126,13 @@ module Halibut::HAL
124
126
  def ==(other)
125
127
  to_hash == other.to_hash
126
128
  end
129
+
130
+ private
131
+ module Helpers
132
+ def self.stringify_keys(hash)
133
+ hash.each_with_object({}) {|(k,v), obj| obj[k.to_s] = v }
134
+ end
135
+ end
127
136
  end
128
137
  end
129
138
 
@@ -1,4 +1,4 @@
1
- module Halibut
1
+ module Halibut::Core
2
2
 
3
3
  # This is an abstract map with behaviour specific to HAL.
4
4
  #
@@ -17,15 +17,15 @@ module Halibut
17
17
  # relations = RelationMap.new
18
18
  # relations.add 'self', Link.new('/resource/1')
19
19
  # relations['self']
20
- # # => [#<Halibut::HAL::Link:0x007fa0ca5b92b8 @href=\"/resource/1\",
21
- # @options=#<Halibut::HAL::Link::Options:0x007fa0ca5b9240
20
+ # # => [#<Halibut::Core::Link:0x007fa0ca5b92b8 @href=\"/resource/1\",
21
+ # @options=#<Halibut::Core::Link::Options:0x007fa0ca5b9240
22
22
  # @templated=nil, @type=nil, @name=nil, @profile=nil,
23
23
  # @title=nil, @hreflang=nil>>]
24
24
  #
25
25
  # @param [String] relation relation that the object belongs to
26
26
  # @param [Object] item the object to add to the relation
27
27
  def add(relation, item)
28
- @relations[relation] = @relations[relation].to_a << item
28
+ @relations[relation] = @relations.fetch(relation, []) << item
29
29
  end
30
30
 
31
31
  # Returns a hash corresponding to the object.
@@ -35,14 +35,12 @@ module Halibut
35
35
  #
36
36
  # @return [Hash] relation map in hash format
37
37
  def to_hash
38
- @relations.each_with_object({}) do |pair, obj|
39
- key, *value = pair.flatten
38
+ @relations.each_with_object({}) do |(rel,val), obj|
39
+ rel = rel.to_s
40
+ val = val.length == 1 ? val.first.to_hash : val.map(&:to_hash)
40
41
 
41
- key = key.to_s
42
-
43
- obj[key] = value.map &:to_hash
44
- obj[key].length == 1 and obj[key] = obj[key].first
42
+ obj[rel] = val
45
43
  end
46
44
  end
47
45
  end
48
- end
46
+ end
@@ -1,4 +1,6 @@
1
- module Halibut::HAL
1
+ require 'halibut/core/relation_map'
2
+
3
+ module Halibut::Core
2
4
 
3
5
  # This class represents a HAL Resource object.
4
6
  #
@@ -26,18 +28,18 @@ module Halibut::HAL
26
28
  # like suggested in https://github.com/locks/halibut/issues/1.
27
29
  #
28
30
  # # Resource without self link (e.g. POSTing a new resource)
29
- # resource = Halibut::HAL::Resource.new
31
+ # resource = Halibut::Core::Resource.new
30
32
  # resource.set_property :name, 'Halibut Rules'
31
33
  # resource.set_property :winner, 'Tiger Blood'
32
34
  #
33
35
  # # Resource with a self link
34
- # resource = Halibut::HAL::Resource.new
36
+ # resource = Halibut::Core::Resource.new
35
37
  #
36
38
  # @param [String] href Link that will be added to the self relation.
37
39
  def initialize(href=nil, properties={}, links={}, embedded={})
38
- @namespaces = Halibut::RelationMap.new
39
- @links = Halibut::RelationMap.new
40
- @embedded = Halibut::RelationMap.new
40
+ @namespaces = RelationMap.new
41
+ @links = RelationMap.new
42
+ @embedded = RelationMap.new
41
43
  @properties = {}
42
44
 
43
45
  add_link('self', href) if href
@@ -61,7 +63,7 @@ module Halibut::HAL
61
63
 
62
64
  # Sets a property in the resource.
63
65
  #
64
- # resource = Halibut::HAL::Resource.new
66
+ # resource = Halibut::Core::Resource.new
65
67
  # resource.set_property :name, 'FooBar'
66
68
  # resource.property :name
67
69
  # # => "FooBar"
@@ -69,12 +71,20 @@ module Halibut::HAL
69
71
  # @param [Object] property the key
70
72
  # @param [Object] value the value
71
73
  def set_property(property, value)
72
- @properties[property] = value
74
+ if property == '_links' || property == '_embedded'
75
+ raise ArgumentError, "Argument #{property} is a reserved property"
76
+ end
77
+
78
+ tap { @properties[property] = value }
79
+ end
80
+
81
+ def []=(property, value)
82
+ tap { @properties[property] = value }
73
83
  end
74
84
 
75
85
  # Returns the value of a property in the resource
76
86
  #
77
- # resource = Halibut::HAL::Resource.new
87
+ # resource = Halibut::Core::Resource.new
78
88
  # resource.set_property :name, 'FooBar'
79
89
  # resource.property :name
80
90
  # # => "FooBar"
@@ -89,12 +99,12 @@ module Halibut::HAL
89
99
  # @param [String] name The name of the namespace
90
100
  # @param [String] href The templated URI of the namespace
91
101
  def add_namespace(name, href)
92
- @links.add 'curie', Link.new(href, templated: true, name: name)
102
+ add_link 'curie', href, templated: true, name: name
93
103
  end
94
104
 
95
105
  # Adds link to relation.
96
106
  #
97
- # resource = Halibut::HAL::Resource.new
107
+ # resource = Halibut::Core::Resource.new
98
108
  # resource.add_link 'next', '/resource/2', name: 'Foo'
99
109
  # link = resource.links['next'].first
100
110
  # link.href
@@ -131,7 +141,7 @@ module Halibut::HAL
131
141
 
132
142
  # Compares two resources.
133
143
  #
134
- # @param [Halibut::HAL::Resource] other Resource to compare to
144
+ # @param [Halibut::Core::Resource] other Resource to compare to
135
145
  # @return [true, false] Result of the comparison
136
146
  def ==(other)
137
147
  @properties == other.properties &&
@@ -1,4 +1,4 @@
1
1
  module Halibut
2
2
  # Semver version (I'll try, pinkie promise)
3
- VERSION = "0.3.1"
3
+ VERSION = "0.4.0"
4
4
  end
@@ -9,7 +9,7 @@ read_files = ->() {
9
9
  describe Halibut::Adapter::JSON do
10
10
 
11
11
  it "serializes to JSON" do
12
- resource = Halibut::HAL::Resource.new("http://example.com")
12
+ resource = Halibut::Core::Resource.new("http://example.com")
13
13
  subject = Halibut::Adapter::JSON.dump resource
14
14
  json = load_json "simple"
15
15
 
@@ -19,12 +19,12 @@ describe Halibut::Adapter::JSON do
19
19
  it "deserializes from JSON" do
20
20
  subject = Halibut::Adapter::JSON.load(load_json "serialize")
21
21
 
22
- order = Halibut::HAL::Resource.new "/orders/123"
22
+ order = Halibut::Core::Resource.new "/orders/123"
23
23
  order.set_property "total", 30.00
24
24
  order.set_property "currency", "USD"
25
25
  order.set_property "status", "shipped"
26
26
 
27
- resource = Halibut::HAL::Resource.new "/orders"
27
+ resource = Halibut::Core::Resource.new "/orders"
28
28
  resource.add_link "find", "/orders{?id}", templated: true
29
29
  resource.add_link "next", "/orders/1", "name" => 'hotdog'
30
30
  resource.add_link "next", "/orders/9"
@@ -39,12 +39,12 @@ describe Halibut::Adapter::JSON do
39
39
  json = Halibut::Adapter::JSON.load(load_json "serialize")
40
40
  json = Halibut::Adapter::JSON.dump(json)
41
41
 
42
- order = Halibut::HAL::Resource.new "/orders/123"
42
+ order = Halibut::Core::Resource.new "/orders/123"
43
43
  order.set_property "total", 30.00
44
44
  order.set_property "currency", "USD"
45
45
  order.set_property "status", "shipped"
46
46
 
47
- resource = Halibut::HAL::Resource.new "/orders"
47
+ resource = Halibut::Core::Resource.new "/orders"
48
48
  resource.add_link "find", "/orders{?id}", templated: true
49
49
  resource.add_link "next", "/orders/1", "name" => 'hotdog'
50
50
  resource.add_link "next", "/orders/9"
@@ -69,4 +69,4 @@ describe Halibut::Adapter::JSON do
69
69
  end
70
70
  end
71
71
 
72
- end
72
+ end
data/spec/builder_spec.rb CHANGED
@@ -7,14 +7,14 @@ describe Halibut::Builder do
7
7
  describe "Empty resource" do
8
8
  it "builds empty resource with no self link" do
9
9
  builder = Halibut::Builder.new
10
- resource = Halibut::HAL::Resource.new
10
+ resource = Halibut::Core::Resource.new
11
11
 
12
12
  builder.resource.must_equal resource
13
13
  end
14
14
 
15
15
  it "builds empty resource with self link" do
16
16
  builder = Halibut::Builder.new 'default'
17
- resource = Halibut::HAL::Resource.new 'default'
17
+ resource = Halibut::Core::Resource.new 'default'
18
18
 
19
19
  builder.resource.must_equal resource
20
20
  end
@@ -26,7 +26,7 @@ describe Halibut::Builder do
26
26
  property 'foo', 'bar'
27
27
  end
28
28
 
29
- resource = Halibut::HAL::Resource.new
29
+ resource = Halibut::Core::Resource.new
30
30
  resource.set_property 'foo', 'bar'
31
31
 
32
32
  builder.resource.properties['foo'].must_equal 'bar'
@@ -40,7 +40,7 @@ describe Halibut::Builder do
40
40
  property 'medals', { gold: 1, silver: 5, bronze: 10 }
41
41
  end
42
42
 
43
- resource = Halibut::HAL::Resource.new
43
+ resource = Halibut::Core::Resource.new
44
44
  resource.set_property 'foo', 'bar'
45
45
  resource.set_property 'baz', 'quux'
46
46
  resource.set_property 'medals', { gold: 1, silver: 5, bronze: 10 }
@@ -61,7 +61,7 @@ describe Halibut::Builder do
61
61
  link 'cs:search', '/search{?broms,noms}', templated: true
62
62
  end
63
63
 
64
- resource = Halibut::HAL::Resource.new
64
+ resource = Halibut::Core::Resource.new
65
65
  resource.add_link 'cs:broms', '/broms/1'
66
66
  resource.add_link 'cs:search', '/search{?broms,noms}', templated: true
67
67
 
@@ -75,7 +75,7 @@ describe Halibut::Builder do
75
75
  link 'cs:search', '/search{?broms,noms}', templated: true
76
76
  end
77
77
 
78
- resource = Halibut::HAL::Resource.new
78
+ resource = Halibut::Core::Resource.new
79
79
  resource.add_link 'cs:broms', '/broms/1'
80
80
  resource.add_link 'cs:broms', '/broms/2'
81
81
  resource.add_link 'cs:search', '/search{?broms,noms}', templated: true
@@ -93,11 +93,11 @@ describe Halibut::Builder do
93
93
  end
94
94
  end
95
95
 
96
- game = Halibut::HAL::Resource.new '/game/1'
96
+ game = Halibut::Core::Resource.new '/game/1'
97
97
  game.set_property(:name, 'Crash Bandicoot')
98
98
  game.set_property(:console, 'PlayStation')
99
99
 
100
- resource = Halibut::HAL::Resource.new
100
+ resource = Halibut::Core::Resource.new
101
101
  resource.embed_resource('games', game)
102
102
 
103
103
  builder.resource.must_equal resource, diff(builder.resource.to_hash, resource.to_hash)
@@ -115,15 +115,15 @@ describe Halibut::Builder do
115
115
  end
116
116
  end
117
117
 
118
- game1 = Halibut::HAL::Resource.new '/game/1'
118
+ game1 = Halibut::Core::Resource.new '/game/1'
119
119
  game1.set_property(:name, 'Crash Bandicoot')
120
120
  game1.set_property(:console, 'PlayStation')
121
121
 
122
- game2 = Halibut::HAL::Resource.new '/game/2'
122
+ game2 = Halibut::Core::Resource.new '/game/2'
123
123
  game2.set_property(:name, 'Super Mario Land')
124
124
  game2.set_property(:console, 'Game Boy')
125
125
 
126
- resource = Halibut::HAL::Resource.new
126
+ resource = Halibut::Core::Resource.new
127
127
  resource.embed_resource('games', game1)
128
128
  resource.embed_resource('games', game2)
129
129
 
@@ -148,11 +148,11 @@ describe Halibut::Builder do
148
148
  end
149
149
  end
150
150
 
151
- user = Halibut::HAL::Resource.new '/users/1'
151
+ user = Halibut::Core::Resource.new '/users/1'
152
152
  user.set_property :name, "foo"
153
153
  user.set_property :nick, "bar"
154
154
 
155
- resource = Halibut::HAL::Resource.new
155
+ resource = Halibut::Core::Resource.new
156
156
  resource.add_link 'games', '/games/1'
157
157
  resource.add_link 'games', '/games/2'
158
158
  resource.add_link 'games', '/games/3'
@@ -164,20 +164,16 @@ describe Halibut::Builder do
164
164
  end
165
165
 
166
166
  describe "Namespace helper" do
167
- let(:name) { 'cs' }
168
- let(:href) { 'http://cs-api.herokuapp.com/rels/{rel}' }
167
+ let(:namespace) { 'cs' }
168
+ let(:href) { 'http://cs-api.herokuapp.com/rels/{rel}' }
169
169
 
170
170
  it "builds resource using curie DSL" do
171
171
  builder = Halibut::Builder.new do
172
172
  namespace 'cs', 'http://cs-api.herokuapp.com/rels/{rel}'
173
173
  end
174
174
 
175
- builder = Halibut::Builder.new
176
- builder.namespace 'cs', 'http://cs-api.herokuapp.com/rels/{rel}'
177
-
178
175
  curie = builder.resource.links['curie'].first
179
-
180
- curie.name.must_equal name
176
+ curie.name.must_equal namespace
181
177
  curie.href.must_equal href
182
178
  end
183
179
  end
@@ -1,19 +1,21 @@
1
- require_relative 'spec_helper'
1
+ require_relative '../spec_helper'
2
2
 
3
- describe Halibut::HAL::Link do
3
+ require 'halibut/core/link'
4
+
5
+ describe Halibut::Core::Link do
4
6
  let(:normal_uri) { 'http://example.com' }
5
7
  let(:tmpl_uri) { 'http://example.com/{id}' }
6
8
 
7
9
  describe "href" do
8
10
  it "accepts non-templated uri" do
9
- link = Halibut::HAL::Link.new normal_uri
11
+ link = Halibut::Core::Link.new normal_uri
10
12
 
11
13
  link.templated?.must_equal false
12
14
  link.href.must_equal normal_uri
13
15
  end
14
16
 
15
17
  it "accepts templated uri" do
16
- link = Halibut::HAL::Link.new tmpl_uri, templated: true
18
+ link = Halibut::Core::Link.new tmpl_uri, templated: true
17
19
 
18
20
  link.templated?.must_equal true
19
21
  link.href.must_equal tmpl_uri
@@ -22,14 +24,14 @@ describe Halibut::HAL::Link do
22
24
 
23
25
  describe "optionals" do
24
26
  it "are set correctly" do
25
- link1 = Halibut::HAL::Link.new normal_uri, {
27
+ link1 = Halibut::Core::Link.new normal_uri, {
26
28
  :type => 'type',
27
29
  :name => 'name',
28
30
  :profile => 'profile',
29
31
  :title => 'title',
30
32
  :hreflang => 'hreflang'
31
33
  }
32
- link2 = Halibut::HAL::Link.new normal_uri, {
34
+ link2 = Halibut::Core::Link.new normal_uri, {
33
35
  :type => 'type',
34
36
  :name => 'name',
35
37
  :profile => 'profile',
@@ -1,7 +1,9 @@
1
- require_relative 'spec_helper'
1
+ require_relative '../spec_helper'
2
2
 
3
- describe Halibut::RelationMap do
4
- subject { Halibut::RelationMap.new }
3
+ require 'halibut/core/relation_map'
4
+
5
+ describe Halibut::Core::RelationMap do
6
+ subject { Halibut::Core::RelationMap.new }
5
7
 
6
8
  it "is empty" do
7
9
  subject.must_be_empty
@@ -1,7 +1,9 @@
1
- require_relative 'spec_helper'
1
+ require_relative '../spec_helper'
2
2
 
3
- describe Halibut::HAL::Resource do
4
- subject { Halibut::HAL::Resource.new }
3
+ require 'halibut/core/resource'
4
+
5
+ describe Halibut::Core::Resource do
6
+ subject { Halibut::Core::Resource.new }
5
7
  let(:templated_uri) { "http://example.com/{path}{?query}" }
6
8
  let(:normal_uri) { "http://example.com" }
7
9
 
@@ -12,6 +14,11 @@ describe Halibut::HAL::Resource do
12
14
  subject.properties['property'].must_equal "value"
13
15
  end
14
16
 
17
+ it "fails to set reserved property" do
18
+ -> { subject.set_property "_links", "lol" }.must_raise ArgumentError
19
+ -> { subject.set_property "_embedded", "lol" }.must_raise ArgumentError
20
+ end
21
+
15
22
  it "read property" do
16
23
  subject.set_property "property", "value"
17
24
 
@@ -28,7 +35,7 @@ describe Halibut::HAL::Resource do
28
35
  end
29
36
 
30
37
  it "default" do
31
- resource = Halibut::HAL::Resource.new normal_uri
38
+ resource = Halibut::Core::Resource.new normal_uri
32
39
 
33
40
  resource.links.wont_be_empty
34
41
  resource.links['self'].first.href.must_equal normal_uri
@@ -76,9 +83,9 @@ describe Halibut::HAL::Resource do
76
83
  end
77
84
 
78
85
  describe "Embedded resources" do
79
- subject { Halibut::HAL::Resource.new }
80
- let(:res1) { Halibut::HAL::Resource.new "http://first-resource.com" }
81
- let(:res2) { Halibut::HAL::Resource.new "http://secnd-resource.com" }
86
+ subject { Halibut::Core::Resource.new }
87
+ let(:res1) { Halibut::Core::Resource.new "http://first-resource.com" }
88
+ let(:res2) { Halibut::Core::Resource.new "http://secnd-resource.com" }
82
89
 
83
90
  it "no embedded resource" do
84
91
  subject.embedded.must_be_empty
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  require 'bundler/setup'
2
2
 
3
+ require 'coveralls'
4
+ Coveralls.wear!
5
+
3
6
  require 'minitest/autorun'
4
- require 'minitest/hell'
5
7
 
6
8
  require 'halibut'
7
9
 
10
+
8
11
  # Testing helper to load JSON files. Returns a string containing JSON.
9
12
  def load_json(filename)
10
13
  File.read(File.dirname(__FILE__)+"/fixtures/#{filename}.json")
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: halibut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.4.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ricardo Mendes
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-14 00:00:00.000000000 Z
11
+ date: 2013-12-14 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: multi_json
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,15 +20,13 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
- name: nokogiri
28
+ name: addressable
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,23 +34,20 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
- name: addressable
42
+ name: rake
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
- type: :runtime
48
+ type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: minitest
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: hash-differ
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -100,7 +89,6 @@ extra_rdoc_files: []
100
89
  files:
101
90
  - .gitignore
102
91
  - .gitmodules
103
- - .rvmrc
104
92
  - .travis.yml
105
93
  - Gemfile
106
94
  - Guardfile
@@ -111,62 +99,59 @@ files:
111
99
  - halibut.gemspec
112
100
  - lib/halibut.rb
113
101
  - lib/halibut/adapter/json.rb
114
- - lib/halibut/adapter/xml.rb
115
102
  - lib/halibut/builder.rb
116
- - lib/halibut/hal/link.rb
117
- - lib/halibut/hal/resource.rb
103
+ - lib/halibut/core.rb
104
+ - lib/halibut/core/link.rb
105
+ - lib/halibut/core/relation_map.rb
106
+ - lib/halibut/core/resource.rb
118
107
  - lib/halibut/link_relation.rb
119
- - lib/halibut/relation_map.rb
120
108
  - lib/halibut/version.rb
121
109
  - spec/adapter/json_spec.rb
122
- - spec/adapter/xml_spec.rb
123
110
  - spec/builder_spec.rb
111
+ - spec/core/link_spec.rb
112
+ - spec/core/relation_map_spec.rb
113
+ - spec/core/resource_spec.rb
124
114
  - spec/fixtures/example.json
125
115
  - spec/fixtures/example.xml
126
116
  - spec/fixtures/minimal.json
127
117
  - spec/fixtures/serialize.json
128
118
  - spec/fixtures/simple.json
129
119
  - spec/link_relation_spec.rb
130
- - spec/link_spec.rb
131
- - spec/relation_map_spec.rb
132
- - spec/resource_spec.rb
133
120
  - spec/spec_helper.rb
134
121
  homepage: http://locks.github.com/halibut
135
122
  licenses: []
123
+ metadata: {}
136
124
  post_install_message:
137
125
  rdoc_options: []
138
126
  require_paths:
139
127
  - lib
140
128
  required_ruby_version: !ruby/object:Gem::Requirement
141
- none: false
142
129
  requirements:
143
- - - ~>
130
+ - - ! '>='
144
131
  - !ruby/object:Gem::Version
145
132
  version: 1.9.3
146
133
  required_rubygems_version: !ruby/object:Gem::Requirement
147
- none: false
148
134
  requirements:
149
135
  - - ! '>='
150
136
  - !ruby/object:Gem::Version
151
137
  version: '0'
152
138
  requirements: []
153
139
  rubyforge_project:
154
- rubygems_version: 1.8.24
140
+ rubygems_version: 2.0.0
155
141
  signing_key:
156
- specification_version: 3
142
+ specification_version: 4
157
143
  summary: A HAL parser and builder for use in Hypermedia APIs
158
144
  test_files:
159
145
  - spec/adapter/json_spec.rb
160
- - spec/adapter/xml_spec.rb
161
146
  - spec/builder_spec.rb
147
+ - spec/core/link_spec.rb
148
+ - spec/core/relation_map_spec.rb
149
+ - spec/core/resource_spec.rb
162
150
  - spec/fixtures/example.json
163
151
  - spec/fixtures/example.xml
164
152
  - spec/fixtures/minimal.json
165
153
  - spec/fixtures/serialize.json
166
154
  - spec/fixtures/simple.json
167
155
  - spec/link_relation_spec.rb
168
- - spec/link_spec.rb
169
- - spec/relation_map_spec.rb
170
- - spec/resource_spec.rb
171
156
  - spec/spec_helper.rb
172
157
  has_rdoc:
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm use --create default@halibut
@@ -1,86 +0,0 @@
1
- require 'nokogiri'
2
-
3
- module Halibut::Adapter
4
-
5
- module XML
6
- def self.load(xml)
7
- ResourceExtractor.new(xml).resource
8
- end
9
-
10
- def self.dump(resource)
11
- raise NotImplementedError
12
- end
13
-
14
- private
15
- def self.extended(base)
16
- base.extend InstanceMethods
17
- end
18
-
19
- module InstanceMethods
20
- def to_xml
21
- raise NotImplementedError
22
- end
23
- end
24
-
25
- class ResourceExtractor
26
-
27
- attr_reader :resource
28
-
29
- def initialize(xml)
30
- xml = Nokogiri::XML(xml)
31
-
32
- @document = xml.root
33
- @resource = Halibut::HAL::Resource.new extract_self_link
34
-
35
- extract_curie
36
- extract_properties
37
- extract_links
38
- extract_resources
39
- end
40
-
41
- private
42
- def extract_self_link
43
- @document.attr 'href'
44
- end
45
-
46
- def extract_curie
47
- @document.namespace_scopes
48
- .reject {|ns| ns.prefix.eql? 'xsi' }
49
- .each do |ns|
50
- @resource.add_link 'curie', ns.href, name: ns.prefix
51
- end
52
- end
53
-
54
- def extract_properties
55
- properties = @document.xpath '/resource/*[not(self::link) and not(self::resource)]'
56
-
57
- properties.each do |property|
58
- @resource.set_property property.name, property.content
59
- end
60
- end
61
-
62
- def extract_links
63
- links = @document.xpath('/resource/link')
64
-
65
- links.each do |link|
66
- @resource.add_link link['rel'],
67
- link['href'],
68
- extract_link_options(link)
69
- end
70
- end
71
-
72
- # In case there are no options on the link, it returns an empty hash
73
- def extract_link_options(link)
74
- Hash[link.reject {|(key)| key.eql? 'rel' }
75
- .reject {|(key)| key.eql? 'href' }]
76
- end
77
-
78
- def extract_resources
79
- @document.xpath('/resource/resource')
80
- .map {|r| [] << r['rel'] << ResourceExtractor.new(r.to_xml).resource }
81
- .each {|rel,res| @resource.embed_resource rel, res }
82
- end
83
- end
84
- end
85
-
86
- end
@@ -1,49 +0,0 @@
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
- builder = Halibut::Builder.new 'https://example.com/api/customer/123456' do
19
- property 'age', "33"
20
- property 'expired', "false"
21
- property 'id', "123456"
22
- property 'name', 'Example Resource'
23
- property 'nullprop', ""
24
- property 'optional', "true"
25
-
26
- relation 'curie' do
27
- link 'https://example.com/apidocs/accounts', name: 'ns'
28
- link 'https://example.com/apidocs/roles', name: 'role'
29
- end
30
- link 'ns:parent', 'https://example.com/api/customer/1234', name: 'bob',
31
- title: 'The Parent',
32
- hreflang: 'en'
33
- link 'ns:users', 'https://example.com/api/customer/123456?users'
34
- end.resource
35
-
36
- xml = load_resource('exampleWithNullProperty.xml')
37
-
38
- deserialized = Halibut::Adapter::XML.load(xml)
39
- deserialized.must_equal builder, diff(deserialized.to_hash, builder.to_hash)
40
- end
41
-
42
- it "provides to_xml helper" do
43
- skip "To Be Implemented"
44
-
45
- xml = Halibut::Adapter::XML.load(load_resource 'exampleWithNullProperty.xml')
46
- xml = Halibut::Adapter::XML.dump(xml)
47
- end
48
-
49
- end