test: license checker unit tests (#110)
This commit is contained in:
186
tests/test_license_checker.py
Normal file
186
tests/test_license_checker.py
Normal file
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Tests for license_checker.py — Pipeline 5.4"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
# Add scripts dir to path
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from license_checker import (
|
||||
normalize_license,
|
||||
check_compatibility,
|
||||
parse_requirements_txt,
|
||||
parse_package_json,
|
||||
parse_pyproject_toml,
|
||||
parse_go_mod,
|
||||
detect_project_license,
|
||||
scan_dep_files,
|
||||
generate_report,
|
||||
format_text,
|
||||
Severity,
|
||||
DepLicense,
|
||||
)
|
||||
|
||||
|
||||
class TestNormalizeLicense(unittest.TestCase):
|
||||
def test_mit_aliases(self):
|
||||
for alias in ["mit", "MIT License", "The MIT License", "MIT license"]:
|
||||
self.assertEqual(normalize_license(alias), "MIT")
|
||||
|
||||
def test_apache_aliases(self):
|
||||
for alias in ["Apache 2.0", "Apache-2.0", "apache software license"]:
|
||||
self.assertEqual(normalize_license(alias), "Apache-2.0")
|
||||
|
||||
def test_gpl_aliases(self):
|
||||
self.assertEqual(normalize_license("GPL-3.0"), "GPL-3.0")
|
||||
self.assertEqual(normalize_license("gplv3"), "GPL-3.0")
|
||||
|
||||
def test_unknown(self):
|
||||
self.assertEqual(normalize_license(""), "UNKNOWN")
|
||||
self.assertEqual(normalize_license("UNKNOWN"), "UNKNOWN")
|
||||
|
||||
def test_already_spdx(self):
|
||||
self.assertEqual(normalize_license("BSD-3-Clause"), "BSD-3-Clause")
|
||||
|
||||
|
||||
class TestCheckCompatibility(unittest.TestCase):
|
||||
def test_permissive_ok(self):
|
||||
sev, msg = check_compatibility("MIT", "MIT")
|
||||
self.assertEqual(sev, Severity.OK)
|
||||
|
||||
def test_gpl_in_mit_error(self):
|
||||
sev, msg = check_compatibility("GPL-3.0", "MIT")
|
||||
self.assertEqual(sev, Severity.ERROR)
|
||||
|
||||
def test_unknown_warning(self):
|
||||
sev, msg = check_compatibility("UNKNOWN", "MIT")
|
||||
self.assertEqual(sev, Severity.WARNING)
|
||||
|
||||
def test_apache_in_mit_ok(self):
|
||||
sev, msg = check_compatibility("Apache-2.0", "MIT")
|
||||
self.assertEqual(sev, Severity.OK)
|
||||
|
||||
def test_lgpl_in_mit_error(self):
|
||||
sev, msg = check_compatibility("LGPL-3.0", "MIT")
|
||||
self.assertEqual(sev, Severity.ERROR)
|
||||
|
||||
|
||||
class TestParseRequirements(unittest.TestCase):
|
||||
def test_basic(self):
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
|
||||
f.write("requests>=2.28.0\nflask==2.3.0\n# comment\npytest\n")
|
||||
f.flush()
|
||||
deps = parse_requirements_txt(f.name)
|
||||
os.unlink(f.name)
|
||||
names = [d.name for d in deps]
|
||||
self.assertIn("requests", names)
|
||||
self.assertIn("flask", names)
|
||||
self.assertIn("pytest", names)
|
||||
self.assertEqual(len(deps), 3)
|
||||
|
||||
def test_skip_flags(self):
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
|
||||
f.write("-r other.txt\n--index-url https://pypi.org\nreal-dep\n")
|
||||
f.flush()
|
||||
deps = parse_requirements_txt(f.name)
|
||||
os.unlink(f.name)
|
||||
self.assertEqual(len(deps), 1)
|
||||
self.assertEqual(deps[0].name, "real-dep")
|
||||
|
||||
|
||||
class TestParsePackageJson(unittest.TestCase):
|
||||
def test_basic(self):
|
||||
data = {
|
||||
"dependencies": {"express": "^4.18.0", "lodash": "^4.17.21"},
|
||||
"devDependencies": {"jest": "^29.0.0"},
|
||||
}
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||
json.dump(data, f)
|
||||
f.flush()
|
||||
deps = parse_package_json(f.name)
|
||||
os.unlink(f.name)
|
||||
names = [d.name for d in deps]
|
||||
self.assertIn("express", names)
|
||||
self.assertIn("jest", names)
|
||||
self.assertEqual(len(deps), 3)
|
||||
|
||||
|
||||
class TestParseGoMod(unittest.TestCase):
|
||||
def test_basic(self):
|
||||
content = """module example.com/mymod
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
)
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".mod", delete=False) as f:
|
||||
f.write(content)
|
||||
f.flush()
|
||||
deps = parse_go_mod(f.name)
|
||||
os.unlink(f.name)
|
||||
self.assertEqual(len(deps), 2)
|
||||
self.assertEqual(deps[0].name, "github.com/gin-gonic/gin")
|
||||
|
||||
|
||||
class TestDetectProjectLicense(unittest.TestCase):
|
||||
def test_mit_file(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
with open(os.path.join(d, "LICENSE"), "w") as f:
|
||||
f.write("MIT License\n\nCopyright (c) 2024...\n")
|
||||
self.assertEqual(detect_project_license(d), "MIT")
|
||||
|
||||
def test_apache_file(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
with open(os.path.join(d, "LICENSE"), "w") as f:
|
||||
f.write("Apache License Version 2.0...")
|
||||
self.assertEqual(detect_project_license(d), "Apache-2.0")
|
||||
|
||||
def test_no_license(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
self.assertEqual(detect_project_license(d), "UNKNOWN")
|
||||
|
||||
|
||||
class TestScanDeps(unittest.TestCase):
|
||||
def test_multi_ecosystem(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
with open(os.path.join(d, "requirements.txt"), "w") as f:
|
||||
f.write("flask\nrequests\n")
|
||||
with open(os.path.join(d, "package.json"), "w") as f:
|
||||
json.dump({"dependencies": {"express": "^4.0.0"}}, f)
|
||||
deps = scan_dep_files(d)
|
||||
names = [d.name for d in deps]
|
||||
self.assertIn("flask", names)
|
||||
self.assertIn("express", names)
|
||||
|
||||
|
||||
class TestGenerateReport(unittest.TestCase):
|
||||
def test_basic(self):
|
||||
deps = [
|
||||
DepLicense(name="flask", license="BSD-3-Clause", source="requirements.txt"),
|
||||
DepLicense(name="gpl-pkg", license="GPL-3.0", source="requirements.txt"),
|
||||
DepLicense(name="unknown-pkg", license="UNKNOWN", source="requirements.txt"),
|
||||
]
|
||||
report = generate_report(deps, "MIT")
|
||||
self.assertEqual(report.summary["ok"], 1)
|
||||
self.assertEqual(report.summary["error"], 1)
|
||||
self.assertEqual(report.summary["warning"], 1)
|
||||
self.assertEqual(len(report.errors), 1)
|
||||
self.assertIn("gpl-pkg", report.errors[0])
|
||||
|
||||
def test_format_text(self):
|
||||
deps = [DepLicense(name="flask", license="BSD-3-Clause", source="requirements.txt")]
|
||||
report = generate_report(deps, "MIT")
|
||||
text = format_text(report)
|
||||
self.assertIn("LICENSE COMPATIBILITY REPORT", text)
|
||||
self.assertIn("flask", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user