diff --git a/tests/common.py b/tests/common.py index d860d60..69bdec3 100644 --- a/tests/common.py +++ b/tests/common.py @@ -17,9 +17,8 @@ def check_files_sequential(files: list[str]): expected_number += 1 def folder_is_empty(path): - return len(list(Path(path).iterdir())) != 0 + return len(list(Path(path).iterdir())) == 0 def folder_contains_files(path): files = [f.name for f in Path(path).rglob('*') if f.is_file()] return len(files) > 0 - diff --git a/tests/conftest.py b/tests/conftest.py index 4f29d39..e51676b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,40 +2,73 @@ import os from pathlib import Path +from types import SimpleNamespace import pytest def get_all_fixtures(): """Автоматически находим все файлы в директории тестовых данных.""" - st_files = Path(__file__).parent.glob("fixtures/*.st") - list_st_files = [f for f in st_files if f.is_file()] - # Добавляем файлы из внешнего списка, если он задан - file_list = os.getenv("TEMPLATES_LIST") - if file_list: - if not Path(file_list).is_file(): - raise FileNotFoundError(f"Файл списка дополнительных шаблонов не найден: {file_list}") - file_lines = Path(file_list).read_text(encoding='utf-8-sig').splitlines() - for item in file_lines: - item_path = Path(item).expanduser() if item.startswith("~") else Path(item) - if item_path.is_file(): - list_st_files.append(item_path) - else: - raise FileNotFoundError( - f"Файл шаблона из списка дополнительных файлов " - f"({Path(file_list).name}) не найден: {item_path}") + def from_dir(): + st_files = Path(__file__).parent.glob("fixtures/*.st") + list_st_files = [f for f in st_files if f.is_file()] + return list_st_files - return [pytest.param(e, id=e.name) for e in list_st_files] + def from_env(): + # Добавляем файлы из внешнего списка, если он задан + list_st_files = [] + file_list = os.getenv("TEMPLATES_LIST") + if file_list: + if not Path(file_list).is_file(): + raise FileNotFoundError(f"Файл списка дополнительных шаблонов не найден: {file_list}") + file_lines = Path(file_list).read_text(encoding='utf-8-sig').splitlines() + for item in file_lines: + item_path = Path(item).expanduser() if item.startswith("~") else Path(item) + if item_path.is_file(): + list_st_files.append(item_path) + else: + raise FileNotFoundError( + f"Файл шаблона из списка дополнительных файлов " + f"({Path(file_list).name}) не найден: {item_path}") + return list_st_files -@pytest.fixture(scope="class", name="test_file_path", params=get_all_fixtures()) -def test_data_path(request): - """Путь к каждому тестовому файлу.""" - return Path(request.param) + list_st_files = from_dir() + list_st_files.extend(from_env()) + + result = [] + for f in list_st_files: + if f.name.startswith("00-"): + spec = {"level": 0, "objects": 0} + elif f.name.startswith("01-"): + spec = {"level": 1, "objects": 1} + elif f.name.startswith("02-"): + spec = {"level": 1, "objects": 2} + else: + spec = {"level": None, "objects": None} + spec["name"] = f.name + spec["path"] = f + result.append(SimpleNamespace(**spec)) + + return [pytest.param(r, id=r.name) for r in result] + +@pytest.fixture(scope="class", params=get_all_fixtures()) +def file_path_spec(request): + return request.param @pytest.fixture(scope="class") -def test_data(test_file_path): +def file_path(file_path_spec): + """Путь к каждому тестовому файлу.""" + return file_path_spec.path + +@pytest.fixture(scope="class") +def file_data_spec(file_path_spec): """Данные каждого тестового файла.""" - file_data = test_file_path.read_text(encoding='utf-8-sig') - return file_data + file_path_spec.data = file_path_spec.path.read_text(encoding='utf-8-sig') + return file_path_spec + +@pytest.fixture(scope="class") +def file_data(file_data_spec): + """Данные каждого тестового файла.""" + return file_data_spec.data @pytest.fixture() def temp_src(tmp_path): diff --git a/tests/fixtures/02-one+.st b/tests/fixtures/02-one+.st new file mode 100644 index 0000000..e7c8e88 --- /dev/null +++ b/tests/fixtures/02-one+.st @@ -0,0 +1,8 @@ +{1, +{1, +{"Новый2",1,0,"",""}, +{0, +{"Еще что-то*",0,0,"*********"," "} +} +} +} \ No newline at end of file diff --git a/tests/fixtures/02-brackets.st b/tests/fixtures/09-brackets.st similarity index 100% rename from tests/fixtures/02-brackets.st rename to tests/fixtures/09-brackets.st diff --git a/tests/test_api.py b/tests/test_api.py index 1f4e6ff..c32b96b 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -3,19 +3,19 @@ from tests.common import folder_is_empty class Test_API: - def test_parse(self, test_file_path, temp_src): + def test_parse(self, file_path_spec, temp_src): """Тест библиотеки: парсинг""" - parse_to_src(str(test_file_path), str(temp_src)) - if test_file_path.stat().st_size > 6: - assert folder_is_empty(temp_src), f"Папка src пустая {temp_src}" + parse_to_src(str(file_path_spec.path), str(temp_src)) + if file_path_spec.level != 0: + assert not folder_is_empty(temp_src), f"Папка src пустая {temp_src}" else: - assert not folder_is_empty(temp_src), f"Для пустого файла что-то распарсилось {temp_src}" + assert folder_is_empty(temp_src), f"Для пустого файла что-то распарсилось {temp_src}" - def test_render(self, test_file_path, temp_src, tmp_path): + def test_render(self, file_path, temp_src, tmp_path): """Тест библиотеки: сборка""" - parse_to_src(str(test_file_path), str(temp_src)) + parse_to_src(str(file_path), str(temp_src)) temp_file = tmp_path / "output.st" render_from_src(str(temp_src), str(temp_file)) assert temp_file.exists(), f"Файл сборки не создан {temp_file}" - assert test_file_path.read_text(encoding='utf-8-sig') == temp_file.read_text(encoding='utf-8-sig'), 'Собранный файл не совпадает с исходным' \ No newline at end of file + assert file_path.read_text(encoding='utf-8-sig') == temp_file.read_text(encoding='utf-8-sig'), 'Собранный файл не совпадает с исходным' \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py index 39d6229..7bbaaf4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,7 +4,7 @@ from onec_codetemplate_parser.cli import app runner = CliRunner() -class Test_CLI: +class TestCLI: def test_help_command(self): """Тест вывода справки""" @@ -30,27 +30,27 @@ class Test_CLI: assert "path " in result.stdout, result.stdout assert "src " in result.stdout, result.stdout - def test_parse_command(self, test_file_path, temp_src): + def test_parse_command(self, file_path, temp_src): """Тест выполнения команды парсинга""" - result = runner.invoke(app, ["parse", str(test_file_path), str(temp_src)]) + result = runner.invoke(app, ["parse", str(file_path), str(temp_src)]) assert result.exit_code == 0, result.stdout + result.stderr - def test_render_command(self, test_file_path, temp_src, temp_output_st): + def test_render_command(self, file_path_spec, temp_src, temp_output_st): """Тест выполнения команды сборки""" - if test_file_path.name == '00-empty.st': - print("Пропускаем тест: папка SRC будет пустой, CLI не пройдет валидацию") - pytest.skip(reason="Пропускаем тест: папка SRC будет пустой, CLI не пройдет валидацию") + if file_path_spec.level == 0: + pytest.skip(reason=f"Пропускаем тест {file_path_spec.name}: папка SRC будет пустой, CLI не пройдет валидацию") return - runner.invoke(app, ["parse", str(test_file_path), str(temp_src)]) + file_path = file_path_spec.path + runner.invoke(app, ["parse", str(file_path), str(temp_src)]) result = runner.invoke(app, ["render", str(temp_output_st), str(temp_src)], catch_exceptions=False) assert result.exit_code == 0, result.stdout + result.stderr - assert test_file_path.read_text(encoding='utf-8-sig') == temp_output_st.read_text(encoding='utf-8-sig'), 'Собранный файл не совпадает с исходным' + assert file_path.read_text(encoding='utf-8-sig') == temp_output_st.read_text(encoding='utf-8-sig'), 'Собранный файл не совпадает с исходным' - def test_pretty_print_command(self, test_file_path): + def test_pretty_print_command(self, file_path_spec): """Тест выполнения команды парсинга""" - result = runner.invoke(app, ["pretty", str(test_file_path)]) + result = runner.invoke(app, ["pretty", str(file_path_spec.path)]) assert result.exit_code == 0, result.stdout + result.stderr - if test_file_path.name == '00-empty.st_': - assert len(result.stdout.splitlines()) == 1, result.stdout + result.stderr - else: + if file_path_spec.objects is None: assert len(result.stdout.splitlines()) > 1, result.stdout + result.stderr + else: + assert len(result.stdout.rstrip(). splitlines()) == file_path_spec.objects + 1, result.stdout + result.stderr diff --git a/tests/test_core.py b/tests/test_core.py index cd650fd..cd4202d 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,45 +1,60 @@ from onec_codetemplate_parser import repository from onec_codetemplate_parser.parser import parse -from tests.common import check_files_sequential +from tests.common import check_files_sequential, folder_contains_files, folder_is_empty class TestReadSkobkofile: - def test_00_test_file_exist(self, test_file_path): - assert test_file_path.exists() + def test_00_test_file_exist(self, file_path): + assert file_path.exists() - def test_01_parse_eq_compile(self, test_data): - root = parse(test_data) + def test_01_parse_eq_compile(self, file_data): + root = parse(file_data) new_data = root.compile() - assert new_data == test_data + assert new_data == file_data - def test_02_save_and_read(self, test_data, tmp_path): - root = parse(test_data) + def test_02_save_and_read(self, file_data, tmp_path): + root = parse(file_data) new_data = root.compile() tmp_file = tmp_path / 'tmp.st' tmp_file.write_text(new_data, encoding='utf-8-sig') new_data = tmp_file.read_text(encoding='utf-8-sig') - assert new_data == test_data + assert new_data == file_data class TestWriteToFiles: - def test_white_to_src(self, test_data, temp_src): - root = parse(test_data) + def test_white_to_src(self, file_data_spec, temp_src): + root = parse(file_data_spec.data) root.to_src(temp_src) - # TODO: добавить разные проверки для каждого файла + # файл не пустой - что-то в src должно быть + if file_data_spec.level is None or file_data_spec.level > 0: + assert folder_contains_files(temp_src), f"В папке нет ни одного файла {temp_src}" + assert not folder_is_empty(temp_src), f"Папка src пустая {temp_src}" - # assert folder_contains_files(temp_src), f"В папке нет ни одного файла {temp_src}" - # assert not folder_is_empty(temp_src), f"Папка src пустая {temp_src}" - - # Проверка: есть ли папки - # dirs = [p for p in temp_src.iterdir() if p.is_dir()] - # assert len(dirs) == 1, f"Ожидалась 1 папка в src, получили {len(dirs)}" - # assert temp_src / "001.0_Надулич" in dirs, f"Папка 001.0_Надулич не найдена в {temp_src}" - - d = temp_src / "001.0_Надулич" / "002.0_Комментарии" - if d.exists(): - subfiles = list(p.name for p in repository.dir_items(d)) + # объектов больше одного - всегда одна папка первого уровня + if file_data_spec.objects is None or file_data_spec.objects > 1: + dirs = [p for p in temp_src.iterdir() if p.is_dir()] + assert len(dirs) == 1, f"Ожидалась 1 папка в src, получили {len(dirs)}" + + # один объект - одна папка без файлов + if file_data_spec.objects == 1: + dirs = [p for p in next(temp_src.iterdir()).iterdir() if p.is_dir()] + assert len(dirs) == 0, f"Ожидалась что папок 2 уровня не будет в src/001, получили {len(dirs)}" + + files = [p for p in next(temp_src.iterdir()).iterdir() if p.is_file()] + assert len(files) == 1, f"Должен быть только .мета-файл в src/001 {temp_src}" + + if file_data_spec.objects == 2: + dirs = [p for p in next(temp_src.iterdir()).iterdir() if p.is_dir()] + assert len(dirs) == 0, f"Ожидалась 1 папка в src/001, получили {len(dirs)}" + + files = [p for p in next(temp_src.iterdir()).iterdir() if p.is_file()] + assert len(files) == 2, f"Ожидалось 2 файла в src/001(.meta и leaf), получили {len(files)}" + + if file_data_spec.name == "09-brackets": + folder = "001.0_Новый1" + assert (temp_src/folder).exists(), f"Папка первого уровня {folder} не найдена в {file_data_spec.name}" + subfiles = list(p.name for p in repository.dir_items(temp_src/folder)) check_files_sequential(subfiles) -