braque 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +67 -0
- data/lib/braque/collection.rb +19 -0
- data/lib/braque/model.rb +61 -0
- data/lib/braque/version.rb +3 -0
- data/lib/braque.rb +9 -0
- data/spec/braque/collection_spec.rb +61 -0
- data/spec/braque/model_spec.rb +159 -0
- data/spec/fixtures/collection.json +23 -0
- data/spec/fixtures/resource.json +11 -0
- data/spec/fixtures/root.json +18 -0
- data/spec/spec_helper.rb +15 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b7c808e05c6710b54706c5a3dfdcca8a36af7e41
|
4
|
+
data.tar.gz: d90bcc7ed6d6cb29677ea06b92a344a72eb99f5d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f093efaacf01e01ad2028759609f21768efad162bea40d28e8e0617bbe278ff4338d05be7af922555dff9b96cdf5ccaf744cbe3d29ebf92d1cb35e83fc512d68
|
7
|
+
data.tar.gz: 12acb696429f1f62af2c8983a14b52da695cae0a8584b4626fcd4ac8348c1270379d6d5461e6f4c4d66f47bf5ff751c7fe9f8b7f2888ce276c20619f6cdf95ee
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Dylan Fareed
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Braque
|
2
|
+
|
3
|
+
Braque aims to provide a simple and familiar interface for setting up clients to interact with [Hypermedia (hal+json)](http://stateless.co/hal_specification.html) API services. It is a lightweight wrapper around [Hyperclient](https://github.com/codegram/hyperclient) and [ActiveAttr](https://github.com/cgriego/active_attr).
|
4
|
+
|
5
|
+
Braque is an early-stage and exploratory project.
|
6
|
+
|
7
|
+
### Model setup
|
8
|
+
|
9
|
+
```Braque::Model``` is ActiveSupport concern. You can use Braque::Model to map a remote resource to a class in your application. Do so by including Braque::Model in the class, defining the API service's root url and authentication details, and listing attributes which we expect from the API.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
class Article
|
13
|
+
include Braque::Model
|
14
|
+
self.api_root = Rails.application.config_for(:article_service)['url']
|
15
|
+
self.api_token = Rails.application.config_for(:article_service)['token']
|
16
|
+
|
17
|
+
attribute :id
|
18
|
+
attribute :title
|
19
|
+
attribute :body
|
20
|
+
attribute :summary
|
21
|
+
attribute :created_at
|
22
|
+
attribute :updated_at
|
23
|
+
end
|
24
|
+
```
|
25
|
+
|
26
|
+
In a Rails app, you can then use this model simply:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class ArticlesController < ApplicationController
|
30
|
+
before_filter :find_article, except: :index
|
31
|
+
|
32
|
+
def index
|
33
|
+
@articles = Article.list(page: params[:page], size: params[:size])
|
34
|
+
end
|
35
|
+
|
36
|
+
def new
|
37
|
+
end
|
38
|
+
|
39
|
+
def create
|
40
|
+
@article = Article.create params[:article]
|
41
|
+
redirect_to article_path(@article)
|
42
|
+
end
|
43
|
+
|
44
|
+
def show
|
45
|
+
end
|
46
|
+
|
47
|
+
def edit
|
48
|
+
end
|
49
|
+
|
50
|
+
def update
|
51
|
+
@article = @article.save params[:article]
|
52
|
+
redirect_to article_path(id: @article.id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def destroy
|
56
|
+
@article.destroy
|
57
|
+
redirect_to articles_path
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def find_article
|
63
|
+
@article = Article.find params[:id]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
```
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Braque
|
2
|
+
module Collection
|
3
|
+
class LinkedArray < Array
|
4
|
+
attr_reader :next_link
|
5
|
+
attr_reader :previous_link
|
6
|
+
|
7
|
+
def initialize(response = [], klass)
|
8
|
+
next_link = response._links.try(:next)
|
9
|
+
previous_link = response._links.try(:prev)
|
10
|
+
retrieved_items = []
|
11
|
+
response.each do |item|
|
12
|
+
retrieved_items << klass.new(item)
|
13
|
+
end
|
14
|
+
@retrieved_items, @next_link, @previous_link = retrieved_items, next_link, previous_link
|
15
|
+
super retrieved_items
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/braque/model.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
module Braque
|
2
|
+
module Model
|
3
|
+
extend ::ActiveSupport::Concern
|
4
|
+
include ::ActiveAttr::Model
|
5
|
+
|
6
|
+
included do
|
7
|
+
def to_param
|
8
|
+
"#{id}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def save(params = {})
|
12
|
+
response = self.class.client.method(self.class.instance_method_name).call(id: id)._patch("#{self.class.instance_method_name}" => params)
|
13
|
+
self.class.new response
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy
|
17
|
+
response = self.class.client.method(self.class.instance_method_name).call(id: id)._delete
|
18
|
+
end
|
19
|
+
|
20
|
+
class_eval <<-WRITER
|
21
|
+
def self.#{collection_method_name}
|
22
|
+
end
|
23
|
+
WRITER
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
include Braque::Collection
|
28
|
+
cattr_accessor :api_root
|
29
|
+
cattr_accessor :api_token
|
30
|
+
|
31
|
+
def list(options = {})
|
32
|
+
response = client.method(collection_method_name).call(page: options[:page], size: options[:size])
|
33
|
+
LinkedArray.new response, self
|
34
|
+
end
|
35
|
+
|
36
|
+
def find(id)
|
37
|
+
response = client.method(instance_method_name).call(id: id)
|
38
|
+
new response
|
39
|
+
end
|
40
|
+
|
41
|
+
def create(params = {})
|
42
|
+
response = client.method(collection_method_name).call._post("#{instance_method_name}" => params)
|
43
|
+
new response
|
44
|
+
end
|
45
|
+
|
46
|
+
def collection_method_name
|
47
|
+
name.tableize
|
48
|
+
end
|
49
|
+
|
50
|
+
def instance_method_name
|
51
|
+
collection_method_name.singularize
|
52
|
+
end
|
53
|
+
|
54
|
+
def client
|
55
|
+
Hyperclient.new(api_root) do |client|
|
56
|
+
client.headers['Http-Authorization'] = api_token
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/braque.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Braque::Collection do
|
4
|
+
context 'paginate_and_sort in a GravityModel class' do
|
5
|
+
before(:all) do
|
6
|
+
class BraqueClass
|
7
|
+
include ::ActiveAttr::Model
|
8
|
+
include Braque::Collection
|
9
|
+
attribute :id
|
10
|
+
attribute :title
|
11
|
+
end
|
12
|
+
|
13
|
+
class ResponseLinks
|
14
|
+
attr_reader :next
|
15
|
+
attr_reader :prev
|
16
|
+
def initialize(next_str, previous_str)
|
17
|
+
@next = next_str
|
18
|
+
@prev = previous_str
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ResponseCollection < Array
|
23
|
+
attr_reader :_links
|
24
|
+
def initialize(array = [], next_str, previous_str)
|
25
|
+
@_links = ResponseLinks.new next_str, previous_str
|
26
|
+
super array
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'LinkedArray' do
|
32
|
+
context '#initialize' do
|
33
|
+
before(:all) do
|
34
|
+
@array = [{ id: 1, title: 'hello' }, { id: 2, title: 'goodbye' }]
|
35
|
+
@response = ResponseCollection.new @array, true, false
|
36
|
+
@linked_array = BraqueClass::LinkedArray.new(@response, BraqueClass)
|
37
|
+
end
|
38
|
+
it 'returns an array of the correct number of items' do
|
39
|
+
expect(@linked_array.count).to eq 2
|
40
|
+
end
|
41
|
+
it 'returns an array of new items based on the calling class' do
|
42
|
+
expect(@linked_array.first.id).to eq 1
|
43
|
+
expect(@linked_array.first.title).to eq @array.first[:title]
|
44
|
+
expect(@linked_array.first.class.name).to eq 'BraqueClass'
|
45
|
+
|
46
|
+
expect(@linked_array[1].id).to eq 2
|
47
|
+
expect(@linked_array[1].title).to eq @array[1][:title]
|
48
|
+
expect(@linked_array[1].class.name).to eq 'BraqueClass'
|
49
|
+
end
|
50
|
+
it 'responds to previous_link with the correct value' do
|
51
|
+
expect(@linked_array).to respond_to(:previous_link)
|
52
|
+
expect(@linked_array.previous_link).to eq false
|
53
|
+
end
|
54
|
+
it 'responds to next_link with the correct value' do
|
55
|
+
expect(@linked_array).to respond_to(:next_link)
|
56
|
+
expect(@linked_array.next_link).to eq true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Braque::Model, type: :model do
|
4
|
+
before(:all) do
|
5
|
+
class Breeze
|
6
|
+
include ::Braque::Model
|
7
|
+
self.api_root = 'http://localhost:9292'
|
8
|
+
self.api_token = 'replace-me'
|
9
|
+
attribute :id
|
10
|
+
attribute :title
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:root_response) { JSON.parse(File.read 'spec/fixtures/root.json') }
|
15
|
+
let(:collection_response) { JSON.parse(File.read 'spec/fixtures/collection.json') }
|
16
|
+
let(:resource_response) { JSON.parse(File.read 'spec/fixtures/resource.json') }
|
17
|
+
let(:root_request) do
|
18
|
+
WebMock.stub_request(:get, "#{Breeze.api_root}/")
|
19
|
+
.with(headers: { 'Http-Authorization' => Breeze.api_token })
|
20
|
+
.to_return(status: 200, body: root_response)
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'class methods' do
|
24
|
+
it 'responds to find, create, and list' do
|
25
|
+
expect(Breeze).to respond_to(:find, :create, :list)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'converts the class name into collection_method_name' do
|
29
|
+
expect(Breeze.collection_method_name).to eq 'breezes'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'converts the class name into instance_method_name' do
|
33
|
+
expect(Breeze.instance_method_name).to eq 'breeze'
|
34
|
+
end
|
35
|
+
|
36
|
+
context '.list' do
|
37
|
+
before(:each) do
|
38
|
+
root_request
|
39
|
+
@collection_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes")
|
40
|
+
.with(headers: { 'Http-Authorization' => Breeze.api_token })
|
41
|
+
.to_return(status: 200, body: collection_response)
|
42
|
+
@breezes = Breeze.list
|
43
|
+
end
|
44
|
+
it 'performs the API root request' do
|
45
|
+
expect(root_request).to have_been_requested
|
46
|
+
end
|
47
|
+
it 'performs the collection request' do
|
48
|
+
expect(@collection_request).to have_been_requested
|
49
|
+
end
|
50
|
+
it 'returns an array of items' do
|
51
|
+
expect(@breezes.count).to be 1
|
52
|
+
expect(@breezes.first).to be_a_kind_of Breeze
|
53
|
+
end
|
54
|
+
it 'returns items with the correct class' do
|
55
|
+
expect(@breezes.first).to be_a_kind_of Breeze
|
56
|
+
end
|
57
|
+
it 'returns an array of items with the correct attributes' do
|
58
|
+
breeze = @breezes.first
|
59
|
+
expect(breeze.id).to eq collection_response['_embedded']['breezes'].first['id']
|
60
|
+
expect(breeze.title).to eq collection_response['_embedded']['breezes'].first['title']
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context '.find' do
|
65
|
+
before(:each) do
|
66
|
+
root_request
|
67
|
+
@resource_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes/1")
|
68
|
+
.with(headers: { 'Http-Authorization' => Breeze.api_token })
|
69
|
+
.to_return(status: 200, body: resource_response)
|
70
|
+
@breeze = Breeze.find 1
|
71
|
+
end
|
72
|
+
it 'performs the API root request' do
|
73
|
+
expect(root_request).to have_been_requested
|
74
|
+
end
|
75
|
+
it 'performs the resource request' do
|
76
|
+
expect(@resource_request).to have_been_requested
|
77
|
+
end
|
78
|
+
it 'returns an item with the correct class' do
|
79
|
+
expect(@breeze).to be_a_kind_of Breeze
|
80
|
+
end
|
81
|
+
it 'returns an item with the correct attributes' do
|
82
|
+
expect(@breeze.id).to eq resource_response['id']
|
83
|
+
expect(@breeze.title).to eq resource_response['title']
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context '.create' do
|
88
|
+
before(:each) do
|
89
|
+
root_request
|
90
|
+
@create_request = WebMock.stub_request(:post, "#{Breeze.api_root}/breezes")
|
91
|
+
.with(headers: { 'Http-Authorization' => Breeze.api_token })
|
92
|
+
.to_return(status: 201, body: resource_response)
|
93
|
+
@params = { title: 'What a nice breeze.' }
|
94
|
+
@breeze = Breeze.create(@params)
|
95
|
+
end
|
96
|
+
it 'performs the API root request' do
|
97
|
+
expect(root_request).to have_been_requested
|
98
|
+
end
|
99
|
+
it 'performs the create request' do
|
100
|
+
expect(@create_request).to have_been_requested
|
101
|
+
end
|
102
|
+
it 'returns an item with the correct class' do
|
103
|
+
expect(@breeze).to be_a_kind_of Breeze
|
104
|
+
end
|
105
|
+
it 'returns an item with the correct attributes' do
|
106
|
+
expect(@breeze.id).to eq resource_response['id']
|
107
|
+
expect(@breeze.title).to eq resource_response['title']
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
context 'instance methods' do
|
112
|
+
it 'sets to_param string based on instance.id' do
|
113
|
+
expect(Breeze.new(id: 1).to_param).to eq 1.to_s
|
114
|
+
end
|
115
|
+
|
116
|
+
context '#save' do
|
117
|
+
before(:each) do
|
118
|
+
root_request
|
119
|
+
@save_request = WebMock.stub_request(:patch, "#{Breeze.api_root}/breezes/1")
|
120
|
+
.with(headers: { 'Http-Authorization' => Breeze.api_token })
|
121
|
+
.to_return(status: 200, body: resource_response)
|
122
|
+
@params = { title: 'What a nice breeze.' }
|
123
|
+
@breeze = Breeze.new(id: 1).save(@params)
|
124
|
+
end
|
125
|
+
it 'performs the API root request' do
|
126
|
+
expect(root_request).to have_been_requested
|
127
|
+
end
|
128
|
+
it 'performs the save request' do
|
129
|
+
expect(@save_request).to have_been_requested
|
130
|
+
end
|
131
|
+
it 'returns an item with the correct class' do
|
132
|
+
expect(@breeze).to be_a_kind_of Breeze
|
133
|
+
end
|
134
|
+
it 'returns an item with the correct attributes' do
|
135
|
+
expect(@breeze.id).to eq resource_response['id']
|
136
|
+
expect(@breeze.title).to eq resource_response['title']
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context '#destroy' do
|
141
|
+
before(:each) do
|
142
|
+
root_request
|
143
|
+
@destroy_request = WebMock.stub_request(:delete, "#{Breeze.api_root}/breezes/1")
|
144
|
+
.with(headers: { 'Http-Authorization' => Breeze.api_token })
|
145
|
+
.to_return(status: 200)
|
146
|
+
@resource_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes/1")
|
147
|
+
.with(headers: { 'Http-Authorization' => Breeze.api_token })
|
148
|
+
.to_return(status: 200, body: resource_response)
|
149
|
+
@breeze = Breeze.new(id: 1).destroy
|
150
|
+
end
|
151
|
+
it 'performs the API root request' do
|
152
|
+
expect(root_request).to have_been_requested
|
153
|
+
end
|
154
|
+
it 'performs the destroy request' do
|
155
|
+
expect(@destroy_request).to have_been_requested
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"total_count":1,
|
3
|
+
"total_pages":1,
|
4
|
+
"current_page":1,
|
5
|
+
"_links":{
|
6
|
+
"self":{
|
7
|
+
"href":"http://localhost:9292/breezes"
|
8
|
+
}
|
9
|
+
},
|
10
|
+
"_embedded":{
|
11
|
+
"breezes":[
|
12
|
+
{
|
13
|
+
"id":1,
|
14
|
+
"title":"Southerly Breeze",
|
15
|
+
"_links":{
|
16
|
+
"self":{
|
17
|
+
"href":"http://localhost:9292/breezes/1"
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
]
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"_links":{
|
3
|
+
"self":{
|
4
|
+
"href":"http://localhost:9292"
|
5
|
+
},
|
6
|
+
"health":{
|
7
|
+
"href":"http://localhost:9292/health"
|
8
|
+
},
|
9
|
+
"breezes":{
|
10
|
+
"href":"http://localhost:9292/breezes{?page,size}",
|
11
|
+
"templated":true
|
12
|
+
},
|
13
|
+
"breeze":{
|
14
|
+
"href":"http://localhost:9292/breezes/{id}",
|
15
|
+
"templated":true
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
Dir["#{File.dirname(__FILE__)}/shared/**/*.rb"].each do |file|
|
5
|
+
require file
|
6
|
+
end
|
7
|
+
|
8
|
+
Dir["#{File.dirname(__FILE__)}/fixtures/**/*.rb"].each do |file|
|
9
|
+
require file
|
10
|
+
end
|
11
|
+
|
12
|
+
# Require library up front
|
13
|
+
require 'braque'
|
14
|
+
require 'shoulda/matchers'
|
15
|
+
require 'webmock/rspec'
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: braque
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dylan Fareed
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hyperclient
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: active_attr
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.8.5
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.8.5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.2.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.2.0
|
55
|
+
description: Braque provides a simple interface for interacting with Hypermedia API
|
56
|
+
services in Ruby apps.
|
57
|
+
email:
|
58
|
+
- email@dylanfareed.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- MIT-LICENSE
|
64
|
+
- README.md
|
65
|
+
- lib/braque.rb
|
66
|
+
- lib/braque/collection.rb
|
67
|
+
- lib/braque/model.rb
|
68
|
+
- lib/braque/version.rb
|
69
|
+
- spec/braque/collection_spec.rb
|
70
|
+
- spec/braque/model_spec.rb
|
71
|
+
- spec/fixtures/collection.json
|
72
|
+
- spec/fixtures/resource.json
|
73
|
+
- spec/fixtures/root.json
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
homepage: https://github.com/dylanfareed/braque
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 2.4.3
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: Braque provides a simple interface for interacting with Hypermedia API services
|
99
|
+
in Ruby apps.
|
100
|
+
test_files: []
|