200 lines
7.0 KiB
Python
200 lines
7.0 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
import click
|
|
|
|
|
|
SRC_ROOT = Path(__file__).resolve().parents[2] / "src"
|
|
|
|
if str(SRC_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(SRC_ROOT))
|
|
|
|
|
|
from ffx import cli # noqa: E402
|
|
|
|
|
|
class StaticConfig:
|
|
def __init__(self, subtitles_directory: str = ""):
|
|
self._subtitles_directory = subtitles_directory
|
|
|
|
def getSubtitlesDirectoryPath(self):
|
|
return self._subtitles_directory
|
|
|
|
|
|
class UnmuxOutputDirectoryTests(unittest.TestCase):
|
|
def test_subtitles_only_with_label_uses_configured_subtitles_base_directory(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
context = {
|
|
"config": StaticConfig(str(Path(tempdir) / "subtitles")),
|
|
}
|
|
|
|
resolved_output_directory, should_create = cli.resolveUnmuxOutputDirectory(
|
|
context,
|
|
"",
|
|
True,
|
|
"dball",
|
|
)
|
|
|
|
self.assertEqual(str(Path(tempdir) / "subtitles" / "dball"), resolved_output_directory)
|
|
self.assertTrue(should_create)
|
|
|
|
def test_explicit_output_directory_requires_directory(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
context = {
|
|
"config": StaticConfig(str(Path(tempdir) / "subtitles")),
|
|
}
|
|
explicit_output_directory = str(Path(tempdir) / "manual")
|
|
|
|
resolved_output_directory, should_create = cli.resolveUnmuxOutputDirectory(
|
|
context,
|
|
explicit_output_directory,
|
|
True,
|
|
"dball",
|
|
)
|
|
|
|
self.assertEqual(explicit_output_directory, resolved_output_directory)
|
|
self.assertTrue(should_create)
|
|
|
|
def test_subtitles_only_without_label_keeps_existing_behavior(self):
|
|
context = {
|
|
"config": StaticConfig("/tmp/subtitles"),
|
|
}
|
|
|
|
resolved_output_directory, should_create = cli.resolveUnmuxOutputDirectory(
|
|
context,
|
|
"",
|
|
True,
|
|
"",
|
|
)
|
|
|
|
self.assertEqual("", resolved_output_directory)
|
|
self.assertFalse(should_create)
|
|
|
|
def test_subtitles_only_with_label_requires_configured_default_when_output_directory_is_missing(self):
|
|
context = {
|
|
"config": StaticConfig(""),
|
|
}
|
|
|
|
with self.assertRaises(click.ClickException) as caught:
|
|
cli.resolveUnmuxOutputDirectory(
|
|
context,
|
|
"",
|
|
True,
|
|
"dball",
|
|
)
|
|
|
|
self.assertIn("subtitlesDirectory default", str(caught.exception))
|
|
|
|
def test_missing_output_directory_can_be_confirmed_and_created_with_parents(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
output_directory = Path(tempdir) / "missing" / "parents" / "manual"
|
|
|
|
with patch("ffx.cli.click.confirm", return_value=True) as mocked_confirm:
|
|
created = cli.ensureUnmuxOutputDirectory(
|
|
{"dry_run": False},
|
|
str(output_directory),
|
|
)
|
|
|
|
self.assertTrue(created)
|
|
self.assertTrue(output_directory.is_dir())
|
|
mocked_confirm.assert_called_once()
|
|
|
|
def test_tty_carriage_return_accepts_default_directory_creation(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
output_directory = Path(tempdir) / "missing" / "manual"
|
|
|
|
with patch("ffx.cli.sys.stdin.isatty", return_value=True), patch(
|
|
"ffx.cli.click.getchar",
|
|
return_value="\r",
|
|
) as mocked_getchar, patch("ffx.cli.click.confirm") as mocked_confirm:
|
|
created = cli.ensureUnmuxOutputDirectory(
|
|
{"dry_run": False},
|
|
str(output_directory),
|
|
)
|
|
|
|
self.assertTrue(created)
|
|
self.assertTrue(output_directory.is_dir())
|
|
mocked_getchar.assert_called_once()
|
|
mocked_confirm.assert_not_called()
|
|
|
|
def test_yes_creates_missing_output_directory_without_prompt(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
output_directory = Path(tempdir) / "missing" / "parents" / "manual"
|
|
|
|
with patch("ffx.cli.click.confirm") as mocked_confirm:
|
|
created = cli.ensureUnmuxOutputDirectory(
|
|
{"dry_run": False, "yes": True},
|
|
str(output_directory),
|
|
)
|
|
|
|
self.assertTrue(created)
|
|
self.assertTrue(output_directory.is_dir())
|
|
mocked_confirm.assert_not_called()
|
|
|
|
def test_missing_output_directory_can_be_rejected(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
output_directory = Path(tempdir) / "missing" / "manual"
|
|
|
|
with patch("ffx.cli.click.confirm", return_value=False) as mocked_confirm:
|
|
with self.assertRaises(click.ClickException) as caught:
|
|
cli.ensureUnmuxOutputDirectory(
|
|
{"dry_run": False},
|
|
str(output_directory),
|
|
)
|
|
|
|
self.assertFalse(output_directory.exists())
|
|
self.assertIn("aborted by user", str(caught.exception))
|
|
mocked_confirm.assert_called_once()
|
|
|
|
def test_existing_output_directory_does_not_prompt(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
output_directory = Path(tempdir) / "manual"
|
|
output_directory.mkdir()
|
|
|
|
with patch("ffx.cli.click.confirm") as mocked_confirm:
|
|
created = cli.ensureUnmuxOutputDirectory(
|
|
{"dry_run": False},
|
|
str(output_directory),
|
|
)
|
|
|
|
self.assertFalse(created)
|
|
mocked_confirm.assert_not_called()
|
|
|
|
def test_existing_non_directory_output_path_fails_without_prompt(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
output_path = Path(tempdir) / "manual"
|
|
output_path.write_text("not a directory", encoding="utf-8")
|
|
|
|
with patch("ffx.cli.click.confirm") as mocked_confirm:
|
|
with self.assertRaises(click.ClickException) as caught:
|
|
cli.ensureUnmuxOutputDirectory(
|
|
{"dry_run": False},
|
|
str(output_path),
|
|
)
|
|
|
|
self.assertIn("not a directory", str(caught.exception))
|
|
mocked_confirm.assert_not_called()
|
|
|
|
def test_dry_run_does_not_prompt_or_create_missing_output_directory(self):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
output_directory = Path(tempdir) / "missing" / "manual"
|
|
|
|
with patch("ffx.cli.click.confirm") as mocked_confirm:
|
|
created = cli.ensureUnmuxOutputDirectory(
|
|
{"dry_run": True},
|
|
str(output_directory),
|
|
)
|
|
|
|
self.assertFalse(created)
|
|
self.assertFalse(output_directory.exists())
|
|
mocked_confirm.assert_not_called()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|