hypa 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 28d59bb2cad450e802dec69f3be3504452ae06d8
4
+ data.tar.gz: 5ee7de39652bc9aa30f6ed7fdba7e6ce93bc47d2
5
+ SHA512:
6
+ metadata.gz: 646d4101496edf2411102046db7fa7e3ea0ac411564027d102cbc4bee6e67a6e3ae4aa32bc20cbda53e3738d2284f5cfe6748cd87838384086b14b668b14ef6f
7
+ data.tar.gz: 16ecce86ef0630d56568e02b202e5de285d5f6d965c38348be73534be8eee8e4c249806ad0e2c248ea32edcdf91da88b6e527af8ea764c6891e7a22763f80817
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ vendor
3
+ .DS_Store
4
+ coverage
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --tty
@@ -0,0 +1 @@
1
+ 2.0.0-p0
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ - rbx-19mode
6
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,76 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hypa (0.0.1)
5
+ addressable
6
+ extlib
7
+ multi_json
8
+ sequel
9
+ sinatra
10
+ virtus
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ addressable (2.3.4)
16
+ backports (2.6.7)
17
+ colorize (0.5.8)
18
+ coveralls (0.6.7)
19
+ colorize
20
+ multi_json (~> 1.3)
21
+ rest-client
22
+ simplecov (>= 0.7)
23
+ thor
24
+ descendants_tracker (0.0.1)
25
+ diff-lcs (1.2.4)
26
+ extlib (0.9.16)
27
+ mime-types (1.23)
28
+ multi_json (1.7.2)
29
+ oj (2.0.12)
30
+ puma (2.0.1)
31
+ rack (>= 1.1, < 2.0)
32
+ rack (1.5.2)
33
+ rack-protection (1.5.0)
34
+ rack
35
+ rack-test (0.6.2)
36
+ rack (>= 1.0)
37
+ rake (0.9.6)
38
+ rest-client (1.6.7)
39
+ mime-types (>= 1.16)
40
+ rspec (2.13.0)
41
+ rspec-core (~> 2.13.0)
42
+ rspec-expectations (~> 2.13.0)
43
+ rspec-mocks (~> 2.13.0)
44
+ rspec-core (2.13.1)
45
+ rspec-expectations (2.13.0)
46
+ diff-lcs (>= 1.1.3, < 2.0)
47
+ rspec-mocks (2.13.1)
48
+ sequel (3.47.0)
49
+ simplecov (0.7.1)
50
+ multi_json (~> 1.0)
51
+ simplecov-html (~> 0.7.1)
52
+ simplecov-html (0.7.1)
53
+ sinatra (1.4.2)
54
+ rack (~> 1.5, >= 1.5.2)
55
+ rack-protection (~> 1.4)
56
+ tilt (~> 1.3, >= 1.3.4)
57
+ sqlite3 (1.3.7)
58
+ thor (0.18.1)
59
+ tilt (1.4.0)
60
+ virtus (0.5.4)
61
+ backports (~> 2.6.1)
62
+ descendants_tracker (~> 0.0.1)
63
+
64
+ PLATFORMS
65
+ ruby
66
+
67
+ DEPENDENCIES
68
+ coveralls
69
+ hypa!
70
+ oj
71
+ puma
72
+ rack-test
73
+ rake
74
+ rspec
75
+ simplecov
76
+ sqlite3
@@ -0,0 +1,3 @@
1
+ # Hypa: Web Framework to make Hypermedia APIs
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/hypa.png)] [![Build Status](https://travis-ci.org/nmerouze/hypa.png?branch=master)](https://travis-ci.org/nmerouze/hypa) [![Code Climate](https://codeclimate.com/github/nmerouze/hypa.png)](https://codeclimate.com/github/nmerouze/hypa) [![Dependency Status](https://gemnasium.com/nmerouze/hypa.png)](https://gemnasium.com/nmerouze/hypa) [![Coverage Status](https://coveralls.io/repos/nmerouze/hypa/badge.png?branch=master)](https://coveralls.io/r/nmerouze/hypa)
@@ -0,0 +1,2 @@
1
+ task(:spec) { ruby '-S rspec' }
2
+ task(default: [:spec])
@@ -0,0 +1,52 @@
1
+ require File.expand_path('../../lib/hypa', __FILE__)
2
+ require 'sequel'
3
+
4
+ Hypa::Database.connection = Sequel.sqlite
5
+
6
+ Hypa::Database.connection.create_table(:posts) do
7
+ primary_key :id
8
+ String :title
9
+ end
10
+
11
+ Hypa::Database.connection.from(:posts).insert(title: 'What a title!')
12
+
13
+ class Todo < Hypa::Application
14
+ end
15
+
16
+ Todo.item :post do |i|
17
+ i.href = '/posts/{id}'
18
+
19
+ i.data = [
20
+ { name: 'title', value: '{title}', prompt: 'Title' }
21
+ ]
22
+ end
23
+
24
+ Todo.template :post do |t|
25
+ t.data = [
26
+ { name: 'title', value: '', prompt: 'Title' }
27
+ ]
28
+ end
29
+
30
+ Todo.template :search do |t|
31
+ t.data = [
32
+ { name: 'q', value: '', prompt: 'Search' }
33
+ ]
34
+ end
35
+
36
+ Todo.collection :posts do |c|
37
+ c.version = '1.0'
38
+ c.href = '/posts'
39
+
40
+ c.links = [
41
+ { rel: 'feed', href: '/posts/feed' }
42
+ ]
43
+
44
+ c.queries = [
45
+ { rel: 'search', href: '/posts/search', prompt: 'Search', data: Todo.template(:search).data }
46
+ ]
47
+
48
+ c.template = Todo.template(:post)
49
+ end
50
+
51
+ # https://github.com/rkh/mustermann
52
+ # https://github.com/awslabs/seahorse
@@ -0,0 +1,35 @@
1
+ $:.unshift File.expand_path('../lib', __FILE__)
2
+ require 'hypa/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "hypa"
6
+ s.version = Hypa::VERSION
7
+ s.author = "Nicolas Mérouze"
8
+ s.email = "nicolas@merouze.me"
9
+ s.homepage = "https://github.com/nmerouze/hypa"
10
+ s.summary = %q{Web Framework to make Hypermedia APIs}
11
+ s.description = s.summary
12
+ s.license = 'MIT'
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.extra_rdoc_files = %w[README.md]
17
+ s.require_path = 'lib'
18
+ s.required_ruby_version = '>= 1.9.3'
19
+
20
+ s.add_dependency 'virtus'
21
+ s.add_dependency 'extlib'
22
+ s.add_dependency 'multi_json'
23
+ s.add_dependency 'sinatra'
24
+ s.add_dependency 'addressable'
25
+ s.add_dependency 'sequel'
26
+
27
+ s.add_development_dependency 'rspec'
28
+ s.add_development_dependency 'rack-test'
29
+ s.add_development_dependency 'rake'
30
+ s.add_development_dependency 'sqlite3'
31
+ s.add_development_dependency 'oj'
32
+ s.add_development_dependency 'puma'
33
+ s.add_development_dependency 'simplecov'
34
+ s.add_development_dependency 'coveralls'
35
+ end
@@ -0,0 +1,158 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/setup'
4
+ require 'virtus'
5
+ require 'sinatra'
6
+ require 'multi_json'
7
+ require 'addressable/template'
8
+ require 'rack/utils'
9
+ require 'extlib/class'
10
+ require 'extlib/inflection'
11
+
12
+ module Hypa
13
+ class Attribute
14
+ include Virtus
15
+
16
+ attribute :name, String
17
+ attribute :value, String
18
+ attribute :prompt, String
19
+ end
20
+
21
+ class Link
22
+ include Virtus
23
+
24
+ attribute :rel, String
25
+ attribute :href, String
26
+ end
27
+
28
+ class Item
29
+ include Virtus
30
+
31
+ attribute :href, String
32
+ attribute :data, Array[Attribute]
33
+ attribute :links, Array[Link]
34
+
35
+ def render(data)
36
+ self.href = Addressable::Template.new(self.href).expand(data).to_s
37
+ self.data.each { |a| a.value = Rack::Utils.unescape(Addressable::Template.new(a.value).expand(data).to_s) }
38
+ self
39
+ end
40
+ end
41
+
42
+ class Template
43
+ include Virtus
44
+
45
+ attribute :data, Array[Attribute]
46
+ end
47
+
48
+ class Query
49
+ include Virtus
50
+
51
+ attribute :data, Array[Attribute]
52
+ attribute :rel, String
53
+ attribute :href, String
54
+ attribute :prompt, String
55
+ end
56
+
57
+ class Collection
58
+ include Virtus
59
+
60
+ attribute :version, String
61
+ attribute :href, String
62
+ attribute :links, Array[Link]
63
+ attribute :items, Array[Item]
64
+ attribute :template, Template
65
+ attribute :queries, Array[Query]
66
+ end
67
+
68
+ class Database
69
+ cattr_accessor :connection
70
+
71
+ def self.all(coll_name)
72
+ @@connection.from(coll_name).all
73
+ end
74
+ end
75
+
76
+ class Application < Sinatra::Base
77
+ cattr_accessor :templates, :collections, :items
78
+
79
+ set :show_exceptions, false
80
+
81
+ before do
82
+ content_type 'application/vnd.collection+json'
83
+ end
84
+
85
+ get '/:collection' do
86
+ coll_name = params[:collection]
87
+
88
+ if collection = @@collections[coll_name.to_sym]
89
+ items = Database.all(coll_name)
90
+
91
+ collection.items = items.map do |data|
92
+ @@items[coll_name.singular.to_sym].clone.render(data)
93
+ end
94
+
95
+ MultiJson.dump(collection.to_hash, mode: :compat)
96
+ else
97
+ status 404
98
+ MultiJson.dump({ error: 'Not found.' }, mode: :compat)
99
+ end
100
+ end
101
+
102
+ get '/:collection/:id' do
103
+ end
104
+
105
+ post '/:collection' do
106
+ end
107
+
108
+ patch '/:collection/:id' do
109
+ end
110
+
111
+ delete '/:collection/:id' do
112
+ end
113
+
114
+ class << self
115
+ def template(name, &block)
116
+ @@templates ||= {}
117
+
118
+ if block_given?
119
+ template = Template.new
120
+ block.call(template)
121
+ @@templates[name] = template
122
+ else
123
+ template = @@templates[name]
124
+ end
125
+
126
+ template
127
+ end
128
+
129
+ def collection(name, &block)
130
+ @@collections ||= {}
131
+
132
+ if block_given?
133
+ collection = Collection.new
134
+ block.call(collection)
135
+ @@collections[name] = collection
136
+ else
137
+ collection = @@collections[name]
138
+ end
139
+
140
+ collection
141
+ end
142
+
143
+ def item(name, &block)
144
+ @@items ||= {}
145
+
146
+ if block_given?
147
+ item = Item.new
148
+ block.call(item)
149
+ @@items[name] = item
150
+ else
151
+ item = @@items[name]
152
+ end
153
+
154
+ item
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,3 @@
1
+ module Hypa
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,294 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Hypa::Attribute do
6
+ it 'stores name' do
7
+ a = Hypa::Attribute.new(:name => 'full_name')
8
+ expect(a.name).to eq('full_name')
9
+ end
10
+
11
+ it 'stores value' do
12
+ a = Hypa::Attribute.new(:value => 'Nicolas Mérouze')
13
+ expect(a.value).to eq('Nicolas Mérouze')
14
+ end
15
+
16
+ it 'stores prompt' do
17
+ a = Hypa::Attribute.new(:prompt => 'Full Name')
18
+ expect(a.prompt).to eq('Full Name')
19
+ end
20
+ end
21
+
22
+ describe Hypa::Link do
23
+ it 'stores rel' do
24
+ l = Hypa::Link.new(:rel => 'feed')
25
+ expect(l.rel).to eq('feed')
26
+ end
27
+
28
+ it 'stores href' do
29
+ l = Hypa::Link.new(:href => 'http://example.org/posts/feed')
30
+ expect(l.href).to eq('http://example.org/posts/feed')
31
+ end
32
+ end
33
+
34
+ describe Hypa::Item do
35
+ it 'stores href' do
36
+ i = Hypa::Item.new(:href => 'http://example.org/posts/1')
37
+ expect(i.href).to eq('http://example.org/posts/1')
38
+ end
39
+
40
+ it 'stores data' do
41
+ a = Hypa::Attribute.new
42
+ item = Hypa::Item.new(:data => [a])
43
+ expect(item.data).to eq([a])
44
+ end
45
+
46
+ it 'stores links' do
47
+ i = Hypa::Item.new(:links => [])
48
+ expect(i.links).to eq([])
49
+ end
50
+ end
51
+
52
+ describe Hypa::Item, '#render' do
53
+ before do
54
+ @item = Hypa::Item.new(href: '/posts/{id}', data: [
55
+ { name: 'title', value: '{title}', prompt: 'Title' }
56
+ ])
57
+ @item.render(id: 1, title: 'My Custom Title')
58
+ end
59
+
60
+ it 'renders href with passed data' do
61
+ expect(@item.href).to eq('/posts/1')
62
+ end
63
+
64
+ it 'renders data values with passed data' do
65
+ expect(@item.data.first[:value]).to eq('My Custom Title')
66
+ end
67
+ end
68
+
69
+ describe Hypa::Template do
70
+ it 'stores data' do
71
+ a = Hypa::Attribute.new
72
+ t = Hypa::Template.new(:data => [a])
73
+ expect(t.data).to eq([a])
74
+ end
75
+ end
76
+
77
+ describe Hypa::Query do
78
+ it 'stores data' do
79
+ a = Hypa::Attribute.new
80
+ q = Hypa::Query.new(:data => [a])
81
+ expect(q.data).to eq([a])
82
+ end
83
+
84
+ it 'stores rel' do
85
+ q = Hypa::Query.new(:rel => 'feed')
86
+ expect(q.rel).to eq('feed')
87
+ end
88
+
89
+ it 'stores href' do
90
+ q = Hypa::Link.new(:href => 'http://example.org/posts/feed')
91
+ expect(q.href).to eq('http://example.org/posts/feed')
92
+ end
93
+
94
+ it 'stores prompt' do
95
+ q = Hypa::Query.new(:prompt => 'Full Name')
96
+ expect(q.prompt).to eq('Full Name')
97
+ end
98
+ end
99
+
100
+ describe Hypa::Collection do
101
+ it 'stores version' do
102
+ c = Hypa::Collection.new(:version => '1.0')
103
+ expect(c.version).to eq('1.0')
104
+ end
105
+
106
+ it 'stores href' do
107
+ c = Hypa::Collection.new(:href => 'http://example.org/posts/')
108
+ expect(c.href).to eq('http://example.org/posts/')
109
+ end
110
+
111
+ it 'stores links' do
112
+ l = Hypa::Link.new
113
+ c = Hypa::Collection.new(:links => [l])
114
+ expect(c.links).to eq([l])
115
+ end
116
+
117
+ it 'stores items' do
118
+ i = Hypa::Item.new
119
+ c = Hypa::Collection.new(:items => [i])
120
+ expect(c.items).to eq([i])
121
+ end
122
+
123
+ it 'stores queries' do
124
+ q = Hypa::Query.new
125
+ c = Hypa::Collection.new(:queries => [q])
126
+ expect(c.queries).to eq([q])
127
+ end
128
+
129
+ it 'stores template' do
130
+ t = Hypa::Template.new
131
+ c = Hypa::Collection.new(:template => t)
132
+ expect(c.template).to eq(t)
133
+ end
134
+ end
135
+
136
+ describe Hypa::Application, '.template' do
137
+ before do
138
+ @template = Hypa::Template.new
139
+ Hypa::Template.stub(:new => @template)
140
+
141
+ Hypa::Application.template :mock do |t|
142
+ t.data = [
143
+ { name: 'full_name', value: '', prompt: 'Full Name' }
144
+ ]
145
+ end
146
+ end
147
+
148
+ context 'with block' do
149
+ it 'initializes a template with block' do
150
+ expect(@template.data.size).to eq(1)
151
+ expect(@template.data.first.attributes).to eq(name: 'full_name', value: '', prompt: 'Full Name')
152
+ end
153
+
154
+ it 'stores a template' do
155
+ expect(Hypa::Application.templates).to eq({ mock: @template })
156
+ end
157
+ end
158
+
159
+ context 'without block' do
160
+ it 'returns a template' do
161
+ expect(Hypa::Application.template(:mock)).to eq(@template)
162
+ end
163
+ end
164
+ end
165
+
166
+ describe Hypa::Application, '.collection' do
167
+ before do
168
+ @collection = Hypa::Collection.new
169
+ Hypa::Collection.stub(:new => @collection)
170
+
171
+ Hypa::Application.collection :mock do |c|
172
+ c.version = 'custom version'
173
+ end
174
+ end
175
+
176
+ context 'with block' do
177
+ it 'initializes a collection with block' do
178
+ expect(@collection.version).to eq('custom version')
179
+ end
180
+
181
+ it 'stores a collection' do
182
+ expect(Hypa::Application.collections).to eq(mock: @collection)
183
+ end
184
+ end
185
+
186
+ context 'without block' do
187
+ it 'returns a collection' do
188
+ expect(Hypa::Application.collection(:mock)).to eq(@collection)
189
+ end
190
+ end
191
+ end
192
+
193
+ describe Hypa::Application, '.item' do
194
+ before do
195
+ @item = Hypa::Item.new
196
+ Hypa::Item.stub(:new => @item)
197
+
198
+ Hypa::Application.item :mock do |i|
199
+ i.href = '/posts/{id}'
200
+ end
201
+ end
202
+
203
+ context 'with block' do
204
+ it 'initializes am item with block' do
205
+ expect(@item.href).to eq('/posts/{id}')
206
+ end
207
+
208
+ it 'stores a item' do
209
+ expect(Hypa::Application.items).to eq(mock: @item)
210
+ end
211
+ end
212
+
213
+ context 'without block' do
214
+ it 'returns a item' do
215
+ expect(Hypa::Application.item(:mock)).to eq(@item)
216
+ end
217
+ end
218
+ end
219
+
220
+ describe 'GET /:collection' do
221
+ include Rack::Test::Methods
222
+
223
+ def app
224
+ Hypa::Application
225
+ end
226
+
227
+ context 'with existing collection' do
228
+ before do
229
+ Hypa::Database.stub(:all).and_return([{id: 1234, title: 'My Test'}])
230
+ item
231
+ template
232
+ collection
233
+ get '/posts'
234
+ end
235
+
236
+ it 'renders collection' do
237
+ expect(last_response.body).to eq(MultiJson.dump(app.collection(:posts), mode: :compat))
238
+ end
239
+
240
+ it 'renders items' do
241
+ body = MultiJson.load(last_response.body)
242
+
243
+ expect(body['items'][0]).to eq({
244
+ 'href' => '/posts/1234',
245
+
246
+ 'links' => [],
247
+
248
+ 'data' => [
249
+ { 'name' => 'title', 'value' => 'My Test', 'prompt' => 'Title' }
250
+ ]
251
+ })
252
+ end
253
+ end
254
+
255
+ context 'withouth existing collection' do
256
+ before do
257
+ template
258
+ collection
259
+ get '/fakes'
260
+ end
261
+
262
+ it 'renders 404' do
263
+ expect(last_response.status).to eq(404)
264
+ end
265
+ end
266
+
267
+ def item
268
+ app.item :post do |i|
269
+ i.href = '/posts/{id}'
270
+
271
+ i.data = [
272
+ { name: 'title', value: '{title}', prompt: 'Title' },
273
+ ]
274
+ end
275
+ end
276
+
277
+ def template
278
+ app.template :post do |t|
279
+ t.data = [
280
+ { name: 'title', value: '', prompt: 'Title' },
281
+ { name: 'body', value: '', prompt: 'Body' }
282
+ ]
283
+ end
284
+ end
285
+
286
+ def collection
287
+ app.collection :posts do |c|
288
+ c.version = '1.0'
289
+ c.href = '/posts'
290
+
291
+ c.template = app.template(:post)
292
+ end
293
+ end
294
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/setup'
4
+ require 'rack/test'
5
+ require 'simplecov'
6
+ require 'coveralls'
7
+
8
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
9
+ SimpleCov::Formatter::HTMLFormatter,
10
+ Coveralls::SimpleCov::Formatter
11
+ ]
12
+
13
+ SimpleCov.start do
14
+ project_name 'hypa'
15
+ minimum_coverage 95
16
+
17
+ add_filter '/spec/'
18
+ add_filter '/vendor/'
19
+ add_group 'Library', 'lib'
20
+ end
21
+
22
+ require File.expand_path('../../lib/hypa', __FILE__)
metadata ADDED
@@ -0,0 +1,256 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hypa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nicolas Mérouze
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: virtus
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: extlib
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: multi_json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sinatra
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: addressable
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sequel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rack-test
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rake
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: oj
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: puma
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - '>='
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: coveralls
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - '>='
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - '>='
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ description: Web Framework to make Hypermedia APIs
210
+ email: nicolas@merouze.me
211
+ executables: []
212
+ extensions: []
213
+ extra_rdoc_files:
214
+ - README.md
215
+ files:
216
+ - .gitignore
217
+ - .rspec
218
+ - .ruby-version
219
+ - .travis.yml
220
+ - Gemfile
221
+ - Gemfile.lock
222
+ - README.md
223
+ - Rakefile
224
+ - examples/todo.rb
225
+ - hypa.gemspec
226
+ - lib/hypa.rb
227
+ - lib/hypa/version.rb
228
+ - spec/lib/hypa_spec.rb
229
+ - spec/spec_helper.rb
230
+ homepage: https://github.com/nmerouze/hypa
231
+ licenses:
232
+ - MIT
233
+ metadata: {}
234
+ post_install_message:
235
+ rdoc_options: []
236
+ require_paths:
237
+ - lib
238
+ required_ruby_version: !ruby/object:Gem::Requirement
239
+ requirements:
240
+ - - '>='
241
+ - !ruby/object:Gem::Version
242
+ version: 1.9.3
243
+ required_rubygems_version: !ruby/object:Gem::Requirement
244
+ requirements:
245
+ - - '>='
246
+ - !ruby/object:Gem::Version
247
+ version: '0'
248
+ requirements: []
249
+ rubyforge_project:
250
+ rubygems_version: 2.0.3
251
+ signing_key:
252
+ specification_version: 4
253
+ summary: Web Framework to make Hypermedia APIs
254
+ test_files:
255
+ - spec/lib/hypa_spec.rb
256
+ - spec/spec_helper.rb