angelo 0.0.7 → 0.0.9

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: 19662f6ad2cd2af07d8468c0db06e79cace30ad6
4
+ data.tar.gz: e9f0dea09b6fdd129d627893024722dbce7a9836
5
+ SHA512:
6
+ metadata.gz: 878aefb22125a90079c96e8647ccb607eb96033ab6f898482c07210561ed5abb4e82c5af9e4fa34aa06306d1f39dd87f683e48a30b81df7d61d85e28dba1d9d3
7
+ data.tar.gz: a7982735780dd4bd941c4a4a13d42857eaacfc95731c4b8c4aef19a0b36350221e41a1fd606356eb009dc2d43c425f97388327a2c979781b0350ad1bba3f343c
@@ -2,5 +2,4 @@ language: ruby
2
2
  rvm:
3
3
  - "1.9.3"
4
4
  - "2.0.0"
5
- - rbx-19mode
6
5
  script: bundle exec rspec
@@ -1,7 +1,18 @@
1
1
  changelog
2
2
  =========
3
3
 
4
- ### 0.0.7 5 nov 2013 gunpowder treason
4
+ ### 0.0.9 20 feb 2014
5
+
6
+ * memoize params
7
+ * slight changes for mustermann
8
+ * add '-o addr' bind to address cmd line option
9
+ * add '-p port' bind to port cmd line option
10
+
11
+ ### 0.0.8 5 nov 2013 gunpowder treason
12
+
13
+ * add mustermann support
14
+
15
+ ### 0.0.7 5 nov 2013
5
16
 
6
17
  * fix gemspec
7
18
  * add codename
@@ -25,7 +36,6 @@ changelog
25
36
 
26
37
  ### 0.0.3 30 oct 2013
27
38
 
28
-
29
39
  * added tilt/erb
30
40
  * added before/after
31
41
  * added content_type/headers
data/Gemfile CHANGED
@@ -6,10 +6,13 @@ gem 'tilt'
6
6
  platform :rbx do
7
7
  gem 'rubysl-cgi'
8
8
  gem 'rubysl-erb'
9
- gem 'rubysl-json'
10
9
  gem 'rubysl-prettyprint'
11
10
  end
12
11
 
12
+ platform :ruby_20 do
13
+ gem 'mustermann'
14
+ end
15
+
13
16
  group :development do
14
17
  gem 'pry'
15
18
  gem 'pry-nav'
data/README.md CHANGED
@@ -3,9 +3,17 @@ Angelo
3
3
 
