azeroth 0.6.3 → 0.6.4

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: ff267cb06b99dea008313ebf30569e33565cbbe210602b3008bd859016c28755
4
- data.tar.gz: 494a34050515c0dcd7e05ecdce0151e26f089e0ae39d3c1652a38d210ec1f99d
3
+ metadata.gz: ac2c03e9a7b51ed50db9ecab43a4f7257d98839126f79a45cc6b3563efd7b296
4
+ data.tar.gz: 95d18220fae24c2f049cf186fe25a0d5cdc94bada48ccd9ce02b867c5334f3ce
5
5
  SHA512:
6
- metadata.gz: 1e89465dc060b9ab4a0b9a6c95e6b2cb054ab08efd32ebf312bbe94f751f5d505f20230632e8435d0de57898f9bbd9875215fd23c59f51a1de6516a2bfb0e273
7
- data.tar.gz: fe6c480bc37d5e03ea61eb22df4c66154537fca6917d671e19fac1ce7bdf5de5051dfd736de0c7529ffa240512f615bd5a1c1a2e5ed285a3326956bd59758dd4
6
+ metadata.gz: 8dd092347ebebde2ccdaad5b2c165a8a595a2f8f2a6fc463303566f1b3812d84b22a0295f75ce9dbf696c752ad045691953696166705e0294f94ae3450b0f3e7
7
+ data.tar.gz: 4a406a9e2d4609034cab48bd8aff6ead1c644f3535d3cacd6e18523881572dde035afccbc4279ee96f9a110a0b078897641ebcfc5008a93cf47b7b4ce89bd746
@@ -7,6 +7,7 @@ AllCops:
7
7
  Metrics/BlockLength:
8
8
  Exclude:
9
9
  - 'spec/**/*_spec.rb'
10
+ - 'spec/dummy/db/schema.rb'
10
11
  - 'spec/support/shared_*/**/*.rb'
11
12
  - 'azeroth.gemspec'
12
13
 
@@ -24,3 +25,13 @@ Style/HashTransformKeys:
24
25
 
25
26
  Style/HashTransformValues:
26
27
  Enabled: true
28
+
29
+ RSpec/ExampleLength:
30
+ Exclude:
31
+ - 'spec/integration/readme/**/*_spec.rb'
32
+ - 'spec/integration/yard/**/*_spec.rb'
33
+
34
+ RSpec/MultipleExpectations:
35
+ Exclude:
36
+ - 'spec/integration/readme/**/*_spec.rb'
37
+ - 'spec/integration/yard/**/*_spec.rb'
data/README.md CHANGED
@@ -11,4 +11,116 @@ Azeroth
11
11
 
12
12
  Yard Documentation
13
13
  -------------------
