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