route_mechanic 0.1.0 → 0.1.5
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/.github/workflows/test.yml +59 -0
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/README.md +5 -3
- data/fixtures/fake_app/lib/engine.rb +5 -0
- data/fixtures/fake_app/rails_app.rb +14 -0
- data/lib/route_mechanic/rspec/matchers.rb +3 -3
- data/lib/route_mechanic/testing/methods.rb +34 -12
- data/lib/route_mechanic/version.rb +1 -1
- data/route_mechanic.gemspec +3 -2
- metadata +27 -6
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 880e2dd0341ed11d953e4a4d27e71431ef393049153224f62231ba3c527252c8
|
4
|
+
data.tar.gz: '0592972c3d62edf50cbeb1f4bcfee4473921e789c31eff61cd2673927c22013b'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a75f67529149119f59e7e78082a4364ea98b15c4906959a75d4970420a877444d36c37e150f21ab4a2a7e347daf80afe2645072f40d93cff18d57a6427fa5e1
|
7
|
+
data.tar.gz: 71dd0672e63045a5c386ce4510712f75472a07abc236a8d73b696a361ef4fd65a394afb2578ac8f8b3c216d9d4f5e7142cc823fbef67e52c99b65a28f129fd8d
|
@@ -0,0 +1,59 @@
|
|
1
|
+
name: test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
types:
|
9
|
+
- opened
|
10
|
+
- synchronize
|
11
|
+
- reopened
|
12
|
+
schedule:
|
13
|
+
- cron: "0 10 * * 5" # JST 19:00 (Fri)
|
14
|
+
|
15
|
+
env:
|
16
|
+
CI: "true"
|
17
|
+
|
18
|
+
jobs:
|
19
|
+
test:
|
20
|
+
runs-on: ubuntu-latest
|
21
|
+
container: ${{ matrix.ruby }}
|
22
|
+
strategy:
|
23
|
+
fail-fast: false
|
24
|
+
matrix:
|
25
|
+
ruby:
|
26
|
+
- ruby:2.3
|
27
|
+
- ruby:2.4
|
28
|
+
- ruby:2.5
|
29
|
+
- ruby:2.6
|
30
|
+
- ruby:2.7
|
31
|
+
- rubylang/ruby:master-nightly-bionic
|
32
|
+
test_framework:
|
33
|
+
- rspec
|
34
|
+
- rake
|
35
|
+
include:
|
36
|
+
- ruby: rubylang/ruby:master-nightly-bionic
|
37
|
+
allow_failures: "true"
|
38
|
+
|
39
|
+
steps:
|
40
|
+
- uses: actions/checkout@v2
|
41
|
+
- name: Cache vendor/bundle
|
42
|
+
uses: actions/cache@v2
|
43
|
+
with:
|
44
|
+
path: vendor/bundle
|
45
|
+
key: v1-gem-${{ runner.os }}-${{ matrix.ruby }}-${{ github.sha }}
|
46
|
+
restore-keys: |
|
47
|
+
v1-gem-${{ runner.os }}-${{ matrix.ruby }}-
|
48
|
+
continue-on-error: ${{ matrix.allow_failures == 'true' }}
|
49
|
+
- name: bundle update
|
50
|
+
run: |
|
51
|
+
set -xe
|
52
|
+
bundle config path vendor/bundle
|
53
|
+
bundle update --jobs $(nproc) --retry 3
|
54
|
+
continue-on-error: ${{ matrix.allow_failures == 'true' }}
|
55
|
+
- name: Run ${{ matrix.test_framework }}
|
56
|
+
run: |
|
57
|
+
set -xe
|
58
|
+
bundle exec ${{ matrix.test_framework }}
|
59
|
+
continue-on-error: ${{ matrix.allow_failures == 'true' }}
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# RouteMechanic
|
2
|
+
[](https://badge.fury.io/rb/route_mechanic)
|
3
|
+
[](https://github.com/ohbarye/route_mechanic/actions?query=workflow%3Atest)
|
2
4
|
|
3
5
|
No need to maintain Rails' routing tests manually. RouteMechanic automatically detects broken routes and missing action methods in controller once you've finished installation.
|
4
6
|
|
@@ -31,7 +33,7 @@ Just add a test file which has only one test case using `have_valid_routes` matc
|
|
31
33
|
```ruby
|
32
34
|
RSpec.describe 'Rails.application', type: :routing do
|
33
35
|
it "fails if application does not have valid routes" do
|
34
|
-
|
36
|
+
expect(Rails.application).to have_valid_routes
|
35
37
|
end
|
36
38
|
end
|
37
39
|
```
|
@@ -44,7 +46,7 @@ Just add a test file like below.
|
|
44
46
|
class RoutingTest < Minitest::Test
|
45
47
|
include ::RouteMechanic::Testing::Methods
|
46
48
|
|
47
|
-
def
|
49
|
+
def test_that_application_has_correct_routes
|
48
50
|
assert_all_routes
|
49
51
|
end
|
50
52
|
end
|
@@ -55,7 +57,7 @@ end
|
|
55
57
|
It tells you broken routes as follows.
|
56
58
|
|
57
59
|
```ruby
|
58
|
-
0)
|
60
|
+
0) Rail.application fails if application does not have valid routes
|
59
61
|
Failure/Error: expect(Rails.application.routes).to have_valid_routes
|
60
62
|
|
61
63
|
[Route Mechanic]
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'rails/application'
|
2
2
|
require "action_controller/railtie"
|
3
3
|
|
4
|
+
require_relative './lib/engine'
|
5
|
+
|
4
6
|
FakeApp = Class.new(Rails::Application)
|
5
7
|
FakeApp.config.eager_load = false
|
6
8
|
FakeApp.config.hosts << 'www.example.com' if FakeApp.config.respond_to?(:hosts)
|
@@ -8,7 +10,19 @@ FakeApp.config.root = File.dirname(__FILE__)
|
|
8
10
|
FakeApp.initialize!
|
9
11
|
|
10
12
|
FakeApp.routes.draw do
|
13
|
+
constraints subdomain: /\A[0-9a-z-]+\z/ do
|
14
|
+
get '/constraints_test' => 'users#index'
|
15
|
+
end
|
16
|
+
|
17
|
+
scope ':locale', locale: /en|ja/ do
|
18
|
+
get '/locale_test', to: 'photos#index'
|
19
|
+
get '/photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
|
20
|
+
end
|
21
|
+
|
22
|
+
get 'organizations/:id', to: 'organizations#show', id: /[A-Z]\d{5}/
|
23
|
+
|
11
24
|
resources :users do
|
12
25
|
get 'friends', to: :friends
|
26
|
+
mount FakeEngine::Engine, at: "/fake_engine", fake_default_param: 'FAKE'
|
13
27
|
end
|
14
28
|
end
|
@@ -8,7 +8,7 @@ module RouteMechanic
|
|
8
8
|
include ::RSpec::Matchers::Composable
|
9
9
|
include RouteMechanic::Testing::Methods
|
10
10
|
|
11
|
-
# @param [
|
11
|
+
# @param [Rails::Application] expected
|
12
12
|
def initialize(expected)
|
13
13
|
@expected = expected
|
14
14
|
end
|
@@ -42,8 +42,8 @@ module RouteMechanic
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def have_valid_routes(
|
46
|
-
HaveValidRoutes.new(
|
45
|
+
def have_valid_routes(application=Rails.application)
|
46
|
+
HaveValidRoutes.new(application)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -3,6 +3,7 @@ require "route_mechanic/testing/error_aggregator"
|
|
3
3
|
require "route_mechanic/testing/minitest_assertion_adopter"
|
4
4
|
require "action_controller"
|
5
5
|
require "action_controller/test_case"
|
6
|
+
require "regexp-examples"
|
6
7
|
|
7
8
|
module RouteMechanic
|
8
9
|
module Testing
|
@@ -10,12 +11,10 @@ module RouteMechanic
|
|
10
11
|
include MinitestAssertionAdapter if defined?(RSpec)
|
11
12
|
include ActionDispatch::Assertions
|
12
13
|
|
13
|
-
# @param [
|
14
|
+
# @param [Rails::Application] application
|
14
15
|
# @raise [Minitest::Assertion]
|
15
|
-
def assert_all_routes(
|
16
|
-
|
17
|
-
# If user already defines @routes, do not override
|
18
|
-
@routes ||= routes
|
16
|
+
def assert_all_routes(application=Rails.application)
|
17
|
+
@application = application
|
19
18
|
|
20
19
|
# Instead of including ActionController::TestCase::Behavior, set up
|
21
20
|
# https://github.com/rails/rails/blob/5b6aa8c20a3abfd6274c83f196abf73cacb3400b/actionpack/lib/action_controller/test_case.rb#L519-L520
|
@@ -29,19 +28,43 @@ module RouteMechanic
|
|
29
28
|
|
30
29
|
private
|
31
30
|
|
31
|
+
def routes
|
32
|
+
# assert_routing expect @routes to exists as like this class inherits ActionController::TestCase.
|
33
|
+
# If user already defines @routes, do not override
|
34
|
+
@routes ||= @application.routes
|
35
|
+
|
36
|
+
return @routes if @routes.routes.size > 0
|
37
|
+
|
38
|
+
# If routes setting is not loaded when running test, it automatically loads config/routes as Rails does.
|
39
|
+
load_path = "#{Rails.root.join('config/routes.rb')}"
|
40
|
+
@application.routes_reloader.paths << load_path unless @application.routes_reloader.paths.include? load_path
|
41
|
+
@application.reload_routes!
|
42
|
+
@routes
|
43
|
+
end
|
44
|
+
|
32
45
|
# @param [RouteMechanic::Testing::RouteWrapper] wrapper
|
33
46
|
# @raise [Minitest::Assertion]
|
34
47
|
def assert_routes(wrapper)
|
35
48
|
required_parts = wrapper.required_parts.reduce({}) do |memo, required_part|
|
36
|
-
|
49
|
+
dummy = if wrapper.requirements[required_part].is_a?(Regexp)
|
50
|
+
wrapper.requirements[required_part].examples.last
|
51
|
+
else
|
52
|
+
'1'
|
53
|
+
end
|
54
|
+
memo.merge({ required_part => dummy }) # Set pseudo params to meets requirements
|
37
55
|
end
|
38
56
|
|
39
57
|
base_option = { controller: wrapper.controller, action: wrapper.action }
|
40
|
-
url =
|
58
|
+
url = routes.url_helpers.url_for(
|
41
59
|
base_option.merge({ only_path: true }).merge(required_parts))
|
42
60
|
expected_options = base_option.merge(required_parts)
|
43
61
|
|
44
|
-
|
62
|
+
assert_generates(url, expected_options)
|
63
|
+
# Q. Why not using `assert_routing` or `assert_recognize`?
|
64
|
+
# A. They strictly checks `constraints` in routes.rb and
|
65
|
+
# this gem can't generate a request that meets whole constraints just in time.
|
66
|
+
# https://github.com/ohbarye/route_mechanic/issues/7#issuecomment-695957142
|
67
|
+
# https://guides.rubyonrails.org/routing.html#specifying-constraints
|
45
68
|
end
|
46
69
|
|
47
70
|
# @return [Array<Controller>]
|
@@ -55,19 +78,18 @@ module RouteMechanic
|
|
55
78
|
# If complicated controllers path is used, use Rails.application.eager_load! instead.
|
56
79
|
def eager_load_controllers
|
57
80
|
load_path = "#{Rails.root.join('app/controllers')}"
|
58
|
-
relname_range = (load_path.to_s.length + 1)...-3
|
59
81
|
Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
|
60
|
-
require_dependency file
|
82
|
+
require_dependency file
|
61
83
|
end
|
62
84
|
end
|
63
85
|
|
64
86
|
# @return [Array<ActionDispatch::Journey::Route>]
|
65
87
|
def target_routes
|
66
|
-
|
88
|
+
routes.routes.reject do |journey_route|
|
67
89
|
# Skip internals, endpoints that Rails adds by default
|
68
90
|
# Also Engines should be skipped since Engine's tests should be done in Engine
|
69
91
|
wrapper = RouteWrapper.new(journey_route)
|
70
|
-
wrapper.internal? || wrapper.
|
92
|
+
wrapper.internal? || !wrapper.defaults[:controller] || !wrapper.defaults[:action] || wrapper.path.start_with?('/rails/')
|
71
93
|
end
|
72
94
|
end
|
73
95
|
end
|
data/route_mechanic.gemspec
CHANGED
@@ -8,12 +8,12 @@ Gem::Specification.new do |spec|
|
|
8
8
|
|
9
9
|
spec.summary = %q{RouteMechanic detects broken routes with ease}
|
10
10
|
spec.description = %q{No need to maintain Rails' routing tests manually. RouteMechanic automatically detects broken routes and missing action methods in controller once you've finished installation.}
|
11
|
-
spec.homepage = "https://github.com/ohbarye/
|
11
|
+
spec.homepage = "https://github.com/ohbarye/route_mechanic"
|
12
12
|
spec.license = "MIT"
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
14
|
|
15
15
|
spec.metadata["homepage_uri"] = spec.homepage
|
16
|
-
spec.metadata["source_code_uri"] = "https://github.com/ohbarye/
|
16
|
+
spec.metadata["source_code_uri"] = "https://github.com/ohbarye/route_mechanic"
|
17
17
|
|
18
18
|
# Specify which files should be added to the gem when it is released.
|
19
19
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -25,4 +25,5 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
27
|
spec.add_runtime_dependency "actionpack", ">= 4.2", "< 6.1"
|
28
|
+
spec.add_runtime_dependency "regexp-examples", ">= 1.5", "< 2"
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: route_mechanic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ohbarye
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -30,6 +30,26 @@ dependencies:
|
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '6.1'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: regexp-examples
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.5'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '2'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.5'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '2'
|
33
53
|
description: No need to maintain Rails' routing tests manually. RouteMechanic automatically
|
34
54
|
detects broken routes and missing action methods in controller once you've finished
|
35
55
|
installation.
|
@@ -39,9 +59,9 @@ executables: []
|
|
39
59
|
extensions: []
|
40
60
|
extra_rdoc_files: []
|
41
61
|
files:
|
62
|
+
- ".github/workflows/test.yml"
|
42
63
|
- ".gitignore"
|
43
64
|
- ".rspec"
|
44
|
-
- ".travis.yml"
|
45
65
|
- CODE_OF_CONDUCT.md
|
46
66
|
- Gemfile
|
47
67
|
- LICENSE.txt
|
@@ -51,6 +71,7 @@ files:
|
|
51
71
|
- bin/setup
|
52
72
|
- fixtures/fake_app/app/controllers/application_controller.rb
|
53
73
|
- fixtures/fake_app/app/controllers/users_controller.rb
|
74
|
+
- fixtures/fake_app/lib/engine.rb
|
54
75
|
- fixtures/fake_app/rails_app.rb
|
55
76
|
- lib/route_mechanic.rb
|
56
77
|
- lib/route_mechanic/rspec/matchers.rb
|
@@ -61,12 +82,12 @@ files:
|
|
61
82
|
- lib/route_mechanic/testing/route_wrapper.rb
|
62
83
|
- lib/route_mechanic/version.rb
|
63
84
|
- route_mechanic.gemspec
|
64
|
-
homepage: https://github.com/ohbarye/
|
85
|
+
homepage: https://github.com/ohbarye/route_mechanic
|
65
86
|
licenses:
|
66
87
|
- MIT
|
67
88
|
metadata:
|
68
|
-
homepage_uri: https://github.com/ohbarye/
|
69
|
-
source_code_uri: https://github.com/ohbarye/
|
89
|
+
homepage_uri: https://github.com/ohbarye/route_mechanic
|
90
|
+
source_code_uri: https://github.com/ohbarye/route_mechanic
|
70
91
|
post_install_message:
|
71
92
|
rdoc_options: []
|
72
93
|
require_paths:
|