1#
2# SPDX-License-Identifier: MIT
3#
4
5from unittest.case import TestCase
6import oe.license
7
8class SeenVisitor(oe.license.LicenseVisitor):
9    def __init__(self):
10        self.seen = []
11        oe.license.LicenseVisitor.__init__(self)
12
13    def visit_Str(self, node):
14        self.seen.append(node.s)
15
16class TestSingleLicense(TestCase):
17    licenses = [
18        "GPLv2",
19        "LGPL-2.0",
20        "Artistic",
21        "MIT",
22        "GPLv3+",
23        "FOO_BAR",
24    ]
25    invalid_licenses = ["GPL/BSD"]
26
27    @staticmethod
28    def parse(licensestr):
29        visitor = SeenVisitor()
30        visitor.visit_string(licensestr)
31        return visitor.seen
32
33    def test_single_licenses(self):
34        for license in self.licenses:
35            licenses = self.parse(license)
36            self.assertListEqual(licenses, [license])
37
38    def test_invalid_licenses(self):
39        for license in self.invalid_licenses:
40            with self.assertRaises(oe.license.InvalidLicense) as cm:
41                self.parse(license)
42            self.assertEqual(cm.exception.license, license)
43
44class TestSimpleCombinations(TestCase):
45    tests = {
46        "FOO&BAR": ["FOO", "BAR"],
47        "BAZ & MOO": ["BAZ", "MOO"],
48        "ALPHA|BETA": ["ALPHA"],
49        "BAZ&MOO|FOO": ["FOO"],
50        "FOO&BAR|BAZ": ["FOO", "BAR"],
51    }
52    preferred = ["ALPHA", "FOO", "BAR"]
53
54    def test_tests(self):
55        def choose(a, b):
56            if all(lic in self.preferred for lic in b):
57                return b
58            else:
59                return a
60
61        for license, expected in self.tests.items():
62            licenses = oe.license.flattened_licenses(license, choose)
63            self.assertListEqual(licenses, expected)
64
65class TestComplexCombinations(TestSimpleCombinations):
66    tests = {
67        "FOO & (BAR | BAZ)&MOO": ["FOO", "BAR", "MOO"],
68        "(ALPHA|(BETA&THETA)|OMEGA)&DELTA": ["OMEGA", "DELTA"],
69        "((ALPHA|BETA)&FOO)|BAZ": ["BETA", "FOO"],
70        "(GPL-2.0|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0", "BSD-4-clause", "MIT"],
71    }
72    preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0"]
73
74class TestIsIncluded(TestCase):
75    tests = {
76        ("FOO | BAR", None, None):
77            [True, ["FOO"]],
78        ("FOO | BAR", None, "FOO"):
79            [True, ["BAR"]],
80        ("FOO | BAR", "BAR", None):
81            [True, ["BAR"]],
82        ("FOO | BAR & FOOBAR", "*BAR", None):
83            [True, ["BAR", "FOOBAR"]],
84        ("FOO | BAR & FOOBAR", None, "FOO*"):
85            [False, ["FOOBAR"]],
86        ("(FOO | BAR) & FOOBAR | BARFOO", None, "FOO"):
87            [True, ["BAR", "FOOBAR"]],
88        ("(FOO | BAR) & FOOBAR | BAZ & MOO & BARFOO", None, "FOO"):
89            [True, ["BAZ", "MOO", "BARFOO"]],
90        ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, None):
91            [True, ["GPL-3.0", "GPL-2.0", "LGPL-2.1"]],
92        ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0"):
93            [True, ["Proprietary"]],
94        ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0 Proprietary"):
95            [False, ["GPL-3.0"]]
96    }
97
98    def test_tests(self):
99        for args, expected in self.tests.items():
100            is_included, licenses = oe.license.is_included(
101                args[0], (args[1] or '').split(), (args[2] or '').split())
102            self.assertEqual(is_included, expected[0])
103            self.assertListEqual(licenses, expected[1])
104