Skip to content

Commit 897df91

Browse files
michaelkhabarovmichaelkhabarov
authored andcommitted
Decorators refactor (#41)
1 parent e01272a commit 897df91

File tree

11 files changed

+121
-62
lines changed

11 files changed

+121
-62
lines changed

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ AllCops:
88
Rails/ApplicationRecord:
99
Enabled: false
1010

11+
Rails/Output:
12+
Enabled: false
13+
1114
Metrics/ParameterLists:
1215
CountKeywordArgs: false
1316

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ GIT
2222
PATH
2323
remote: .
2424
specs:
25-
enum_machine (1.0.0)
25+
enum_machine (2.0.0)
2626
activemodel
2727
activerecord
2828
activesupport
@@ -138,7 +138,7 @@ GEM
138138
sqlite3 (1.7.3-arm64-darwin)
139139
sqlite3 (1.7.3-x86_64-darwin)
140140
sqlite3 (1.7.3-x86_64-linux)
141-
timeout (0.4.1)
141+
timeout (0.4.2)
142142
tzinfo (2.0.6)
143143
concurrent-ruby (~> 1.0)
144144
unicode-display_width (3.1.2)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class Product
6969

7070
include EnumMachine[color: { enum: %w[red green] }]
7171
# or reuse from model
72-
Product::COLOR.decorator_module
72+
Product::COLOR.enum_decorator
7373
end
7474

7575
Product::COLOR.values # => ["red", "green"]
@@ -122,8 +122,8 @@ class Product
122122
attr_accessor :color
123123

124124
include EnumMachine[color: {
125-
enum: %w[red green],
126-
decorator: ColorDecorator
125+
enum: %w[red green],
126+
value_decorator: ColorDecorator
127127
}]
128128
end
129129

lib/enum_machine.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
require_relative "enum_machine/version"
44
require_relative "enum_machine/driver_simple_class"
5-
require_relative "enum_machine/build_attribute"
5+
require_relative "enum_machine/build_value_class"
66
require_relative "enum_machine/attribute_persistence_methods"
7-
require_relative "enum_machine/build_class"
7+
require_relative "enum_machine/build_enum_class"
88
require_relative "enum_machine/machine"
99
require "active_support"
1010

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
module EnumMachine
4-
module BuildClass
4+
module BuildEnumClass
55
def self.call(enum_values:, i18n_scope:, value_class:, machine: nil)
66
aliases = machine&.instance_variable_get(:@aliases) || {}
77

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# frozen_string_literal: true
22

33
module EnumMachine
4-
module BuildAttribute
5-
def self.call(enum_values:, i18n_scope:, decorator:, machine: nil)
4+
module BuildValueClass
5+
def self.call(enum_values:, i18n_scope:, value_decorator:, machine: nil)
66
aliases = machine&.instance_variable_get(:@aliases) || {}
77

88
Class.new(String) do
9-
include(decorator) if decorator
9+
include(value_decorator) if value_decorator
1010

1111
define_method(:machine) { machine } if machine
1212

lib/enum_machine/driver_active_record.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module EnumMachine
44
module DriverActiveRecord
5-
def enum_machine(attr, enum_values, i18n_scope: nil, decorator: nil, &block)
5+
def enum_machine(attr, enum_values, i18n_scope: nil, value_decorator: nil, &block)
66
klass = self
77

88
i18n_scope ||= "#{klass.base_class.to_s.underscore}.#{attr}"
@@ -11,13 +11,13 @@ def enum_machine(attr, enum_values, i18n_scope: nil, decorator: nil, &block)
1111
machine = Machine.new(enum_values, klass, enum_const_name, attr)
1212
machine.instance_eval(&block) if block
1313

14-
value_class = BuildAttribute.call(enum_values: enum_values, i18n_scope: i18n_scope, machine: machine, decorator: decorator)
15-
enum_klass = BuildClass.call(enum_values: enum_values, i18n_scope: i18n_scope, machine: machine, value_class: value_class)
14+
value_class = BuildValueClass.call(enum_values: enum_values, i18n_scope: i18n_scope, machine: machine, value_decorator: value_decorator)
15+
enum_class = BuildEnumClass.call(enum_values: enum_values, i18n_scope: i18n_scope, machine: machine, value_class: value_class)
1616

1717
value_class.extend(AttributePersistenceMethods[attr, enum_values])
1818

1919
# default_proc for working with custom values not defined in enum list but may exists in db
20-
enum_klass.value_attribute_mapping.default_proc =
20+
enum_class.value_attribute_mapping.default_proc =
2121
proc do |hash, enum_value|
2222
hash[enum_value] = value_class.new(enum_value).freeze
2323
end
@@ -102,12 +102,12 @@ def initialize_dup(other)
102102

103103
enum_decorator =
104104
Module.new do
105-
define_singleton_method(:included) do |decorating_klass|
106-
decorating_klass.prepend define_methods
107-
decorating_klass.const_set enum_const_name, enum_klass
105+
define_singleton_method(:included) do |decorating_class|
106+
decorating_class.prepend define_methods
107+
decorating_class.const_set enum_const_name, enum_class
108108
end
109109
end
110-
enum_klass.define_singleton_method(:decorator_module) { enum_decorator }
110+
enum_class.define_singleton_method(:enum_decorator) { enum_decorator }
111111

112112
klass.include(enum_decorator)
113113

lib/enum_machine/driver_simple_class.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,35 @@ def self.call(args)
1111
Module.new do
1212
define_singleton_method(:included) do |klass|
1313
args.each do |attr, params|
14-
enum_values = params.fetch(:enum)
15-
i18n_scope = params.fetch(:i18n_scope, nil)
16-
decorator = params.fetch(:decorator, nil)
14+
enum_values = params.fetch(:enum)
15+
i18n_scope = params.fetch(:i18n_scope, nil)
16+
value_decorator = params.fetch(:value_decorator, nil)
1717

1818
if defined?(ActiveRecord) && klass <= ActiveRecord::Base
1919
klass.enum_machine(attr, enum_values, i18n_scope: i18n_scope)
2020
else
2121
enum_const_name = attr.to_s.upcase
22-
value_class = BuildAttribute.call(enum_values: enum_values, i18n_scope: i18n_scope, decorator: decorator)
23-
enum_klass = BuildClass.call(enum_values: enum_values, i18n_scope: i18n_scope, value_class: value_class)
22+
value_class = BuildValueClass.call(enum_values: enum_values, i18n_scope: i18n_scope, value_decorator: value_decorator)
23+
enum_class = BuildEnumClass.call(enum_values: enum_values, i18n_scope: i18n_scope, value_class: value_class)
2424

2525
define_methods =
2626
Module.new do
2727
define_method(attr) do
2828
enum_value = super()
2929
return unless enum_value
3030

31-
enum_klass.value_attribute_mapping.fetch(enum_value)
31+
enum_class.value_attribute_mapping.fetch(enum_value)
3232
end
3333
end
3434

3535
enum_decorator =
3636
Module.new do
37-
define_singleton_method(:included) do |decorating_klass|
38-
decorating_klass.prepend define_methods
39-
decorating_klass.const_set enum_const_name, enum_klass
37+
define_singleton_method(:included) do |decorating_class|
38+
decorating_class.prepend define_methods
39+
decorating_class.const_set enum_const_name, enum_class
4040
end
4141
end
42-
enum_klass.define_singleton_method(:decorator_module) { enum_decorator }
42+
enum_class.define_singleton_method(:enum_decorator) { enum_decorator }
4343

4444
klass.include(enum_decorator)
4545
enum_decorator

lib/enum_machine/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module EnumMachine
4-
VERSION = "1.0.0"
4+
VERSION = "2.0.0"
55
end

spec/enum_machine/active_record_enum_spec.rb

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@
7878
end
7979
end
8080

81-
context "when with decorator" do
82-
let(:decorator_module) do
81+
context "when with value_decorator" do
82+
let(:decorator) do
8383
Module.new do
8484
def am_i_choice?
8585
self == "choice"
@@ -88,9 +88,9 @@ def am_i_choice?
8888
end
8989

9090
let(:model_with_decorator) do
91-
decorator = decorator_module
91+
value_decorator = decorator
9292
Class.new(TestModel) do
93-
enum_machine :state, %w[choice in_delivery], decorator: decorator
93+
enum_machine :state, %w[choice in_delivery], value_decorator: value_decorator
9494
end
9595
end
9696

@@ -106,6 +106,73 @@ def am_i_choice?
106106
end
107107
end
108108

109+
describe("#enum_decorator") do
110+
let(:model) do
111+
Class.new(TestModel) do
112+
enum_machine :state, %w[choice in_delivery]
113+
include EnumMachine[color: { enum: %w[red green blue] }]
114+
end
115+
end
116+
117+
let(:klass) do
118+
Class.new(TestModel) do
119+
enum_machine :state, %w[choice in_delivery]
120+
include EnumMachine[color: { enum: %w[red green blue] }]
121+
end
122+
end
123+
124+
it "decorates plain class from ar" do
125+
decorating_model = model
126+
decorated_class =
127+
Class.new do
128+
include decorating_model::STATE.enum_decorator
129+
include decorating_model::COLOR.enum_decorator
130+
attr_accessor :state, :color
131+
end
132+
133+
decorated_item = decorated_class.new
134+
decorated_item.state = "choice"
135+
decorated_item.color = "red"
136+
137+
expect(decorated_item.state).to be_choice
138+
expect(decorated_item.color).to be_red
139+
expect(decorated_class::STATE::CHOICE).to eq "choice"
140+
expect(decorated_class::COLOR::RED).to eq "red"
141+
end
142+
143+
it "decorates ar from plain class" do
144+
decorating_class = klass
145+
decorated_model =
146+
Class.new(TestModel) do
147+
include decorating_class::STATE.enum_decorator
148+
include decorating_class::COLOR.enum_decorator
149+
end
150+
151+
decorated_item = decorated_model.new(state: "choice", color: "red")
152+
153+
expect(decorated_item.state).to be_choice
154+
expect(decorated_item.color).to be_red
155+
expect(decorated_model::STATE::CHOICE).to eq "choice"
156+
expect(decorated_model::COLOR::RED).to eq "red"
157+
end
158+
159+
it "decorates ar from ar" do
160+
decorating_model = model
161+
decorated_model =
162+
Class.new(TestModel) do
163+
include decorating_model::STATE.enum_decorator
164+
include decorating_model::COLOR.enum_decorator
165+
end
166+
167+
decorated_item = decorated_model.new(state: "choice", color: "red")
168+
169+
expect(decorated_item.state).to be_choice
170+
expect(decorated_item.color).to be_red
171+
expect(decorated_model::STATE::CHOICE).to eq "choice"
172+
expect(decorated_model::COLOR::RED).to eq "red"
173+
end
174+
end
175+
109176
it "serialize model" do
110177
Object.const_set(:TestModelSerialize, model)
111178
m = TestModelSerialize.create(state: "choice", color: "wrong")
@@ -118,30 +185,6 @@ def am_i_choice?
118185
expect(unserialized_m.color.red?).to be(false)
119186
end
120187

121-
it "test decorator" do
122-
decorating_model =
123-
Class.new(TestModel) do
124-
enum_machine :state, %w[choice in_delivery]
125-
include EnumMachine[color: { enum: %w[red green blue] }]
126-
end
127-
128-
decorated_klass =
129-
Class.new do
130-
include decorating_model::STATE.decorator_module
131-
include decorating_model::COLOR.decorator_module
132-
attr_accessor :state, :color
133-
end
134-
135-
decorated_item = decorated_klass.new
136-
decorated_item.state = "choice"
137-
decorated_item.color = "red"
138-
139-
expect(decorated_item.state).to be_choice
140-
expect(decorated_item.color).to be_red
141-
expect(decorated_klass::STATE::CHOICE).to eq "choice"
142-
expect(decorated_klass::COLOR::RED).to eq "red"
143-
end
144-
145188
it "returns state value by []" do
146189
expect(model::STATE["in_delivery"]).to eq "in_delivery"
147190
expect(model::STATE["in_delivery"].in_delivery?).to be(true)

0 commit comments

Comments
 (0)