4
4
  [![Build Status](https://travis-ci.org/kenichi/angelo.png?branch=master)](https://travis-ci.org/kenichi/angelo)
5
5
 
6
- A Sinatra-esque DSL for Reel.
6
+ A [Sinatra](https://github.com/sinatra/sinatra)-esque DSL for [Reel](https://github.com/celluloid/reel).
7
7
 
8
- __SUPER ALPHA!__
8
+ ### Notes/Features
9
+
10
+ * "easy" websocket support via `socket '/path' do |s|` route handler
11
+ * "easy" websocket stashing via `websockets` helper
12
+ * no rack/rack-style params
13
+ * optional tilt/erb support
14
+ * optional mustermann support
15
+
16
+ Lots of work left to do!
9
17
 
10
18
  ### Quick example
11
19
 
@@ -57,16 +65,11 @@ end
57
65
  Foo.run
58
66
  ```
59
67
 
60
- ### Tilt / ERB
68
+ ### [Tilt](https://github.com/rtomayko/tilt) / ERB
61
69
 
62
70
  To make `erb` available in route blocks
63
71
 
64
- 1. add `tilt` to your `Gemfile`:
65
-
66
- ```ruby
67
- gem 'tilt'
68
- ```
69
-
72
+ 1. add `tilt` to your `Gemfile`: `gem 'tilt'`
70
73
  2. require `angelo/tilt/erb`
71
74
  3. include `Angelo::Tilt::ERB` in your app
72
75
 
@@ -83,6 +86,46 @@ class Foo < Angelo::Base
83
86
  end
84
87
  ```
85
88
 
89
+ ### [Mustermann](https://github.com/rkh/mustermann)
90
+
91
+ To make routes blocks match path with Mustermann patterns
92
+
93
+ 1. be using ruby &gt;=2.0.0
94
+ 2. add 'mustermann' to to your `Gemfile`: `platform(:ruby_20){ gem 'mustermann' }`
95
+ 3. require `angelo/mustermann`
96
+ 4. include `Angelo::Mustermann` in your app
97
+
98
+ ```ruby
99
+ class Foo < Angelo::Base
100
+ include Angelo::Tilt::ERB
101
+ include Angelo::Mustermann
102
+
103
+ get '/:foo/things/:bar' do
104
+
105
+ # `params` is merged with the Mustermann object#params hash, so
106
+ # a "GET /some/things/are_good?foo=other&bar=are_bad" would have:
107
+ # params: {
108
+ # 'foo' => 'some',
109
+ # 'bar' => 'are_good'
110
+ # }
111
+
112
+ @foo = params[:foo]
113
+ @bar = params[:bar]
114
+ erb :index
115
+ end
116
+
117
+ end
118
+ ```
119
+
120
+ NOTE: this always sets the Mustermann object's `type` to `:sinatra`
121
+
122
+ ### Contributing
123
+
124
+ YES, HAVE SOME
125
+
126
+ * :fork_and_knife: Fork this repo, make changes, send PR!
127
+ * :shipit: if Good stuff?
128
+
86
129
  ### License
87
130
 
88
131
  see LICENSE
@@ -8,29 +8,29 @@ require 'json'
8
8
 
9
9
  module Angelo
10
10
 
11
- GET = 'GET'.freeze
12
- POST = 'POST'.freeze
13
- PUT = 'PUT'.freeze
14
- DELETE = 'DELETE'.freeze
15
- OPTIONS = 'OPTIONS'.freeze
11
+ GET = 'GET'
12
+ POST = 'POST'
13
+ PUT = 'PUT'
14
+ DELETE = 'DELETE'
15
+ OPTIONS = 'OPTIONS'
16
16
 
17
17
  ROUTABLE = [:get, :post, :put, :delete, :socket]
18
18
  HTTPABLE = [:get, :post, :put, :delete]
19
19
 
20
- CONTENT_TYPE_HEADER_KEY = 'Content-Type'.freeze
20
+ CONTENT_TYPE_HEADER_KEY = 'Content-Type'
21
21
 
22
- HTML_TYPE = 'text/html'.freeze
23
- JSON_TYPE = 'application/json'.freeze
24
- FORM_TYPE = 'application/x-www-form-urlencoded'.freeze
22
+ HTML_TYPE = 'text/html'
23
+ JSON_TYPE = 'application/json'
24
+ FORM_TYPE = 'application/x-www-form-urlencoded'
25
25
 
26
- DEFAULT_ADDR = '127.0.0.1'.freeze
26
+ DEFAULT_ADDR = '127.0.0.1'
27
27
  DEFAULT_PORT = 4567
28
28
 
29
29
  DEFAULT_RESPONSE_HEADERS = {
30
30
  CONTENT_TYPE_HEADER_KEY => HTML_TYPE
31
31
  }
32
32
 
33
- NOT_FOUND = 'Not Found'.freeze
33
+ NOT_FOUND = 'Not Found'
34
34
 
35
35
  end
36
36
 
@@ -7,6 +7,17 @@ module Angelo
7
7
  extend Forwardable
8
8
  def_delegators :@responder, :content_type, :headers, :request
9
9
 
10
+ @@addr = DEFAULT_ADDR
11
+ @@port = DEFAULT_PORT
12
+
13
+ if ARGV.any?
14
+ require 'optparse'
15
+ OptionParser.new { |op|
16
+ op.on('-p port', 'set the port (default is 4567)') { |val| @@port = Integer(val) }
17
+ op.on('-o addr', "set the host (default is #{@@addr})") { |val| @@addr = val }
18
+ }.parse!(ARGV.dup)
19
+ end
20
+
10
21
  attr_accessor :responder
11
22
 
12
23
  class << self
@@ -18,7 +29,6 @@ module Angelo
18
29
 
19
30
  def subclass.root
20
31
  @root ||= File.expand_path '..', app_file
21
- @root
22
32
  end
23
33
 
24
34
  def subclass.view_dir
@@ -71,8 +81,8 @@ module Angelo
71
81
  Responder.content_type type
72
82
  end
73
83
 
74
- def run host = DEFAULT_ADDR, port = DEFAULT_PORT
75
- @server = Angelo::Server.new self, host, port
84
+ def run addr = @@addr, port = @@port
85
+ @server = Angelo::Server.new self, addr, port
76
86
  trap "INT" do
77
87
  @server.terminate if @server and @server.alive?
78
88
  exit
@@ -88,7 +98,6 @@ module Angelo
88
98
  when POST; parse_post_body
89
99
  when PUT; parse_post_body
90
100
  end
91
- @params
92
101
  end
93
102
 
94
103
  def websockets; self.class.websockets; end
@@ -0,0 +1,55 @@
1
+ require 'mustermann'
2
+
3
+ module Angelo
4
+
5
+ module Mustermann
6
+
7
+ # hrm, sneaky
8
+ #
9
+ def self.included base
10
+ base.extend ClassMethods
11
+ base.class_eval do
12
+ def_delegator :@responder, :mustermann
13
+ end
14
+
15
+ [Responder, WebsocketResponder].each do |res|
16
+ res.class_eval do
17
+ attr_accessor :mustermann
18
+ end
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+
24
+ HTTPABLE.each do |m|
25
+ define_method m do |path, &block|
26
+ path = ::Mustermann.new path
27
+ routes[m][path] = Responder.new &block
28
+ end
29
+ end
30
+
31
+ def routes
32
+ @routes ||= {}
33
+ ROUTABLE.each do |m|
34
+ @routes[m] ||= RouteMap.new
35
+ end
36
+ @routes
37
+ end
38
+
39
+ end
40
+
41
+ def params
42
+ @params ||= super.merge mustermann.params(request.path)
43
+ end
44
+
45
+ class RouteMap < Hash
46
+ def [] route
47
+ mustermann = keys.select {|k| k.match(route)}.first
48
+ responder = fetch mustermann
49
+ responder.mustermann = mustermann
50
+ responder
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -4,8 +4,8 @@ module Angelo
4
4
 
5
5
  module ParamsParser
6
6
 
7
- EMPTY_JSON = '{}'.freeze
8
- SEMICOLON = ';'.freeze
7
+ EMPTY_JSON = '{}'
8
+ SEMICOLON = ';'
9
9
 
10
10
  def parse_formencoded str
11
11
  str.split('&').reduce(Responder.symhash) do |p, kv|
@@ -50,25 +50,32 @@ module Angelo
50
50
  end
51
51
 
52
52
  def handle_request
53
- begin
54
- if @response_handler
55
- @base.before if @base.respond_to? :before
56
- @body = @response_handler.bind(@base).call || ''
57
- @base.after if @base.respond_to? :after
58
- else
59
- raise NotImplementedError
60
- end
61
- rescue => e
62
- error_message = case
63
- when respond_with?(:json)
64
- { error: e.message }.to_json
65
- else
66
- e.message
67
- end
68
- @connection.respond :internal_server_error, headers, error_message
69
- @connection.close
70
- error "#{e.class} - #{e.message}"
71
- ::STDERR.puts e.backtrace
53
+ if @response_handler
54
+ @base.before if @base.respond_to? :before
55
+ @body = @response_handler.bind(@base).call || ''
56
+ @base.after if @base.respond_to? :after
57
+ else
58
+ raise NotImplementedError
59
+ end
60
+ rescue => e
61
+ handle_error e
62
+ end
63
+
64
+ def handle_error _error, report = true
65
+ @connection.respond :internal_server_error, headers, error_message(_error)
66
+ @connection.close
67
+ if report
68
+ error "#{_error.class} - #{_error.message}"
69
+ ::STDERR.puts _error.backtrace
70
+ end
71
+ end
72
+
73
+ def error_message _error
74
+ case
75
+ when respond_with?(:json)
76
+ { error: _error.message }.to_json
77
+ else
78
+ _error.message
72
79
  end
73
80
  end
74
81
 
@@ -99,8 +106,17 @@ module Angelo
99
106
  end
100
107
 
101
108
  def respond
102
- @body = @body.to_json if respond_with? :json
109
+ @body = case @body
110
+ when String
111
+ JSON.parse @body if respond_with? :json # for the raises
112
+ @body
113
+ when Hash
114
+ raise 'html response requires String' if respond_with? :html
115
+ @body.to_json if respond_with? :json
116
+ end
103
117
  @connection.respond :ok, headers, @body
118
+ rescue => e
119
+ handle_error e, false
104
120
  end
105
121
 
106
122
  end
@@ -3,15 +3,17 @@ module Angelo
3
3
 
4
4
  module Helpers
5
5
 
6
- HTTP_URL = 'http://%s:%d'.freeze
7
- WS_URL = 'ws://%s:%d'.freeze
6
+ HTTP_URL = 'http://%s:%d'
7
+ WS_URL = 'ws://%s:%d'
8
8
 
9
9
  attr_reader :last_response
10
10
 
11
11
  def define_app &block
12
12
 
13
13
  before do
14
- app = Class.new Angelo::Base, &block
14
+ app = Class.new Angelo::Base
15
+ app.class_eval { content_type :html } # reset
16
+ app.class_eval &block
15
17
  @server = Angelo::Server.new app
16
18
  end
17
19
 
@@ -5,7 +5,7 @@ module Angelo
5
5
 
6
6
  def initialize base, host = '127.0.0.1', port = 4567
7
7
  @base = base
8
- info "Angelo #{VERSION} \"#{CODENAME}\""
8
+ info "Angelo #{VERSION}"
9
9
  info "listening on #{host}:#{port}"
10
10
  super host, port, &method(:on_connection)
11
11
  end
@@ -13,7 +13,7 @@ module Angelo
13
13
 
14
14
  module ClassMethods
15
15
 
16
- DEFAULT_LAYOUT = 'layout.html.erb'.freeze
16
+ DEFAULT_LAYOUT = 'layout.html.erb'
17
17
 
18
18
  def view_glob *glob
19
19
  File.join view_dir, *glob
@@ -1,4 +1,3 @@
1
1
  module Angelo
2
- CODENAME = 'Gunpowder Treason'
3
- VERSION = '0.0.7'
2
+ VERSION = '0.0.9'
4
3
  end
@@ -0,0 +1,92 @@
1
+ if RUBY_VERSION =~ /^2\./
2
+
3
+ require_relative '../spec_helper'
4
+ require 'angelo/mustermann'
5
+
6
+ TILT_MM_TEST_ROOT = File.expand_path '..', __FILE__
7
+
8
+ describe Angelo::Mustermann do
9
+
10
+ describe 'pattern matching' do
11
+
12
+ pattern = '/:foo/things/:bar'
13
+ let(:mm_pattern){ ::Mustermann.new(pattern) }
14
+
15
+ define_app do
16
+ include Angelo::Mustermann
17
+ content_type :json
18
+
19
+ get pattern do
20
+ params
21
+ end
22
+
23
+ [:post, :put].each do |m|
24
+ __send__ m, pattern do
25
+ params
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ it 'matches via mustermann routes objects' do
32
+ path = '/some/things/are_good'
33
+ get path
34
+ last_response_should_be_json mm_pattern.params(path)
35
+ end
36
+
37
+ it 'overrides query string params' do
38
+ path = '/some/things/are_good'
39
+ get path, foo: 'other', bar: 'are_bad'
40
+ last_response_should_be_json mm_pattern.params(path)
41
+ end
42
+
43
+ it 'overrides post body params' do
44
+ path = '/some/things/are_good'
45
+ headers = {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
46
+ [:post, :put].each do |m|
47
+ __send__ m, path, {foo: 'other', bar: 'are_bad'}.to_json, headers
48
+ last_response_should_be_json mm_pattern.params(path)
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ describe 'tilt/erb integration' do
55
+
56
+ define_app do
57
+ include Angelo::Tilt::ERB
58
+ include Angelo::Mustermann
59
+
60
+ @root = TILT_MM_TEST_ROOT
61
+
62
+ get '/:foo/things/:bar' do
63
+ @title = params[:foo]
64
+ @foo = 'bear'
65
+ erb :index, locals: {bar: params[:bar]}
66
+ end
67
+
68
+ end
69
+
70
+ it 'renders templates using mustermann params' do
71
+ get '/aardvark/things/alpaca'
72
+ expected = <<HTML
73
+ <!doctype html>
74
+ <html>
75
+ <head>
76
+ <title>aardvark</title>
77
+ </head>
78
+ <body>
79
+ foo - bear
80
+ locals :bar - alpaca
81
+
82
+ </body>
83
+ </html>
84
+ HTML
85
+ last_response_should_be_html expected
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -83,7 +83,7 @@ describe Angelo::WebsocketResponder do
83
83
 
84
84
  describe 'helper contexts' do
85
85
  let(:obj){ {'foo' => 'bar'} }
86
- let(:wait_for_block) { ->(client){ JSON.parse(client.recv).should eq obj}}
86
+ let(:wait_for_block){ ->(client){ JSON.parse(client.recv).should eq obj}}
87
87
 
88
88
  define_app do
89
89
 
@@ -113,4 +113,173 @@ describe Angelo::Base do
113
113
 
114
114
  end
115
115
 
116
+ describe 'content_type helper' do
117
+
118
+ describe 'when in route block' do
119
+
120
+ define_app do
121
+ Angelo::HTTPABLE.each do |m|
122
+
123
+ __send__ m, '/html' do
124
+ content_type :html
125
+ '<html><body>hi</body></html>'
126
+ end
127
+
128
+ __send__ m, '/bad_html_h' do
129
+ content_type :html
130
+ {hi: 'there'}
131
+ end
132
+
133
+ __send__ m, '/json' do
134
+ content_type :json
135
+ {hi: 'there'}
136
+ end
137
+
138
+ __send__ m, '/json_s' do
139
+ content_type :json
140
+ {woo: 'woo'}.to_json
141
+ end
142
+
143
+ __send__ m, '/bad_json_s' do
144
+ content_type :json
145
+ {hi: 'there'}.to_json.gsub /{/, 'so doge'
146
+ end
147
+
148
+ end
149
+ end
150
+
151
+ it 'sets html content type for current route' do
152
+ Angelo::HTTPABLE.each do |m|
153
+ __send__ m, '/html'
154
+ last_response_should_be_html '<html><body>hi</body></html>'
155
+ end
156
+ end
157
+
158
+ it 'sets json content type for current route and to_jsons hashes' do
159
+ Angelo::HTTPABLE.each do |m|
160
+ __send__ m, '/json'
161
+ last_response_should_be_json 'hi' => 'there'
162
+ end
163
+ end
164
+
165
+ it 'does not to_json strings' do
166
+ Angelo::HTTPABLE.each do |m|
167
+ __send__ m, '/json_s'
168
+ last_response_should_be_json 'woo' => 'woo'
169
+ end
170
+ end
171
+
172
+ it '500s on html hashes' do
173
+ Angelo::HTTPABLE.each do |m|
174
+ __send__ m, '/bad_html_h'
175
+ last_response.status.should eq 500
176
+ end
177
+ end
178
+
179
+ it '500s on bad json strings' do
180
+ Angelo::HTTPABLE.each do |m|
181
+ __send__ m, '/bad_json_s'
182
+ last_response.status.should eq 500
183
+ end
184
+ end
185
+
186
+ end
187
+
188
+ describe 'when in class def' do
189
+
190
+ describe 'html type' do
191
+
192
+ define_app do
193
+ content_type :html
194
+ Angelo::HTTPABLE.each do |m|
195
+ __send__ m, '/html' do
196
+ '<html><body>hi</body></html>'
197
+ end
198
+ end
199
+ end
200
+
201
+ it 'sets default content type' do
202
+ Angelo::HTTPABLE.each do |m|
203
+ __send__ m, '/html'
204
+ last_response_should_be_html '<html><body>hi</body></html>'
205
+ end
206
+ end
207
+
208
+ end
209
+
210
+ describe 'json type' do
211
+
212
+ define_app do
213
+ content_type :json
214
+ Angelo::HTTPABLE.each do |m|
215
+ __send__ m, '/json' do
216
+ {hi: 'there'}
217
+ end
218
+ end
219
+ end
220
+
221
+ it 'sets default content type' do
222
+ Angelo::HTTPABLE.each do |m|
223
+ __send__ m, '/json'
224
+ last_response_should_be_json 'hi' => 'there'
225
+ end
226
+ end
227
+ end
228
+
229
+ end
230
+
231
+ describe 'when in both' do
232
+
233
+ describe 'json in html' do
234
+
235
+ define_app do
236
+ content_type :html
237
+ Angelo::HTTPABLE.each do |m|
238
+ __send__ m, '/json' do
239
+ content_type :json
240
+ {hi: 'there'}
241
+ end
242
+ end
243
+ end
244
+
245
+ it 'sets html content type for current route when default is set json' do
246
+ Angelo::HTTPABLE.each do |m|
247
+ __send__ m, '/json'
248
+ last_response_should_be_json 'hi' => 'there'
249
+ end
250
+ end
251
+
252
+ end
253
+
254
+ describe 'html in json' do
255
+
256
+ define_app do
257
+ content_type :json
258
+ Angelo::HTTPABLE.each do |m|
259
+ __send__ m, '/html' do
260
+ content_type :html
261
+ '<html><body>hi</body></html>'
262
+ end
263
+ end
264
+ end
265
+
266
+ it 'sets json content type for current route when default is set html' do
267
+ Angelo::HTTPABLE.each do |m|
268
+ __send__ m, '/html'
269
+ last_response_should_be_html '<html><body>hi</body></html>'
270
+ end
271
+ end
272
+
273
+ end
274
+
275
+ end
276
+
277
+ end
278
+
279
+ describe 'params helper' do
280
+ end
281
+
282
+ describe 'websockets helper' do
283
+ end
284
+
116
285
  end
metadata CHANGED
@@ -1,30 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: angelo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
5
- prerelease:
4
+ version: 0.0.9
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kenichi Nakamura
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-11-05 00:00:00.000000000 Z
11
+ date: 2014-02-20 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: reel
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
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
  description: A Sinatra-esque DSL for Reel
@@ -36,13 +33,14 @@ extra_rdoc_files: []
36
33
  files:
37
34
  - .gitignore
38
35
  - .travis.yml
39
- - CHANGELOG
36
+ - CHANGELOG.md
40
37
  - Gemfile
41
38
  - LICENSE
42
39
  - README.md
43
40
  - angelo.gemspec
44
41
  - lib/angelo.rb
45
42
  - lib/angelo/base.rb
43
+ - lib/angelo/mustermann.rb
46
44
  - lib/angelo/params_parser.rb
47
45
  - lib/angelo/responder.rb
48
46
  - lib/angelo/responder/websocket.rb
@@ -51,6 +49,7 @@ files:
51
49
  - lib/angelo/tilt/erb.rb
52
50
  - lib/angelo/version.rb
53
51
  - spec/angelo/erb_spec.rb
52
+ - spec/angelo/mustermann_spec.rb
54
53
  - spec/angelo/params_spec.rb
55
54
  - spec/angelo/views/index.html.erb
56
55
  - spec/angelo/views/layout.html.erb
@@ -60,33 +59,34 @@ files:
60
59
  homepage: https://github.com/kenichi/angelo
61
60
  licenses:
62
61
  - apache
62
+ metadata: {}
63
63
  post_install_message:
64
64
  rdoc_options: []
65
65
  require_paths:
66
66
  - lib
67
67
  required_ruby_version: !ruby/object:Gem::Requirement
68
- none: false
69
68
  requirements:
70
- - - ! '>='
69
+ - - '>='
71
70
  - !ruby/object:Gem::Version
72
71
  version: '0'
73
72
  required_rubygems_version: !ruby/object:Gem::Requirement
74
- none: false
75
73
  requirements:
76
- - - ! '>='
74
+ - - '>='
77
75
  - !ruby/object:Gem::Version
78
76
  version: '0'
79
77
  requirements: []
80
78
  rubyforge_project:
81
- rubygems_version: 1.8.23
79
+ rubygems_version: 2.0.14
82
80
  signing_key:
83
- specification_version: 3
81
+ specification_version: 4
84
82
  summary: A Sinatra-esque DSL for Reel
85
83
  test_files:
86
84
  - spec/angelo/erb_spec.rb
85
+ - spec/angelo/mustermann_spec.rb
87
86
  - spec/angelo/params_spec.rb
88
87
  - spec/angelo/views/index.html.erb
89
88
  - spec/angelo/views/layout.html.erb
90
89
  - spec/angelo/websocket_spec.rb
91
90
  - spec/angelo_spec.rb
92
91
  - spec/spec_helper.rb
92
+ has_rdoc: