grape-app 0.8.1 → 0.8.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: 77187b9f038601c08edaa41385655236b13907e88a22baa30cdc037641ebb214
4
- data.tar.gz: c21cce56ec2393c67ef7885c01c187641205367b44b2624c0944b560f6aeb954
3
+ metadata.gz: 9b76f380cd6957fb37025cb07c4343471d9fa892f387c9f5110eb5a713f7a5bc
4
+ data.tar.gz: 34b4f3c1c0912fac71bed2d75448f90bf6aba60ec96300c208c13aca324a19a7
5
5
  SHA512:
6
- metadata.gz: b29b7f6971e417b1d5d2a0e396eb456c37a5b0cee7ae3b9716faf8adc96a4321df510b9809dd457b5f37e3a70af2ee6e708eb1ffbc140daa5c5455266ad560bb
7
- data.tar.gz: dd6e2198260a448270026d13776c2fb0b26f8e236349491fbde0438b5495d959a044361555efc6e7a03bffcf7e4c0f88d0aab0397870ec01e70253ac68fd726a
6
+ metadata.gz: f2325d245dba242af124309a3a9193e9c4af1fe17fb9e611650a1230b453b4086a3870073690e60911141e9e10696db9f416c49f530f95d6a9a6e818d70e0822
7
+ data.tar.gz: c1415686241fffa006cfb36b4518b2342e2fa889e175beae428659acf0b4dbd4a8f934eb89cf734fba729189d640d6377cd3fe6fabebc4d5cc72517c296fbfd0
@@ -2,5 +2,6 @@ language: ruby
2
2
  rvm:
3
3
  - 2.5
4
4
  - 2.6
5
+ - 2.7
5
6
  before_install:
6
7
  - gem install bundler
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grape-app (0.8.1)
4
+ grape-app (0.8.6)
5
5
  activesupport
6
6
  grape (>= 1.2)
7
7
  grape-entity
8
- rack-cors
8
+ rack-cors (>= 1.1)
9
9
  rack-ssl-enforcer
10
10
  thor
11
11
  zeitwerk (>= 2.1)
@@ -13,94 +13,124 @@ 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.3.2)
17
+ activesupport (= 6.0.3.2)
18
+ activerecord (6.0.3.2)
19
+ activemodel (= 6.0.3.2)
20
+ activesupport (= 6.0.3.2)
21
+ activesupport (6.0.3.2)
22
22
  concurrent-ruby (~> 1.0, >= 1.0.2)
23
23
  i18n (>= 0.7, < 2)
24
24
  minitest (~> 5.1)
25
25
  tzinfo (~> 1.1)
26
- zeitwerk (~> 2.2)
27
- ast (2.4.0)
26
+ zeitwerk (~> 2.2, >= 2.2.2)
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.3)
32
+ builder (3.2.4)
33
33
  coercible (1.0.0)
34
34
  descendants_tracker (~> 0.0.1)
35
- concurrent-ruby (1.1.5)
35
+ concurrent-ruby (1.1.6)
36
36
  descendants_tracker (0.0.4)
37
37
  thread_safe (~> 0.3, >= 0.3.1)
38
- diff-lcs (1.3)
38
+ diff-lcs (1.4.4)
39
+ dry-configurable (0.11.6)
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.4.0)
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.2.4)
62
+ grape (1.3.3)
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
- virtus (>= 1.0.0)
47
- grape-entity (0.7.1)
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.7.0)
72
+ i18n (1.8.3)
51
73
  concurrent-ruby (~> 1.0)
52
74
  ice_nine (0.11.2)
53
- jaro_winkler (1.5.4)
54
- minitest (5.13.0)
75
+ minitest (5.14.1)
55
76
  multi_json (1.14.1)
56
- mustermann (1.0.3)
57
- mustermann-grape (1.0.0)
58
- mustermann (~> 1.0.0)
59
- parallel (1.18.0)
60
- parser (2.6.5.0)
61
- ast (~> 2.4.0)
62
- rack (2.0.7)
77
+ mustermann (1.1.1)
78
+ ruby2_keywords (~> 0.0.1)
79
+ mustermann-grape (1.0.1)
80
+ mustermann (>= 1.0.0)
81
+ parallel (1.19.2)
82
+ parser (2.7.1.4)
83
+ ast (~> 2.4.1)
84
+ rack (2.2.3)
63
85
  rack-accept (0.4.5)
64
86
  rack (>= 0.4)
65
- rack-cors (1.0.3)
87
+ rack-cors (1.1.1)
88
+ rack (>= 2.0.0)
66
89
  rack-ssl-enforcer (0.2.9)
67
90
  rack-test (1.1.0)
68
91
  rack (>= 1.0, < 3)
69
92
  rainbow (3.0.0)
70
- rake (13.0.0)
93
+ rake (13.0.1)
94
+ regexp_parser (1.7.1)
95
+ rexml (3.2.4)
71
96
  rspec (3.9.0)
72
97
  rspec-core (~> 3.9.0)
73
98
  rspec-expectations (~> 3.9.0)
74
99
  rspec-mocks (~> 3.9.0)
75
- rspec-core (3.9.0)
76
- rspec-support (~> 3.9.0)
77
- rspec-expectations (3.9.0)
100
+ rspec-core (3.9.2)
101
+ rspec-support (~> 3.9.3)
102
+ rspec-expectations (3.9.2)
78
103
  diff-lcs (>= 1.2.0, < 2.0)
79
104
  rspec-support (~> 3.9.0)
80
- rspec-mocks (3.9.0)
105
+ rspec-mocks (3.9.1)
81
106
  diff-lcs (>= 1.2.0, < 2.0)
82
107
  rspec-support (~> 3.9.0)
83
- rspec-support (3.9.0)
84
- rubocop (0.76.0)
85
- jaro_winkler (~> 1.5.1)
108
+ rspec-support (3.9.3)
109
+ rubocop (0.86.0)
86
110
  parallel (~> 1.10)
87
- parser (>= 2.6)
111
+ parser (>= 2.7.0.1)
88
112
  rainbow (>= 2.2.2, < 4.0)
113
+ regexp_parser (>= 1.7)
114
+ rexml
115
+ rubocop-ast (>= 0.0.3, < 1.0)
89
116
  ruby-progressbar (~> 1.7)
90
- unicode-display_width (>= 1.4.0, < 1.7)
117
+ unicode-display_width (>= 1.4.0, < 2.0)
118
+ rubocop-ast (0.1.0)
119
+ parser (>= 2.7.0.1)
91
120
  ruby-progressbar (1.10.1)
92
- sqlite3 (1.4.1)
93
- thor (0.20.3)
121
+ ruby2_keywords (0.0.2)
122
+ sqlite3 (1.4.2)
123
+ thor (1.0.1)
94
124
  thread_safe (0.3.6)
95
- tzinfo (1.2.5)
125
+ tzinfo (1.2.7)
96
126
  thread_safe (~> 0.1)
97
- unicode-display_width (1.6.0)
127
+ unicode-display_width (1.7.0)
98
128
  virtus (1.0.5)
99
129
  axiom-types (~> 0.1)
100
130
  coercible (~> 1.0)
101
131
  descendants_tracker (~> 0.0, >= 0.0.3)
102
132
  equalizer (~> 0.0, >= 0.0.9)
103
- zeitwerk (2.2.1)
133
+ zeitwerk (2.3.1)
104
134
 
105
135
  PLATFORMS
106
136
  ruby
@@ -114,6 +144,7 @@ DEPENDENCIES
114
144
  rspec
115
145
  rubocop
116
146
  sqlite3
147
+ virtus
117
148
 
118
149
  BUNDLED WITH
