route_mechanic 0.1.1 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2378e095ad88def369adb3b2b271a9e324a853b535670e3b1be95f4e98d2ee0
4
- data.tar.gz: 12f172bb4021e0c56e4ea740a269d10e41a2c67d2f3f040137882dc414ffe448
3
+ metadata.gz: a9ff0ae5fc0f5045075d58e1a353cb60c7dd440a2a964b2990b12f5298493496
4
+ data.tar.gz: b8b517e7f557d648aee51cb1f6e61cb151058cbf2bd662df11783a67c0d05378
5
5
  SHA512:
6
- metadata.gz: 3ee458593e8f2e095c11cb2ce1f36095c50d53eacab10e72032429b4514641d1afe676a37082121c629ba7c23e1ede37362a3ee0ce563caf35f76bf0760bb2ae
7
- data.tar.gz: 3079f7b95a27e7c2c3bddd735352283f85cd6f83e362398406c70206160783dba53a83cfe35daf42ab2965857b445dac148d53cbf1cff29fbbb338443c9f7bde
6
+ metadata.gz: ab4884a5c8f220562e025581a1aad63b66221b15e573a97fc3d0b1517149ff78cb4beb493c1f4ee58077f4ec97ebfc3d81c98673854032c3e23dac132d2368d3
7
+ data.tar.gz: c054466bbe6a7750fde4eb1563b82d819a51d0f4e638b11309f2ee8962fa67503c3a5f976232d02d68b873f550e7f5aa175ab6b27327942ddb88322b34f7937d
@@ -23,7 +23,6 @@ jobs:
23
23
  fail-fast: false
24
24
  matrix:
25
25
  ruby:
26
- - ruby:2.3
27
26
  - ruby:2.4
28
27
  - ruby:2.5
29
28
  - ruby:2.6
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  /fixtures/fake_app/log/
11
11
  /fixtures/fake_app/tmp/
12
12
  /.rspec_status
13
+ /.byebug_history
data/Gemfile CHANGED
@@ -7,3 +7,4 @@ gem "rake", "~> 12.0"
7
7
  gem "minitest", "~> 5.0"
8
8
  gem "rspec", "~> 3.0"
9
9
  gem "rails"
10
+ gem "byebug"
data/README.md CHANGED
@@ -33,7 +33,7 @@ Just add a test file which has only one test case using `have_valid_routes` matc
33
33
  ```ruby
34
34
  RSpec.describe 'Rails.application', type: :routing do
35
35
  it "fails if application does not have valid routes" do
36
- expect(Rails.application.routes).to have_valid_routes
36
+ expect(Rails.application).to have_valid_routes
37
37
  end
38
38
  end
39
39
  ```
@@ -0,0 +1,5 @@
1
+ module FakeEngine
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace FakeEngine
4
+ end
5
+ end
@@ -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,20 @@ 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'
27
+ post 'create_as_another_name', to: 'users#create'
13
28
  end
14
29
  end
@@ -8,7 +8,7 @@ module RouteMechanic
8
8
  include ::RSpec::Matchers::Composable
9
9
  include RouteMechanic::Testing::Methods
10
10
 
11
- # @param [ActionDispatch::Routing::RouteSet] expected
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(routes=Rails.application.routes)
46
- HaveValidRoutes.new(routes)
45
+ def have_valid_routes(application=Rails.application)
46
+ HaveValidRoutes.new(application)
47
47
  end
48
48
  end
49
49
  end
@@ -40,15 +40,15 @@ module RouteMechanic
40
40
  @controllers.each do |controller|
41
41
  controller_path = controller.controller_path
42
42
  controller.action_methods.each do |action_method|
43
- journey_route = @routes.detect do |route|
43
+ journey_routes = @routes.select do |route|
44
44
  route.defaults[:controller].to_sym == controller_path.to_sym && route.defaults[:action].to_sym == action_method.to_sym
45
45
  end
46
46
 
47
- if journey_route
48
- wrapper = RouteWrapper.new journey_route
49
- @controller_routes << wrapper
50
- else
47
+ if journey_routes.empty?
51
48
  @controller_routes_errors << { controller: controller, action: action_method }
49
+ else
50
+ wrappers = journey_routes.map { |r| RouteWrapper.new(r) }
51
+ @controller_routes.concat(wrappers)
52
52
  end
53
53
  end
54
54
  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 [ActionDispatch::Routing::RouteSet] routes
14
+ # @param [Rails::Application] application
14
15
  # @raise [Minitest::Assertion]
15
- def assert_all_routes(routes=Rails.application.routes)
16
- # assert_routing expect @routes to exists as like this class inherits ActionController::TestCase.
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
- memo.merge({ required_part => '1' }) # '1' is pseudo id
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 = @routes.url_helpers.url_for(
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
- assert_routing({ path: url, method: wrapper.verb }, expected_options)
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>]
@@ -62,11 +85,11 @@ module RouteMechanic
62
85
 
63
86
  # @return [Array<ActionDispatch::Journey::Route>]
64
87
  def target_routes
65
- @routes.routes.reject do |journey_route|
88
+ routes.routes.reject do |journey_route|
66
89
  # Skip internals, endpoints that Rails adds by default
67
90
  # Also Engines should be skipped since Engine's tests should be done in Engine
68
91
  wrapper = RouteWrapper.new(journey_route)
69
- wrapper.internal? || wrapper.required_defaults.empty? || wrapper.path.start_with?('/rails/')
92
+ wrapper.internal? || !wrapper.defaults[:controller] || !wrapper.defaults[:action] || wrapper.path.start_with?('/rails/')
70
93
  end
71
94
  end
72
95
  end
@@ -1,3 +1,3 @@
1
1
  module RouteMechanic
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
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
11
  spec.homepage = "https://github.com/ohbarye/route_mechanic"
12
12
  spec.license = "MIT"
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
14
14
 
15
15
  spec.metadata["homepage_uri"] = spec.homepage
16
16
  spec.metadata["source_code_uri"] = "https://github.com/ohbarye/route_mechanic"
@@ -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.1
4
+ version: 0.1.6
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-19 00:00:00.000000000 Z
11
+ date: 2020-09-22 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.
@@ -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
@@ -75,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
96
  requirements:
76
97
  - - ">="
77
98
  - !ruby/object:Gem::Version
78
- version: 2.3.0
99
+ version: 2.4.0
79
100
  required_rubygems_version: !ruby/object:Gem::Requirement
80
101
  requirements:
81
102
  - - ">="