Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to log non-existing keys #132

Open
renchap opened this issue Apr 19, 2021 · 2 comments
Open

Add a way to log non-existing keys #132

renchap opened this issue Apr 19, 2021 · 2 comments

Comments

@renchap
Copy link
Contributor

renchap commented Apr 19, 2021

I would like to collect any missing keys in the base language PO file. I tried using the Logger repo but, as noted in the documentation:

Unfound may not always mean missing, if you choose not to translate a word because the key is a good translation, it will appear nevertheless.

Currently I only emit warnings in the logger's callback when the current language is not the default one so I skip empty keys, but as most of my tests are ran using the default language it does not allow me to generate a list of missing keys after running my test suite.

I can not find a way to differentiate between a missing key and an empty one? It does not really need to be optimised, for example I could collect all keys from the logger in an array and then at the end of my test suite check all of them against the PO file and report any missing ones.

Do you have an idea on how to best achieve this?

@grosser
Copy link
Owner

grosser commented Apr 19, 2021

don't have a good idea, plz update the issue if you have something that works :)

@renchap
Copy link
Contributor Author

renchap commented Apr 24, 2021

I have something that works, but this is quite ugly as it relies on parsing the PO file again to extract msgids:

class FastGettextUnhandledCollector
  include Singleton

  def unhandled_keys
    @unhandled_keys ||= Set.new
  end

  def reset_unhandled_keys
    @unhandled_keys = Set.new
  end

  def callback(key)
    case Rails.env
    when "test"
      unhandled_keys << key
    else
      Rails.logger.warn("Untranslated key: #{key_or_array_of_ids}") unless I18n.locale == I18n.default_locale
    end
  end

  def unhandled_keys_not_in_po
    unhandled_keys - keys_in_po
  end

  private

  def po_filename
    FastGettext.translation_repositories["app"].chain[0]
               .instance_variable_get(:@files)["en"].instance_variable_get(:@filename)
  end

  def keys_in_po
    @keys_in_po ||= extract_keys_from_po_file
  end

  def extract_keys_from_po_file
    keys = []

    File.open(po_filename, "r").each do |line|
      line.match(/^msgid "(.+)"$/) do |match|
        keys << match[1]
      end
    end

    keys
  end
end

# You initialise it like this:

repos = [
  FastGettext::TranslationRepository.build("app", path: "locale", type: :po),
  FastGettext::TranslationRepository.build(
    "logger",
    type: :logger,
    callback: ->(key_or_array_of_ids) { NotosFastGettextLogger.instance.callback(key_or_array_of_ids) },
  ),
]
FastGettext.add_text_domain "app", type: :chain, chain: repos

# And then in your test suite

setup { FastGettextUnhandledCollector.instance.reset_unhandled_keys }
teardown do
  keys = FastGettextUnhandledCollector.instance.unhandled_keys_not_in_po
  assert_equal 0, keys.size, "Some Gettext keys are not present in default language PO file: #{keys.to_a.join(' | ')}"
end

Test will then fail if code hit by a test triggers the a translation for a msgid not present in the PO file for your main language.

I tried to properly extract the msgids from the translation repository but it does not seem possible as empty msgstr do not seem loaded at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants