rutter 0.1.2 → 0.2.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 +5 -5
- data/.gitignore +2 -0
- data/.rubocop.yml +14 -4
- data/.travis.yml +12 -2
- data/Gemfile +4 -1
- data/LICENSE.txt +1 -1
- data/README.md +17 -102
- data/Rakefile +7 -1
- data/bench/config.ru +10 -9
- data/lib/rutter.rb +10 -7
- data/lib/rutter/builder.rb +180 -221
- data/lib/rutter/mount.rb +21 -0
- data/lib/rutter/naming.rb +95 -0
- data/lib/rutter/route.rb +69 -126
- data/lib/rutter/routes.rb +36 -9
- data/lib/rutter/scope.rb +39 -40
- data/lib/rutter/verbs.rb +8 -0
- data/lib/rutter/version.rb +1 -1
- data/rutter.gemspec +4 -3
- data/spec/integration/rack_spec.rb +21 -13
- data/spec/spec_helper.rb +6 -48
- data/spec/support/rack.rb +20 -0
- data/spec/unit/builder_spec.rb +86 -74
- data/spec/unit/namespace_spec.rb +26 -0
- data/spec/unit/route_spec.rb +33 -50
- data/spec/unit/routes_spec.rb +20 -11
- data/spec/unit/rutter_spec.rb +3 -2
- data/spec/unit/scope_spec.rb +49 -56
- metadata +25 -17
- data/bench/dynamic_routes +0 -20
- data/bench/expand +0 -19
- data/bench/helper.rb +0 -19
- data/bench/mount +0 -32
- data/bench/routes_helper +0 -24
- data/bench/static_routes +0 -20
- data/spec/integration/mount_spec.rb +0 -18
- data/spec/integration/params_spec.rb +0 -28
- data/spec/integration/redirect_spec.rb +0 -36
data/spec/unit/routes_spec.rb
CHANGED
@@ -2,22 +2,27 @@
|
|
2
2
|
|
3
3
|
module Rutter
|
4
4
|
RSpec.describe Routes do
|
5
|
-
let(:router) {
|
5
|
+
let(:router) { Rutter.new }
|
6
6
|
let(:routes) { Routes.new(router) }
|
7
|
+
let(:endpoint) { ->(_) {} }
|
7
8
|
|
8
9
|
it "has a *_path helper method" do
|
9
|
-
router.get "/books/:id", to:
|
10
|
-
|
10
|
+
router.get "/books/:id", to: endpoint, as: :book
|
11
|
+
|
12
|
+
expect(routes.book_path(id: 54))
|
13
|
+
.to eq("/books/54")
|
11
14
|
end
|
12
15
|
|
13
16
|
it "has a *_url helper method" do
|
14
|
-
router.get "/books/:id", to:
|
15
|
-
|
17
|
+
router.get "/books/:id", to: endpoint, as: :book
|
18
|
+
|
19
|
+
expect(routes.book_url(id: 54))
|
20
|
+
.to eq("http://localhost:9292/books/54")
|
16
21
|
end
|
17
22
|
|
18
|
-
it "raises
|
23
|
+
it "raises RuntimeError if route not found" do
|
19
24
|
expect { routes.invalid_path }
|
20
|
-
.to raise_error(
|
25
|
+
.to raise_error(RuntimeError)
|
21
26
|
end
|
22
27
|
|
23
28
|
it "raises NoMethodError if unknown method is called" do
|
@@ -26,10 +31,14 @@ module Rutter
|
|
26
31
|
end
|
27
32
|
|
28
33
|
it "support respond_to?" do
|
29
|
-
router.get "/books/:id", to:
|
30
|
-
|
31
|
-
expect(routes.respond_to?(:
|
32
|
-
|
34
|
+
router.get "/books/:id", to: endpoint, as: :book
|
35
|
+
|
36
|
+
expect(routes.respond_to?(:book))
|
37
|
+
.to eq(false)
|
38
|
+
expect(routes.respond_to?(:book_path))
|
39
|
+
.to eq(true)
|
40
|
+
expect(routes.respond_to?(:book_url))
|
41
|
+
.to eq(true)
|
33
42
|
end
|
34
43
|
end
|
35
44
|
end
|
data/spec/unit/rutter_spec.rb
CHANGED
data/spec/unit/scope_spec.rb
CHANGED
@@ -1,75 +1,68 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Rutter
|
4
|
-
RSpec.describe
|
5
|
-
let(:router) {
|
4
|
+
RSpec.describe Scope do
|
5
|
+
let(:router) { Rutter.new }
|
6
|
+
let(:endpoint) { ->(_) {} }
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
get "/
|
8
|
+
it "support nested scopes" do
|
9
|
+
router.scope path: "animals", namespace: "species", as: :animals do
|
10
|
+
scope path: "mammals", namespace: "mammals", as: :mammals do
|
11
|
+
get "/cats", to: "cats#index", as: :cats
|
11
12
|
end
|
12
|
-
|
13
|
-
route = router.flat_map.first
|
14
|
-
|
15
|
-
expect(route.path).to eq("/web/books")
|
16
|
-
expect(route.endpoint[:controller]).to eq("Web::Books")
|
17
13
|
end
|
18
14
|
|
19
|
-
|
20
|
-
router.scope path: "/admin", namespace: "Secure", as: :koolaid do
|
21
|
-
get "/", to: ->(env) {}
|
22
|
-
post "/", to: ->(env) {}
|
23
|
-
put "/", to: ->(env) {}
|
24
|
-
patch "/", to: ->(env) {}
|
25
|
-
delete "/", to: ->(env) {}
|
26
|
-
options "/", to: ->(env) {}
|
27
|
-
head "/", to: ->(env) {}
|
28
|
-
trace "/", to: ->(env) {}
|
29
|
-
end
|
15
|
+
route = router.flat_map.first
|
30
16
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
expect(router.flat_map[7].method).to eq("TRACE")
|
39
|
-
end
|
17
|
+
expect(route.path)
|
18
|
+
.to eq("/animals/mammals/cats")
|
19
|
+
expect(route.endpoint)
|
20
|
+
.to eq(controller: "Species::Mammals::Cats", action: "index")
|
21
|
+
expect(router.named_map[:animals_mammals_cats])
|
22
|
+
.to eq(route)
|
23
|
+
end
|
40
24
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
25
|
+
describe "#add" do
|
26
|
+
it "support using route constraints" do
|
27
|
+
scope = router.scope path: "/books"
|
28
|
+
route = scope.get "/:id",
|
29
|
+
to: endpoint,
|
30
|
+
constraints: { id: /\d+/ }
|
46
31
|
|
47
|
-
|
48
|
-
|
49
|
-
|
32
|
+
expect(route.match?(env_for("/books/82")))
|
33
|
+
.to be(true)
|
34
|
+
expect(route.match?(env_for("/books/pickaxe")))
|
35
|
+
.to be(false)
|
50
36
|
end
|
37
|
+
end
|
51
38
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
route = router.flat_map.first
|
39
|
+
describe "#mount" do
|
40
|
+
it "matches path prefixes" do
|
41
|
+
scope = router.scope path: "/api"
|
42
|
+
route = scope.mount endpoint, at: "/v1"
|
60
43
|
|
61
|
-
expect(route.
|
62
|
-
|
63
|
-
expect(route.
|
64
|
-
|
44
|
+
expect(route.match?(env_for("/")))
|
45
|
+
.to be_nil
|
46
|
+
expect(route.match?(env_for("/api")))
|
47
|
+
.to be_nil
|
48
|
+
expect(route.match?(env_for("/api/v1")))
|
49
|
+
.to eq("/api/v1")
|
50
|
+
expect(route.match?(env_for("/api/v1/books")))
|
51
|
+
.to eq("/api/v1")
|
65
52
|
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "verbs" do
|
56
|
+
let(:scope) { router.scope }
|
66
57
|
|
67
|
-
|
68
|
-
|
69
|
-
|
58
|
+
VERBS.each do |verb|
|
59
|
+
describe "##{verb.downcase}" do
|
60
|
+
it "recognize #{verb} verb" do
|
61
|
+
route = scope.public_send verb.downcase, "/", to: endpoint
|
70
62
|
|
71
|
-
|
72
|
-
|
63
|
+
expect(router.verb_map[verb])
|
64
|
+
.to eq([route])
|
65
|
+
end
|
73
66
|
end
|
74
67
|
end
|
75
68
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rutter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Sandelius
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mustermann
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rack
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,25 +110,21 @@ files:
|
|
96
110
|
- README.md
|
97
111
|
- Rakefile
|
98
112
|
- bench/config.ru
|
99
|
-
- bench/dynamic_routes
|
100
|
-
- bench/expand
|
101
|
-
- bench/helper.rb
|
102
|
-
- bench/mount
|
103
|
-
- bench/routes_helper
|
104
|
-
- bench/static_routes
|
105
113
|
- lib/rutter.rb
|
106
114
|
- lib/rutter/builder.rb
|
115
|
+
- lib/rutter/mount.rb
|
116
|
+
- lib/rutter/naming.rb
|
107
117
|
- lib/rutter/route.rb
|
108
118
|
- lib/rutter/routes.rb
|
109
119
|
- lib/rutter/scope.rb
|
120
|
+
- lib/rutter/verbs.rb
|
110
121
|
- lib/rutter/version.rb
|
111
122
|
- rutter.gemspec
|
112
|
-
- spec/integration/mount_spec.rb
|
113
|
-
- spec/integration/params_spec.rb
|
114
123
|
- spec/integration/rack_spec.rb
|
115
|
-
- spec/integration/redirect_spec.rb
|
116
124
|
- spec/spec_helper.rb
|
125
|
+
- spec/support/rack.rb
|
117
126
|
- spec/unit/builder_spec.rb
|
127
|
+
- spec/unit/namespace_spec.rb
|
118
128
|
- spec/unit/route_spec.rb
|
119
129
|
- spec/unit/routes_spec.rb
|
120
130
|
- spec/unit/rutter_spec.rb
|
@@ -131,25 +141,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
141
|
requirements:
|
132
142
|
- - ">="
|
133
143
|
- !ruby/object:Gem::Version
|
134
|
-
version: 2.
|
144
|
+
version: 2.5.0
|
135
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
146
|
requirements:
|
137
147
|
- - ">="
|
138
148
|
- !ruby/object:Gem::Version
|
139
149
|
version: 2.5.0
|
140
150
|
requirements: []
|
141
|
-
|
142
|
-
rubygems_version: 2.6.13
|
151
|
+
rubygems_version: 3.0.3
|
143
152
|
signing_key:
|
144
153
|
specification_version: 4
|
145
154
|
summary: HTTP router for Rack.
|
146
155
|
test_files:
|
147
|
-
- spec/integration/mount_spec.rb
|
148
|
-
- spec/integration/params_spec.rb
|
149
156
|
- spec/integration/rack_spec.rb
|
150
|
-
- spec/integration/redirect_spec.rb
|
151
157
|
- spec/spec_helper.rb
|
158
|
+
- spec/support/rack.rb
|
152
159
|
- spec/unit/builder_spec.rb
|
160
|
+
- spec/unit/namespace_spec.rb
|
153
161
|
- spec/unit/route_spec.rb
|
154
162
|
- spec/unit/routes_spec.rb
|
155
163
|
- spec/unit/rutter_spec.rb
|
data/bench/dynamic_routes
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -W0
|
2
|
-
|
3
|
-
require_relative "helper"
|
4
|
-
|
5
|
-
router = Rutter.new
|
6
|
-
app = Rack::MockRequest.new(router)
|
7
|
-
|
8
|
-
Benchmark.bm(50) do |b|
|
9
|
-
b.report "generating routes" do
|
10
|
-
DICT.each do |route|
|
11
|
-
router.get "#{route}/:id", to: $endpoint
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
b.report "recognizing routes" do
|
16
|
-
TIMES.times do
|
17
|
-
app.get("#{DICT.sample}/54")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/bench/expand
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -W0
|
2
|
-
|
3
|
-
require_relative "helper"
|
4
|
-
|
5
|
-
router = Rutter.new
|
6
|
-
|
7
|
-
Benchmark.bm(50) do |b|
|
8
|
-
b.report "generating routes" do
|
9
|
-
DICT.each do |route|
|
10
|
-
router.get "#{route}/:id", to: $endpoint, as: route
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
b.report "expand routes" do
|
15
|
-
TIMES.times do
|
16
|
-
router.path(DICT.sample.to_sym, id: 54, key: "value")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/bench/helper.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require "benchmark"
|
2
|
-
require "rack"
|
3
|
-
require_relative "../lib/rutter"
|
4
|
-
|
5
|
-
BATCH_SIZE = 1000
|
6
|
-
TIMES = 100000
|
7
|
-
DICT = IO.foreach("/usr/share/dict/words")
|
8
|
-
.lazy
|
9
|
-
.map { |word| word.chomp.downcase }
|
10
|
-
.uniq
|
11
|
-
.take(BATCH_SIZE)
|
12
|
-
.sort_by(&:length)
|
13
|
-
.reverse
|
14
|
-
|
15
|
-
$endpoint = ->(env) { [200, {}, ["Hello World"]] }
|
16
|
-
|
17
|
-
puts "Loading #{BATCH_SIZE} routes, calling them #{TIMES} times...\n"
|
18
|
-
|
19
|
-
GC.disable
|
data/bench/mount
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -W0
|
2
|
-
|
3
|
-
require_relative "helper"
|
4
|
-
|
5
|
-
router = Rutter.new
|
6
|
-
app = Rack::MockRequest.new(router)
|
7
|
-
|
8
|
-
DICT.each do |route|
|
9
|
-
router.mount $endpoint, at: route
|
10
|
-
end
|
11
|
-
|
12
|
-
builder = Rack::Builder.app do
|
13
|
-
DICT.each do |route|
|
14
|
-
map("/#{route}") { run $endpoint }
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
rack_app = Rack::MockRequest.new(builder)
|
19
|
-
|
20
|
-
Benchmark.bm(50) do |b|
|
21
|
-
b.report "recognizing mounts" do
|
22
|
-
TIMES.times do
|
23
|
-
app.get("/#{DICT.sample}/sub/path")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
b.report "recognizing rack map" do
|
28
|
-
TIMES.times do
|
29
|
-
rack_app.get("/#{DICT.sample}/sub/path")
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/bench/routes_helper
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -W0
|
2
|
-
|
3
|
-
require_relative "helper"
|
4
|
-
|
5
|
-
router = Rutter.new
|
6
|
-
routes = Rutter::Routes.new(router)
|
7
|
-
|
8
|
-
DICT.each do |route|
|
9
|
-
router.get "#{route}/:id", to: $endpoint, as: route
|
10
|
-
end
|
11
|
-
|
12
|
-
Benchmark.bm(50) do |b|
|
13
|
-
b.report "dynamic *_path" do
|
14
|
-
TIMES.times do
|
15
|
-
routes.public_send "#{DICT.sample}_path", id: 54, key: "value"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
b.report "dynamic *_url" do
|
20
|
-
TIMES.times do
|
21
|
-
routes.public_send "#{DICT.sample}_url", id: 54, key: "value"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/bench/static_routes
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -W0
|
2
|
-
|
3
|
-
require_relative "helper"
|
4
|
-
|
5
|
-
router = Rutter.new
|
6
|
-
app = Rack::MockRequest.new(router)
|
7
|
-
|
8
|
-
Benchmark.bm(50) do |b|
|
9
|
-
b.report "generating routes" do
|
10
|
-
DICT.each do |route|
|
11
|
-
router.get route, to: $endpoint
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
b.report "recognizing routes" do
|
16
|
-
TIMES.times do
|
17
|
-
app.get(DICT.sample)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe "Rutter::Builder#mount" do
|
4
|
-
let(:router) do
|
5
|
-
Rutter.new do
|
6
|
-
mount ->(_env) { [200, {}, ["Admin App"]] }, at: "/admin"
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def app
|
11
|
-
router.freeze
|
12
|
-
end
|
13
|
-
|
14
|
-
it "forwards the request to the given application" do
|
15
|
-
get "/admin/with/sub/paths"
|
16
|
-
expect(last_response.body).to eq("Admin App")
|
17
|
-
end
|
18
|
-
end
|