diff --git a/.github/workflows/check-same-version.yml b/.github/workflows/check-same-version.yml index c3cb65c..5e732b5 100644 --- a/.github/workflows/check-same-version.yml +++ b/.github/workflows/check-same-version.yml @@ -26,7 +26,7 @@ jobs: cache: 'pip' # optional and only works for Python projects - name: Run same-version - uses: willynilly/same-version@v5.1.0 + uses: willynilly/same-version@v6.0.0 with: fail_for_missing_file: false check_github_event: true diff --git a/CITATION.cff b/CITATION.cff index 8d5cf03..d1e862d 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -34,7 +34,7 @@ keywords: - metadata - harmonization license: Apache-2.0 -version: "5.1.0" +version: "6.0.0" date-released: "2025-06-10" references: - title: Citation File Format diff --git a/README.md b/README.md index 3c0e44b..188c091 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,9 @@ This workflow runs after the tag or release exists and can report problems, but - GitHub tag/release - `CITATION.cff` - `pyproject.toml` (Python) -- `setup.py` (Python) +- `setup.py` (Python, via static analysis only — no execution) - `setup.cfg` (Python) -- Python files with `__version__` assignment +- Python files with `__version__` assignment (static parsing only — must be assigned directly to a string literal) - `codemeta.json` (General) - `.zenodo.json` (General) - `package.json` (JS/TypeScript) @@ -259,7 +259,7 @@ jobs: python-version: ">=3.10" - name: Run same-version - uses: willynilly/same-version@v5.1.0 + uses: willynilly/same-version@v6.0.0 with: fail_for_missing_file: false check_github_event: true @@ -309,7 +309,7 @@ jobs: python-version: ">=3.10" - name: Run same-version - uses: willynilly/same-version@v5.1.0 + uses: willynilly/same-version@v6.0.0 with: fail_for_missing_file: false check_github_event: true @@ -347,7 +347,7 @@ Add to your `.pre-commit-config.yaml`: ```yaml repos: - repo: https://github.com/willynilly/same-version - rev: v5.1.0 # Use latest tag + rev: v6.0.0 # Use latest tag hooks: - id: same-version stages: [pre-commit, pre-push] diff --git a/example.pre-commit-config.yaml b/example.pre-commit-config.yaml index eb340b0..6698d6c 100644 --- a/example.pre-commit-config.yaml +++ b/example.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/willynilly/same-version - rev: v5.1.0 # Use latest tag + rev: v6.0.0 # Use latest tag hooks: - id: same-version stages: [pre-commit, pre-push] diff --git a/pyproject.toml b/pyproject.toml index 590c014..6dfafeb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "same-version" -version = "5.1.0" +version = "6.0.0" description = "Automatically ensures your software version metadata is consistent across key project files." readme = "README.md" requires-python = ">=3.10" diff --git a/src/same_version/extractors/py_ast_extractor.py b/src/same_version/extractors/py_ast_extractor.py index dfeb714..b05977c 100644 --- a/src/same_version/extractors/py_ast_extractor.py +++ b/src/same_version/extractors/py_ast_extractor.py @@ -7,7 +7,8 @@ class PyAstExtractor(FileExtractor): def _get_data(self) -> dict: data = {} + data['tree'] = None if self.target_file_path and self.target_exists: with open(self.target_file_path, 'r', encoding='utf-8') as f: - data['tree'] = ast.parse(f.read(), filename=self.target_file_path.resolve()) + data['tree'] = ast.parse(f.read(), filename=str(self.target_file_path.resolve())) return data \ No newline at end of file diff --git a/src/same_version/extractors/py_version_assignment_extractor.py b/src/same_version/extractors/py_version_assignment_extractor.py index 74e129a..f91ecec 100644 --- a/src/same_version/extractors/py_version_assignment_extractor.py +++ b/src/same_version/extractors/py_version_assignment_extractor.py @@ -10,7 +10,7 @@ class PyVersionAssignmentExtractor(PyAstExtractor): def __init__(self, cli_args: Namespace): target_cli_parameter_name: str = '--py-version-assignment-path' - default_target_name: str = "Python file with __version__ assignment" + default_target_name: str = "Python file with __version__ assignment to a literal string" super().__init__( target_file_path=self._create_target_file_path_from_cli_arg(cli_args=cli_args, cli_arg_parameter=target_cli_parameter_name), default_target_name=default_target_name, diff --git a/src/same_version/extractors/ro_crate_metadata_json_extractor.py b/src/same_version/extractors/ro_crate_metadata_json_extractor.py index 76954ab..aecf59a 100644 --- a/src/same_version/extractors/ro_crate_metadata_json_extractor.py +++ b/src/same_version/extractors/ro_crate_metadata_json_extractor.py @@ -19,7 +19,7 @@ def _get_version_from_data(self, data: dict) -> str | None: version = None graph: list | None = data.get('@graph', None) if isinstance(graph, list) and graph is not None: - id = self.cli_args.get('ro_crate_metadata_json_id', None) + id = vars(self.cli_args).get('ro_crate_metadata_json_id', None) if id is not None: for resource in graph: resource_id = resource.get('@id', None) diff --git a/src/same_version/extractors/setup_cfg_extractor.py b/src/same_version/extractors/setup_cfg_extractor.py index 3ca9ffe..9fc7503 100644 --- a/src/same_version/extractors/setup_cfg_extractor.py +++ b/src/same_version/extractors/setup_cfg_extractor.py @@ -1,3 +1,4 @@ +import configparser from argparse import Namespace from same_version.extractors.ini_extractor import IniExtractor @@ -15,13 +16,18 @@ def __init__(self, cli_args: Namespace): ) def _get_version_from_data(self, data: dict) -> str | None: - config = data.get('config', None) + config: configparser.ConfigParser | None = data.get('config', None) if config is None: return None - metadata = config.get('metadata', None) - if metadata is None: + + if not config.has_section('metadata'): return None - version = config.get('version', None) + + if not config.has_option('metadata', 'version'): + return None + + version = config.get('metadata', 'version') + if isinstance(version, str): version = version.strip() diff --git a/src/same_version/extractors/setup_py_extractor.py b/src/same_version/extractors/setup_py_extractor.py index b5da133..5b4f4a8 100644 --- a/src/same_version/extractors/setup_py_extractor.py +++ b/src/same_version/extractors/setup_py_extractor.py @@ -1,12 +1,12 @@ +import ast import logging -import subprocess from argparse import Namespace -from same_version.extractors.file_extractor import FileExtractor +from same_version.extractors.py_ast_extractor import PyAstExtractor logger = logging.getLogger(__name__) -class SetupPyExtractor(FileExtractor): +class SetupPyExtractor(PyAstExtractor): def __init__(self, cli_args: Namespace): target_cli_parameter_name: str = '--setup-py-path' @@ -17,21 +17,62 @@ def __init__(self, cli_args: Namespace): target_cli_parameter_name=target_cli_parameter_name ) - def _get_data(self) -> dict: - data = {} - - if not self.target_exists: - data['version'] = None - else: - try: - output = subprocess.check_output(['python', str(self.target_file_path), '--version'], stderr=subprocess.STDOUT) - data['version'] = output.decode('utf-8').strip() - except subprocess.CalledProcessError as e: - logger.error(f"❌ Error running {self.target_name} --version:\n{e.output.decode('utf-8')}") - data['version'] = None - - return data - def _get_version_from_data(self, data: dict) -> str | None: - version = data.get('version', None) - return version \ No newline at end of file + tree = data.get('tree', None) + if tree is None: + return None + + visitor = SetupPyVisitor() + visitor.visit(tree) + + version: str | None = visitor.version + if not isinstance(version, str) and version is not None: + version = None + + return version + + +class SetupPyVisitor(ast.NodeVisitor): + def __init__(self): + self.version = None + self.assignments = {} + + def visit_Assign(self, node): + # Capture simple assignments: version = "1.2.3" + if len(node.targets) == 1 and isinstance(node.targets[0], ast.Name): + var_name = node.targets[0].id + value = self._get_constant_value(node.value) + if value is not None: + self.assignments[var_name] = value + + def visit_Call(self, node): + # Look for any call to 'setup' function + if self._is_setup_call(node): + for kw in node.keywords: + if kw.arg == "version": + value = self._get_constant_value(kw.value) + if value is None and isinstance(kw.value, ast.Name): + # Handle: version=version_var + value = self.assignments.get(kw.value.id) + if value is not None: + self.version = value + + def _get_constant_value(self, node): + if isinstance(node, ast.Constant): # Python 3.8+ + if isinstance(node.value, str): + return node.value + elif isinstance(node, ast.Str): # Python <3.8 + return node.s + return None + + def _is_setup_call(self, node): + # Accept setup() or setuptools.setup() + if isinstance(node.func, ast.Name): + return node.func.id == "setup" + if isinstance(node.func, ast.Attribute): + return ( + node.func.attr == "setup" and + isinstance(node.func.value, ast.Name) and + node.func.value.id == "setuptools" + ) + return False diff --git a/src/same_version/main.py b/src/same_version/main.py index 8ef2660..b817bd7 100644 --- a/src/same_version/main.py +++ b/src/same_version/main.py @@ -51,7 +51,7 @@ logger = logging.getLogger(__name__) def parse_args() -> argparse.Namespace: - parser = argparse.ArgumentParser(description="Check metadata files for consistent software versions using canonical PEP 440 and SemVer") + parser = argparse.ArgumentParser(description="Check whether your software version metadata is consistent across key project files.") parser.add_argument('--base-version', required=False, help='A base version from which to check') parser.add_argument('--fail-for-missing-file', default=False, required=False, help='Fail for any checked file that is missing') parser.add_argument('--check-citation-cff', default=True, required=False, help='Check CITATION.cff? (true/false)') diff --git a/tests/extractors/conftest.py b/tests/extractors/conftest.py index 628e697..75f3081 100644 --- a/tests/extractors/conftest.py +++ b/tests/extractors/conftest.py @@ -15,4 +15,72 @@ def cli_args_with_base_version(): @pytest.fixture def cli_args_with_valid_package_json_path(): package_json_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'package.json' - return Namespace(package_json_path=package_json_path) \ No newline at end of file + return Namespace(package_json_path=package_json_path) + +@pytest.fixture +def cli_args_with_valid_pom_xml_path(): + pom_xml_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'pom.xml' + return Namespace(pom_xml_path=pom_xml_path) + +@pytest.fixture +def cli_args_with_valid_pyproject_toml_path(): + pyproject_toml_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'pyproject.toml' + return Namespace(pyproject_toml_path=pyproject_toml_path) + +@pytest.fixture +def cli_args_with_valid_cargo_toml_path(): + cargo_toml_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'Cargo.toml' + return Namespace(cargo_toml_path=cargo_toml_path) + +@pytest.fixture +def cli_args_with_valid_composer_json_path(): + composer_json_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'composer.json' + return Namespace(composer_json_path=composer_json_path) + +@pytest.fixture +def cli_args_with_valid_codemeta_json_path(): + codemeta_json_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'codemeta.json' + return Namespace(codemeta_json_path=codemeta_json_path) + +@pytest.fixture +def cli_args_with_valid_ro_crate_metadata_json_path_and_id(): + ro_crate_metadata_json_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'ro-crate-metadata.json' + ro_crate_metadata_json_id: str = 'software/' + return Namespace(ro_crate_metadata_json_path=ro_crate_metadata_json_path, ro_crate_metadata_json_id=ro_crate_metadata_json_id) + +@pytest.fixture +def cli_args_with_valid_zenodo_json_path(): + zenodo_json_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / '.zenodo.json' + return Namespace(zenodo_json_path=zenodo_json_path) + +@pytest.fixture +def cli_args_with_valid_nuspec_path(): + nuspec_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / '.nuspec' + return Namespace(nuspec_path=nuspec_path) + +@pytest.fixture +def cli_args_with_valid_r_description_path(): + r_description_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'DESCRIPTION' + return Namespace(r_description_path=r_description_path) + +@pytest.fixture +def cli_args_with_valid_setup_cfg_path(): + setup_cfg_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'setup.cfg' + return Namespace(setup_cfg_path=setup_cfg_path) + +@pytest.fixture +def cli_args_with_valid_setup_py_path(): + setup_py_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'setup.py' + return Namespace(setup_py_path=setup_py_path) + +@pytest.fixture +def cli_args_with_valid_citation_cff_path(): + citation_cff_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'CITATION.cff' + return Namespace(citation_cff_path=citation_cff_path) + +@pytest.fixture +def cli_args_with_valid_py_version_assignment_path(): + py_version_assignment_path: Path = Path(__file__).resolve().parent.parent / 'test_data' / 'main_with_literal_version_assignment.py' + return Namespace(py_version_assignment_path=py_version_assignment_path) + + diff --git a/tests/extractors/test_cargo_toml_extractor.py b/tests/extractors/test_cargo_toml_extractor.py new file mode 100644 index 0000000..ee9e896 --- /dev/null +++ b/tests/extractors/test_cargo_toml_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.cargo_toml_extractor import CargoTomlExtractor + + +def test_cargo_toml_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_cargo_toml_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'Cargo.toml' + +def test_cargo_toml_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_cargo_toml_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--cargo-toml-path' + +def test_cargo_toml_extractor_extract_version_with_cli_args_with_valid_cargo_toml_path(cli_args_with_valid_cargo_toml_path: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=cli_args_with_valid_cargo_toml_path) + assert extractor.extract_version() == '10.0.8' + +def test_cargo_toml_extractor_target_parameter_with_cli_args_with_valid_cargo_toml_path(cli_args_with_valid_cargo_toml_path: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=cli_args_with_valid_cargo_toml_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'Cargo.toml' + +def test_cargo_toml_extractor_target_exists_with_cli_args_with_valid_cargo_toml_path(cli_args_with_valid_cargo_toml_path: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=cli_args_with_valid_cargo_toml_path) + assert extractor.target_exists is True + +def test_cargo_toml_extractor_target_cli_parameter_name_with_cli_args_with_valid_cargo_toml_path(cli_args_with_valid_cargo_toml_path: Namespace): + extractor:CargoTomlExtractor = CargoTomlExtractor(cli_args=cli_args_with_valid_cargo_toml_path) + assert extractor.target_cli_parameter_name == '--cargo-toml-path' \ No newline at end of file diff --git a/tests/extractors/test_citation_cff_extractor.py b/tests/extractors/test_citation_cff_extractor.py new file mode 100644 index 0000000..692da53 --- /dev/null +++ b/tests/extractors/test_citation_cff_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.citation_cff_extractor import CitationCffExtractor + + +def test_citation_cff_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_citation_cff_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'CITATION.cff' + +def test_citation_cff_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_citation_cff_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--citation-cff-path' + +def test_citation_cff_extractor_extract_version_with_cli_args_with_valid_citation_cff_path(cli_args_with_valid_citation_cff_path: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=cli_args_with_valid_citation_cff_path) + assert extractor.extract_version() == '0.0.8000' + +def test_citation_cff_extractor_target_parameter_with_cli_args_with_valid_citation_cff_path(cli_args_with_valid_citation_cff_path: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=cli_args_with_valid_citation_cff_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'CITATION.cff' + +def test_citation_cff_extractor_target_exists_with_cli_args_with_valid_citation_cff_path(cli_args_with_valid_citation_cff_path: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=cli_args_with_valid_citation_cff_path) + assert extractor.target_exists is True + +def test_citation_cff_extractor_target_cli_parameter_name_with_cli_args_with_valid_citation_cff_path(cli_args_with_valid_citation_cff_path: Namespace): + extractor:CitationCffExtractor = CitationCffExtractor(cli_args=cli_args_with_valid_citation_cff_path) + assert extractor.target_cli_parameter_name == '--citation-cff-path' \ No newline at end of file diff --git a/tests/extractors/test_codemeta_json_extractor.py b/tests/extractors/test_codemeta_json_extractor.py new file mode 100644 index 0000000..319c21d --- /dev/null +++ b/tests/extractors/test_codemeta_json_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.codemeta_json_extractor import CodeMetaJsonExtractor + + +def test_codemeta_json_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_codemeta_json_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'codemeta.json' + +def test_codemeta_json_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_codemeta_json_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--codemeta-json-path' + +def test_codemeta_json_extractor_extract_version_with_cli_args_with_valid_codemeta_json_path(cli_args_with_valid_codemeta_json_path: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=cli_args_with_valid_codemeta_json_path) + assert extractor.extract_version() == '13.9.4' + +def test_codemeta_json_extractor_target_parameter_with_cli_args_with_valid_codemeta_json_path(cli_args_with_valid_codemeta_json_path: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=cli_args_with_valid_codemeta_json_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'codemeta.json' + +def test_codemeta_json_extractor_target_exists_with_cli_args_with_valid_codemeta_json_path(cli_args_with_valid_codemeta_json_path: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=cli_args_with_valid_codemeta_json_path) + assert extractor.target_exists is True + +def test_codemeta_json_extractor_target_cli_parameter_name_with_cli_args_with_valid_codemeta_json_path(cli_args_with_valid_codemeta_json_path: Namespace): + extractor:CodeMetaJsonExtractor = CodeMetaJsonExtractor(cli_args=cli_args_with_valid_codemeta_json_path) + assert extractor.target_cli_parameter_name == '--codemeta-json-path' \ No newline at end of file diff --git a/tests/extractors/test_composer_json_extractor.py b/tests/extractors/test_composer_json_extractor.py new file mode 100644 index 0000000..babfad1 --- /dev/null +++ b/tests/extractors/test_composer_json_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.composer_json_extractor import ComposerJsonExtractor + + +def test_composer_json_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_composer_json_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'composer.json' + +def test_composer_json_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_composer_json_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--composer-json-path' + +def test_composer_json_extractor_extract_version_with_cli_args_with_valid_composer_json_path(cli_args_with_valid_composer_json_path: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=cli_args_with_valid_composer_json_path) + assert extractor.extract_version() == '6.0.8' + +def test_composer_json_extractor_target_parameter_with_cli_args_with_valid_composer_json_path(cli_args_with_valid_composer_json_path: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=cli_args_with_valid_composer_json_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'composer.json' + +def test_composer_json_extractor_target_exists_with_cli_args_with_valid_composer_json_path(cli_args_with_valid_composer_json_path: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=cli_args_with_valid_composer_json_path) + assert extractor.target_exists is True + +def test_composer_json_extractor_target_cli_parameter_name_with_cli_args_with_valid_composer_json_path(cli_args_with_valid_composer_json_path: Namespace): + extractor:ComposerJsonExtractor = ComposerJsonExtractor(cli_args=cli_args_with_valid_composer_json_path) + assert extractor.target_cli_parameter_name == '--composer-json-path' \ No newline at end of file diff --git a/tests/extractors/test_nuspec_extractor.py b/tests/extractors/test_nuspec_extractor.py new file mode 100644 index 0000000..72f181f --- /dev/null +++ b/tests/extractors/test_nuspec_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.nuspec_extractor import NuspecExtractor + + +def test_nuspec_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_nuspec_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=empty_cli_args) + assert extractor.target_name == '.nuspec' + +def test_nuspec_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_nuspec_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--nuspec-path' + +def test_nuspec_extractor_extract_version_with_cli_args_with_valid_nuspec_path(cli_args_with_valid_nuspec_path: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=cli_args_with_valid_nuspec_path) + assert extractor.extract_version() == '4.8.12' + +def test_nuspec_extractor_target_parameter_with_cli_args_with_valid_nuspec_path(cli_args_with_valid_nuspec_path: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=cli_args_with_valid_nuspec_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == '.nuspec' + +def test_nuspec_extractor_target_exists_with_cli_args_with_valid_nuspec_path(cli_args_with_valid_nuspec_path: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=cli_args_with_valid_nuspec_path) + assert extractor.target_exists is True + +def test_nuspec_extractor_target_cli_parameter_name_with_cli_args_with_valid_nuspec_path(cli_args_with_valid_nuspec_path: Namespace): + extractor:NuspecExtractor = NuspecExtractor(cli_args=cli_args_with_valid_nuspec_path) + assert extractor.target_cli_parameter_name == '--nuspec-path' \ No newline at end of file diff --git a/tests/extractors/test_pom_xml_extractor.py b/tests/extractors/test_pom_xml_extractor.py new file mode 100644 index 0000000..523808b --- /dev/null +++ b/tests/extractors/test_pom_xml_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.pom_xml_extractor import PomXmlExtractor + + +def test_pom_xml_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_pom_xml_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'pom.xml' + +def test_pom_xml_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_pom_xml_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--pom-xml-path' + +def test_pom_xml_extractor_extract_version_with_cli_args_with_valid_pom_xml_path(cli_args_with_valid_pom_xml_path: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=cli_args_with_valid_pom_xml_path) + assert extractor.extract_version() == '1.2.3' + +def test_pom_xml_extractor_target_parameter_with_cli_args_with_valid_pom_xml_path(cli_args_with_valid_pom_xml_path: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=cli_args_with_valid_pom_xml_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'pom.xml' + +def test_pom_xml_extractor_target_exists_with_cli_args_with_valid_pom_xml_path(cli_args_with_valid_pom_xml_path: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=cli_args_with_valid_pom_xml_path) + assert extractor.target_exists is True + +def test_pom_xml_extractor_target_cli_parameter_name_with_cli_args_with_valid_pom_xml_path(cli_args_with_valid_pom_xml_path: Namespace): + extractor:PomXmlExtractor = PomXmlExtractor(cli_args=cli_args_with_valid_pom_xml_path) + assert extractor.target_cli_parameter_name == '--pom-xml-path' \ No newline at end of file diff --git a/tests/extractors/test_py_version_assignment_extractor.py b/tests/extractors/test_py_version_assignment_extractor.py new file mode 100644 index 0000000..b70274e --- /dev/null +++ b/tests/extractors/test_py_version_assignment_extractor.py @@ -0,0 +1,39 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.py_version_assignment_extractor import ( + PyVersionAssignmentExtractor, +) + + +def test_py_version_assignment_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_py_version_assignment_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=empty_cli_args) + assert extractor.target_name == "Python file with __version__ assignment to a literal string" + +def test_py_version_assignment_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_py_version_assignment_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--py-version-assignment-path' + +def test_py_version_assignment_extractor_extract_version_with_cli_args_with_valid_py_version_assignment_path(cli_args_with_valid_py_version_assignment_path: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=cli_args_with_valid_py_version_assignment_path) + assert extractor.extract_version() == '15.2.4' + +def test_py_version_assignment_extractor_target_parameter_with_cli_args_with_valid_py_version_assignment_path(cli_args_with_valid_py_version_assignment_path: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=cli_args_with_valid_py_version_assignment_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'main_with_literal_version_assignment.py' + +def test_py_version_assignment_extractor_target_exists_with_cli_args_with_valid_py_version_assignment_path(cli_args_with_valid_py_version_assignment_path: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=cli_args_with_valid_py_version_assignment_path) + assert extractor.target_exists is True + +def test_py_version_assignment_extractor_target_cli_parameter_name_with_cli_args_with_valid_py_version_assignment_path(cli_args_with_valid_py_version_assignment_path: Namespace): + extractor:PyVersionAssignmentExtractor = PyVersionAssignmentExtractor(cli_args=cli_args_with_valid_py_version_assignment_path) + assert extractor.target_cli_parameter_name == '--py-version-assignment-path' \ No newline at end of file diff --git a/tests/extractors/test_pyproject_toml_extractor.py b/tests/extractors/test_pyproject_toml_extractor.py new file mode 100644 index 0000000..b3d6180 --- /dev/null +++ b/tests/extractors/test_pyproject_toml_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.pyproject_toml_extractor import PyprojectTomlExtractor + + +def test_pyproject_toml_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_pyproject_toml_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'pyproject.toml' + +def test_pyproject_toml_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_pyproject_toml_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--pyproject-toml-path' + +def test_pyproject_toml_extractor_extract_version_with_cli_args_with_valid_pyproject_toml_path(cli_args_with_valid_pyproject_toml_path: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=cli_args_with_valid_pyproject_toml_path) + assert extractor.extract_version() == '8.7.6' + +def test_pyproject_toml_extractor_target_parameter_with_cli_args_with_valid_pyproject_toml_path(cli_args_with_valid_pyproject_toml_path: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=cli_args_with_valid_pyproject_toml_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'pyproject.toml' + +def test_pyproject_toml_extractor_target_exists_with_cli_args_with_valid_pyproject_toml_path(cli_args_with_valid_pyproject_toml_path: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=cli_args_with_valid_pyproject_toml_path) + assert extractor.target_exists is True + +def test_pyproject_toml_extractor_target_cli_parameter_name_with_cli_args_with_valid_pyproject_toml_path(cli_args_with_valid_pyproject_toml_path: Namespace): + extractor:PyprojectTomlExtractor = PyprojectTomlExtractor(cli_args=cli_args_with_valid_pyproject_toml_path) + assert extractor.target_cli_parameter_name == '--pyproject-toml-path' \ No newline at end of file diff --git a/tests/extractors/test_r_description_extractor.py b/tests/extractors/test_r_description_extractor.py new file mode 100644 index 0000000..99c9a8d --- /dev/null +++ b/tests/extractors/test_r_description_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.r_description_extractor import RDescriptionExtractor + + +def test_r_description_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_r_description_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'DESCRIPTION' + +def test_r_description_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_r_description_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--r-description-path' + +def test_r_description_extractor_extract_version_with_cli_args_with_valid_r_description_path(cli_args_with_valid_r_description_path: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=cli_args_with_valid_r_description_path) + assert extractor.extract_version() == '3.1.4' + +def test_r_description_extractor_target_parameter_with_cli_args_with_valid_r_description_path(cli_args_with_valid_r_description_path: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=cli_args_with_valid_r_description_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'DESCRIPTION' + +def test_r_description_extractor_target_exists_with_cli_args_with_valid_r_description_path(cli_args_with_valid_r_description_path: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=cli_args_with_valid_r_description_path) + assert extractor.target_exists is True + +def test_r_description_extractor_target_cli_parameter_name_with_cli_args_with_valid_r_description_path(cli_args_with_valid_r_description_path: Namespace): + extractor:RDescriptionExtractor = RDescriptionExtractor(cli_args=cli_args_with_valid_r_description_path) + assert extractor.target_cli_parameter_name == '--r-description-path' \ No newline at end of file diff --git a/tests/extractors/test_ro_crate_metadata_json_extractor.py b/tests/extractors/test_ro_crate_metadata_json_extractor.py new file mode 100644 index 0000000..c54d936 --- /dev/null +++ b/tests/extractors/test_ro_crate_metadata_json_extractor.py @@ -0,0 +1,39 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.ro_crate_metadata_json_extractor import ( + RoCrateMetadataJsonExtractor, +) + + +def test_ro_crate_metadata_json_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_ro_crate_metadata_json_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'ro-crate-metadata.json' + +def test_ro_crate_metadata_json_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_ro_crate_metadata_json_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--ro-crate-metadata-json-path' + +def test_ro_crate_metadata_json_extractor_extract_version_with_cli_args_with_valid_ro_crate_metadata_json_path_and_id(cli_args_with_valid_ro_crate_metadata_json_path_and_id: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=cli_args_with_valid_ro_crate_metadata_json_path_and_id) + assert extractor.extract_version() == '7.2.5' + +def test_ro_crate_metadata_json_extractor_target_parameter_with_cli_args_with_valid_ro_crate_metadata_json_path_and_id(cli_args_with_valid_ro_crate_metadata_json_path_and_id: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=cli_args_with_valid_ro_crate_metadata_json_path_and_id) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'ro-crate-metadata.json' + +def test_ro_crate_metadata_json_extractor_target_exists_with_cli_args_with_valid_ro_crate_metadata_json_path_and_id(cli_args_with_valid_ro_crate_metadata_json_path_and_id: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=cli_args_with_valid_ro_crate_metadata_json_path_and_id) + assert extractor.target_exists is True + +def test_ro_crate_metadata_json_extractor_target_cli_parameter_name_with_cli_args_with_valid_ro_crate_metadata_json_path_and_id(cli_args_with_valid_ro_crate_metadata_json_path_and_id: Namespace): + extractor:RoCrateMetadataJsonExtractor = RoCrateMetadataJsonExtractor(cli_args=cli_args_with_valid_ro_crate_metadata_json_path_and_id) + assert extractor.target_cli_parameter_name == '--ro-crate-metadata-json-path' \ No newline at end of file diff --git a/tests/extractors/test_setup_cfg_extractor.py b/tests/extractors/test_setup_cfg_extractor.py new file mode 100644 index 0000000..631f050 --- /dev/null +++ b/tests/extractors/test_setup_cfg_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.setup_cfg_extractor import SetupCfgExtractor + + +def test_setup_cfg_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_setup_cfg_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'setup.cfg' + +def test_setup_cfg_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_setup_cfg_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--setup-cfg-path' + +def test_setup_cfg_extractor_extract_version_with_cli_args_with_valid_setup_cfg_path(cli_args_with_valid_setup_cfg_path: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=cli_args_with_valid_setup_cfg_path) + assert extractor.extract_version() == '9.0.3' + +def test_setup_cfg_extractor_target_parameter_with_cli_args_with_valid_setup_cfg_path(cli_args_with_valid_setup_cfg_path: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=cli_args_with_valid_setup_cfg_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'setup.cfg' + +def test_setup_cfg_extractor_target_exists_with_cli_args_with_valid_setup_cfg_path(cli_args_with_valid_setup_cfg_path: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=cli_args_with_valid_setup_cfg_path) + assert extractor.target_exists is True + +def test_setup_cfg_extractor_target_cli_parameter_name_with_cli_args_with_valid_setup_cfg_path(cli_args_with_valid_setup_cfg_path: Namespace): + extractor:SetupCfgExtractor = SetupCfgExtractor(cli_args=cli_args_with_valid_setup_cfg_path) + assert extractor.target_cli_parameter_name == '--setup-cfg-path' \ No newline at end of file diff --git a/tests/extractors/test_setup_py_extractor.py b/tests/extractors/test_setup_py_extractor.py new file mode 100644 index 0000000..ee9abba --- /dev/null +++ b/tests/extractors/test_setup_py_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.setup_py_extractor import SetupPyExtractor + + +def test_setup_py_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_setup_py_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=empty_cli_args) + assert extractor.target_name == 'setup.py' + +def test_setup_py_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_setup_py_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--setup-py-path' + +def test_setup_py_extractor_extract_version_with_cli_args_with_valid_setup_py_path(cli_args_with_valid_setup_py_path: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=cli_args_with_valid_setup_py_path) + assert extractor.extract_version() == '8.3.7' + +def test_setup_py_extractor_target_parameter_with_cli_args_with_valid_setup_py_path(cli_args_with_valid_setup_py_path: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=cli_args_with_valid_setup_py_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == 'setup.py' + +def test_setup_py_extractor_target_exists_with_cli_args_with_valid_setup_py_path(cli_args_with_valid_setup_py_path: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=cli_args_with_valid_setup_py_path) + assert extractor.target_exists is True + +def test_setup_py_extractor_target_cli_parameter_name_with_cli_args_with_valid_setup_py_path(cli_args_with_valid_setup_py_path: Namespace): + extractor:SetupPyExtractor = SetupPyExtractor(cli_args=cli_args_with_valid_setup_py_path) + assert extractor.target_cli_parameter_name == '--setup-py-path' \ No newline at end of file diff --git a/tests/extractors/test_zenodo_json_extractor.py b/tests/extractors/test_zenodo_json_extractor.py new file mode 100644 index 0000000..01fcc7c --- /dev/null +++ b/tests/extractors/test_zenodo_json_extractor.py @@ -0,0 +1,37 @@ +from argparse import Namespace +from pathlib import Path + +from same_version.extractors.zenodo_json_extractor import ZenodoJsonExtractor + + +def test_zenodo_json_extractor_extract_version_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=empty_cli_args) + assert extractor.extract_version() is None + +def test_zenodo_json_extractor_target_parameter_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_name == '.zenodo.json' + +def test_zenodo_json_extractor_target_exists_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_exists is False + +def test_zenodo_json_extractor_target_cli_parameter_name_with_empty_cli_args(empty_cli_args: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=empty_cli_args) + assert extractor.target_cli_parameter_name == '--zenodo-json-path' + +def test_zenodo_json_extractor_extract_version_with_cli_args_with_valid_zenodo_json_path(cli_args_with_valid_zenodo_json_path: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=cli_args_with_valid_zenodo_json_path) + assert extractor.extract_version() == '4.2.6' + +def test_zenodo_json_extractor_target_parameter_with_cli_args_with_valid_zenodo_json_path(cli_args_with_valid_zenodo_json_path: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=cli_args_with_valid_zenodo_json_path) + assert extractor.target_name is not None and Path(extractor.target_name).name == '.zenodo.json' + +def test_zenodo_json_extractor_target_exists_with_cli_args_with_valid_zenodo_json_path(cli_args_with_valid_zenodo_json_path: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=cli_args_with_valid_zenodo_json_path) + assert extractor.target_exists is True + +def test_zenodo_json_extractor_target_cli_parameter_name_with_cli_args_with_valid_zenodo_json_path(cli_args_with_valid_zenodo_json_path: Namespace): + extractor:ZenodoJsonExtractor = ZenodoJsonExtractor(cli_args=cli_args_with_valid_zenodo_json_path) + assert extractor.target_cli_parameter_name == '--zenodo-json-path' \ No newline at end of file diff --git a/tests/test_data/.nuspec b/tests/test_data/.nuspec new file mode 100644 index 0000000..e78267f --- /dev/null +++ b/tests/test_data/.nuspec @@ -0,0 +1,15 @@ + + + + My.Dummy.App + 4.8.12 + My Dummy App + Test Author + Test Author + false + A dummy NuGet package for unit testing. + Initial dummy release. + Copyright 2025 + dummy test unit-test + + diff --git a/tests/test_data/.zenodo.json b/tests/test_data/.zenodo.json new file mode 100644 index 0000000..a2224a8 --- /dev/null +++ b/tests/test_data/.zenodo.json @@ -0,0 +1,21 @@ +{ + "title": "My Dummy App", + "version": "4.2.6", + "description": "A dummy app for unit testing.", + "creators": [ + { + "name": "Test Author", + "affiliation": "Example Institute", + "orcid": "0000-0000-0000-0000" + } + ], + "license": "MIT", + "upload_type": "software", + "publication_date": "2024-06-14", + "keywords": [ + "dummy", + "test", + "unit test" + ], + "access_right": "open" +} \ No newline at end of file diff --git a/tests/test_data/CITATION.cff b/tests/test_data/CITATION.cff new file mode 100644 index 0000000..58e9ee1 --- /dev/null +++ b/tests/test_data/CITATION.cff @@ -0,0 +1,14 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +title: "My Dummy App" +version: "0.0.8000" +doi: 10.5281/zenodo.1234567 +authors: + - family-names: Author + given-names: Test + affiliation: Example Institute + orcid: https://orcid.org/0000-0000-0000-0000 +date-released: 2025-06-14 +license: MIT +repository-code: https://github.com/example/my-dummy-app +url: https://github.com/example/my-dummy-app diff --git a/tests/test_data/Cargo.toml b/tests/test_data/Cargo.toml new file mode 100644 index 0000000..a7592e3 --- /dev/null +++ b/tests/test_data/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "my-dummy-app" +version = "10.0.8" +authors = ["Test Author "] +edition = "2021" +description = "A dummy Rust app for unit testing." +license = "MIT" + +[dependencies] +serde = { version = "1.0", features = ["derive"] } diff --git a/tests/test_data/DESCRIPTION b/tests/test_data/DESCRIPTION new file mode 100644 index 0000000..e029388 --- /dev/null +++ b/tests/test_data/DESCRIPTION @@ -0,0 +1,11 @@ +Package: mydummyapp +Type: Package +Title: A Dummy App for Unit Testing +Version: 3.1.4 +Author: Test Author [aut] +Maintainer: Test Author +Description: A dummy R package to use for unit testing of metadata parsers. +License: MIT +Encoding: UTF-8 +LazyData: true +RoxygenNote: 7.1.1 diff --git a/tests/test_data/codemeta.json b/tests/test_data/codemeta.json new file mode 100644 index 0000000..50c0ea4 --- /dev/null +++ b/tests/test_data/codemeta.json @@ -0,0 +1,15 @@ +{ + "@context": "https://doi.org/10.5063/schema/codemeta-2.0", + "@type": "SoftwareSourceCode", + "name": "my-dummy-app", + "version": "13.9.4", + "description": "A dummy app for unit testing.", + "author": { + "@type": "Person", + "name": "Test Author", + "email": "author@example.com" + }, + "license": "MIT", + "programmingLanguage": "Python", + "identifier": "https://github.com/example/my-dummy-app" +} \ No newline at end of file diff --git a/tests/test_data/composer.json b/tests/test_data/composer.json new file mode 100644 index 0000000..3c7dff3 --- /dev/null +++ b/tests/test_data/composer.json @@ -0,0 +1,22 @@ +{ + "name": "example/my-dummy-app", + "description": "A dummy PHP app for unit testing.", + "version": "6.0.8", + "type": "project", + "license": "MIT", + "authors": [ + { + "name": "Test Author", + "email": "author@example.com" + } + ], + "require": { + "php": ">=7.4", + "monolog/monolog": "^2.0" + }, + "autoload": { + "psr-4": { + "MyDummyApp\\": "src/" + } + } +} \ No newline at end of file diff --git a/tests/test_data/main_with_literal_version_assignment.py b/tests/test_data/main_with_literal_version_assignment.py new file mode 100644 index 0000000..30fe614 --- /dev/null +++ b/tests/test_data/main_with_literal_version_assignment.py @@ -0,0 +1,12 @@ +# version_metadata.py + +""" +My Dummy App +""" + +__author__ = "Test Author" +__email__ = "author@example.com" +__version__ = "15.2.4" + +def main(): + print("Hello world") diff --git a/tests/test_data/pom.xml b/tests/test_data/pom.xml new file mode 100644 index 0000000..ef2eedd --- /dev/null +++ b/tests/test_data/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + + com.example + my-app + 1.2.3 + + My Dummy App + A dummy pom for unit testing. + diff --git a/tests/test_data/pyproject.toml b/tests/test_data/pyproject.toml new file mode 100644 index 0000000..3673759 --- /dev/null +++ b/tests/test_data/pyproject.toml @@ -0,0 +1,14 @@ +[project] +name = "my-dummy-app" +version = "8.7.6" +description = "A dummy app for unit testing." +authors = [ + { name = "Test Author", email = "author@example.com" } +] +dependencies = [ + "requests >=2.0.0" +] + +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" diff --git a/tests/test_data/ro-crate-metadata.json b/tests/test_data/ro-crate-metadata.json new file mode 100644 index 0000000..0a2c507 --- /dev/null +++ b/tests/test_data/ro-crate-metadata.json @@ -0,0 +1,53 @@ +{ + "@context": [ + "https://w3id.org/ro/crate/1.1/context", + { + "@vocab": "https://schema.org/", + "ro": "https://w3id.org/ro/terms/" + } + ], + "@graph": [ + { + "@id": "ro-crate-metadata.json", + "@type": "CreativeWork", + "about": { + "@id": "./" + } + }, + { + "@id": "./", + "@type": "Dataset", + "name": "My Dummy RO-Crate for Unit Testing", + "description": "A dummy RO-Crate used for metadata unit testing.", + "license": { + "@id": "https://opensource.org/licenses/MIT" + }, + "author": { + "@type": "Person", + "name": "Test Author", + "affiliation": { + "@type": "Organization", + "name": "Example Institute" + } + }, + "datePublished": "2025-06-14", + "hasPart": { + "@id": "software/" + } + }, + { + "@id": "software/", + "@type": "SoftwareSourceCode", + "name": "My Dummy App", + "version": "7.2.5", + "programmingLanguage": { + "@type": "ComputerLanguage", + "name": "Python" + }, + "license": { + "@id": "https://opensource.org/licenses/MIT" + }, + "codeRepository": "https://github.com/example/my-dummy-app" + } + ] +} \ No newline at end of file diff --git a/tests/test_data/setup.cfg b/tests/test_data/setup.cfg new file mode 100644 index 0000000..922722c --- /dev/null +++ b/tests/test_data/setup.cfg @@ -0,0 +1,23 @@ +[metadata] +name = my-dummy-app +version = 9.0.3 +description = A dummy app for unit testing. +author = Test Author +author_email = author@example.com +license = MIT +url = https://github.com/example/my-dummy-app +classifiers = + Programming Language :: Python :: 3 + License :: OSI Approved :: MIT License + Development Status :: 4 - Beta + +[options] +packages = find: +python_requires = >=3.7 +install_requires = + requests >=2.0.0 + +[options.extras_require] +dev = + pytest + flake8 diff --git a/tests/test_data/setup.py b/tests/test_data/setup.py new file mode 100644 index 0000000..cfccbd9 --- /dev/null +++ b/tests/test_data/setup.py @@ -0,0 +1,27 @@ +from setuptools import find_packages, setup + +setup( + name="my-dummy-app", + version="8.3.7", + description="A dummy app for unit testing.", + author="Test Author", + author_email="author@example.com", + url="https://github.com/example/my-dummy-app", + license="MIT", + packages=find_packages(), + python_requires=">=3.7", + install_requires=[ + "requests>=2.0.0" + ], + extras_require={ + "dev": [ + "pytest", + "flake8" + ] + }, + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Development Status :: 4 - Beta" + ] +)