-
-
Notifications
You must be signed in to change notification settings - Fork 745
Expand file tree
/
Copy pathtest_required_phrases.py
More file actions
276 lines (223 loc) · 9.94 KB
/
Copy pathtest_required_phrases.py
File metadata and controls
276 lines (223 loc) · 9.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#
# Copyright (c) nexB Inc. and others. All rights reserved.
# ScanCode is a trademark of nexB Inc.
# SPDX-License-Identifier: Apache-2.0
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
# See https://github.com/nexB/scancode-toolkit for support or download.
# See https://aboutcode.org for more information about nexB OSS projects.
#
from unittest import TestCase as TestCaseClass
import pytest
from licensedcode.models import InvalidRule
from licensedcode.models import Rule
from licensedcode.required_phrases import update_rules_using_is_required_phrases_rules
from licensedcode.required_phrases import update_rules_using_license_attributes
from licensedcode.required_phrases import IsRequiredPhrase
from licensedcode.required_phrases import add_required_phrase_markers
from licensedcode.spans import Span
from licensedcode.required_phrases import find_phrase_spans_in_text
from licensedcode.tokenize import get_existing_required_phrase_spans
class TestIsRequiredPhraseCanSort(TestCaseClass):
required_phrase_texts = [
"mit",
"the MIT License",
"MIT License with Disclaimer",
"licenses: mit",
"MIT license",
]
is_required_phrases = [
IsRequiredPhrase(
required_phrase_text=text,
rule=Rule(
license_expression="mit",
identifier="mit_231.RULE",
text=text,
is_required_phrase=True,
is_license_tag=True,
)
)
for text in required_phrase_texts
]
def test_sort_is_required_phrases_works(self):
srps = IsRequiredPhrase.sorted(self.is_required_phrases)
results = [srp.required_phrase_text for srp in srps]
expected = [
"MIT License with Disclaimer",
"the MIT License",
"licenses: mit",
"MIT license",
"mit",
]
assert results == expected
class TestFindPhraseInText:
text_with_stopwords = (
"A copy of the GNU General Public License is available as "
"/usr/share/common-licenses/GPL-2 in the Debian GNU/Linux distribution. "
"A copy of the GNU General Public License is available as "
"/usr/share/common-licenses/GPL-2 in the Debian GNU/Linux distribution."
)
text_with_stopwords_and_marked_required_phrases = (
"A copy of the GNU General Public License is available as "
"/{{usr/share/common-licenses/GPL-2}} in the Debian GNU/Linux distribution. "
"A copy of the GNU General Public License is available as "
"/{{usr/share/common-licenses/GPL-2}} in the Debian GNU/Linux distribution."
)
def test_find_phrase_spans_in_text_with_behaves_same_as_get_existing_required_phrase_spans(self):
spans_with_phrase = find_phrase_spans_in_text(
text=self.text_with_stopwords,
phrase_text="usr share common licenses gpl 2",
)
spans_with_find = get_existing_required_phrase_spans(
text=self.text_with_stopwords_and_marked_required_phrases,
)
assert spans_with_phrase == spans_with_find
def test_find_phrase_spans_in_text_and_add_required_phrase_matches(self):
spans = find_phrase_spans_in_text(
text=self.text_with_stopwords,
phrase_text="usr share common licenses gpl 2",
)
text = self.text_with_stopwords
for span in spans:
text = add_required_phrase_markers(
text=text,
required_phrase_span=span,
)
assert text == self.text_with_stopwords_and_marked_required_phrases
class TestFindSpansInText:
text_with_articles = (
"A copy of the GNU General Public License is available as "
"/usr/share/common-licenses/GPL-2 in the Debian GNU/Linux distribution. "
"A copy of the GNU General Public License is available as "
"/usr/share/common-licenses/GPL-2 in the Debian GNU/Linux distribution."
)
text_with_articles_and_marked_required_phrases = (
"A copy of the GNU General Public License is available as "
"/{{usr/share/common-licenses/GPL-2}} in the Debian GNU/Linux distribution. "
"A copy of the GNU General Public License is available as "
"/{{usr/share/common-licenses/GPL-2}} in the Debian GNU/Linux distribution."
)
text_with_extra_characters = (
"This is the http://www.opensource.org/licenses/mit-license.php MIT "
"Software License which is OSI-certified, and GPL-compatible."
)
text_with_extra_characters_and_marked_required_phrases = (
"This is the http://www.opensource.org/licenses/mit-license.php {{MIT "
"Software License}} which is OSI-certified, and GPL-compatible."
)
def test_find_phrase_spans_in_text(self):
text = "is released under the MIT license. See the LICENSE"
spans = find_phrase_spans_in_text(text=text, phrase_text="mit license")
assert spans == [Span(4, 5)]
def test_find_phrase_spans_in_text_multiple(self):
spans = find_phrase_spans_in_text(
text=self.text_with_articles,
phrase_text="usr share common licenses gpl 2",
)
assert spans == [Span(10, 15), Span(32, 37)]
def test_find_phrase_spans_in_text_then_add_with_multiple_spans(self):
spans = find_phrase_spans_in_text(
text=self.text_with_articles,
phrase_text="usr share common licenses gpl 2",
)
text = self.text_with_articles
for span in spans:
text = add_required_phrase_markers(
text=text,
required_phrase_span=span,
)
assert text == self.text_with_articles_and_marked_required_phrases
def test_add_required_phrase_markers_in_text_with_extra_characters(self):
spans = find_phrase_spans_in_text(
text=self.text_with_extra_characters,
phrase_text="mit software license",
)
text = self.text_with_extra_characters
for span in spans:
text = add_required_phrase_markers(
text=text,
required_phrase_span=span,
)
assert text == self.text_with_extra_characters_and_marked_required_phrases
class TestKeyPhrasesCanBeMarked(TestCaseClass):
@pytest.mark.scanslow
def test_update_rules_using_is_required_phrases_rules(self):
update_rules_using_is_required_phrases_rules(verbose=True, dry_run=True)
@pytest.mark.scanslow
def test_update_rules_using_license_attributes(self):
update_rules_using_license_attributes(verbose=True, dry_run=True)
@pytest.mark.scanslow
def test_update_composite_rules_using_license_attributes(self):
from licensedcode.required_phrases import update_composite_rules_using_license_attributes
update_composite_rules_using_license_attributes(verbose=True, dry_run=True)
class TestCompositeRulesAnnotation(TestCaseClass):
def test_composite_rule_marks_both_phrases(self):
from licensedcode.required_phrases import add_required_phrase_to_rule
rule = Rule(
license_expression="mit AND apache-2.0",
identifier="mit_and_apache-2.0_test.RULE",
text="Licensed under the MIT License or the Apache License.",
is_license_notice=True,
)
added_mit = add_required_phrase_to_rule(
rule=rule,
required_phrase="MIT License",
source="composite",
dry_run=True,
)
assert added_mit
assert "{{MIT License}}" in rule.text
added_apache = add_required_phrase_to_rule(
rule=rule,
required_phrase="Apache License",
source="composite",
dry_run=True,
)
assert added_apache
assert "{{Apache License}}" in rule.text
def test_composite_rule_no_double_marking(self):
from licensedcode.required_phrases import add_required_phrase_to_rule
rule = Rule(
license_expression="mit AND apache-2.0",
identifier="mit_and_apache-2.0_test.RULE",
text="Licensed under the {{MIT License}} or the Apache License.",
is_license_notice=True,
)
added = add_required_phrase_to_rule(
rule=rule,
required_phrase="MIT License",
source="composite",
dry_run=True,
)
assert not added
def test_composite_rule_three_keys_all_marked(self):
from licensedcode.required_phrases import add_required_phrase_to_rule
rule = Rule(
license_expression="mit AND apache-2.0 AND bsd-new",
identifier="triple_test.RULE",
text="Dual licensed: MIT License, Apache License, and BSD License.",
is_license_notice=True,
)
add_required_phrase_to_rule(rule=rule, required_phrase="MIT License", source="", dry_run=True)
add_required_phrase_to_rule(rule=rule, required_phrase="Apache License", source="", dry_run=True)
add_required_phrase_to_rule(rule=rule, required_phrase="BSD License", source="", dry_run=True)
assert "{{MIT License}}" in rule.text
assert "{{Apache License}}" in rule.text
assert "{{BSD License}}" in rule.text
def test_composite_rule_overlapping_spans_handled(self):
from licensedcode.required_phrases import add_required_phrase_to_rule
rule = Rule(
license_expression="mit AND mit-0",
identifier="overlap_test.RULE",
text="Released under the MIT License terms.",
is_license_notice=True,
)
added = add_required_phrase_to_rule(
rule=rule, required_phrase="MIT License", source="", dry_run=True,
)
assert added
assert "{{MIT License}}" in rule.text
# "MIT" overlaps with already marked span, should not double mark
added2 = add_required_phrase_to_rule(
rule=rule, required_phrase="MIT", source="", dry_run=True,
)
assert not added2