ruby-enum 0.9.0 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +94 -64
- data/README.md +59 -0
- data/Rakefile +7 -0
- data/benchmarks/case.rb +45 -0
- data/coverage/index.html +5445 -501
- data/lib/ruby-enum/enum/case.rb +84 -0
- data/lib/ruby-enum/enum/i18n_mock.rb +19 -0
- data/lib/ruby-enum/enum.rb +6 -3
- data/lib/ruby-enum/errors/base.rb +3 -3
- data/lib/ruby-enum/version.rb +1 -1
- data/lib/ruby-enum.rb +15 -3
- data/ruby-enum.gemspec +2 -1
- data/spec/ruby-enum/enum/case_spec.rb +118 -0
- data/spec/ruby-enum/enum_spec.rb +106 -34
- data/spec_i18n/Gemfile +9 -0
- data/spec_i18n/Gemfile.lock +35 -0
- data/spec_i18n/Rakefile +12 -0
- data/spec_i18n/spec/i18n_spec.rb +48 -0
- data/spec_i18n/spec/spec_helper.rb +8 -0
- metadata +16 -21
- data/pkg/ruby-enum-0.8.0.gem +0 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ruby
|
4
|
+
module Enum
|
5
|
+
##
|
6
|
+
# Adds a method to an enum class that allows for exhaustive matching on a value.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class Color
|
10
|
+
# include Ruby::Enum
|
11
|
+
# include Ruby::Enum::Case
|
12
|
+
#
|
13
|
+
# define :RED, :red
|
14
|
+
# define :GREEN, :green
|
15
|
+
# define :BLUE, :blue
|
16
|
+
# define :YELLOW, :yellow
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Color.case(Color::RED, {
|
20
|
+
# [Color::RED, Color::GREEN] => -> { "red or green" },
|
21
|
+
# Color::BLUE => -> { "blue" },
|
22
|
+
# Color::YELLOW => -> { "yellow" },
|
23
|
+
# })
|
24
|
+
#
|
25
|
+
# Reserves the :else key for a default case:
|
26
|
+
# Color.case(Color::RED, {
|
27
|
+
# [Color::RED, Color::GREEN] => -> { "red or green" },
|
28
|
+
# else: -> { "blue or yellow" },
|
29
|
+
# })
|
30
|
+
module Case
|
31
|
+
def self.included(klass)
|
32
|
+
klass.extend(ClassMethods)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# @see Ruby::Enum::Case
|
37
|
+
module ClassMethods
|
38
|
+
class ValuesNotDefinedError < StandardError
|
39
|
+
end
|
40
|
+
|
41
|
+
class NotAllCasesHandledError < StandardError
|
42
|
+
end
|
43
|
+
|
44
|
+
def case(value, cases)
|
45
|
+
validate_cases(cases)
|
46
|
+
|
47
|
+
filtered_cases = cases.select do |values, _proc|
|
48
|
+
values = [values] unless values.is_a?(Array)
|
49
|
+
values.include?(value)
|
50
|
+
end
|
51
|
+
|
52
|
+
return call_proc(cases[:else], value) if filtered_cases.none?
|
53
|
+
|
54
|
+
results = filtered_cases.map { |_values, proc| call_proc(proc, value) }
|
55
|
+
|
56
|
+
# Return the first result if there is only one result
|
57
|
+
results.size == 1 ? results.first : results
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def call_proc(proc, value)
|
63
|
+
return if proc.nil?
|
64
|
+
|
65
|
+
if proc.arity == 1
|
66
|
+
proc.call(value)
|
67
|
+
else
|
68
|
+
proc.call
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def validate_cases(cases)
|
73
|
+
all_values = cases.keys.flatten - [:else]
|
74
|
+
else_defined = cases.key?(:else)
|
75
|
+
superfluous_values = all_values - values
|
76
|
+
missing_values = values - all_values
|
77
|
+
|
78
|
+
raise ValuesNotDefinedError, "Value(s) not defined: #{superfluous_values.join(', ')}" if superfluous_values.any?
|
79
|
+
raise NotAllCasesHandledError, "Not all cases handled: #{missing_values.join(', ')}" if missing_values.any? && !else_defined
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
module Ruby
|
5
|
+
module Enum
|
6
|
+
##
|
7
|
+
# Mock I18n module in case the i18n gem is not available.
|
8
|
+
module I18nMock
|
9
|
+
def self.load_path
|
10
|
+
[]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.translate(key, _options = {})
|
14
|
+
key
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
# :nocov:
|
data/lib/ruby-enum/enum.rb
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
module Ruby
|
4
4
|
module Enum
|
5
|
+
class << self
|
6
|
+
# Needed for I18n mock
|
7
|
+
attr_accessor :i18n
|
8
|
+
end
|
9
|
+
|
5
10
|
attr_reader :key, :value
|
6
11
|
|
7
12
|
def initialize(key, value)
|
@@ -144,9 +149,7 @@ module Ruby
|
|
144
149
|
end
|
145
150
|
|
146
151
|
def to_h
|
147
|
-
|
148
|
-
[key, enum.value]
|
149
|
-
end]
|
152
|
+
@_enum_hash.transform_values(&:value)
|
150
153
|
end
|
151
154
|
|
152
155
|
private
|
@@ -22,13 +22,13 @@ module Ruby
|
|
22
22
|
@summary = create_summary(key, attributes)
|
23
23
|
@resolution = create_resolution(key, attributes)
|
24
24
|
|
25
|
-
"\nProblem:\n #{@problem}"\
|
25
|
+
"\nProblem:\n #{@problem}" \
|
26
26
|
"\nSummary:\n #{@summary}" + "\nResolution:\n #{@resolution}"
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
-
BASE_KEY = 'ruby.enum.errors.messages'
|
31
|
+
BASE_KEY = 'ruby.enum.errors.messages' # :nodoc:
|
32
32
|
|
33
33
|
# Given the key of the specific error and the options hash, translate the
|
34
34
|
# message.
|
@@ -39,7 +39,7 @@ module Ruby
|
|
39
39
|
#
|
40
40
|
# Returns a localized error message string.
|
41
41
|
def translate(key, options)
|
42
|
-
::
|
42
|
+
Ruby::Enum.i18n.translate("#{BASE_KEY}.#{key}", locale: :en, **options).strip
|
43
43
|
end
|
44
44
|
|
45
45
|
# Create the problem.
|
data/lib/ruby-enum/version.rb
CHANGED
data/lib/ruby-enum.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'i18n'
|
4
|
-
|
5
3
|
require 'ruby-enum/version'
|
6
4
|
require 'ruby-enum/enum'
|
5
|
+
require 'ruby-enum/enum/case'
|
6
|
+
require 'ruby-enum/enum/i18n_mock'
|
7
|
+
|
8
|
+
# Try to load the I18n gem and provide a mock if it is not available.
|
9
|
+
begin
|
10
|
+
require 'i18n'
|
11
|
+
Ruby::Enum.i18n = I18n
|
12
|
+
rescue LoadError
|
13
|
+
# I18n is not available
|
14
|
+
# :nocov:
|
15
|
+
# Tests for this loading are in the spec_i18n folder
|
16
|
+
Ruby::Enum.i18n = Ruby::Enum::I18nMock
|
17
|
+
# :nocov:
|
18
|
+
end
|
7
19
|
|
8
|
-
|
20
|
+
Ruby::Enum.i18n.load_path << File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')
|
9
21
|
|
10
22
|
require 'ruby-enum/errors/base'
|
11
23
|
require 'ruby-enum/errors/uninitialized_constant_error'
|
data/ruby-enum.gemspec
CHANGED
@@ -10,10 +10,11 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.email = 'dblock@dblock.org'
|
11
11
|
s.platform = Gem::Platform::RUBY
|
12
12
|
s.required_rubygems_version = '>= 1.3.6'
|
13
|
+
s.required_ruby_version = '>= 2.7'
|
13
14
|
s.files = Dir['**/*']
|
14
15
|
s.require_paths = ['lib']
|
15
16
|
s.homepage = 'http://github.com/dblock/ruby-enum'
|
16
17
|
s.licenses = ['MIT']
|
17
18
|
s.summary = 'Enum-like behavior for Ruby.'
|
18
|
-
s.
|
19
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
19
20
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Ruby::Enum::Case do
|
6
|
+
test_enum =
|
7
|
+
Class.new do
|
8
|
+
include Ruby::Enum
|
9
|
+
include Ruby::Enum::Case
|
10
|
+
|
11
|
+
define :RED, :red
|
12
|
+
define :GREEN, :green
|
13
|
+
define :BLUE, :blue
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.case' do
|
17
|
+
context 'when all cases are defined' do
|
18
|
+
subject { test_enum.case(test_enum::RED, cases) }
|
19
|
+
|
20
|
+
let(:cases) do
|
21
|
+
{
|
22
|
+
[test_enum::RED, test_enum::GREEN] => -> { 'red or green' },
|
23
|
+
test_enum::BLUE => -> { 'blue' }
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
it { is_expected.to eq('red or green') }
|
28
|
+
|
29
|
+
context 'when the value is nil' do
|
30
|
+
subject { test_enum.case(nil, cases) }
|
31
|
+
|
32
|
+
it { is_expected.to be_nil }
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when the value is empty' do
|
36
|
+
subject { test_enum.case('', cases) }
|
37
|
+
|
38
|
+
it { is_expected.to be_nil }
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when the value is the value of the enum' do
|
42
|
+
subject { test_enum.case(:red, cases) }
|
43
|
+
|
44
|
+
it { is_expected.to eq('red or green') }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the value is used inside the lambda' do
|
48
|
+
subject { test_enum.case(test_enum::RED, cases) }
|
49
|
+
|
50
|
+
let(:cases) do
|
51
|
+
{
|
52
|
+
[test_enum::RED, test_enum::GREEN] => ->(color) { "is #{color}" },
|
53
|
+
test_enum::BLUE => -> { 'blue' }
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
it { is_expected.to eq('is red') }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when there are mutliple matches' do
|
62
|
+
subject do
|
63
|
+
test_enum.case(
|
64
|
+
test_enum::RED,
|
65
|
+
{
|
66
|
+
[test_enum::RED, test_enum::GREEN] => -> { 'red or green' },
|
67
|
+
test_enum::RED => -> { 'red' },
|
68
|
+
test_enum::BLUE => -> { 'blue' }
|
69
|
+
}
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
it { is_expected.to eq(['red or green', 'red']) }
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when not all cases are defined' do
|
77
|
+
it 'raises an error' do
|
78
|
+
expect do
|
79
|
+
test_enum.case(
|
80
|
+
test_enum::RED,
|
81
|
+
{ [test_enum::RED, test_enum::GREEN] => -> { 'red or green' } }
|
82
|
+
)
|
83
|
+
end.to raise_error(Ruby::Enum::Case::ClassMethods::NotAllCasesHandledError)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when not all cases are defined but :else is specified (default case)' do
|
88
|
+
it 'does not raise an error' do
|
89
|
+
expect do
|
90
|
+
result = test_enum.case(
|
91
|
+
test_enum::BLUE,
|
92
|
+
{
|
93
|
+
[test_enum::RED, test_enum::GREEN] => -> { 'red or green' },
|
94
|
+
else: -> { 'blue' }
|
95
|
+
}
|
96
|
+
)
|
97
|
+
|
98
|
+
expect(result).to eq('blue')
|
99
|
+
end.not_to raise_error
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when a superfluous case is defined' do
|
104
|
+
it 'raises an error' do
|
105
|
+
expect do
|
106
|
+
test_enum.case(
|
107
|
+
test_enum::RED,
|
108
|
+
{
|
109
|
+
[test_enum::RED, test_enum::GREEN] => -> { 'red or green' },
|
110
|
+
test_enum::BLUE => -> { 'blue' },
|
111
|
+
:something => -> { 'green' }
|
112
|
+
}
|
113
|
+
)
|
114
|
+
end.to raise_error(Ruby::Enum::Case::ClassMethods::ValuesNotDefinedError)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/spec/ruby-enum/enum_spec.rb
CHANGED
@@ -22,10 +22,28 @@ describe Ruby::Enum do
|
|
22
22
|
expect(Colors::RED).to eq 'red'
|
23
23
|
expect(Colors::GREEN).to eq 'green'
|
24
24
|
end
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
context 'when the i18n gem is loaded' do
|
27
|
+
it 'raises UninitializedConstantError on an invalid constant' do
|
28
|
+
expect do
|
29
|
+
Colors::ANYTHING
|
30
|
+
end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /The constant Colors::ANYTHING has not been defined./
|
31
|
+
end
|
27
32
|
end
|
28
|
-
|
33
|
+
|
34
|
+
context 'when the i18n gem is not loaded' do
|
35
|
+
before do
|
36
|
+
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises UninitializedConstantError on an invalid constant' do
|
40
|
+
expect do
|
41
|
+
Colors::ANYTHING
|
42
|
+
end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /ruby.enum.errors.messages.uninitialized_constant.summary/
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#each' do
|
29
47
|
it 'iterates over constants' do
|
30
48
|
keys = []
|
31
49
|
enum_keys = []
|
@@ -40,7 +58,8 @@ describe Ruby::Enum do
|
|
40
58
|
expect(enum_values).to eq %w[red green]
|
41
59
|
end
|
42
60
|
end
|
43
|
-
|
61
|
+
|
62
|
+
describe '#map' do
|
44
63
|
it 'maps constants' do
|
45
64
|
key_key_values = Colors.map do |key, enum|
|
46
65
|
[key, enum.key, enum.value]
|
@@ -50,103 +69,152 @@ describe Ruby::Enum do
|
|
50
69
|
expect(key_key_values[1]).to eq [:GREEN, :GREEN, 'green']
|
51
70
|
end
|
52
71
|
end
|
53
|
-
|
72
|
+
|
73
|
+
describe '#parse' do
|
54
74
|
it 'parses exact value' do
|
55
75
|
expect(Colors.parse('red')).to eq(Colors::RED)
|
56
76
|
end
|
77
|
+
|
57
78
|
it 'is case-insensitive' do
|
58
79
|
expect(Colors.parse('ReD')).to eq(Colors::RED)
|
59
80
|
end
|
81
|
+
|
60
82
|
it 'returns nil for a null value' do
|
61
83
|
expect(Colors.parse(nil)).to be_nil
|
62
84
|
end
|
85
|
+
|
63
86
|
it 'returns nil for an invalid value' do
|
64
87
|
expect(Colors.parse('invalid')).to be_nil
|
65
88
|
end
|
66
89
|
end
|
67
|
-
|
90
|
+
|
91
|
+
describe '#key?' do
|
68
92
|
it 'returns true for valid keys accessed directly' do
|
69
93
|
Colors.keys.each do |key| # rubocop:disable Style/HashEachMethods
|
70
|
-
expect(Colors.key?(key)).to
|
94
|
+
expect(Colors.key?(key)).to be(true)
|
71
95
|
end
|
72
96
|
end
|
97
|
+
|
73
98
|
it 'returns true for valid keys accessed via each_keys' do
|
74
99
|
Colors.each_key do |key|
|
75
|
-
expect(Colors.key?(key)).to
|
100
|
+
expect(Colors.key?(key)).to be(true)
|
76
101
|
end
|
77
102
|
end
|
103
|
+
|
78
104
|
it 'returns false for invalid keys' do
|
79
|
-
expect(Colors.key?(:NOT_A_KEY)).to
|
105
|
+
expect(Colors.key?(:NOT_A_KEY)).to be(false)
|
80
106
|
end
|
81
107
|
end
|
82
|
-
|
108
|
+
|
109
|
+
describe '#value' do
|
83
110
|
it 'returns string values for keys' do
|
84
111
|
Colors.each do |key, enum|
|
85
112
|
expect(Colors.value(key)).to eq(enum.value)
|
86
113
|
end
|
87
114
|
end
|
115
|
+
|
88
116
|
it 'returns nil for an invalid key' do
|
89
117
|
expect(Colors.value(:NOT_A_KEY)).to be_nil
|
90
118
|
end
|
91
119
|
end
|
92
|
-
|
120
|
+
|
121
|
+
describe '#value?' do
|
93
122
|
it 'returns true for valid values accessed directly' do
|
94
123
|
Colors.values.each do |value| # rubocop:disable Style/HashEachMethods
|
95
|
-
expect(Colors.value?(value)).to
|
124
|
+
expect(Colors.value?(value)).to be(true)
|
96
125
|
end
|
97
126
|
end
|
127
|
+
|
98
128
|
it 'returns true for valid values accessed via each_value' do
|
99
129
|
Colors.each_value do |value|
|
100
|
-
expect(Colors.value?(value)).to
|
130
|
+
expect(Colors.value?(value)).to be(true)
|
101
131
|
end
|
102
132
|
end
|
133
|
+
|
103
134
|
it 'returns false for invalid values' do
|
104
|
-
expect(Colors.value?('I am not a value')).to
|
135
|
+
expect(Colors.value?('I am not a value')).to be(false)
|
105
136
|
end
|
106
137
|
end
|
107
|
-
|
138
|
+
|
139
|
+
describe '#key' do
|
108
140
|
it 'returns enum instances for values' do
|
109
|
-
Colors.each do |_, enum|
|
141
|
+
Colors.each do |_, enum| # rubocop:disable Style/HashEachMethods
|
110
142
|
expect(Colors.key(enum.value)).to eq(enum.key)
|
111
143
|
end
|
112
144
|
end
|
145
|
+
|
113
146
|
it 'returns nil for an invalid value' do
|
114
147
|
expect(Colors.key('invalid')).to be_nil
|
115
148
|
end
|
116
149
|
end
|
117
|
-
|
150
|
+
|
151
|
+
describe '#keys' do
|
118
152
|
it 'returns keys' do
|
119
153
|
expect(Colors.keys).to eq(%i[RED GREEN])
|
120
154
|
end
|
121
155
|
end
|
122
|
-
|
156
|
+
|
157
|
+
describe '#values' do
|
123
158
|
it 'returns values' do
|
124
159
|
expect(Colors.values).to eq(%w[red green])
|
125
160
|
end
|
126
161
|
end
|
127
|
-
|
162
|
+
|
163
|
+
describe '#to_h' do
|
128
164
|
it 'returns a hash of key:values' do
|
129
165
|
expect(Colors.to_h).to eq(RED: 'red', GREEN: 'green')
|
130
166
|
end
|
131
167
|
end
|
132
168
|
|
133
|
-
context '
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
169
|
+
context 'when a duplicate key is used' do
|
170
|
+
context 'when the i18n gem is loaded' do
|
171
|
+
it 'raises DuplicateKeyError' do
|
172
|
+
expect do
|
173
|
+
Colors.class_eval do
|
174
|
+
define :RED, 'some'
|
175
|
+
end
|
176
|
+
end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /The constant Colors::RED has already been defined./
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'when the i18n gem is not loaded' do
|
181
|
+
before do
|
182
|
+
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'raises DuplicateKeyError' do
|
186
|
+
expect do
|
187
|
+
Colors.class_eval do
|
188
|
+
define :RED, 'some'
|
189
|
+
end
|
190
|
+
end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /ruby.enum.errors.messages.duplicate_key.message/
|
191
|
+
end
|
140
192
|
end
|
141
193
|
end
|
142
194
|
|
143
|
-
context '
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
195
|
+
context 'when a duplicate value is used' do
|
196
|
+
context 'when the i18n gem is loaded' do
|
197
|
+
it 'raises a DuplicateValueError' do
|
198
|
+
expect do
|
199
|
+
Colors.class_eval do
|
200
|
+
define :Other, 'red'
|
201
|
+
end
|
202
|
+
end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /The value red has already been defined./
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'when the i18n gem is not loaded' do
|
207
|
+
before do
|
208
|
+
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'raises a DuplicateValueError' do
|
212
|
+
expect do
|
213
|
+
Colors.class_eval do
|
214
|
+
define :Other, 'red'
|
215
|
+
end
|
216
|
+
end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /ruby.enum.errors.messages.duplicate_value.summary/
|
217
|
+
end
|
150
218
|
end
|
151
219
|
end
|
152
220
|
|
@@ -176,11 +244,14 @@ describe Ruby::Enum do
|
|
176
244
|
it 'contains its own enums' do
|
177
245
|
expect(FirstSubclass::ORANGE).to eq 'orange'
|
178
246
|
end
|
247
|
+
|
179
248
|
it 'parent class should not have enums defined in child classes' do
|
180
249
|
expect { Colors::ORANGE }.to raise_error Ruby::Enum::Errors::UninitializedConstantError
|
181
250
|
end
|
182
|
-
|
251
|
+
|
252
|
+
context 'when defining a 2 level depth subclass' do
|
183
253
|
subject { SecondSubclass }
|
254
|
+
|
184
255
|
it 'contains its own enums and all the enums defined in the parent classes' do
|
185
256
|
expect(subject::RED).to eq 'red'
|
186
257
|
expect(subject::GREEN).to eq 'green'
|
@@ -227,6 +298,7 @@ describe Ruby::Enum do
|
|
227
298
|
define :undefined
|
228
299
|
end
|
229
300
|
subject { States }
|
301
|
+
|
230
302
|
it 'behaves like an enum' do
|
231
303
|
expect(subject.created).to eq 'Created'
|
232
304
|
expect(subject.published).to eq 'Published'
|
data/spec_i18n/Gemfile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
ruby-enum (1.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.5.0)
|
10
|
+
rake (13.1.0)
|
11
|
+
rspec (3.12.0)
|
12
|
+
rspec-core (~> 3.12.0)
|
13
|
+
rspec-expectations (~> 3.12.0)
|
14
|
+
rspec-mocks (~> 3.12.0)
|
15
|
+
rspec-core (3.12.2)
|
16
|
+
rspec-support (~> 3.12.0)
|
17
|
+
rspec-expectations (3.12.3)
|
18
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
+
rspec-support (~> 3.12.0)
|
20
|
+
rspec-mocks (3.12.6)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.12.0)
|
23
|
+
rspec-support (3.12.1)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
arm64-darwin-22
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
rake
|
31
|
+
rspec (~> 3.0)
|
32
|
+
ruby-enum!
|
33
|
+
|
34
|
+
BUNDLED WITH
|
35
|
+
2.5.1
|
data/spec_i18n/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
test_class = Class.new do
|
6
|
+
include Ruby::Enum
|
7
|
+
|
8
|
+
define :RED, 'red'
|
9
|
+
define :GREEN, 'green'
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Ruby::Enum do
|
13
|
+
context 'when the i18n gem is not loaded' do
|
14
|
+
it 'raises UninitializedConstantError on an invalid constant' do
|
15
|
+
expect do
|
16
|
+
test_class::ANYTHING
|
17
|
+
end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /ruby.enum.errors.messages.uninitialized_constant.summary/
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when a duplicate key is used' do
|
21
|
+
before do
|
22
|
+
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'raises DuplicateKeyError' do
|
26
|
+
expect do
|
27
|
+
test_class.class_eval do
|
28
|
+
define :RED, 'some'
|
29
|
+
end
|
30
|
+
end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /ruby.enum.errors.messages.duplicate_key.message/
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when a duplicate value is used' do
|
35
|
+
before do
|
36
|
+
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises a DuplicateValueError' do
|
40
|
+
expect do
|
41
|
+
test_class.class_eval do
|
42
|
+
define :Other, 'red'
|
43
|
+
end
|
44
|
+
end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /ruby.enum.errors.messages.duplicate_value.summary/
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|