def test_spdx_info_of_directory(empty_directory): """Raise IsADirectoryError when calling spdx_info_of on a directory.""" (empty_directory / "src").mkdir() project = Project(empty_directory) with pytest.raises(IsADirectoryError): project.spdx_info_of(empty_directory / "src")
def test_all_files(empty_directory): """Given a directory with some files, yield all files.""" (empty_directory / "foo").touch() (empty_directory / "bar").touch() project = Project(empty_directory) assert {file_.name for file_ in project.all_files()} == {"foo", "bar"}
def test_spdx_info_of_unlicensed_file(fake_repository): """Return an empty SpdxInfo object when asking for the SPDX information of a file that has no SPDX information. """ (fake_repository / "foo.py").touch() project = Project(fake_repository) assert not any(project.spdx_info_of("foo.py"))
def test_all_files_ignore_dot_license(empty_directory): """When file and file.license are present, only yield file.""" (empty_directory / "foo").touch() (empty_directory / "foo.license").touch() project = Project(empty_directory) assert {file_.name for file_ in project.all_files()} == {"foo"}
def test_all_files_ignore_git(empty_directory): """When the git directory is present, ignore it.""" (empty_directory / ".git").mkdir() (empty_directory / ".git/config").touch() project = Project(empty_directory) assert not list(project.all_files())
def test_all_files_ignore_shl_license(empty_directory): """SHL-2.1 contains an SPDX tag referencing itself. It should be skipped.""" (empty_directory / "SHL-2.1").write_text("foo") (empty_directory / "SHL-2.1.txt").write_text("foo") project = Project(empty_directory) assert not list(project.all_files())
def test_spdx_info_of_file_does_not_exist(fake_repository): """Raise FileNotFoundError when asking for the SPDX info of a file that does not exist. """ project = Project(fake_repository) with pytest.raises(FileNotFoundError): project.spdx_info_of(fake_repository / "does_not_exist")
def test_spdx_info_of_binary_succeeds(fake_repository): """spdx_info_of succeeds when the target is covered by dep5.""" shutil.copy(RESOURCES_DIRECTORY / "fsfe.png", fake_repository / "doc/fsfe.png") project = Project(fake_repository) spdx_info = project.spdx_info_of("doc/fsfe.png") assert LicenseSymbol("CC0-1.0") in spdx_info.spdx_expressions
def test_all_files_submodule_is_ignored(submodule_repository): """If a submodule is ignored, all_files should not raise an Exception.""" (submodule_repository / "submodule/foo.py").write_text("foo") gitignore = submodule_repository / ".gitignore" contents = gitignore.read_text() contents += "\nsubmodule/\n" gitignore.write_text(contents) project = Project(submodule_repository) assert Path("submodule/foo.py").absolute() not in project.all_files()
def test_all_files_git_ignored_different_cwd(git_repository): """Given a Git repository where some files are ignored, do not yield those files. Be in a different CWD during the above. """ os.chdir(git_repository / "LICENSES") project = Project(git_repository) assert Path("build/hello.py").absolute() not in project.all_files()
def test_spdx_info_of_only_copyright(fake_repository): """A file contains only a copyright line. Test whether it correctly picks up on that. """ (fake_repository / "foo.py").write_text("SPDX-Copyright: 2017 Mary Sue") project = Project(fake_repository) spdx_info = project.spdx_info_of("foo.py") assert not any(spdx_info.spdx_expressions) assert len(spdx_info.copyright_lines) == 1 assert spdx_info.copyright_lines.pop() == "2017 Mary Sue"
def test_all_files_on_single_file(empty_directory): """When a file is given as parameter instead of a directory, just yield the file. """ (empty_directory / "foo").touch() project = Project(empty_directory) result = list(project.all_files(empty_directory / "foo")) assert len(result) == 1 assert result[0].name == "foo"
def test_all_files_ignore_cal_license(empty_directory): """CAL licenses contain SPDX tags referencing themselves. They should be skipped. """ (empty_directory / "CAL-1.0").write_text("foo") (empty_directory / "CAL-1.0.txt").write_text("foo") (empty_directory / "CAL-1.0-Combined-Work-Exception").write_text("foo") (empty_directory / "CAL-1.0-Combined-Work-Exception.txt").write_text("foo") project = Project(empty_directory) assert not list(project.all_files())
def test_spdx_info_of_only_copyright_also_covered_by_debian(fake_repository): """A file contains only a copyright line, but debian/copyright also has information on this file. Use both. """ (fake_repository / "doc/foo.py").write_text("SPDX-Copyright: in file") project = Project(fake_repository) spdx_info = project.spdx_info_of("doc/foo.py") assert any(spdx_info.spdx_expressions) assert len(spdx_info.copyright_lines) == 2 assert "in file" in spdx_info.copyright_lines assert "2017 Mary Sue" in spdx_info.copyright_lines
def test_all_files_symlinks(empty_directory): """All symlinks must be ignored.""" (empty_directory / "blob").write_text("foo") (empty_directory / "blob.license").write_text( cleandoc(""" spdx-FileCopyrightText: Jane Doe spdx-License-Identifier: GPL-3.0-or-later """).replace("spdx", "SPDX")) (empty_directory / "symlink").symlink_to("blob") project = Project(empty_directory) assert Path("symlink").absolute() not in project.all_files()
def test_relative_from_root_no_shared_base_path(empty_directory): """A path can still be relative from root if the paths do not have a common prefix. For instance, if root is /path/to/root and given root/src/hello.py from the directory /path/to, return src/hello.py. This is a bit involved, but works out. """ project = Project(empty_directory) parent = empty_directory.parent os.chdir(parent) assert project.relative_from_root( Path(f"{project.root.name}/src/hello.py")) == Path("src/hello.py")
def test_license_file_detected(empty_directory): """Test whether---when given a file and a license file---the license file is detected and read. """ (empty_directory / "foo.py").touch() (empty_directory / "foo.py.license").write_text( "SPDX-Copyright: 2017 Mary Sue\nSPDX-License-Identifier: MIT\n") project = Project(empty_directory) spdx_info = project.spdx_info_of("foo.py") assert "2017 Mary Sue" in spdx_info.copyright_lines assert LicenseSymbol("MIT") in spdx_info.spdx_expressions
def test_spdx_info_of_also_covered_by_dep5(fake_repository): """A file contains all SPDX information, but .reuse/dep5 also provides information on this file. Use both. """ (fake_repository / "doc/foo.py").write_text( dedent(""" SPDX-License-Identifier: MIT SPDX-FileCopyrightText: in file""")) project = Project(fake_repository) spdx_info = project.spdx_info_of("doc/foo.py") assert LicenseSymbol("MIT") in spdx_info.spdx_expressions assert LicenseSymbol("CC0-1.0") in spdx_info.spdx_expressions assert "SPDX-FileCopyrightText: in file" in spdx_info.copyright_lines assert "2017 Mary Sue" in spdx_info.copyright_lines
def test_spdx_info_of_no_duplicates(empty_directory): """A file contains the same lines twice. The SpdxInfo only contains those lines once. """ spdx_line = "SPDX-License-Identifier: GPL-3.0-or-later\n" copyright_line = "SPDX-Copyright: 2017 Free Software Foundation Europe\n" text = spdx_line + copyright_line (empty_directory / "foo.py").write_text(text * 2) project = Project(empty_directory) spdx_info = project.spdx_info_of("foo.py") assert len(spdx_info.spdx_expressions) == 1 assert LicenseSymbol("GPL-3.0-or-later") in spdx_info.spdx_expressions assert len(spdx_info.copyright_lines) == 1 assert "2017 Free Software Foundation Europe" in spdx_info.copyright_lines
def test_detect_all_licenses(empty_directory): """In a directory where licenses are marked through various means, detect all of them. """ license_files = ["COPYING", "LICENSE", "COPYRIGHT", "LICENSES/foo"] (empty_directory / "LICENSES").mkdir() counter = 1 for lic in license_files: (empty_directory / lic).write_text( "Valid-License-Identifier: LicenseRef-{}".format(counter)) counter += 1 (empty_directory / "LICENSES/MIT.txt").write_text("nothing") (empty_directory / "LICENSES/LicenseRef-{}.txt".format(counter)).write_text("nothing") project = Project(empty_directory) assert len(project.licenses) == 6 assert all( [Path(lic) in project.licenses.values() for lic in license_files]) assert Path("LICENSES/MIT.txt") in project.licenses.values() assert (Path("LICENSES/LicenseRef-{}.txt".format(counter)) in project.licenses.values())
def test_licenses_empty(empty_directory, license_file): """If the identifier of a license could not be identified, silently carry on.""" (empty_directory / "LICENSES").mkdir() (empty_directory / license_file).touch() project = Project(empty_directory) assert "LicenseRef-Unknown0" in project.licenses
def test_lint_submodule(submodule_repository): """Extremely simple test for lint with an ignored submodule.""" project = Project(submodule_repository) (submodule_repository / "submodule/foo.c").touch() report = ProjectReport.generate(project) result = lint(report) assert result
def test_licenses_duplicate(empty_directory): """Raise a RuntimeError if multiple files resolve to the same license.""" text = "Valid-License-Identifier: MIT" (empty_directory / "COPYING").write_text(text) (empty_directory / "LICENSE").write_text(text) with pytest.raises(RuntimeError): Project(empty_directory)
def test_lint_submodule_included(submodule_repository): """Extremely simple test for lint with an included submodule.""" project = Project(submodule_repository, include_submodules=True) (submodule_repository / "submodule/foo.c").write_text("foo") report = ProjectReport.generate(project) result = lint(report) assert not result
def test_licenses_empty(empty_directory): """If the identifier of a license could not be identified, silently carry on.""" (empty_directory / "LICENSES").mkdir() (empty_directory / "LICENSES/foo.txt").touch() project = Project(empty_directory) assert "foo" in project.licenses
def test_generate_project_report_bad_license_in_file(fake_repository): """Bad licenses in files are detected.""" (fake_repository / "foo.py").write_text("SPDX" "-License-Identifier: bad") project = Project(fake_repository) result = ProjectReport.generate(project) assert "bad" in result.bad_licenses
def test_lint_unused_licenses(fake_repository, stringio): """An unused license is detected.""" (fake_repository / "LICENSES/MIT.txt").write_text("foo") project = Project(fake_repository) report = ProjectReport.generate(project) lint_summary(report, out=stringio) assert "MIT" in stringio.getvalue()
def test_generate_project_report_missing_license(fake_repository): """Missing licenses are detected.""" (fake_repository / "LICENSES/GPL-3.0-or-later.txt").unlink() project = Project(fake_repository) result = ProjectReport.generate(project) assert "GPL-3.0-or-later" in result.missing_licenses assert not result.bad_licenses
def test_generate_project_report_simple(fake_repository): """Simple generate test, just to see if it sort of works.""" project = Project(fake_repository) result = ProjectReport.generate(project) assert not result.missing_licenses assert not result.bad_licenses assert not result.read_errors assert result.file_reports
def test_generate_project_report_read_error(fake_repository): """Files that cannot be read are added to the read error list.""" (fake_repository / "bad").symlink_to("does_not_exist") project = Project(fake_repository) result = ProjectReport.generate(project) # pylint: disable=superfluous-parens assert (fake_repository / "bad") in result.read_errors