grape-roar 0.4.1 → 0.5.0

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.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +2 -0
  3. data/.github/dependabot.yml +6 -0
  4. data/.github/workflows/danger.yml +22 -0
  5. data/.github/workflows/lint.yml +15 -0
  6. data/.github/workflows/test-activerecord.yml +34 -0
  7. data/.github/workflows/test-mongodb.yml +33 -0
  8. data/.github/workflows/test.yml +19 -0
  9. data/.rubocop.yml +7 -6
  10. data/.rubocop_todo.yml +163 -21
  11. data/CHANGELOG.md +13 -11
  12. data/Dangerfile +4 -0
  13. data/Gemfile +16 -8
  14. data/Gemfile.danger +6 -0
  15. data/README.md +41 -22
  16. data/grape-roar.gemspec +2 -3
  17. data/lib/grape/roar/extensions/relations/adapters/base.rb +1 -1
  18. data/lib/grape/roar/extensions/relations/adapters/mongoid.rb +1 -1
  19. data/lib/grape/roar/extensions/relations/adapters.rb +2 -2
  20. data/lib/grape/roar/extensions/relations/mapper.rb +7 -2
  21. data/lib/grape/roar/extensions/relations/validations/active_record.rb +11 -38
  22. data/lib/grape/roar/extensions/relations/validations/mongoid/6.rb +48 -0
  23. data/lib/grape/roar/extensions/relations/validations/mongoid/7.rb +75 -0
  24. data/lib/grape/roar/extensions/relations/validations/mongoid.rb +5 -84
  25. data/lib/grape/roar/representer.rb +4 -1
  26. data/lib/grape/roar/version.rb +1 -1
  27. data/spec/decorator_spec.rb +0 -2
  28. data/spec/extensions/relations/adapters/active_record_spec.rb +21 -17
  29. data/spec/extensions/relations/adapters/adapters_module_spec.rb +3 -2
  30. data/spec/extensions/relations/adapters/mongoid_spec.rb +21 -17
  31. data/spec/extensions/relations/dsl_methods_spec.rb +14 -14
  32. data/spec/extensions/relations/mapper_spec.rb +10 -10
  33. data/spec/extensions/relations/validations/active_record_spec.rb +35 -32
  34. data/spec/extensions/relations/validations/mongoid_spec.rb +64 -61
  35. data/spec/nested_representer_spec.rb +0 -2
  36. data/spec/present_with_spec.rb +0 -2
  37. data/spec/relations_spec.rb +6 -5
  38. data/spec/representer_spec.rb +34 -8
  39. data/spec/spec_helper.rb +6 -2
  40. data/spec/support/all/article_representer.rb +1 -0
  41. data/spec/support/all/grape_app_context.rb +0 -2
  42. metadata +19 -12
  43. data/.travis.yml +0 -36
  44. data/Appraisals +0 -9
  45. data/gemfiles/with_activerecord.gemfile +0 -22
  46. data/gemfiles/with_mongoid.gemfile +0 -22
@@ -1,45 +1,48 @@
1
1
  # frozen_string_literal: true
2
- describe Grape::Roar::Extensions::Relations::Validations::ActiveRecord, active_record: true do
3
- let(:model_klass) { double }
4
2
 
5
- subject do
6
- klass = Class.new do
7
- def initialize(klass)
8
- @klass = klass
3
+ if defined?(ActiveRecord)
4
+ describe Grape::Roar::Extensions::Relations::Validations::ActiveRecord, :activerecord do
5
+ let(:model_klass) { double }
6
+
7
+ subject do
8
+ klass = Class.new do
9
+ def initialize(klass)
10
+ @klass = klass
11
+ end
12
+
13
+ attr_reader :klass
9
14
  end
10
15
 
11
- attr_reader :klass
16
+ klass.include(described_class)
17
+ klass.new(model_klass)
12
18
  end
13
19
 
14
- klass.include(described_class)
15
- klass.new(model_klass)
16
- end
17
-
18
- before do
19
- expect(model_klass).to receive(:reflections).twice
20
- .and_return(reflections)
21
- end
20
+ before do
21
+ expect(model_klass).to receive(:reflections).twice
22
+ .and_return(reflections)
23
+ end
22
24
 
