hobby 0.0.12 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2d2d480ccdf4a60839072589bfaa58309a00bf4a
4
- data.tar.gz: e69b2439193e69c2f53adc780dac6666f71a01e6
2
+ SHA256:
3
+ metadata.gz: f7a734e16047e8e04ef87e68c1e20cb376dbaee578b756fb888244c6603d7c25
4
+ data.tar.gz: f0e946385562830eed6e1af944afe587ff3ae8957e7f1e268652a4223a2f89b5
5
5
  SHA512:
6
- metadata.gz: ff31f1f11344235dec85b8d021008a1b89a18ab65b8e4743add83b8e8e8e3104af567c8bdb01a5e84d6a78c5c9248a95272e3de7f3ac88fc6c60180a3e7266ee
7
- data.tar.gz: 723ba318c713c9d21c44c3bf8397e48a7204a562c7294545aedd7a26634a402887269878618cc61e91b3a2dcbe3454a0aa590dfde07f1cc51532c0d8123a0f2f
6
+ metadata.gz: c13de4d63efe75751e854d610e4cda08b658cd80f889b3e3d8e5e9b62d80f50ed2efa9dadcb91926b6669fb462ddf882d77fda11674d4b0c563debed8be1b0ed
7
+ data.tar.gz: 251399b7b9ca7340e843c6ce33c1dbf3ebe3a90ec50d62bba030e71a282c49e512c60a589e95613bd41d5c5b82b2adf9abe1adaa2f42d4f205cae8b45f4fe5f3
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  language: ruby
3
3
  rvm:
4
+ - 2.5
4
5
  - 2.4
5
6
  - 2.3
6
7
  script: bundle exec rspec
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'devtools', github: 'mbj/devtools'
4
- gem 'mutant', github: 'mbj/mutant'
3
+ gem 'devtools'
4
+ gem 'mutant'
5
5
  gem 'minitest'
6
6
  gem 'minitest-power_assert'
7
7
  gem 'rack-test'
data/hobby.gemspec CHANGED
@@ -4,10 +4,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'hobby'
7
- spec.version = '0.0.12'
7
+ spec.version = '0.2.0'
8
8
  spec.authors = ['Anatoly Chernow']
9
9
  spec.email = ['chertoly@gmail.com']
10
- spec.summary = %q{A minimal DSL over rack}
10
+ spec.summary = %q{A professional way to create Rack applications.}
11
11
  spec.homepage = 'https://github.com/ch1c0t/hobby'
12
12
  spec.license = 'MIT'
13
13
 
@@ -16,5 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
17
  spec.require_paths = ['lib']
18
18
 
19
- spec.add_dependency 'rack'
19
+ spec.add_dependency 'rack', '>= 2'
20
+
21
+ spec.required_ruby_version = '>= 2.6.6'
20
22
  end
data/lib/hobby.rb CHANGED
@@ -10,20 +10,19 @@ module Hobby
10
10
 
11
11
  def self.included app
12
12
  app.extend Singleton
13
- app.builder, app.router = Rack::Builder.new, Router.new
13
+ app.router = Router.new
14
14
  app.request, app.response = Rack::Request, Rack::Response
15
15
  end
16
16
 
17
17
  module Singleton
18
- attr_accessor :builder, :router, :request, :response
18
+ attr_accessor :router, :request, :response
19
19
 
20
20
  def new (*)
21
- builder.run super
22
- builder.to_app
21
+ super.router.to_rack_app
23
22
  end
24
23
 
25
24
  extend Forwardable
26
- delegate [:map, :use] => :builder
25
+ delegate [:map, :use] => :router
27
26
 
28
27
  VERBS.each do |verb|
29
28
  define_method verb.downcase do |path = '/', &action|
@@ -41,9 +40,9 @@ module Hobby
41
40
  protected
42
41
  def handle env
43
42
  catch :halt do
44
- @route = self.class.router.route_for (@env = env)
43
+ @route = router.route_for (@env = env)
45
44
  fill_body
46
- response
45
+ response.to_a
47
46
  end
48
47
  end
49
48
 
data/lib/hobby/helpers.rb CHANGED
@@ -1,7 +1,19 @@
1
1
  module Hobby
