halibut 0.3.1 → 0.4.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.
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