23
- %w[
24
- belongs_to
25
- has_many
26
- has_one
27
- has_and_belongs_to_many
28
- ].each do |relation|
29
- context "##{relation}_valid?" do
30
- let(:relation_klass) do
31
- "::ActiveRecord::Reflection::#{relation.camelize}"\
25
+ %w[
26
+ belongs_to
27
+ has_many
28
+ has_one
29
+ has_and_belongs_to_many
30
+ ].each do |relation|
31
+ describe "##{relation}_valid?" do
32
+ let(:relation_klass) do
33
+ "::ActiveRecord::Reflection::#{relation.camelize}" \
32
34
  'Reflection'.constantize.allocate
33
- end
35
+ end
34
36
 
35
- let(:reflections) { { test: relation_klass, fail: Class.new } }
37
+ let(:reflections) { { test: relation_klass, fail: Class.new } }
36
38
 
37
- it 'properly validates the relation' do
38
- expect(subject.send("#{relation}_valid?", :test)).to eql(true)
39
- expect { subject.send("#{relation}_valid?", :fail) }.to raise_error(
40
- Grape::Roar::Extensions::Relations::\
41
- Exceptions::InvalidRelationError
42
- )
39
+ it 'properly validates the relation' do
40
+ expect(subject.send("#{relation}_valid?", :test)).to eql(true)
41
+ expect { subject.send("#{relation}_valid?", :fail) }.to raise_error(
42
+ Grape::Roar::Extensions::Relations::
43
+ Exceptions::InvalidRelationError
44
+ )
45
+ end
43
46
  end
44
47
  end
45
48
  end
@@ -1,86 +1,89 @@
1
1
  # frozen_string_literal: true
2
- describe Grape::Roar::Extensions::Relations::Validations::Mongoid, mongoid: true do
3
- let(:model_klass) { double }
4
2
 
5
- subject do
6
- klass = Class.new do
7
- def initialize(klass)
8
- @klass = klass
3
+ if defined?(Mongoid)
4
+ describe Grape::Roar::Extensions::Relations::Validations::Mongoid, :mongoid do
5
+ let(:model_klass) { double }
6
+ let(:map_reflection) do
7
+ proc do |r|
8
+ case r
9
+ when /and/ then 'ManyToMany'
10
+ when /many/ then 'Many'
11
+ when /one/ then 'One'
12
+ when /belongs/ then 'In'
13
+ end
9
14
  end
10
-
11
- attr_reader :klass
12
15
  end
13
16
 
14
- klass.include(described_class)
15
- klass.new(model_klass)
16
- end
17
+ subject do
18
+ klass = Class.new do
19
+ def initialize(klass)
20
+ @klass = klass
21
+ end
17
22
 
18
- let(:map_reflection) do
19
- proc do |r|
20
- case r
21
- when /and/ then 'ManyToMany'
22
- when /many/ then 'Many'
23
- when /one/ then 'One'
24
- when /belongs/ then 'In'
23
+ attr_reader :klass
25
24
  end
25
+
26
+ klass.include(described_class)
27
+ klass.new(model_klass)
26
28
  end
27
- end
28
29
 
29
- before do
30
- expect(model_klass).to receive(:reflect_on_association).twice do |r|
31
- if r == :test_rel
32
- {
33
- relation: "Mongoid::Relations::#{relation_klass}"\
34
- "::#{map_reflection.call(test_method)}".constantize
35
- }
36
- else
37
- { relation: double }
30
+ before do
31
+ expect(model_klass).to receive(:reflect_on_association).twice do |r|
32
+ if r == :test_rel
33
+ if Gem::Version.new(Mongoid::VERSION) < Gem::Version.new('7')
34
+ { relation: "Mongoid::Relations::#{relation_klass}::#{map_reflection.call(test_method)}".constantize }
35
+ else
36
+ { relation: "Mongoid::Association::#{relation_klass}::#{test_method.to_s.camelize}".constantize }
37
+ end
38
+ else
39
+ { relation: double }
40
+ end
38
41
  end
39
42
  end
40
- end
41
43
 
42
- context 'referenced' do
43
- let(:relation_klass) { 'Referenced' }
44
+ context 'referenced' do
45
+ let(:relation_klass) { 'Referenced' }
44
46
 
