grape-app 0.8.7 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
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