2
2
  module Helpers
3
+ extend Forwardable
4
+
3
5
  attr_reader :env, :route
4
6
 
7
+ def router
8
+ @router ||= begin
9
+ router = self.class.router.clone
10
+ router.app = self
11
+ router
12
+ end
13
+ end
14
+
15
+ delegate [:map, :use] => :router
16
+
5
17
  def request
6
18
  @request ||= self.class.request.new env
7
19
  end
@@ -15,7 +27,7 @@ module Hobby
15
27
  end
16
28
 
17
29
  def halt
18
- throw :halt, response
30
+ throw :halt, response.to_a
19
31
  end
20
32
 
21
33
  def not_found
@@ -30,5 +42,9 @@ module Hobby
30
42
  def status status
31
43
  response.status = status
32
44
  end
45
+
46
+ def script_name
47
+ env.fetch 'SCRIPT_NAME'
48
+ end
33
49
  end
34
50
  end
data/lib/hobby/router.rb CHANGED
@@ -2,6 +2,11 @@ module Hobby
2
2
  class Router
3
3
  def initialize
4
4
  @routes = Routes.new
5
+ @uses, @maps = [], []
6
+ end
7
+
8
+ def initialize_copy _router
9
+ @uses, @maps = @uses.dup, @maps.dup
5
10
  end
6
11
 
7
12
  def add_route verb, path, &action
@@ -17,8 +22,33 @@ module Hobby
17
22
  route, params = @routes["#{env['REQUEST_METHOD']}#{env['PATH_INFO']}"]
18
23
  params ? route.with_params(params) : route
19
24
  end
25
+
26
+ def use *all
27
+ @uses << all
28
+ end
29
+
30
+ def map path, app = nil, &block
31
+ @maps << Builder::Map.new(path, app, &block)
32
+ end
33
+
34
+ attr_accessor :app
35
+
36
+ def to_rack_app
37
+ builder = create_builder
38
+ builder.run app
39
+ builder.to_app
40
+ end
41
+
42
+ private
43
+ def create_builder
44
+ builder = Builder.new
45
+ @uses.each { |all| builder.add_use *all }
46
+ @maps.each { |map| builder.add_map map }
47
+ builder
48
+ end
20
49
  end
21
50
  end
22
51
 
52
+ require 'hobby/router/builder'
23
53
  require 'hobby/router/routes'
24
54
  require 'hobby/router/route'
@@ -0,0 +1,25 @@
1
+ module Hobby
2
+ class Router
3
+ class Builder < Rack::Builder
4
+ # To work around
5
+ # https://github.com/mbj/mutant#the-crash--stuck-problem-mri
6
+ alias add_use use
7
+ alias add_map2 map
8
+
9
+ def add_map map
10
+ if map.app
11
+ add_map2 map.path do run map.app end
12
+ else
13
+ add_map2 map.path, &map.block
14
+ end
15
+ end
16
+
17
+ class Map
18
+ attr_reader :path, :app, :block
19
+ def initialize path, app, &block
20
+ @path, @app, @block = path, app, block
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
data/readme.adoc CHANGED
@@ -27,8 +27,16 @@ $ gem install hobby
27
27
  [[introduction]]
28
28
  == Introduction
29
29
 
30
- Hobby features a Sinatra-like DSL, but in contrast to Sinatra,
31
- Hobby applications behave like usual Ruby classes.
30
+ Hobby provides a Ruby DSL to create web applications. It is well suited both for standalone and inside-Rails use.
31
+
32
+ The DSL looks a lot like Sinatra, but Hobby applications are
33
+
34
+ * more reusable
35
+ * more reliable
36
+ +
37
+ The API and the codebase are much smaller and fully covered with specs. 100% mutation coverage is constantly maintained.
38
+ * https://github.com/luislavena/bench-micro#requestssec[more performant]
39
+ * https://github.com/luislavena/bench-micro#memory-allocationrequest[consume less resources]
32
40
 
33
41
  To create a Hobby application, you create a class and include `Hobby` in it.
34
42
  For example:
@@ -40,9 +48,9 @@ require 'hobby'
40
48
  class C
41
49
  include Hobby