14
- [https://www.rubydoc.info/gems/azeroth/0.6.3](https://www.rubydoc.info/gems/azeroth/0.6.3)
14
+ [https://www.rubydoc.info/gems/azeroth/0.6.4](https://www.rubydoc.info/gems/azeroth/0.6.4)
15
+
16
+ Azeroth has been designed making the coding of controllers easier
17
+ as routes in controllers are usually copy, paste and replace of same
18
+ code.
19
+
20
+ Azeroth was originally developed for controller actions
21
+ which will respond with json or template rendering based
22
+ on the requested format `.json` or `.html` where `html` rendering
23
+ does not perform database operations
24
+
25
+ Future versions will enable `html` rendering to also perform
26
+ database operations.
27
+
28
+ Usage
29
+ -----
30
+
31
+ ## Azeroth::Resourceable
32
+
33
+ [Resourceable](https://www.rubydoc.info/gems/azeroth/Azeroth/Resourceable)
34
+ module adds class method [resource_for](https://www.rubydoc.info/gems/azeroth/Azeroth/Resourceable/ClassMethods#resource_for-instance_method)
35
+ which adds a resource and action methods for `create`, `show`, `index`,
36
+ `update`, `delete`, `edit`
37
+
38
+ It accepts options
39
+ -only List of actions to be built
40
+ -except List of actions to not to be built
41
+ -decorator Decorator class or flag allowing/disallowing decorators
42
+
43
+ ```ruby
44
+ # publishers_controller.rb
45
+
46
+ class PublishersController < ApplicationController
47
+ include Azeroth::Resourceable
48
+ skip_before_action :verify_authenticity_token
49
+
50
+ resource_for :publisher, only: %i[create index]
51
+ end
52
+ ```
53
+
54
+ ```ruby
55
+ # games_controller.rb
56
+
57
+ class GamesController < ApplicationController
58
+ include Azeroth::Resourceable
59
+ skip_before_action :verify_authenticity_token
60
+
61
+ resource_for :game, except: :delete
62
+
63
+ private
64
+
65
+ def games
66
+ publisher.games
67
+ end
68
+
69
+ def publisher
70
+ @publisher ||= Publisher.find(publisher_id)
71
+ end
72
+
73
+ def publisher_id
74
+ params.require(:publisher_id)
75
+ end
76
+ end
77
+ ```
78
+
79
+ ## Azeroth::Decorator
80
+
81
+ [Decorators](https://www.rubydoc.info/gems/azeroth/Azeroth/Decorator) are
82
+ used to define how an object is exposed as json on controller responses
83
+ defining which and how fields will be exposed
84
+
85
+ ```ruby
86
+ # pokemon/decorator.rb
87
+
88
+ class Pokemon::Decorator < Azeroth::Decorator
89
+ expose :name
90
+ expose :previous_form_name, as: :evolution_of, if: :evolution?
91
+
92
+ def evolution?
93
+ previous_form
94
+ end
95
+
96
+ def previous_form_name
97
+ previous_form.name
98
+ end
99
+ end
100
+ ```
101
+
102
+ ```ruby
103
+ # pokemon/favorite_decorator.rb
104
+
105
+ class Pokemon::FavoriteDecorator < Pokemon::Decorator
106
+ expose :nickname
107
+ end
108
+ ```
109
+
110
+ ```ruby
111
+ # pokemon_master/decorator.rb
112
+
113
+ class PokemonMaster < ActiveRecord::Base
114
+ has_one :favorite_pokemon, -> { where(favorite: true) },
115
+ class_name: 'Pokemon'
116
+ has_many :pokemons
117
+ end
118
+ ```
119
+
120
+ Exposing is done through the class method
121
+ [expose](https://www.rubydoc.info/gems/azeroth/Azeroth/Decorator#expose-class_method)
122
+ which accepts several options:
123
+
124
+ -as: custom key to expose
125
+ -if: method/block to be called checking if an attribute should or should not be exposed
126
+ -decorator: flag to use or not a decorator or decorator class to be used
@@ -84,6 +84,8 @@ module Azeroth
84
84
  # to be called
85
85
  # checking if an attribute should or should not
86
86
  # be exposed
87
+ # @option options_hash decorator [FalseClass,TrueClass,Class]
88
+ # flag to use or not a decorator or decorator class to be used
87
89
  #
88
90
  # @return [Array<Symbol>]
89
91
  #
@@ -104,6 +106,125 @@ module Azeroth
104
106
  # end
105
107
  # end
106
108
  # end
109
+ #
110
+ # @example With relations
111
+ # # pokemon/decorator.rb
112
+ #
113
+ # class Pokemon::Decorator < Azeroth::Decorator
114
+ # expose :name
115
+ # expose :previous_form_name, as: :evolution_of, if: :evolution?
116
+ #
117
+ # def evolution?
118
+ # previous_form
119
+ # end
120
+ #
121
+ # def previous_form_name
122
+ # previous_form.name
123
+ # end
124
+ # end
125
+ #
126
+ # # pokemon/favorite_decorator.rb
127
+ #
128
+ # class Pokemon::FavoriteDecorator < Pokemon::Decorator
129
+ # expose :nickname
130
+ # end
131
+ #
132
+ # # pokemon_master/decorator.rb
133
+ #
134
+ # class PokemonMaster < ActiveRecord::Base
135
+ # has_one :favorite_pokemon, -> { where(favorite: true) },
136
+ # class_name: 'Pokemon'
137
+ # has_many :pokemons
138
+ # end
139
+ #
140
+ # # pokemon.rb
141
+ #
142
+ # class Pokemon < ActiveRecord::Base
143
+ # belongs_to :pokemon_master
144
+ # has_one :previous_form,
145
+ # class_name: 'Pokemon',
146
+ # foreign_key: :previous_form_id
147
+ # end
148
+ #
149
+ # # pokemon_master.rb
150
+ #
151
+ # class PokemonMaster::Decorator < Azeroth::Decorator
152
+ # expose :name
153
+ # expose :age
154
+ # expose :favorite_pokemon, decorator: Pokemon::FavoriteDecorator
155
+ # expose :pokemons
156
+ #
157
+ # def name
158
+ # [
159
+ # first_name,
160
+ # last_name
161
+ # ].compact.join(' ')
162
+ # end
163
+ # end
164
+ #
165
+ # # schema.rb
166
+ #
167
+ # ActiveRecord::Schema.define do
168
+ # self.verbose = false
169
+ #
170
+ # create_table :pokemon_masters, force: true do |t|
171
+ # t.string :first_name, null: false
172
+ # t.string :last_name
173
+ # t.integer :age, null: false
174
+ # end
175
+ #
176
+ # create_table :pokemons, force: true do |t|
177
+ # t.string :name, null: false
178
+ # t.string :nickname
179
+ # t.integer :pokemon_master_id
180
+ # t.boolean :favorite
181
+ # t.integer :previous_form_id
182
+ # t.index %i[pokemon_master_id favorite], unique: true
183
+ # end
184
+ #
185
+ # add_foreign_key 'pokemons', 'pokemon_masters'
186
+ # end
187
+ #
188
+ # # test.rb
189
+ #
190
+ # master = PokemonMaster.create(
191
+ # first_name: 'Ash',
192
+ # last_name: 'Ketchum',
193
+ # age: 10
194
+ # )
195
+ #
196
+ # master.create_favorite_pokemon(
197
+ # name: 'pikachu',
198
+ # nickname: 'Pikachu'
199
+ # )
200
+ #
201
+ # metapod = Pokemon.create(name: :metapod)
202
+ #
203
+ # master.pokemons.create(
204
+ # name: 'butterfree', previous_form: metapod
205
+ # )
206
+ # master.pokemons.create(name: 'squirtle')
207
+ #
208
+ # decorator = PokemonMaster::Decorator.new(master)
209
+ #
210
+ # decorator.as_json
211
+ # # returns
212
+ # # {
213
+ # # 'age' => 10,
214
+ # # 'name' => 'Ash Ketchum',
215
+ # # 'favorite_pokemon' => {
216
+ # # 'name' => 'pikachu',
217
+ # # 'nickname' => 'Pikachu'
218
+ # # },
219
+ # # 'pokemons' => [{
220
+ # # 'name' => 'butterfree',
221
+ # # 'evolution_of' => 'metapod'
222
+ # # }, {
223
+ # # 'name' => 'squirtle'
224
+ # # }, {
225
+ # # 'name' => 'pikachu'
226
+ # # }]
227
+ # # }
107
228
  def expose(attribute, **options_hash)
108
229
  options = Decorator::Options.new(options_hash)
109
230
 
@@ -97,9 +97,9 @@ module Azeroth
97
97
  #
98
98
  # @return [Class<Decorator>, NilClass]
99
99
  def decorator_from_options
100
- return options.decorator if options.decorator
100
+ return options.decorator if options.decorator_defined?
101
101
 
102
- Azeroth::DummyDecorator unless options.any_decorator?
102
+ Azeroth::DummyDecorator unless options.decorator
103
103
  end
104
104
 
105
105
  # @private
@@ -13,7 +13,7 @@ module Azeroth
13
13
  DEFAULT_OPTIONS = {
14
14
  as: nil,
15
15
  if: nil,
16
- decorator: nil
16
+ decorator: true
17
17
  }.freeze
18
18
 
19
19
  with_options DEFAULT_OPTIONS
@@ -62,8 +62,8 @@ module Azeroth
62
62
  # #as_json call on value
63
63
  #
64
64
  # @return [TrueClass,FalseClass]
65
- def any_decorator?
66
- decorator != false
65
+ def decorator_defined?
66
+ decorator.is_a?(Class)
67
67
  end
68
68
  end
69
69
  end
@@ -7,6 +7,10 @@ module Azeroth
7
7
  # @author Darthjee
8
8
  #
9
9
  # Concern for building controller methods for the routes
10
+ #
11
+ # @example (see Resourceable::ClassMethods#resource_for)
12
+ #
13
+ # @see Resourceable::ClassMethods
10
14
  module Resourceable
11
15
  extend ActiveSupport::Concern
12
16
 
@@ -10,8 +10,13 @@ module Azeroth
10
10
  # Adds resource methods for resource
11
11
  #
12
12
  # @param name [String, Symbol] Name of the resource
13
- # @param (see Options#initialize)
14
- # @option (see Options#initialize)
13
+ # @param options [Hash] resource building options
14
+ # @option options only [Array<Symbol,String>] List of
15
+ # actions to be built
16
+ # @option options except [Array<Symbol,String>] List of
17
+ # actions to not to be built
18
+ # @option options decorator [Azeroth::Decorator,TrueClass,FalseClass]
19
+ # Decorator class or flag allowing/disallowing decorators
15
20
  #
16
21
  # @return [Array<MethodDefinition>] list of methods created
17
22
  #
@@ -30,6 +35,95 @@ module Azeroth
30
35
  #
31
36
  # resource_for :document, only: %w[create index show]
32
37
  # end
38
+ #
39
+ # @example complete example gmaes and publishers
40
+ # class PublishersController < ApplicationController
41
+ # include Azeroth::Resourceable
42
+ # skip_before_action :verify_authenticity_token
43
+ #
44
+ # resource_for :publisher, only: %i[create index]
45
+ # end
46
+ #
47
+ # class GamesController < ApplicationController
48
+ # include Azeroth::Resourceable
49
+ # skip_before_action :verify_authenticity_token
50
+ #
51
+ # resource_for :game, except: :delete
52
+ #
53
+ # private
54
+ #
55
+ # def games
56
+ # publisher.games
57
+ # end
58
+ #
59
+ # def publisher
60
+ # @publisher ||= Publisher.find(publisher_id)
61
+ # end
62
+ #
63
+ # def publisher_id
64
+ # params.require(:publisher_id)
65
+ # end
66
+ # end
67
+ #
68
+ # ActiveRecord::Schema.define do
69
+ # self.verbose = false
70
+ #
71
+ # create_table :publishers, force: true do |t|
72
+ # t.string :name
73
+ # end
74
+ #
75
+ # create_table :games, force: true do |t|
76
+ # t.string :name
77
+ # t.integer :publisher_id
78
+ # end
79
+ # end
80
+ #
81
+ # class Publisher < ActiveRecord::Base
82
+ # has_many :games
83
+ # end
84
+ #
85
+ # class Game < ActiveRecord::Base
86
+ # belongs_to :publisher
87
+ # end
88
+ #
89
+ # class Game::Decorator < Azeroth::Decorator
90
+ # expose :id
91
+ # expose :name
92
+ # expose :publisher, decorator: NameDecorator
93
+ # end
94
+ #
95
+ # @example requesting games and publishers
96
+ # post "/publishers.json", params: {
97
+ # publisher: {
98
+ # name: 'Nintendo'
99
+ # }
100
+ # }
101
+ #
102
+ # publisher = JSON.parse(response.body)
103
+ # # returns
104
+ # # {
105
+ # # 'id' => 11,
106
+ # # 'name' => 'Nintendo'
107
+ # # }
108
+ #
109
+ # publisher = Publisher.last
110
+ # post "/publishers/#{publisher['id']}/games.json", params: {
111
+ # game: {
112
+ # name: 'Pokemon'
113
+ # }
114
+ # }
115
+ #
116
+ # game = Game.last
117
+ #
118
+ # JSON.parse(response.body)
119
+ # # returns
120
+ # # {
121
+ # # id: game.id,
122
+ # # name: 'Pokemon',
123
+ # # publisher: {
124
+ # # name: 'Nintendo'
125
+ # # }
126
+ # }
33
127
  def resource_for(name, **options)
34
128
  Builder.new(
35
129
  self, name, Azeroth::Options.new(options)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Azeroth
4
- VERSION = '0.6.3'
4
+ VERSION = '0.6.4'
5
5
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GamesController < ApplicationController
4
+ include Azeroth::Resourceable
5
+ skip_before_action :verify_authenticity_token
6
+
7
+ resource_for :game, except: :delete
8
+
9
+ private
10
+
11
+ def games
12
+ publisher.games
13
+ end
14
+
15
+ def publisher
16
+ @publisher ||= Publisher.find(publisher_id)
17
+ end
18
+
19
+ def publisher_id
20
+ params.require(:publisher_id)
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PublishersController < ApplicationController
4
+ include Azeroth::Resourceable
5
+ skip_before_action :verify_authenticity_token
6
+
7
+ resource_for :publisher, only: %i[create index]
8
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Game < ActiveRecord::Base
4
+ belongs_to :publisher
5
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Game < ActiveRecord::Base
4
+ class Decorator < Azeroth::Decorator
5
+ expose :id
6
+ expose :name
7
+ expose :publisher, decorator: NameDecorator
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NameDecorator < Azeroth::Decorator
4
+ expose :name
5
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pokemon < ActiveRecord::Base
4
+ belongs_to :pokemon_master
5
+ has_one :previous_form,
6
+ class_name: 'Pokemon',
7
+ foreign_key: :previous_form_id
8
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pokemon
4
+ class Decorator < Azeroth::Decorator
5
+ expose :name
6
+ expose :previous_form_name, as: :evolution_of, if: :evolution?
7
+
8
+ def evolution?
9
+ previous_form
10
+ end
11
+
12
+ def previous_form_name
13
+ previous_form.name
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pokemon
4
+ class FavoriteDecorator < Pokemon::Decorator
5
+ expose :nickname
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PokemonMaster < ActiveRecord::Base
4
+ has_one :favorite_pokemon, -> { where(favorite: true) },
5
+ class_name: 'Pokemon'
6
+ has_many :pokemons
7
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PokemonMaster
4
+ class Decorator < Azeroth::Decorator
5
+ expose :name
6
+ expose :age
7
+ expose :favorite_pokemon, decorator: Pokemon::FavoriteDecorator
8
+ expose :pokemons
9
+
10
+ def name
11
+ [
12
+ first_name,
13
+ last_name
14
+ ].compact.join(' ')
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Publisher < ActiveRecord::Base
4
+ has_many :games
5
+ end
@@ -4,4 +4,8 @@ Rails.application.routes.draw do
4
4
  resources :documents
5
5
  resources :public_documents, controller: :index_documents
6
6
  resources :create_documents, controller: :documents_with_error
7
+
8
+ resources :publishers, only: %i[create index] do
9
+ resources :games, except: :delete
10
+ end
7
11
  end
@@ -22,4 +22,30 @@ ActiveRecord::Schema.define do
22
22
  t.integer :factory_id
23
23
  t.string :name
24
24
  end
25
+
26
+ create_table :publishers, force: true do |t|
27
+ t.string :name
28
+ end
29
+
30
+ create_table :games, force: true do |t|
31
+ t.string :name
32
+ t.integer :publisher_id
33
+ end
34
+
35
+ create_table :pokemon_masters, force: true do |t|
36
+ t.string :first_name, null: false
37
+ t.string :last_name
38
+ t.integer :age, null: false
39
+ end
40
+
41
+ create_table :pokemons, force: true do |t|
42
+ t.string :name, null: false
43
+ t.string :nickname
44
+ t.integer :pokemon_master_id
45
+ t.boolean :favorite
46
+ t.integer :previous_form_id
47
+ t.index %i[pokemon_master_id favorite], unique: true
48
+ end
49
+
50
+ add_foreign_key 'pokemons', 'pokemon_masters'
25
51
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Azeroth::Decorator do
6
+ describe 'readme' do
7
+ it 'decorates model' do
8
+ master = PokemonMaster.create(
9
+ first_name: 'Ash',
10
+ last_name: 'Ketchum',
11
+ age: 10
12
+ )
13
+
14
+ master.create_favorite_pokemon(
15
+ name: 'pikachu',
16
+ nickname: 'Pikachu'
17
+ )
18
+
19
+ metapod = Pokemon.create(name: :metapod)
20
+
21
+ master.pokemons.create(
22
+ name: 'butterfree', previous_form: metapod
23
+ )
24
+ master.pokemons.create(name: 'squirtle')
25
+
26
+ decorator = PokemonMaster::Decorator.new(master)
27
+
28
+ expect(decorator.as_json).to eq(
29
+ {
30
+ 'age' => 10,
31
+ 'name' => 'Ash Ketchum',
32
+ 'favorite_pokemon' => {
33
+ 'name' => 'pikachu',
34
+ 'nickname' => 'Pikachu'
35
+ },
36
+ 'pokemons' => [{
37
+ 'name' => 'butterfree',
38
+ 'evolution_of' => 'metapod'
39
+ }, {
40
+ 'name' => 'squirtle'
41
+ }, {
42
+ 'name' => 'pikachu'
43
+ }]
44
+ }
45
+ )
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GamesController, controller: true do
6
+ describe 'readme' do
7
+ describe 'POST create' do
8
+ it 'create game' do
9
+ post '/publishers.json', params: {
10
+ publisher: {
11
+ name: 'Nintendo'
12
+ }
13
+ }
14
+
15
+ publisher = JSON.parse(response.body)
16
+ expect(publisher)
17
+ .to eq({
18
+ 'id' => publisher['id'],
19
+ 'name' => 'Nintendo'
20
+ })
21
+
22
+ publisher = Publisher.last
23
+ post "/publishers/#{publisher['id']}/games.json", params: {
24
+ game: {
25
+ name: 'Pokemon'
26
+ }
27
+ }
28
+
29
+ game = Game.last
30
+
31
+ expect(JSON.parse(response.body))
32
+ .to eq({
33
+ 'id' => game.id,
34
+ 'name' => 'Pokemon',
35
+ 'publisher' => {
36
+ 'name' => 'Nintendo'
37
+ }
38
+ })
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,24 +1,65 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Azeroth::Decorator do
4
- subject(:decorator) { DummyModel::Decorator.new(object) }
5
-
6
- let(:object) do
7
- DummyModel.new(
8
- id: 100,
9
- first_name: 'John',
10
- last_name: 'Wick',
11
- favorite_pokemon: 'Arcanine'
12
- )
13
- end
4
+ describe 'yard' do
5
+ describe '#as_json' do
6
+ it 'simple example' do
7
+ object = DummyModel.new(
8
+ id: 100,
9
+ first_name: 'John',
10
+ last_name: 'Wick',
11
+ favorite_pokemon: 'Arcanine'
12
+ )
13
+
14
+ decorator = DummyModel::Decorator.new(object)
15
+
16
+ expect(decorator.as_json).to eq(
17
+ 'name' => 'John Wick',
18
+ 'age' => nil,
19
+ 'pokemon' => 'Arcanine'
20
+ )
21
+ end
22
+
23
+ it 'complete example' do
24
+ master = PokemonMaster.create(
25
+ first_name: 'Ash',
26
+ last_name: 'Ketchum',
27
+ age: 10
28
+ )
29
+
30
+ master.create_favorite_pokemon(
31
+ name: 'pikachu',
32
+ nickname: 'Pikachu'
33
+ )
34
+
35
+ metapod = Pokemon.create(name: :metapod)
36
+
37
+ master.pokemons.create(
38
+ name: 'butterfree', previous_form: metapod
39
+ )
40
+ master.pokemons.create(name: 'squirtle')
41
+
42
+ decorator = PokemonMaster::Decorator.new(master)
14
43
 
15
- describe '#as_json' do
16
- it 'returns exposed attributes' do
17
- expect(decorator.as_json).to eq(
18
- 'name' => 'John Wick',
19
- 'age' => nil,
20
- 'pokemon' => 'Arcanine'
21
- )
44
+ expect(decorator.as_json).to eq(
45
+ {
46
+ 'age' => 10,
47
+ 'name' => 'Ash Ketchum',
48
+ 'favorite_pokemon' => {
49
+ 'name' => 'pikachu',
50
+ 'nickname' => 'Pikachu'
51
+ },
52
+ 'pokemons' => [{
53
+ 'name' => 'butterfree',
54
+ 'evolution_of' => 'metapod'
55
+ }, {
56
+ 'name' => 'squirtle'
57
+ }, {
58
+ 'name' => 'pikachu'
59
+ }]
60
+ }
61
+ )
62
+ end
22
63
  end
23
64
  end
24
65
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GamesController, controller: true do
6
+ describe 'yard' do
7
+ describe 'POST create' do
8
+ it 'create game' do
9
+ post '/publishers.json', params: {
10
+ publisher: {
11
+ name: 'Nintendo'
12
+ }
13
+ }
14
+
15
+ publisher = JSON.parse(response.body)
16
+ expect(publisher)
17
+ .to eq({
18
+ 'id' => publisher['id'],
19
+ 'name' => 'Nintendo'
20
+ })
21
+
22
+ publisher = Publisher.last
23
+ post "/publishers/#{publisher['id']}/games.json", params: {
24
+ game: {
25
+ name: 'Pokemon'
26
+ }
27
+ }
28
+
29
+ game = Game.last
30
+
31
+ expect(JSON.parse(response.body))
32
+ .to eq({
33
+ 'id' => game.id,
34
+ 'name' => 'Pokemon',
35
+ 'publisher' => {
36
+ 'name' => 'Nintendo'
37
+ }
38
+ })
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :game, class: '::Game' do
5
+ sequence(:name) { |n| "Game #{n}" }
6
+ publisher
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :publisher, class: '::Publisher' do
5
+ sequence(:name) { |n| "Publisher #{n}" }
6
+ end
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: azeroth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darthjee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-05 00:00:00.000000000 Z
11
+ date: 2020-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -452,7 +452,9 @@ files:
452
452
  - spec/dummy/app/controllers/concerns/.keep
453
453
  - spec/dummy/app/controllers/documents_controller.rb
454
454
  - spec/dummy/app/controllers/documents_with_error_controller.rb
455
+ - spec/dummy/app/controllers/games_controller.rb
455
456
  - spec/dummy/app/controllers/index_documents_controller.rb
457
+ - spec/dummy/app/controllers/publishers_controller.rb
456
458
  - spec/dummy/app/helpers/application_helper.rb
457
459
  - spec/dummy/app/jobs/application_job.rb
458
460
  - spec/dummy/app/mailers/application_mailer.rb
@@ -465,10 +467,19 @@ files:
465
467
  - spec/dummy/app/models/dummy_model/decorator.rb
466
468
  - spec/dummy/app/models/factory.rb
467
469
  - spec/dummy/app/models/factory/decorator_with_product.rb
470
+ - spec/dummy/app/models/game.rb
471
+ - spec/dummy/app/models/game/decorator.rb
468
472
  - spec/dummy/app/models/id_decorator.rb
473
+ - spec/dummy/app/models/name_decorator.rb
474
+ - spec/dummy/app/models/pokemon.rb
475
+ - spec/dummy/app/models/pokemon/decorator.rb
476
+ - spec/dummy/app/models/pokemon/favorite_decorator.rb
477
+ - spec/dummy/app/models/pokemon_master.rb
478
+ - spec/dummy/app/models/pokemon_master/decorator.rb
469
479
  - spec/dummy/app/models/product.rb
470
480
  - spec/dummy/app/models/product/decorator.rb
471
481
  - spec/dummy/app/models/product/decorator_with_factory.rb
482
+ - spec/dummy/app/models/publisher.rb
472
483
  - spec/dummy/app/models/user.rb
473
484
  - spec/dummy/app/views/documents/edit.html
474
485
  - spec/dummy/app/views/documents/index.html
@@ -519,7 +530,10 @@ files:
519
530
  - spec/dummy/storage/.keep
520
531
  - spec/dummy/tmp/.keep
521
532
  - spec/dummy/tmp/storage/.keep
533
+ - spec/integration/readme/azeroth/decorator_spec.rb
534
+ - spec/integration/readme/controllers/games_controller_spec.rb
522
535
  - spec/integration/yard/azeroth/decorator_spec.rb
536
+ - spec/integration/yard/controllers/games_controller_spec.rb
523
537
  - spec/lib/azeroth/decorator/hash_builder_spec.rb
524
538
  - spec/lib/azeroth/decorator/key_value_extractor_spec.rb
525
539
  - spec/lib/azeroth/decorator_spec.rb
@@ -545,7 +559,9 @@ files:
545
559
  - spec/support/factories/document.rb
546
560
  - spec/support/factories/dummy_model.rb
547
561
  - spec/support/factories/factory.rb
562
+ - spec/support/factories/game.rb
548
563
  - spec/support/factories/product.rb
564
+ - spec/support/factories/publisher.rb
549
565
  - spec/support/factories/user.rb
550
566
  - spec/support/factory_bot.rb
551
567
  - spec/support/matchers/add_method.rb
@@ -591,7 +607,9 @@ test_files:
591
607
  - spec/dummy/app/controllers/concerns/.keep
592
608
  - spec/dummy/app/controllers/documents_controller.rb
593
609
  - spec/dummy/app/controllers/documents_with_error_controller.rb
610
+ - spec/dummy/app/controllers/games_controller.rb
594
611
  - spec/dummy/app/controllers/index_documents_controller.rb
612
+ - spec/dummy/app/controllers/publishers_controller.rb
595
613
  - spec/dummy/app/helpers/application_helper.rb
596
614
  - spec/dummy/app/jobs/application_job.rb
597
615
  - spec/dummy/app/mailers/application_mailer.rb
@@ -604,10 +622,19 @@ test_files:
604
622
  - spec/dummy/app/models/dummy_model/decorator.rb
605
623
  - spec/dummy/app/models/factory.rb
606
624
  - spec/dummy/app/models/factory/decorator_with_product.rb
625
+ - spec/dummy/app/models/game.rb
626
+ - spec/dummy/app/models/game/decorator.rb
607
627
  - spec/dummy/app/models/id_decorator.rb
628
+ - spec/dummy/app/models/name_decorator.rb
629
+ - spec/dummy/app/models/pokemon.rb
630
+ - spec/dummy/app/models/pokemon/decorator.rb
631
+ - spec/dummy/app/models/pokemon/favorite_decorator.rb
632
+ - spec/dummy/app/models/pokemon_master.rb
633
+ - spec/dummy/app/models/pokemon_master/decorator.rb
608
634
  - spec/dummy/app/models/product.rb
609
635
  - spec/dummy/app/models/product/decorator.rb
610
636
  - spec/dummy/app/models/product/decorator_with_factory.rb
637
+ - spec/dummy/app/models/publisher.rb
611
638
  - spec/dummy/app/models/user.rb
612
639
  - spec/dummy/app/views/documents/edit.html
613
640
  - spec/dummy/app/views/documents/index.html
@@ -658,7 +685,10 @@ test_files:
658
685
  - spec/dummy/storage/.keep
659
686
  - spec/dummy/tmp/.keep
660
687
  - spec/dummy/tmp/storage/.keep
688
+ - spec/integration/readme/azeroth/decorator_spec.rb
689
+ - spec/integration/readme/controllers/games_controller_spec.rb
661
690
  - spec/integration/yard/azeroth/decorator_spec.rb
691
+ - spec/integration/yard/controllers/games_controller_spec.rb
662
692
  - spec/lib/azeroth/decorator/hash_builder_spec.rb
663
693
  - spec/lib/azeroth/decorator/key_value_extractor_spec.rb
664
694
  - spec/lib/azeroth/decorator_spec.rb
@@ -684,7 +714,9 @@ test_files:
684
714
  - spec/support/factories/document.rb
685
715
  - spec/support/factories/dummy_model.rb
686
716
  - spec/support/factories/factory.rb
717
+ - spec/support/factories/game.rb
687
718
  - spec/support/factories/product.rb
719
+ - spec/support/factories/publisher.rb
688
720
  - spec/support/factories/user.rb
689
721
  - spec/support/factory_bot.rb
690
722
  - spec/support/matchers/add_method.rb