diff --git a/tests/structs/test_base_swarm.py b/tests/structs/test_base_swarm.py new file mode 100644 index 00000000..98f27ba1 --- /dev/null +++ b/tests/structs/test_base_swarm.py @@ -0,0 +1,20 @@ +import pytest + + +def test_base_swarm_module_can_be_imported(): + """Test that base_swarm module can be imported""" + from swarms.structs import base_swarm + assert base_swarm is not None + + +def test_base_swarm_class_exists(): + """Test that BaseSwarm class exists""" + from swarms.structs.base_swarm import BaseSwarm + assert BaseSwarm is not None + + +def test_base_swarm_is_abstract(): + """Test that BaseSwarm is an abstract base class""" + from swarms.structs.base_swarm import BaseSwarm + from abc import ABC + assert issubclass(BaseSwarm, ABC) diff --git a/tests/structs/test_base_swarm_placeholder.py b/tests/structs/test_base_swarm_placeholder.py new file mode 100644 index 00000000..947c23c0 --- /dev/null +++ b/tests/structs/test_base_swarm_placeholder.py @@ -0,0 +1,17 @@ +import pytest + + +def test_base_swarm_module_imports(): + """Test that base_swarm module can be imported""" + try: + from swarms.structs import base_swarm + assert base_swarm is not None + except ImportError: + pytest.skip("base_swarm module not found") + + +def test_base_swarm_placeholder(): + """Placeholder test for base_swarm - primarily contains classes""" + # base_swarm.py contains primarily class definitions + # Tests for class-based code would require more complex setup + assert True diff --git a/tests/structs/test_collaborative_utils.py b/tests/structs/test_collaborative_utils.py new file mode 100644 index 00000000..4aa8388b --- /dev/null +++ b/tests/structs/test_collaborative_utils.py @@ -0,0 +1,104 @@ +import pytest +from swarms.structs.collaborative_utils import talk_to_agent +from swarms.structs.agent import Agent + + +def create_test_agent(name: str, description: str = "Test agent") -> Agent: + """Create a real Agent instance for testing""" + return Agent( + agent_name=name, + agent_description=description, + system_prompt=f"You are {name}, a helpful test assistant.", + model_name="gpt-4o-mini", + max_loops=1, + verbose=False, + ) + + +def test_talk_to_agent_success(): + """Test successful agent-to-agent communication""" + current_agent = create_test_agent("CurrentAgent") + target_agent = create_test_agent("TargetAgent") + + agents = [current_agent, target_agent] + + result = talk_to_agent( + current_agent=current_agent, + agents=agents, + task="What is 2+2?", + agent_name="TargetAgent", + max_loops=1 + ) + + assert result is not None + # Result should be a list or string from the debate + assert len(str(result)) > 0 + + +def test_talk_to_agent_not_found(): + """Test error when target agent not found""" + current_agent = create_test_agent("CurrentAgent") + + agents = [current_agent] + + with pytest.raises(ValueError, match="Agent 'NonExistent' not found"): + talk_to_agent( + current_agent=current_agent, + agents=agents, + task="Test task", + agent_name="NonExistent" + ) + + +def test_talk_to_agent_with_max_loops(): + """Test talk_to_agent with custom max_loops""" + current_agent = create_test_agent("CurrentAgent") + target_agent = create_test_agent("TargetAgent") + + agents = [current_agent, target_agent] + + result = talk_to_agent( + current_agent=current_agent, + agents=agents, + task="Discuss the weather briefly", + agent_name="TargetAgent", + max_loops=2 + ) + + assert result is not None + + +def test_talk_to_agent_no_agent_name_attribute(): + """Test when target agent is not found by name""" + current_agent = create_test_agent("CurrentAgent") + # Create another agent with different name + other_agent = create_test_agent("OtherAgent") + + agents = [current_agent, other_agent] + + with pytest.raises(ValueError, match="Agent 'TargetAgent' not found"): + talk_to_agent( + current_agent=current_agent, + agents=agents, + task="Test", + agent_name="TargetAgent" + ) + + +def test_talk_to_agent_output_type(): + """Test talk_to_agent with custom output_type""" + current_agent = create_test_agent("CurrentAgent") + target_agent = create_test_agent("TargetAgent") + + agents = [current_agent, target_agent] + + result = talk_to_agent( + current_agent=current_agent, + agents=agents, + task="Say hello", + agent_name="TargetAgent", + output_type="str", + max_loops=1 + ) + + assert result is not None diff --git a/tests/structs/test_concat.py b/tests/structs/test_concat.py new file mode 100644 index 00000000..9e8bbc21 --- /dev/null +++ b/tests/structs/test_concat.py @@ -0,0 +1,68 @@ +import pytest +from swarms.structs.concat import concat_strings + + +def test_concat_strings_basic(): + """Test basic string concatenation""" + result = concat_strings(["hello", " ", "world"]) + assert result == "hello world" + + +def test_concat_strings_empty_list(): + """Test concatenation with empty list""" + result = concat_strings([]) + assert result == "" + + +def test_concat_strings_single_element(): + """Test concatenation with single element""" + result = concat_strings(["hello"]) + assert result == "hello" + + +def test_concat_strings_multiple_elements(): + """Test concatenation with multiple elements""" + result = concat_strings(["a", "b", "c", "d", "e"]) + assert result == "abcde" + + +def test_concat_strings_with_special_characters(): + """Test concatenation with special characters""" + result = concat_strings(["hello", "\n", "world", "\t", "!"]) + assert result == "hello\nworld\t!" + + +def test_concat_strings_not_list_raises_typeerror(): + """Test that non-list input raises TypeError""" + with pytest.raises(TypeError, match="Input must be a list of strings"): + concat_strings("not a list") + + +def test_concat_strings_non_string_element_raises_typeerror(): + """Test that list with non-string elements raises TypeError""" + with pytest.raises(TypeError, match="All elements in the list must be strings"): + concat_strings(["hello", 123, "world"]) + + +def test_concat_strings_mixed_types_raises_typeerror(): + """Test that list with mixed types raises TypeError""" + with pytest.raises(TypeError, match="All elements in the list must be strings"): + concat_strings(["hello", None, "world"]) + + +def test_concat_strings_with_numbers_raises_typeerror(): + """Test that list containing numbers raises TypeError""" + with pytest.raises(TypeError, match="All elements in the list must be strings"): + concat_strings([1, 2, 3]) + + +def test_concat_strings_empty_strings(): + """Test concatenation with empty strings""" + result = concat_strings(["", "", ""]) + assert result == "" + + +def test_concat_strings_unicode(): + """Test concatenation with unicode characters""" + result = concat_strings(["Hello", " ", "δΈ–η•Œ", " ", "🌍"]) + assert result == "Hello δΈ–η•Œ 🌍" diff --git a/tests/structs/test_council_as_judge_functions.py b/tests/structs/test_council_as_judge_functions.py new file mode 100644 index 00000000..0994b290 --- /dev/null +++ b/tests/structs/test_council_as_judge_functions.py @@ -0,0 +1,189 @@ +import pytest +from swarms.structs.council_as_judge import ( + EvaluationError, + DimensionEvaluationError, + AggregationError, + EVAL_DIMENSIONS, + judge_system_prompt, + build_judge_prompt, + aggregator_system_prompt, + build_aggregation_prompt, +) + + +def test_evaluation_error_is_exception(): + """Test that EvaluationError is an Exception subclass""" + assert issubclass(EvaluationError, Exception) + + +def test_dimension_evaluation_error_is_evaluation_error(): + """Test that DimensionEvaluationError is an EvaluationError subclass""" + assert issubclass(DimensionEvaluationError, EvaluationError) + + +def test_aggregation_error_is_evaluation_error(): + """Test that AggregationError is an EvaluationError subclass""" + assert issubclass(AggregationError, EvaluationError) + + +def test_eval_dimensions_exists(): + """Test that EVAL_DIMENSIONS dictionary exists""" + assert isinstance(EVAL_DIMENSIONS, dict) + assert len(EVAL_DIMENSIONS) > 0 + + +def test_eval_dimensions_contains_expected_keys(): + """Test that EVAL_DIMENSIONS contains expected evaluation dimensions""" + expected_dimensions = [ + "accuracy", + "helpfulness", + "harmlessness", + "coherence", + "conciseness", + "instruction_adherence", + ] + for dimension in expected_dimensions: + assert dimension in EVAL_DIMENSIONS + + +def test_eval_dimensions_values_are_strings(): + """Test that all EVAL_DIMENSIONS values are strings""" + for dimension, description in EVAL_DIMENSIONS.items(): + assert isinstance(description, str) + assert len(description) > 0 + + +def test_judge_system_prompt_returns_string(): + """Test that judge_system_prompt returns a string""" + result = judge_system_prompt() + assert isinstance(result, str) + assert len(result) > 0 + + +def test_judge_system_prompt_contains_key_phrases(): + """Test that judge_system_prompt contains expected content""" + result = judge_system_prompt() + assert "evaluator" in result.lower() + assert "feedback" in result.lower() + + +def test_build_judge_prompt_valid_dimension(): + """Test build_judge_prompt with valid dimension""" + result = build_judge_prompt( + dimension_name="accuracy", + task="Test task", + task_response="Test response" + ) + assert isinstance(result, str) + assert "accuracy" in result.lower() + assert "Test task" in result + assert "Test response" in result + + +def test_build_judge_prompt_invalid_dimension_raises_error(): + """Test that build_judge_prompt raises KeyError for invalid dimension""" + with pytest.raises(KeyError, match="Unknown evaluation dimension"): + build_judge_prompt( + dimension_name="invalid_dimension", + task="Test task", + task_response="Test response" + ) + + +def test_build_judge_prompt_includes_evaluation_focus(): + """Test that build_judge_prompt includes evaluation focus from EVAL_DIMENSIONS""" + result = build_judge_prompt( + dimension_name="helpfulness", + task="Test task", + task_response="Test response" + ) + # Should contain some content from EVAL_DIMENSIONS["helpfulness"] + assert "helpfulness" in result.lower() + + +def test_aggregator_system_prompt_returns_string(): + """Test that aggregator_system_prompt returns a string""" + result = aggregator_system_prompt() + assert isinstance(result, str) + assert len(result) > 0 + + +def test_aggregator_system_prompt_contains_key_phrases(): + """Test that aggregator_system_prompt contains expected content""" + result = aggregator_system_prompt() + assert "synthesizing" in result.lower() or "synthesis" in result.lower() + assert "report" in result.lower() + + +def test_build_aggregation_prompt_basic(): + """Test build_aggregation_prompt with basic input""" + rationales = { + "accuracy": "This response is accurate", + "helpfulness": "This response is helpful" + } + result = build_aggregation_prompt(rationales) + assert isinstance(result, str) + assert "accuracy" in result.lower() + assert "helpfulness" in result.lower() + assert "This response is accurate" in result + assert "This response is helpful" in result + + +def test_build_aggregation_prompt_empty_dict(): + """Test build_aggregation_prompt with empty dictionary""" + result = build_aggregation_prompt({}) + assert isinstance(result, str) + assert len(result) > 0 + + +def test_build_aggregation_prompt_single_dimension(): + """Test build_aggregation_prompt with single dimension""" + rationales = {"accuracy": "Accuracy analysis"} + result = build_aggregation_prompt(rationales) + assert "accuracy" in result.lower() + assert "Accuracy analysis" in result + + +def test_build_aggregation_prompt_multiple_dimensions(): + """Test build_aggregation_prompt with multiple dimensions""" + rationales = { + "accuracy": "Accuracy text", + "helpfulness": "Helpfulness text", + "coherence": "Coherence text" + } + result = build_aggregation_prompt(rationales) + for dim, text in rationales.items(): + assert dim.upper() in result + assert text in result + + +def test_evaluation_error_can_be_raised(): + """Test that EvaluationError can be raised""" + with pytest.raises(EvaluationError, match="Test error"): + raise EvaluationError("Test error") + + +def test_dimension_evaluation_error_can_be_raised(): + """Test that DimensionEvaluationError can be raised""" + with pytest.raises(DimensionEvaluationError, match="Dimension error"): + raise DimensionEvaluationError("Dimension error") + + +def test_aggregation_error_can_be_raised(): + """Test that AggregationError can be raised""" + with pytest.raises(AggregationError, match="Aggregation error"): + raise AggregationError("Aggregation error") + + +def test_judge_system_prompt_is_cacheable(): + """Test that judge_system_prompt can be called multiple times""" + result1 = judge_system_prompt() + result2 = judge_system_prompt() + assert result1 == result2 + + +def test_aggregator_system_prompt_is_cacheable(): + """Test that aggregator_system_prompt can be called multiple times""" + result1 = aggregator_system_prompt() + result2 = aggregator_system_prompt() + assert result1 == result2 diff --git a/tests/structs/test_cron_job_functions.py b/tests/structs/test_cron_job_functions.py new file mode 100644 index 00000000..ebd55b5b --- /dev/null +++ b/tests/structs/test_cron_job_functions.py @@ -0,0 +1,82 @@ +import pytest +from swarms.structs.cron_job import ( + CronJobError, + CronJobConfigError, + CronJobScheduleError, + CronJobExecutionError, +) + + +def test_cron_job_error_is_exception(): + """Test that CronJobError is an Exception subclass""" + assert issubclass(CronJobError, Exception) + + +def test_cron_job_config_error_is_cron_job_error(): + """Test that CronJobConfigError is a CronJobError subclass""" + assert issubclass(CronJobConfigError, CronJobError) + + +def test_cron_job_schedule_error_is_cron_job_error(): + """Test that CronJobScheduleError is a CronJobError subclass""" + assert issubclass(CronJobScheduleError, CronJobError) + + +def test_cron_job_execution_error_is_cron_job_error(): + """Test that CronJobExecutionError is a CronJobError subclass""" + assert issubclass(CronJobExecutionError, CronJobError) + + +def test_cron_job_error_can_be_raised(): + """Test that CronJobError can be raised and caught""" + with pytest.raises(CronJobError, match="Test error"): + raise CronJobError("Test error") + + +def test_cron_job_config_error_can_be_raised(): + """Test that CronJobConfigError can be raised and caught""" + with pytest.raises(CronJobConfigError, match="Config error"): + raise CronJobConfigError("Config error") + + +def test_cron_job_schedule_error_can_be_raised(): + """Test that CronJobScheduleError can be raised and caught""" + with pytest.raises(CronJobScheduleError, match="Schedule error"): + raise CronJobScheduleError("Schedule error") + + +def test_cron_job_execution_error_can_be_raised(): + """Test that CronJobExecutionError can be raised and caught""" + with pytest.raises(CronJobExecutionError, match="Execution error"): + raise CronJobExecutionError("Execution error") + + +def test_cron_job_error_inheritance_chain(): + """Test that all CronJob errors inherit from CronJobError and Exception""" + assert issubclass(CronJobConfigError, Exception) + assert issubclass(CronJobScheduleError, Exception) + assert issubclass(CronJobExecutionError, Exception) + + +def test_cron_job_error_with_custom_message(): + """Test CronJobError with custom message""" + error = CronJobError("Custom error message") + assert str(error) == "Custom error message" + + +def test_cron_job_config_error_with_custom_message(): + """Test CronJobConfigError with custom message""" + error = CronJobConfigError("Invalid configuration") + assert str(error) == "Invalid configuration" + + +def test_cron_job_schedule_error_with_custom_message(): + """Test CronJobScheduleError with custom message""" + error = CronJobScheduleError("Scheduling failed") + assert str(error) == "Scheduling failed" + + +def test_cron_job_execution_error_with_custom_message(): + """Test CronJobExecutionError with custom message""" + error = CronJobExecutionError("Task failed") + assert str(error) == "Task failed" diff --git a/tests/structs/test_deep_discussion_functions.py b/tests/structs/test_deep_discussion_functions.py new file mode 100644 index 00000000..9ad072cd --- /dev/null +++ b/tests/structs/test_deep_discussion_functions.py @@ -0,0 +1,164 @@ +import pytest +from swarms.structs.deep_discussion import one_on_one_debate +from swarms.structs.agent import Agent + + +def create_test_agent(name: str, description: str = "Test agent") -> Agent: + """Create a real Agent instance for testing""" + return Agent( + agent_name=name, + agent_description=description, + system_prompt=f"You are {name}, a helpful test assistant. Keep responses brief.", + model_name="gpt-4o-mini", + max_loops=1, + verbose=False, + ) + + +def test_one_on_one_debate_requires_two_agents(): + """Test that one_on_one_debate requires exactly two agents""" + agent1 = create_test_agent("Agent1") + + with pytest.raises(ValueError, match="exactly two agents"): + one_on_one_debate(agents=[agent1], task="Test") + + +def test_one_on_one_debate_with_three_agents_raises_error(): + """Test that one_on_one_debate raises error with three agents""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + agent3 = create_test_agent("Agent3") + + with pytest.raises(ValueError, match="exactly two agents"): + one_on_one_debate(agents=[agent1, agent2, agent3], task="Test") + + +def test_one_on_one_debate_with_empty_list_raises_error(): + """Test that one_on_one_debate raises error with empty agent list""" + with pytest.raises(ValueError, match="exactly two agents"): + one_on_one_debate(agents=[], task="Test") + + +def test_one_on_one_debate_basic_execution(): + """Test basic execution of one_on_one_debate""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + result = one_on_one_debate( + agents=[agent1, agent2], + task="What is 2+2?", + max_loops=1 + ) + + # Result should exist + assert result is not None + + +def test_one_on_one_debate_max_loops(): + """Test that one_on_one_debate respects max_loops parameter""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + result = one_on_one_debate( + agents=[agent1, agent2], + task="Briefly discuss: What makes a good team?", + max_loops=2 + ) + + # Result should exist + assert result is not None + + +def test_one_on_one_debate_with_img_parameter(): + """Test that one_on_one_debate accepts img parameter""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + # Test that the function accepts img parameter without error + result = one_on_one_debate( + agents=[agent1, agent2], + task="Describe briefly", + img=None, # Using None to avoid needing actual image + max_loops=1 + ) + + assert result is not None + + +def test_one_on_one_debate_alternates_speakers(): + """Test that one_on_one_debate produces output from debate""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + result = one_on_one_debate( + agents=[agent1, agent2], + task="Exchange one brief greeting each", + max_loops=2 + ) + + # Verify output was produced + assert result is not None + assert len(str(result)) > 0 + + +def test_one_on_one_debate_with_zero_loops(): + """Test one_on_one_debate with zero max_loops""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + result = one_on_one_debate( + agents=[agent1, agent2], + task="Task", + max_loops=0 + ) + + # With 0 loops, result should still be returned (possibly empty) + assert result is not None + + +def test_one_on_one_debate_output_type_parameter(): + """Test that one_on_one_debate accepts output_type parameter""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + # Should not raise error with valid output_type + result = one_on_one_debate( + agents=[agent1, agent2], + task="Say hello briefly", + max_loops=1, + output_type="str" + ) + + assert result is not None + + +def test_one_on_one_debate_passes_task_to_first_agent(): + """Test that initial task is passed and processed""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + initial_task = "What is the capital of France?" + result = one_on_one_debate( + agents=[agent1, agent2], + task=initial_task, + max_loops=1 + ) + + # Result should contain some response + assert result is not None + assert len(str(result)) > 0 + + +def test_one_on_one_debate_produces_output(): + """Test that debate executes and produces output""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + result = one_on_one_debate( + agents=[agent1, agent2], + task="What color is the sky?", + max_loops=1 + ) + + # Debate should produce a result + assert result is not None diff --git a/tests/structs/test_heavy_swarm.py b/tests/structs/test_heavy_swarm.py new file mode 100644 index 00000000..a9c6a3ef --- /dev/null +++ b/tests/structs/test_heavy_swarm.py @@ -0,0 +1,19 @@ +import pytest + + +def test_heavy_swarm_module_can_be_imported(): + """Test that heavy_swarm module can be imported""" + try: + from swarms.structs import heavy_swarm + assert heavy_swarm is not None + except ImportError: + pytest.skip("heavy_swarm module has import dependencies") + + +def test_heavy_swarm_class_exists(): + """Test that HeavySwarm class exists if module is available""" + try: + from swarms.structs.heavy_swarm import HeavySwarm + assert HeavySwarm is not None + except (ImportError, AttributeError): + pytest.skip("HeavySwarm class not available or has dependencies") diff --git a/tests/structs/test_hierarchical_structured_communication_framework.py b/tests/structs/test_hierarchical_structured_communication_framework.py new file mode 100644 index 00000000..a9d83ecf --- /dev/null +++ b/tests/structs/test_hierarchical_structured_communication_framework.py @@ -0,0 +1,21 @@ +import pytest + + +def test_hierarchical_framework_module_can_be_imported(): + """Test that hierarchical_structured_communication_framework module can be imported""" + try: + from swarms.structs import hierarchical_structured_communication_framework + assert hierarchical_structured_communication_framework is not None + except ImportError: + pytest.skip("Module has import dependencies") + + +def test_hierarchical_framework_class_exists(): + """Test that classes exist in hierarchical framework""" + try: + from swarms.structs.hierarchical_structured_communication_framework import ( + HierarchicalSwarmFramework + ) + assert HierarchicalSwarmFramework is not None + except (ImportError, AttributeError): + pytest.skip("Classes not available or have dependencies") diff --git a/tests/structs/test_image_batch_processor_functions.py b/tests/structs/test_image_batch_processor_functions.py new file mode 100644 index 00000000..b3560dce --- /dev/null +++ b/tests/structs/test_image_batch_processor_functions.py @@ -0,0 +1,71 @@ +import pytest +from swarms.structs.image_batch_processor import ( + ImageProcessingError, + InvalidAgentError, +) + + +def test_image_processing_error_is_exception(): + """Test that ImageProcessingError is an Exception subclass""" + assert issubclass(ImageProcessingError, Exception) + + +def test_invalid_agent_error_is_exception(): + """Test that InvalidAgentError is an Exception subclass""" + assert issubclass(InvalidAgentError, Exception) + + +def test_image_processing_error_can_be_raised(): + """Test that ImageProcessingError can be raised and caught""" + with pytest.raises(ImageProcessingError, match="Image error"): + raise ImageProcessingError("Image error") + + +def test_invalid_agent_error_can_be_raised(): + """Test that InvalidAgentError can be raised and caught""" + with pytest.raises(InvalidAgentError, match="Agent error"): + raise InvalidAgentError("Agent error") + + +def test_image_processing_error_with_custom_message(): + """Test ImageProcessingError with custom message""" + error = ImageProcessingError("Failed to process image") + assert str(error) == "Failed to process image" + + +def test_invalid_agent_error_with_custom_message(): + """Test InvalidAgentError with custom message""" + error = InvalidAgentError("Invalid agent configuration") + assert str(error) == "Invalid agent configuration" + + +def test_image_processing_error_inheritance(): + """Test ImageProcessingError inheritance""" + error = ImageProcessingError("Test") + assert isinstance(error, Exception) + assert isinstance(error, ImageProcessingError) + + +def test_invalid_agent_error_inheritance(): + """Test InvalidAgentError inheritance""" + error = InvalidAgentError("Test") + assert isinstance(error, Exception) + assert isinstance(error, InvalidAgentError) + + +def test_image_processing_error_can_be_caught_as_exception(): + """Test that ImageProcessingError can be caught as Exception""" + try: + raise ImageProcessingError("Test error") + except Exception as e: + assert isinstance(e, ImageProcessingError) + assert str(e) == "Test error" + + +def test_invalid_agent_error_can_be_caught_as_exception(): + """Test that InvalidAgentError can be caught as Exception""" + try: + raise InvalidAgentError("Test error") + except Exception as e: + assert isinstance(e, InvalidAgentError) + assert str(e) == "Test error" diff --git a/tests/structs/test_ma_blocks.py b/tests/structs/test_ma_blocks.py new file mode 100644 index 00000000..674984f6 --- /dev/null +++ b/tests/structs/test_ma_blocks.py @@ -0,0 +1,173 @@ +import pytest +from swarms.structs.ma_blocks import ( + aggregator_agent_task_prompt, + aggregate, + run_agent, + find_agent_by_name, +) +from swarms.structs.agent import Agent +from swarms.structs.conversation import Conversation + + +def create_test_agent(name: str, description: str = "Test agent") -> Agent: + """Create a real Agent instance for testing""" + return Agent( + agent_name=name, + agent_description=description, + system_prompt=f"You are {name}, a helpful test assistant. Keep responses brief.", + model_name="gpt-4o-mini", + max_loops=1, + verbose=False, + ) + + +def test_aggregator_agent_task_prompt(): + """Test aggregator agent task prompt generation""" + agent1 = create_test_agent("Agent1", "First test agent") + agent2 = create_test_agent("Agent2", "Second test agent") + + workers = [agent1, agent2] + + conversation = Conversation() + conversation.add(role="Agent1", content="Hello") + conversation.add(role="Agent2", content="Hi") + + result = aggregator_agent_task_prompt( + task="Test task", + workers=workers, + conversation=conversation + ) + + assert "Test task" in result + assert "2" in result # Number of agents + assert "Hello" in result or "Hi" in result + + +def test_aggregate_missing_task_raises_error(): + """Test that missing task raises ValueError""" + agent = create_test_agent("TestAgent") + with pytest.raises(ValueError, match="Task is required"): + aggregate(workers=[agent], task=None) + + +def test_aggregate_missing_workers_raises_error(): + """Test that missing workers raises ValueError""" + with pytest.raises(ValueError, match="Workers is required"): + aggregate(workers=None, task="Test") + + +def test_aggregate_workers_not_list_raises_error(): + """Test that non-list workers raises ValueError""" + agent = create_test_agent("TestAgent") + with pytest.raises(ValueError, match="Workers must be a list"): + aggregate(workers=agent, task="Test") + + +def test_aggregate_workers_not_callable_raises_error(): + """Test that non-callable workers raises ValueError""" + with pytest.raises(ValueError, match="Workers must be a list of Callable"): + aggregate(workers=["not", "callable"], task="Test") + + +def test_run_agent_none_agent_raises_error(): + """Test that None agent raises ValueError""" + with pytest.raises(ValueError, match="Agent cannot be None"): + run_agent(agent=None, task="Test") + + +def test_run_agent_none_task_raises_error(): + """Test that None task raises ValueError""" + agent = create_test_agent("TestAgent") + with pytest.raises(ValueError, match="Task cannot be None"): + run_agent(agent=agent, task=None) + + +def test_run_agent_not_agent_instance_raises_error(): + """Test that non-Agent instance raises TypeError""" + with pytest.raises(TypeError, match="Agent must be an instance of Agent"): + run_agent(agent="not an agent", task="Test") + + +def test_run_agent_success(): + """Test successful agent run""" + agent = create_test_agent("TestAgent") + + result = run_agent(agent=agent, task="What is 2+2?") + + assert result is not None + assert len(str(result)) > 0 + + +def test_run_agent_with_kwargs(): + """Test run_agent with additional kwargs""" + agent = create_test_agent("TestAgent") + + result = run_agent( + agent=agent, + task="Say hello" + ) + + assert result is not None + + +def test_find_agent_by_name_empty_list_raises_error(): + """Test that empty agents list raises ValueError""" + with pytest.raises(ValueError, match="Agents list cannot be empty"): + find_agent_by_name(agents=[], agent_name="Test") + + +def test_find_agent_by_name_non_string_raises_error(): + """Test that non-string agent_name raises TypeError""" + agent = create_test_agent("TestAgent") + with pytest.raises(TypeError, match="Agent name must be a string"): + find_agent_by_name(agents=[agent], agent_name=123) + + +def test_find_agent_by_name_empty_string_raises_error(): + """Test that empty agent_name raises ValueError""" + agent = create_test_agent("TestAgent") + with pytest.raises(ValueError, match="Agent name cannot be empty"): + find_agent_by_name(agents=[agent], agent_name=" ") + + +def test_find_agent_by_name_success(): + """Test successful agent finding by name""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + # Note: find_agent_by_name looks for 'name' attribute, not 'agent_name' + agent1.name = "Agent1" + agent2.name = "Agent2" + + result = find_agent_by_name( + agents=[agent1, agent2], + agent_name="Agent2" + ) + + assert result == agent2 + + +def test_find_agent_by_name_not_found_raises_error(): + """Test that agent not found raises RuntimeError""" + agent = create_test_agent("Agent1") + agent.name = "Agent1" + + with pytest.raises(RuntimeError, match="Error finding agent"): + find_agent_by_name(agents=[agent], agent_name="NonExistent") + + +def test_find_agent_by_name_agent_with_name_attribute(): + """Test finding agent when agent has name attribute""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("TargetAgent") + + # Set the name attribute that find_agent_by_name looks for + agent1.name = "Agent1" + agent2.name = "TargetAgent" + + result = find_agent_by_name( + agents=[agent1, agent2], + agent_name="TargetAgent" + ) + + assert result == agent2 diff --git a/tests/structs/test_ma_utils.py b/tests/structs/test_ma_utils.py new file mode 100644 index 00000000..56fe06e8 --- /dev/null +++ b/tests/structs/test_ma_utils.py @@ -0,0 +1,174 @@ +import pytest +from swarms.structs.ma_utils import ( + list_all_agents, + set_random_models_for_agents, + create_agent_map, +) +from swarms.structs.agent import Agent +from swarms.structs.conversation import Conversation + + +def create_test_agent(name: str, description: str = "Test agent") -> Agent: + """Create a real Agent instance for testing""" + return Agent( + agent_name=name, + agent_description=description, + system_prompt=f"You are {name}, a helpful test assistant.", + model_name="gpt-4o-mini", + max_loops=1, + verbose=False, + ) + + +def test_list_all_agents_basic(): + """Test basic listing of agents""" + agent1 = create_test_agent("Agent1", "First agent") + agent2 = create_test_agent("Agent2", "Second agent") + + result = list_all_agents([agent1, agent2], name="Test Team") + + assert "Test Team" in result + assert "Total Agents: 2" in result + assert "Agent1" in result + assert "Agent2" in result + + +def test_list_all_agents_with_description(): + """Test listing agents with team description""" + agent = create_test_agent("TestAgent", "Test description") + + result = list_all_agents( + [agent], + name="My Team", + description="A great team" + ) + + assert "My Team" in result + assert "A great team" in result + + +def test_list_all_agents_with_conversation(): + """Test adding agents to conversation""" + agent = create_test_agent("Agent", "Desc") + + conversation = Conversation() + + result = list_all_agents( + [agent], + conversation=conversation, + add_to_conversation=True + ) + + assert result is None + # Conversation should have content added + assert len(conversation.conversation_history) > 0 + + +def test_list_all_agents_fallback_to_name(): + """Test that agent name uses agent_name attribute""" + agent = create_test_agent("TestName", "Test description") + + result = list_all_agents([agent]) + assert "TestName" in result + + +def test_list_all_agents_fallback_to_system_prompt(): + """Test that description uses agent_description""" + agent = create_test_agent("Agent", "Agent description here") + + result = list_all_agents([agent]) + assert "Agent" in result + + +def test_set_random_models_for_agents_with_none(): + """Test setting random model when agents is None""" + result = set_random_models_for_agents(agents=None) + assert isinstance(result, str) + assert len(result) > 0 + + +def test_set_random_models_for_agents_with_list(): + """Test setting random models for list of agents""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + agents = [agent1, agent2] + + result = set_random_models_for_agents(agents=agents) + + assert result == agents + assert hasattr(agent1, 'model_name') + assert hasattr(agent2, 'model_name') + + +def test_set_random_models_for_agents_with_single_agent(): + """Test setting random model for single agent""" + agent = create_test_agent("SingleAgent") + + result = set_random_models_for_agents(agents=agent) + + assert result == agent + assert hasattr(agent, 'model_name') + + +def test_set_random_models_for_agents_custom_models(): + """Test setting random models with custom model list""" + agent = create_test_agent("CustomAgent") + custom_models = ["model1", "model2", "model3"] + + result = set_random_models_for_agents(agents=agent, model_names=custom_models) + + assert hasattr(agent, 'model_name') + assert agent.model_name in custom_models + + +def test_create_agent_map_basic(): + """Test creating agent map with basic agents""" + agent1 = create_test_agent("Agent1") + agent2 = create_test_agent("Agent2") + + result = create_agent_map([agent1, agent2]) + + assert "Agent1" in result + assert "Agent2" in result + assert result["Agent1"] == agent1 + assert result["Agent2"] == agent2 + + +def test_create_agent_map_with_real_agents(): + """Test creating agent map with real Agent instances""" + agent1 = create_test_agent("RealAgent1") + agent2 = create_test_agent("RealAgent2") + + result = create_agent_map([agent1, agent2]) + + assert "RealAgent1" in result + assert "RealAgent2" in result + assert result["RealAgent1"] == agent1 + assert result["RealAgent2"] == agent2 + + +def test_create_agent_map_empty_raises_error(): + """Test that empty agent list raises ValueError""" + with pytest.raises(ValueError, match="Agents list cannot be empty"): + create_agent_map([]) + + +def test_create_agent_map_caching(): + """Test that agent map is cached for identical inputs""" + agent = create_test_agent("CachedAgent") + + agents = [agent] + result1 = create_agent_map(agents) + result2 = create_agent_map(agents) + + # Should return the same cached result + assert result1 == result2 + + +def test_list_all_agents_no_collaboration_prompt(): + """Test list_all_agents without collaboration prompt""" + agent = create_test_agent("Agent", "Description") + + result = list_all_agents([agent], add_collaboration_prompt=False) + + assert "Agent" in result diff --git a/tests/structs/test_multi_agent_debates.py b/tests/structs/test_multi_agent_debates.py new file mode 100644 index 00000000..ea13c1b4 --- /dev/null +++ b/tests/structs/test_multi_agent_debates.py @@ -0,0 +1,19 @@ +import pytest + + +def test_multi_agent_debates_module_can_be_imported(): + """Test that multi_agent_debates module can be imported""" + try: + from swarms.structs import multi_agent_debates + assert multi_agent_debates is not None + except ImportError: + pytest.skip("Module has import dependencies") + + +def test_multi_agent_debates_class_exists(): + """Test that MultiAgentDebate class exists""" + try: + from swarms.structs.multi_agent_debates import MultiAgentDebate + assert MultiAgentDebate is not None + except (ImportError, AttributeError): + pytest.skip("Class not available or has dependencies") diff --git a/tests/structs/test_multi_model_gpu_manager.py b/tests/structs/test_multi_model_gpu_manager.py new file mode 100644 index 00000000..b3da6ead --- /dev/null +++ b/tests/structs/test_multi_model_gpu_manager.py @@ -0,0 +1,19 @@ +import pytest + + +def test_multi_model_gpu_manager_module_can_be_imported(): + """Test that multi_model_gpu_manager module can be imported""" + try: + from swarms.structs import multi_model_gpu_manager + assert multi_model_gpu_manager is not None + except ImportError: + pytest.skip("Module has import dependencies or GPU requirements") + + +def test_multi_model_gpu_manager_class_exists(): + """Test that MultiModelGPUManager class exists""" + try: + from swarms.structs.multi_model_gpu_manager import MultiModelGPUManager + assert MultiModelGPUManager is not None + except (ImportError, AttributeError): + pytest.skip("Class not available or has GPU dependencies") diff --git a/tests/structs/test_remaining_modules.py b/tests/structs/test_remaining_modules.py new file mode 100644 index 00000000..6ebb8605 --- /dev/null +++ b/tests/structs/test_remaining_modules.py @@ -0,0 +1,82 @@ +import pytest + + +def test_heavy_swarm_module_imports(): + """Test that heavy_swarm module can be imported""" + try: + from swarms.structs import heavy_swarm + assert heavy_swarm is not None + except ImportError: + pytest.skip("heavy_swarm module not found or contains import errors") + + +def test_hierarchical_structured_communication_framework_module_imports(): + """Test that hierarchical_structured_communication_framework module can be imported""" + try: + from swarms.structs import hierarchical_structured_communication_framework + assert hierarchical_structured_communication_framework is not None + except ImportError: + pytest.skip("Module not found or contains import errors") + + +def test_multi_agent_debates_module_imports(): + """Test that multi_agent_debates module can be imported""" + try: + from swarms.structs import multi_agent_debates + assert multi_agent_debates is not None + except ImportError: + pytest.skip("Module not found or contains import errors") + + +def test_multi_model_gpu_manager_module_imports(): + """Test that multi_model_gpu_manager module can be imported""" + try: + from swarms.structs import multi_model_gpu_manager + assert multi_model_gpu_manager is not None + except ImportError: + pytest.skip("Module not found or contains import errors") + + +def test_social_algorithms_module_imports(): + """Test that social_algorithms module can be imported""" + try: + from swarms.structs import social_algorithms + assert social_algorithms is not None + except ImportError: + pytest.skip("Module not found or contains import errors") + + +def test_swarm_templates_module_imports(): + """Test that swarm_templates module can be imported""" + try: + from swarms.structs import swarm_templates + assert swarm_templates is not None + except ImportError: + pytest.skip("Module not found or contains import errors") + + +def test_swarming_architectures_module_imports(): + """Test that swarming_architectures module can be imported""" + try: + from swarms.structs import swarming_architectures + assert swarming_architectures is not None + except ImportError: + pytest.skip("Module not found or contains import errors") + + +def test_various_alt_swarms_module_imports(): + """Test that various_alt_swarms module can be imported""" + try: + from swarms.structs import various_alt_swarms + assert various_alt_swarms is not None + except ImportError: + pytest.skip("Module not found or contains import errors") + + +def test_modules_contain_classes_placeholder(): + """ + Placeholder test noting these modules primarily contain class definitions. + Class-based tests require more complex setup with mocking and instance creation. + Future work: Add comprehensive class-based tests. + """ + assert True diff --git a/tests/structs/test_safe_loading.py b/tests/structs/test_safe_loading.py new file mode 100644 index 00000000..cdfbfbc7 --- /dev/null +++ b/tests/structs/test_safe_loading.py @@ -0,0 +1,328 @@ +import pytest +import json +import os +import tempfile +from datetime import datetime +from uuid import UUID, uuid4 +from swarms.structs.safe_loading import ( + SafeLoaderUtils, + SafeStateManager, +) + + +# Test SafeLoaderUtils.is_class_instance +def test_is_class_instance_with_custom_class(): + """Test that is_class_instance detects custom class instances""" + class CustomClass: + def __init__(self): + self.value = 42 + + obj = CustomClass() + assert SafeLoaderUtils.is_class_instance(obj) is True + + +def test_is_class_instance_with_none(): + """Test that is_class_instance returns False for None""" + assert SafeLoaderUtils.is_class_instance(None) is False + + +def test_is_class_instance_with_builtin_types(): + """Test that is_class_instance returns False for built-in types""" + assert SafeLoaderUtils.is_class_instance(42) is False + assert SafeLoaderUtils.is_class_instance("string") is False + assert SafeLoaderUtils.is_class_instance([1, 2, 3]) is False + assert SafeLoaderUtils.is_class_instance({"key": "value"}) is False + assert SafeLoaderUtils.is_class_instance(True) is False + + +def test_is_class_instance_with_class_itself(): + """Test that is_class_instance returns False for class itself""" + class CustomClass: + pass + + assert SafeLoaderUtils.is_class_instance(CustomClass) is False + + +# Test SafeLoaderUtils.is_safe_type +def test_is_safe_type_with_basic_types(): + """Test that is_safe_type returns True for basic safe types""" + assert SafeLoaderUtils.is_safe_type(None) is True + assert SafeLoaderUtils.is_safe_type(True) is True + assert SafeLoaderUtils.is_safe_type(42) is True + assert SafeLoaderUtils.is_safe_type(3.14) is True + assert SafeLoaderUtils.is_safe_type("string") is True + + +def test_is_safe_type_with_datetime(): + """Test that is_safe_type returns True for datetime""" + dt = datetime.now() + assert SafeLoaderUtils.is_safe_type(dt) is True + + +def test_is_safe_type_with_uuid(): + """Test that is_safe_type returns True for UUID""" + uid = uuid4() + assert SafeLoaderUtils.is_safe_type(uid) is True + + +def test_is_safe_type_with_safe_list(): + """Test that is_safe_type returns True for list of safe types""" + assert SafeLoaderUtils.is_safe_type([1, 2, 3]) is True + assert SafeLoaderUtils.is_safe_type(["a", "b", "c"]) is True + + +def test_is_safe_type_with_unsafe_list(): + """Test that is_safe_type returns False for list with unsafe types""" + class CustomClass: + pass + + assert SafeLoaderUtils.is_safe_type([CustomClass()]) is False + + +def test_is_safe_type_with_safe_dict(): + """Test that is_safe_type returns True for dict with safe types""" + assert SafeLoaderUtils.is_safe_type({"key": "value"}) is True + assert SafeLoaderUtils.is_safe_type({"num": 42, "str": "hello"}) is True + + +def test_is_safe_type_with_unsafe_dict(): + """Test that is_safe_type returns False for dict with unsafe types""" + class CustomClass: + pass + + assert SafeLoaderUtils.is_safe_type({"obj": CustomClass()}) is False + + +def test_is_safe_type_with_non_string_dict_keys(): + """Test that is_safe_type returns False for dict with non-string keys""" + assert SafeLoaderUtils.is_safe_type({1: "value"}) is False + + +# Test SafeLoaderUtils.get_class_attributes +def test_get_class_attributes_basic(): + """Test that get_class_attributes returns all attributes""" + class TestClass: + class_var = "class" + + def __init__(self): + self.instance_var = "instance" + + obj = TestClass() + attrs = SafeLoaderUtils.get_class_attributes(obj) + assert "class_var" in attrs + assert "instance_var" in attrs + + +def test_get_class_attributes_inheritance(): + """Test that get_class_attributes includes inherited attributes""" + class Parent: + parent_var = "parent" + + class Child(Parent): + child_var = "child" + + def __init__(self): + self.instance_var = "instance" + + obj = Child() + attrs = SafeLoaderUtils.get_class_attributes(obj) + assert "parent_var" in attrs + assert "child_var" in attrs + assert "instance_var" in attrs + + +# Test SafeLoaderUtils.create_state_dict +def test_create_state_dict_basic(): + """Test that create_state_dict creates dict of safe values""" + class TestClass: + def __init__(self): + self.safe_value = 42 + self.safe_string = "hello" + self._private = "private" + + obj = TestClass() + state = SafeLoaderUtils.create_state_dict(obj) + assert state["safe_value"] == 42 + assert state["safe_string"] == "hello" + assert "_private" not in state + + +def test_create_state_dict_skips_unsafe(): + """Test that create_state_dict skips unsafe types""" + class Inner: + pass + + class TestClass: + def __init__(self): + self.safe = 42 + self.unsafe = Inner() + + obj = TestClass() + state = SafeLoaderUtils.create_state_dict(obj) + assert "safe" in state + assert "unsafe" not in state + + +# Test SafeLoaderUtils.preserve_instances +def test_preserve_instances_basic(): + """Test that preserve_instances preserves class instances""" + class Inner: + def __init__(self): + self.value = 100 + + class Outer: + def __init__(self): + self.safe = 42 + self.instance = Inner() + + obj = Outer() + preserved = SafeLoaderUtils.preserve_instances(obj) + assert "instance" in preserved + assert isinstance(preserved["instance"], Inner) + assert "safe" not in preserved + + +def test_preserve_instances_skips_private(): + """Test that preserve_instances skips private attributes""" + class Inner: + pass + + class Outer: + def __init__(self): + self._private_instance = Inner() + self.public_instance = Inner() + + obj = Outer() + preserved = SafeLoaderUtils.preserve_instances(obj) + assert "_private_instance" not in preserved + assert "public_instance" in preserved + + +# Test SafeStateManager.save_state and load_state +def test_save_and_load_state(): + """Test that save_state and load_state work correctly""" + class TestClass: + def __init__(self): + self.value = 42 + self.text = "hello" + + obj = TestClass() + + with tempfile.TemporaryDirectory() as tmpdir: + file_path = os.path.join(tmpdir, "state.json") + + # Save state + SafeStateManager.save_state(obj, file_path) + + # Verify file exists + assert os.path.exists(file_path) + + # Load state into new object + new_obj = TestClass() + new_obj.value = 0 # Change value to test loading + new_obj.text = "" + + SafeStateManager.load_state(new_obj, file_path) + + assert new_obj.value == 42 + assert new_obj.text == "hello" + + +def test_save_state_creates_directory(): + """Test that save_state creates directory if it doesn't exist""" + class TestClass: + def __init__(self): + self.value = 42 + + obj = TestClass() + + with tempfile.TemporaryDirectory() as tmpdir: + file_path = os.path.join(tmpdir, "subdir", "state.json") + + SafeStateManager.save_state(obj, file_path) + + assert os.path.exists(file_path) + + +def test_load_state_preserves_instances(): + """Test that load_state preserves existing class instances""" + class Inner: + def __init__(self, val): + self.val = val + + class Outer: + def __init__(self): + self.safe = 42 + self.instance = Inner(100) + + obj = Outer() + + with tempfile.TemporaryDirectory() as tmpdir: + file_path = os.path.join(tmpdir, "state.json") + + # Save state + SafeStateManager.save_state(obj, file_path) + + # Create new object with different values + new_obj = Outer() + new_obj.safe = 0 + original_instance = new_obj.instance + + # Load state + SafeStateManager.load_state(new_obj, file_path) + + # Safe value should be updated + assert new_obj.safe == 42 + + # Instance should be preserved (same object) + assert new_obj.instance is original_instance + assert new_obj.instance.val == 100 + + +def test_load_state_file_not_found(): + """Test that load_state raises FileNotFoundError for missing file""" + class TestClass: + pass + + obj = TestClass() + + with pytest.raises(FileNotFoundError, match="State file not found"): + SafeStateManager.load_state(obj, "/nonexistent/path.json") + + +def test_save_state_with_datetime(): + """Test that save_state handles datetime objects""" + class TestClass: + def __init__(self): + self.created_at = datetime(2024, 1, 1, 12, 0, 0) + + obj = TestClass() + + with tempfile.TemporaryDirectory() as tmpdir: + file_path = os.path.join(tmpdir, "state.json") + + # Should not raise an error + SafeStateManager.save_state(obj, file_path) + assert os.path.exists(file_path) + + +def test_save_state_with_uuid(): + """Test that save_state handles UUID objects""" + class TestClass: + def __init__(self): + self.id = uuid4() + + obj = TestClass() + + with tempfile.TemporaryDirectory() as tmpdir: + file_path = os.path.join(tmpdir, "state.json") + + # Should not raise an error + SafeStateManager.save_state(obj, file_path) + assert os.path.exists(file_path) + + +def test_is_safe_type_with_tuple(): + """Test that is_safe_type returns True for tuple of safe types""" + assert SafeLoaderUtils.is_safe_type((1, 2, 3)) is True + assert SafeLoaderUtils.is_safe_type(("a", "b")) is True diff --git a/tests/structs/test_social_algorithms.py b/tests/structs/test_social_algorithms.py new file mode 100644 index 00000000..fc186f13 --- /dev/null +++ b/tests/structs/test_social_algorithms.py @@ -0,0 +1,19 @@ +import pytest + + +def test_social_algorithms_module_can_be_imported(): + """Test that social_algorithms module can be imported""" + try: + from swarms.structs import social_algorithms + assert social_algorithms is not None + except ImportError: + pytest.skip("Module has import dependencies") + + +def test_social_algorithms_classes_exist(): + """Test that social algorithm classes exist""" + try: + from swarms.structs.social_algorithms import SocialSwarm + assert SocialSwarm is not None + except (ImportError, AttributeError): + pytest.skip("Classes not available or have dependencies") diff --git a/tests/structs/test_stopping_conditions.py b/tests/structs/test_stopping_conditions.py new file mode 100644 index 00000000..7a0c7cf2 --- /dev/null +++ b/tests/structs/test_stopping_conditions.py @@ -0,0 +1,194 @@ +import pytest +from swarms.structs.stopping_conditions import ( + check_done, + check_finished, + check_complete, + check_success, + check_failure, + check_error, + check_stopped, + check_cancelled, + check_exit, + check_end, + check_stopping_conditions, +) + + +def test_check_done_true(): + """Test check_done returns True when is in string""" + assert check_done("Task is ") is True + + +def test_check_done_false(): + """Test check_done returns False when is not in string""" + assert check_done("Task in progress") is False + + +def test_check_finished_true(): + """Test check_finished returns True when 'finished' is in string""" + assert check_finished("Task finished successfully") is True + + +def test_check_finished_false(): + """Test check_finished returns False when 'finished' is not in string""" + assert check_finished("Task in progress") is False + + +def test_check_complete_true(): + """Test check_complete returns True when 'complete' is in string""" + assert check_complete("Task is complete") is True + + +def test_check_complete_false(): + """Test check_complete returns False when 'complete' is not in string""" + assert check_complete("Task in progress") is False + + +def test_check_success_true(): + """Test check_success returns True when 'success' is in string""" + assert check_success("Task success") is True + + +def test_check_success_false(): + """Test check_success returns False when 'success' is not in string""" + assert check_success("Task failed") is False + + +def test_check_failure_true(): + """Test check_failure returns True when 'failure' is in string""" + assert check_failure("Task failure detected") is True + + +def test_check_failure_false(): + """Test check_failure returns False when 'failure' is not in string""" + assert check_failure("Task succeeded") is False + + +def test_check_error_true(): + """Test check_error returns True when 'error' is in string""" + assert check_error("An error occurred") is True + + +def test_check_error_false(): + """Test check_error returns False when 'error' is not in string""" + assert check_error("Everything is fine") is False + + +def test_check_stopped_true(): + """Test check_stopped returns True when 'stopped' is in string""" + assert check_stopped("Task was stopped") is True + + +def test_check_stopped_false(): + """Test check_stopped returns False when 'stopped' is not in string""" + assert check_stopped("Task is running") is False + + +def test_check_cancelled_true(): + """Test check_cancelled returns True when 'cancelled' is in string""" + assert check_cancelled("Task cancelled by user") is True + + +def test_check_cancelled_false(): + """Test check_cancelled returns False when 'cancelled' is not in string""" + assert check_cancelled("Task is running") is False + + +def test_check_exit_true(): + """Test check_exit returns True when 'exit' is in string""" + assert check_exit("Program will exit") is True + + +def test_check_exit_false(): + """Test check_exit returns False when 'exit' is not in string""" + assert check_exit("Task is running") is False + + +def test_check_end_true(): + """Test check_end returns True when 'end' is in string""" + assert check_end("This is the end") is True + + +def test_check_end_false(): + """Test check_end returns False when 'end' is not in string""" + assert check_end("Task is running") is False + + +def test_check_stopping_conditions_done(): + """Test check_stopping_conditions returns correct message for done""" + result = check_stopping_conditions("Task is ") + assert result == "Task is done" + + +def test_check_stopping_conditions_finished(): + """Test check_stopping_conditions returns correct message for finished""" + result = check_stopping_conditions("Task finished successfully") + assert result == "Task is finished" + + +def test_check_stopping_conditions_complete(): + """Test check_stopping_conditions returns correct message for complete""" + result = check_stopping_conditions("Task is complete") + assert result == "Task is complete" + + +def test_check_stopping_conditions_success(): + """Test check_stopping_conditions returns correct message for success""" + result = check_stopping_conditions("Task success") + assert result == "Task succeeded" + + +def test_check_stopping_conditions_failure(): + """Test check_stopping_conditions returns correct message for failure""" + result = check_stopping_conditions("Task failure") + assert result == "Task failed" + + +def test_check_stopping_conditions_error(): + """Test check_stopping_conditions returns correct message for error""" + result = check_stopping_conditions("An error occurred") + assert result == "Task encountered an error" + + +def test_check_stopping_conditions_stopped(): + """Test check_stopping_conditions returns correct message for stopped""" + result = check_stopping_conditions("Task was stopped") + assert result == "Task was stopped" + + +def test_check_stopping_conditions_cancelled(): + """Test check_stopping_conditions returns correct message for cancelled""" + result = check_stopping_conditions("Task was cancelled") + assert result == "Task was cancelled" + + +def test_check_stopping_conditions_exit(): + """Test check_stopping_conditions returns correct message for exit""" + result = check_stopping_conditions("Program will exit") + assert result == "Task exited" + + +def test_check_stopping_conditions_end(): + """Test check_stopping_conditions returns correct message for end""" + result = check_stopping_conditions("This is the end") + assert result == "Task ended" + + +def test_check_stopping_conditions_none(): + """Test check_stopping_conditions returns None when no condition is met""" + result = check_stopping_conditions("Task is running normally") + assert result is None + + +def test_check_stopping_conditions_priority(): + """Test that check_stopping_conditions returns first matching condition""" + # 'finished' appears before other conditions in the list, so it should match first + result = check_stopping_conditions("Task is finished and complete") + assert result == "Task is finished" + + +def test_check_stopping_conditions_case_sensitive(): + """Test that all checks are case-sensitive""" + assert check_done("DONE") is False # Should be + assert check_finished("FINISHED") is False # lowercase 'finished' required + assert check_complete("COMPLETE") is False # lowercase 'complete' required diff --git a/tests/structs/test_swarm_id.py b/tests/structs/test_swarm_id.py new file mode 100644 index 00000000..ec53d85f --- /dev/null +++ b/tests/structs/test_swarm_id.py @@ -0,0 +1,43 @@ +import pytest +from swarms.structs.swarm_id import swarm_id + + +def test_swarm_id_returns_string(): + """Test that swarm_id returns a string""" + result = swarm_id() + assert isinstance(result, str) + + +def test_swarm_id_starts_with_swarm(): + """Test that swarm_id starts with 'swarm-'""" + result = swarm_id() + assert result.startswith("swarm-") + + +def test_swarm_id_has_correct_format(): + """Test that swarm_id has correct format (swarm-{hex})""" + result = swarm_id() + parts = result.split("-", 1) + assert len(parts) == 2 + assert parts[0] == "swarm" + assert len(parts[1]) == 32 # UUID4 hex is 32 characters + + +def test_swarm_id_is_unique(): + """Test that swarm_id generates unique IDs""" + ids = [swarm_id() for _ in range(100)] + assert len(ids) == len(set(ids)) + + +def test_swarm_id_hex_characters(): + """Test that the hex part contains only valid hex characters""" + result = swarm_id() + hex_part = result.split("-", 1)[1] + assert all(c in "0123456789abcdef" for c in hex_part) + + +def test_swarm_id_no_hyphens_in_hex(): + """Test that hex part has no hyphens (uuid4().hex strips them)""" + result = swarm_id() + hex_part = result.split("-", 1)[1] + assert "-" not in hex_part diff --git a/tests/structs/test_swarm_rearrange_functions.py b/tests/structs/test_swarm_rearrange_functions.py new file mode 100644 index 00000000..a62b95da --- /dev/null +++ b/tests/structs/test_swarm_rearrange_functions.py @@ -0,0 +1,140 @@ +import pytest +from swarms.structs.swarm_rearrange import swarm_arrange +from swarms.structs.agent import Agent +from swarms.structs.swarm_router import SwarmRouter + + +def create_test_agent(name: str, description: str = "Test agent") -> Agent: + """Create a real Agent instance for testing""" + return Agent( + agent_name=name, + agent_description=description, + system_prompt=f"You are {name}, a helpful test assistant. Keep responses brief.", + model_name="gpt-4o-mini", + max_loops=1, + verbose=False, + ) + + +def create_test_swarm(name: str) -> SwarmRouter: + """Create a real SwarmRouter instance for testing""" + agent = create_test_agent(f"{name}_agent") + return SwarmRouter( + name=name, + description=f"Test swarm {name}", + agents=[agent], + swarm_type="SequentialWorkflow", + max_loops=1, + ) + + +def test_swarm_arrange_with_none_swarms(): + """Test swarm_arrange with None swarms parameter""" + result = swarm_arrange( + name="Test", + swarms=None, + flow="A->B", + task="Test task" + ) + # Should handle None swarms gracefully + assert result is not None + + +def test_swarm_arrange_returns_string(): + """Test that swarm_arrange returns a string""" + swarm = create_test_swarm("SwarmA") + + result = swarm_arrange( + name="TestArrange", + swarms=[swarm], + flow="SwarmA", + task="What is 2+2?" + ) + assert isinstance(result, str) + + +def test_swarm_arrange_with_empty_swarms_list(): + """Test swarm_arrange with empty swarms list""" + result = swarm_arrange( + name="Test", + swarms=[], + flow="A->B", + task="Test task" + ) + # Should handle empty swarms + assert isinstance(result, str) + + +def test_swarm_arrange_with_custom_name(): + """Test swarm_arrange with custom name""" + swarm = create_test_swarm("SwarmA") + + result = swarm_arrange( + name="CustomName", + description="Custom description", + swarms=[swarm], + flow="SwarmA", + task="Say hello" + ) + assert result is not None + + +def test_swarm_arrange_with_json_output_type(): + """Test swarm_arrange with json output type""" + swarm = create_test_swarm("SwarmA") + + result = swarm_arrange( + name="Test", + swarms=[swarm], + output_type="json", + flow="SwarmA", + task="What is 1+1?" + ) + assert isinstance(result, str) + + +def test_swarm_arrange_with_default_parameters(): + """Test swarm_arrange with mostly default parameters""" + result = swarm_arrange() + assert isinstance(result, str) + + +def test_swarm_arrange_with_multiple_swarms(): + """Test swarm_arrange with multiple swarms""" + swarm1 = create_test_swarm("SwarmA") + swarm2 = create_test_swarm("SwarmB") + + result = swarm_arrange( + name="MultiSwarm", + swarms=[swarm1, swarm2], + flow="SwarmA->SwarmB", + task="Complete this simple task" + ) + assert isinstance(result, str) + + +def test_swarm_arrange_with_sequential_flow(): + """Test swarm_arrange with sequential flow pattern""" + swarm1 = create_test_swarm("First") + swarm2 = create_test_swarm("Second") + + result = swarm_arrange( + name="Sequential", + swarms=[swarm1, swarm2], + flow="First->Second", + task="Process this step by step" + ) + assert isinstance(result, str) + + +def test_swarm_arrange_with_kwargs(): + """Test swarm_arrange with additional kwargs""" + swarm = create_test_swarm("SwarmA") + + result = swarm_arrange( + name="Test", + swarms=[swarm], + flow="SwarmA", + task="Simple test" + ) + assert isinstance(result, str) diff --git a/tests/structs/test_swarm_templates.py b/tests/structs/test_swarm_templates.py new file mode 100644 index 00000000..4f6c49f8 --- /dev/null +++ b/tests/structs/test_swarm_templates.py @@ -0,0 +1,19 @@ +import pytest + + +def test_swarm_templates_module_can_be_imported(): + """Test that swarm_templates module can be imported""" + try: + from swarms.structs import swarm_templates + assert swarm_templates is not None + except ImportError: + pytest.skip("Module has import dependencies") + + +def test_swarm_templates_classes_exist(): + """Test that swarm template classes exist""" + try: + from swarms.structs.swarm_templates import SwarmTemplate + assert SwarmTemplate is not None + except (ImportError, AttributeError): + pytest.skip("Classes not available or have dependencies") diff --git a/tests/structs/test_swarming_architectures.py b/tests/structs/test_swarming_architectures.py new file mode 100644 index 00000000..64ebcb56 --- /dev/null +++ b/tests/structs/test_swarming_architectures.py @@ -0,0 +1,188 @@ +import pytest +from unittest.mock import Mock +from swarms.structs.swarming_architectures import ( + circular_swarm, + grid_swarm, + linear_swarm, + star_swarm, + mesh_swarm, + pyramid_swarm, + fibonacci_swarm, + prime_swarm, + power_swarm, + log_swarm, + exponential_swarm, + geometric_swarm, + harmonic_swarm, + staircase_swarm, + sigmoid_swarm, + sinusoidal_swarm, + one_to_one, +) + + +def test_circular_swarm_with_single_agent(): + """Test circular_swarm with a single agent""" + agent = Mock() + agent.run.return_value = "Response" + + result = circular_swarm(agents=[agent], tasks=["Task 1"]) + assert result is not None + + +def test_grid_swarm_with_agents(): + """Test grid_swarm with multiple agents""" + agents = [Mock() for _ in range(4)] + for agent in agents: + agent.run.return_value = "Response" + + result = grid_swarm(agents=agents, tasks=["Task 1", "Task 2"]) + assert result is not None + + +def test_linear_swarm_with_tasks(): + """Test linear_swarm with sequential tasks""" + agents = [Mock(), Mock()] + for agent in agents: + agent.run.return_value = "Response" + + result = linear_swarm(agents=agents, tasks=["Task 1"]) + assert result is not None + + +def test_star_swarm_basic(): + """Test star_swarm with central coordinator""" + agents = [Mock() for _ in range(3)] + for agent in agents: + agent.run.return_value = "Response" + + result = star_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_mesh_swarm_basic(): + """Test mesh_swarm with interconnected agents""" + agents = [Mock(), Mock()] + for agent in agents: + agent.run.return_value = "Response" + + result = mesh_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_pyramid_swarm_basic(): + """Test pyramid_swarm hierarchical structure""" + agents = [Mock() for _ in range(3)] + for agent in agents: + agent.run.return_value = "Response" + + result = pyramid_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_fibonacci_swarm_basic(): + """Test fibonacci_swarm with fibonacci sequence""" + agents = [Mock() for _ in range(5)] + for agent in agents: + agent.run.return_value = "Response" + + result = fibonacci_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_prime_swarm_basic(): + """Test prime_swarm with prime number sequence""" + agents = [Mock() for _ in range(5)] + for agent in agents: + agent.run.return_value = "Response" + + result = prime_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_power_swarm_basic(): + """Test power_swarm with power sequence""" + agents = [Mock() for _ in range(4)] + for agent in agents: + agent.run.return_value = "Response" + + result = power_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_log_swarm_basic(): + """Test log_swarm with logarithmic sequence""" + agents = [Mock() for _ in range(3)] + for agent in agents: + agent.run.return_value = "Response" + + result = log_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_exponential_swarm_basic(): + """Test exponential_swarm with exponential growth""" + agents = [Mock() for _ in range(4)] + for agent in agents: + agent.run.return_value = "Response" + + result = exponential_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_geometric_swarm_basic(): + """Test geometric_swarm with geometric sequence""" + agents = [Mock() for _ in range(4)] + for agent in agents: + agent.run.return_value = "Response" + + result = geometric_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_harmonic_swarm_basic(): + """Test harmonic_swarm with harmonic sequence""" + agents = [Mock() for _ in range(3)] + for agent in agents: + agent.run.return_value = "Response" + + result = harmonic_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_sigmoid_swarm_basic(): + """Test sigmoid_swarm with sigmoid curve""" + agents = [Mock() for _ in range(3)] + for agent in agents: + agent.run.return_value = "Response" + + result = sigmoid_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_sinusoidal_swarm_basic(): + """Test sinusoidal_swarm with sinusoidal pattern""" + agents = [Mock() for _ in range(3)] + for agent in agents: + agent.run.return_value = "Response" + + result = sinusoidal_swarm(agents=agents, tasks=["Task"]) + assert result is not None + + +def test_circular_swarm_returns_result(): + """Test that circular_swarm returns a result""" + agent = Mock() + agent.run.return_value = "Test response" + + result = circular_swarm(agents=[agent], tasks=["Task"]) + assert result is not None + + +def test_linear_swarm_returns_result(): + """Test that linear_swarm returns a result""" + agent = Mock() + agent.run.return_value = "Test response" + + result = linear_swarm(agents=[agent], tasks=["Task"]) + assert result is not None diff --git a/tests/structs/test_utils.py b/tests/structs/test_utils.py new file mode 100644 index 00000000..92ffbca7 --- /dev/null +++ b/tests/structs/test_utils.py @@ -0,0 +1,164 @@ +import pytest +from swarms.structs.utils import find_agent_by_id, find_agent_by_name +from swarms.structs.agent import Agent + + +def create_test_agent(name: str, agent_id: str = None, description: str = "Test agent") -> Agent: + """Create a real Agent instance for testing""" + agent = Agent( + agent_name=name, + agent_description=description, + system_prompt=f"You are {name}, a helpful test assistant. Keep responses brief.", + model_name="gpt-4o-mini", + max_loops=1, + verbose=False, + ) + if agent_id: + agent.id = agent_id + # Set name attribute for find_agent_by_name + agent.name = name + return agent + + +def test_find_agent_by_id_found(): + """Test finding agent by ID when agent exists""" + agent1 = create_test_agent("Agent One", "agent-1") + agent2 = create_test_agent("Agent Two", "agent-2") + + agents = [agent1, agent2] + + result = find_agent_by_id("agent-1", agents) + assert result == agent1 + + +def test_find_agent_by_id_not_found(): + """Test finding agent by ID when agent does not exist""" + agent1 = create_test_agent("Agent One", "agent-1") + + agents = [agent1] + + result = find_agent_by_id("agent-99", agents) + assert result is None + + +def test_find_agent_by_id_with_task(): + """Test finding agent by ID and running a task""" + agent = create_test_agent("Agent One", "agent-1") + + agents = [agent] + + result = find_agent_by_id("agent-1", agents, task="What is 2+2?") + assert result is not None + assert len(str(result)) > 0 + + +def test_find_agent_by_id_with_task_and_kwargs(): + """Test finding agent by ID and running a task with kwargs""" + agent = create_test_agent("Agent One", "agent-1") + + agents = [agent] + + result = find_agent_by_id( + agent_id="agent-1", agents=agents, task="Say hello" + ) + assert result is not None + + +def test_find_agent_by_id_empty_list(): + """Test finding agent by ID in empty list""" + result = find_agent_by_id("agent-1", []) + assert result is None + + +def test_find_agent_by_id_exception_handling(): + """Test that find_agent_by_id handles task execution""" + agent = create_test_agent("Agent One", "agent-1") + + agents = [agent] + + # Should execute successfully with real agent + result = find_agent_by_id("agent-1", agents, task="What is the capital of France?") + assert result is not None + + +def test_find_agent_by_name_found(): + """Test finding agent by name when agent exists""" + agent1 = create_test_agent("Agent One", "agent-1") + agent2 = create_test_agent("Agent Two", "agent-2") + + agents = [agent1, agent2] + + result = find_agent_by_name("Agent One", agents) + assert result == agent1 + + +def test_find_agent_by_name_not_found(): + """Test finding agent by name when agent does not exist""" + agent1 = create_test_agent("Agent One", "agent-1") + + agents = [agent1] + + result = find_agent_by_name("Agent Ninety Nine", agents) + assert result is None + + +def test_find_agent_by_name_with_task(): + """Test finding agent by name and running a task""" + agent = create_test_agent("Agent One", "agent-1") + + agents = [agent] + + result = find_agent_by_name("Agent One", agents, task="What is 3+3?") + assert result is not None + assert len(str(result)) > 0 + + +def test_find_agent_by_name_with_task_and_kwargs(): + """Test finding agent by name and running a task with kwargs""" + agent = create_test_agent("Agent One", "agent-1") + + agents = [agent] + + result = find_agent_by_name( + agent_name="Agent One", agents=agents, task="Say goodbye" + ) + assert result is not None + + +def test_find_agent_by_name_empty_list(): + """Test finding agent by name in empty list""" + result = find_agent_by_name("Agent One", []) + assert result is None + + +def test_find_agent_by_name_exception_handling(): + """Test that find_agent_by_name handles task execution""" + agent = create_test_agent("Agent One", "agent-1") + + agents = [agent] + + # Should execute successfully with real agent + result = find_agent_by_name("Agent One", agents, task="List 3 colors") + assert result is not None + + +def test_find_agent_by_id_multiple_agents(): + """Test finding correct agent by ID when multiple agents exist""" + agents = [] + for i in range(10): + agent = create_test_agent(f"Agent {i}", f"agent-{i}") + agents.append(agent) + + result = find_agent_by_id("agent-5", agents) + assert result.id == "agent-5" + + +def test_find_agent_by_name_multiple_agents(): + """Test finding correct agent by name when multiple agents exist""" + agents = [] + for i in range(10): + agent = create_test_agent(f"Agent {i}", f"agent-{i}") + agents.append(agent) + + result = find_agent_by_name("Agent 5", agents) + assert result.name == "Agent 5" diff --git a/tests/structs/test_various_alt_swarms.py b/tests/structs/test_various_alt_swarms.py new file mode 100644 index 00000000..55c9d6a6 --- /dev/null +++ b/tests/structs/test_various_alt_swarms.py @@ -0,0 +1,19 @@ +import pytest + + +def test_various_alt_swarms_module_can_be_imported(): + """Test that various_alt_swarms module can be imported""" + try: + from swarms.structs import various_alt_swarms + assert various_alt_swarms is not None + except ImportError: + pytest.skip("Module has import dependencies") + + +def test_various_alt_swarms_classes_exist(): + """Test that alternative swarm classes exist""" + try: + from swarms.structs.various_alt_swarms import VariousAltSwarm + assert VariousAltSwarm is not None + except (ImportError, AttributeError): + pytest.skip("Classes not available or have dependencies")