"""Tests for the CLI interface.""" import pytest from tzst.cli import create_parser, main class TestCLIParser: """Test CLI argument parsing.""" def test_parser_creation(self): """Test that parser can be created.""" parser = create_parser() assert parser is not None def test_add_command_parsing(self): """Test parsing of add command.""" parser = create_parser() args = parser.parse_args(["a", "test.tzst", "file1.txt", "file2.txt"]) assert args.command == "a" assert args.archive == "test.tzst" assert args.files == ["file1.txt", "file2.txt"] assert args.compression_level == 3 # default def test_extract_command_parsing(self): """Test parsing of extract command.""" parser = create_parser() args = parser.parse_args(["x", "test.tzst", "-o", "output"]) assert args.command == "x" assert args.archive == "test.tzst" assert args.output == "output" def test_list_command_parsing(self): """Test parsing of list command.""" parser = create_parser() args = parser.parse_args(["l", "test.tzst", "-v"]) assert args.command == "l" assert args.archive == "test.tzst" assert args.verbose is True def test_test_command_parsing(self): """Test parsing of test command.""" parser = create_parser() args = parser.parse_args(["t", "test.tzst"]) assert args.command == "t" assert args.archive == "test.tzst" class TestCLICommands: """Test CLI command execution.""" def test_add_command(self, sample_files, temp_dir): """Test add command functionality.""" archive_path = temp_dir / "test.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] # Run add command result = main(["a", str(archive_path)] + file_paths) assert result == 0 assert archive_path.exists() def test_list_command(self, sample_files, temp_dir): """Test list command functionality.""" archive_path = temp_dir / "test.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] # Create archive first main(["a", str(archive_path)] + file_paths) # Run list command result = main(["l", str(archive_path)]) assert result == 0 def test_extract_command(self, sample_files, temp_dir): """Test extract command functionality.""" archive_path = temp_dir / "test.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] extract_dir = temp_dir / "extracted" # Create archive first main(["a", str(archive_path)] + file_paths) # Run extract command result = main(["x", str(archive_path), "-o", str(extract_dir)]) assert result == 0 assert extract_dir.exists() def test_test_command(self, sample_files, temp_dir): """Test test command functionality.""" archive_path = temp_dir / "test.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] # Create archive first main(["a", str(archive_path)] + file_paths) # Run test command result = main(["t", str(archive_path)]) assert result == 0 class TestCLIErrorHandling: """Test CLI error handling.""" def test_missing_archive(self, temp_dir): """Test handling of missing archive file.""" fake_archive = temp_dir / "fake.tzst" result = main(["l", str(fake_archive)]) assert result == 1 def test_missing_files_to_add(self, temp_dir): """Test handling of missing files to add.""" archive_path = temp_dir / "test.tzst" fake_file = temp_dir / "fake.txt" result = main(["a", str(archive_path), str(fake_file)]) assert result == 1 def test_no_command(self): """Test handling of no command provided.""" result = main([]) assert result == 1 def test_keyboard_interrupt_handling(self, temp_dir): """Test that KeyboardInterrupt is handled properly.""" # This test is more conceptual since we can't easily simulate KeyboardInterrupt # in a unit test, but we can verify the error handling structure exists from tzst.cli import cmd_add # Create a mock args object class MockArgs: archive = str(temp_dir / "interrupt_test.tzst") files = ["non_existent_file.txt"] compression_level = 3 # Test that the function handles FileNotFoundError properly result = cmd_add(MockArgs()) assert result == 1 # Should return error code for missing files class TestCLIAliases: """Test CLI command aliases.""" def test_add_aliases(self, sample_files, temp_dir): """Test add command aliases.""" archive_path = temp_dir / "test.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] # Test 'add' alias result = main(["add", str(archive_path)] + file_paths) assert result == 0 # Test 'create' alias archive_path2 = temp_dir / "test2.tzst" result = main(["create", str(archive_path2)] + file_paths) assert result == 0 def test_extract_aliases(self, sample_files, temp_dir): """Test extract command aliases.""" archive_path = temp_dir / "test.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] extract_dir = temp_dir / "extracted" # Create archive first main(["a", str(archive_path)] + file_paths) # Test 'extract' alias result = main(["extract", str(archive_path), "-o", str(extract_dir)]) assert result == 0 def test_list_aliases(self, sample_files, temp_dir): """Test list command aliases.""" archive_path = temp_dir / "test.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] # Create archive first main(["a", str(archive_path)] + file_paths) # Test 'list' alias result = main(["list", str(archive_path)]) assert result == 0 @pytest.mark.integration class TestCLIIntegration: """Integration tests for CLI.""" def test_full_workflow(self, sample_files, temp_dir): """Test complete workflow: create, list, test, extract.""" archive_path = temp_dir / "workflow.tzst" file_paths = [str(f) for f in sample_files if f.is_file()] extract_dir = temp_dir / "workflow_extracted" # Create archive result = main(["a", str(archive_path)] + file_paths) assert result == 0 assert archive_path.exists() # List contents result = main(["l", str(archive_path)]) assert result == 0 # Test integrity result = main(["t", str(archive_path)]) assert result == 0 # Extract result = main(["x", str(archive_path), "-o", str(extract_dir)]) assert result == 0 assert extract_dir.exists() # Verify extracted files exist and have correct content for file_path in sample_files: if file_path.is_file(): relative_path = file_path.relative_to(sample_files[0].parent) extracted_file = extract_dir / relative_path assert extracted_file.exists() # Compare content original_content = file_path.read_bytes() extracted_content = extracted_file.read_bytes() assert original_content == extracted_content class TestCLIStreamingOptions: """Test CLI streaming options.""" def test_extract_streaming_flag(self, sample_files, temp_dir): """Test extract command with streaming flag.""" archive_path = temp_dir / "cli_streaming_test.tzst" file_paths = [f for f in sample_files if f.is_file()] # Create archive first from tzst import create_archive create_archive(archive_path, file_paths) # Test extract with streaming parser = create_parser() args = parser.parse_args( ["x", str(archive_path), "--streaming", "-o", str(temp_dir / "extracted")] ) assert args.command == "x" assert hasattr(args, "streaming") assert args.streaming is True def test_list_streaming_flag(self, sample_files, temp_dir): """Test list command with streaming flag.""" archive_path = temp_dir / "cli_list_streaming.tzst" file_paths = [f for f in sample_files if f.is_file()] # Create archive first from tzst import create_archive create_archive(archive_path, file_paths) # Test list with streaming parser = create_parser() args = parser.parse_args(["l", str(archive_path), "--streaming"]) assert args.command == "l" assert hasattr(args, "streaming") assert args.streaming is True def test_test_streaming_flag(self, sample_files, temp_dir): """Test test command with streaming flag.""" archive_path = temp_dir / "cli_test_streaming.tzst" file_paths = [f for f in sample_files if f.is_file()] # Create archive first from tzst import create_archive create_archive(archive_path, file_paths) # Test test command with streaming parser = create_parser() args = parser.parse_args(["t", str(archive_path), "--streaming"]) assert args.command == "t" assert hasattr(args, "streaming") assert args.streaming is True