42
50
 
43
- get("/hello") {
51
+ get "/hello" do
44
52
  "Hello, world."
45
- }
53
+ end
46
54
  end
47
55
  ----
48
56
 
@@ -74,9 +82,9 @@ class C
74
82
  @name = name
75
83
  end
76
84
 
77
- get("/hello") {
85
+ get "/hello" do
78
86
  "Hello, #{@name}."
79
- }
87
+ end
80
88
  end
81
89
  ----
82
90
 
@@ -95,9 +103,9 @@ class C
95
103
  @name.upcase
96
104
  end
97
105
 
98
- get("/hello") {
106
+ get "/hello" do
99
107
  "Hello, #{name}."
100
- }
108
+ end
101
109
  end
102
110
  ----
103
111
 
@@ -133,29 +141,12 @@ For common HTTP verbs, Hobby provides the route definers(methods named according
133
141
  class App
134
142
  include Hobby
135
143
 
136
- get '/' do
137
- # ...
138
- end
139
-
140
- post '/' do
141
- # ...
142
- end
143
-
144
- put '/' do
145
- # ...
146
- end
147
-
148
- patch '/' do
149
- # ...
150
- end
151
-
152
- delete '/' do
153
- # ...
154
- end
155
-
156
- options '/' do
157
- # ...
158
- end
144
+ get { 'Some string.' }
145
+ post { 'Some string.' }
146
+ put { 'Some string.' }
147
+ patch { 'Some string.' }
148
+ delete { 'Some string.' }
149
+ # TODO: find a good example for `options`
159
150
  end
160
151
  ----
161
152
 
@@ -285,8 +276,8 @@ to '/anatoly' and '/patricio' routes:
285
276
  class App
286
277
  include Hobby
287
278
 
288
- map('/anatoly') { run C.new 'Anatoly' }
289
- map('/patricio') { run C.new 'Patricio' }
279
+ map '/anatoly', C.new('Anatoly')
280
+ map '/patricio', C.new('Patricio')
290
281
 
291
282
  get '/' do
292
283
  'Mapping app.'
@@ -327,7 +318,6 @@ Many components of an application can be customized or replaced.
327
318
  class App
328
319
  include Hobby
329
320
 
330
- self.builder = custom_builder
331
321
  self.router = custom_router
332
322
  self.request = custom_request
333
323
  self.response = custom_response
@@ -350,5 +340,5 @@ To perform mutation analysis:
350
340
 
351
341
  [source,bash]
352
342
  ----
353
- bundle exec mutant --use rspec 'Hobby*'
343
+ bundle exec mutant --use rspec 'Hobby*' --include lib --require hobby
354
344
  ----
data/spec/app_spec.rb CHANGED
@@ -75,6 +75,17 @@ describe Hobby::App do
75
75
  end
76
76
  end
77
77
 
78
+ describe '#router' do
79
+ it 'gives a distinct router to each app' do
80
+ app = Class.new { include Hobby }
81
+
82
+ first_instance = app.new
83
+ second_instance = app.new
84
+
85
+ assert { not first_instance.router.equal? second_instance.router }
86
+ end
87
+ end
88
+
78
89
  describe :integration do
79
90
  before do
80
91
  described_class.app = build_app described_class
@@ -89,6 +100,51 @@ describe Hobby::App do
89
100
  get '/map'
90
101
  assert { last_response.body == 'from map' }
91
102
  end
103
+
104
+ it 'mounts an application to the rack stack with old deprecated syntax' do
105
+ get '/deprecated_map'
106
+ assert { last_response.body == 'from deprecated map' }
107
+ end
108
+ end
109
+
110
+ describe MapInsideInitialize do
111
+ describe 'without any passed arguments' do
112
+ def app
113
+ described_class.app.new
114
+ end
115
+
116
+ it do
117
+ get '/'
118
+ assert { last_response.body == 'hello world' }
119
+ get '/first_map'
120
+ assert { last_response.body == 'first mapapp' }
121
+ get '/second_map'
122
+ assert { last_response.body == 'second mapapp' }
123
+ end
124
+ end
125
+
126
+ describe 'with passed routes' do
127
+ def app
128
+ some_app = Class.new {
129
+ include Hobby
130
+ get { 'Some string.' }
131
+ }
132
+ routes = { '/third_map' => some_app.new }
133
+ described_class.app.new routes
134
+ end
135
+
136
+ it do
137
+ get '/'
138
+ assert { last_response.body == 'hello world' }
139
+ get '/first_map'
140
+ assert { last_response.body == 'first mapapp' }
141
+ get '/second_map'
142
+ assert { last_response.body == 'second mapapp' }
143
+
144
+ get '/third_map'
145
+ assert { last_response.body == 'Some string.' }
146
+ end
147
+ end
92
148
  end
93
149
 
94
150
  describe Use do
@@ -98,6 +154,13 @@ describe Hobby::App do
98
154
  end
99
155
  end
100
156
 
157
+ describe UseInsideInitialize do
158
+ it do
159
+ get '/'
160
+ assert { last_response.content_type == 'application/json' }
161
+ end
162
+ end
163
+
101
164
  describe WithoutPath do
102
165
  it 'is accessible as /' do
103
166
  get '/'
@@ -171,5 +234,53 @@ describe Hobby::App do
171
234
  assert { last_response.body == 'Created.' }
172
235
  end
173
236
  end
237
+
238
+ describe UnshareableRouterMaps do
239
+ it do
240
+ get '/1/first'
241
+ assert { last_response.body == 'The name is A.' }
242
+ get '/1/second'
243
+ assert { last_response.body == 'The name is B.' }
244
+ get '/1/third'
245
+ assert { last_response.body == '404' }
246
+
247
+ get '/2/first'
248
+ assert { last_response.body == 'The name is A.' }
249
+ get '/2/second'
250
+ assert { last_response.body == 'The name is B.' }
251
+ get '/2/third'
252
+ assert { last_response.body == 'The name is C.' }
253
+
254
+ get '/3/first'
255
+ assert { last_response.body == 'The name is A.' }
256
+ get '/3/second'
257
+ assert { last_response.body == 'The name is B.' }
258
+ get '/3/third'
259
+ assert { last_response.body == '404' }
260
+ end
261
+ end
262
+
263
+ describe UnshareableRouterUses do
264
+ it do
265
+ get '/1'
266
+ assert { last_response.content_type == 'application/html' }
267
+
268
+ get '/2'
269
+ assert { last_response.content_type == 'application/json' }
270
+
271
+ get '/3'
272
+ assert { last_response.content_type == 'application/html' }
273
+ end
274
+ end
275
+
276
+ describe ScriptName do
277
+ it do
278
+ get '/'
279
+ assert { last_response.body == '' }
280
+
281
+ get '/some/path'
282
+ assert { last_response.body == '/some/path' }
283
+ end
284
+ end
174
285
  end
175
286
  end
data/spec/apps/Map.rb CHANGED
@@ -1,5 +1,5 @@
1
- map '/map' do
2
- run Proc.new { |env| [200, {}, ['from map']] }
1
+ map '/map', Proc.new { |env| [200, {}, ['from map']] }
2
+ map '/deprecated_map' do
3
+ run Proc.new { |env| [200, {}, ['from deprecated map']] }
3
4
  end
4
-
5
5
  get('/') { 'hello world' }
@@ -0,0 +1,13 @@
1
+ first_app = Proc.new { |env| [200, {}, ['first mapapp']] }
2
+ second_app = Proc.new { |env| [200, {}, ['second mapapp']] }
3
+
4
+ map '/first_map', first_app
5
+ map '/second_map', second_app
6
+
7
+ get('/') { 'hello world' }
8
+
9
+ def initialize hash = {}
10
+ hash.each do |route, app|
11
+ map route, app
12
+ end
13
+ end
data/spec/apps/Nested.rb CHANGED
@@ -1,17 +1,15 @@
1
- map('/nested') do
2
- nested_app = Class.new do
3
- include Hobby::App
1
+ nested_app = Class.new do
2
+ include Hobby::App
4
3
 
5
- def initialize first, second
6
- @a = first
7
- @b = second
8
- @c = yield
9
- end
10
-
11
- get do
12
- "#{@a}:#{@b}:#{@c}"
13
- end
4
+ def initialize first, second
5
+ @a = first
6
+ @b = second
7
+ @c = yield
14
8
  end
15
9
 
16
- run nested_app.new(:a, :b) { :c }
10
+ get do
11
+ "#{@a}:#{@b}:#{@c}"
12
+ end
17
13
  end
14
+
15
+ map '/nested', nested_app.new(:a, :b) { :c }
@@ -5,4 +5,12 @@ self.router = Class.new {
5
5
  def route_for _request
6
6
  -> { 'for any route' }
7
7
  end
8
+
9
+ attr_accessor :app
10
+
11
+ def to_rack_app
12
+ builder = Rack::Builder.new
13
+ builder.run app
14
+ builder.to_app
15
+ end
8
16
  }.new
@@ -0,0 +1,12 @@
1
+ get do
2
+ script_name
3
+ end
4
+
5
+ app = Class.new do
6
+ include Hobby
7
+ get do
8
+ script_name
9
+ end
10
+ end
11
+
12
+ map '/some/path', app.new
@@ -0,0 +1,29 @@
1
+ mapped_app = Class.new do
2
+ include Hobby
3
+
4
+ def initialize name
5
+ @name = name
6
+ end
7
+
8
+ get { "The name is #{@name}." }
9
+ end
10
+
11
+ mapping_app = Class.new do
12
+ include Hobby
13
+
14
+ map '/first', mapped_app.new('A')
15
+ map '/second', mapped_app.new('B')
16
+
17
+ def initialize routes = {}
18
+ routes.each do |route, app|
19
+ map route, app
20
+ end
21
+ end
22
+ end
23
+
24
+ map '/1', mapping_app.new
25
+
26
+ routes = { '/third' => mapped_app.new('C') }
27
+ map '/2', mapping_app.new(routes)
28
+
29
+ map '/3', mapping_app.new
@@ -0,0 +1,16 @@
1
+ require 'json'
2
+
3
+ app = Class.new do
4
+ include Hobby
5
+ get { 'hello world'.to_json }
6
+
7
+ use Rack::ContentType, 'application/html'
8
+
9
+ def initialize middleware_with_arguments = nil
10
+ use *middleware_with_arguments if middleware_with_arguments
11
+ end
12
+ end
13
+
14
+ map '/1', app.new
15
+ map '/2', app.new([Rack::ContentType, 'application/json'])
16
+ map '/3', app.new
@@ -0,0 +1,7 @@
1
+ require 'json'
2
+
3
+ get { 'hello world'.to_json }
4
+
5
+ def initialize
6
+ use Rack::ContentType, 'application/json'
7
+ end
data/spec/helper.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  require 'devtools/spec_helper'
2
2
 
3
3
  require 'hobby'
4
+ require_relative 'mutant_patches' if defined? Mutant
4
5
 
5
6
  require 'minitest'
6
7
  require 'minitest-power_assert'
7
8
  Minitest::Assertions.prepend Minitest::PowerAssert::Assertions
8
9
 
9
- if defined? Mutant
10
- class Mutant::Selector::Expression
11
- def call _subject
12
- integration.all_tests
13
- end
10
+ module EnvFor
11
+ def env_for path, verb = 'GET'
12
+ {'REQUEST_METHOD' => verb, 'PATH_INFO' => path }
14
13
  end
15
14
  end
16
15
 
17
16
  RSpec.configure do |config|
18
17
  config.expect_with :rspec, :minitest
18
+ config.include EnvFor
19
19
  end
@@ -0,0 +1,27 @@
1
+ # Run all the specs for any subject.
2
+ class Mutant::Selector::Expression
3
+ def call _subject
4
+ integration.all_tests
5
+ end
6
+ end
7
+
8
+ # Do not silence stdout and stderr of the running mutation.
9
+ class Mutant::Isolation::Fork
10
+ def result
11
+ yield
12
+ end
13
+ end
14
+
15
+ # Print the source of the current mutation.
16
+ class Mutant::Loader
17
+ def call
18
+ source = Unparser.unparse node
19
+
20
+ puts <<~S
21
+ Current mutation:
22
+ #{source}
23
+ S
24
+
25
+ kernel.eval source, binding, subject.source_path.to_s, subject.source_line
26
+ end
27
+ end
@@ -2,10 +2,6 @@ module RouterMatchers
2
2
  extend self
3
3
  SOME_ROUTE = ->{:some_route}
4
4
 
5
- def env_for path, verb = 'GET'
6
- {'REQUEST_METHOD' => verb, 'PATH_INFO' => path }
7
- end
8
-
9
5
  def add_routes *routes
10
6
  routes.each { |route| subject.add_route 'GET', route, &SOME_ROUTE }
11
7
  end
@@ -22,7 +18,7 @@ module RouterMatchers
22
18
  route && (route.to_proc.call == SOME_ROUTE.call) && params_are_ok
23
19
  end
24
20
 
25
- chain :and_set_params do |**params|
21
+ chain :and_set_params do |params|
26
22
  @params = params
27
23
  end
28
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hobby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anatoly Chernow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-23 00:00:00.000000000 Z
11
+ date: 2021-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '2'
27
27
  description:
28
28
  email:
29
29
  - chertoly@gmail.com
@@ -39,6 +39,7 @@ files:
39
39
  - lib/hobby.rb
40
40
  - lib/hobby/helpers.rb
41
41
  - lib/hobby/router.rb
42
+ - lib/hobby/router/builder.rb
42
43
  - lib/hobby/router/route.rb
43
44
  - lib/hobby/router/routes.rb
44
45
  - readme.adoc
@@ -49,12 +50,18 @@ files:
49
50
  - spec/apps/Halting.rb
50
51
  - spec/apps/Main.rb
51
52
  - spec/apps/Map.rb
53
+ - spec/apps/MapInsideInitialize.rb
52
54
  - spec/apps/Nested.rb
53
55
  - spec/apps/OneRouteRouter.rb
56
+ - spec/apps/ScriptName.rb
54
57
  - spec/apps/Status.rb
58
+ - spec/apps/UnshareableRouterMaps.rb
59
+ - spec/apps/UnshareableRouterUses.rb
55
60
  - spec/apps/Use.rb
61
+ - spec/apps/UseInsideInitialize.rb
56
62
  - spec/apps/WithoutPath.rb
57
63
  - spec/helper.rb
64
+ - spec/mutant_patches.rb
58
65
  - spec/router_matchers.rb
59
66
  - spec/router_spec.rb
60
67
  homepage: https://github.com/ch1c0t/hobby
@@ -69,18 +76,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
76
  requirements:
70
77
  - - ">="
71
78
  - !ruby/object:Gem::Version
72
- version: '0'
79
+ version: 2.6.6
73
80
  required_rubygems_version: !ruby/object:Gem::Requirement
74
81
  requirements:
75
82
  - - ">="
76
83
  - !ruby/object:Gem::Version
77
84
  version: '0'
78
85
  requirements: []
79
- rubyforge_project:
80
- rubygems_version: 2.6.11
86
+ rubygems_version: 3.2.3
81
87
  signing_key:
82
88
  specification_version: 4
83
- summary: A minimal DSL over rack
89
+ summary: A professional way to create Rack applications.
84
90
  test_files:
85
91
  - spec/app_spec.rb
86
92
  - spec/apps/ContentType.rb
@@ -89,11 +95,17 @@ test_files:
89
95
  - spec/apps/Halting.rb
90
96
  - spec/apps/Main.rb
91
97
  - spec/apps/Map.rb
98
+ - spec/apps/MapInsideInitialize.rb
92
99
  - spec/apps/Nested.rb
93
100
  - spec/apps/OneRouteRouter.rb
101
+ - spec/apps/ScriptName.rb
94
102
  - spec/apps/Status.rb
103
+ - spec/apps/UnshareableRouterMaps.rb
104
+ - spec/apps/UnshareableRouterUses.rb
95
105
  - spec/apps/Use.rb
106
+ - spec/apps/UseInsideInitialize.rb
96
107
  - spec/apps/WithoutPath.rb
97
108
  - spec/helper.rb
109
+ - spec/mutant_patches.rb
98
110
  - spec/router_matchers.rb
99
111
  - spec/router_spec.rb