rails-rfc6570 2.0.0 → 2.5.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/CHANGELOG.md +50 -0
- data/README.md +4 -4
- data/lib/rails/rfc6570.rb +45 -208
- data/lib/rails/rfc6570/formatter.rb +52 -0
- data/lib/rails/rfc6570/patches.rb +2 -0
- data/lib/rails/rfc6570/version.rb +3 -1
- data/lib/rails/rfc6570/visitor.rb +119 -0
- data/rails-rfc6570.gemspec +13 -12
- data/spec/dummy/log/test.log +2685 -658
- data/spec/rails/rfc6570/visitor_spec.rb +133 -0
- data/spec/{rfc6570_spec.rb → rails/rfc6570_spec.rb} +51 -21
- data/spec/spec_helper.rb +13 -7
- metadata +17 -14
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe ::Rails::RFC6570::Visitor do
|
6
|
+
subject(:accept) { visitor.accept(node) }
|
7
|
+
|
8
|
+
let(:visitor) { described_class.new }
|
9
|
+
let(:node) { ::ActionDispatch::Journey::Parser.new.parse(path) }
|
10
|
+
|
11
|
+
describe '/' do
|
12
|
+
let(:path) { '/' }
|
13
|
+
|
14
|
+
it { is_expected.to eq %w[/] }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '/path/path' do
|
18
|
+
let(:path) { '/path/path' }
|
19
|
+
|
20
|
+
it { is_expected.to eq %w[/ path / path] }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '/:title' do
|
24
|
+
let(:path) { '/:title' }
|
25
|
+
|
26
|
+
it { is_expected.to eq %w[/ {title}] }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '/:title(.:format)' do
|
30
|
+
let(:path) { '/:title(.:format)' }
|
31
|
+
|
32
|
+
it { is_expected.to eq %w[/ {title} {.format}] }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '/path/:title' do
|
36
|
+
let(:path) { '/path/:title' }
|
37
|
+
|
38
|
+
it { is_expected.to eq %w[/ path / {title}] }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '/path/pre-(:id)-post' do
|
42
|
+
let(:path) { '/path/pre-(:id)-post' }
|
43
|
+
|
44
|
+
it { is_expected.to eq %w[/ path / pre- {id} -post] }
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '/path(/:title)' do
|
48
|
+
let(:path) { '/path(/:title)' }
|
49
|
+
|
50
|
+
it { is_expected.to eq %w[/ path {/title}] }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '/path/*capture/:title' do
|
54
|
+
let(:path) { '/path/*capture/:title' }
|
55
|
+
|
56
|
+
it { is_expected.to eq %w[/ path {/capture*} / {title}] }
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '/path(/*capture)/:title' do
|
60
|
+
let(:path) { '/path(/*capture)/:title' }
|
61
|
+
|
62
|
+
it { is_expected.to eq %w[/ path {/capture*} / {title}] }
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '/path(/*capture)(/:title)' do
|
66
|
+
let(:path) { '/path(/*capture)(/:title)' }
|
67
|
+
|
68
|
+
it { is_expected.to eq %w[/ path {/capture*} {/title}] }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '*a/path/*b' do
|
72
|
+
let(:path) { '*a/path/*b' }
|
73
|
+
|
74
|
+
it { is_expected.to eq %w[{/a*} / path {/b*}] }
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'path/*a/path/*b' do
|
78
|
+
let(:path) { 'path/*a/path/*b' }
|
79
|
+
|
80
|
+
it { is_expected.to eq %w[path {/a*} / path {/b*}] }
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'path/*a/*b' do
|
84
|
+
let(:path) { 'path/*a/*b' }
|
85
|
+
|
86
|
+
it { is_expected.to eq %w[path {/a*} {/b*}] }
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'path/*a/:title' do
|
90
|
+
let(:path) { 'path/*a/:title' }
|
91
|
+
|
92
|
+
it { is_expected.to eq %w[path {/a*} / {title}] }
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'path/*a(/:title)' do
|
96
|
+
let(:path) { 'path/*a(/:title)' }
|
97
|
+
|
98
|
+
it { is_expected.to eq %w[path {/a*} {/title}] }
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '/(:title)' do
|
102
|
+
let(:path) { '/(:title)' }
|
103
|
+
|
104
|
+
it { is_expected.to eq %w[/ {title}] }
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '(/:title)' do
|
108
|
+
let(:path) { '(/:title)' }
|
109
|
+
|
110
|
+
it { is_expected.to eq %w[{/title}] }
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '(/:title/)' do
|
114
|
+
let(:path) { '(/:title/)' }
|
115
|
+
|
116
|
+
it { is_expected.to eq %w[{/title} /] }
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '(/:a(/:b))' do
|
120
|
+
let(:path) { '(/:a(/:b))' }
|
121
|
+
|
122
|
+
it { is_expected.to eq %w[{/a} {/b}] }
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '(/a)|(/b)' do
|
126
|
+
let(:path) { '(/a)|(/b)' }
|
127
|
+
|
128
|
+
it do
|
129
|
+
expect { accept }.to \
|
130
|
+
raise_error 'OR nodes cannot be serialized to URI templates'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
4
6
|
inflect.acronym 'API'
|
5
7
|
end
|
6
8
|
|
7
|
-
|
8
9
|
Dummy::Application.routes.draw do
|
9
10
|
get '/' => 'api#index', as: :root
|
10
11
|
|
11
|
-
|
12
|
+
# Unnamed routes should be ignored
|
13
|
+
get '/path/to/unnamed' => 'api#index', as: nil
|
12
14
|
|
13
15
|
get '/action' => 'api#action', as: :action
|
14
16
|
|
@@ -25,16 +27,26 @@ class APIController < ApplicationController
|
|
25
27
|
render json: rfc6570_routes
|
26
28
|
end
|
27
29
|
|
28
|
-
rfc6570_params action: [
|
30
|
+
rfc6570_params action: %i[param1 param2]
|
29
31
|
def action
|
30
32
|
render json: {
|
33
|
+
ref: action_url,
|
31
34
|
template: action_rfc6570,
|
32
35
|
template_url: action_url_rfc6570,
|
33
36
|
template_path: action_path_rfc6570,
|
34
37
|
partial: test6_rfc6570.partial_expand(title: 'TITLE'),
|
35
|
-
|
38
|
+
ignore: test6_rfc6570(ignore: %w[title]),
|
39
|
+
expand: test6_rfc6570.expand(capture: %w[a b], title: 'TITLE')
|
36
40
|
}
|
37
41
|
end
|
42
|
+
|
43
|
+
def default_url_options
|
44
|
+
if (root = request.headers['__OSN']).present?
|
45
|
+
super.merge original_script_name: root
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
38
50
|
end
|
39
51
|
|
40
52
|
describe Rails::RFC6570, type: :request do
|
@@ -44,64 +56,82 @@ describe Rails::RFC6570, type: :request do
|
|
44
56
|
context 'root' do
|
45
57
|
before { get '/' }
|
46
58
|
|
47
|
-
it '
|
48
|
-
expect(json.keys).to match_array
|
59
|
+
it 'returns list of all parsed and named routes' do
|
60
|
+
expect(json.keys).to match_array \
|
61
|
+
%w[root action test1 test2 test3 test4 test5 test6]
|
49
62
|
end
|
50
63
|
|
51
|
-
it '
|
64
|
+
it 'includes known parameters' do
|
52
65
|
expect(json['action']).to eq "#{host}/action{?param1,param2}"
|
53
66
|
end
|
54
67
|
|
55
|
-
it '
|
68
|
+
it 'parses capture symbols' do
|
56
69
|
expect(json['test1']).to eq "#{host}/path/{title}"
|
57
70
|
end
|
58
71
|
|
59
|
-
it '
|
72
|
+
it 'parses capture group' do
|
60
73
|
expect(json['test2']).to eq "#{host}/path/pp-{title}-abc"
|
61
74
|
end
|
62
75
|
|
63
|
-
it '
|
76
|
+
it 'parses capture group with slash included' do
|
64
77
|
expect(json['test3']).to eq "#{host}/path{/title}"
|
65
78
|
end
|
66
79
|
|
67
|
-
it '
|
80
|
+
it 'parses splash operator (I)' do
|
68
81
|
expect(json['test4']).to eq "#{host}/path{/capture*}/{title}"
|
69
82
|
end
|
70
83
|
|
71
|
-
it '
|
84
|
+
it 'parses splash operator (II)' do
|
72
85
|
expect(json['test5']).to eq "#{host}/path{/capture*}/{title}"
|
73
86
|
end
|
74
87
|
|
75
|
-
it '
|
88
|
+
it 'parses splash operator (III)' do
|
76
89
|
expect(json['test6']).to eq "#{host}/path{/capture*}{/title}"
|
77
90
|
end
|
78
91
|
end
|
79
92
|
|
80
93
|
context 'action' do
|
81
|
-
before { get '/action' }
|
94
|
+
before { get '/action', headers: headers }
|
82
95
|
|
83
|
-
it '
|
96
|
+
it 'includes URL helpers' do
|
84
97
|
expect(response.status).to eq 200
|
85
98
|
end
|
86
99
|
|
87
|
-
it '
|
100
|
+
it 'allows to return and render templates' do
|
88
101
|
expect(json['template']).to eq "#{host}/action{?param1,param2}"
|
89
102
|
end
|
90
103
|
|
91
|
-
it '
|
104
|
+
it 'allows to return and render url templates' do
|
92
105
|
expect(json['template_url']).to eq "#{host}/action{?param1,param2}"
|
93
106
|
end
|
94
107
|
|
95
|
-
it '
|
96
|
-
expect(json['template_path']).to eq
|
108
|
+
it 'allows to return and render path templates' do
|
109
|
+
expect(json['template_path']).to eq '/action{?param1,param2}'
|
97
110
|
end
|
98
111
|
|
99
|
-
it '
|
112
|
+
it 'allows to return and render partial expanded templates' do
|
100
113
|
expect(json['partial']).to eq "#{host}/path{/capture*}/TITLE"
|
101
114
|
end
|
102
115
|
|
103
|
-
it '
|
116
|
+
it 'allows to return and render expanded templates (I)' do
|
117
|
+
expect(json['ignore']).to eq "#{host}/path{/capture*}{.format}"
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'allows to return and render expanded templates (II)' do
|
104
121
|
expect(json['expand']).to eq "#{host}/path/a/b/TITLE"
|
105
122
|
end
|
123
|
+
|
124
|
+
context 'with origin_script_name' do
|
125
|
+
let(:headers) { {'__OSN' => '/fuubar'} }
|
126
|
+
|
127
|
+
before do
|
128
|
+
# Consistency check with normal URL helper
|
129
|
+
expect(json['ref']).to eq "#{host}/fuubar/action"
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'prefixes origin script name' do
|
133
|
+
expect(json['template']).to eq "#{host}/fuubar/action{?param1,param2}"
|
134
|
+
end
|
135
|
+
end
|
106
136
|
end
|
107
137
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,23 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Coverage
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start
|
6
|
+
|
7
|
+
if ENV['CI']
|
8
|
+
require 'codecov'
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
5
10
|
end
|
6
11
|
|
7
|
-
#
|
8
12
|
ENV['RAILS_ENV'] ||= 'test'
|
9
|
-
require File.expand_path('
|
13
|
+
require File.expand_path('dummy/config/environment', __dir__)
|
10
14
|
require 'rspec/rails'
|
11
15
|
|
12
16
|
Rails.backtrace_cleaner.remove_silencers!
|
13
17
|
|
14
18
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
15
19
|
# in spec/support/ and its subdirectories.
|
16
|
-
Dir[File.expand_path('
|
20
|
+
Dir[File.expand_path('support/**/*.rb', __dir__)].sort.each {|f| require f }
|
17
21
|
|
18
22
|
# Checks for pending migrations before tests are run.
|
19
23
|
# If you are not using ActiveRecord, you can remove this line.
|
20
|
-
|
24
|
+
if defined?(ActiveRecord::Migration) && Rails::VERSION::MAJOR >= 4
|
25
|
+
ActiveRecord::Migration.check_pending!
|
26
|
+
end
|
21
27
|
|
22
28
|
RSpec.configure do |config|
|
23
29
|
config.order = 'random'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-rfc6570
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Graichen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '4.2'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '6.2'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: '4.2'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '6.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: addressable
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -48,19 +48,19 @@ dependencies:
|
|
48
48
|
name: bundler
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '0'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - "
|
58
|
+
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
61
|
-
description:
|
60
|
+
version: '0'
|
61
|
+
description:
|
62
62
|
email:
|
63
|
-
-
|
63
|
+
- jgraichen@altimos.de
|
64
64
|
executables: []
|
65
65
|
extensions: []
|
66
66
|
extra_rdoc_files: []
|
@@ -69,8 +69,10 @@ files:
|
|
69
69
|
- LICENSE.txt
|
70
70
|
- README.md
|
71
71
|
- lib/rails/rfc6570.rb
|
72
|
+
- lib/rails/rfc6570/formatter.rb
|
72
73
|
- lib/rails/rfc6570/patches.rb
|
73
74
|
- lib/rails/rfc6570/version.rb
|
75
|
+
- lib/rails/rfc6570/visitor.rb
|
74
76
|
- rails-rfc6570.gemspec
|
75
77
|
- spec/dummy/README.rdoc
|
76
78
|
- spec/dummy/Rakefile
|
@@ -101,7 +103,8 @@ files:
|
|
101
103
|
- spec/dummy/public/422.html
|
102
104
|
- spec/dummy/public/500.html
|
103
105
|
- spec/dummy/public/favicon.ico
|
104
|
-
- spec/
|
106
|
+
- spec/rails/rfc6570/visitor_spec.rb
|
107
|
+
- spec/rails/rfc6570_spec.rb
|
105
108
|
- spec/spec_helper.rb
|
106
109
|
homepage: https://github.com/jgraichen/rails-rfc6570
|
107
110
|
licenses:
|
@@ -122,8 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
125
|
- !ruby/object:Gem::Version
|
123
126
|
version: '0'
|
124
127
|
requirements: []
|
125
|
-
|
126
|
-
rubygems_version: 2.6.11
|
128
|
+
rubygems_version: 3.1.2
|
127
129
|
signing_key:
|
128
130
|
specification_version: 4
|
129
131
|
summary: Pragmatical access to your Rails routes as RFC6570 URI templates.
|
@@ -157,5 +159,6 @@ test_files:
|
|
157
159
|
- spec/dummy/public/422.html
|
158
160
|
- spec/dummy/public/500.html
|
159
161
|
- spec/dummy/public/favicon.ico
|
160
|
-
- spec/
|
162
|
+
- spec/rails/rfc6570/visitor_spec.rb
|
163
|
+
- spec/rails/rfc6570_spec.rb
|
161
164
|
- spec/spec_helper.rb
|