Files
bDS2/test/bds/translation_completeness_test.exs

87 lines
2.6 KiB
Elixir

defmodule BDS.TranslationCompletenessTest do
use ExUnit.Case, async: true
@translated_locales ~w(de fr it es)
@doc """
Counts empty msgstr entries per non-English locale .po file and ensures
the count never increases. When a new msgid is added to the codebase its
translations MUST be provided for all supported locales; an empty msgstr
in de/fr/it/es causes this test to fail.
English files are excluded — gettext treats empty msgstr as "return msgid
unchanged" for the source language, which is the intended fallback.
The expected counts below represent current untranslated legacy entries
that must decrease over time, never increase. When the count decreases
because translations were added, update the expected count in this test.
"""
test "empty msgstr counts do not increase in non-English locale .po files" do
expected = %{
"de/default.po" => 0,
"de/render.po" => 0,
"de/ui.po" => 153,
"fr/default.po" => 0,
"fr/render.po" => 0,
"fr/ui.po" => 153,
"it/default.po" => 0,
"it/render.po" => 0,
"it/ui.po" => 153,
"es/default.po" => 0,
"es/render.po" => 0,
"es/ui.po" => 153
}
actual =
for locale <- @translated_locales,
domain <- ~w(ui default render) do
file = "priv/gettext/#{locale}/LC_MESSAGES/#{domain}.po"
if File.exists?(file) do
count = empty_msgstr_count(file)
key = "#{locale}/#{domain}.po"
{key, count}
end
end
|> Enum.reject(&is_nil/1)
|> Map.new()
for {file, expected_count} <- expected do
actual_count = Map.get(actual, file, 0)
assert actual_count <= expected_count,
"#{file}: empty msgstr count increased from #{expected_count} to #{actual_count}. " <>
"All new msgid entries MUST have translations for every supported locale (de, fr, it, es). " <>
"When the count decreases because translations were added, update the expected count in this test."
end
end
defp empty_msgstr_count(file) do
file
|> File.read!()
|> String.split("\n")
|> Enum.reduce({nil, 0}, fn line, {current_msgid, count} ->
trimmed = String.trim(line)
case {trimmed, current_msgid} do
{"msgstr \"\"", nil} ->
{nil, count}
{"msgstr \"\"", msgid} ->
if msgid == "" do
{nil, count}
else
{nil, count + 1}
end
{"msgid \"" <> rest, _} ->
{String.trim_trailing(rest, "\""), count}
_ ->
{current_msgid, count}
end
end)
|> elem(1)
end
end