Skip to content

Commit 299c011

Browse files
authored
feat: add question predicate method for check in severals values (#44)
1 parent 30df8f7 commit 299c011

File tree

6 files changed

+41
-15
lines changed

6 files changed

+41
-15
lines changed

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ Gp/UnsafeYamlMarshal:
2424
Enabled: true
2525
Exclude:
2626
- spec/**/*.rb
27+
28+
Gp/OptArgParameters:
29+
Enabled: false

Gemfile.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ GEM
7373
zeitwerk (~> 2.6)
7474
i18n (1.14.6)
7575
concurrent-ruby (~> 1.0)
76-
json (2.8.2)
76+
json (2.9.0)
7777
language_server-protocol (3.17.0.3)
7878
logger (1.6.1)
7979
method_source (1.1.0)
@@ -89,7 +89,7 @@ GEM
8989
rack (3.1.8)
9090
rainbow (3.1.1)
9191
rake (13.2.1)
92-
regexp_parser (2.9.2)
92+
regexp_parser (2.9.3)
9393
rspec (3.13.0)
9494
rspec-core (~> 3.13.0)
9595
rspec-expectations (~> 3.13.0)
@@ -103,17 +103,17 @@ GEM
103103
diff-lcs (>= 1.2.0, < 2.0)
104104
rspec-support (~> 3.13.0)
105105
rspec-support (3.13.1)
106-
rubocop (1.69.0)
106+
rubocop (1.69.2)
107107
json (~> 2.3)
108108
language_server-protocol (>= 3.17.0)
109109
parallel (~> 1.10)
110110
parser (>= 3.3.0.2)
111111
rainbow (>= 2.2.2, < 4.0)
112-
regexp_parser (>= 2.4, < 3.0)
113-
rubocop-ast (>= 1.36.1, < 2.0)
112+
regexp_parser (>= 2.9.3, < 3.0)
113+
rubocop-ast (>= 1.36.2, < 2.0)
114114
ruby-progressbar (~> 1.7)
115115
unicode-display_width (>= 2.4.0, < 4.0)
116-
rubocop-ast (1.36.1)
116+
rubocop-ast (1.37.0)
117117
parser (>= 3.3.1.0)
118118
rubocop-capybara (2.21.0)
119119
rubocop (~> 1.41)

lib/enum_machine/build_enum_class.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def self.call(enum_values:, i18n_scope:, value_class:, machine: nil)
2020
end
2121

2222
if i18n_scope
23-
def self.values_for_form(specific_values = nil) # rubocop:disable Gp/OptArgParameters
23+
def self.values_for_form(specific_values = nil)
2424
(specific_values || values).map { |v| [human_name_for(v), v] }
2525
end
2626

lib/enum_machine/build_value_class.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ def self.call(enum_values:, i18n_scope:, value_decorator:, machine: nil)
88
Class.new(String) do
99
include(value_decorator) if value_decorator
1010

11-
define_method(:machine) { machine } if machine
11+
define_method(:machine) { machine }
12+
define_method(:enum_values) { enum_values }
13+
private :enum_values, :machine
1214

1315
def inspect
1416
"#<EnumMachine \"#{self}\">"
@@ -50,6 +52,22 @@ def can?(enum_value)
5052
::I18n.t(self, scope: full_scope, default: self)
5153
end
5254
end
55+
56+
def respond_to_missing?(method_name, _include_private = false)
57+
method_name = method_name.name if method_name.is_a?(Symbol)
58+
59+
method_name.end_with?("?") &&
60+
method_name.include?("__") &&
61+
(method_name.delete_suffix("?").split("__") - enum_values).empty?
62+
end
63+
64+
def method_missing(method_name)
65+
return super unless respond_to_missing?(method_name)
66+
67+
m_enums = method_name.name.delete_suffix("?").split("__")
68+
self.class.define_method(method_name) { m_enums.include?(self) }
69+
send(method_name)
70+
end
5371
end
5472
end
5573
end

lib/enum_machine/machine.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module EnumMachine
44
class Machine
55
attr_reader :enum_values, :base_klass, :enum_const_name, :attr_name
66

7-
def initialize(enum_values, base_klass = nil, enum_const_name = nil, attr_name = nil) # rubocop:disable Gp/OptArgParameters
7+
def initialize(enum_values, base_klass = nil, enum_const_name = nil, attr_name = nil)
88
@enum_values = enum_values
99
@base_klass = base_klass
1010
@enum_const_name = enum_const_name

spec/enum_machine/driver_simple_class_spec.rb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def initialize(state)
77
@state = state
88
end
99

10-
include EnumMachine[state: { enum: %w[choice in_delivery] }]
10+
include EnumMachine[state: { enum: %w[choice in_delivery lost] }]
1111
end
1212

1313
module ValueDecorator
@@ -23,14 +23,17 @@ def initialize(state)
2323
@state = state
2424
end
2525

26-
include EnumMachine[state: { enum: %w[choice in_delivery], value_decorator: ValueDecorator }]
26+
include EnumMachine[state: { enum: %w[choice in_delivery lost], value_decorator: ValueDecorator }]
2727
end
2828

2929
RSpec.describe "DriverSimpleClass" do
3030
subject(:item) { TestClass.new("choice") }
3131

32-
it { expect(item.state).to be_choice }
33-
it { expect(item.state).not_to be_in_delivery }
32+
it { expect(item.state.choice?).to be true }
33+
it { expect(item.state.in_delivery?).to be false }
34+
it { expect(item.state.choice__in_delivery?).to be true }
35+
it { expect(item.state.lost__in_delivery?).to be false }
36+
it { expect { item.state.last__in_delivery? }.to raise_error(NoMethodError) }
3437
it { expect(item.state).to eq "choice" }
3538
it { expect(item.state.frozen?).to be true }
3639

@@ -68,13 +71,15 @@ def initialize(state)
6871

6972
describe "TestClass::STATE const" do
7073
it "#values" do
71-
expect(TestClass::STATE.values).to eq(%w[choice in_delivery])
74+
expect(TestClass::STATE.values).to eq(%w[choice in_delivery lost])
7275
end
7376

7477
it "#[]" do
7578
expect(TestClass::STATE["in_delivery"]).to eq "in_delivery"
7679
expect(TestClass::STATE["in_delivery"].in_delivery?).to be(true)
7780
expect(TestClass::STATE["in_delivery"].choice?).to be(false)
81+
expect(TestClass::STATE["in_delivery"].in_delivery__choice?).to be(true)
82+
expect(TestClass::STATE["in_delivery"].lost__choice?).to be(false)
7883
expect(TestClass::STATE["wrong"]).to be_nil
7984
end
8085

@@ -118,7 +123,7 @@ def initialize(state)
118123
end
119124

120125
it "decorates enum values in enum const" do
121-
expect(TestClassWithDecorator::STATE.values.map(&:am_i_choice?)).to eq([true, false])
126+
expect(TestClassWithDecorator::STATE.values.map(&:am_i_choice?)).to eq([true, false, false])
122127
expect((TestClassWithDecorator::STATE.values & ["in_delivery"]).map(&:am_i_choice?)).to eq([false])
123128
end
124129

0 commit comments

Comments
 (0)