Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,10 @@ jobs:
- run: bundle install --jobs=3 --retry=3 --path=vendor/bundle
- run: bundle exec rake spec
continue-on-error: ${{ matrix.entry.allowed-failure }}
- name: Specs for when the i18n gem is not available
run: |
cd spec_i18n
bundle install --jobs=3 --retry=3
pwd
bundle exec rake spec
continue-on-error: ${{ matrix.entry.allowed-failure }}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### 1.0.0 (Next)

* [#41](https://github.com/dblock/ruby-enum/pull/41): Make i18n dependency optional - [@peterfication](https://github.com/peterfication).
* [#43](https://github.com/dblock/ruby-enum/pull/43): Add exhaustive case matcher - [@peterfication](https://github.com/peterfication).
* [#40](https://github.com/dblock/ruby-enum/pull/39): Enable new Rubocop cops and address/allowlist lints - [@petergoldstein](https://github.com/petergoldstein).
* [#39](https://github.com/dblock/ruby-enum/pull/39): Require Ruby >= 2.7 - [@petergoldstein](https://github.com/petergoldstein).
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Enum-like behavior for Ruby, heavily inspired by [this](http://www.rubyfleebie.c
- [Duplicate enumerator keys or duplicate values](#duplicate-enumerator-keys-or-duplicate-values)
- [Inheritance](#inheritance)
- [Exhaustive case matcher](#exhaustive-case-matcher)
- [I18n support](#i18n-support)
- [Benchmarks](#benchmarks)
- [Contributing](#contributing)
- [Copyright and License](#copyright-and-license)
Expand Down Expand Up @@ -300,6 +301,15 @@ Color.Case(color, {
})
```

### I18n support

This gem has an optional dependency to `i18n`. If it's available, the error messages will have a nice description and can be translated. If it's not available, the errors will only contain the message keys.

```ruby
# Add this to your Gemfile if you want to have a nice error description instead of just a message key.
gem "i18n"
```

## Benchmarks

Benchmark scripts are defined in the [`benchmarks`](benchmarks) folder and can be run with Rake:
Expand Down
17 changes: 14 additions & 3 deletions lib/ruby-enum.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
# frozen_string_literal: true

require 'i18n'

require 'ruby-enum/version'
require 'ruby-enum/enum'
require 'ruby-enum/enum/case'
require 'ruby-enum/enum/i18n_mock'

# Try to load the I18n gem and provide a mock if it is not available.
begin
require 'i18n'
Ruby::Enum.i18n = I18n
rescue LoadError
# I18n is not available
# :nocov:
# Tests for this loading are in the spec_i18n folder
Ruby::Enum.i18n = Ruby::Enum::I18nMock
# :nocov:
end

I18n.load_path << File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')
Ruby::Enum.i18n.load_path << File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')

require 'ruby-enum/errors/base'
require 'ruby-enum/errors/uninitialized_constant_error'
Expand Down
5 changes: 5 additions & 0 deletions lib/ruby-enum/enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

module Ruby
module Enum
class << self
# Needed for I18n mock
attr_accessor :i18n
end

attr_reader :key, :value

def initialize(key, value)
Expand Down
19 changes: 19 additions & 0 deletions lib/ruby-enum/enum/i18n_mock.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

# :nocov:
module Ruby
module Enum
##
# Mock I18n module in case the i18n gem is not available.
module I18nMock
def self.load_path
[]
end

def self.translate(key, _options = {})
key
end
end
end
end
# :nocov:
2 changes: 1 addition & 1 deletion lib/ruby-enum/errors/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def compose_message(key, attributes = {})
#
# Returns a localized error message string.
def translate(key, options)
::I18n.translate("#{BASE_KEY}.#{key}", locale: :en, **options).strip
Ruby::Enum.i18n.translate("#{BASE_KEY}.#{key}", locale: :en, **options).strip
end

# Create the problem.
Expand Down
1 change: 0 additions & 1 deletion ruby-enum.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ Gem::Specification.new do |s|
s.homepage = 'http://github.com/dblock/ruby-enum'
s.licenses = ['MIT']
s.summary = 'Enum-like behavior for Ruby.'
s.add_dependency 'i18n'
s.metadata['rubygems_mfa_required'] = 'true'
end
76 changes: 62 additions & 14 deletions spec/ruby-enum/enum_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,24 @@ class SecondSubclass < FirstSubclass
expect(Colors::GREEN).to eq 'green'
end

it 'raises UninitializedConstantError on an invalid constant' do
expect { Colors::ANYTHING }.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /The constant Colors::ANYTHING has not been defined./
context 'when the i18n gem is loaded' do
it 'raises UninitializedConstantError on an invalid constant' do
expect do
Colors::ANYTHING
end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /The constant Colors::ANYTHING has not been defined./
end
end

context 'when the i18n gem is not loaded' do
before do
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
end

it 'raises UninitializedConstantError on an invalid constant' do
expect do
Colors::ANYTHING
end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /ruby.enum.errors.messages.uninitialized_constant.summary/
end
end

describe '#each' do
Expand Down Expand Up @@ -151,22 +167,54 @@ class SecondSubclass < FirstSubclass
end

context 'when a duplicate key is used' do
it 'raises DuplicateKeyError' do
expect do
Colors.class_eval do
define :RED, 'some'
end
end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /The constant Colors::RED has already been defined./
context 'when the i18n gem is loaded' do
it 'raises DuplicateKeyError' do
expect do
Colors.class_eval do
define :RED, 'some'
end
end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /The constant Colors::RED has already been defined./
end
end

context 'when the i18n gem is not loaded' do
before do
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
end

it 'raises DuplicateKeyError' do
expect do
Colors.class_eval do
define :RED, 'some'
end
end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /ruby.enum.errors.messages.duplicate_key.message/
end
end
end

context 'when a duplicate value is used' do
it 'raises a DuplicateValueError' do
expect do
Colors.class_eval do
define :Other, 'red'
end
end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /The value red has already been defined./
context 'when the i18n gem is loaded' do
it 'raises a DuplicateValueError' do
expect do
Colors.class_eval do
define :Other, 'red'
end
end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /The value red has already been defined./
end
end

context 'when the i18n gem is not loaded' do
before do
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
end

it 'raises a DuplicateValueError' do
expect do
Colors.class_eval do
define :Other, 'red'
end
end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /ruby.enum.errors.messages.duplicate_value.summary/
end
end
end

Expand Down
9 changes: 9 additions & 0 deletions spec_i18n/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

source 'http://rubygems.org'

gemspec path: '../', name: 'ruby-enum'

# This Gemfile should not include any gem that has i18n as a dependency.
gem 'rake'
gem 'rspec', '~> 3.0'
12 changes: 12 additions & 0 deletions spec_i18n/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require 'rubygems'

require 'rspec/core'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec) do |spec|
spec.pattern = FileList['spec/**/*_spec.rb']
end

task default: %i[spec]
48 changes: 48 additions & 0 deletions spec_i18n/spec/i18n_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

require 'spec_helper'

test_class = Class.new do
include Ruby::Enum

define :RED, 'red'
define :GREEN, 'green'
end

describe Ruby::Enum do
context 'when the i18n gem is not loaded' do
it 'raises UninitializedConstantError on an invalid constant' do
expect do
test_class::ANYTHING
end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /ruby.enum.errors.messages.uninitialized_constant.summary/
end

context 'when a duplicate key is used' do
before do
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
end

it 'raises DuplicateKeyError' do
expect do
test_class.class_eval do
define :RED, 'some'
end
end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /ruby.enum.errors.messages.duplicate_key.message/
end
end

context 'when a duplicate value is used' do
before do
allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
end

it 'raises a DuplicateValueError' do
expect do
test_class.class_eval do
define :Other, 'red'
end
end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /ruby.enum.errors.messages.duplicate_value.summary/
end
end
end
end
8 changes: 8 additions & 0 deletions spec_i18n/spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))

require 'rubygems'

require 'rspec'
require 'ruby-enum'