Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ def get_version() -> str:
include_package_data=True,
classifiers=["Topic :: Utilities", "Programming Language :: Python :: 3.9"],
requires=["setuptools", "wheel", "typing", "pillow", "numpy", "requests"],
entry_points={
"console_scripts": [
"loadimg=loadimg.loadimg:main",
],
},
)
49 changes: 49 additions & 0 deletions src/loadimg/loadimg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import argparse
import sys

try:
from .utils import load_img
except ImportError:
from utils import load_img


def main():
parser = argparse.ArgumentParser(
prog="loadimg", description="Load and convert images from various sources"
)
parser.add_argument("input", help="Input image (file path, URL, or base64 string)")
parser.add_argument(
"--output-type",
choices=["pil", "numpy", "str", "base64", "ascii", "ansi"],
default="ansi",
help="Output format (default: ansi)",
)
parser.add_argument(
"--input-type",
choices=["auto", "base64", "file", "url", "numpy", "pil"],
default="auto",
help="Input type (default: auto)",
)

args = parser.parse_args()
if not hasattr(args, "input"):
parser.print_help()
exit(1)

try:
result = load_img(
args.input, output_type=args.output_type, input_type=args.input_type
)
if isinstance(result, str):
print(result)
else:
print(f"Image converted successfully to {args.output_type} format")
except Exception as e:
print(f"Error: {e}")
return 1

return 0


if __name__ == "__main__":
sys.exit(main())
95 changes: 95 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import unittest
import tempfile
import os
from PIL import Image
from unittest.mock import patch, MagicMock
from loadimg.loadimg import main


class TestCLI(unittest.TestCase):
def setUp(self):
# Create a temporary test image
self.temp_dir = tempfile.TemporaryDirectory()
self.test_image_path = os.path.join(self.temp_dir.name, "test.png")
test_image = Image.new("RGB", (100, 100), color="red")
test_image.save(self.test_image_path)

def tearDown(self):
self.temp_dir.cleanup()

@patch("argparse.ArgumentParser.parse_args")
def test_main_with_file_input(self, mock_args):
# Test basic file input with default settings
mock_args.return_value = MagicMock(
input=self.test_image_path, output_type="ansi", input_type="auto"
)

with patch("builtins.print") as mock_print:
exit_code = main()
self.assertEqual(exit_code, 0)
mock_print.assert_called()

@patch("argparse.ArgumentParser.parse_args")
def test_main_with_invalid_file(self, mock_args):
# Test handling of non-existent file
mock_args.return_value = MagicMock(
input="nonexistent.jpg", output_type="ansi", input_type="auto"
)

with patch("builtins.print") as mock_print:
exit_code = main()
self.assertEqual(exit_code, 1)
mock_print.assert_called()

@patch("argparse.ArgumentParser.parse_args")
def test_main_with_different_output_types(self, mock_args):
# Test different output types
output_types = ["ascii", "ansi", "base64", "str"]

for output_type in output_types:
mock_args.return_value = MagicMock(
input=self.test_image_path, output_type=output_type, input_type="auto"
)

with patch("builtins.print") as mock_print:
exit_code = main()
self.assertEqual(exit_code, 0)
mock_print.assert_called()

def test_cli_argument_parsing(self):
test_cases = [
["loadimg", self.test_image_path],
["loadimg", self.test_image_path, "--output-type", "ascii"],
["loadimg", self.test_image_path, "--input-type", "file"],
[
"loadimg",
self.test_image_path,
"--output-type",
"ansi",
"--input-type",
"file",
],
]

for args in test_cases:
with patch("sys.argv", args), patch("builtins.print"), patch(
"argparse.ArgumentParser._print_message"
), patch("sys.exit") as mock_exit:
main()
# Check that sys.exit wasn't called with an error code
if mock_exit.called:
self.assertEqual(mock_exit.call_args[0][0], 0)

def test_help_message(self):
with patch("sys.argv", ["loadimg", "--help"]), patch(
"argparse.ArgumentParser.print_help"
) as mock_help, patch("builtins.print"), patch("sys.exit"):
try:
main()
except SystemExit:
pass
mock_help.assert_called_once()


if __name__ == "__main__":
unittest.main()