Garantindo a consistência das traduções no Rails


Leia em 1 minuto

Sempre que você trabalha com aplicativos internacionalizados, é muito comum esquecer de traduzir uma ou outra chave de sua aplicação. Embora em produção seja possível fazer o fallback para o idioma padrão, nem sempre isso é uma alternativa interessante.

Para garantir que seu aplicativo foi internacionalizado corretamente, é possível fazer algumas coisas.

Primeiro, você pode configurar o ambiente de testes para lançar uma exceção sempre que uma tradução não for encontrada. Para fazer isso, defina o handler de exceções do I18n. No meu caso, estou configurando o RSpec para sempre definir este handler antes de grupo de testes ser executado. No arquivo spec/support/i18n.rb, adicione o código abaixo:

RSpec.configure do |config|
  config.before(:all) do
    I18n.exception_handler = proc do |scope, *args|
      message = scope.to_s
      raise message unless message.include?(".i18n.plural.rule")
    end

    I18n.locale = ENV.fetch("LOCALE", I18n.default_locale)
  end

  config.after(:all) do
    I18n.exception_handler = I18n::ExceptionHandler.new
    I18n.locale = I18n.default_locale
  end
end

Se você está usando algum idioma cuja pluralização seja parecida com a do inglês, uma exceção será lançada dizendo que a chave en.i18n.plural.rule não existe. Você pode ignorá-la sem medo.

Nós também estamos definindo o idioma corrente dos testes. Uma das maneira que você pode definir este idioma é executando o comando LOCALE=pt-BR rspec, por exemplo. Embora funcione, você provavelmente não irá se lembrar de fazer isso constantemente. Então, vamos criar uma rake task quer irá executar a suíte para cada um dos idiomas disponíveis.

Crie o arquivo tasks/rspec.rake com o conteúdo abaixo:

desc "Run localized specs"
task "spec:i18n" => :environment do
  I18n.available_locales.each do |locale|
    ENV["LOCALE"] = locale.to_s
    Rake::Task["spec"].reenable
    Rake::Task["spec"].invoke
  end
end

Agora, para executar os testes de forma localizada, basta executar o comando rake spec:i18n. Você não precisa fazer isso toda hora. Só executo esta tarefa antes de fazer o commit. E se você usa algum sistema de integração contínua, pode executar esta tarefa apenas lá!

Vale lembrar que para que isso funcione, você deve sempre sempre utilizar o método I18n.t em seus testes. Para economizar algumas teclas na digitação, você pode criar um helper que faz isso para você. No arquivo spec/support/helpers.rb, eu adicionei um método _ que faz justamente isso.

RSpec.configure do |config|
  config.include Module.new {
    def _(*args, &block)
      I18n.t(*args, &block)
    end
  }
end

Perceba que decidi por utilizar o método _, muito usado para fazer internacionalização com Gettext, em vez do método t definindo pelo Rails em controllers, views e helpers. Isso é apenas para garantir que não irei sobrescrever este método, caso ele já exista.