grape-app 0.8.7 → 0.8.8

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: feff7b4ee1c4e672754a8e9e85f4c80016e2414a6f81b10d40cb8cea5ccdc900
4
- data.tar.gz: 15ede4a9152b0e274041a1f0a94c0edd9eaaaabc3ca6be7fd28e5a50041f54ed
3
+ metadata.gz: ba29de5fd70e82430c9bedfe0381fbabf43cd420d16c416e162582926f7bbec1
4
+ data.tar.gz: 71f550566eb3fccf9d66baf45c2e987bef0876a48daf139aac0eedf0746f350e
5
5
  SHA512:
6
- metadata.gz: adf69f2a62a197ac8393abbf00da46b093313900701cbdb9b3ab76cc21e78331c20ebfbbde3131e023a014b0dae76946a6949f275e0bc8cd5fc7f3ea27c552d0
7
- data.tar.gz: b5f4919555de644ba358415a2473ef6ea51d290d32acc82b2e52baf6919a245f3e7fa1bc79ec08b9f7c53a0afacc8ac89d4e62d69eb1b549956111f4c7c4769a
6
+ metadata.gz: 74835d8b690aacee9164288561974a4954823cb9cac45206e93927c17fbde803f2b13a8bbab437fea84470c36cf518d17c20b00e3459702c965e9c74522ddfd5
7
+ data.tar.gz: 97cbb35a1ade9fb541759efc71789163161c2bf255b36a94febe0ba1698a364d333dbec8a30a8e923d6f2ecbce80edffa164557737d071ae6a8016db2bde94f4
@@ -0,0 +1,21 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ["2.6", "2.7", "3.0"]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby-version }}
20
+ bundler-cache: true
21
+ - run: bundle exec rake
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grape-app (0.8.7)
4
+ grape-app (0.8.8)
5
5
  activesupport
6
6
  grape (>= 1.2)
7
7
  grape-entity
@@ -13,30 +13,22 @@ PATH
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
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)
16
+ activemodel (6.1.3.1)
17
+ activesupport (= 6.1.3.1)
18
+ activerecord (6.1.3.1)
19
+ activemodel (= 6.1.3.1)
20
+ activesupport (= 6.1.3.1)
21
+ activesupport (6.1.3.1)
22
22
  concurrent-ruby (~> 1.0, >= 1.0.2)
23
23
  i18n (>= 1.6, < 2)
24
24
  minitest (>= 5.1)
25
25
  tzinfo (~> 2.0)
26
26
  zeitwerk (~> 2.3)
27
- ast (2.4.1)
28
- axiom-types (0.1.1)
29
- descendants_tracker (~> 0.0.4)
30
- ice_nine (~> 0.11.0)
31
- thread_safe (~> 0.3, >= 0.3.1)
27
+ ast (2.4.2)
32
28
  builder (3.2.4)
33
- coercible (1.0.0)
34
- descendants_tracker (~> 0.0.1)
35
- concurrent-ruby (1.1.7)
36
- descendants_tracker (0.0.4)
37
- thread_safe (~> 0.3, >= 0.3.1)
29
+ concurrent-ruby (1.1.8)
38
30
  diff-lcs (1.4.4)
39
- dry-configurable (0.12.0)
31
+ dry-configurable (0.12.1)
40
32
  concurrent-ruby (~> 1.0)
41
33
  dry-core (~> 0.5, >= 0.5.0)
42
34
  dry-container (0.7.2)
@@ -44,40 +36,36 @@ GEM
44
36
  dry-configurable (~> 0.1, >= 0.1.3)
45
37
  dry-core (0.5.0)
46
38
  concurrent-ruby (~> 1.0)
47
- dry-equalizer (0.3.0)
48
39
  dry-inflector (0.2.0)
49
- dry-logic (1.1.0)
40
+ dry-logic (1.1.1)
50
41
  concurrent-ruby (~> 1.0)
51
42
  dry-core (~> 0.5, >= 0.5)
52
- dry-types (1.4.0)
43
+ dry-types (1.5.1)
53
44
  concurrent-ruby (~> 1.0)
54
45
  dry-container (~> 0.3)
55
- dry-core (~> 0.4, >= 0.4.4)
56
- dry-equalizer (~> 0.3)
46
+ dry-core (~> 0.5, >= 0.5)
57
47
  dry-inflector (~> 0.1, >= 0.1.2)
