fix: resolve CI test failures and update test configuration
This commit is contained in:
248
tests/unit/test_parsers.py
Normal file
248
tests/unit/test_parsers.py
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
"""Tests for package parsers."""
|
||||||
|
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from depcheck.models import PackageManager
|
||||||
|
from depcheck.parsers import create_parser_registry
|
||||||
|
from depcheck.parsers.cargo import CargoParser
|
||||||
|
from depcheck.parsers.go import GoParser
|
||||||
|
from depcheck.parsers.npm import NpmParser
|
||||||
|
from depcheck.parsers.pip import PipParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestNpmParser:
|
||||||
|
"""Tests for NPM package.json parser."""
|
||||||
|
|
||||||
|
def test_parse_simple_package_json(self):
|
||||||
|
"""Test parsing a simple package.json."""
|
||||||
|
content = """{
|
||||||
|
"name": "test-project",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "4.18.2",
|
||||||
|
"lodash": "4.17.21"
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
pkg_path = Path(tmpdir) / "package.json"
|
||||||
|
pkg_path.write_text(content)
|
||||||
|
|
||||||
|
parser = NpmParser()
|
||||||
|
deps = parser.parse(pkg_path)
|
||||||
|
|
||||||
|
assert len(deps) == 2
|
||||||
|
assert any(d.name == "express" for d in deps)
|
||||||
|
assert any(d.name == "lodash" for d in deps)
|
||||||
|
|
||||||
|
def test_parse_dev_dependencies(self):
|
||||||
|
"""Test parsing devDependencies."""
|
||||||
|
content = """{
|
||||||
|
"name": "test-project",
|
||||||
|
"devDependencies": {
|
||||||
|
"jest": "29.7.0",
|
||||||
|
"eslint": "8.56.0"
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
pkg_path = Path(tmpdir) / "package.json"
|
||||||
|
pkg_path.write_text(content)
|
||||||
|
|
||||||
|
parser = NpmParser()
|
||||||
|
deps = parser.parse(pkg_path)
|
||||||
|
|
||||||
|
assert len(deps) == 2
|
||||||
|
assert all(d.category == "devDependencies" for d in deps)
|
||||||
|
|
||||||
|
def test_parse_optional_dependencies(self):
|
||||||
|
"""Test parsing optionalDependencies."""
|
||||||
|
content = """{
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "2.3.3"
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
pkg_path = Path(tmpdir) / "package.json"
|
||||||
|
pkg_path.write_text(content)
|
||||||
|
|
||||||
|
parser = NpmParser()
|
||||||
|
deps = parser.parse(pkg_path)
|
||||||
|
|
||||||
|
assert len(deps) == 1
|
||||||
|
assert deps[0].category == "optionalDependencies"
|
||||||
|
|
||||||
|
def test_invalid_json_handled_gracefully(self):
|
||||||
|
"""Test that invalid JSON is handled gracefully."""
|
||||||
|
content = "{ invalid json }"
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
pkg_path = Path(tmpdir) / "package.json"
|
||||||
|
pkg_path.write_text(content)
|
||||||
|
|
||||||
|
parser = NpmParser()
|
||||||
|
deps = parser.parse(pkg_path)
|
||||||
|
|
||||||
|
assert len(deps) == 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestPipParser:
|
||||||
|
"""Tests for pip requirements.txt parser."""
|
||||||
|
|
||||||
|
def test_parse_requirements_txt(self):
|
||||||
|
"""Test parsing requirements.txt."""
|
||||||
|
content = """# This is a comment
|
||||||
|
requests>=2.31.0
|
||||||
|
flask>=2.0.0
|
||||||
|
numpy==1.24.0
|
||||||
|
"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
req_path = Path(tmpdir) / "requirements.txt"
|
||||||
|
req_path.write_text(content)
|
||||||
|
|
||||||
|
parser = PipParser()
|
||||||
|
deps = parser.parse(req_path)
|
||||||
|
|
||||||
|
assert len(deps) == 3
|
||||||
|
assert any(d.name == "requests" for d in deps)
|
||||||
|
assert any(d.name == "flask" for d in deps)
|
||||||
|
assert any(d.name == "numpy" for d in deps)
|
||||||
|
|
||||||
|
def test_parse_requirements_with_comments(self):
|
||||||
|
"""Test that comments are ignored."""
|
||||||
|
content = """requests==2.31.0 # inline comment
|
||||||
|
flask>=2.0.0; python_version >= \"3.8\"
|
||||||
|
"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
req_path = Path(tmpdir) / "requirements.txt"
|
||||||
|
req_path.write_text(content)
|
||||||
|
|
||||||
|
parser = PipParser()
|
||||||
|
deps = parser.parse(req_path)
|
||||||
|
|
||||||
|
assert len(deps) >= 1
|
||||||
|
|
||||||
|
def test_parse_pyproject_toml(self):
|
||||||
|
"""Test parsing pyproject.toml."""
|
||||||
|
content = """
|
||||||
|
[project]
|
||||||
|
dependencies = [
|
||||||
|
\"requests>=2.31.0\",
|
||||||
|
\"flask>=2.0.0\"
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
toml_path = Path(tmpdir) / "pyproject.toml"
|
||||||
|
toml_path.write_text(content)
|
||||||
|
|
||||||
|
parser = PipParser()
|
||||||
|
deps = parser.parse(toml_path)
|
||||||
|
|
||||||
|
assert len(deps) == 2
|
||||||
|
|
||||||
|
|
||||||
|
class TestGoParser:
|
||||||
|
"""Tests for Go go.mod parser."""
|
||||||
|
|
||||||
|
def test_parse_go_mod(self):
|
||||||
|
"""Test parsing go.mod file."""
|
||||||
|
content = """
|
||||||
|
module github.com/example/project
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/stretchr/testify v1.8.4
|
||||||
|
golang.org/x/crypto v0.17.0
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
mod_path = Path(tmpdir) / "go.mod"
|
||||||
|
mod_path.write_text(content)
|
||||||
|
|
||||||
|
parser = GoParser()
|
||||||
|
deps = parser.parse(mod_path)
|
||||||
|
|
||||||
|
assert len(deps) == 2
|
||||||
|
assert any("testify" in d.name for d in deps)
|
||||||
|
assert any("crypto" in d.name for d in deps)
|
||||||
|
|
||||||
|
|
||||||
|
class TestCargoParser:
|
||||||
|
"""Tests for Rust Cargo.toml parser."""
|
||||||
|
|
||||||
|
def test_parse_cargo_toml(self):
|
||||||
|
"""Test parsing Cargo.toml file."""
|
||||||
|
content = """
|
||||||
|
[package]
|
||||||
|
name = "my-project"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = "1.0"
|
||||||
|
tokio = "1.36"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
proptest = "1.4"
|
||||||
|
"""
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
cargo_path = Path(tmpdir) / "Cargo.toml"
|
||||||
|
cargo_path.write_text(content)
|
||||||
|
|
||||||
|
parser = CargoParser()
|
||||||
|
deps = parser.parse(cargo_path)
|
||||||
|
|
||||||
|
assert len(deps) == 3
|
||||||
|
assert any(d.name == "serde" for d in deps)
|
||||||
|
assert any(d.name == "tokio" for d in deps)
|
||||||
|
assert any(d.name == "proptest" for d in deps)
|
||||||
|
|
||||||
|
|
||||||
|
class TestParserRegistry:
|
||||||
|
"""Tests for parser registry."""
|
||||||
|
|
||||||
|
def test_get_parser_for_package_json(self):
|
||||||
|
"""Test getting correct parser for package.json."""
|
||||||
|
registry = create_parser_registry()
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
pkg_path = Path(tmpdir) / "package.json"
|
||||||
|
pkg_path.write_text('{"name": "test"}')
|
||||||
|
|
||||||
|
parser = registry.get_parser(pkg_path)
|
||||||
|
assert parser is not None
|
||||||
|
assert parser.package_manager == PackageManager.NPM
|
||||||
|
|
||||||
|
def test_get_parser_for_requirements(self):
|
||||||
|
"""Test getting correct parser for requirements.txt."""
|
||||||
|
registry = create_parser_registry()
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
req_path = Path(tmpdir) / "requirements.txt"
|
||||||
|
req_path.write_text("requests==2.31.0")
|
||||||
|
|
||||||
|
parser = registry.get_parser(req_path)
|
||||||
|
assert parser is not None
|
||||||
|
assert parser.package_manager == PackageManager.PIP
|
||||||
|
|
||||||
|
def test_no_parser_for_unknown_file(self):
|
||||||
|
"""Test that unknown file types return None."""
|
||||||
|
registry = create_parser_registry()
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
unknown_path = Path(tmpdir) / "unknown.ext"
|
||||||
|
unknown_path.write_text("some content")
|
||||||
|
|
||||||
|
parser = registry.get_parser(unknown_path)
|
||||||
|
assert parser is None
|
||||||
Reference in New Issue
Block a user