grape-app 0.8.2 → 0.8.7
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/.rubocop.yml +9 -3
- data/.travis.yml +1 -1
- data/Gemfile.lock +102 -56
- data/grape-app.gemspec +4 -3
- data/lib/grape/app.rb +8 -4
- data/lib/grape/app/cli.rb +1 -2
- data/lib/grape/app/configuration.rb +0 -2
- data/lib/grape/app/helpers/caching.rb +4 -5
- data/lib/grape/app/helpers/respond_with.rb +1 -1
- data/lib/grape/app/tasks/databases.rake +2 -4
- data/lib/grape/app/templates/app/api/v1.rb +1 -2
- data/lib/grape/app/templates/config/environments/production.rb +4 -2
- data/lib/grape/app/templates/spec/spec_helper.rb +1 -1
- data/spec/grape/app/helpers/caching_spec.rb +19 -3
- data/spec/grape/app/helpers/params_spec.rb +2 -1
- data/spec/grape/app_spec.rb +10 -9
- data/spec/scenario/app/api/posts.rb +1 -1
- data/spec/scenario/app/api/v1.rb +1 -1
- data/spec/spec_helper.rb +14 -4
- metadata +19 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: feff7b4ee1c4e672754a8e9e85f4c80016e2414a6f81b10d40cb8cea5ccdc900
|
|
4
|
+
data.tar.gz: 15ede4a9152b0e274041a1f0a94c0edd9eaaaabc3ca6be7fd28e5a50041f54ed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: adf69f2a62a197ac8393abbf00da46b093313900701cbdb9b3ab76cc21e78331c20ebfbbde3131e023a014b0dae76946a6949f275e0bc8cd5fc7f3ea27c552d0
|
|
7
|
+
data.tar.gz: b5f4919555de644ba358415a2473ef6ea51d290d32acc82b2e52baf6919a245f3e7fa1bc79ec08b9f7c53a0afacc8ac89d4e62d69eb1b549956111f4c7c4769a
|
data/.rubocop.yml
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
-
|
|
1
|
+
inherit_gem:
|
|
2
|
+
rubocop-bsm:
|
|
3
|
+
- default.yml
|
|
4
|
+
inherit_mode:
|
|
5
|
+
merge:
|
|
6
|
+
- Exclude
|
|
3
7
|
|
|
4
8
|
AllCops:
|
|
5
|
-
TargetRubyVersion: "2.
|
|
9
|
+
TargetRubyVersion: "2.6"
|
|
6
10
|
Metrics/ParameterLists:
|
|
7
11
|
Exclude:
|
|
8
12
|
- lib/grape/app/helpers/caching.rb
|
|
13
|
+
Rake/Desc:
|
|
14
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
grape-app (0.8.
|
|
4
|
+
grape-app (0.8.7)
|
|
5
5
|
activesupport
|
|
6
6
|
grape (>= 1.2)
|
|
7
7
|
grape-entity
|
|
@@ -13,95 +13,140 @@ PATH
|
|
|
13
13
|
GEM
|
|
14
14
|
remote: https://rubygems.org/
|
|
15
15
|
specs:
|
|
16
|
-
activemodel (6.
|
|
17
|
-
activesupport (= 6.
|
|
18
|
-
activerecord (6.
|
|
19
|
-
activemodel (= 6.
|
|
20
|
-
activesupport (= 6.
|
|
21
|
-
activesupport (6.
|
|
16
|
+
activemodel (6.1.1)
|
|
17
|
+
activesupport (= 6.1.1)
|
|
18
|
+
activerecord (6.1.1)
|
|
19
|
+
activemodel (= 6.1.1)
|
|
20
|
+
activesupport (= 6.1.1)
|
|
21
|
+
activesupport (6.1.1)
|
|
22
22
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
23
|
-
i18n (>=
|
|
24
|
-
minitest (
|
|
25
|
-
tzinfo (~>
|
|
26
|
-
zeitwerk (~> 2.
|
|
27
|
-
ast (2.4.
|
|
23
|
+
i18n (>= 1.6, < 2)
|
|
24
|
+
minitest (>= 5.1)
|
|
25
|
+
tzinfo (~> 2.0)
|
|
26
|
+
zeitwerk (~> 2.3)
|
|
27
|
+
ast (2.4.1)
|
|
28
28
|
axiom-types (0.1.1)
|
|
29
29
|
descendants_tracker (~> 0.0.4)
|
|
30
30
|
ice_nine (~> 0.11.0)
|
|
31
31
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
32
|
-
builder (3.2.
|
|
32
|
+
builder (3.2.4)
|
|
33
33
|
coercible (1.0.0)
|
|
34
34
|
descendants_tracker (~> 0.0.1)
|
|
35
|
-
concurrent-ruby (1.1.
|
|
35
|
+
concurrent-ruby (1.1.7)
|
|
36
36
|
descendants_tracker (0.0.4)
|
|
37
37
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
38
|
-
diff-lcs (1.
|
|
38
|
+
diff-lcs (1.4.4)
|
|
39
|
+
dry-configurable (0.12.0)
|
|
40
|
+
concurrent-ruby (~> 1.0)
|
|
41
|
+
dry-core (~> 0.5, >= 0.5.0)
|
|
42
|
+
dry-container (0.7.2)
|
|
43
|
+
concurrent-ruby (~> 1.0)
|
|
44
|
+
dry-configurable (~> 0.1, >= 0.1.3)
|
|
45
|
+
dry-core (0.5.0)
|
|
46
|
+
concurrent-ruby (~> 1.0)
|
|
47
|
+
dry-equalizer (0.3.0)
|
|
48
|
+
dry-inflector (0.2.0)
|
|
49
|
+
dry-logic (1.1.0)
|
|
50
|
+
concurrent-ruby (~> 1.0)
|
|
51
|
+
dry-core (~> 0.5, >= 0.5)
|
|
52
|
+
dry-types (1.4.0)
|
|
53
|
+
concurrent-ruby (~> 1.0)
|
|
54
|
+
dry-container (~> 0.3)
|
|
55
|
+
dry-core (~> 0.4, >= 0.4.4)
|
|
56
|
+
dry-equalizer (~> 0.3)
|
|
57
|
+
dry-inflector (~> 0.1, >= 0.1.2)
|
|
58
|
+
dry-logic (~> 1.0, >= 1.0.2)
|
|
39
59
|
equalizer (0.0.11)
|
|
40
|
-
grape (1.
|
|
60
|
+
grape (1.5.1)
|
|
41
61
|
activesupport
|
|
42
62
|
builder
|
|
63
|
+
dry-types (>= 1.1)
|
|
43
64
|
mustermann-grape (~> 1.0.0)
|
|
44
65
|
rack (>= 1.3.0)
|
|
45
66
|
rack-accept
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
activesupport (>= 4.0)
|
|
67
|
+
grape-entity (0.8.2)
|
|
68
|
+
activesupport (>= 3.0.0)
|
|
49
69
|
multi_json (>= 1.3.2)
|
|
50
|
-
i18n (1.7
|
|
70
|
+
i18n (1.8.7)
|
|
51
71
|
concurrent-ruby (~> 1.0)
|
|
52
72
|
ice_nine (0.11.2)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
mustermann-grape (1.0.
|
|
58
|
-
mustermann (
|
|
59
|
-
parallel (1.
|
|
60
|
-
parser (
|
|
61
|
-
ast (~> 2.4.
|
|
62
|
-
rack (2.
|
|
73
|
+
minitest (5.14.3)
|
|
74
|
+
multi_json (1.15.0)
|
|
75
|
+
mustermann (1.1.1)
|
|
76
|
+
ruby2_keywords (~> 0.0.1)
|
|
77
|
+
mustermann-grape (1.0.1)
|
|
78
|
+
mustermann (>= 1.0.0)
|
|
79
|
+
parallel (1.20.1)
|
|
80
|
+
parser (3.0.0.0)
|
|
81
|
+
ast (~> 2.4.1)
|
|
82
|
+
rack (2.2.3)
|
|
63
83
|
rack-accept (0.4.5)
|
|
64
84
|
rack (>= 0.4)
|
|
65
|
-
rack-cors (1.1.
|
|
85
|
+
rack-cors (1.1.1)
|
|
66
86
|
rack (>= 2.0.0)
|
|
67
87
|
rack-ssl-enforcer (0.2.9)
|
|
68
88
|
rack-test (1.1.0)
|
|
69
89
|
rack (>= 1.0, < 3)
|
|
70
90
|
rainbow (3.0.0)
|
|
71
|
-
rake (13.0.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
rspec-
|
|
76
|
-
|
|
77
|
-
rspec-
|
|
78
|
-
rspec-
|
|
91
|
+
rake (13.0.3)
|
|
92
|
+
regexp_parser (2.0.3)
|
|
93
|
+
rexml (3.2.4)
|
|
94
|
+
rspec (3.10.0)
|
|
95
|
+
rspec-core (~> 3.10.0)
|
|
96
|
+
rspec-expectations (~> 3.10.0)
|
|
97
|
+
rspec-mocks (~> 3.10.0)
|
|
98
|
+
rspec-core (3.10.1)
|
|
99
|
+
rspec-support (~> 3.10.0)
|
|
100
|
+
rspec-expectations (3.10.1)
|
|
79
101
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
80
|
-
rspec-support (~> 3.
|
|
81
|
-
rspec-mocks (3.
|
|
102
|
+
rspec-support (~> 3.10.0)
|
|
103
|
+
rspec-mocks (3.10.1)
|
|
82
104
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
83
|
-
rspec-support (~> 3.
|
|
84
|
-
rspec-support (3.
|
|
85
|
-
rubocop (
|
|
86
|
-
jaro_winkler (~> 1.5.1)
|
|
105
|
+
rspec-support (~> 3.10.0)
|
|
106
|
+
rspec-support (3.10.1)
|
|
107
|
+
rubocop (1.8.1)
|
|
87
108
|
parallel (~> 1.10)
|
|
88
|
-
parser (>=
|
|
109
|
+
parser (>= 3.0.0.0)
|
|
89
110
|
rainbow (>= 2.2.2, < 4.0)
|
|
111
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
112
|
+
rexml
|
|
113
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
|
90
114
|
ruby-progressbar (~> 1.7)
|
|
91
|
-
unicode-display_width (>= 1.4.0, <
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
115
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
116
|
+
rubocop-ast (1.4.0)
|
|
117
|
+
parser (>= 2.7.1.5)
|
|
118
|
+
rubocop-bsm (0.5.4)
|
|
119
|
+
rubocop (~> 1.0)
|
|
120
|
+
rubocop-performance
|
|
121
|
+
rubocop-rails
|
|
122
|
+
rubocop-rake
|
|
123
|
+
rubocop-rspec
|
|
124
|
+
rubocop-performance (1.9.2)
|
|
125
|
+
rubocop (>= 0.90.0, < 2.0)
|
|
126
|
+
rubocop-ast (>= 0.4.0)
|
|
127
|
+
rubocop-rails (2.9.1)
|
|
128
|
+
activesupport (>= 4.2.0)
|
|
129
|
+
rack (>= 1.1)
|
|
130
|
+
rubocop (>= 0.90.0, < 2.0)
|
|
131
|
+
rubocop-rake (0.5.1)
|
|
132
|
+
rubocop
|
|
133
|
+
rubocop-rspec (2.1.0)
|
|
134
|
+
rubocop (~> 1.0)
|
|
135
|
+
rubocop-ast (>= 1.1.0)
|
|
136
|
+
ruby-progressbar (1.11.0)
|
|
137
|
+
ruby2_keywords (0.0.3)
|
|
138
|
+
sqlite3 (1.4.2)
|
|
139
|
+
thor (1.0.1)
|
|
95
140
|
thread_safe (0.3.6)
|
|
96
|
-
tzinfo (
|
|
97
|
-
|
|
98
|
-
unicode-display_width (
|
|
141
|
+
tzinfo (2.0.4)
|
|
142
|
+
concurrent-ruby (~> 1.0)
|
|
143
|
+
unicode-display_width (2.0.0)
|
|
99
144
|
virtus (1.0.5)
|
|
100
145
|
axiom-types (~> 0.1)
|
|
101
146
|
coercible (~> 1.0)
|
|
102
147
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
|
103
148
|
equalizer (~> 0.0, >= 0.0.9)
|
|
104
|
-
zeitwerk (2.2
|
|
149
|
+
zeitwerk (2.4.2)
|
|
105
150
|
|
|
106
151
|
PLATFORMS
|
|
107
152
|
ruby
|
|
@@ -113,8 +158,9 @@ DEPENDENCIES
|
|
|
113
158
|
rack-test
|
|
114
159
|
rake
|
|
115
160
|
rspec
|
|
116
|
-
rubocop
|
|
161
|
+
rubocop-bsm
|
|
117
162
|
sqlite3
|
|
163
|
+
virtus
|
|
118
164
|
|
|
119
165
|
BUNDLED WITH
|
|
120
|
-
2.
|
|
166
|
+
2.2.5
|
data/grape-app.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'grape-app'
|
|
3
|
-
s.version = '0.8.
|
|
3
|
+
s.version = '0.8.7'
|
|
4
4
|
s.authors = ['Black Square Media Ltd']
|
|
5
5
|
s.email = ['info@blacksquaremedia.com']
|
|
6
6
|
s.summary = %(Standalone Grape API apps)
|
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
|
12
12
|
s.test_files = `git ls-files -z -- spec/*`.split("\x0")
|
|
13
13
|
s.executables = ['grape-app']
|
|
14
14
|
s.require_paths = ['lib']
|
|
15
|
-
s.required_ruby_version = '>= 2.
|
|
15
|
+
s.required_ruby_version = '>= 2.6'
|
|
16
16
|
|
|
17
17
|
s.add_dependency 'activesupport'
|
|
18
18
|
s.add_dependency 'grape', '>= 1.2'
|
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
|
27
27
|
s.add_development_dependency 'rack-test'
|
|
28
28
|
s.add_development_dependency 'rake'
|
|
29
29
|
s.add_development_dependency 'rspec'
|
|
30
|
-
s.add_development_dependency 'rubocop'
|
|
30
|
+
s.add_development_dependency 'rubocop-bsm'
|
|
31
31
|
s.add_development_dependency 'sqlite3'
|
|
32
|
+
s.add_development_dependency 'virtus'
|
|
32
33
|
end
|
data/lib/grape/app.rb
CHANGED
|
@@ -8,11 +8,10 @@ require 'rack/cors'
|
|
|
8
8
|
require 'rack/ssl-enforcer'
|
|
9
9
|
require 'zeitwerk'
|
|
10
10
|
|
|
11
|
-
class Grape::App < Grape::API
|
|
11
|
+
class Grape::App < Grape::API
|
|
12
12
|
class << self
|
|
13
|
-
|
|
14
13
|
# Run initializers
|
|
15
|
-
def init!(root=nil)
|
|
14
|
+
def init!(root = nil)
|
|
16
15
|
@root = Pathname.new(root) if root
|
|
17
16
|
|
|
18
17
|
# Require bundle
|
|
@@ -73,7 +72,12 @@ class Grape::App < Grape::API::Instance
|
|
|
73
72
|
config = self.config
|
|
74
73
|
@middleware ||= Rack::Builder.new do
|
|
75
74
|
use Rack::Cors, &config.cors if config.cors
|
|
76
|
-
|
|
75
|
+
|
|
76
|
+
if config.force_ssl.is_a?(Hash)
|
|
77
|
+
use Rack::SslEnforcer, **config.force_ssl
|
|
78
|
+
elsif config.force_ssl
|
|
79
|
+
use Rack::SslEnforcer
|
|
80
|
+
end
|
|
77
81
|
config.middleware.each do |block|
|
|
78
82
|
instance_eval(&block)
|
|
79
83
|
end
|
data/lib/grape/app/cli.rb
CHANGED
|
@@ -24,14 +24,13 @@ module Grape::App::CLI
|
|
|
24
24
|
def init_lib
|
|
25
25
|
empty_directory File.join(name, 'lib', name)
|
|
26
26
|
end
|
|
27
|
-
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
class Runner < Thor
|
|
31
30
|
register Builder, :new, 'new NAME', 'create a new application'
|
|
32
31
|
|
|
33
32
|
desc 'console ENV', 'Launch console'
|
|
34
|
-
def console(env='development')
|
|
33
|
+
def console(env = 'development')
|
|
35
34
|
ENV['GRAPE_ENV'] = env
|
|
36
35
|
require File.expand_path('config/environment', Dir.pwd)
|
|
37
36
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
class Grape::App::Configuration < ActiveSupport::InheritableOptions
|
|
2
|
-
|
|
3
2
|
def middleware(&block)
|
|
4
3
|
self[:middleware] ||= []
|
|
5
4
|
self[:middleware].push(block) if block
|
|
@@ -22,5 +21,4 @@ class Grape::App::Configuration < ActiveSupport::InheritableOptions
|
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
23
|
end
|
|
25
|
-
|
|
26
24
|
end
|
|
@@ -17,14 +17,13 @@ module Grape::App::Helpers::Caching
|
|
|
17
17
|
# article
|
|
18
18
|
# end
|
|
19
19
|
#
|
|
20
|
-
def fresh_when(object=nil, etag: nil, last_modified: nil, **cache_control)
|
|
20
|
+
def fresh_when(object = nil, etag: nil, last_modified: nil, last_modified_field: :updated_at, **cache_control)
|
|
21
21
|
etag ||= object
|
|
22
|
-
last_modified
|
|
23
|
-
|
|
22
|
+
last_modified = object.try(last_modified_field) || object.try(:maximum, last_modified_field) if last_modified.nil?
|
|
24
23
|
etag = ActiveSupport::Digest.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))
|
|
25
24
|
header 'ETag', etag
|
|
26
25
|
header 'Last-Modified', last_modified.httpdate if last_modified
|
|
27
|
-
cache_control(cache_control)
|
|
26
|
+
cache_control(**cache_control) unless cache_control.empty?
|
|
28
27
|
|
|
29
28
|
if_modified_since = headers['If-Modified-Since']
|
|
30
29
|
if_modified_since = Time.rfc2822(if_modified_since) rescue nil if if_modified_since # rubocop:disable Style/RescueModifier
|
|
@@ -49,7 +48,7 @@ module Grape::App::Helpers::Caching
|
|
|
49
48
|
# stats = article.really_expensive_call if stale?(article)
|
|
50
49
|
# end
|
|
51
50
|
#
|
|
52
|
-
def stale?(object=nil, **freshness_opts)
|
|
51
|
+
def stale?(object = nil, **freshness_opts)
|
|
53
52
|
fresh_when(object, **freshness_opts)
|
|
54
53
|
true
|
|
55
54
|
end
|
|
@@ -11,7 +11,6 @@ ActiveRecord::Tasks::DatabaseTasks.tap do |config|
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
namespace :db do
|
|
14
|
-
|
|
15
14
|
Rake::Task['load_config'].clear
|
|
16
15
|
|
|
17
16
|
task load_config: :environment do
|
|
@@ -34,12 +33,12 @@ namespace :db do
|
|
|
34
33
|
ar_version = [ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR].join('.')
|
|
35
34
|
|
|
36
35
|
FileUtils.mkdir_p(migrations_path)
|
|
37
|
-
File.write path,
|
|
36
|
+
File.write path, <<~RUBY
|
|
38
37
|
class #{name.camelize} < ActiveRecord::Migration[#{ar_version}]
|
|
39
38
|
def change
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
|
-
|
|
41
|
+
RUBY
|
|
43
42
|
puts path
|
|
44
43
|
end
|
|
45
44
|
|
|
@@ -47,5 +46,4 @@ namespace :db do
|
|
|
47
46
|
desc 'Prepare test DB'
|
|
48
47
|
task :prepare
|
|
49
48
|
end
|
|
50
|
-
|
|
51
49
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
Grape::App.configure do |config|
|
|
2
|
-
# Force SSL
|
|
3
|
-
#
|
|
2
|
+
# Force SSL, please see https://github.com/tobmatth/rack-ssl-enforcer
|
|
3
|
+
# for configuration options.
|
|
4
|
+
#
|
|
5
|
+
# config.force_ssl = { strict: true }
|
|
4
6
|
|
|
5
7
|
# CORS is disabled by default, please see https://github.com/cyu/rack-cors
|
|
6
8
|
# for configuration options.
|
|
@@ -5,11 +5,10 @@ RSpec.describe Grape::App::Helpers::Caching do
|
|
|
5
5
|
|
|
6
6
|
let(:app) { TestAPI }
|
|
7
7
|
|
|
8
|
-
it '
|
|
8
|
+
it 'handles fresh-when' do
|
|
9
9
|
get '/articles'
|
|
10
10
|
expect(last_response.status).to eq(200)
|
|
11
11
|
expect(last_response.headers).to include(
|
|
12
|
-
'Cache-Control' => 'public',
|
|
13
12
|
'Content-Type' => 'application/json',
|
|
14
13
|
'ETag' => '975ca8804565c1a569450d61090b2743',
|
|
15
14
|
'Last-Modified' => 'Fri, 05 Jan 2018 11:25:20 GMT',
|
|
@@ -31,7 +30,23 @@ RSpec.describe Grape::App::Helpers::Caching do
|
|
|
31
30
|
expect(last_response.status).to eq(200)
|
|
32
31
|
end
|
|
33
32
|
|
|
34
|
-
it '
|
|
33
|
+
it 'handles fresh_when for records that were never updated' do
|
|
34
|
+
get '/articles/never_updated'
|
|
35
|
+
expect(last_response.status).to eq(200)
|
|
36
|
+
expect(last_response.headers).to include(
|
|
37
|
+
'Last-Modified' => 'Fri, 05 Jan 2018 11:25:00 GMT',
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'supports cache-control' do
|
|
42
|
+
get '/articles?public=true'
|
|
43
|
+
expect(last_response.status).to eq(200)
|
|
44
|
+
expect(last_response.headers).to include(
|
|
45
|
+
'Cache-Control' => 'public',
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'handles stale? (with cache-control)' do
|
|
35
50
|
get '/articles/1'
|
|
36
51
|
expect(last_response.status).to eq(200)
|
|
37
52
|
expect(last_response.headers).to include(
|
|
@@ -44,6 +59,7 @@ RSpec.describe Grape::App::Helpers::Caching do
|
|
|
44
59
|
'id' => 1,
|
|
45
60
|
'title' => 'Welcome',
|
|
46
61
|
'updated_at' => '2018-01-05 11:25:10 UTC',
|
|
62
|
+
'created_at' => '2018-01-05 11:25:00 UTC',
|
|
47
63
|
)
|
|
48
64
|
|
|
49
65
|
get '/articles/1', {}, 'HTTP_IF_NONE_MATCH' => last_response.headers['ETag']
|
|
@@ -5,10 +5,11 @@ RSpec.describe Grape::App::Helpers::Params do
|
|
|
5
5
|
|
|
6
6
|
let(:app) { TestAPI }
|
|
7
7
|
|
|
8
|
-
it '
|
|
8
|
+
it 'limits params' do
|
|
9
9
|
post '/articles', title: 'Today', fresh: true, id: 1234, updated_at: Time.now
|
|
10
10
|
expect(last_response.status).to eq(201)
|
|
11
11
|
expect(JSON.parse(last_response.body)).to eq(
|
|
12
|
+
'created_at' => nil,
|
|
12
13
|
'id' => 9,
|
|
13
14
|
'title' => 'Today',
|
|
14
15
|
'updated_at' => '2018-01-05 11:25:15 UTC',
|
data/spec/grape/app_spec.rb
CHANGED
|
@@ -4,37 +4,38 @@ RSpec.describe Grape::App do
|
|
|
4
4
|
include Rack::Test::Methods
|
|
5
5
|
|
|
6
6
|
subject { described_class }
|
|
7
|
+
|
|
7
8
|
before { subject.init! File.expand_path('../scenario', __dir__) }
|
|
8
9
|
|
|
9
10
|
def app
|
|
10
11
|
subject.middleware
|
|
11
12
|
end
|
|
12
13
|
|
|
13
|
-
it '
|
|
14
|
+
it 'has an env' do
|
|
14
15
|
expect(subject.env).to be_instance_of(ActiveSupport::StringInquirer)
|
|
15
16
|
expect(subject.env).to eq('test')
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
it '
|
|
19
|
+
it 'has an root' do
|
|
19
20
|
expect(subject.root).to be_instance_of(Pathname)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
it '
|
|
23
|
-
expect(subject).to be < Grape::API
|
|
23
|
+
it 'is an API instance' do
|
|
24
|
+
expect(subject).to be < Grape::API
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
it '
|
|
27
|
+
it 'inits with default time zone' do
|
|
27
28
|
expect(Time.zone.name).to eq('UTC')
|
|
28
29
|
expect(Thread.new { Time.zone }.value.name).to eq('UTC')
|
|
29
30
|
end
|
|
30
31
|
|
|
31
|
-
it '
|
|
32
|
+
it 'configures i18n' do
|
|
32
33
|
expect(I18n.load_path).to include(subject.root.join('config', 'locales', 'en.yml').to_s)
|
|
33
34
|
expect(I18n.default_locale).to eq(:en)
|
|
34
35
|
expect(I18n.exception_handler).to be_instance_of(Proc)
|
|
35
36
|
end
|
|
36
37
|
|
|
37
|
-
it '
|
|
38
|
+
it 'reads env specific initializers' do
|
|
38
39
|
expect(subject.config).to include(
|
|
39
40
|
:test_specific,
|
|
40
41
|
:raise_on_missing_translations,
|
|
@@ -43,13 +44,13 @@ RSpec.describe Grape::App do
|
|
|
43
44
|
)
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
it '
|
|
47
|
+
it 'prepares middleware' do
|
|
47
48
|
expect(subject.middleware).to be_instance_of(Rack::Builder)
|
|
48
49
|
expect(subject.middleware.send(:instance_variable_get, :@use).size).to eq(2)
|
|
49
50
|
expect(subject.middleware.send(:instance_variable_get, :@run)).to be(subject)
|
|
50
51
|
end
|
|
51
52
|
|
|
52
|
-
it '
|
|
53
|
+
it 'applies middleware' do
|
|
53
54
|
header 'Origin', 'test.host'
|
|
54
55
|
get '/v1/ok'
|
|
55
56
|
expect(last_response).to be_ok
|
data/spec/scenario/app/api/v1.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
ENV['RACK_ENV'] ||= 'test'
|
|
2
2
|
require 'grape-app'
|
|
3
3
|
require 'rack/test'
|
|
4
|
+
require 'virtus'
|
|
4
5
|
|
|
5
6
|
class Article
|
|
6
7
|
include Virtus.model
|
|
@@ -13,8 +14,8 @@ class Article
|
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def each
|
|
16
|
-
yield Article.new(id: 1, title: 'Welcome', updated_at: Time.at(1515151510).utc)
|
|
17
|
-
yield Article.new(id: 2, title: 'Bye', updated_at: Time.at(1515151520).utc)
|
|
17
|
+
yield Article.new(id: 1, title: 'Welcome', updated_at: Time.at(1515151510).utc, created_at: Time.at(1515151500).utc)
|
|
18
|
+
yield Article.new(id: 2, title: 'Bye', updated_at: Time.at(1515151520).utc, created_at: Time.at(1515151500).utc)
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -25,13 +26,14 @@ class Article
|
|
|
25
26
|
attribute :id
|
|
26
27
|
attribute :title
|
|
27
28
|
attribute :updated_at
|
|
29
|
+
attribute :created_at
|
|
28
30
|
|
|
29
31
|
def to_param
|
|
30
32
|
id.to_s
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
class TestAPI < Grape::API
|
|
36
|
+
class TestAPI < Grape::API
|
|
35
37
|
format :json
|
|
36
38
|
|
|
37
39
|
helpers Grape::App::Helpers::Caching
|
|
@@ -39,10 +41,18 @@ class TestAPI < Grape::API::Instance
|
|
|
39
41
|
|
|
40
42
|
get '/articles' do
|
|
41
43
|
scope = Article.all
|
|
42
|
-
|
|
44
|
+
opts = params[:public] ? { public: params[:public] } : {}
|
|
45
|
+
fresh_when(scope, **opts)
|
|
43
46
|
scope.map(&:to_hash)
|
|
44
47
|
end
|
|
45
48
|
|
|
49
|
+
get '/articles/never_updated' do
|
|
50
|
+
article = Article.all.first
|
|
51
|
+
article.updated_at = nil
|
|
52
|
+
|
|
53
|
+
fresh_when(article, last_modified_field: :created_at)
|
|
54
|
+
end
|
|
55
|
+
|
|
46
56
|
get '/articles/:id' do
|
|
47
57
|
article = Article.all.first
|
|
48
58
|
article.to_hash if stale?(article, stale_if_error: 5, extras: { a: 1, b: 2 })
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grape-app
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Black Square Media Ltd
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-01-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -179,7 +179,7 @@ dependencies:
|
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
180
|
version: '0'
|
|
181
181
|
- !ruby/object:Gem::Dependency
|
|
182
|
-
name: rubocop
|
|
182
|
+
name: rubocop-bsm
|
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
|
184
184
|
requirements:
|
|
185
185
|
- - ">="
|
|
@@ -206,6 +206,20 @@ dependencies:
|
|
|
206
206
|
- - ">="
|
|
207
207
|
- !ruby/object:Gem::Version
|
|
208
208
|
version: '0'
|
|
209
|
+
- !ruby/object:Gem::Dependency
|
|
210
|
+
name: virtus
|
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
|
212
|
+
requirements:
|
|
213
|
+
- - ">="
|
|
214
|
+
- !ruby/object:Gem::Version
|
|
215
|
+
version: '0'
|
|
216
|
+
type: :development
|
|
217
|
+
prerelease: false
|
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
219
|
+
requirements:
|
|
220
|
+
- - ">="
|
|
221
|
+
- !ruby/object:Gem::Version
|
|
222
|
+
version: '0'
|
|
209
223
|
description: ''
|
|
210
224
|
email:
|
|
211
225
|
- info@blacksquaremedia.com
|
|
@@ -277,14 +291,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
277
291
|
requirements:
|
|
278
292
|
- - ">="
|
|
279
293
|
- !ruby/object:Gem::Version
|
|
280
|
-
version: '2.
|
|
294
|
+
version: '2.6'
|
|
281
295
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
296
|
requirements:
|
|
283
297
|
- - ">="
|
|
284
298
|
- !ruby/object:Gem::Version
|
|
285
299
|
version: '0'
|
|
286
300
|
requirements: []
|
|
287
|
-
rubygems_version: 3.
|
|
301
|
+
rubygems_version: 3.1.4
|
|
288
302
|
signing_key:
|
|
289
303
|
specification_version: 4
|
|
290
304
|
summary: Standalone Grape API apps
|