58
48
  dry-logic (~> 1.0, >= 1.0.2)
59
- equalizer (0.0.11)
60
- grape (1.5.1)
49
+ grape (1.5.3)
61
50
  activesupport
62
51
  builder
63
52
  dry-types (>= 1.1)
64
53
  mustermann-grape (~> 1.0.0)
65
54
  rack (>= 1.3.0)
66
55
  rack-accept
67
- grape-entity (0.8.2)
56
+ grape-entity (0.9.0)
68
57
  activesupport (>= 3.0.0)
69
58
  multi_json (>= 1.3.2)
70
- i18n (1.8.7)
59
+ i18n (1.8.10)
71
60
  concurrent-ruby (~> 1.0)
72
- ice_nine (0.11.2)
73
- minitest (5.14.3)
61
+ minitest (5.14.4)
74
62
  multi_json (1.15.0)
75
63
  mustermann (1.1.1)
76
64
  ruby2_keywords (~> 0.0.1)
77
65
  mustermann-grape (1.0.1)
78
66
  mustermann (>= 1.0.0)
79
67
  parallel (1.20.1)
80
- parser (3.0.0.0)
68
+ parser (3.0.1.0)
81
69
  ast (~> 2.4.1)
82
70
  rack (2.2.3)
83
71
  rack-accept (0.4.5)
@@ -89,8 +77,8 @@ GEM
89
77
  rack (>= 1.0, < 3)
90
78
  rainbow (3.0.0)
91
79
  rake (13.0.3)
92
- regexp_parser (2.0.3)
93
- rexml (3.2.4)
80
+ regexp_parser (2.1.1)
81
+ rexml (3.2.5)
94
82
  rspec (3.10.0)
95
83
  rspec-core (~> 3.10.0)
96
84
  rspec-expectations (~> 3.10.0)
@@ -100,11 +88,11 @@ GEM
100
88
  rspec-expectations (3.10.1)
101
89
  diff-lcs (>= 1.2.0, < 2.0)
102
90
  rspec-support (~> 3.10.0)
103
- rspec-mocks (3.10.1)
91
+ rspec-mocks (3.10.2)
104
92
  diff-lcs (>= 1.2.0, < 2.0)
105
93
  rspec-support (~> 3.10.0)
106
- rspec-support (3.10.1)
107
- rubocop (1.8.1)
94
+ rspec-support (3.10.2)
95
+ rubocop (1.12.1)
108
96
  parallel (~> 1.10)
109
97
  parser (>= 3.0.0.0)
110
98
  rainbow (>= 2.2.2, < 4.0)
@@ -113,15 +101,15 @@ GEM
113
101
  rubocop-ast (>= 1.2.0, < 2.0)
114
102
  ruby-progressbar (~> 1.7)
115
103
  unicode-display_width (>= 1.4.0, < 3.0)
116
- rubocop-ast (1.4.0)
104
+ rubocop-ast (1.4.1)
117
105
  parser (>= 2.7.1.5)
118
- rubocop-bsm (0.5.4)
106
+ rubocop-bsm (0.5.6)
119
107
  rubocop (~> 1.0)
120
108
  rubocop-performance
121
109
  rubocop-rails
122
110
  rubocop-rake
123
111
  rubocop-rspec
124
- rubocop-performance (1.9.2)
112
+ rubocop-performance (1.10.2)
125
113
  rubocop (>= 0.90.0, < 2.0)
126
114
  rubocop-ast (>= 0.4.0)
127
115
  rubocop-rails (2.9.1)
@@ -130,22 +118,16 @@ GEM
130
118
  rubocop (>= 0.90.0, < 2.0)
131
119
  rubocop-rake (0.5.1)
132
120
  rubocop
133
- rubocop-rspec (2.1.0)
121
+ rubocop-rspec (2.2.0)
134
122
  rubocop (~> 1.0)
135
123
  rubocop-ast (>= 1.1.0)
136
124
  ruby-progressbar (1.11.0)
137
- ruby2_keywords (0.0.3)
125
+ ruby2_keywords (0.0.4)
138
126
  sqlite3 (1.4.2)
139
- thor (1.0.1)
140
- thread_safe (0.3.6)
127
+ thor (1.1.0)
141
128
  tzinfo (2.0.4)
142
129
  concurrent-ruby (~> 1.0)
143
130
  unicode-display_width (2.0.0)