119
- 2.0.2
150
+ 2.1.4
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'grape-app'
3
- s.version = '0.8.1'
3
+ s.version = '0.8.6'
4
4
  s.authors = ['Black Square Media Ltd']
5
5
  s.email = ['info@blacksquaremedia.com']
6
- s.summary = %(Stanalone Grape API apps)
6
+ s.summary = %(Standalone Grape API apps)
7
7
  s.description = %()
8
8
  s.homepage = 'https://github.com/bsm/grape-app'
9
9
  s.license = 'MIT'
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency 'activesupport'
18
18
  s.add_dependency 'grape', '>= 1.2'
19
19
  s.add_dependency 'grape-entity'
20
- s.add_dependency 'rack-cors'
20
+ s.add_dependency 'rack-cors', '>= 1.1'
21
21
  s.add_dependency 'rack-ssl-enforcer'
22
22
  s.add_dependency 'thor'
23
23
  s.add_dependency 'zeitwerk', '>= 2.1'
@@ -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
@@ -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::Instance
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
@@ -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 ||= object.try(:updated_at) || object.try(:maximum, :updated_at)
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
@@ -6,7 +6,7 @@ module Grape::App::Helpers::RespondWith
6
6
  end
7
7
 
8
8
  # @param [ActiveRecord::Base] record validated record
9
- def respond_with(record, opts={})
9
+ def respond_with(record, opts = {})
10
10
  unless record.errors.empty?
11
11
  opts[:with] = Errors
12
12
  status 400
@@ -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, <<-MIGRATION.strip_heredoc
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
- MIGRATION
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,4 +1,4 @@
1
- class API::V1 < Grape::API::Instance
1
+ class API::V1 < Grape::API
2
2
  version 'v1'
3
3
  prefix 'api'
4
4
  format :json
@@ -11,5 +11,4 @@ class API::V1 < Grape::API::Instance
11
11
 
12
12
  # Mount components
13
13
  # mount API::Posts
14
-
15
14
  end
@@ -9,7 +9,6 @@ RSpec.describe Grape::App::Helpers::Caching 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,6 +30,22 @@ RSpec.describe Grape::App::Helpers::Caching do
31
30
  expect(last_response.status).to eq(200)
32
31
  end
33
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
+
41
+ it 'should support 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
+
34
49
  it 'should handle stale? (with cache-control)' do
35
50
  get '/articles/1'
36
51
  expect(last_response.status).to eq(200)
@@ -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']
@@ -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',
@@ -20,7 +20,7 @@ RSpec.describe Grape::App do
20
20
  end
21
21
 
22
22
  it 'should be an API instance' do
23
- expect(subject).to be < Grape::API::Instance
23
+ expect(subject).to be < Grape::API
24
24
  end
25
25
 
26
26
  it 'should init with default time zone' do
@@ -1,4 +1,4 @@
1
- class API::Posts < Grape::API::Instance
1
+ class API::Posts < Grape::API
2
2
  get '/posts' do
3
3
  []
4
4
  end
@@ -1,4 +1,4 @@
1
- class API::V1 < Grape::API::Instance
1
+ class API::V1 < Grape::API
2
2
  version 'v1'
3
3
  format :json
4
4
 
@@ -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::Instance
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
- fresh_when(scope, public: true)
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.1
4
+ version: 0.8.6
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: 2019-11-06 00:00:00.000000000 Z
11
+ date: 2020-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '1.1'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '1.1'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rack-ssl-enforcer
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -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,10 +298,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
298
  - !ruby/object:Gem::Version
285
299
  version: '0'
286
300
  requirements: []
287
- rubygems_version: 3.0.6
301
+ rubygems_version: 3.1.4
288
302
  signing_key:
289
303
  specification_version: 4
290
- summary: Stanalone Grape API apps
304
+ summary: Standalone Grape API apps
291
305
  test_files:
292
306
  - spec/grape/app/helpers/caching_spec.rb
293
307
  - spec/grape/app/helpers/params_spec.rb