45
- %i[
46
- belongs_to
47
- has_and_belongs_to_many
48
- has_many
49
- has_one
50
- ].each do |test_method|
51
- context "##{test_method}_valid? validates the relation" do
52
- let(:test_method) { test_method }
47
+ %i[
48
+ belongs_to
49
+ has_and_belongs_to_many
50
+ has_many
51
+ has_one
52
+ ].each do |test_method|
53
+ describe "##{test_method}_valid? validates the relation" do
54
+ let(:test_method) { test_method }
53
55
 
54
- it 'properly validates the relation' do
55
- expect(subject.send("#{test_method}_valid?", :test_rel)).to eql(true)
56
+ it 'properly validates the relation' do
57
+ expect(subject.send("#{test_method}_valid?", :test_rel)).to eql(true)
56
58
 
57
- expect do
58
- subject.send("#{test_method}_valid?", :fail)
59
- end.to raise_error(
60
- Grape::Roar::Extensions::Relations::\
61
- Exceptions::InvalidRelationError
62
- )
59
+ expect do
60
+ subject.send("#{test_method}_valid?", :fail)
61
+ end.to raise_error(
62
+ Grape::Roar::Extensions::Relations::
63
+ Exceptions::InvalidRelationError
64
+ )
65
+ end
63
66
  end
64
67
  end
65
68
  end
66
- end
67
69
 
68
- context 'referenced' do
69
- let(:relation_klass) { 'Embedded' }
70
+ context 'embedded' do
71
+ let(:relation_klass) { 'Embedded' }
70
72
 
71
- %i[embeds_one embeds_many].each do |test_method|
72
- context "##{test_method}_valid? validates the relation" do
73
- let(:test_method) { test_method }
73
+ %i[embeds_one embeds_many].each do |test_method|
74
+ describe "##{test_method}_valid? validates the relation" do
75
+ let(:test_method) { test_method }
74
76
 
75
- it 'properly validates the relation' do
76
- expect(subject.send("#{test_method}_valid?", :test_rel)).to eql(true)
77
+ it 'properly validates the relation' do
78
+ expect(subject.send("#{test_method}_valid?", :test_rel)).to eql(true)
77
79
 
78
- expect do
79
- subject.send("#{test_method}_valid?", :fail)
80
- end.to raise_error(
81
- Grape::Roar::Extensions::Relations::\
82
- Exceptions::InvalidRelationError
83
- )
80
+ expect do
81
+ subject.send("#{test_method}_valid?", :fail)
82
+ end.to raise_error(
83
+ Grape::Roar::Extensions::Relations::
84
+ Exceptions::InvalidRelationError
85
+ )
86
+ end
84
87
  end
85
88
  end
86
89
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
-
5
3
  describe Grape::Roar do
6
4
  context 'nested representer' do
7
5
  include_context 'Grape API App'
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
-
5
3
  describe Grape::Roar do
6
4
  include_context 'Grape API App'
7
5
 
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Grape::Roar::Extensions::Relations do
4
- context '.included' do
4
+ describe '.included' do
5
5
  subject { Class.new }
6
+
6
7
  after { subject.include(described_class) }
7
8
 
8
9
  it 'mixes DSLMethods into the singleton class of its target' do
@@ -12,11 +13,11 @@ describe Grape::Roar::Extensions::Relations do
12
13
  end
13
14
  end
14
15
 
15
- context 'with mongoid', mongoid: true do
16
+ context 'with mongoid', :mongoid do
16
17
  include_context 'Grape API App'
17
18
 
18
19
  # Make sure Mongo is empty
19
- before(:each) { Mongoid::Config.purge! }
20
+ before { Mongoid::Config.purge! }
20
21
 
21
22
  let(:result) { JSON.parse(last_response.body) }
22
23
 
@@ -39,7 +40,7 @@ describe Grape::Roar::Extensions::Relations do
39
40
 
40
41
  it 'correctly generates links for items' do
