rutter 0.1.1 → 0.1.2
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 +4 -4
- data/.rspec +2 -0
- data/.travis.yml +3 -6
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +3 -5
- data/lib/rutter/builder.rb +20 -20
- data/lib/rutter/route.rb +10 -10
- data/lib/rutter/routes.rb +2 -2
- data/lib/rutter/scope.rb +1 -1
- data/lib/rutter/version.rb +1 -1
- data/rutter.gemspec +1 -2
- data/spec/integration/mount_spec.rb +2 -4
- data/spec/integration/params_spec.rb +4 -4
- data/spec/integration/rack_spec.rb +7 -6
- data/spec/integration/redirect_spec.rb +10 -7
- data/spec/spec_helper.rb +79 -7
- data/spec/unit/builder_spec.rb +34 -39
- data/spec/unit/route_spec.rb +31 -38
- data/spec/unit/routes_spec.rb +10 -11
- data/spec/unit/rutter_spec.rb +3 -5
- data/spec/unit/scope_spec.rb +21 -20
- metadata +5 -20
- data/spec/support/assertions.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e0af90882ec8c36cf23e278e384a38e38aa3959
|
4
|
+
data.tar.gz: '0387e7a032da114cb32b1635330dd878f207e960'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 236b39818113ff5910c9be230bbb7ec42478c30b891a56ecbfe2083756b5c16299f44b9e603ab0c5d6cbae33643699d988a03f66668c44a2cd9cd401309154c9
|
7
|
+
data.tar.gz: 8ffd27decede4f74d81a374296376692b47918946f9aab638f8369a1d539c088c803a9d3ad5551f6e942ffa0a94344147d251482c78f975b164760745d41e9e7
|
data/.rspec
ADDED
data/.travis.yml
CHANGED
@@ -2,20 +2,17 @@ language: ruby
|
|
2
2
|
script: "bundle exec rake spec:coverage"
|
3
3
|
cache: bundler
|
4
4
|
before_install:
|
5
|
-
-
|
6
|
-
- rvm @global do gem install bundler -v 1.15.0
|
5
|
+
- "gem update --system"
|
7
6
|
after_script:
|
8
|
-
- "CODECLIMATE_REPO_TOKEN=
|
7
|
+
- "CODECLIMATE_REPO_TOKEN=05a406e21e530e8210057604aa78eccebb988a8201c6b1e78187dff978bdee07 bundle exec codeclimate-test-reporter"
|
9
8
|
rvm:
|
10
|
-
- 2.
|
9
|
+
- 2.5.0
|
11
10
|
- 2.4.0
|
12
11
|
- ruby-head
|
13
|
-
- jruby-9.1.13.0
|
14
12
|
- jruby-head
|
15
13
|
matrix:
|
16
14
|
allow_failures:
|
17
15
|
- rvm: jruby-head
|
18
|
-
- rvm: jruby-9.1.13.0
|
19
16
|
- rvm: ruby-head
|
20
17
|
branches:
|
21
18
|
only:
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -132,7 +132,7 @@ end
|
|
132
132
|
|
133
133
|
## Contributing
|
134
134
|
|
135
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/sandelius/
|
135
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/sandelius/rutter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
136
136
|
|
137
137
|
|
138
138
|
## License
|
data/Rakefile
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
+
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require "bundler/gem_tasks"
|
4
|
-
require "
|
5
|
+
require "rspec/core/rake_task"
|
5
6
|
|
6
|
-
|
7
|
-
t.pattern = "spec/**/*_spec.rb"
|
8
|
-
t.libs.push "spec"
|
9
|
-
end
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
8
|
|
11
9
|
namespace :spec do
|
12
10
|
task :coverage do
|
data/lib/rutter/builder.rb
CHANGED
@@ -9,11 +9,11 @@ module Rutter
|
|
9
9
|
# The router redirect incoming requests to defined endpoints. Most often
|
10
10
|
# it's to a controller and an action or a Rack endpoint.
|
11
11
|
#
|
12
|
-
# @attr_reader [Array<Rutter::Route>]
|
12
|
+
# @attr_reader flat_map [Array<Rutter::Route>]
|
13
13
|
# Defined routes.
|
14
|
-
# @attr_reader [Hash<String => Array>]
|
14
|
+
# @attr_reader verb_map [Hash<String => Array>]
|
15
15
|
# Routes group by verb.
|
16
|
-
# @attr_reader [Hash<Symbol => Rutter::Route>]
|
16
|
+
# @attr_reader named_map [Hash<Symbol => Rutter::Route>]
|
17
17
|
# Named routes.
|
18
18
|
#
|
19
19
|
# @example basic usage
|
@@ -32,13 +32,13 @@ module Rutter
|
|
32
32
|
|
33
33
|
# Initializes the router.
|
34
34
|
#
|
35
|
-
# @param [String]
|
35
|
+
# @param scheme [String]
|
36
36
|
# URL scheme.
|
37
|
-
# @param [String]
|
37
|
+
# @param host [String]
|
38
38
|
# URL host.
|
39
|
-
# @param [Integer]
|
39
|
+
# @param port [Integer]
|
40
40
|
# URL port.
|
41
|
-
# @param [String]
|
41
|
+
# @param controller_suffix [String]
|
42
42
|
# Suffix string for controllers (BooksController).
|
43
43
|
#
|
44
44
|
# @yield
|
@@ -65,9 +65,9 @@ module Rutter
|
|
65
65
|
|
66
66
|
# Mount a Rack application at the specified path.
|
67
67
|
#
|
68
|
-
# @param [Class, Object]
|
68
|
+
# @param app [Class, Object]
|
69
69
|
# A class or an object that responds to `call`.
|
70
|
-
# @param [String]
|
70
|
+
# @param at [String]
|
71
71
|
# Path prefix to match.
|
72
72
|
#
|
73
73
|
# @return [void]
|
@@ -77,9 +77,9 @@ module Rutter
|
|
77
77
|
|
78
78
|
# Convenient method to create a redirect endpoint.
|
79
79
|
#
|
80
|
-
# @param [String]
|
80
|
+
# @param destination [String]
|
81
81
|
# The destination.
|
82
|
-
# @param [Integer]
|
82
|
+
# @param status [Integer]
|
83
83
|
# Response status code.
|
84
84
|
#
|
85
85
|
# @return [Proc]
|
@@ -109,13 +109,13 @@ module Rutter
|
|
109
109
|
|
110
110
|
# Adds a new route to the collection.
|
111
111
|
#
|
112
|
-
# @param [String, Symbol]
|
112
|
+
# @param method [String, Symbol]
|
113
113
|
# Request method.
|
114
|
-
# @param [String]
|
114
|
+
# @param path [String]
|
115
115
|
# Path template.
|
116
|
-
# @param [String, Symbol]
|
116
|
+
# @param as [String, Symbol]
|
117
117
|
# Route identifier (name).
|
118
|
-
# @param [String, Proc]
|
118
|
+
# @param to [String, Proc]
|
119
119
|
# Route endpoint.
|
120
120
|
#
|
121
121
|
# @return [Rutter::Route]
|
@@ -171,9 +171,9 @@ module Rutter
|
|
171
171
|
|
172
172
|
# Transforms a named route into a URL path.
|
173
173
|
#
|
174
|
-
# @param [Symbol]
|
174
|
+
# @param name [Symbol]
|
175
175
|
# Name of the route.
|
176
|
-
# @param [Hash]
|
176
|
+
# @param params [Hash]
|
177
177
|
# Route paremeters.
|
178
178
|
#
|
179
179
|
# @return [String]
|
@@ -192,7 +192,7 @@ module Rutter
|
|
192
192
|
|
193
193
|
# Transforms a named route into a full URL with scheme and host.
|
194
194
|
#
|
195
|
-
# @param [Symbol]
|
195
|
+
# @param name [Symbol]
|
196
196
|
# Name of the route.
|
197
197
|
# @option params [String] :_scheme (configuration.scheme)
|
198
198
|
# Override scheme.
|
@@ -220,7 +220,7 @@ module Rutter
|
|
220
220
|
|
221
221
|
# Process the request and is compatible with the Rack protocol.
|
222
222
|
#
|
223
|
-
# @param [Hash]
|
223
|
+
# @param env [Hash]
|
224
224
|
# Rack environment hash.
|
225
225
|
#
|
226
226
|
# @return [Array]
|
@@ -262,7 +262,7 @@ module Rutter
|
|
262
262
|
#
|
263
263
|
# @private
|
264
264
|
def match(env)
|
265
|
-
path = env["PATH_INFO"].downcase
|
265
|
+
path = (env["PATH_INFO"] || "/").downcase
|
266
266
|
path = path.chomp("/") if path != "/" && path.end_with?("/")
|
267
267
|
|
268
268
|
routes = verb_map[env["REQUEST_METHOD"]]
|
data/lib/rutter/route.rb
CHANGED
@@ -5,11 +5,11 @@ require "cgi"
|
|
5
5
|
module Rutter
|
6
6
|
# Represents a single route.
|
7
7
|
#
|
8
|
-
# @attr_reader [String]
|
8
|
+
# @attr_reader method [String]
|
9
9
|
# Request method to match.
|
10
|
-
# @attr_reader [String]
|
10
|
+
# @attr_reader path [String]
|
11
11
|
# Path to match.
|
12
|
-
# @attr_reader [Hash]
|
12
|
+
# @attr_reader endpoint [Hash]
|
13
13
|
# Route endpoint.
|
14
14
|
class Route
|
15
15
|
# Valid request verbs.
|
@@ -19,13 +19,13 @@ module Rutter
|
|
19
19
|
|
20
20
|
# Initializes the route.
|
21
21
|
#
|
22
|
-
# @param [Symbol, String]
|
22
|
+
# @param method [Symbol, String]
|
23
23
|
# Requets method to match.
|
24
|
-
# @param [String]
|
24
|
+
# @param path [String]
|
25
25
|
# Path template.
|
26
|
-
# @param [String, Proc, Hash]
|
26
|
+
# @param endpoint [String, Proc, Hash]
|
27
27
|
# Route endpoint.
|
28
|
-
# @param [String, false]
|
28
|
+
# @param controller_suffix [String, false]
|
29
29
|
# Suffix for string controllers.
|
30
30
|
#
|
31
31
|
# @return [self]
|
@@ -52,7 +52,7 @@ module Rutter
|
|
52
52
|
|
53
53
|
# Matches the given path to the route pattern.
|
54
54
|
#
|
55
|
-
# @param [String]
|
55
|
+
# @param path_info [String]
|
56
56
|
# Requested path to match against.
|
57
57
|
#
|
58
58
|
# @return [Boolean]
|
@@ -64,7 +64,7 @@ module Rutter
|
|
64
64
|
#
|
65
65
|
# NOTE: If the path does not match, `nil` is returned.
|
66
66
|
#
|
67
|
-
# @param [String]
|
67
|
+
# @param path [String]
|
68
68
|
# Requested path to extract params from.
|
69
69
|
#
|
70
70
|
# @return [nil, Hash<String => String>]
|
@@ -76,7 +76,7 @@ module Rutter
|
|
76
76
|
|
77
77
|
# Expands the pattern with the given arguments.
|
78
78
|
#
|
79
|
-
# @param [Hash]
|
79
|
+
# @param params [Hash]
|
80
80
|
# Expand parameters.
|
81
81
|
#
|
82
82
|
# @return [String] Expanded string.
|
data/lib/rutter/routes.rb
CHANGED
@@ -15,7 +15,7 @@ module Rutter
|
|
15
15
|
|
16
16
|
# Initializes the helper.
|
17
17
|
#
|
18
|
-
# @param [Rutter::Builder]
|
18
|
+
# @param builder [Rutter::Builder]
|
19
19
|
# Route builder object.
|
20
20
|
#
|
21
21
|
# @return [self]
|
@@ -35,7 +35,7 @@ module Rutter
|
|
35
35
|
# @private
|
36
36
|
def respond_to_missing?(method_name, include_private = false)
|
37
37
|
meth = method_name.to_s
|
38
|
-
meth.end_with?("_path"
|
38
|
+
meth.end_with?("_path", "_url") || super
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
data/lib/rutter/scope.rb
CHANGED
data/lib/rutter/version.rb
CHANGED
data/rutter.gemspec
CHANGED
@@ -24,7 +24,6 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_development_dependency "bundler"
|
26
26
|
spec.add_development_dependency "rake"
|
27
|
-
spec.add_development_dependency "
|
28
|
-
spec.add_development_dependency "mocha"
|
27
|
+
spec.add_development_dependency "rspec"
|
29
28
|
spec.add_development_dependency "rack-test"
|
30
29
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
describe "Rutter::Builder#mount" do
|
3
|
+
RSpec.describe "Rutter::Builder#mount" do
|
6
4
|
let(:router) do
|
7
5
|
Rutter.new do
|
8
6
|
mount ->(_env) { [200, {}, ["Admin App"]] }, at: "/admin"
|
@@ -15,6 +13,6 @@ describe "Rutter::Builder#mount" do
|
|
15
13
|
|
16
14
|
it "forwards the request to the given application" do
|
17
15
|
get "/admin/with/sub/paths"
|
18
|
-
|
16
|
+
expect(last_response.body).to eq("Admin App")
|
19
17
|
end
|
20
18
|
end
|
@@ -11,7 +11,7 @@ class TestController
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
describe "ramverk.router_params" do
|
14
|
+
RSpec.describe "ramverk.router_params" do
|
15
15
|
let(:router) { Rutter.new(controller_suffix: "Controller") }
|
16
16
|
|
17
17
|
def app
|
@@ -21,8 +21,8 @@ describe "ramverk.router_params" do
|
|
21
21
|
it "calls the endpoint (controller)" do
|
22
22
|
router.get "/books/:title", to: "Test#index"
|
23
23
|
get "/books/eloquent-ruby"
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
expect(last_response.status).to eq(100)
|
25
|
+
expect(last_response.body)
|
26
|
+
.to eq('{"title":"eloquent-ruby","action":"index"}')
|
27
27
|
end
|
28
28
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
describe "Rack integration" do
|
5
|
+
RSpec.describe "Rack integration" do
|
6
6
|
let(:router) do
|
7
7
|
Rutter.new do
|
8
8
|
get "/books", to: ->(_env) { [200, {}, ["Books"]] }
|
@@ -16,17 +16,18 @@ describe "Rack integration" do
|
|
16
16
|
describe "with match" do
|
17
17
|
it "calls the matched endpoint" do
|
18
18
|
get "/books"
|
19
|
-
|
20
|
-
|
19
|
+
expect(last_response.status).to eq(200)
|
20
|
+
expect(last_response.body).to eq("Books")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "with no match" do
|
25
25
|
it "returns 404" do
|
26
26
|
get "/authors"
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
|
28
|
+
expect(last_response.status).to eq(404)
|
29
|
+
expect(last_response.body).to eq("Route Not Found")
|
30
|
+
expect(last_response.headers["X-Cascade"]).to eq("pass")
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
describe "Rutter::Builder#redirect" do
|
5
|
+
RSpec.describe "Rutter::Builder#redirect" do
|
6
6
|
let(:router) do
|
7
7
|
Rutter.new do
|
8
8
|
get "/legacy-path", to: redirect("/new_path")
|
@@ -17,17 +17,20 @@ describe "Rutter::Builder#redirect" do
|
|
17
17
|
|
18
18
|
it "redirect the request to the new path" do
|
19
19
|
get "/legacy-path"
|
20
|
-
|
21
|
-
|
20
|
+
|
21
|
+
expect(last_response.status).to eq(302)
|
22
|
+
expect(last_response.body).to eq("")
|
23
|
+
|
22
24
|
follow_redirect!
|
23
|
-
|
24
|
-
|
25
|
+
|
26
|
+
expect(last_response.status).to eq(200)
|
27
|
+
expect(last_response.body).to eq("Redirected")
|
25
28
|
end
|
26
29
|
|
27
30
|
it "support setting custom status" do
|
28
31
|
get "/legacy-path-custom-status"
|
29
|
-
|
32
|
+
expect(last_response.status).to eq(301)
|
30
33
|
follow_redirect!
|
31
|
-
|
34
|
+
expect(last_response.status).to eq(200)
|
32
35
|
end
|
33
36
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,16 +12,88 @@ if ENV["COVERAGE"] == "true"
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
require "minitest/autorun"
|
16
|
-
require "minitest/pride"
|
17
|
-
require "rack/test"
|
18
|
-
require "mocha/mini_test"
|
19
|
-
|
20
15
|
# Require support (helper) modules
|
21
16
|
Dir["./spec/support/**/*.rb"].each { |f| require f }
|
22
17
|
|
18
|
+
# Require library
|
19
|
+
require "rack/test"
|
23
20
|
require "rutter"
|
24
21
|
|
25
|
-
|
26
|
-
|
22
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
23
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
24
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
25
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
26
|
+
# files.
|
27
|
+
#
|
28
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
29
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
30
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
31
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
32
|
+
# a separate helper file that requires the additional dependencies and performs
|
33
|
+
# the additional setup, and require it from the spec files that actually need
|
34
|
+
# it.
|
35
|
+
#
|
36
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
37
|
+
RSpec.configure do |config|
|
38
|
+
config.include Rack::Test::Methods
|
39
|
+
|
40
|
+
# rspec-expectations config goes here. You can use an alternate
|
41
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
42
|
+
# assertions if you prefer.
|
43
|
+
config.expect_with :rspec do |expectations|
|
44
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
45
|
+
# and `failure_message` of custom matchers include text for helper methods
|
46
|
+
# defined using `chain`, e.g.:
|
47
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
48
|
+
# # => "be bigger than 2 and smaller than 4"
|
49
|
+
# ...rather than:
|
50
|
+
# # => "be bigger than 2"
|
51
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
52
|
+
end
|
53
|
+
|
54
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
55
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
56
|
+
config.mock_with :rspec do |mocks|
|
57
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
58
|
+
# a real object. This is generally recommended, and will default to
|
59
|
+
# `true` in RSpec 4.
|
60
|
+
mocks.verify_partial_doubles = true
|
61
|
+
end
|
62
|
+
|
63
|
+
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
64
|
+
# have no way to turn it off -- the option exists only for backwards
|
65
|
+
# compatibility in RSpec 3). It causes shared context metadata to be
|
66
|
+
# inherited by the metadata hash of host groups and examples, rather than
|
67
|
+
# triggering implicit auto-inclusion in groups with matching metadata.
|
68
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
69
|
+
|
70
|
+
# This allows you to limit a spec run to individual examples or groups
|
71
|
+
# you care about by tagging them with `:focus` metadata. When nothing
|
72
|
+
# is tagged with `:focus`, all examples get run. RSpec also provides
|
73
|
+
# aliases for `it`, `describe`, and `context` that include `:focus`
|
74
|
+
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
75
|
+
config.filter_run_when_matching :focus
|
76
|
+
|
77
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
78
|
+
# recommended. For more details, see:
|
79
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
80
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
81
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
82
|
+
config.disable_monkey_patching!
|
83
|
+
|
84
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
85
|
+
# be too noisy due to issues in dependencies.
|
86
|
+
config.warnings = true
|
87
|
+
|
88
|
+
# Run specs in random order to surface order dependencies. If you find an
|
89
|
+
# order dependency and want to debug it, you can fix the order by providing
|
90
|
+
# the seed, which is printed after each run.
|
91
|
+
# --seed 1234
|
92
|
+
config.order = :random
|
93
|
+
|
94
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
95
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
96
|
+
# test failures related to randomization by passing the same `--seed` value
|
97
|
+
# as the one that triggered the failure.
|
98
|
+
Kernel.srand config.seed
|
27
99
|
end
|
data/spec/unit/builder_spec.rb
CHANGED
@@ -1,53 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
3
|
module Rutter
|
6
|
-
describe Builder do
|
4
|
+
RSpec.describe Builder do
|
7
5
|
let(:router) { Builder.new }
|
8
6
|
|
9
7
|
describe "#add" do
|
10
8
|
it "returns the created route object" do
|
11
9
|
route = router.get "/books", to: ->(env) {}
|
12
10
|
named_route = router.get "/named_books", to: ->(env) {}, as: :books
|
13
|
-
|
14
|
-
|
11
|
+
|
12
|
+
expect(route).to be_a(Route)
|
13
|
+
expect(named_route).to be_a(Route)
|
15
14
|
end
|
16
15
|
|
17
16
|
it "adds a route to the collection" do
|
18
17
|
router.get "/books", to: ->(env) {}
|
19
18
|
router.post "/books", to: ->(env) {}
|
20
19
|
|
21
|
-
|
20
|
+
expect(router.flat_map.size).to eq(2)
|
22
21
|
end
|
23
22
|
|
24
23
|
it "stores the name of the route" do
|
25
24
|
route = router.add "GET", "/books", as: :books, to: ->(env) {}
|
26
|
-
|
25
|
+
expect(router.named_map[:books]).to eq(route)
|
27
26
|
end
|
28
27
|
|
29
28
|
it "normalizes route names" do
|
30
29
|
router.get "/books", as: :_bookie__books__, to: ->(env) {}
|
31
|
-
|
30
|
+
expect(router.named_map.key?(:bookie_books)).to eq(true)
|
32
31
|
end
|
33
32
|
|
34
33
|
it "raises an error if named route already been defined" do
|
35
34
|
router.get "/books", as: :books, to: ->(env) {}
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
assert_equal "a route called 'books' has already been defined",
|
42
|
-
err.message
|
36
|
+
expect { router.get "/books", as: :books, to: ->(env) {} }
|
37
|
+
.to raise_error("a route called 'books' has already been defined")
|
43
38
|
end
|
44
39
|
end
|
45
40
|
|
46
41
|
describe "#root" do
|
47
42
|
it "adds a root path with a root name" do
|
48
43
|
route = router.root to: ->(env) {}
|
49
|
-
|
50
|
-
|
44
|
+
|
45
|
+
expect(route.path).to eq("/")
|
46
|
+
expect(router.named_map[:root]).to eq(route)
|
51
47
|
end
|
52
48
|
end
|
53
49
|
|
@@ -55,7 +51,7 @@ module Rutter
|
|
55
51
|
Route::VERBS.each do |verb|
|
56
52
|
it "accept the #{verb} verb as method" do
|
57
53
|
router.send verb.downcase, "/", to: ->() {}
|
58
|
-
|
54
|
+
expect(router.flat_map[0].method).to eq(verb)
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
@@ -63,42 +59,41 @@ module Rutter
|
|
63
59
|
describe "#path" do
|
64
60
|
it "generates a URL path from the arguments" do
|
65
61
|
router.get "/users/:id(/:username)", to: "Users#show", as: :user
|
66
|
-
|
67
|
-
|
68
|
-
|
62
|
+
|
63
|
+
expect(router.path(:user, id: 45, username: "sandelius"))
|
64
|
+
.to eq("/users/45/sandelius")
|
65
|
+
expect(router.path(:user, id: 45)).to eq("/users/45")
|
69
66
|
end
|
70
67
|
|
71
68
|
it "raises an error if route has not been defined" do
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
assert_equal "no route called 'user'", err.message
|
69
|
+
expect { router.path(:user) }
|
70
|
+
.to raise_error("no route called 'user'")
|
76
71
|
end
|
77
72
|
end
|
78
73
|
|
79
74
|
describe "#url" do
|
80
75
|
it "generates a full URL" do
|
81
76
|
router.get "/users/:id", to: "Users#show", as: :user
|
82
|
-
|
77
|
+
|
78
|
+
expect(router.url(:user, id: 54)).to eq("http://example.com/users/54")
|
83
79
|
end
|
84
80
|
|
85
81
|
it "allows host scheme and subdomain to be set" do
|
86
82
|
router.get "/users/:id", to: "Users#show", as: :user
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
id: 54, _host: "example.com", _scheme: "https", _subdomain: "api"
|
92
|
-
)
|
83
|
+
|
84
|
+
url = router.url(
|
85
|
+
:user,
|
86
|
+
id: 54, _host: "example.com", _scheme: "https", _subdomain: "api"
|
93
87
|
)
|
88
|
+
|
89
|
+
expect(url).to eq("https://api.example.com/users/54")
|
94
90
|
end
|
95
91
|
|
96
92
|
it "adds port if no 80 or 433" do
|
97
93
|
router.get "/users/:id", to: "Users#show", as: :user
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
)
|
94
|
+
|
95
|
+
expect(router.url(:user, id: 54, _port: 333))
|
96
|
+
.to eq("http://example.com:333/users/54")
|
102
97
|
end
|
103
98
|
end
|
104
99
|
|
@@ -106,10 +101,10 @@ module Rutter
|
|
106
101
|
it "freezes all objects" do
|
107
102
|
router.freeze
|
108
103
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
104
|
+
expect(router).to be_frozen
|
105
|
+
expect(router.flat_map).to be_frozen
|
106
|
+
expect(router.named_map).to be_frozen
|
107
|
+
expect(router.verb_map).to be_frozen
|
113
108
|
end
|
114
109
|
end
|
115
110
|
end
|
data/spec/unit/route_spec.rb
CHANGED
@@ -1,87 +1,80 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
3
|
module Rutter
|
6
|
-
describe Route do
|
4
|
+
RSpec.describe Route do
|
7
5
|
it "raises an error if request method is invalid" do
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
assert_equal "invalid verb: 'NONE'", err.message
|
6
|
+
expect { Route.new("NONE", "/", ->(env) {}) }
|
7
|
+
.to raise_error(ArgumentError, "invalid verb: 'NONE'")
|
13
8
|
end
|
14
9
|
|
15
10
|
it "normalizes path" do
|
16
11
|
route = Route.new("GET", "//about////us/", ->(env) {})
|
17
|
-
|
12
|
+
expect(route.path).to eq("/about/us")
|
18
13
|
end
|
19
14
|
|
20
15
|
describe "#expand" do
|
21
16
|
it "expand dynamic routes" do
|
22
17
|
route = Route.new("GET", "/books/:id(/:title)", -> {})
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
18
|
+
|
19
|
+
expect(route.expand(id: 54, title: "eloquent", include: [:foo]))
|
20
|
+
.to eq("/books/54/eloquent?include[]=foo")
|
21
|
+
expect(route.expand(id: 54, include: [:foo]))
|
22
|
+
.to eq("/books/54?include[]=foo")
|
23
|
+
expect(route.expand(id: 54, title: "eloquent"))
|
24
|
+
.to eq("/books/54/eloquent")
|
25
|
+
expect(route.expand(id: 54)).to eq("/books/54")
|
30
26
|
end
|
31
27
|
|
32
28
|
it "expand static routes" do
|
33
29
|
route = Route.new("GET", "/books", -> {})
|
34
|
-
|
35
|
-
|
30
|
+
expect(route.expand(include: [:foo])).to eq("/books?include[]=foo")
|
31
|
+
expect(route.expand).to eq("/books")
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
39
35
|
describe "#match?" do
|
40
36
|
it "matches non regexp" do
|
41
|
-
|
42
|
-
|
37
|
+
expect(Route.new("GET", "/books", -> {}).match?("/books"))
|
38
|
+
.to eq(true)
|
43
39
|
end
|
44
40
|
|
45
41
|
it "support named parameters" do
|
46
42
|
route = Route.new("GET", "/pages/:id(/:title)", -> {})
|
47
43
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
expect(route.match?("/pages/54/eloquent-ruby")).to eq(true)
|
45
|
+
expect(route.match?("/pages/54")).to eq(true)
|
46
|
+
expect(route.match?("/pages/54.rb")).to eq(false)
|
47
|
+
expect(route.match?("/pages")).to eq(false)
|
52
48
|
end
|
53
49
|
|
54
50
|
it "support catch-all parameter" do
|
55
51
|
route = Route.new("GET", "/pages/*slug", -> {})
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
|
53
|
+
expect(route.match?("/pages/54/eloquent-ruby")).to eq(true)
|
54
|
+
expect(route.match?("/pages/54/eloquent-ruby.rb")).to eq(true)
|
55
|
+
expect(route.match?("/pages/54/eloquent-ruby/with/more/parts")).to eq(true)
|
56
|
+
expect(route.match?("/pages")).to eq(false)
|
60
57
|
end
|
61
58
|
end
|
62
59
|
|
63
60
|
describe "#params" do
|
64
61
|
it "extract params" do
|
65
62
|
route = Route.new("GET", "/pages/:id(/:title)", -> {})
|
66
|
-
assert_equal(
|
67
|
-
{ "id" => "54", "title" => "eloquent-ruby" },
|
68
|
-
route.params("/pages/54/eloquent-ruby")
|
69
|
-
)
|
70
63
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
64
|
+
expect(route.params("/pages/54/eloquent-ruby"))
|
65
|
+
.to eq("id" => "54", "title" => "eloquent-ruby")
|
66
|
+
expect(route.params("/pages/54"))
|
67
|
+
.to eq("id" => "54", "title" => nil)
|
75
68
|
end
|
76
69
|
|
77
70
|
it "returns nil if no match" do
|
78
71
|
route = Route.new("GET", "/books/:id", -> {})
|
79
|
-
|
72
|
+
expect(route.params("/posts/54")).to be_nil
|
80
73
|
end
|
81
74
|
|
82
75
|
it "returns empty array if no params present" do
|
83
76
|
route = Route.new("GET", "/books", -> {})
|
84
|
-
|
77
|
+
expect(route.params("/books")).to eq({})
|
85
78
|
end
|
86
79
|
end
|
87
80
|
end
|
data/spec/unit/routes_spec.rb
CHANGED
@@ -1,36 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
3
|
module Rutter
|
6
|
-
describe Routes do
|
4
|
+
RSpec.describe Routes do
|
7
5
|
let(:router) { Builder.new }
|
8
6
|
let(:routes) { Routes.new(router) }
|
9
7
|
|
10
8
|
it "has a *_path helper method" do
|
11
9
|
router.get "/books/:id", to: "Books#show", as: :book
|
12
|
-
|
10
|
+
expect(routes.book_path(id: 54)).to eq("/books/54")
|
13
11
|
end
|
14
12
|
|
15
13
|
it "has a *_url helper method" do
|
16
14
|
router.get "/books/:id", to: "Books#show", as: :book
|
17
|
-
|
18
|
-
routes.book_url(id: 54)
|
15
|
+
expect(routes.book_url(id: 54)).to eq("http://example.com/books/54")
|
19
16
|
end
|
20
17
|
|
21
18
|
it "raises ArgumentError if route not found" do
|
22
|
-
|
19
|
+
expect { routes.invalid_path }
|
20
|
+
.to raise_error(ArgumentError)
|
23
21
|
end
|
24
22
|
|
25
23
|
it "raises NoMethodError if unknown method is called" do
|
26
|
-
|
24
|
+
expect { routes.invalid }
|
25
|
+
.to raise_error(NoMethodError)
|
27
26
|
end
|
28
27
|
|
29
28
|
it "support respond_to?" do
|
30
29
|
router.get "/books/:id", to: "Books#show", as: :book
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
expect(routes.respond_to?(:book)).to eq(false)
|
31
|
+
expect(routes.respond_to?(:book_path)).to eq(true)
|
32
|
+
expect(routes.respond_to?(:book_url)).to eq(true)
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
data/spec/unit/rutter_spec.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
describe Rutter do
|
3
|
+
RSpec.describe Rutter do
|
6
4
|
it "has a version number" do
|
7
|
-
|
5
|
+
expect(Rutter::VERSION).to be_a(String)
|
8
6
|
end
|
9
7
|
|
10
8
|
describe ".new" do
|
11
9
|
it "returns a new Builder object" do
|
12
|
-
|
10
|
+
expect(Rutter.new).to be_a(Rutter::Builder)
|
13
11
|
end
|
14
12
|
end
|
15
13
|
end
|
data/spec/unit/scope_spec.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
3
|
module Rutter
|
6
|
-
describe Builder do
|
4
|
+
RSpec.describe Builder do
|
7
5
|
let(:router) { Builder.new }
|
8
6
|
|
9
7
|
describe "scope" do
|
@@ -13,8 +11,9 @@ module Rutter
|
|
13
11
|
end
|
14
12
|
|
15
13
|
route = router.flat_map.first
|
16
|
-
|
17
|
-
|
14
|
+
|
15
|
+
expect(route.path).to eq("/web/books")
|
16
|
+
expect(route.endpoint[:controller]).to eq("Web::Books")
|
18
17
|
end
|
19
18
|
|
20
19
|
it "recognizes all verbs" do
|
@@ -29,14 +28,14 @@ module Rutter
|
|
29
28
|
trace "/", to: ->(env) {}
|
30
29
|
end
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
expect(router.flat_map[0].method).to eq("GET")
|
32
|
+
expect(router.flat_map[1].method).to eq("POST")
|
33
|
+
expect(router.flat_map[2].method).to eq("PUT")
|
34
|
+
expect(router.flat_map[3].method).to eq("PATCH")
|
35
|
+
expect(router.flat_map[4].method).to eq("DELETE")
|
36
|
+
expect(router.flat_map[5].method).to eq("OPTIONS")
|
37
|
+
expect(router.flat_map[6].method).to eq("HEAD")
|
38
|
+
expect(router.flat_map[7].method).to eq("TRACE")
|
40
39
|
end
|
41
40
|
|
42
41
|
describe "#root" do
|
@@ -45,8 +44,8 @@ module Rutter
|
|
45
44
|
root to: ->(env) {}
|
46
45
|
end
|
47
46
|
|
48
|
-
|
49
|
-
|
47
|
+
expect(router.flat_map.first.path).to eq("/admin")
|
48
|
+
expect(router.named_map.key?(:koolaid_root)).to eq(true)
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
@@ -58,16 +57,18 @@ module Rutter
|
|
58
57
|
end
|
59
58
|
|
60
59
|
route = router.flat_map.first
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
60
|
+
|
61
|
+
expect(route.path).to eq("/animals/mammals/cats")
|
62
|
+
expect(route.endpoint[:controller]).to eq("Species::Mammals::Cats")
|
63
|
+
expect(route.endpoint[:action]).to eq("index")
|
64
|
+
expect(router.named_map.key?(:animals_mammals_cats)).to eq(true)
|
65
65
|
end
|
66
66
|
|
67
67
|
describe "#mount" do
|
68
68
|
it "calls the root mount with path prefix" do
|
69
69
|
app = ->(_env) {}
|
70
|
-
|
70
|
+
|
71
|
+
expect(router).to receive(:mount).with(app, at: "/admin/books")
|
71
72
|
router.scope(path: "/admin") { mount app, at: "books" }
|
72
73
|
end
|
73
74
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rutter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
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: 2018-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -53,21 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
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: mocha
|
56
|
+
name: rspec
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
@@ -101,6 +87,7 @@ extensions: []
|
|
101
87
|
extra_rdoc_files: []
|
102
88
|
files:
|
103
89
|
- ".gitignore"
|
90
|
+
- ".rspec"
|
104
91
|
- ".rubocop.yml"
|
105
92
|
- ".travis.yml"
|
106
93
|
- ".yardopts"
|
@@ -127,7 +114,6 @@ files:
|
|
127
114
|
- spec/integration/rack_spec.rb
|
128
115
|
- spec/integration/redirect_spec.rb
|
129
116
|
- spec/spec_helper.rb
|
130
|
-
- spec/support/assertions.rb
|
131
117
|
- spec/unit/builder_spec.rb
|
132
118
|
- spec/unit/route_spec.rb
|
133
119
|
- spec/unit/routes_spec.rb
|
@@ -153,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
139
|
version: 2.5.0
|
154
140
|
requirements: []
|
155
141
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.6.
|
142
|
+
rubygems_version: 2.6.13
|
157
143
|
signing_key:
|
158
144
|
specification_version: 4
|
159
145
|
summary: HTTP router for Rack.
|
@@ -163,7 +149,6 @@ test_files:
|
|
163
149
|
- spec/integration/rack_spec.rb
|
164
150
|
- spec/integration/redirect_spec.rb
|
165
151
|
- spec/spec_helper.rb
|
166
|
-
- spec/support/assertions.rb
|
167
152
|
- spec/unit/builder_spec.rb
|
168
153
|
- spec/unit/route_spec.rb
|
169
154
|
- spec/unit/routes_spec.rb
|