grape-app 0.8.4 → 0.8.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/Gemfile.lock +58 -31
- data/grape-app.gemspec +2 -1
- data/lib/grape/app.rb +1 -2
- 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 +0 -2
- data/spec/grape/app/helpers/caching_spec.rb +9 -0
- data/spec/grape/app/helpers/params_spec.rb +1 -0
- data/spec/spec_helper.rb +11 -2
- metadata +17 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0c4a05ef1c03ec244f8f99896b795bde1b89ce280af80c46558fb9dc09a26b40
|
|
4
|
+
data.tar.gz: 3bfca4ffb992d3c0b9407215ae3cf08c538be22c6337d86125dcc1d2cf65bec4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee63d58b3fcea0b099e749a82bf945753f50077c41ddefb833ea2c40b5aaedd6243b52296846b85117836f2c985e4eaa33aa402fe5ffe99e862106c1f99c25ba
|
|
7
|
+
data.tar.gz: 3e8a010d81aaf298110440a18da811d3829ebe6a6a915db16b05c0d96fabe7b53cbc79b3be227943f39b58185e3a81983d153087071f3170c16b41277969357b
|
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.5)
|
|
5
5
|
activesupport
|
|
6
6
|
grape (>= 1.2)
|
|
7
7
|
grape-entity
|
|
@@ -13,12 +13,12 @@ PATH
|
|
|
13
13
|
GEM
|
|
14
14
|
remote: https://rubygems.org/
|
|
15
15
|
specs:
|
|
16
|
-
activemodel (6.0.1)
|
|
17
|
-
activesupport (= 6.0.1)
|
|
18
|
-
activerecord (6.0.1)
|
|
19
|
-
activemodel (= 6.0.1)
|
|
20
|
-
activesupport (= 6.0.1)
|
|
21
|
-
activesupport (6.0.1)
|
|
16
|
+
activemodel (6.0.2.1)
|
|
17
|
+
activesupport (= 6.0.2.1)
|
|
18
|
+
activerecord (6.0.2.1)
|
|
19
|
+
activemodel (= 6.0.2.1)
|
|
20
|
+
activesupport (= 6.0.2.1)
|
|
21
|
+
activesupport (6.0.2.1)
|
|
22
22
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
23
23
|
i18n (>= 0.7, < 2)
|
|
24
24
|
minitest (~> 5.1)
|
|
@@ -32,70 +32,96 @@ GEM
|
|
|
32
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.6)
|
|
36
36
|
descendants_tracker (0.0.4)
|
|
37
37
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
38
38
|
diff-lcs (1.3)
|
|
39
|
+
dry-configurable (0.11.3)
|
|
40
|
+
concurrent-ruby (~> 1.0)
|
|
41
|
+
dry-core (~> 0.4, >= 0.4.7)
|
|
42
|
+
dry-equalizer (~> 0.2)
|
|
43
|
+
dry-container (0.7.2)
|
|
44
|
+
concurrent-ruby (~> 1.0)
|
|
45
|
+
dry-configurable (~> 0.1, >= 0.1.3)
|
|
46
|
+
dry-core (0.4.9)
|
|
47
|
+
concurrent-ruby (~> 1.0)
|
|
48
|
+
dry-equalizer (0.3.0)
|
|
49
|
+
dry-inflector (0.2.0)
|
|
50
|
+
dry-logic (1.0.6)
|
|
51
|
+
concurrent-ruby (~> 1.0)
|
|
52
|
+
dry-core (~> 0.2)
|
|
53
|
+
dry-equalizer (~> 0.2)
|
|
54
|
+
dry-types (1.3.1)
|
|
55
|
+
concurrent-ruby (~> 1.0)
|
|
56
|
+
dry-container (~> 0.3)
|
|
57
|
+
dry-core (~> 0.4, >= 0.4.4)
|
|
58
|
+
dry-equalizer (~> 0.3)
|
|
59
|
+
dry-inflector (~> 0.1, >= 0.1.2)
|
|
60
|
+
dry-logic (~> 1.0, >= 1.0.2)
|
|
39
61
|
equalizer (0.0.11)
|
|
40
|
-
grape (1.
|
|
62
|
+
grape (1.3.0)
|
|
41
63
|
activesupport
|
|
42
64
|
builder
|
|
65
|
+
dry-types (>= 1.1)
|
|
43
66
|
mustermann-grape (~> 1.0.0)
|
|
44
67
|
rack (>= 1.3.0)
|
|
45
68
|
rack-accept
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
activesupport (>= 4.0)
|
|
69
|
+
grape-entity (0.8.0)
|
|
70
|
+
activesupport (>= 3.0.0)
|
|
49
71
|
multi_json (>= 1.3.2)
|
|
50
|
-
i18n (1.
|
|
72
|
+
i18n (1.8.2)
|
|
51
73
|
concurrent-ruby (~> 1.0)
|
|
52
74
|
ice_nine (0.11.2)
|
|
53
75
|
jaro_winkler (1.5.4)
|
|
54
|
-
minitest (5.
|
|
76
|
+
minitest (5.14.0)
|
|
55
77
|
multi_json (1.14.1)
|
|
56
|
-
mustermann (1.
|
|
57
|
-
|
|
58
|
-
|
|
78
|
+
mustermann (1.1.1)
|
|
79
|
+
ruby2_keywords (~> 0.0.1)
|
|
80
|
+
mustermann-grape (1.0.1)
|
|
81
|
+
mustermann (>= 1.0.0)
|
|
59
82
|
parallel (1.19.1)
|
|
60
|
-
parser (2.
|
|
83
|
+
parser (2.7.0.4)
|
|
61
84
|
ast (~> 2.4.0)
|
|
62
|
-
rack (2.
|
|
85
|
+
rack (2.2.2)
|
|
63
86
|
rack-accept (0.4.5)
|
|
64
87
|
rack (>= 0.4)
|
|
65
|
-
rack-cors (1.1.
|
|
88
|
+
rack-cors (1.1.1)
|
|
66
89
|
rack (>= 2.0.0)
|
|
67
90
|
rack-ssl-enforcer (0.2.9)
|
|
68
91
|
rack-test (1.1.0)
|
|
69
92
|
rack (>= 1.0, < 3)
|
|
70
93
|
rainbow (3.0.0)
|
|
71
94
|
rake (13.0.1)
|
|
95
|
+
rexml (3.2.4)
|
|
72
96
|
rspec (3.9.0)
|
|
73
97
|
rspec-core (~> 3.9.0)
|
|
74
98
|
rspec-expectations (~> 3.9.0)
|
|
75
99
|
rspec-mocks (~> 3.9.0)
|
|
76
|
-
rspec-core (3.9.
|
|
77
|
-
rspec-support (~> 3.9.
|
|
100
|
+
rspec-core (3.9.1)
|
|
101
|
+
rspec-support (~> 3.9.1)
|
|
78
102
|
rspec-expectations (3.9.0)
|
|
79
103
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
80
104
|
rspec-support (~> 3.9.0)
|
|
81
|
-
rspec-mocks (3.9.
|
|
105
|
+
rspec-mocks (3.9.1)
|
|
82
106
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
83
107
|
rspec-support (~> 3.9.0)
|
|
84
|
-
rspec-support (3.9.
|
|
85
|
-
rubocop (0.
|
|
108
|
+
rspec-support (3.9.2)
|
|
109
|
+
rubocop (0.80.1)
|
|
86
110
|
jaro_winkler (~> 1.5.1)
|
|
87
111
|
parallel (~> 1.10)
|
|
88
|
-
parser (>= 2.
|
|
112
|
+
parser (>= 2.7.0.1)
|
|
89
113
|
rainbow (>= 2.2.2, < 4.0)
|
|
114
|
+
rexml
|
|
90
115
|
ruby-progressbar (~> 1.7)
|
|
91
116
|
unicode-display_width (>= 1.4.0, < 1.7)
|
|
92
117
|
ruby-progressbar (1.10.1)
|
|
93
|
-
|
|
94
|
-
|
|
118
|
+
ruby2_keywords (0.0.2)
|
|
119
|
+
sqlite3 (1.4.2)
|
|
120
|
+
thor (1.0.1)
|
|
95
121
|
thread_safe (0.3.6)
|
|
96
|
-
tzinfo (1.2.
|
|
122
|
+
tzinfo (1.2.6)
|
|
97
123
|
thread_safe (~> 0.1)
|
|
98
|
-
unicode-display_width (1.6.
|
|
124
|
+
unicode-display_width (1.6.1)
|
|
99
125
|
virtus (1.0.5)
|
|
100
126
|
axiom-types (~> 0.1)
|
|
101
127
|
coercible (~> 1.0)
|
|
@@ -115,6 +141,7 @@ DEPENDENCIES
|
|
|
115
141
|
rspec
|
|
116
142
|
rubocop
|
|
117
143
|
sqlite3
|
|
144
|
+
virtus
|
|
118
145
|
|
|
119
146
|
BUNDLED WITH
|
|
120
|
-
2.
|
|
147
|
+
2.1.2
|
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.5'
|
|
4
4
|
s.authors = ['Black Square Media Ltd']
|
|
5
5
|
s.email = ['info@blacksquaremedia.com']
|
|
6
6
|
s.summary = %(Standalone Grape API apps)
|
|
@@ -29,4 +29,5 @@ Gem::Specification.new do |s|
|
|
|
29
29
|
s.add_development_dependency 'rspec'
|
|
30
30
|
s.add_development_dependency 'rubocop'
|
|
31
31
|
s.add_development_dependency 'sqlite3'
|
|
32
|
+
s.add_development_dependency 'virtus'
|
|
32
33
|
end
|
data/lib/grape/app.rb
CHANGED
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) unless cache_control.empty?
|
|
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
|
|
@@ -47,5 +46,4 @@ namespace :db do
|
|
|
47
46
|
desc 'Prepare test DB'
|
|
48
47
|
task :prepare
|
|
49
48
|
end
|
|
50
|
-
|
|
51
49
|
end
|
|
@@ -30,6 +30,14 @@ RSpec.describe Grape::App::Helpers::Caching do
|
|
|
30
30
|
expect(last_response.status).to eq(200)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
it 'should handle 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
|
+
|
|
33
41
|
it 'should support cache-control' do
|
|
34
42
|
get '/articles?public=true'
|
|
35
43
|
expect(last_response.status).to eq(200)
|
|
@@ -51,6 +59,7 @@ RSpec.describe Grape::App::Helpers::Caching do
|
|
|
51
59
|
'id' => 1,
|
|
52
60
|
'title' => 'Welcome',
|
|
53
61
|
'updated_at' => '2018-01-05 11:25:10 UTC',
|
|
62
|
+
'created_at' => '2018-01-05 11:25:00 UTC',
|
|
54
63
|
)
|
|
55
64
|
|
|
56
65
|
get '/articles/1', {}, 'HTTP_IF_NONE_MATCH' => last_response.headers['ETag']
|
|
@@ -9,6 +9,7 @@ RSpec.describe Grape::App::Helpers::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/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,6 +26,7 @@ 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
|
|
@@ -44,6 +46,13 @@ class TestAPI < Grape::API
|
|
|
44
46
|
scope.map(&:to_hash)
|
|
45
47
|
end
|
|
46
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
|
+
|
|
47
56
|
get '/articles/:id' do
|
|
48
57
|
article = Article.all.first
|
|
49
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.5
|
|
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: 2020-03-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -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
|
|
@@ -284,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
284
298
|
- !ruby/object:Gem::Version
|
|
285
299
|
version: '0'
|
|
286
300
|
requirements: []
|
|
287
|
-
rubygems_version: 3.
|
|
301
|
+
rubygems_version: 3.1.2
|
|
288
302
|
signing_key:
|
|
289
303
|
specification_version: 4
|
|
290
304
|
summary: Standalone Grape API apps
|