41
42
  expect(result['_links']['items'].map { |l| l['href'] }).to all(
42
- match(/^http:\/\/example\.org\/items\/[A-Za-z0-9]*$/)
43
+ match(%r{^http://example\.org/items/[A-Za-z0-9]*$})
43
44
  )
44
45
  end
45
46
  end
@@ -64,7 +65,7 @@ describe Grape::Roar::Extensions::Relations do
64
65
 
65
66
  it 'correctly represents the embedded cart' do
66
67
  expect(result['_embedded']['cart']['_links']['self']['href'])
67
- .to match(/^http:\/\/example\.org\/carts\/[A-Za-z0-9]*$/)
68
+ .to match(%r{^http://example\.org/carts/[A-Za-z0-9]*$})
68
69
 
69
70
  expect(result['_embedded']['cart']['_links']['items'].count).to eql(1)
70
71
  expect(result['_embedded']['cart']['_links']['items'].first).to eql(
@@ -1,20 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
-
5
3
  describe Grape::Roar do
6
4
  include_context 'Grape API App'
7
5
 
8
6
  context 'representer' do
9
- before do
10
- subject.get('/article/:id') do
11
- Article.new(title: 'Lonestar', id: params[:id])
7
+ context 'with a known model' do
8
+ before do
9
+ subject.get('/article/:id') do
10
+ Article.new(title: 'Lonestar', id: params[:id])
11
+ end
12
+ end
13
+
14
+ it 'returns a hypermedia representation' do
15
+ get '/article/666'
16
+ expect(last_response.body).to eq '{"title":"Lonestar","id":"666","links":[{"rel":"self","href":"/article/666"}]}'
12
17
  end
13
18
  end
14
19
 
15
- it 'returns a hypermedia representation' do
16
- get '/article/666'
17
- expect(last_response.body).to eq '{"title":"Lonestar","id":"666","links":[{"rel":"self","href":"/article/666"}]}'
20
+ context 'without an instance singleton' do
21
+ context 'as nil' do
22
+ before do
23
+ subject.get('/article/:id') do
24
+ present(nil, with: ArticleRepresenter)
25
+ end
26
+ end
27
+
28
+ it 'raises TypeError' do
29
+ expect { get '/article/666' }.to raise_error(TypeError)
30
+ end
31
+ end
32
+
33
+ context 'as another immediate value' do
34
+ before do
35
+ subject.get('/article/:id') do
36
+ present(5, with: ArticleRepresenter)
37
+ end
38
+ end
39
+
40
+ it 'raises TypeError' do
41
+ expect { get '/article/666' }.to raise_error(TypeError)
42
+ end
43
+ end
18
44
  end
19
45
  end
20
46
  end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,11 @@
3
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
5
5
 
6
+ require 'ostruct'
7
+ require 'bigdecimal'
8
+ require 'base64'
9
+ require 'logger'
10
+
6
11
  require 'bundler'
7
12
  Bundler.setup :default, :test
8
13
  Bundler.require
@@ -15,13 +20,12 @@ require 'roar/hypermedia'
15
20
 
16
21
  require 'grape/roar'
17
22
  require 'rack/test'
18
-
19
23
  require 'rspec'
20
24
 
21
25
  RSpec.configure do |config|
22
26
  config.include Rack::Test::Methods
23
27
  config.filter_run_excluding(
24
- active_record: true, mongoid: true
28
+ activerecord: true, mongoid: true
25
29
  )
26
30
  end
27
31
 
@@ -3,6 +3,7 @@
3
3
  module ArticleRepresenter
4
4
  include Roar::JSON
5
5
  include Roar::Hypermedia
6
+ include Grape::Roar::Representer
6
7
 
7
8
  property :title
8
9
  property :id
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
-
5
3
  shared_context 'Grape API App' do
6
4
  subject do
7
5
  Class.new(Grape::API)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-roar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-14 00:00:00.000000000 Z
11
+ date: 2025-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grape
@@ -59,22 +59,27 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - ".github/FUNDING.yml"
63
+ - ".github/dependabot.yml"
64
+ - ".github/workflows/danger.yml"
65
+ - ".github/workflows/lint.yml"
66
+ - ".github/workflows/test-activerecord.yml"
67
+ - ".github/workflows/test-mongodb.yml"
68
+ - ".github/workflows/test.yml"
62
69
  - ".gitignore"
63
70
  - ".rspec"
64
71
  - ".rubocop.yml"
65
72
  - ".rubocop_todo.yml"
66
- - ".travis.yml"
67
- - Appraisals
68
73
  - CHANGELOG.md
69
74
  - CONTRIBUTING.md
75
+ - Dangerfile
70
76
  - Gemfile
77
+ - Gemfile.danger
71
78
  - LICENSE
72
79
  - README.md
73
80
  - RELEASING.md
74
81
  - Rakefile
75
82
  - UPGRADING.md
76
- - gemfiles/with_activerecord.gemfile
77
- - gemfiles/with_mongoid.gemfile
78
83
  - grape-roar.gemspec
79
84
  - lib/grape-roar.rb
80
85
  - lib/grape/roar.rb
@@ -92,6 +97,8 @@ files:
92
97
  - lib/grape/roar/extensions/relations/validations/active_record.rb
93
98
  - lib/grape/roar/extensions/relations/validations/misc.rb
94
99
  - lib/grape/roar/extensions/relations/validations/mongoid.rb
100
+ - lib/grape/roar/extensions/relations/validations/mongoid/6.rb
101
+ - lib/grape/roar/extensions/relations/validations/mongoid/7.rb
95
102
  - lib/grape/roar/formatter.rb
96
103
  - lib/grape/roar/representer.rb
97
104
  - lib/grape/roar/version.rb
@@ -125,8 +132,9 @@ files:
125
132
  homepage: http://github.com/ruby-grape/grape-roar
126
133
  licenses:
127
134
  - MIT
128
- metadata: {}
129
- post_install_message:
135
+ metadata:
136
+ rubygems_mfa_required: 'true'
137
+ post_install_message:
130
138
  rdoc_options: []
131
139
  require_paths:
132
140
  - lib
@@ -141,9 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
149
  - !ruby/object:Gem::Version
142
150
  version: '0'
143
151
  requirements: []
144
- rubyforge_project:
145
- rubygems_version: 2.6.11
146
- signing_key:
152
+ rubygems_version: 3.5.16
153
+ signing_key:
147
154
  specification_version: 4
148
155
  summary: Enable Resource-Oriented Architectures in Grape API DSL
149
156
  test_files: []
data/.travis.yml DELETED
@@ -1,36 +0,0 @@
1
- sudo: false
2
-
3
- language: ruby
4
-
5
- cache: bundler
6
-
7
- rvm:
8
- - 2.4.1
9
- - 2.3.4
10
-
11
- gemfile:
12
- - Gemfile
13
- - gemfiles/with_activerecord.gemfile
14
- - gemfiles/with_mongoid.gemfile
15
-
16
- services:
17
- - mongodb
18
- - pg
19
-
20
- matrix:
21
- include:
22
- - env: SPEC_OPTS="--tag active_record"
23
- gemfile: gemfiles/with_activerecord.gemfile
24
- rvm: 2.4.1
25
- - env: SPEC_OPTS="--tag mongoid"
26
- gemfile: gemfiles/with_mongoid.gemfile
27
- rvm: 2.4.1
28
- - env: SPEC_OPTS="--tag active_record"
29
- gemfile: gemfiles/with_activerecord.gemfile
30
- rvm: 2.3.4
31
- - env: SPEC_OPTS="--tag mongoid"
32
- gemfile: gemfiles/with_mongoid.gemfile
33
- rvm: 2.3.4
34
-
35
-
36
- script: bundle exec rake
data/Appraisals DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- appraise 'with-activerecord' do
4
- gem 'activerecord', '>= 4.0.0', require: 'active_record'
5
- end
6
-
7
- appraise 'with-mongoid' do
8
- gem 'mongoid', '>= 5.0.0', require: 'mongoid'
9
- end
@@ -1,22 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", ">= 4.0.0", require: "active_record"
6
-
7
- group :development do
8
- gem "appraisal", "2.2.0"
9
- end
10
-
11
- group :test do
12
- gem "rack-test"
13
- gem "rspec", "~> 3.1"
14
- end
15
-
16
- group :development, :test do
17
- gem "nokogiri", "1.6.3.1"
18
- gem "rake", "~> 10.5.0"
19
- gem "rubocop", "0.49.1"
20
- end
21
-
22
- gemspec path: "../"
@@ -1,22 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "mongoid", ">= 5.0.0", require: "mongoid"
6
-
7
- group :development do
8
- gem "appraisal", "2.2.0"
9
- end
10
-
11
- group :test do
12
- gem "rack-test"
13
- gem "rspec", "~> 3.1"
14
- end
15
-
16
- group :development, :test do
17
- gem "nokogiri", "1.6.3.1"
18
- gem "rake", "~> 10.5.0"
19
- gem "rubocop", "0.49.1"
20
- end
21
-
22
- gemspec path: "../"