144
- virtus (1.0.5)
145
- axiom-types (~> 0.1)
146
- coercible (~> 1.0)
147
- descendants_tracker (~> 0.0, >= 0.0.3)
148
- equalizer (~> 0.0, >= 0.0.9)
149
131
  zeitwerk (2.4.2)
150
132
 
151
133
  PLATFORMS
@@ -160,7 +142,6 @@ DEPENDENCIES
160
142
  rspec
161
143
  rubocop-bsm
162
144
  sqlite3
163
- virtus
164
145
 
165
146
  BUNDLED WITH
166
147
  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.7'
3
+ s.version = '0.8.8'
4
4
  s.authors = ['Black Square Media Ltd']
5
5
  s.email = ['info@blacksquaremedia.com']
6
6
  s.summary = %(Standalone Grape API apps)
@@ -29,5 +29,4 @@ Gem::Specification.new do |s|
29
29
  s.add_development_dependency 'rspec'
30
30
  s.add_development_dependency 'rubocop-bsm'
31
31
  s.add_development_dependency 'sqlite3'
32
- s.add_development_dependency 'virtus'
33
32
  end
data/lib/grape/app.rb CHANGED
@@ -78,10 +78,13 @@ class Grape::App < Grape::API
78
78
  elsif config.force_ssl
79
79
  use Rack::SslEnforcer
80
80
  end
81
+
81
82
  config.middleware.each do |block|
82
83
  instance_eval(&block)
83
84
  end
84
85
 
86
+ use Grape::App::Middleware::ConnectionManagement if defined?(ActiveRecord)
87
+
85
88
  run Grape::App
86
89
  end
87
90
  end
@@ -107,3 +110,4 @@ end
107
110
  require 'grape/app/configuration'
108
111
  require 'grape/app/helpers'
109
112
  require 'grape/app/inflector'
113
+ require 'grape/app/middleware'
@@ -0,0 +1,5 @@
1
+ module Grape::App::Middleware
2
+ extend ActiveSupport::Autoload
3
+
4
+ autoload :ConnectionManagement
5
+ end
@@ -0,0 +1,12 @@
1
+ class Grape::App::Middleware::ConnectionManagement
2
+ def initialize(app)
3
+ @app = app
4
+ end
5
+
6
+ def call(env)
7
+ @app.call(env)
8
+ rescue ::ActiveRecord::StatementInvalid
9
+ ::ActiveRecord::Base.clear_active_connections!
10
+ raise
11
+ end
12
+ end
@@ -9,6 +9,7 @@ class API::V1 < Grape::API
9
9
  # error_response message: e.message, status: 404
10
10
  # end
11
11
 
12
- # Mount components
12
+ # Mount components:
13
+ #
13
14
  # mount API::Posts
14
15
  end
@@ -3,14 +3,46 @@ require 'spec_helper'
3
3
  RSpec.describe Grape::App::Helpers::Caching do
4
4
  include Rack::Test::Methods
5
5
 
6
- let(:app) { TestAPI }
6
+ let :app do
7
+ helper = described_class
8
+ Class.new(Grape::API) do
9
+ format :json
10
+
11
+ helpers helper
12
+
13
+ get '/articles' do
14
+ scope = Article.order(:id)
15
+ opts = params[:public] ? { public: params[:public] } : {}
16
+ fresh_when(scope, **opts)
17
+ scope.to_a
18
+ end
19
+
20
+ get '/articles/never_updated' do
21
+ article = Article.first
22
+ article.updated_at = nil
23
+
24
+ fresh_when(article, last_modified_field: :created_at)
25
+ end
26
+
27
+ get '/articles/:id' do
28
+ article = Article.first
29
+ article if stale?(article, stale_if_error: 5, extras: { a: 1, b: 2 })
30
+ end
31
+ end
32
+ end
33
+ let(:created_at) { Time.at(1515151500).utc }
34
+
35
+ before do
36
+ Article.create! title: 'Welcome', created_at: created_at, updated_at: created_at + 10
37
+ Article.create! title: 'Bye', created_at: created_at, updated_at: created_at + 20
38
+ end
7
39
 
8
40
  it 'handles fresh-when' do
9
41
  get '/articles'
10
42
  expect(last_response.status).to eq(200)
11
43
  expect(last_response.headers).to include(
12
44
  'Content-Type' => 'application/json',
13
- 'ETag' => '975ca8804565c1a569450d61090b2743',
45
+ 'ETag' => 'a5f6c4b024510c9835d8d70cbd3ed00c',
14
46
  'Last-Modified' => 'Fri, 05 Jan 2018 11:25:20 GMT',
15
47
  )
16
48
  expect(JSON.parse(last_response.body).size).to eq(2)
@@ -52,21 +84,21 @@ RSpec.describe Grape::App::Helpers::Caching do
52
84
  expect(last_response.headers).to include(
53
85
  'Cache-Control' => 'private, stale-if-error=5, a=1, b=2',
54
86
  'Content-Type' => 'application/json',
55
- 'ETag' => 'c4ca4238a0b923820dcc509a6f75849b',
87
+ 'ETag' => '0154407bafc97186a494a05e0652ff61',
56
88
  'Last-Modified' => 'Fri, 05 Jan 2018 11:25:10 GMT',
57
89
  )
58
90
  expect(JSON.parse(last_response.body)).to eq(
59
91
  'id' => 1,
60
92
  'title' => 'Welcome',
61
- 'updated_at' => '2018-01-05 11:25:10 UTC',
62
- 'created_at' => '2018-01-05 11:25:00 UTC',
93
+ 'updated_at' => '2018-01-05T11:25:10.000Z',
94
+ 'created_at' => '2018-01-05T11:25:00.000Z',
63
95
  )
64
96
 
65
97
  get '/articles/1', {}, 'HTTP_IF_NONE_MATCH' => last_response.headers['ETag']
66
98
  expect(last_response.status).to eq(304)
67
99
  expect(last_response.headers).to include(
68
100
  'Cache-Control' => 'private, stale-if-error=5, a=1, b=2',
69
- 'ETag' => 'c4ca4238a0b923820dcc509a6f75849b',
101
+ 'ETag' => '0154407bafc97186a494a05e0652ff61',
70
102
  'Last-Modified' => 'Fri, 05 Jan 2018 11:25:10 GMT',
71
103
  )
72
104
  end
@@ -3,16 +3,32 @@ require 'spec_helper'
3
3
  RSpec.describe Grape::App::Helpers::Params do
4
4
  include Rack::Test::Methods
5
5
 
6
- let(:app) { TestAPI }
6
+ let :app do
7
+ helper = described_class
8
+ Class.new(Grape::API) do
9
+ format :json
10
+
11
+ helpers helper
12
+
13
+ params do
14
+ optional :title
15
+ end
16
+ post '/articles' do
17
+ attrs = { id: 9, updated_at: Time.at(1515151515).utc }
18
+ attrs.update(declared_params)
19
+ Article.new(attrs)
20
+ end
21
+ end
22
+ end
7
23
 
8
24
  it 'limits params' do
9
- post '/articles', title: 'Today', fresh: true, id: 1234, updated_at: Time.now
25
+ post '/articles', title: 'Today', id: 1234, updated_at: Time.now
10
26
  expect(last_response.status).to eq(201)
11
27
  expect(JSON.parse(last_response.body)).to eq(
12
28
  'created_at' => nil,
13
29
  'id' => 9,
14
30
  'title' => 'Today',
15
- 'updated_at' => '2018-01-05 11:25:15 UTC',
31
+ 'updated_at' => '2018-01-05T11:25:15.000Z',
16
32
  )
17
33
  end
18
34
  end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Grape::App::Middleware::ConnectionManagement do
4
+ include Rack::Test::Methods
5
+
6
+ let :app do
7
+ failing = ->(_) { raise(ActiveRecord::StatementInvalid) }
8
+ middleware = described_class
9
+ Rack::Builder.new do
10
+ use middleware
11
+ run failing
12
+ end
13
+ end
14
+
15
+ it 'clears active connections' do
16
+ ActiveRecord::Base.connection
17
+ expect(ActiveRecord::Base.connection_handler).to be_active_connections
18
+
19
+ expect { get '/' }.to raise_error(ActiveRecord::StatementInvalid)
20
+ expect(ActiveRecord::Base.connection_handler).not_to be_active_connections
21
+ end
22
+ end
@@ -46,7 +46,7 @@ RSpec.describe Grape::App do
46
46
 
47
47
  it 'prepares middleware' do
48
48
  expect(subject.middleware).to be_instance_of(Rack::Builder)
