towerops/test/mix/tasks/populate_english_test.exs
2026-02-03 10:19:56 -06:00

247 lines
6.9 KiB
Elixir

defmodule Mix.Tasks.PopulateEnglishTest do
use ExUnit.Case, async: false
import ExUnit.CaptureIO
import Mix.Tasks.PopulateEnglish, only: [run: 1]
setup do
# Create temporary directory for test files
temp_dir = Path.join(System.tmp_dir!(), "populate_english_test_#{System.unique_integer([:positive])}")
po_dir = Path.join([temp_dir, "priv", "gettext", "en", "LC_MESSAGES"])
File.mkdir_p!(po_dir)
on_exit(fn ->
File.rm_rf!(temp_dir)
end)
{:ok, temp_dir: temp_dir, po_dir: po_dir}
end
describe "run/1" do
test "populates empty msgstr with msgid", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid "Hello"
msgstr ""
msgid "Goodbye"
msgstr ""
""")
# Change to temp directory so the task finds the files
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
capture_io(fn -> run([]) end)
end)
content = File.read!(po_file)
assert content =~ ~s(msgid "Hello"\nmsgstr "Hello")
assert content =~ ~s(msgid "Goodbye"\nmsgstr "Goodbye")
end
test "preserves existing non-empty msgstr", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid "Hello"
msgstr "Hola"
msgid "Goodbye"
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
capture_io(fn -> run([]) end)
end)
content = File.read!(po_file)
assert content =~ ~s(msgid "Hello"\nmsgstr "Hola")
assert content =~ ~s(msgid "Goodbye"\nmsgstr "Goodbye")
end
test "handles multiline msgid and msgstr", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid ""
"This is a "
"multiline string"
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
capture_io(fn -> run([]) end)
end)
content = File.read!(po_file)
assert content =~ ~s(msgstr ""\n"This is a "\n"multiline string")
end
test "preserves comments and metadata", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
# Comment line
## Another comment
msgid "Hello"
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
capture_io(fn -> run([]) end)
end)
content = File.read!(po_file)
assert content =~ "# Comment line"
assert content =~ "## Another comment"
assert content =~ ~s(msgid "Hello"\nmsgstr "Hello")
end
test "skips plural forms", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid "One item"
msgid_plural "%{count} items"
msgstr[0] ""
msgstr[1] ""
msgid "Regular message"
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
capture_io(fn -> run([]) end)
end)
content = File.read!(po_file)
# Plural forms should not be modified
assert content =~ ~s(msgstr[0] "")
assert content =~ ~s(msgstr[1] "")
# Regular message should be populated
assert content =~ ~s(msgid "Regular message"\nmsgstr "Regular message")
end
test "handles empty msgid", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid ""
msgstr ""
msgid "Hello"
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
capture_io(fn -> run([]) end)
end)
content = File.read!(po_file)
# Empty msgid should not be populated
lines = String.split(content, "\n")
empty_msgid_index = Enum.find_index(lines, &(&1 == ~s(msgid "")))
assert Enum.at(lines, empty_msgid_index + 1) == ~s(msgstr "")
# Non-empty msgid should be populated
assert content =~ ~s(msgid "Hello"\nmsgstr "Hello")
end
test "handles escaped characters in strings", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid "Line one\\nLine two"
msgstr ""
msgid "Tab\\there"
msgstr ""
msgid "Quote \\"here\\""
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
capture_io(fn -> run([]) end)
end)
content = File.read!(po_file)
assert content =~ ~s(msgid "Line one\\nLine two"\nmsgstr "Line one\\nLine two")
assert content =~ ~s(msgid "Tab\\there"\nmsgstr "Tab\\there")
assert content =~ ~s(msgid "Quote \\"here\\""\nmsgstr "Quote \\"here\\"")
end
test "processes multiple .po files", %{po_dir: po_dir} do
po_file1 = Path.join(po_dir, "test1.po")
po_file2 = Path.join(po_dir, "test2.po")
File.write!(po_file1, """
msgid "Hello"
msgstr ""
""")
File.write!(po_file2, """
msgid "Goodbye"
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
output = capture_io(fn -> run([]) end)
assert output =~ "2 English translation file(s)"
end)
assert File.read!(po_file1) =~ ~s(msgid "Hello"\nmsgstr "Hello")
assert File.read!(po_file2) =~ ~s(msgid "Goodbye"\nmsgstr "Goodbye")
end
test "reports no changes when file already populated", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid "Hello"
msgstr "Hello"
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
output = capture_io(fn -> run([]) end)
assert output =~ "No changes: test.po"
end)
end
test "reports updated when file is modified", %{po_dir: po_dir} do
po_file = Path.join(po_dir, "test.po")
File.write!(po_file, """
msgid "Hello"
msgstr ""
""")
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
output = capture_io(fn -> run([]) end)
assert output =~ "Updated: test.po"
end)
end
test "handles missing directory gracefully" do
temp_dir = Path.join(System.tmp_dir!(), "nonexistent_#{System.unique_integer([:positive])}")
File.mkdir_p!(temp_dir)
try do
File.cd!(temp_dir, fn ->
assert_raise Mix.Error, fn ->
capture_io(fn -> run([]) end)
end
end)
after
File.rm_rf!(temp_dir)
end
end
test "reports when no .po files found", %{po_dir: po_dir} do
File.cd!(Path.dirname(Path.dirname(Path.dirname(Path.dirname(po_dir)))), fn ->
output = capture_io(fn -> run([]) end)
assert output =~ "No .po files found"
end)
end
end
end