From 00b6e7a42de669428cdda7b946f5e6f82ef2b31a Mon Sep 17 00:00:00 2001 From: "John M. Horan" Date: Mon, 26 Feb 2018 15:32:05 -0800 Subject: [PATCH 1/7] Add 'Copyright' class #82 * Create 'Copyright' class. * Add 'Copyright' to 'File' object. * Add empty lists for 'copyrights' and 'licenses' fields to 'File.to_dict()'. * Add new tests, fix failing tests. Signed-off-by: John M. Horan --- src/deltacode/models.py | 51 +++++++++- tests/test_cli.py | 66 ++++++++++++ tests/test_deltacode.py | 96 +++++++++++------- tests/test_models.py | 215 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 377 insertions(+), 51 deletions(-) diff --git a/src/deltacode/models.py b/src/deltacode/models.py index 46d5ce00..33f25d53 100644 --- a/src/deltacode/models.py +++ b/src/deltacode/models.py @@ -161,6 +161,7 @@ def __init__(self, dictionary={}): self.sha1 = dictionary.get('sha1', '') self.original_path = '' self.licenses = self.get_licenses(dictionary) if dictionary.get('licenses') else [] + self.copyrights = self.get_copyrights(dictionary) if dictionary.get('copyrights') else [] def get_licenses(self, dictionary): if dictionary.get('licenses') == []: @@ -168,6 +169,12 @@ def get_licenses(self, dictionary): else: return [License(l) for l in dictionary.get('licenses')] + def get_copyrights(self, dictionary): + if dictionary.get('copyrights') == []: + return [] + else: + return [Copyright(l) for l in dictionary.get('copyrights')] + def to_dict(self): d = OrderedDict([ ('path', self.path), @@ -180,6 +187,13 @@ def to_dict(self): if self.licenses: d['licenses'] = [l.to_dict() for l in self.licenses] + else: + d['licenses'] = [] + + if self.copyrights: + d['copyrights'] = [l.to_dict() for l in self.copyrights] + else: + d['copyrights'] = [] return d @@ -199,7 +213,8 @@ def __repr__(self): class License(object): """ - License object created from the 'license' field in an ABCD formatted 'file' dictionary. + License object created from the 'license' field in an ABCD formatted 'file' + dictionary. """ def __init__(self, dictionary={}): self.key = dictionary.get('key') @@ -225,7 +240,39 @@ def to_dict(self): def __repr__(self): """ - Return string containing a printable representation of the License object. + Return string containing a printable representation of the License + object. + """ + return "%s" % self.__dict__ + + +class Copyright(object): + """ + Copyright object created from the 'copyrights' field in an ABCD formatted + 'file' dictionary. + """ + def __init__(self, dictionary={}): + self.statements = dictionary.get('statements') + self.holders = dictionary.get('holders') + self.authors = dictionary.get('authors') + + def to_dict(self): + """ + Given a Copyright object, return an OrderedDict with the full + set of fields from the ScanCode 'copyrights' value. + """ + d = OrderedDict([ + ('statements', self.statements), + ('holders', self.holders), + ('authors', self.authors) + ]) + + return d + + def __repr__(self): + """ + Return string containing a printable representation of the Copyright + object. """ return "%s" % self.__dict__ diff --git a/tests/test_cli.py b/tests/test_cli.py index 1ccf6154..37f8c717 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -313,6 +313,17 @@ def test_json_output_option_selected_all_selected(self): "category": "Permissive", "owner": "Apache Software Foundation" } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [] + } ] }, "old": { @@ -330,6 +341,17 @@ def test_json_output_option_selected_all_selected(self): "category": "Permissive", "owner": "Apache Software Foundation" } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [] + } ] } } @@ -356,6 +378,17 @@ def test_json_output_option_selected_all_selected(self): "category": "Permissive", "owner": "Apache Software Foundation" } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [] + } ] }, "old": { @@ -373,6 +406,17 @@ def test_json_output_option_selected_all_selected(self): "category": "Permissive", "owner": "Apache Software Foundation" } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [] + } ] } } @@ -427,6 +471,17 @@ def test_json_output_option_selected_all_not_selected(self): "category": "Permissive", "owner": "Apache Software Foundation" } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [] + } ] }, "old": { @@ -444,6 +499,17 @@ def test_json_output_option_selected_all_not_selected(self): "category": "Permissive", "owner": "Apache Software Foundation" } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [] + } ] } } diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index f4604fd3..6bd4a053 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -208,7 +208,9 @@ def test_Delta_one_None(self): ('name', ''), ('size', ''), ('sha1', ''), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])) ]) @@ -221,7 +223,9 @@ def test_Delta_one_None(self): ('name', ''), ('size', ''), ('sha1', ''), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])), ('old', None) ]) @@ -379,7 +383,9 @@ def test_Delta_to_dict_removed(self): ('name', 'removed.txt'), ('size', 20), ('sha1', 'a'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])) ]) @@ -407,7 +413,9 @@ def test_Delta_to_dict_added(self): ('name', 'added.txt'), ('size', 20), ('sha1', 'a'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])), ('old', None) ]) @@ -444,7 +452,9 @@ def test_Delta_to_dict_modified(self): ('name', 'modified.txt'), ('size', 20), ('sha1', 'a'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])), ('old', OrderedDict([ ('path', 'path/modified.txt'), @@ -452,7 +462,9 @@ def test_Delta_to_dict_modified(self): ('name', 'modified.txt'), ('size', 21), ('sha1', 'b'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])) ]) @@ -488,7 +500,9 @@ def test_Delta_to_dict_unmodified(self): ('name', 'unmodified.txt'), ('size', 20), ('sha1', 'a'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])), ('old', OrderedDict([ ('path', 'path/unmodified.txt'), @@ -496,7 +510,9 @@ def test_Delta_to_dict_unmodified(self): ('name', 'unmodified.txt'), ('size', 20), ('sha1', 'a'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])) ]) @@ -532,7 +548,9 @@ def test_Delta_to_dict_moved(self): ('name', 'moved.txt'), ('size', 20), ('sha1', 'a'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])), ('old', OrderedDict([ ('path', 'path_old/moved.txt'), @@ -540,7 +558,9 @@ def test_Delta_to_dict_moved(self): ('name', 'moved.txt'), ('size', 20), ('sha1', 'a'), - ('original_path', '') + ('original_path', ''), + ('licenses', []), + ('copyrights', []) ])) ]) @@ -646,8 +666,8 @@ def test_score_new_no_lic_info(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -663,7 +683,7 @@ def test_score_new_no_lic_info(self): ('owner', None) ]) ] - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == None + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] def test_score_new_no_lic_info_below_cutoff_score(self): new_scan = self.get_test_loc('deltacode/score_new_no_lic_info_below_cutoff_score_new.json') @@ -679,8 +699,8 @@ def test_score_new_no_lic_info_below_cutoff_score(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -696,7 +716,7 @@ def test_score_new_no_lic_info_below_cutoff_score(self): ('owner', None) ]) ] - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == None + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] def test_score_old_no_lic_info(self): new_scan = self.get_test_loc('deltacode/score_old_no_lic_info_new.json') @@ -712,15 +732,15 @@ def test_score_old_no_lic_info(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [40] assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info added'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('key', 'mit'), @@ -745,15 +765,15 @@ def test_score_old_no_lic_info_below_cutoff_score(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [40] assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info added'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('key', 'mit'), @@ -778,8 +798,8 @@ def test_score_multiple_lic_keys(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -826,8 +846,8 @@ def test_score_new_lic_below_cutoff_score(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -867,8 +887,8 @@ def test_score_old_lic_below_cutoff_score(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -908,8 +928,8 @@ def test_score_no_lic_change(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -949,8 +969,8 @@ def test_score_new_multiple_keys_same_lic(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -997,8 +1017,8 @@ def test_score_multiple_lic_keys_new_below_cutoff_score(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -1052,8 +1072,8 @@ def test_score_multiple_lic_keys_old_below_cutoff_score(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] @@ -1107,8 +1127,8 @@ def test_score_single_lic_change(self): assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] - assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None - assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == None + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] diff --git a/tests/test_models.py b/tests/test_models.py index 0e165f93..3e5e4520 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -481,15 +481,16 @@ def test_File_to_dict_simple_w_license(self): 'size': 20, 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', 'original_path': '', - 'licenses': [ - { - "key": "apache-2.0", - "score": 80.0, - "short_name": "Apache 2.0", - "category": "Permissive", - "owner": "Apache Software Foundation" - } - ] + 'licenses': [ + { + "key": "apache-2.0", + "score": 80.0, + "short_name": "Apache 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation" + } + ], + 'copyrights': [] } result = models.File(data).to_dict() @@ -513,7 +514,9 @@ def test_File_to_dict_simple(self): 'name': 'file1.txt', 'size': 20, 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', - 'original_path': '' + 'original_path': '', + 'licenses': [], + 'copyrights': [] } result = models.File(data).to_dict() @@ -529,7 +532,9 @@ def test_File_to_dict_empty(self): 'name': '', 'size': '', 'sha1': '', - 'original_path': '' + 'original_path': '', + 'licenses': [], + 'copyrights': [] } result = empty_file.to_dict() @@ -574,6 +579,7 @@ def test_File_create_object_license_one(self): assert 'file1.txt' == result.name assert 20 == result.size assert '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b' == result.sha1 + assert [] == result.copyrights assert len(result.licenses) == 1 assert result.licenses[0].key == 'apache-2.0' with pytest.raises(AttributeError): @@ -597,6 +603,7 @@ def test_File_create_object_license_none(self): assert 20 == result.size assert '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b' == result.sha1 assert [] == result.licenses + assert [] == result.copyrights def test_File_create_object_license_missing(self): data = { @@ -620,6 +627,7 @@ def test_File_empty(self): assert empty_file.size == '' assert empty_file.sha1 == '' assert empty_file.licenses == [] + assert empty_file.copyrights == [] def test_File_create_object(self): data = { @@ -650,3 +658,188 @@ def test_File_size_difference(self): b['size'] = 8192 b_file = models.File(b) assert -4096 == a_file.size_difference(b_file) + + def test_Copyright_to_dict_simple(self): + data = { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + "holders": [ + "Jean-loup Gailly, Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + + expected = { + 'statements': [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + 'holders': [ + "Jean-loup Gailly, Mark Adler" + ], + 'authors': [] + } + + result = models.Copyright(data).to_dict() + + assert result == expected + with pytest.raises(AttributeError): + assert result.made_up_key == "a_string" + + def test_Copyright_to_dict_empty(self): + result = models.Copyright().to_dict() + + for k,v in result.items(): + assert v == None + + def test_Copyright_object_simple(self): + data = { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + "holders": [ + "Jean-loup Gailly, Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + + result = models.Copyright(data) + + assert result.statements == [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ] + assert result.holders == [ + "Jean-loup Gailly, Mark Adler" + ] + assert result.authors == [] + with pytest.raises(AttributeError): + assert result.made_up_key == "a_string" + + def test_Copyright_object_empty(self): + result = models.Copyright() + + for attr, value in vars(result).items(): + assert value == None + + def test_File_to_dict_simple_w_copyright(self): + data = { + 'path': 'a/b/file1.txt', + 'type': 'file', + 'name': 'file1.txt', + 'size': 20, + 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', + 'licenses': [], + 'copyrights': [ + { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + "holders": [ + "Jean-loup Gailly, Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + + expected = { + 'path': 'a/b/file1.txt', + 'type': 'file', + 'name': 'file1.txt', + 'size': 20, + 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', + 'original_path': '', + 'licenses': [], + 'copyrights': [ + { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + "holders": [ + "Jean-loup Gailly, Mark Adler" + ], + "authors": [] + } + ] + } + + result = models.File(data).to_dict() + + assert result == expected + with pytest.raises(AttributeError): + assert result.made_up_key == "a_string" + + def test_File_create_object_copyright_one(self): + data = { + 'path': 'a/b/file1.txt', + 'type': 'file', + 'name': 'file1.txt', + 'size': 20, + 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', + 'licenses': [], + 'copyrights': [ + { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + "holders": [ + "Jean-loup Gailly, Mark Adler" + ], + "authors": [] + } + ] + } + + result = models.File(data) + + assert 'a/b/file1.txt' == result.path + assert 'file' == result.type + assert 'file1.txt' == result.name + assert 20 == result.size + assert '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b' == result.sha1 + assert [] == result.licenses + assert len(result.copyrights) == 1 + assert result.copyrights[0].statements == [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ] + with pytest.raises(AttributeError): + assert result.made_up_key == "a_string" + + def test_File_create_object_copyright_none(self): + data = { + 'path': 'a/b/file1.txt', + 'type': 'file', + 'name': 'file1.txt', + 'size': 20, + 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', + 'copyrights': [] + } + + result = models.File(data) + + assert 'a/b/file1.txt' == result.path + assert 'file' == result.type + assert 'file1.txt' == result.name + assert 20 == result.size + assert '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b' == result.sha1 + assert [] == result.licenses + assert [] == result.copyrights + + def test_File_create_object_copyright_missing(self): + data = { + 'path': 'a/b/file1.txt', + 'type': 'file', + 'name': 'file1.txt', + 'size': 20, + 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', + } + + result = models.File(data) + + assert [] == result.copyrights From f8f5861ec5528b216b4190fc86d45064d7fb53ad Mon Sep 17 00:00:00 2001 From: "John M. Horan" Date: Wed, 28 Feb 2018 17:30:44 -0800 Subject: [PATCH 2/7] Add copyright_diff() to DeltaCode object #83 * Add copyright_diff(). * Refactor license_diff(). * Add new tests and related test old/new scan pairs. Signed-off-by: John M. Horan --- src/deltacode/__init__.py | 69 +++- ..._copyright_and_license_info_added_new.json | 63 +++ ..._copyright_and_license_info_added_old.json | 29 ++ ...opyright_and_license_info_removed_new.json | 29 ++ ...opyright_and_license_info_removed_old.json | 63 +++ ...t_info_added_license_info_removed_new.json | 41 ++ ...t_info_added_license_info_removed_old.json | 51 +++ .../score_copyright_info_added_new.json | 39 ++ .../score_copyright_info_added_old.json | 29 ++ .../score_copyright_info_removed_new.json | 29 ++ .../score_copyright_info_removed_old.json | 39 ++ ...info_added_copyright_info_removed_new.json | 51 +++ ...info_added_copyright_info_removed_old.json | 41 ++ .../score_no_copyright_changes_new.json | 39 ++ .../score_no_copyright_changes_old.json | 39 ++ .../score_no_copyright_info_new.json | 29 ++ .../score_no_copyright_info_old.json | 29 ++ .../deltacode/score_no_copyright_key_new.json | 28 ++ .../deltacode/score_no_copyright_key_old.json | 28 ++ .../score_single_copyright_change_new.json | 39 ++ .../score_single_copyright_change_old.json | 39 ++ tests/test_deltacode.py | 391 ++++++++++++++++++ 22 files changed, 1220 insertions(+), 14 deletions(-) create mode 100644 tests/data/deltacode/score_copyright_and_license_info_added_new.json create mode 100644 tests/data/deltacode/score_copyright_and_license_info_added_old.json create mode 100644 tests/data/deltacode/score_copyright_and_license_info_removed_new.json create mode 100644 tests/data/deltacode/score_copyright_and_license_info_removed_old.json create mode 100644 tests/data/deltacode/score_copyright_info_added_license_info_removed_new.json create mode 100644 tests/data/deltacode/score_copyright_info_added_license_info_removed_old.json create mode 100644 tests/data/deltacode/score_copyright_info_added_new.json create mode 100644 tests/data/deltacode/score_copyright_info_added_old.json create mode 100644 tests/data/deltacode/score_copyright_info_removed_new.json create mode 100644 tests/data/deltacode/score_copyright_info_removed_old.json create mode 100644 tests/data/deltacode/score_license_info_added_copyright_info_removed_new.json create mode 100644 tests/data/deltacode/score_license_info_added_copyright_info_removed_old.json create mode 100644 tests/data/deltacode/score_no_copyright_changes_new.json create mode 100644 tests/data/deltacode/score_no_copyright_changes_old.json create mode 100644 tests/data/deltacode/score_no_copyright_info_new.json create mode 100644 tests/data/deltacode/score_no_copyright_info_old.json create mode 100644 tests/data/deltacode/score_no_copyright_key_new.json create mode 100644 tests/data/deltacode/score_no_copyright_key_old.json create mode 100644 tests/data/deltacode/score_single_copyright_change_new.json create mode 100644 tests/data/deltacode/score_single_copyright_change_old.json diff --git a/src/deltacode/__init__.py b/src/deltacode/__init__.py index a9edb389..f7dbcf27 100644 --- a/src/deltacode/__init__.py +++ b/src/deltacode/__init__.py @@ -57,6 +57,7 @@ def __init__(self, new_path, old_path, options): self.determine_delta() self.determine_moved() self.license_diff() + self.copyright_diff() # Sort deltas by score, descending, i.e., high > low. self.deltas.sort(key=lambda Delta: Delta.score, reverse=True) @@ -191,28 +192,68 @@ def license_diff(self): attribute -- if there has been a license change and depending on the nature of that change. """ - for i in self.deltas: - if 20 <= i.score < 100: + for delta in self.deltas: + if 20 <= delta.score < 100: - new_licenses = i.new_file.licenses or [] - old_licenses = i.old_file.licenses or [] + new_licenses = delta.new_file.licenses or [] + old_licenses = delta.old_file.licenses or [] - if len(i.new_file.licenses) > 0 and i.old_file.licenses == []: - i.factors.append('license info added') - i.score += 20 + if len(delta.new_file.licenses) > 0 and delta.old_file.licenses == []: + delta.factors.append('license info added') + delta.score += 20 return - if i.new_file.licenses == [] and len(i.old_file.licenses) > 0: - i.factors.append('license info removed') - i.score += 15 + if delta.new_file.licenses == [] and len(delta.old_file.licenses) > 0: + delta.factors.append('license info removed') + delta.score += 15 return - new_keys = set(l.key for l in new_licenses) - old_keys = set(l.key for l in old_licenses) + new_keys = set(license.key for license in new_licenses) + old_keys = set(license.key for license in old_licenses) if new_keys != old_keys: - i.factors.append('license change') - i.score += 10 + delta.factors.append('license change') + delta.score += 10 + + def copyright_diff(self): + """ + Compare the copyright details for a pair of 'new' and 'old' File objects + in a Delta object and change the Delta object's 'score' attribute -- + and add an appropriate category (e.g., 'copyright info removed', 'copyright + info added' or 'copyright change') to the Delta object's 'factors' + attribute -- if there has been a copyright change and depending on the + nature of that change. + """ + for delta in self.deltas: + if 20 <= delta.score < 100: + + new_copyrights = delta.new_file.copyrights or [] + old_copyrights = delta.old_file.copyrights or [] + + if len(delta.new_file.copyrights) > 0 and delta.old_file.copyrights == []: + delta.factors.append('copyright info added') + delta.score += 15 + return + + if delta.new_file.copyrights == [] and len(delta.old_file.copyrights) > 0: + delta.factors.append('copyright info removed') + delta.score += 10 + return + + new_statements = set(statement for copyright in new_copyrights for statement in copyright.statements) + old_statements = set(statement for copyright in old_copyrights for statement in copyright.statements) + + new_holders = set(holder for copyright in new_copyrights for holder in copyright.holders) + old_holders = set(holder for copyright in old_copyrights for holder in copyright.holders) + + new_authors = set(author for copyright in new_copyrights for author in copyright.authors) + old_authors = set(author for copyright in old_copyrights for author in copyright.authors) + + if ((new_statements != old_statements) or + (new_holders != old_holders) or + (new_authors != old_authors)): + delta.factors.append('copyright change') + delta.score += 5 def index_deltas(self, index_key='path', delta_list=[]): """ diff --git a/tests/data/deltacode/score_copyright_and_license_info_added_new.json b/tests/data/deltacode/score_copyright_and_license_info_added_new.json new file mode 100644 index 00000000..fcc1837c --- /dev/null +++ b/tests/data/deltacode/score_copyright_and_license_info_added_new.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-1.0-plus", + "score": 20.0, + "short_name": "GPL 1.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "text_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-1.0-plus", + "spdx_license_key": "GPL-1.0+", + "spdx_url": "https://spdx.org/licenses/GPL-1.0", + "start_line": 353, + "end_line": 353, + "matched_rule": { + "identifier": "gpl_63.RULE", + "license_choice": false, + "licenses": [ + "gpl-1.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_and_license_info_added_old.json b/tests/data/deltacode/score_copyright_and_license_info_added_old.json new file mode 100644 index 00000000..8f1827ea --- /dev/null +++ b/tests/data/deltacode/score_copyright_and_license_info_added_old.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_and_license_info_removed_new.json b/tests/data/deltacode/score_copyright_and_license_info_removed_new.json new file mode 100644 index 00000000..0f20da55 --- /dev/null +++ b/tests/data/deltacode/score_copyright_and_license_info_removed_new.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_and_license_info_removed_old.json b/tests/data/deltacode/score_copyright_and_license_info_removed_old.json new file mode 100644 index 00000000..acf940b0 --- /dev/null +++ b/tests/data/deltacode/score_copyright_and_license_info_removed_old.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-1.0-plus", + "score": 20.0, + "short_name": "GPL 1.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "text_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-1.0-plus", + "spdx_license_key": "GPL-1.0+", + "spdx_url": "https://spdx.org/licenses/GPL-1.0", + "start_line": 353, + "end_line": 353, + "matched_rule": { + "identifier": "gpl_63.RULE", + "license_choice": false, + "licenses": [ + "gpl-1.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_info_added_license_info_removed_new.json b/tests/data/deltacode/score_copyright_info_added_license_info_removed_new.json new file mode 100644 index 00000000..408882d0 --- /dev/null +++ b/tests/data/deltacode/score_copyright_info_added_license_info_removed_new.json @@ -0,0 +1,41 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_info_added_license_info_removed_old.json b/tests/data/deltacode/score_copyright_info_added_license_info_removed_old.json new file mode 100644 index 00000000..75bab5c8 --- /dev/null +++ b/tests/data/deltacode/score_copyright_info_added_license_info_removed_old.json @@ -0,0 +1,51 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_info_added_new.json b/tests/data/deltacode/score_copyright_info_added_new.json new file mode 100644 index 00000000..011499d7 --- /dev/null +++ b/tests/data/deltacode/score_copyright_info_added_new.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_info_added_old.json b/tests/data/deltacode/score_copyright_info_added_old.json new file mode 100644 index 00000000..8f1827ea --- /dev/null +++ b/tests/data/deltacode/score_copyright_info_added_old.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_info_removed_new.json b/tests/data/deltacode/score_copyright_info_removed_new.json new file mode 100644 index 00000000..0f20da55 --- /dev/null +++ b/tests/data/deltacode/score_copyright_info_removed_new.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_info_removed_old.json b/tests/data/deltacode/score_copyright_info_removed_old.json new file mode 100644 index 00000000..8cfbbc2d --- /dev/null +++ b/tests/data/deltacode/score_copyright_info_removed_old.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_license_info_added_copyright_info_removed_new.json b/tests/data/deltacode/score_license_info_added_copyright_info_removed_new.json new file mode 100644 index 00000000..a98af09d --- /dev/null +++ b/tests/data/deltacode/score_license_info_added_copyright_info_removed_new.json @@ -0,0 +1,51 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_license_info_added_copyright_info_removed_old.json b/tests/data/deltacode/score_license_info_added_copyright_info_removed_old.json new file mode 100644 index 00000000..29f8b601 --- /dev/null +++ b/tests/data/deltacode/score_license_info_added_copyright_info_removed_old.json @@ -0,0 +1,41 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_no_copyright_changes_new.json b/tests/data/deltacode/score_no_copyright_changes_new.json new file mode 100644 index 00000000..011499d7 --- /dev/null +++ b/tests/data/deltacode/score_no_copyright_changes_new.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_no_copyright_changes_old.json b/tests/data/deltacode/score_no_copyright_changes_old.json new file mode 100644 index 00000000..8cfbbc2d --- /dev/null +++ b/tests/data/deltacode/score_no_copyright_changes_old.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_no_copyright_info_new.json b/tests/data/deltacode/score_no_copyright_info_new.json new file mode 100644 index 00000000..0f20da55 --- /dev/null +++ b/tests/data/deltacode/score_no_copyright_info_new.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_no_copyright_info_old.json b/tests/data/deltacode/score_no_copyright_info_old.json new file mode 100644 index 00000000..8f1827ea --- /dev/null +++ b/tests/data/deltacode/score_no_copyright_info_old.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_no_copyright_key_new.json b/tests/data/deltacode/score_no_copyright_key_new.json new file mode 100644 index 00000000..96e9edf9 --- /dev/null +++ b/tests/data/deltacode/score_no_copyright_key_new.json @@ -0,0 +1,28 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_no_copyright_key_old.json b/tests/data/deltacode/score_no_copyright_key_old.json new file mode 100644 index 00000000..3fa8182e --- /dev/null +++ b/tests/data/deltacode/score_no_copyright_key_old.json @@ -0,0 +1,28 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_single_copyright_change_new.json b/tests/data/deltacode/score_single_copyright_change_new.json new file mode 100644 index 00000000..011499d7 --- /dev/null +++ b/tests/data/deltacode/score_single_copyright_change_new.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_single_copyright_change_old.json b/tests/data/deltacode/score_single_copyright_change_old.json new file mode 100644 index 00000000..a099ae03 --- /dev/null +++ b/tests/data/deltacode/score_single_copyright_change_old.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + "holders": [ + "Jean-loup Gailly, Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index 6bd4a053..0fe3398a 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -1153,3 +1153,394 @@ def test_score_single_lic_change(self): ('owner', None) ]) ] + + def test_score_single_copyright_change(self): + new_scan = self.get_test_loc('deltacode/score_single_copyright_change_new.json') + old_scan = self.get_test_loc('deltacode/score_single_copyright_change_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [25] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'copyright change'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler']), + ('holders', ['Jean-loup Gailly, Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 25]) == 1 + assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_copyright_info_added(self): + new_scan = self.get_test_loc('deltacode/score_copyright_info_added_new.json') + old_scan = self.get_test_loc('deltacode/score_copyright_info_added_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [35] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'copyright info added'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + + assert len([i for i in deltas_object if i.score == 35]) == 1 + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_copyright_info_removed(self): + new_scan = self.get_test_loc('deltacode/score_copyright_info_removed_new.json') + old_scan = self.get_test_loc('deltacode/score_copyright_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [30] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'copyright info removed'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + + assert len([i for i in deltas_object if i.score == 30]) == 1 + assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_no_copyright_info(self): + new_scan = self.get_test_loc('deltacode/score_no_copyright_info_new.json') + old_scan = self.get_test_loc('deltacode/score_no_copyright_info_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [20] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 1 + + def test_score_no_copyright_changes(self): + new_scan = self.get_test_loc('deltacode/score_no_copyright_changes_new.json') + old_scan = self.get_test_loc('deltacode/score_no_copyright_changes_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [20] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 1 + + def test_score_no_copyright_key(self): + new_scan = self.get_test_loc('deltacode/score_no_copyright_key_new.json') + old_scan = self.get_test_loc('deltacode/score_no_copyright_key_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [20] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 1 + + def test_score_copyright_and_license_info_added(self): + new_scan = self.get_test_loc('deltacode/score_copyright_and_license_info_added_new.json') + old_scan = self.get_test_loc('deltacode/score_copyright_and_license_info_added_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [55] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info added', 'copyright info added'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-1.0-plus'), + ('score', 20.0), + ('short_name', 'GPL 1.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + + assert len([i for i in deltas_object if i.score == 55]) == 1 + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_copyright_and_license_info_removed(self): + new_scan = self.get_test_loc('deltacode/score_copyright_and_license_info_removed_new.json') + old_scan = self.get_test_loc('deltacode/score_copyright_and_license_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [45] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info removed', 'copyright info removed'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-1.0-plus'), + ('score', 20.0), + ('short_name', 'GPL 1.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + + assert len([i for i in deltas_object if i.score == 55]) == 0 + assert len([i for i in deltas_object if i.score == 45]) == 1 + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_copyright_info_added_license_info_removed(self): + new_scan = self.get_test_loc('deltacode/score_copyright_info_added_license_info_removed_new.json') + old_scan = self.get_test_loc('deltacode/score_copyright_info_added_license_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [50] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info removed', 'copyright info added'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-3.0-plus'), + ('score', 100.0), + ('short_name', 'GPL 3.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + + assert len([i for i in deltas_object if i.score == 55]) == 0 + assert len([i for i in deltas_object if i.score == 50]) == 1 + assert len([i for i in deltas_object if i.score == 45]) == 0 + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_license_info_added_copyright_info_removed(self): + new_scan = self.get_test_loc('deltacode/score_license_info_added_copyright_info_removed_new.json') + old_scan = self.get_test_loc('deltacode/score_license_info_added_copyright_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [50] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info added', 'copyright info removed'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-3.0-plus'), + ('score', 100.0), + ('short_name', 'GPL 3.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + + assert len([i for i in deltas_object if i.score == 55]) == 0 + assert len([i for i in deltas_object if i.score == 50]) == 1 + assert len([i for i in deltas_object if i.score == 45]) == 0 + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 0 From f1c9f4d62e481901cd1e562b546810f7516bc87a Mon Sep 17 00:00:00 2001 From: "John M. Horan" Date: Thu, 1 Mar 2018 18:32:32 -0800 Subject: [PATCH 3/7] Add additional copyright-related tests #83 Signed-off-by: John M. Horan --- .../cli/copyright_and_license_info_added.csv | 2 + .../copyright_and_license_info_added_new.json | 63 +++++++++ .../copyright_and_license_info_added_old.json | 29 ++++ .../copyright_and_license_info_removed.csv | 2 + ...opyright_and_license_info_removed_new.json | 29 ++++ ...opyright_and_license_info_removed_old.json | 63 +++++++++ .../copyright_change_no_license_change.csv | 2 + ...opyright_change_no_license_change_new.json | 63 +++++++++ ...opyright_change_no_license_change_old.json | 63 +++++++++ tests/data/cli/copyright_info_added.csv | 2 + ...yright_info_added_license_info_removed.csv | 2 + ...t_info_added_license_info_removed_new.json | 41 ++++++ ...t_info_added_license_info_removed_old.json | 51 +++++++ tests/data/cli/copyright_info_added_new.json | 39 ++++++ tests/data/cli/copyright_info_added_old.json | 29 ++++ tests/data/cli/copyright_info_removed.csv | 2 + .../data/cli/copyright_info_removed_new.json | 29 ++++ .../data/cli/copyright_info_removed_old.json | 39 ++++++ .../license_change_no_copyright_change.csv | 2 + ...icense_change_no_copyright_change_new.json | 63 +++++++++ ...icense_change_no_copyright_change_old.json | 63 +++++++++ ...ense_info_added_copyright_info_removed.csv | 2 + ...info_added_copyright_info_removed_new.json | 51 +++++++ ...info_added_copyright_info_removed_old.json | 41 ++++++ tests/data/cli/single_copyright_change.csv | 2 + .../data/cli/single_copyright_change_new.json | 39 ++++++ .../data/cli/single_copyright_change_old.json | 39 ++++++ ...opyright_change_no_license_change_new.json | 63 +++++++++ ...opyright_change_no_license_change_old.json | 63 +++++++++ ...icense_change_no_copyright_change_new.json | 63 +++++++++ ...icense_change_no_copyright_change_old.json | 63 +++++++++ tests/test_cli.py | 126 ++++++++++++++++++ tests/test_deltacode.py | 118 ++++++++++++++++ 33 files changed, 1348 insertions(+) create mode 100644 tests/data/cli/copyright_and_license_info_added.csv create mode 100644 tests/data/cli/copyright_and_license_info_added_new.json create mode 100644 tests/data/cli/copyright_and_license_info_added_old.json create mode 100644 tests/data/cli/copyright_and_license_info_removed.csv create mode 100644 tests/data/cli/copyright_and_license_info_removed_new.json create mode 100644 tests/data/cli/copyright_and_license_info_removed_old.json create mode 100644 tests/data/cli/copyright_change_no_license_change.csv create mode 100644 tests/data/cli/copyright_change_no_license_change_new.json create mode 100644 tests/data/cli/copyright_change_no_license_change_old.json create mode 100644 tests/data/cli/copyright_info_added.csv create mode 100644 tests/data/cli/copyright_info_added_license_info_removed.csv create mode 100644 tests/data/cli/copyright_info_added_license_info_removed_new.json create mode 100644 tests/data/cli/copyright_info_added_license_info_removed_old.json create mode 100644 tests/data/cli/copyright_info_added_new.json create mode 100644 tests/data/cli/copyright_info_added_old.json create mode 100644 tests/data/cli/copyright_info_removed.csv create mode 100644 tests/data/cli/copyright_info_removed_new.json create mode 100644 tests/data/cli/copyright_info_removed_old.json create mode 100644 tests/data/cli/license_change_no_copyright_change.csv create mode 100644 tests/data/cli/license_change_no_copyright_change_new.json create mode 100644 tests/data/cli/license_change_no_copyright_change_old.json create mode 100644 tests/data/cli/license_info_added_copyright_info_removed.csv create mode 100644 tests/data/cli/license_info_added_copyright_info_removed_new.json create mode 100644 tests/data/cli/license_info_added_copyright_info_removed_old.json create mode 100644 tests/data/cli/single_copyright_change.csv create mode 100644 tests/data/cli/single_copyright_change_new.json create mode 100644 tests/data/cli/single_copyright_change_old.json create mode 100644 tests/data/deltacode/score_copyright_change_no_license_change_new.json create mode 100644 tests/data/deltacode/score_copyright_change_no_license_change_old.json create mode 100644 tests/data/deltacode/score_license_change_no_copyright_change_new.json create mode 100644 tests/data/deltacode/score_license_change_no_copyright_change_old.json diff --git a/tests/data/cli/copyright_and_license_info_added.csv b/tests/data/cli/copyright_and_license_info_added.csv new file mode 100644 index 00000000..c43d1276 --- /dev/null +++ b/tests/data/cli/copyright_and_license_info_added.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified license info added copyright info added,55,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_and_license_info_added_new.json b/tests/data/cli/copyright_and_license_info_added_new.json new file mode 100644 index 00000000..fcc1837c --- /dev/null +++ b/tests/data/cli/copyright_and_license_info_added_new.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-1.0-plus", + "score": 20.0, + "short_name": "GPL 1.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "text_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-1.0-plus", + "spdx_license_key": "GPL-1.0+", + "spdx_url": "https://spdx.org/licenses/GPL-1.0", + "start_line": 353, + "end_line": 353, + "matched_rule": { + "identifier": "gpl_63.RULE", + "license_choice": false, + "licenses": [ + "gpl-1.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_and_license_info_added_old.json b/tests/data/cli/copyright_and_license_info_added_old.json new file mode 100644 index 00000000..8f1827ea --- /dev/null +++ b/tests/data/cli/copyright_and_license_info_added_old.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_and_license_info_removed.csv b/tests/data/cli/copyright_and_license_info_removed.csv new file mode 100644 index 00000000..e673203f --- /dev/null +++ b/tests/data/cli/copyright_and_license_info_removed.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified license info removed copyright info removed,45,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_and_license_info_removed_new.json b/tests/data/cli/copyright_and_license_info_removed_new.json new file mode 100644 index 00000000..0f20da55 --- /dev/null +++ b/tests/data/cli/copyright_and_license_info_removed_new.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_and_license_info_removed_old.json b/tests/data/cli/copyright_and_license_info_removed_old.json new file mode 100644 index 00000000..acf940b0 --- /dev/null +++ b/tests/data/cli/copyright_and_license_info_removed_old.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-1.0-plus", + "score": 20.0, + "short_name": "GPL 1.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "text_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-1.0-plus", + "spdx_license_key": "GPL-1.0+", + "spdx_url": "https://spdx.org/licenses/GPL-1.0", + "start_line": 353, + "end_line": 353, + "matched_rule": { + "identifier": "gpl_63.RULE", + "license_choice": false, + "licenses": [ + "gpl-1.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_change_no_license_change.csv b/tests/data/cli/copyright_change_no_license_change.csv new file mode 100644 index 00000000..8856aa21 --- /dev/null +++ b/tests/data/cli/copyright_change_no_license_change.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified copyright change,25,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_change_no_license_change_new.json b/tests/data/cli/copyright_change_no_license_change_new.json new file mode 100644 index 00000000..92be662e --- /dev/null +++ b/tests/data/cli/copyright_change_no_license_change_new.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Alfred E. Neuman" + ], + "holders": [ + "Alfred E. Neuman" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_change_no_license_change_old.json b/tests/data/cli/copyright_change_no_license_change_old.json new file mode 100644 index 00000000..22828c46 --- /dev/null +++ b/tests/data/cli/copyright_change_no_license_change_old.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_info_added.csv b/tests/data/cli/copyright_info_added.csv new file mode 100644 index 00000000..d0af31c3 --- /dev/null +++ b/tests/data/cli/copyright_info_added.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified copyright info added,35,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_info_added_license_info_removed.csv b/tests/data/cli/copyright_info_added_license_info_removed.csv new file mode 100644 index 00000000..1096e739 --- /dev/null +++ b/tests/data/cli/copyright_info_added_license_info_removed.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified license info removed copyright info added,50,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_info_added_license_info_removed_new.json b/tests/data/cli/copyright_info_added_license_info_removed_new.json new file mode 100644 index 00000000..408882d0 --- /dev/null +++ b/tests/data/cli/copyright_info_added_license_info_removed_new.json @@ -0,0 +1,41 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_info_added_license_info_removed_old.json b/tests/data/cli/copyright_info_added_license_info_removed_old.json new file mode 100644 index 00000000..75bab5c8 --- /dev/null +++ b/tests/data/cli/copyright_info_added_license_info_removed_old.json @@ -0,0 +1,51 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_info_added_new.json b/tests/data/cli/copyright_info_added_new.json new file mode 100644 index 00000000..011499d7 --- /dev/null +++ b/tests/data/cli/copyright_info_added_new.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_info_added_old.json b/tests/data/cli/copyright_info_added_old.json new file mode 100644 index 00000000..8f1827ea --- /dev/null +++ b/tests/data/cli/copyright_info_added_old.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_info_removed.csv b/tests/data/cli/copyright_info_removed.csv new file mode 100644 index 00000000..3019185a --- /dev/null +++ b/tests/data/cli/copyright_info_removed.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified copyright info removed,30,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_info_removed_new.json b/tests/data/cli/copyright_info_removed_new.json new file mode 100644 index 00000000..0f20da55 --- /dev/null +++ b/tests/data/cli/copyright_info_removed_new.json @@ -0,0 +1,29 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/copyright_info_removed_old.json b/tests/data/cli/copyright_info_removed_old.json new file mode 100644 index 00000000..8cfbbc2d --- /dev/null +++ b/tests/data/cli/copyright_info_removed_old.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/license_change_no_copyright_change.csv b/tests/data/cli/license_change_no_copyright_change.csv new file mode 100644 index 00000000..8befee58 --- /dev/null +++ b/tests/data/cli/license_change_no_copyright_change.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified license change,30,path.txt,path.txt,file,300, diff --git a/tests/data/cli/license_change_no_copyright_change_new.json b/tests/data/cli/license_change_no_copyright_change_new.json new file mode 100644 index 00000000..27f95a9d --- /dev/null +++ b/tests/data/cli/license_change_no_copyright_change_new.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-1.0-plus", + "score": 20.0, + "short_name": "GPL 1.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "text_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-1.0-plus", + "spdx_license_key": "GPL-1.0+", + "spdx_url": "https://spdx.org/licenses/GPL-1.0", + "start_line": 353, + "end_line": 353, + "matched_rule": { + "identifier": "gpl_63.RULE", + "license_choice": false, + "licenses": [ + "gpl-1.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/license_change_no_copyright_change_old.json b/tests/data/cli/license_change_no_copyright_change_old.json new file mode 100644 index 00000000..22828c46 --- /dev/null +++ b/tests/data/cli/license_change_no_copyright_change_old.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/license_info_added_copyright_info_removed.csv b/tests/data/cli/license_info_added_copyright_info_removed.csv new file mode 100644 index 00000000..e1900247 --- /dev/null +++ b/tests/data/cli/license_info_added_copyright_info_removed.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified license info added copyright info removed,50,path.txt,path.txt,file,300, diff --git a/tests/data/cli/license_info_added_copyright_info_removed_new.json b/tests/data/cli/license_info_added_copyright_info_removed_new.json new file mode 100644 index 00000000..a98af09d --- /dev/null +++ b/tests/data/cli/license_info_added_copyright_info_removed_new.json @@ -0,0 +1,51 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/license_info_added_copyright_info_removed_old.json b/tests/data/cli/license_info_added_copyright_info_removed_old.json new file mode 100644 index 00000000..29f8b601 --- /dev/null +++ b/tests/data/cli/license_info_added_copyright_info_removed_old.json @@ -0,0 +1,41 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/single_copyright_change.csv b/tests/data/cli/single_copyright_change.csv new file mode 100644 index 00000000..8856aa21 --- /dev/null +++ b/tests/data/cli/single_copyright_change.csv @@ -0,0 +1,2 @@ +Factors,Score,Path,Name,Type,Size,Old Path +modified copyright change,25,path.txt,path.txt,file,300, diff --git a/tests/data/cli/single_copyright_change_new.json b/tests/data/cli/single_copyright_change_new.json new file mode 100644 index 00000000..011499d7 --- /dev/null +++ b/tests/data/cli/single_copyright_change_new.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/cli/single_copyright_change_old.json b/tests/data/cli/single_copyright_change_old.json new file mode 100644 index 00000000..a099ae03 --- /dev/null +++ b/tests/data/cli/single_copyright_change_old.json @@ -0,0 +1,39 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [], + "copyrights": [ + { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler" + ], + "holders": [ + "Jean-loup Gailly, Mark Adler" + ], + "authors": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_change_no_license_change_new.json b/tests/data/deltacode/score_copyright_change_no_license_change_new.json new file mode 100644 index 00000000..92be662e --- /dev/null +++ b/tests/data/deltacode/score_copyright_change_no_license_change_new.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Alfred E. Neuman" + ], + "holders": [ + "Alfred E. Neuman" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_copyright_change_no_license_change_old.json b/tests/data/deltacode/score_copyright_change_no_license_change_old.json new file mode 100644 index 00000000..22828c46 --- /dev/null +++ b/tests/data/deltacode/score_copyright_change_no_license_change_old.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_license_change_no_copyright_change_new.json b/tests/data/deltacode/score_license_change_no_copyright_change_new.json new file mode 100644 index 00000000..27f95a9d --- /dev/null +++ b/tests/data/deltacode/score_license_change_no_copyright_change_new.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "new/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "new/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b_modified", + "licenses": [ + { + "key": "gpl-1.0-plus", + "score": 20.0, + "short_name": "GPL 1.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "text_url": "http://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-1.0-plus", + "spdx_license_key": "GPL-1.0+", + "spdx_url": "https://spdx.org/licenses/GPL-1.0", + "start_line": 353, + "end_line": 353, + "matched_rule": { + "identifier": "gpl_63.RULE", + "license_choice": false, + "licenses": [ + "gpl-1.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/data/deltacode/score_license_change_no_copyright_change_old.json b/tests/data/deltacode/score_license_change_no_copyright_change_old.json new file mode 100644 index 00000000..22828c46 --- /dev/null +++ b/tests/data/deltacode/score_license_change_no_copyright_change_old.json @@ -0,0 +1,63 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.1.0", + "scancode_options": { + "--license": true, + "--info": true + }, + "files_count": 2, + "files": [ + { + "path": "old/default.txt", + "type": "file", + "name": "default.txt", + "size": 100, + "sha1": "a", + "licenses": [], + "copyrights": [] + }, + { + "path": "old/path.txt", + "type": "file", + "name": "path.txt", + "size": 300, + "sha1": "b", + "licenses": [ + { + "key": "gpl-3.0-plus", + "score": 100.0, + "short_name": "GPL 3.0 or later", + "category": "Copyleft", + "owner": "Free Software Foundation (FSF)", + "homepage_url": "http://www.gnu.org/licenses/gpl-3.0-standalone.html", + "text_url": "", + "dejacode_url": "https://enterprise.dejacode.com/urn/urn:dje:license:gpl-3.0-plus", + "spdx_license_key": "GPL-3.0+", + "spdx_url": "http://spdx.org/licenses/GPL-3.0+", + "start_line": 7, + "end_line": 18, + "matched_rule": { + "identifier": "gpl-3.0-plus_3.RULE", + "license_choice": false, + "licenses": [ + "gpl-3.0-plus" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2016 Mark Adler" + ], + "holders": [ + "Mark Adler" + ], + "authors": [], + "start_line": 1, + "end_line": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py index 37f8c717..0b95bc14 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -267,6 +267,132 @@ def test_write_csv_1_file_moved_and_added(self): expected_file = self.get_test_loc('cli/1_file_moved_and_added.csv') check_csvs(result_file, expected_file) + def test_write_csv_single_copyright_change(self): + new_scan = self.get_test_loc('cli/single_copyright_change_new.json') + old_scan = self.get_test_loc('cli/single_copyright_change_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/single_copyright_change.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_copyright_info_added(self): + new_scan = self.get_test_loc('cli/copyright_info_added_new.json') + old_scan = self.get_test_loc('cli/copyright_info_added_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/copyright_info_added.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_copyright_info_removed(self): + new_scan = self.get_test_loc('cli/copyright_info_removed_new.json') + old_scan = self.get_test_loc('cli/copyright_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/copyright_info_removed.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_copyright_and_license_info_added(self): + new_scan = self.get_test_loc('cli/copyright_and_license_info_added_new.json') + old_scan = self.get_test_loc('cli/copyright_and_license_info_added_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/copyright_and_license_info_added.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_copyright_and_license_info_removed(self): + new_scan = self.get_test_loc('cli/copyright_and_license_info_removed_new.json') + old_scan = self.get_test_loc('cli/copyright_and_license_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/copyright_and_license_info_removed.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_copyright_info_added_license_info_removed(self): + new_scan = self.get_test_loc('cli/copyright_info_added_license_info_removed_new.json') + old_scan = self.get_test_loc('cli/copyright_info_added_license_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/copyright_info_added_license_info_removed.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_license_info_added_copyright_info_removed(self): + new_scan = self.get_test_loc('cli/license_info_added_copyright_info_removed_new.json') + old_scan = self.get_test_loc('cli/license_info_added_copyright_info_removed_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/license_info_added_copyright_info_removed.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_copyright_change_no_license_change(self): + new_scan = self.get_test_loc('cli/copyright_change_no_license_change_new.json') + old_scan = self.get_test_loc('cli/copyright_change_no_license_change_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/copyright_change_no_license_change.csv') + check_csvs(result_file, expected_file) + + def test_write_csv_license_change_no_copyright_change(self): + new_scan = self.get_test_loc('cli/license_change_no_copyright_change_new.json') + old_scan = self.get_test_loc('cli/license_change_no_copyright_change_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + delta = DeltaCode(new_scan, old_scan, options) + result_file = self.get_temp_file('.csv') + cli.write_csv(delta, result_file, False) + expected_file = self.get_test_loc('cli/license_change_no_copyright_change.csv') + check_csvs(result_file, expected_file) + def test_json_output_option_selected_all_selected(self): new_scan = self.get_test_loc('cli/scan_1_file_moved_new.json') old_scan = self.get_test_loc('cli/scan_1_file_moved_old.json') diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index 0fe3398a..c18e6f6b 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -1544,3 +1544,121 @@ def test_score_license_info_added_copyright_info_removed(self): assert len([i for i in deltas_object if i.score == 45]) == 0 assert len([i for i in deltas_object if i.score == 30]) == 0 assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_copyright_change_no_license_change(self): + new_scan = self.get_test_loc('deltacode/score_copyright_change_no_license_change_new.json') + old_scan = self.get_test_loc('deltacode/score_copyright_change_no_license_change_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [25] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'copyright change'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Alfred E. Neuman']), + ('holders', ['Alfred E. Neuman']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-3.0-plus'), + ('score', 100.0), + ('short_name', 'GPL 3.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-3.0-plus'), + ('score', 100.0), + ('short_name', 'GPL 3.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + + assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 25]) == 1 + assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_score_license_change_no_copyright_change(self): + new_scan = self.get_test_loc('deltacode/score_license_change_no_copyright_change_new.json') + old_scan = self.get_test_loc('deltacode/score_license_change_no_copyright_change_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'default.txt'] == [0] + assert [d.factors for d in deltas_object if d.new_file.path == 'default.txt'].pop() == ['unmodified'] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'default.txt'].pop() == [] + + assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] + assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [30] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license change'] + assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('statements', ['Copyright (c) 2016 Mark Adler']), + ('holders', ['Mark Adler']), + ('authors', []) + ]) + ] + assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-3.0-plus'), + ('score', 100.0), + ('short_name', 'GPL 3.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ + OrderedDict([ + ('key', 'gpl-1.0-plus'), + ('score', 20.0), + ('short_name', 'GPL 1.0 or later'), + ('category', 'Copyleft'), + ('owner', "Free Software Foundation (FSF)") + ]) + ] + + assert len([i for i in deltas_object if i.score == 30]) == 1 + assert len([i for i in deltas_object if i.score == 25]) == 0 + assert len([i for i in deltas_object if i.score == 20]) == 0 From 59b502dd7c77deb00586b3bb3cb507e57fd05c90 Mon Sep 17 00:00:00 2001 From: "John M. Horan" Date: Tue, 6 Mar 2018 12:30:29 -0800 Subject: [PATCH 4/7] Refactor copyright-related code #82 #83 * Add scoring method to Delta -- Delta.add_score(). * Call new scoring method from DeltaCode.license_diff() and DeltaCode.copyright_diff(). * Add tests for Delta.add_score(). * Modify score for 'copyright info added'. * Remove references to copyright authors. * Add tests cases where a files have large numbers of copyright holders and statements. * Add tests cases where a files have unusual characters -- but errors thrown with French accent characters. Signed-off-by: John M. Horan --- src/deltacode/__init__.py | 37 ++- src/deltacode/models.py | 4 +- .../cli/copyright_and_license_info_added.csv | 2 +- tests/data/cli/copyright_info_added.csv | 2 +- ...yright_info_added_license_info_removed.csv | 2 +- tests/test_cli.py | 78 +++-- tests/test_deltacode.py | 297 +++++++++++++++--- tests/test_models.py | 238 +++++++++++++- 8 files changed, 552 insertions(+), 108 deletions(-) diff --git a/src/deltacode/__init__.py b/src/deltacode/__init__.py index f7dbcf27..37c7655c 100644 --- a/src/deltacode/__init__.py +++ b/src/deltacode/__init__.py @@ -199,21 +199,18 @@ def license_diff(self): old_licenses = delta.old_file.licenses or [] if len(delta.new_file.licenses) > 0 and delta.old_file.licenses == []: - delta.factors.append('license info added') - delta.score += 20 + delta.add_score(20, 'license info added') return if delta.new_file.licenses == [] and len(delta.old_file.licenses) > 0: - delta.factors.append('license info removed') - delta.score += 15 + delta.add_score(15, 'license info removed') return new_keys = set(license.key for license in new_licenses) old_keys = set(license.key for license in old_licenses) if new_keys != old_keys: - delta.factors.append('license change') - delta.score += 10 + delta.add_score(10, 'license change') def copyright_diff(self): """ @@ -231,13 +228,10 @@ def copyright_diff(self): old_copyrights = delta.old_file.copyrights or [] if len(delta.new_file.copyrights) > 0 and delta.old_file.copyrights == []: - delta.factors.append('copyright info added') - delta.score += 15 + delta.add_score(10, 'copyright info added') return - - if delta.new_file.copyrights == [] and len(delta.old_file.copyrights) > 0: - delta.factors.append('copyright info removed') - delta.score += 10 + elif delta.new_file.copyrights == [] and len(delta.old_file.copyrights) > 0: + delta.add_score(10, 'copyright info removed') return new_statements = set(statement for copyright in new_copyrights for statement in copyright.statements) @@ -246,14 +240,9 @@ def copyright_diff(self): new_holders = set(holder for copyright in new_copyrights for holder in copyright.holders) old_holders = set(holder for copyright in old_copyrights for holder in copyright.holders) - new_authors = set(author for copyright in new_copyrights for author in copyright.authors) - old_authors = set(author for copyright in old_copyrights for author in copyright.authors) - if ((new_statements != old_statements) or - (new_holders != old_holders) or - (new_authors != old_authors)): - delta.factors.append('copyright change') - delta.score += 5 + (new_holders != old_holders)): + delta.add_score(5, 'copyright change') def index_deltas(self, index_key='path', delta_list=[]): """ @@ -291,6 +280,16 @@ def __init__(self, score=0, new_file=None, old_file=None): self.factors = [] self.score = score + def add_score(self, score=0, factor=''): + """ + For each Delta object identified in DeltaCode.license_diff() or + DeltaCode.copyright_diff(), add the score to the object's 'score' + attribute and add a string, summarizing the factor associated with the + score, to the object's 'factors' attribute (a list). + """ + self.factors.append(factor) + self.score += score + def to_dict(self): """ Return an OrderedDict comprising the 'factors', 'score' and new and old diff --git a/src/deltacode/models.py b/src/deltacode/models.py index 33f25d53..74f582eb 100644 --- a/src/deltacode/models.py +++ b/src/deltacode/models.py @@ -254,7 +254,6 @@ class Copyright(object): def __init__(self, dictionary={}): self.statements = dictionary.get('statements') self.holders = dictionary.get('holders') - self.authors = dictionary.get('authors') def to_dict(self): """ @@ -263,8 +262,7 @@ def to_dict(self): """ d = OrderedDict([ ('statements', self.statements), - ('holders', self.holders), - ('authors', self.authors) + ('holders', self.holders) ]) return d diff --git a/tests/data/cli/copyright_and_license_info_added.csv b/tests/data/cli/copyright_and_license_info_added.csv index c43d1276..ddea96d8 100644 --- a/tests/data/cli/copyright_and_license_info_added.csv +++ b/tests/data/cli/copyright_and_license_info_added.csv @@ -1,2 +1,2 @@ Factors,Score,Path,Name,Type,Size,Old Path -modified license info added copyright info added,55,path.txt,path.txt,file,300, +modified license info added copyright info added,50,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_info_added.csv b/tests/data/cli/copyright_info_added.csv index d0af31c3..be86ae90 100644 --- a/tests/data/cli/copyright_info_added.csv +++ b/tests/data/cli/copyright_info_added.csv @@ -1,2 +1,2 @@ Factors,Score,Path,Name,Type,Size,Old Path -modified copyright info added,35,path.txt,path.txt,file,300, +modified copyright info added,30,path.txt,path.txt,file,300, diff --git a/tests/data/cli/copyright_info_added_license_info_removed.csv b/tests/data/cli/copyright_info_added_license_info_removed.csv index 1096e739..54b53710 100644 --- a/tests/data/cli/copyright_info_added_license_info_removed.csv +++ b/tests/data/cli/copyright_info_added_license_info_removed.csv @@ -1,2 +1,2 @@ Factors,Score,Path,Name,Type,Size,Old Path -modified license info removed copyright info added,50,path.txt,path.txt,file,300, +modified license info removed copyright info added,45,path.txt,path.txt,file,300, diff --git a/tests/test_cli.py b/tests/test_cli.py index 0b95bc14..d202c464 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -442,13 +442,12 @@ def test_json_output_option_selected_all_selected(self): ], "copyrights": [ { - "statements": [ - "Copyright (c) 2017 Acme Software Inc. and others." - ], - "holders": [ - "Acme Software Inc. and others." - ], - "authors": [] + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ] } ] }, @@ -470,13 +469,12 @@ def test_json_output_option_selected_all_selected(self): ], "copyrights": [ { - "statements": [ - "Copyright (c) 2017 Acme Software Inc. and others." - ], - "holders": [ - "Acme Software Inc. and others." - ], - "authors": [] + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ] } ] } @@ -507,13 +505,12 @@ def test_json_output_option_selected_all_selected(self): ], "copyrights": [ { - "statements": [ - "Copyright (c) 2017 Acme Software Inc. and others." - ], - "holders": [ - "Acme Software Inc. and others." - ], - "authors": [] + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ] } ] }, @@ -535,13 +532,12 @@ def test_json_output_option_selected_all_selected(self): ], "copyrights": [ { - "statements": [ - "Copyright (c) 2017 Acme Software Inc. and others." - ], - "holders": [ - "Acme Software Inc. and others." - ], - "authors": [] + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ] } ] } @@ -600,13 +596,12 @@ def test_json_output_option_selected_all_not_selected(self): ], "copyrights": [ { - "statements": [ - "Copyright (c) 2017 Acme Software Inc. and others." - ], - "holders": [ - "Acme Software Inc. and others." - ], - "authors": [] + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ] } ] }, @@ -628,13 +623,12 @@ def test_json_output_option_selected_all_not_selected(self): ], "copyrights": [ { - "statements": [ - "Copyright (c) 2017 Acme Software Inc. and others." - ], - "holders": [ - "Acme Software Inc. and others." - ], - "authors": [] + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ] } ] } diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index c18e6f6b..f7902422 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -1179,15 +1179,13 @@ def test_score_single_copyright_change(self): assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler']), - ('holders', ['Jean-loup Gailly, Mark Adler']), - ('authors', []) + ('holders', ['Jean-loup Gailly, Mark Adler']) ]) ] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] @@ -1215,19 +1213,18 @@ def test_score_copyright_info_added(self): assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] - assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [35] + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [30] assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'copyright info added'] assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] - assert len([i for i in deltas_object if i.score == 35]) == 1 - assert len([i for i in deltas_object if i.score == 30]) == 0 + assert len([i for i in deltas_object if i.score == 35]) == 0 + assert len([i for i in deltas_object if i.score == 30]) == 1 assert len([i for i in deltas_object if i.score == 20]) == 0 def test_score_copyright_info_removed(self): @@ -1255,8 +1252,7 @@ def test_score_copyright_info_removed(self): assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] @@ -1317,15 +1313,13 @@ def test_score_no_copyright_changes(self): assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] @@ -1380,14 +1374,13 @@ def test_score_copyright_and_license_info_added(self): assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] - assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [55] + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [50] assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info added', 'copyright info added'] assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] @@ -1401,7 +1394,7 @@ def test_score_copyright_and_license_info_added(self): ]) ] - assert len([i for i in deltas_object if i.score == 55]) == 1 + assert len([i for i in deltas_object if i.score == 50]) == 1 assert len([i for i in deltas_object if i.score == 30]) == 0 assert len([i for i in deltas_object if i.score == 20]) == 0 @@ -1430,8 +1423,7 @@ def test_score_copyright_and_license_info_removed(self): assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] @@ -1471,14 +1463,13 @@ def test_score_copyright_info_added_license_info_removed(self): assert [d.old_file.sha1 for d in deltas_object if d.old_file.path == 'path.txt'] == ['b'] assert [d.new_file.sha1 for d in deltas_object if d.new_file.path == 'path.txt'] == ['b_modified'] - assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [50] + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [45] assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license info removed', 'copyright info added'] assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ @@ -1493,8 +1484,8 @@ def test_score_copyright_info_added_license_info_removed(self): assert [d.to_dict().get('new').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] assert len([i for i in deltas_object if i.score == 55]) == 0 - assert len([i for i in deltas_object if i.score == 50]) == 1 - assert len([i for i in deltas_object if i.score == 45]) == 0 + assert len([i for i in deltas_object if i.score == 50]) == 0 + assert len([i for i in deltas_object if i.score == 45]) == 1 assert len([i for i in deltas_object if i.score == 30]) == 0 assert len([i for i in deltas_object if i.score == 20]) == 0 @@ -1523,8 +1514,7 @@ def test_score_license_info_added_copyright_info_removed(self): assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [] @@ -1570,15 +1560,13 @@ def test_score_copyright_change_no_license_change(self): assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Alfred E. Neuman']), - ('holders', ['Alfred E. Neuman']), - ('authors', []) + ('holders', ['Alfred E. Neuman']) ]) ] assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ @@ -1629,15 +1617,13 @@ def test_score_license_change_no_copyright_change(self): assert [d.to_dict().get('old').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('new').get('copyrights') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ OrderedDict([ ('statements', ['Copyright (c) 2016 Mark Adler']), - ('holders', ['Mark Adler']), - ('authors', []) + ('holders', ['Mark Adler']) ]) ] assert [d.to_dict().get('old').get('licenses') for d in deltas_object if d.new_file.path == 'path.txt'].pop() == [ @@ -1662,3 +1648,242 @@ def test_score_license_change_no_copyright_change(self): assert len([i for i in deltas_object if i.score == 30]) == 1 assert len([i for i in deltas_object if i.score == 25]) == 0 assert len([i for i in deltas_object if i.score == 20]) == 0 + + def test_Delta_add_score_added(self): + new = models.File({ + 'path': 'path/added.txt', + 'type': 'file', + 'name': 'added.txt', + 'size': 20, + 'sha1': 'a', + 'original_path': '' + }) + + delta = deltacode.Delta(100, new, None) + + delta.add_score(25, 'This is a test of an added file') + + assert delta.score == 125 + assert delta.factors == ['This is a test of an added file'] + + def test_Delta_add_score_modified(self): + new = models.File({ + 'path': 'path/modified.txt', + 'type': 'file', + 'name': 'modified.txt', + 'size': 20, + 'sha1': 'a', + 'original_path': '' + }) + old = models.File({ + 'path': 'path/modified.txt', + 'type': 'file', + 'name': 'modified.txt', + 'size': 21, + 'sha1': 'b', + 'original_path': '' + }) + + delta = deltacode.Delta(20, new, old) + + delta.add_score(25, 'This is a test of a modified file') + + assert delta.score == 45 + assert delta.factors == ['This is a test of a modified file'] + + def test_Delta_add_score_license_change_no_copyright_change(self): + new_scan = self.get_test_loc('deltacode/score_license_change_no_copyright_change_new.json') + old_scan = self.get_test_loc('deltacode/score_license_change_no_copyright_change_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [30] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license change'] + + for d in deltas_object: + if d.new_file.path == 'path.txt': + d.add_score(25, 'This is a test of a license change') + + assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [55] + assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license change', 'This is a test of a license change'] + + def test_Delta_to_dict_multiple_copyright_statements_and_holders(self): + new = { + 'path': 'path/modified.txt', + 'type': 'file', + 'name': 'modified.txt', + 'size': 21, + 'sha1': 'a_modified', + 'original_path': '', + 'licenses': [], + 'copyrights': [ + { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler", + "Copyright (c) 1998 by Andreas R. Kleinert", + "Copyright (c) 2002-2004 Dmitriy Anisimkov", + "Copyright (c) 1998, 2007 Brian Raiter", + "Copyright (c) 1997,99 Borland Corp.", + "(c) Copyright Henrik Ravn 2004", + "Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.", + "Copyright (c) 2003 Chris Anderson", + "Copyright (c) 1997 Christian Michelsen Research as Advanced Computing", + "Copyright (c) 2009-2010 Mathias Svensson http://result42.com", + "Copyright (c) 1990-2000 Info-ZIP.", + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler", + "Copyright (c) 1998 by Andreas R. Kleinert", + "Copyright (c) 2002-2004 Dmitriy Anisimkov", + "Copyright (c) 1998, 2007 Brian Raiter", + "Copyright (c) 1997,99 Borland Corp.", + "(c) Copyright Henrik Ravn 2004", + "Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.", + "Copyright (c) 2003 Chris Anderson", + "Copyright (c) 1997 Christian Michelsen Research as Advanced Computing", + "Copyright (c) 2009-2010 Mathias Svensson http://result42.com", + "Copyright (c) 1990-2000 Info-ZIP." + ], + "holders": [ + "Jean-loup Gailly, Mark Adler", + "Andreas R. Kleinert", + "Dmitriy Anisimkov", + "Brian Raiter", + "Borland Corp.", + "Henrik Ravn", + "Jean-loup Gailly, Brian Raiter, Gilles Vollant", + "Chris Anderson", + "Christian Michelsen Research as Advanced Computing", + "Mathias Svensson", + "Info-ZIP", + "Jean-loup Gailly, Mark Adler", + "Andreas R. Kleinert", + "Dmitriy Anisimkov", + "Brian Raiter", + "Borland Corp.", + "Henrik Ravn", + "Jean-loup Gailly, Brian Raiter, Gilles Vollant", + "Chris Anderson", + "Christian Michelsen Research as Advanced Computing", + "Mathias Svensson", + "Info-ZIP" + ], + "authors": [] + } + ] + } + + old = { + 'path': 'path/modified.txt', + 'type': 'file', + 'name': 'modified.txt', + 'size': 20, + 'sha1': 'a', + 'original_path': '', + 'licenses': [], + 'copyrights': [ + { + "statements": [ + "Copyright (c) 2018 Jane Doe" + ], + "holders": [ + "Jane Doe" + ], + "authors": [] + } + ] + } + + expected = OrderedDict([ + ('factors', ['modified']), + ('score', 20), + ('new', OrderedDict([ + ('path', 'path/modified.txt'), + ('type', 'file'), + ('name', 'modified.txt'), + ('size', 21), + ('sha1', 'a_modified'), + ('original_path', ''), + ('licenses', []), + ('copyrights', [OrderedDict([ + ('statements', [ + 'Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler', + 'Copyright (c) 1998 by Andreas R. Kleinert', + 'Copyright (c) 2002-2004 Dmitriy Anisimkov', + 'Copyright (c) 1998, 2007 Brian Raiter', + 'Copyright (c) 1997,99 Borland Corp.', + '(c) Copyright Henrik Ravn 2004', + 'Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.', + 'Copyright (c) 2003 Chris Anderson', + 'Copyright (c) 1997 Christian Michelsen Research as Advanced Computing', + 'Copyright (c) 2009-2010 Mathias Svensson http://result42.com', + 'Copyright (c) 1990-2000 Info-ZIP.', + 'Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler', + 'Copyright (c) 1998 by Andreas R. Kleinert', + 'Copyright (c) 2002-2004 Dmitriy Anisimkov', + 'Copyright (c) 1998, 2007 Brian Raiter', + 'Copyright (c) 1997,99 Borland Corp.', + '(c) Copyright Henrik Ravn 2004', + 'Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.', + 'Copyright (c) 2003 Chris Anderson', + 'Copyright (c) 1997 Christian Michelsen Research as Advanced Computing', + 'Copyright (c) 2009-2010 Mathias Svensson http://result42.com', + 'Copyright (c) 1990-2000 Info-ZIP.' + ]), + ('holders', [ + 'Jean-loup Gailly, Mark Adler', + 'Andreas R. Kleinert', + 'Dmitriy Anisimkov', + 'Brian Raiter', + 'Borland Corp.', + 'Henrik Ravn', + 'Jean-loup Gailly, Brian Raiter, Gilles Vollant', + 'Chris Anderson', + 'Christian Michelsen Research as Advanced Computing', + 'Mathias Svensson', + 'Info-ZIP', + 'Jean-loup Gailly, Mark Adler', + 'Andreas R. Kleinert', + 'Dmitriy Anisimkov', + 'Brian Raiter', + 'Borland Corp.', + 'Henrik Ravn', + 'Jean-loup Gailly, Brian Raiter, Gilles Vollant', + 'Chris Anderson', + 'Christian Michelsen Research as Advanced Computing', + 'Mathias Svensson', + 'Info-ZIP' + ])]) + ]) + ])), + ('old', OrderedDict([ + ('path', 'path/modified.txt'), + ('type', 'file'), + ('name', 'modified.txt'), + ('size', 20), + ('sha1', 'a'), + ('original_path', ''), + ('licenses', []), + ('copyrights', [OrderedDict([ + ('statements', [ + 'Copyright (c) 2018 Jane Doe' + ]), + ('holders', [ + 'Jane Doe' + ])]) + ]) + ])) + ]) + + result_new = models.File(new) + result_old = models.File(old) + + delta = deltacode.Delta(20, result_new, result_old) + delta.factors.append('modified') + + assert delta.to_dict() == expected + # print('\n\ndelta.to_dict() = {}\n'.format(delta.to_dict())) diff --git a/tests/test_models.py b/tests/test_models.py index 3e5e4520..3201d4d9 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -678,8 +678,7 @@ def test_Copyright_to_dict_simple(self): ], 'holders': [ "Jean-loup Gailly, Mark Adler" - ], - 'authors': [] + ] } result = models.Copyright(data).to_dict() @@ -715,7 +714,6 @@ def test_Copyright_object_simple(self): assert result.holders == [ "Jean-loup Gailly, Mark Adler" ] - assert result.authors == [] with pytest.raises(AttributeError): assert result.made_up_key == "a_string" @@ -763,8 +761,7 @@ def test_File_to_dict_simple_w_copyright(self): ], "holders": [ "Jean-loup Gailly, Mark Adler" - ], - "authors": [] + ] } ] } @@ -843,3 +840,234 @@ def test_File_create_object_copyright_missing(self): result = models.File(data) assert [] == result.copyrights + + def test_Copyright_multiple_statements_and_holders(self): + new = { + 'path': 'path/modified.txt', + 'type': 'file', + 'name': 'modified.txt', + 'size': 20, + 'sha1': 'a', + 'original_path': '', + 'licenses': [], + 'copyrights': [ + { + "statements": [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler", + "Copyright (c) 1998 by Andreas R. Kleinert", + "Copyright (c) 2002-2004 Dmitriy Anisimkov", + "Copyright (c) 1998, 2007 Brian Raiter", + "Copyright (c) 1997,99 Borland Corp.", + "(c) Copyright Henrik Ravn 2004", + "Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.", + "Copyright (c) 2003 Chris Anderson", + "Copyright (c) 1997 Christian Michelsen Research as Advanced Computing", + "Copyright (c) 2009-2010 Mathias Svensson http://result42.com", + "Copyright (c) 1990-2000 Info-ZIP.", + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler", + "Copyright (c) 1998 by Andreas R. Kleinert", + "Copyright (c) 2002-2004 Dmitriy Anisimkov", + "Copyright (c) 1998, 2007 Brian Raiter", + "Copyright (c) 1997,99 Borland Corp.", + "(c) Copyright Henrik Ravn 2004", + "Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.", + "Copyright (c) 2003 Chris Anderson", + "Copyright (c) 1997 Christian Michelsen Research as Advanced Computing", + "Copyright (c) 2009-2010 Mathias Svensson http://result42.com", + "Copyright (c) 1990-2000 Info-ZIP." + ], + "holders": [ + "Jean-loup Gailly, Mark Adler", + "Andreas R. Kleinert", + "Dmitriy Anisimkov", + "Brian Raiter", + "Borland Corp.", + "Henrik Ravn", + "Jean-loup Gailly, Brian Raiter, Gilles Vollant", + "Chris Anderson", + "Christian Michelsen Research as Advanced Computing", + "Mathias Svensson", + "Info-ZIP", + "Jean-loup Gailly, Mark Adler", + "Andreas R. Kleinert", + "Dmitriy Anisimkov", + "Brian Raiter", + "Borland Corp.", + "Henrik Ravn", + "Jean-loup Gailly, Brian Raiter, Gilles Vollant", + "Chris Anderson", + "Christian Michelsen Research as Advanced Computing", + "Mathias Svensson", + "Info-ZIP" + ], + "authors": [] + } + ] + } + + result_new = models.File(new) + new_copyrights = result_new.copyrights.pop() + + assert new_copyrights.statements == [ + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler", + "Copyright (c) 1998 by Andreas R. Kleinert", + "Copyright (c) 2002-2004 Dmitriy Anisimkov", + "Copyright (c) 1998, 2007 Brian Raiter", + "Copyright (c) 1997,99 Borland Corp.", + "(c) Copyright Henrik Ravn 2004", + "Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.", + "Copyright (c) 2003 Chris Anderson", + "Copyright (c) 1997 Christian Michelsen Research as Advanced Computing", + "Copyright (c) 2009-2010 Mathias Svensson http://result42.com", + "Copyright (c) 1990-2000 Info-ZIP.", + "Copyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler", + "Copyright (c) 1998 by Andreas R. Kleinert", + "Copyright (c) 2002-2004 Dmitriy Anisimkov", + "Copyright (c) 1998, 2007 Brian Raiter", + "Copyright (c) 1997,99 Borland Corp.", + "(c) Copyright Henrik Ravn 2004", + "Copyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.", + "Copyright (c) 2003 Chris Anderson", + "Copyright (c) 1997 Christian Michelsen Research as Advanced Computing", + "Copyright (c) 2009-2010 Mathias Svensson http://result42.com", + "Copyright (c) 1990-2000 Info-ZIP." + ] + + assert new_copyrights.holders == [ + "Jean-loup Gailly, Mark Adler", + "Andreas R. Kleinert", + "Dmitriy Anisimkov", + "Brian Raiter", + "Borland Corp.", + "Henrik Ravn", + "Jean-loup Gailly, Brian Raiter, Gilles Vollant", + "Chris Anderson", + "Christian Michelsen Research as Advanced Computing", + "Mathias Svensson", + "Info-ZIP", + "Jean-loup Gailly, Mark Adler", + "Andreas R. Kleinert", + "Dmitriy Anisimkov", + "Brian Raiter", + "Borland Corp.", + "Henrik Ravn", + "Jean-loup Gailly, Brian Raiter, Gilles Vollant", + "Chris Anderson", + "Christian Michelsen Research as Advanced Computing", + "Mathias Svensson", + "Info-ZIP" + ] + + def test_Copyright_unusual_characters(self): + new = { + 'path': 'path/modified.txt', + 'type': 'file', + 'name': 'modified.txt', + 'size': 20, + 'sha1': 'a', + 'original_path': '', + 'licenses': [], + 'copyrights': [ + { + "statements": [ + "~@ \n \r", + " ", + "\x80abc", + "\xc3", + "\xa0", + "\xaa", + "\xb9", + "\xa9", + "\xa8", + "\xb4", + "\xae", + "-", + "\xe2", + "\x80", + "\x99", + "\xa2", + "\xa7", + "\xbb", + "\xaf", + "U+00E9", + "\xc3\xa9" + + ], + "holders": [ + "~@ \n \r", + " ", + "\x80abc", + "\xc3", + "\xa0", + "\xaa", + "\xb9", + "\xa9", + "\xa8", + "\xb4", + "\xae", + "-", + "\xe2", + "\x80", + "\x99", + "\xa2", + "\xa7", + "\xbb", + "\xaf", + "U+00E9", + "\xc3\xa9" + ], + "authors": [] + } + ] + } + + result_new = models.File(new) + new_copyrights = result_new.copyrights.pop() + + assert new_copyrights.statements == [ + "~@ \n \r", + " ", + "\x80abc", + "\xc3", + "\xa0", + "\xaa", + "\xb9", + "\xa9", + "\xa8", + "\xb4", + "\xae", + "-", + "\xe2", + "\x80", + "\x99", + "\xa2", + "\xa7", + "\xbb", + "\xaf", + "U+00E9", + "\xc3\xa9" + ] + + assert new_copyrights.holders == [ + "~@ \n \r", + " ", + "\x80abc", + "\xc3", + "\xa0", + "\xaa", + "\xb9", + "\xa9", + "\xa8", + "\xb4", + "\xae", + "-", + "\xe2", + "\x80", + "\x99", + "\xa2", + "\xa7", + "\xbb", + "\xaf", + "U+00E9", + "\xc3\xa9" + ] \ No newline at end of file From d2cb79d52bfdc8b57f3bd1dc548442aad77a112d Mon Sep 17 00:00:00 2001 From: "John M. Horan" Date: Tue, 6 Mar 2018 13:09:02 -0800 Subject: [PATCH 5/7] Rename method to 'delta.update()' #82 #83 Signed-off-by: John M. Horan --- src/deltacode/__init__.py | 21 ++++++++++----------- tests/test_deltacode.py | 6 +++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/deltacode/__init__.py b/src/deltacode/__init__.py index 37c7655c..67ac7f1f 100644 --- a/src/deltacode/__init__.py +++ b/src/deltacode/__init__.py @@ -199,18 +199,18 @@ def license_diff(self): old_licenses = delta.old_file.licenses or [] if len(delta.new_file.licenses) > 0 and delta.old_file.licenses == []: - delta.add_score(20, 'license info added') + delta.update(20, 'license info added') return if delta.new_file.licenses == [] and len(delta.old_file.licenses) > 0: - delta.add_score(15, 'license info removed') + delta.update(15, 'license info removed') return new_keys = set(license.key for license in new_licenses) old_keys = set(license.key for license in old_licenses) if new_keys != old_keys: - delta.add_score(10, 'license change') + delta.update(10, 'license change') def copyright_diff(self): """ @@ -228,10 +228,10 @@ def copyright_diff(self): old_copyrights = delta.old_file.copyrights or [] if len(delta.new_file.copyrights) > 0 and delta.old_file.copyrights == []: - delta.add_score(10, 'copyright info added') + delta.update(10, 'copyright info added') return elif delta.new_file.copyrights == [] and len(delta.old_file.copyrights) > 0: - delta.add_score(10, 'copyright info removed') + delta.update(10, 'copyright info removed') return new_statements = set(statement for copyright in new_copyrights for statement in copyright.statements) @@ -242,7 +242,7 @@ def copyright_diff(self): if ((new_statements != old_statements) or (new_holders != old_holders)): - delta.add_score(5, 'copyright change') + delta.update(5, 'copyright change') def index_deltas(self, index_key='path', delta_list=[]): """ @@ -280,12 +280,11 @@ def __init__(self, score=0, new_file=None, old_file=None): self.factors = [] self.score = score - def add_score(self, score=0, factor=''): + def update(self, score=0, factor=''): """ - For each Delta object identified in DeltaCode.license_diff() or - DeltaCode.copyright_diff(), add the score to the object's 'score' - attribute and add a string, summarizing the factor associated with the - score, to the object's 'factors' attribute (a list). + Add the score to the Delta object's 'score' attribute and add a string, + summarizing the factor associated with the score, to the object's + 'factors' attribute (a list). """ self.factors.append(factor) self.score += score diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index f7902422..fc36934b 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -1661,7 +1661,7 @@ def test_Delta_add_score_added(self): delta = deltacode.Delta(100, new, None) - delta.add_score(25, 'This is a test of an added file') + delta.update(25, 'This is a test of an added file') assert delta.score == 125 assert delta.factors == ['This is a test of an added file'] @@ -1686,7 +1686,7 @@ def test_Delta_add_score_modified(self): delta = deltacode.Delta(20, new, old) - delta.add_score(25, 'This is a test of a modified file') + delta.update(25, 'This is a test of a modified file') assert delta.score == 45 assert delta.factors == ['This is a test of a modified file'] @@ -1708,7 +1708,7 @@ def test_Delta_add_score_license_change_no_copyright_change(self): for d in deltas_object: if d.new_file.path == 'path.txt': - d.add_score(25, 'This is a test of a license change') + d.update(25, 'This is a test of a license change') assert [d.score for d in deltas_object if d.new_file.path == 'path.txt'] == [55] assert [d.factors for d in deltas_object if d.new_file.path == 'path.txt'].pop() == ['modified', 'license change', 'This is a test of a license change'] From 195eb00251d99db9e48e0a301cebb70a3939c766 Mon Sep 17 00:00:00 2001 From: "John M. Horan" Date: Wed, 7 Mar 2018 12:09:30 -0800 Subject: [PATCH 6/7] Test copyrights for unusual characters #82 #83 * Added scans and tests for unusual characters like French and German letters with accent marks. Signed-off-by: John M. Horan --- .../scan_unusual_characters_new.json | 554 ++++++++++++++++++ .../scan_unusual_characters_old.json | 164 ++++++ tests/test_deltacode.py | 37 +- tests/test_models.py | 2 +- 4 files changed, 752 insertions(+), 5 deletions(-) create mode 100644 tests/data/deltacode/scan_unusual_characters_new.json create mode 100644 tests/data/deltacode/scan_unusual_characters_old.json diff --git a/tests/data/deltacode/scan_unusual_characters_new.json b/tests/data/deltacode/scan_unusual_characters_new.json new file mode 100644 index 00000000..98053095 --- /dev/null +++ b/tests/data/deltacode/scan_unusual_characters_new.json @@ -0,0 +1,554 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.9.0b1", + "scancode_options": { + "input": "C:\\code\\nexb\\dev\\codebase01\\copyrights\\unusual_characters\\new", + "--copyright": true, + "--info": true, + "--json-pp": "C:\\code\\nexb\\dev\\deltacode\\tests\\data\\deltacode\\scan_unusual_characters_new.json", + "--license": true, + "--package": true + }, + "files_count": 2, + "files": [ + { + "path": "new", + "type": "directory", + "name": "new", + "base_name": "new", + "extension": "", + "size": 0, + "date": null, + "sha1": null, + "md5": null, + "mime_type": null, + "file_type": null, + "programming_language": null, + "is_binary": false, + "is_text": false, + "is_archive": false, + "is_media": false, + "is_source": false, + "is_script": false, + "licenses": [], + "copyrights": [], + "packages": [], + "files_count": 2, + "dirs_count": 0, + "size_count": 4230, + "scan_errors": [] + }, + { + "path": "new/a1.py", + "type": "file", + "name": "a1.py", + "base_name": "a1", + "extension": ".py", + "size": 4030, + "date": "2018-03-07", + "sha1": "8ed1e2247db1c6d22e6fd82dd38de49d8629d811", + "md5": "62281ed749febab129c6c8bc62a847c9", + "mime_type": "text/plain", + "file_type": "UTF-8 Unicode text, with CRLF line terminators", + "programming_language": "Python", + "is_binary": false, + "is_text": true, + "is_archive": false, + "is_media": false, + "is_source": true, + "is_script": false, + "licenses": [ + { + "key": "apache-2.0", + "score": 40.0, + "short_name": "Apache 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:apache-2.0", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 3, + "end_line": 3, + "matched_rule": { + "identifier": "apache-2.0_57.RULE", + "license_choice": false, + "licenses": [ + "apache-2.0" + ] + } + }, + { + "key": "adapt-1.0", + "score": 15.0, + "short_name": "APL 1.0", + "category": "Copyleft", + "owner": "OSI - Open Source Initiative", + "homepage_url": "http://www.opensource.org/licenses/apl1.0.php", + "text_url": "http://www.opensource.org/licenses/apl1.0.php", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:adapt-1.0", + "spdx_license_key": "APL-1.0", + "spdx_url": "https://spdx.org/licenses/APL-1.0", + "start_line": 8, + "end_line": 8, + "matched_rule": { + "identifier": "adapt-1.0_2.RULE", + "license_choice": false, + "licenses": [ + "adapt-1.0" + ] + } + }, + { + "key": "adapt-1.0", + "score": 15.0, + "short_name": "APL 1.0", + "category": "Copyleft", + "owner": "OSI - Open Source Initiative", + "homepage_url": "http://www.opensource.org/licenses/apl1.0.php", + "text_url": "http://www.opensource.org/licenses/apl1.0.php", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:adapt-1.0", + "spdx_license_key": "APL-1.0", + "spdx_url": "https://spdx.org/licenses/APL-1.0", + "start_line": 9, + "end_line": 9, + "matched_rule": { + "identifier": "adapt-1.0_2.RULE", + "license_choice": false, + "licenses": [ + "adapt-1.0" + ] + } + }, + { + "key": "carnegie-mellon", + "score": 100.0, + "short_name": "Carnegie Mellon License", + "category": "Permissive", + "owner": "Carnegie Mellon University", + "homepage_url": "", + "text_url": "", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:carnegie-mellon", + "spdx_license_key": "", + "spdx_url": "", + "start_line": 35, + "end_line": 43, + "matched_rule": { + "identifier": "carnegie-mellon.LICENSE", + "license_choice": false, + "licenses": [ + "carnegie-mellon" + ] + } + }, + { + "key": "cc-by-sa-4.0", + "score": 30.0, + "short_name": "CC-BY-SA-4.0", + "category": "Copyleft", + "owner": "Creative Commons", + "homepage_url": "http://creativecommons.org/licenses/by-sa/4.0/", + "text_url": "http://creativecommons.org/licenses/by-sa/4.0/legalcode", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:cc-by-sa-4.0", + "spdx_license_key": "CC-BY-SA-4.0", + "spdx_url": "https://spdx.org/licenses/CC-BY-SA-4.0", + "start_line": 48, + "end_line": 48, + "matched_rule": { + "identifier": "cc-by-sa-4.0_5.RULE", + "license_choice": false, + "licenses": [ + "cc-by-sa-4.0" + ] + } + }, + { + "key": "mit", + "score": 15.0, + "short_name": "MIT License", + "category": "Permissive", + "owner": "MIT", + "homepage_url": "http://opensource.org/licenses/mit-license.php", + "text_url": "http://opensource.org/licenses/mit-license.php", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:mit", + "spdx_license_key": "MIT", + "spdx_url": "https://spdx.org/licenses/MIT", + "start_line": 70, + "end_line": 70, + "matched_rule": { + "identifier": "mit_27.RULE", + "license_choice": false, + "licenses": [ + "mit" + ] + } + }, + { + "key": "mit", + "score": 15.0, + "short_name": "MIT License", + "category": "Permissive", + "owner": "MIT", + "homepage_url": "http://opensource.org/licenses/mit-license.php", + "text_url": "http://opensource.org/licenses/mit-license.php", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:mit", + "spdx_license_key": "MIT", + "spdx_url": "https://spdx.org/licenses/MIT", + "start_line": 73, + "end_line": 73, + "matched_rule": { + "identifier": "mit_27.RULE", + "license_choice": false, + "licenses": [ + "mit" + ] + } + }, + { + "key": "apache-2.0", + "score": 25.0, + "short_name": "Apache 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:apache-2.0", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 76, + "end_line": 77, + "matched_rule": { + "identifier": "apache-2.0_48.RULE", + "license_choice": false, + "licenses": [ + "apache-2.0" + ] + } + }, + { + "key": "apache-2.0", + "score": 25.0, + "short_name": "Apache 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:apache-2.0", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 78, + "end_line": 78, + "matched_rule": { + "identifier": "apache.RULE", + "license_choice": false, + "licenses": [ + "apache-2.0" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017-2018 Francois Hennebique and others." + ], + "holders": [ + "Francois Hennebique and others." + ], + "authors": [], + "start_line": 2, + "end_line": 2 + }, + { + "statements": [ + "Copyright (c) 1996 Hercules Florence and others." + ], + "holders": [ + "Hercules Florence and others." + ], + "authors": [], + "start_line": 7, + "end_line": 7 + }, + { + "statements": [ + "Copyright (c) 2001-2004 Barthelemy Thimonnier." + ], + "holders": [ + "Barthelemy Thimonnier." + ], + "authors": [], + "start_line": 14, + "end_line": 14 + }, + { + "statements": [ + "Copyright (c) 2015 Edouard-Leon Scott de Martinville." + ], + "holders": [ + "Edouard-Leon Scott de Martinville." + ], + "authors": [], + "start_line": 22, + "end_line": 22 + }, + { + "statements": [ + "Copyright (c) 2012-2014 Henri Dupuy de Lome." + ], + "holders": [ + "Henri Dupuy de Lome." + ], + "authors": [], + "start_line": 28, + "end_line": 28 + }, + { + "statements": [ + "Copyright (c) 2018 Nicolas Grollier de Serviere." + ], + "holders": [ + "Nicolas Grollier de Serviere." + ], + "authors": [], + "start_line": 34, + "end_line": 34 + }, + { + "statements": [ + "Copyright (c) 1999 Ottomar Anschutz." + ], + "holders": [ + "Ottomar Anschutz." + ], + "authors": [], + "start_line": 47, + "end_line": 47 + }, + { + "statements": [ + "Copyright (c) 2015-18 Christiane Nusslein-Volhard." + ], + "holders": [ + "Christiane Nusslein-Volhard." + ], + "authors": [], + "start_line": 52, + "end_line": 52 + }, + { + "statements": [ + "Copyright (c) 1999 Behram Kursunoglu." + ], + "holders": [ + "Behram Kursunoglu." + ], + "authors": [], + "start_line": 60, + "end_line": 60 + }, + { + "statements": [ + "Copyright International Business" + ], + "holders": [ + "International Business" + ], + "authors": [], + "start_line": 61, + "end_line": 62 + }, + { + "statements": [ + "Copyright (c) 2015-2016, Jon Schlinkert." + ], + "holders": [ + "Jon Schlinkert." + ], + "authors": [], + "start_line": 70, + "end_line": 71 + }, + { + "statements": [ + "Copyright (c) 2015 Kyle E. Mitchell" + ], + "holders": [ + "Kyle E. Mitchell" + ], + "authors": [], + "start_line": 73, + "end_line": 74 + }, + { + "statements": [ + "Copyright (c) 2015, Salesforce.com, Inc." + ], + "holders": [ + "Salesforce.com, Inc." + ], + "authors": [], + "start_line": 78, + "end_line": 80 + }, + { + "statements": [ + "Copyright (c) 2016-2018 HERE Global B.V." + ], + "holders": [ + "HERE Global B.V." + ], + "authors": [], + "start_line": 82, + "end_line": 82 + }, + { + "statements": [ + "Copyright (c) 2018 John ~@ Doe.", + "Copyright (c) 2018 John   Doe.", + "Copyright (c) 2018 John x80abc Doe.", + "Copyright (c) 2018 John xc3 Doe.", + "Copyright (c) 2018 John xa0 Doe.", + "Copyright (c) 2018 John xaa Doe.", + "Copyright (c) 2018 John xb9 Doe.", + "Copyright (c) 2018 John xa9 Doe.", + "Copyright (c) 2018 John xa8 Doe.", + "Copyright (c) 2018 John xb4 Doe.", + "Copyright (c) 2018 John xae Doe.", + "Copyright (c) 2018 John", + "Copyright (c) 2018 John xe2 Doe.", + "Copyright (c) 2018 John x80 Doe.", + "Copyright (c) 2018 John x99 Doe.", + "Copyright (c) 2018 John xa2 Doe.", + "Copyright (c) 2018 John xa7 Doe.", + "Copyright (c) 2018 John xbb Doe.", + "Copyright (c) 2018 John xaf Doe.", + "Copyright (c) 2018 John U+00E9 Doe.", + "Copyright (c) 2018 John", + "Copyright (c) 2018 John" + ], + "holders": [ + "John ~@ Doe.", + "John   Doe.", + "John x80abc Doe.", + "John xc3 Doe.", + "John xa0 Doe.", + "John xaa Doe.", + "John xb9 Doe.", + "John xa9 Doe.", + "John xa8 Doe.", + "John xb4 Doe.", + "John xae Doe.", + "John", + "John xe2 Doe.", + "John x80 Doe.", + "John x99 Doe.", + "John xa2 Doe.", + "John xa7 Doe.", + "John xbb Doe.", + "John xaf Doe.", + "John U+00E9 Doe.", + "John", + "John" + ], + "authors": [], + "start_line": 84, + "end_line": 105 + }, + { + "statements": [ + "Copyright (c) 2018 John MOV", + "Copyright (c) 2018 John MOV", + "Copyright (c) 2018 John MOV" + ], + "holders": [ + "John MOV", + "John MOV", + "John MOV" + ], + "authors": [], + "start_line": 107, + "end_line": 109 + }, + { + "statements": [ + "Copyright (c) 2018 John" + ], + "holders": [ + "John" + ], + "authors": [], + "start_line": 111, + "end_line": 111 + } + ], + "packages": [], + "files_count": 0, + "dirs_count": 0, + "size_count": 0, + "scan_errors": [] + }, + { + "path": "new/a2.py", + "type": "file", + "name": "a2.py", + "base_name": "a2", + "extension": ".py", + "size": 200, + "date": "2017-09-26", + "sha1": "310797523e47db8481aeb06f1634317285115091", + "md5": "19efdad483f68bc9997a5c1f7ba41b26", + "mime_type": "text/plain", + "file_type": "ASCII text, with CRLF line terminators", + "programming_language": "Python", + "is_binary": false, + "is_text": true, + "is_archive": false, + "is_media": false, + "is_source": true, + "is_script": false, + "licenses": [ + { + "key": "apache-2.0", + "score": 40.0, + "short_name": "Apache 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:apache-2.0", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 3, + "end_line": 3, + "matched_rule": { + "identifier": "apache-2.0_57.RULE", + "license_choice": false, + "licenses": [ + "apache-2.0" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [], + "start_line": 2, + "end_line": 2 + } + ], + "packages": [], + "files_count": 0, + "dirs_count": 0, + "size_count": 0, + "scan_errors": [] + } + ] +} diff --git a/tests/data/deltacode/scan_unusual_characters_old.json b/tests/data/deltacode/scan_unusual_characters_old.json new file mode 100644 index 00000000..aea43bad --- /dev/null +++ b/tests/data/deltacode/scan_unusual_characters_old.json @@ -0,0 +1,164 @@ +{ + "scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "scancode_version": "2.9.0b1", + "scancode_options": { + "input": "C:\\code\\nexb\\dev\\codebase01\\copyrights\\unusual_characters\\old", + "--copyright": true, + "--info": true, + "--json-pp": "C:\\code\\nexb\\dev\\deltacode\\tests\\data\\models\\scan\\scan_unusual_characters_old.json", + "--license": true, + "--package": true + }, + "files_count": 2, + "files": [ + { + "path": "old", + "type": "directory", + "name": "old", + "base_name": "old", + "extension": "", + "size": 0, + "date": null, + "sha1": null, + "md5": null, + "mime_type": null, + "file_type": null, + "programming_language": null, + "is_binary": false, + "is_text": false, + "is_archive": false, + "is_media": false, + "is_source": false, + "is_script": false, + "licenses": [], + "copyrights": [], + "packages": [], + "files_count": 2, + "dirs_count": 0, + "size_count": 400, + "scan_errors": [] + }, + { + "path": "old/a1.py", + "type": "file", + "name": "a1.py", + "base_name": "a1", + "extension": ".py", + "size": 200, + "date": "2017-09-26", + "sha1": "84b647771481d39dd3a53f6dc210c26abac37748", + "md5": "3cb56efa7140478458dbaa2b30239845", + "mime_type": "text/plain", + "file_type": "ASCII text, with CRLF line terminators", + "programming_language": "Python", + "is_binary": false, + "is_text": true, + "is_archive": false, + "is_media": false, + "is_source": true, + "is_script": false, + "licenses": [ + { + "key": "apache-2.0", + "score": 40.0, + "short_name": "Apache 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:apache-2.0", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 3, + "end_line": 3, + "matched_rule": { + "identifier": "apache-2.0_57.RULE", + "license_choice": false, + "licenses": [ + "apache-2.0" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [], + "start_line": 2, + "end_line": 2 + } + ], + "packages": [], + "files_count": 0, + "dirs_count": 0, + "size_count": 0, + "scan_errors": [] + }, + { + "path": "old/a2.py", + "type": "file", + "name": "a2.py", + "base_name": "a2", + "extension": ".py", + "size": 200, + "date": "2017-09-26", + "sha1": "310797523e47db8481aeb06f1634317285115091", + "md5": "19efdad483f68bc9997a5c1f7ba41b26", + "mime_type": "text/plain", + "file_type": "ASCII text, with CRLF line terminators", + "programming_language": "Python", + "is_binary": false, + "is_text": true, + "is_archive": false, + "is_media": false, + "is_source": true, + "is_script": false, + "licenses": [ + { + "key": "apache-2.0", + "score": 40.0, + "short_name": "Apache 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://enterprise.dejacode.com/urn/urn:dje:license:apache-2.0", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 3, + "end_line": 3, + "matched_rule": { + "identifier": "apache-2.0_57.RULE", + "license_choice": false, + "licenses": [ + "apache-2.0" + ] + } + } + ], + "copyrights": [ + { + "statements": [ + "Copyright (c) 2017 Acme Software Inc. and others." + ], + "holders": [ + "Acme Software Inc. and others." + ], + "authors": [], + "start_line": 2, + "end_line": 2 + } + ], + "packages": [], + "files_count": 0, + "dirs_count": 0, + "size_count": 0, + "scan_errors": [] + } + ] +} diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index fc36934b..d3e58138 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -1649,7 +1649,7 @@ def test_score_license_change_no_copyright_change(self): assert len([i for i in deltas_object if i.score == 25]) == 0 assert len([i for i in deltas_object if i.score == 20]) == 0 - def test_Delta_add_score_added(self): + def test_Delta_update_added(self): new = models.File({ 'path': 'path/added.txt', 'type': 'file', @@ -1666,7 +1666,7 @@ def test_Delta_add_score_added(self): assert delta.score == 125 assert delta.factors == ['This is a test of an added file'] - def test_Delta_add_score_modified(self): + def test_Delta_update_modified(self): new = models.File({ 'path': 'path/modified.txt', 'type': 'file', @@ -1691,7 +1691,7 @@ def test_Delta_add_score_modified(self): assert delta.score == 45 assert delta.factors == ['This is a test of a modified file'] - def test_Delta_add_score_license_change_no_copyright_change(self): + def test_Delta_update_license_change_no_copyright_change(self): new_scan = self.get_test_loc('deltacode/score_license_change_no_copyright_change_new.json') old_scan = self.get_test_loc('deltacode/score_license_change_no_copyright_change_old.json') @@ -1886,4 +1886,33 @@ def test_Delta_to_dict_multiple_copyright_statements_and_holders(self): delta.factors.append('modified') assert delta.to_dict() == expected - # print('\n\ndelta.to_dict() = {}\n'.format(delta.to_dict())) + + def test_Delta_to_dict_Copyright_unusual_characters(self): + new_scan = self.get_test_loc('deltacode/scan_unusual_characters_new.json') + old_scan = self.get_test_loc('deltacode/scan_unusual_characters_old.json') + + options = OrderedDict([ + ('--all-delta-types', False) + ]) + + deltacode_object = DeltaCode(new_scan, old_scan, options) + + deltas_object = deltacode_object.deltas + + assert [d.factors for d in deltas_object if d.new_file.path == 'a1.py'].pop() == ['modified', 'license change', 'copyright change'] + + holders_list = [zzz.holders.pop() for d in deltas_object if d.new_file.path == 'a1.py' for zzz in d.new_file.copyrights] + print('\n\nholders_list_02 = {}\n'.format(holders_list)) + + assert 'Francois Hennebique and others.' in holders_list + assert 'Ottomar Anschutz.' in holders_list + assert 'Christiane Nusslein-Volhard.' in holders_list + assert 'Behram Kursunoglu.' in holders_list + + statements_list = [zzz.statements.pop() for d in deltas_object if d.new_file.path == 'a1.py' for zzz in d.new_file.copyrights] + print('\n\nstatements_list = {}\n'.format(statements_list)) + + assert 'Copyright (c) 2017-2018 Francois Hennebique and others.' in statements_list + assert 'Copyright (c) 1999 Ottomar Anschutz.' in statements_list + assert 'Copyright (c) 2015-18 Christiane Nusslein-Volhard.' in statements_list + assert 'Copyright (c) 1999 Behram Kursunoglu.' in statements_list diff --git a/tests/test_models.py b/tests/test_models.py index 3201d4d9..b5fe5e4c 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1070,4 +1070,4 @@ def test_Copyright_unusual_characters(self): "\xaf", "U+00E9", "\xc3\xa9" - ] \ No newline at end of file + ] From 4199bcd38006f557b76ec66241643eec228deb07 Mon Sep 17 00:00:00 2001 From: "John M. Horan" Date: Thu, 8 Mar 2018 12:33:58 -0800 Subject: [PATCH 7/7] Remove print statements #82 #83 Signed-off-by: John M. Horan --- tests/test_deltacode.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index d3e58138..bc6082c1 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -1901,16 +1901,14 @@ def test_Delta_to_dict_Copyright_unusual_characters(self): assert [d.factors for d in deltas_object if d.new_file.path == 'a1.py'].pop() == ['modified', 'license change', 'copyright change'] - holders_list = [zzz.holders.pop() for d in deltas_object if d.new_file.path == 'a1.py' for zzz in d.new_file.copyrights] - print('\n\nholders_list_02 = {}\n'.format(holders_list)) + holders_list = [c.holders.pop() for d in deltas_object if d.new_file.path == 'a1.py' for c in d.new_file.copyrights] assert 'Francois Hennebique and others.' in holders_list assert 'Ottomar Anschutz.' in holders_list assert 'Christiane Nusslein-Volhard.' in holders_list assert 'Behram Kursunoglu.' in holders_list - statements_list = [zzz.statements.pop() for d in deltas_object if d.new_file.path == 'a1.py' for zzz in d.new_file.copyrights] - print('\n\nstatements_list = {}\n'.format(statements_list)) + statements_list = [c.statements.pop() for d in deltas_object if d.new_file.path == 'a1.py' for c in d.new_file.copyrights] assert 'Copyright (c) 2017-2018 Francois Hennebique and others.' in statements_list assert 'Copyright (c) 1999 Ottomar Anschutz.' in statements_list