-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This adds translations for filter types, interaction names, attribute names, and validation errors. All of them are scoped to :active_interaction.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,5 +20,7 @@ | |
require 'active_interaction/filters/time_filter' | ||
require 'active_interaction/base' | ||
|
||
I18n.backend.load_translations(Dir['lib/active_interaction/locale/*.yml']) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
AaronLasseigne
Author
Owner
|
||
|
||
# @since 0.1.0 | ||
module ActiveInteraction end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,10 @@ def persisted? | |
false | ||
end | ||
|
||
def self.i18n_scope | ||
:active_interaction | ||
end | ||
|
||
extend OverloadHash | ||
|
||
# Returns the output from {#execute} if there are no validation errors or | ||
|
@@ -191,12 +195,13 @@ def self.set_up_validator(attribute, type, filter, options, &block) | |
begin | ||
filter.prepare(attribute, send(attribute), options, &block) | ||
rescue InvalidNestedValue | ||
errors.add(attribute, 'is invalid') | ||
errors.add(attribute, :invalid_nested) | ||
rescue InvalidValue | ||
errors.add(attribute, | ||
"is not a valid #{type.to_s.humanize.downcase}") | ||
errors.add(attribute, :invalid, | ||
type: I18n.translate(:"#{self.class.i18n_scope}.types.#{type.to_s}") | ||
This comment has been minimized.
Sorry, something went wrong.
tfausak
Collaborator
|
||
) | ||
rescue MissingValue | ||
errors.add(attribute, 'is required') | ||
errors.add(attribute, :missing) | ||
end | ||
end | ||
private validator | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
en: | ||
active_interaction: | ||
types: | ||
array: 'array' | ||
boolean: 'boolean' | ||
date: 'date' | ||
date_time: 'date_time' | ||
This comment has been minimized.
Sorry, something went wrong.
tfausak
Collaborator
|
||
file: 'file' | ||
float: 'float' | ||
hash: 'hash' | ||
integer: 'integer' | ||
model: 'model' | ||
string: 'string' | ||
time: 'time' | ||
errors: | ||
messages: | ||
invalid_nested: 'is invalid' | ||
invalid: 'is not a valid %{type}' | ||
missing: 'is required' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
require 'spec_helper' | ||
|
||
describe 'I18n' do | ||
class I18nTest < ActiveInteraction::Base | ||
hash :thing do | ||
integer :i | ||
end | ||
|
||
def execute; end | ||
end | ||
|
||
context 'types' do | ||
before do | ||
I18n.locale = :en | ||
end | ||
|
||
[ | ||
:array, | ||
:boolean, | ||
:date, | ||
:date_time, | ||
:file, | ||
:float, | ||
:hash, | ||
:integer, | ||
:model, | ||
:string, | ||
:time | ||
].each do |type| | ||
This comment has been minimized.
Sorry, something went wrong.
tfausak
Collaborator
|
||
it "has a value for #{type} in English" do | ||
expect(I18n.translate(:"active_interaction.types.#{type}")).to eq type.to_s | ||
end | ||
end | ||
end | ||
|
||
context 'model name' do | ||
let(:model_name) { 'Internationalization Test' } | ||
|
||
before do | ||
I18n.locale = :en | ||
|
||
I18n.backend.store_translations :en, active_interaction: { | ||
models: { | ||
i18n_test: { | ||
one: model_name, | ||
other: model_name + 's' | ||
}}} | ||
end | ||
|
||
it 'returns the translated version of the singular model name' do | ||
expect(I18nTest.model_name.human).to eq model_name | ||
end | ||
|
||
it 'returns the translated version of the plural model name' do | ||
expect(I18nTest.model_name.human(count: 2)).to eq model_name + 's' | ||
end | ||
end | ||
|
||
context 'attributes' do | ||
let(:attr_name) { 'Thing' } | ||
|
||
context 'default' do | ||
it 'returns a humanized version of the attribute name' do | ||
expect(I18nTest.human_attribute_name(:thing)).to eq attr_name | ||
end | ||
end | ||
|
||
context 'translated' do | ||
let(:attr_name) { 'Thing'.downcase.reverse.capitalize } | ||
|
||
before do | ||
I18n.locale = :reverse | ||
|
||
I18n.backend.store_translations :reverse, active_interaction: { | ||
attributes: { | ||
i18n_test: { | ||
thing: attr_name | ||
}}} | ||
end | ||
|
||
it 'returns a translated version of the attribute name' do | ||
expect( | ||
I18nTest.human_attribute_name(:thing) | ||
).to eq attr_name | ||
end | ||
end | ||
end | ||
|
||
context 'validations' do | ||
context 'default' do | ||
before do | ||
I18n.locale = :en | ||
end | ||
|
||
context ':invalid_nested' do | ||
it 'returns "is invalid" in English' do | ||
expect( | ||
I18nTest.run(thing: {i: Object.new}).errors[:thing] | ||
).to eq ['is invalid'] | ||
end | ||
end | ||
|
||
context ':invalid' do | ||
it 'returns "is not a valid hash" in English' do | ||
expect( | ||
I18nTest.run(thing: Object.new).errors[:thing] | ||
).to eq ['is not a valid hash'] | ||
end | ||
end | ||
|
||
context ':missing' do | ||
it 'returns "is required" in English' do | ||
expect( | ||
I18nTest.run().errors[:thing] | ||
).to eq ['is required'] | ||
end | ||
end | ||
end | ||
|
||
context 'translated' do | ||
before do | ||
I18n.locale = :reverse | ||
|
||
I18n.backend.store_translations :reverse, active_interaction: { | ||
types: { | ||
hash: 'hash'.reverse | ||
}, | ||
errors: { | ||
messages: { | ||
invalid_nested: 'is invalid'.reverse, | ||
invalid: "%{type} #{'is not a valid'.reverse}", | ||
missing: 'is required'.reverse | ||
}}} | ||
end | ||
|
||
context ':invalid_nested' do | ||
it 'returns "is invalid" translated' do | ||
expect( | ||
I18nTest.run(thing: {i: Object.new}).errors[:thing] | ||
).to eq ['is invalid'.reverse] | ||
end | ||
end | ||
|
||
context ':invalid' do | ||
it 'returns "is not a valid hash" translated' do | ||
expect( | ||
I18nTest.run(thing: Object.new).errors[:thing] | ||
).to eq ['is not a valid hash'.reverse] | ||
end | ||
end | ||
|
||
context ':missing' do | ||
it 'returns "is required" translated' do | ||
expect( | ||
I18nTest.run().errors[:thing] | ||
).to eq ['is required'.reverse] | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,16 @@ def execute | |
defaults_2: defaults_2 | ||
} | ||
end | ||
|
||
# This causes the tests to fail with: | ||
# Class name cannot be blank. You need to supply a name argument when | ||
# anonymous class given | ||
# | ||
# In particular adding an error in the MissingValue rescue inside | ||
# self.set_up_validator triggers the exception. | ||
def self.model_name | ||
ActiveModel::Name.new(self, nil, 'Temp') | ||
end | ||
This comment has been minimized.
Sorry, something went wrong.
tfausak
Collaborator
|
||
end | ||
end | ||
|
||
|
This is almost certainly overkill, but do we want to use
File.join
? And I usually preferDir.glob
overDir.[]
for explicitness.