Skip to content

Instantly share code, notes, and snippets.

@alpaca-tc
Created May 23, 2021 12:55
Show Gist options
  • Save alpaca-tc/8b9424285346e4c080e345146971a883 to your computer and use it in GitHub Desktop.
Save alpaca-tc/8b9424285346e4c080e345146971a883 to your computer and use it in GitHub Desktop.
ActiveRecordのi18nの定義漏れをテストする
# frozen_string_literal: true
RSpec.describe 'ActiveRecord i18n' do
let(:table_names) { ActiveRecord::Base.connection.tables }
let(:models) do
table_names.map do |table_name|
table_to_model(table_name)
rescue NameError
nil
end.compact
end
let(:missing_locale) do
"Missing #{SecureRandom.uuid}"
end
def table_to_model(table_name)
table_name.singularize.classify.constantize
end
describe 'Model' do
it 'is localizable' do
missing_locales = []
models.each do |model|
localized = model.model_name.human(default: missing_locale)
missing_locales.push(model) if localized == missing_locale
end
expect(missing_locales).to be_empty, -> {
result = missing_locales.map { |model| "#{model.model_name.element}: " }
<<~EOS
Missing model name locales. Please add locales to config/locales/models/defaults/*.yml
#{result.join("\n")}
EOS
}
end
end
describe 'Columns' do
def extract_column_names(model)
# typeは翻訳しないことが多いので無視する
ignore_columns = ['type']
# 外部キーの_idは翻訳しないので無視する
foreign_keys = model.reflect_on_all_associations(:belongs_to).map(&:foreign_key)
# GeneratedColumnは隠蔽されていることが多いので無視する
generated_columns = model.columns.select(&:virtual?).map(&:name)
model.column_names - ignore_columns - foreign_keys - generated_columns
end
it 'is localizable' do
missing_locales = Hash.new { |h, k| h[k] = [] }
models.each do |model|
extract_column_names(model).each do |column_name|
localized = model.human_attribute_name(column_name, default: missing_locale)
missing_locales[model].push(column_name) if localized == missing_locale
end
end
expect(missing_locales).to be_empty, -> {
result = missing_locales.map do |model, attributes|
"#{model.name} [#{attributes.join(', ')}]"
end
<<~EOS
Missing locales. Please add locales to config/locales/models/**/*.yml
#{result.join("\n")}
EOS
}
end
end
describe 'Associations' do
it 'is localizable' do
missing_locales = Hash.new { |h, k| h[k] = [] }
models.each do |model|
reflections = model.reflections.select do |_, reflection|
reflection.options.key?(:dependent)
end
reflections.each_key do |association_name|
localized = model.human_attribute_name(association_name, default: missing_locale)
missing_locales[model].push(association_name) if localized == missing_locale
end
end
expect(missing_locales).to be_empty, -> {
result = missing_locales.map do |model, attributes|
<<~EOS
activerecord:
attributes:
#{model.model_name.singular}:
#{attributes.map { |name| " #{name}:" }.join("\n")}
EOS
end
<<~EOS
Missing association locales.
#{result.join("\n")}
EOS
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment