import os import shutil import tempfile from pathlib import Path from unittest import mock import pytest from click.testing import CliRunner from crewai.cli.create_crew import create_crew, create_folder_structure @pytest.fixture def runner(): return CliRunner() @pytest.fixture def temp_dir(): temp_path = tempfile.mkdtemp() yield temp_path shutil.rmtree(temp_path) def test_create_folder_structure_strips_single_trailing_slash(): with tempfile.TemporaryDirectory() as temp_dir: os.chdir(temp_dir) folder_path, folder_name, class_name = create_folder_structure("hello/") assert folder_name == "hello" assert class_name == "Hello" assert folder_path.name == "hello" assert folder_path.exists() def test_create_folder_structure_strips_multiple_trailing_slashes(): with tempfile.TemporaryDirectory() as temp_dir: os.chdir(temp_dir) folder_path, folder_name, class_name = create_folder_structure("hello///") assert folder_name == "hello" assert class_name == "Hello" assert folder_path.name == "hello" assert folder_path.exists() def test_create_folder_structure_handles_complex_name_with_trailing_slash(): with tempfile.TemporaryDirectory() as temp_dir: os.chdir(temp_dir) folder_path, folder_name, class_name = create_folder_structure("my-awesome_project/") assert folder_name == "my_awesome_project" assert class_name == "MyAwesomeProject" assert folder_path.name == "my_awesome_project" assert folder_path.exists() def test_create_folder_structure_normal_name_unchanged(): with tempfile.TemporaryDirectory() as temp_dir: os.chdir(temp_dir) folder_path, folder_name, class_name = create_folder_structure("hello") assert folder_name == "hello" assert class_name == "Hello" assert folder_path.name == "hello" assert folder_path.exists() def test_create_folder_structure_with_parent_folder(): with tempfile.TemporaryDirectory() as temp_dir: os.chdir(temp_dir) parent_path = Path(temp_dir) / "parent" parent_path.mkdir() folder_path, folder_name, class_name = create_folder_structure("child/", parent_folder=parent_path) assert folder_name == "child" assert class_name == "Child" assert folder_path.name == "child" assert folder_path.parent == parent_path assert folder_path.exists() @mock.patch("crewai.cli.create_crew.copy_template") @mock.patch("crewai.cli.create_crew.write_env_file") @mock.patch("crewai.cli.create_crew.load_env_vars") def test_create_crew_with_trailing_slash_creates_valid_project(mock_load_env, mock_write_env, mock_copy_template, temp_dir): mock_load_env.return_value = {} with tempfile.TemporaryDirectory() as work_dir: os.chdir(work_dir) create_crew("test-project/", skip_provider=True) project_path = Path(work_dir) / "test_project" assert project_path.exists() assert (project_path / "src" / "test_project").exists() mock_copy_template.assert_called() copy_calls = mock_copy_template.call_args_list for call in copy_calls: args = call[0] if len(args) >= 5: folder_name_arg = args[4] assert not folder_name_arg.endswith("/"), f"folder_name should not end with slash: {folder_name_arg}" @mock.patch("crewai.cli.create_crew.copy_template") @mock.patch("crewai.cli.create_crew.write_env_file") @mock.patch("crewai.cli.create_crew.load_env_vars") def test_create_crew_with_multiple_trailing_slashes(mock_load_env, mock_write_env, mock_copy_template, temp_dir): mock_load_env.return_value = {} with tempfile.TemporaryDirectory() as work_dir: os.chdir(work_dir) create_crew("test-project///", skip_provider=True) project_path = Path(work_dir) / "test_project" assert project_path.exists() assert (project_path / "src" / "test_project").exists() @mock.patch("crewai.cli.create_crew.copy_template") @mock.patch("crewai.cli.create_crew.write_env_file") @mock.patch("crewai.cli.create_crew.load_env_vars") def test_create_crew_normal_name_still_works(mock_load_env, mock_write_env, mock_copy_template, temp_dir): mock_load_env.return_value = {} with tempfile.TemporaryDirectory() as work_dir: os.chdir(work_dir) create_crew("normal-project", skip_provider=True) project_path = Path(work_dir) / "normal_project" assert project_path.exists() assert (project_path / "src" / "normal_project").exists() def test_create_folder_structure_handles_spaces_and_dashes_with_slash(): with tempfile.TemporaryDirectory() as temp_dir: os.chdir(temp_dir) folder_path, folder_name, class_name = create_folder_structure("My Cool-Project/") assert folder_name == "my_cool_project" assert class_name == "MyCoolProject" assert folder_path.name == "my_cool_project" assert folder_path.exists() @mock.patch("crewai.cli.create_crew.copy_template") @mock.patch("crewai.cli.create_crew.write_env_file") @mock.patch("crewai.cli.create_crew.load_env_vars") def test_create_crew_with_parent_folder_and_trailing_slash(mock_load_env, mock_write_env, mock_copy_template, temp_dir): mock_load_env.return_value = {} with tempfile.TemporaryDirectory() as work_dir: parent_path = Path(work_dir) / "parent" parent_path.mkdir() create_crew("child-crew/", skip_provider=True, parent_folder=parent_path) crew_path = parent_path / "child_crew" assert crew_path.exists() assert not (crew_path / "src").exists()