49
- expect(subject.middleware.send(:instance_variable_get, :@use).size).to eq(2)
49
+ expect(subject.middleware.send(:instance_variable_get, :@use).size).to eq(3)
50
50
  expect(subject.middleware.send(:instance_variable_get, :@run)).to be(subject)
51
51
  end
52
52
 
data/spec/spec_helper.rb CHANGED
@@ -1,70 +1,16 @@
1
1
  ENV['RACK_ENV'] ||= 'test'
2
2
  require 'grape-app'
3
3
  require 'rack/test'
4
- require 'virtus'
4
+ require 'active_record'
5
5
 
6
- class Article
7
- include Virtus.model
8
-
9
- class Scope
10
- include Enumerable
11
-
12
- def maximum(*)
13
- map(&:updated_at).max
14
- end
15
-
16
- def each
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)
19
- end
20
- end
21
-
22
- def self.all
23
- Scope.new
24
- end
25
-
26
- attribute :id
27
- attribute :title
28
- attribute :updated_at
29
- attribute :created_at
30
-
31
- def to_param
32
- id.to_s
6
+ ActiveRecord::Base.configurations = { 'test' => { 'adapter' => 'sqlite3', 'database' => ':memory:' } }
7
+ ActiveRecord::Base.establish_connection :test
8
+ ActiveRecord::Base.connection.instance_eval do
9
+ create_table :articles do |t|
10
+ t.string :title
11
+ t.timestamps
33
12
  end
34
13
  end
35
14
 
36
- class TestAPI < Grape::API
37
- format :json
38
-
39
- helpers Grape::App::Helpers::Caching
40
- helpers Grape::App::Helpers::Params
41
-
42
- get '/articles' do
43
- scope = Article.all
44
- opts = params[:public] ? { public: params[:public] } : {}
45
- fresh_when(scope, **opts)
46
- scope.map(&:to_hash)
47
- end
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
-
56
- get '/articles/:id' do
57
- article = Article.all.first
58
- article.to_hash if stale?(article, stale_if_error: 5, extras: { a: 1, b: 2 })
59
- end
60
-
61
- params do
62
- requires :title
63
- optional :fresh
64
- end
65
- post '/articles' do
66
- attrs = { id: 9, updated_at: Time.at(1515151515).utc }
67
- attrs.update(declared_params)
68
- Article.new(attrs).to_hash
69
- end
15
+ class Article < ActiveRecord::Base
70
16
  end
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.7
4
+ version: 0.8.8
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: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2021-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -206,20 +206,6 @@ 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'
223
209
  description: ''
224
210
  email:
225
211
  - info@blacksquaremedia.com
@@ -229,9 +215,9 @@ extensions: []
229
215
  extra_rdoc_files: []
230
216
  files:
231
217
  - ".editorconfig"
218
+ - ".github/workflows/test.yml"
232
219
  - ".gitignore"
233
220
  - ".rubocop.yml"
234
- - ".travis.yml"
235
221
  - Gemfile
236
222
  - Gemfile.lock
237
223
  - LICENSE
@@ -250,6 +236,8 @@ files:
250
236
  - lib/grape/app/inflector.rb
251
237
  - lib/grape/app/initializers/post.rb
252
238
  - lib/grape/app/initializers/pre.rb
239
+ - lib/grape/app/middleware.rb
240
+ - lib/grape/app/middleware/connection_management.rb
253
241
  - lib/grape/app/tasks.rb
254
242
  - lib/grape/app/tasks/core.rake
255
243
  - lib/grape/app/tasks/databases.rake
@@ -269,6 +257,7 @@ files:
269
257
  - lib/grape_app.rb
270
258
  - spec/grape/app/helpers/caching_spec.rb
271
259
  - spec/grape/app/helpers/params_spec.rb
260
+ - spec/grape/app/middleware/connection_management_spec.rb
272
261
  - spec/grape/app_spec.rb
273
262
  - spec/scenario/Gemfile
274
263
  - spec/scenario/app/api.rb
@@ -305,6 +294,7 @@ summary: Standalone Grape API apps
305
294
  test_files:
306
295
  - spec/grape/app/helpers/caching_spec.rb
307
296
  - spec/grape/app/helpers/params_spec.rb
297
+ - spec/grape/app/middleware/connection_management_spec.rb
308
298
  - spec/grape/app_spec.rb
309
299
  - spec/scenario/Gemfile
310
300
  - spec/scenario/app/api.rb
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.6
4
- - 2.7
5
- before_install:
6
- - gem install bundler