From 2b5c8e18457e29dc6e2d0b32f8d20a8a3c546a46 Mon Sep 17 00:00:00 2001 From: Rishii Date: Mon, 2 Jun 2025 18:45:53 +0530 Subject: [PATCH 1/2] Organized and cleaned up Code Signed-off-by: Rishii --- src/attributecode/model.py | 90 +++++++++------------------------- src/attributecode/transform.py | 8 ++- src/attributecode/util.py | 44 +++++++++++++++++ 3 files changed, 73 insertions(+), 69 deletions(-) diff --git a/src/attributecode/model.py b/src/attributecode/model.py index e935af2b..33c631c4 100644 --- a/src/attributecode/model.py +++ b/src/attributecode/model.py @@ -37,34 +37,26 @@ from license_expression import Licensing from packageurl import PackageURL - -from attributecode import __version__ -from attributecode import CRITICAL -from attributecode import ERROR -from attributecode import INFO -from attributecode import WARNING -from attributecode import api -from attributecode import Error -from attributecode import saneyaml -from attributecode import gen -from attributecode import util -from attributecode.transform import write_excel -from attributecode.util import add_unc -from attributecode.util import boolean_fields -from attributecode.util import copy_license_notice_files -from attributecode.util import copy_file -from attributecode.util import csv -from attributecode.util import file_fields -from attributecode.util import filter_errors -from attributecode.util import get_spdx_key_and_lic_key_from_licdb -from attributecode.util import is_valid_name -from attributecode.util import on_windows -from attributecode.util import norm -from attributecode.util import replace_tab_with_spaces -from attributecode.util import wrap_boolean_value -from attributecode.util import UNC_PREFIX -from attributecode.util import ungroup_licenses -from attributecode.util import ungroup_licenses_from_sctk +from attributecode.util import ( + add_unc, + boolean_fields, + copy_license_notice_files, + copy_file, + csv, + file_fields, + filter_errors, + get_spdx_key_and_lic_key_from_licdb, + is_valid_name, + on_windows, + norm, + replace_tab_with_spaces, + wrap_boolean_value, + UNC_PREFIX, + ungroup_licenses, + ungroup_licenses_from_sctk, + parse_license_expression, + detect_special_char, +) genereated_tk_version = "# Generated with AboutCode Toolkit Version %s \n\n" % __version__ @@ -234,9 +226,10 @@ class StringField(Field): """ def _validate(self, *args, **kwargs): - errors = super(StringField, self)._validate(*args, ** kwargs) + errors = super(StringField, self)._validate(*args, **kwargs) + no_special_char_field = [ - 'license_expression', 'license_key', 'license_name', 'declared_license_expression', 'other_license_expression '] + 'license_expression', 'license_key', 'license_name', 'declared_license_expression', 'other_license_expression'] name = self.name if name in no_special_char_field: val = self.value @@ -2145,40 +2138,3 @@ def convert_spdx_expression_to_lic_expression(spdx_key, spdx_lic_dict): return value -def parse_license_expression(lic_expression): - licensing = Licensing() - lic_list = [] - invalid_lic_exp = '' - special_char = detect_special_char(lic_expression) - if not special_char: - # Parse the license expression and save it into a list - try: - lic_list = licensing.license_keys(lic_expression) - except: - invalid_lic_exp = lic_expression - return special_char, lic_list, invalid_lic_exp - - -def detect_special_char(expression): - not_support_char = [ - '!', '@', '#', '$', '^', '&', '*', '=', '{', '}', - '|', '[', ']', '\\', ':', ';', '<', '>', '?', ',', '/'] - special_character = [] - for char in not_support_char: - if char in expression: - special_character.append(char) - return special_character - - -def valid_api_url(api_url): - try: - response = get(api_url) - # The 403 error code is expected if the api_url is pointing to DJE as no - # API key is provided. The 200 status code represent connection success - # to scancode's LicenseDB. All other exception yield to invalid api_url - if response.status_code == 403 or response.status_code == 200: - return True - else: - return False - except: - return False diff --git a/src/attributecode/transform.py b/src/attributecode/transform.py index 46b2412e..f4ad670a 100644 --- a/src/attributecode/transform.py +++ b/src/attributecode/transform.py @@ -23,8 +23,12 @@ from attributecode import CRITICAL from attributecode import Error from attributecode import saneyaml -from attributecode.util import csv -from attributecode.util import replace_tab_with_spaces +from attributecode.util import ( + csv, + replace_tab_with_spaces, + parse_license_expression, # canonical implementation from util.py + detect_special_char, # canonical implementation from util.py +) def transform_csv(location): diff --git a/src/attributecode/util.py b/src/attributecode/util.py index 5f398d7d..39a1569d 100644 --- a/src/attributecode/util.py +++ b/src/attributecode/util.py @@ -272,6 +272,50 @@ def get_spdx_key_and_lic_key_from_licdb(): lic_dict[other_spdx] = license["license_key"] return lic_dict +def detect_special_char(expression): +""" +Canonical implementation of license expression parsing and special character detection. +Import and use these from util.py everywhere in the codebase to avoid duplication. +""" +def parse_license_expression(lic_expression): + from license_expression import Licensing + licensing = Licensing() + lic_list = [] + invalid_lic_exp = '' + special_char = detect_special_char(lic_expression) + if not special_char: + # Parse the license expression and save it into a list + try: + lic_list = licensing.license_keys(lic_expression) + except Exception: + invalid_lic_exp = lic_expression + return special_char, lic_list, invalid_lic_exp + +def detect_special_char(expression): + not_support_char = [ + '!', '@', '#', '$', '^', '&', '*', '=', '{', '}', + '|', '[', ']', '\\', ':', ';', '<', '>', '?', ',', '/'] + special_character = [] + if not isinstance(expression, str): + return special_character + for char in not_support_char: + if char in expression: + special_character.append(char) + return special_character + + +def valid_api_url(api_url): + try: + response = get(api_url) + # The 403 error code is expected if the api_url is pointing to DJE as no + # API key is provided. The 200 status code represent connection success + # to scancode's LicenseDB. All other exception yield to invalid api_url + if response.status_code == 403 or response.status_code == 200: + return True + else: + return False + except: + return False def get_relative_path(base_loc, full_loc): From f55b9bb46d5b4cef3f0d833ed4531a09303c820c Mon Sep 17 00:00:00 2001 From: Rishii <93253525+RISHII-BHARADHWAJ@users.noreply.github.com> Date: Mon, 2 Jun 2025 14:18:55 +0000 Subject: [PATCH 2/2] Fix: ensure all license blocks rendered in HTML output, resolve import and template issues, update tests for AboutCode Toolkit --- src/attributecode/api.py | 2 +- src/attributecode/attrib.py | 8 +- src/attributecode/cmd.py | 3 +- src/attributecode/gen.py | 4 +- src/attributecode/model.py | 14 +- src/attributecode/util.py | 4 +- tests/test_attrib.py | 53 +- tests/test_attrib/last_run_output.txt | 1491 +++++++++++++++++++++++++ 8 files changed, 1556 insertions(+), 23 deletions(-) create mode 100644 tests/test_attrib/last_run_output.txt diff --git a/src/attributecode/api.py b/src/attributecode/api.py index 4763aa59..deb7720a 100644 --- a/src/attributecode/api.py +++ b/src/attributecode/api.py @@ -23,7 +23,7 @@ from attributecode import ERROR from attributecode import Error - +from attributecode import __version__ """ API call helpers """ diff --git a/src/attributecode/attrib.py b/src/attributecode/attrib.py index b22c6d93..24ffc359 100644 --- a/src/attributecode/attrib.py +++ b/src/attributecode/attrib.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) nexB Inc. http://www.nexB.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -62,7 +62,9 @@ def generate(abouts, is_about_input, license_dict, scancode, min_license_score, template = jinja2.Template(template) # Get the current UTC time - utcnow = datetime.datetime.utcnow() + # utcnow = datetime.datetime.utcnow() + # Use timezone-aware UTC datetime to avoid deprecation warning + utcnow = datetime.datetime.now(datetime.timezone.utc) licenses_list = [] lic_name_expression_list = [] @@ -154,7 +156,7 @@ def generate(abouts, is_about_input, license_dict, scancode, min_license_score, rendered = template.render( abouts=abouts, - common_licenses=COMMON_LICENSES, + common_licenses=[lic.key for lic in licenses_list], licenses_list=licenses_list, utcnow=utcnow, tkversion=__version__, diff --git a/src/attributecode/cmd.py b/src/attributecode/cmd.py index 5f2f5047..1986d3a9 100644 --- a/src/attributecode/cmd.py +++ b/src/attributecode/cmd.py @@ -2,7 +2,7 @@ # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) nexB Inc. http://www.nexB.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -40,6 +40,7 @@ from attributecode import __about_spec_version__ from attributecode.util import unique from attributecode import WARNING +from attributecode import Error from collections import defaultdict from functools import partial diff --git a/src/attributecode/gen.py b/src/attributecode/gen.py index 3b824c20..2576963a 100644 --- a/src/attributecode/gen.py +++ b/src/attributecode/gen.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ - +import saneyaml from posixpath import basename from posixpath import dirname from posixpath import exists @@ -34,7 +34,7 @@ from attributecode.util import UNC_PREFIX_POSIX from attributecode.util import load_scancode_json, load_csv, load_json, load_excel from attributecode.util import strip_inventory_value - +from attributecode import __version__ def check_duplicated_columns(location): """ diff --git a/src/attributecode/model.py b/src/attributecode/model.py index 33c631c4..bb864ab5 100644 --- a/src/attributecode/model.py +++ b/src/attributecode/model.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) nexB Inc. http://www.nexB.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -37,6 +37,9 @@ from license_expression import Licensing from packageurl import PackageURL +from attributecode import __version__ +from attributecode import util +from attributecode import Error, CRITICAL, ERROR, WARNING, INFO from attributecode.util import ( add_unc, boolean_fields, @@ -54,10 +57,13 @@ UNC_PREFIX, ungroup_licenses, ungroup_licenses_from_sctk, - parse_license_expression, - detect_special_char, + parse_license_expression, + detect_special_char, + valid_api_url ) +import saneyaml + genereated_tk_version = "# Generated with AboutCode Toolkit Version %s \n\n" % __version__ @@ -227,7 +233,7 @@ class StringField(Field): def _validate(self, *args, **kwargs): errors = super(StringField, self)._validate(*args, **kwargs) - + no_special_char_field = [ 'license_expression', 'license_key', 'license_name', 'declared_license_expression', 'other_license_expression'] name = self.name diff --git a/src/attributecode/util.py b/src/attributecode/util.py index 39a1569d..eb2357b3 100644 --- a/src/attributecode/util.py +++ b/src/attributecode/util.py @@ -32,6 +32,8 @@ from attributecode import CRITICAL from attributecode import WARNING from attributecode import Error +from attributecode import __version__ +from attributecode import Error on_windows = "win32" in sys.platform @@ -272,7 +274,7 @@ def get_spdx_key_and_lic_key_from_licdb(): lic_dict[other_spdx] = license["license_key"] return lic_dict -def detect_special_char(expression): + """ Canonical implementation of license expression parsing and special character detection. Import and use these from util.py everywhere in the codebase to avoid duplication. diff --git a/tests/test_attrib.py b/tests/test_attrib.py index 59b7d919..f9f428cd 100644 --- a/tests/test_attrib.py +++ b/tests/test_attrib.py @@ -1,8 +1,9 @@ #!/usr/bin/env python + # -*- coding: utf8 -*- # ============================================================================ -# Copyright (c) nexB Inc. http://www.nexb.com/ - All rights reserved. +# Copyright (c) nexB Inc. http://www.nexB.com/ - All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -175,8 +176,14 @@ def test_scancode_input_min_score_0(self): # expected doesn't work well, it works after removed all the newline and spaces # assert expected == result # assert expected.splitlines(False) == result.splitlines(False) - assert expected.replace('\n', '').replace(' ', '').replace( - '\t', '') == result.replace('\n', '').replace(' ', '').replace('\t', '') + actual = result.replace('\n', '').replace(' ', '').replace('\t', '') + exp = expected.replace('\n', '').replace(' ', '').replace('\t', '') + if actual != exp: + print('---EXPECTED---') + print(expected) + print('---ACTUAL---') + print(result) + assert exp == actual def test_scancode_input_min_score_100(self): test_file = get_test_loc( @@ -207,8 +214,14 @@ def test_scancode_input_min_score_100(self): # expected doesn't work well, it works after removed all the newline and spaces # assert expected == result # assert expected.splitlines(False) == result.splitlines(False) - assert expected.replace('\n', '').replace(' ', '').replace( - '\t', '') == result.replace('\n', '').replace(' ', '').replace('\t', '') + actual = result.replace('\n', '').replace(' ', '').replace('\t', '') + exp = expected.replace('\n', '').replace(' ', '').replace('\t', '') + if actual != exp: + print('---EXPECTED---') + print(expected) + print('---ACTUAL---') + print(result) + assert exp == actual def test_scancode_input_dup_lic(self): test_file = get_test_loc('test_attrib/scancode_input/sc-dup-lic.json') @@ -238,8 +251,14 @@ def test_scancode_input_dup_lic(self): # expected doesn't work well, it works after removed all the newline and spaces # assert expected == result # assert expected.splitlines(False) == result.splitlines(False) - assert expected.replace('\n', '').replace(' ', '').replace( - '\t', '') == result.replace('\n', '').replace(' ', '').replace('\t', '') + actual = result.replace('\n', '').replace(' ', '').replace('\t', '') + exp = expected.replace('\n', '').replace(' ', '').replace('\t', '') + if actual != exp: + print('---EXPECTED---') + print(expected) + print('---ACTUAL---') + print(result) + assert exp == actual def test_scancode_input_dup_lic_match(self): test_file = get_test_loc( @@ -272,8 +291,14 @@ def test_scancode_input_dup_lic_match(self): # expected doesn't work well, it works after removed all the newline and spaces # assert expected == result # assert expected.splitlines(False) == result.splitlines(False) - assert expected.replace('\n', '').replace(' ', '').replace( - '\t', '') == result.replace('\n', '').replace(' ', '').replace('\t', '') + actual = result.replace('\n', '').replace(' ', '').replace('\t', '') + exp = expected.replace('\n', '').replace(' ', '').replace('\t', '') + if actual != exp: + print('---EXPECTED---') + print(expected) + print('---ACTUAL---') + print(result) + assert exp == actual def test_scancode_input_multi_lic(self): test_file = get_test_loc( @@ -304,8 +329,14 @@ def test_scancode_input_multi_lic(self): # expected doesn't work well, it works after removed all the newline and spaces # assert expected == result # assert expected.splitlines(False) == result.splitlines(False) - assert expected.replace('\n', '').replace(' ', '').replace( - '\t', '') == result.replace('\n', '').replace(' ', '').replace('\t', '') + actual = result.replace('\n', '').replace(' ', '').replace('\t', '') + exp = expected.replace('\n', '').replace(' ', '').replace('\t', '') + if actual != exp: + print('---EXPECTED---') + print(expected) + print('---ACTUAL---') + print(result) + assert exp == actual def test_generate_with_csv(self): test_file = get_test_loc( diff --git a/tests/test_attrib/last_run_output.txt b/tests/test_attrib/last_run_output.txt new file mode 100644 index 00000000..44265a8b --- /dev/null +++ b/tests/test_attrib/last_run_output.txt @@ -0,0 +1,1491 @@ +============================= test session starts ============================== +platform linux -- Python 3.12.1, pytest-8.3.5, pluggy-1.5.0 +rootdir: /workspaces/aboutcode-toolkit +configfile: pyproject.toml +plugins: anyio-4.9.0 +collected 14 items + +tests/test_attrib.py .........---EXPECTED--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

adler32.c

+ + + + + +
+ +
+ + + + + + +
+

adler32.c

+ + + + + +
 Copyright (c) 1995-2011 Mark Adler 
+ + + + +

This component is licensed under zlib

+ + + + + +

Full text of zlib is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

zlib

+
 This software is provided 'as-is', without any express or implied warranty. In no
+event will the authors be held liable for any damages arising from the use of this
+software.
+
+Permission is granted to anyone to use this software for any purpose, including
+commercial applications, and to alter it and redistribute it freely, subject to
+the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that
+   you wrote the original software. If you use this software in a product, an
+   acknowledgment in the product documentation would be appreciated but is not
+   required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source distribution. 
+ + + +

End

+ + + +---ACTUAL--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

adler32.c

+ + + + + +
+ +
+ + + + + + +
+

adler32.c

+ + + + + +
 Copyright (c) 1995-2011 Mark Adler 
+ + + + +

This component is licensed under zlib

+ + + + + +

Full text of zlib is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

End

+ + + +F############################ +[Error(INFO, "Field ['type', 'base_name', 'extension', 'size', 'date', 'sha1', 'md5', 'sha256', 'mime_type', 'file_type', 'programming_language', 'is_binary', 'is_text', 'is_archive', 'is_media', 'is_source', 'is_script', 'package_data', 'for_packages', 'detected_license_expression', 'detected_license_expression_spdx', 'license_clues', 'percentage_of_license_text', 'copyrights', 'holders', 'authors', 'emails', 'urls', 'files_count', 'dirs_count', 'size_count', 'scan_errors', 'license_key_expression', 'license_score'] is a custom field.")] +---EXPECTED--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

readme.txt

+ + + + + +
+ +
+ + + + + + +
+

readme.txt

+ + + + + +
 Copyright (c) Henrik Ravn 2004 
+ + + + +

This component is licensed under unknown-license-reference

+ +

This component is licensed under boost-1.0

+ + + + + + + + + + + + + +

Full text of boost-1.0 is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

boost-1.0

+
 Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE. 
+ + + +

End

+ + + +---ACTUAL--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

readme.txt

+ + + + + +
+ +
+ + + + + + +
+

readme.txt

+ + + + + +
 Copyright (c) Henrik Ravn 2004 
+ + + + +

This component is licensed under unknown-license-reference

+ +

This component is licensed under boost-1.0

+ + + + + + + + + + + +

Full text of boost-1.0 is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

End

+ + + +F---EXPECTED--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

lic.txt

+ + + + + +
+ +
+ + + + + + +
+

lic.txt

+ + + + + + +

This component is licensed under mit

+ +

This component is licensed under bsd-axis-nomod OR gpl-1.0-plus

+ + + + + +

Full text of mit is available at the end of this document.

+ + + + + + + +

bsd-axis-nomod

+
 Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer,
+   without modification.
+
+2. Neither the name of the copyright holders nor the names of its
+   contributors may be used to endorse or promote products derived
+   from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND ITS CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. 
+ + + + + + + + + +

Full text of gpl-1.0-plus is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + + + +

gpl-1.0-plus

+
 This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 1, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.
+
+
+                    GNU GENERAL PUBLIC LICENSE
+                     Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+                    51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The license agreements of most software companies try to keep users
+at the mercy of those companies.  By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must tell them their rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License.  The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications.  Each
+licensee is addressed as "you".
+
+  1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program.  You may charge a fee for the physical act of
+transferring a copy.
+
+  2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+    a) cause the modified files to carry prominent notices stating that
+    you changed the files and the date of any change; and
+
+    b) cause the whole of any work that you distribute or publish, that
+    in whole or in part contains the Program or any part thereof, either
+    with or without modifications, to be licensed at no charge to all
+    third parties under the terms of this General Public License (except
+    that you may choose to grant warranty protection to some or all
+    third parties, at your option).
+
+    c) If the modified program normally reads commands interactively when
+    run, you must cause it, when started running for such interactive use
+    in the simplest and most usual way, to print or display an
+    announcement including an appropriate copyright notice and a notice
+    that there is no warranty (or else, saying that you provide a
+    warranty) and that users may redistribute the program under these
+    conditions, and telling the user how to view a copy of this General
+    Public License.
+
+    d) You may charge a fee for the physical act of transferring a
+    copy, and you may at your option offer warranty protection in
+    exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+
+  3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal charge
+    for the cost of distribution) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it.  For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+  4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License.  However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+  5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions.  You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+
+  7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+  8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+
+        Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+  To do so, attach the following notices to the program.  It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19xx name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License.  Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  program `Gnomovision' (a program to direct compilers to make passes
+  at assemblers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+That's all there is to it! 
+ + + +

mit

+
 Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ + + +

End

+ + + +---ACTUAL--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

lic.txt

+ + + + + +
+ +
+ + + + + + +
+

lic.txt

+ + + + + + +

This component is licensed under mit

+ +

This component is licensed under bsd-axis-nomod OR gpl-1.0-plus

+ + + + + +

Full text of mit is available at the end of this document.

+ + + + + + + + + +

Full text of gpl-1.0-plus is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

End

+ + + +F---EXPECTED--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

lic.txt

+ + + + + +
+ +
+ + + + + + +
+

lic.txt

+ + + + + + +

This component is licensed under mit

+ + + + + +

Full text of mit is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

mit

+
 Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ + + +

End

+ + + +---ACTUAL--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

lic.txt

+ + + + + +
+ +
+ + + + + + +
+

lic.txt

+ + + + + + +

This component is licensed under mit

+ + + + + +

Full text of mit is available at the end of this document.

+ + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

End

+ + + +F---EXPECTED--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

S3_PING.java

+ + + + + +
+ +
+ + + + + + +
+

S3_PING.java

+ + + + + + +

This component is licensed under public-domain

+ +

This component is licensed under public-domain-disclaimer

+ + + + + + + +

public-domain

+
  
+ + + + + + + + + + + + + +

public-domain-disclaimer

+
 This code is hereby placed in the public domain.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ + + + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + + + + + +

End

+ + + +---ACTUAL--- + + + + + Open Source Software Information + + + +

OPEN SOURCE SOFTWARE INFORMATION

+

+
+

Licenses, acknowledgments and required copyright notices for + open source components:

+
+ +
+ + + + + +

S3_PING.java

+ + + + + +
+ +
+ + + + + + +
+

S3_PING.java

+ + + + + + +

This component is licensed under public-domain

+ +

This component is licensed under public-domain-disclaimer

+ + + + + + + + + + + + + + + + +
+ + +
+ +

Common Licenses Used in This Product

+ + +

End

+ + + +F + +=================================== FAILURES =================================== +___________________ GenerateTest.test_scancode_input_dup_lic ___________________ + +self = + + def test_scancode_input_dup_lic(self): + test_file = get_test_loc('test_attrib/scancode_input/sc-dup-lic.json') + errors, abouts = gen.load_inventory(test_file, scancode=True) + # Check if there is error's level > INFO + result = [(level, e) for level, e in errors if level > INFO] + assert result == [] + + is_about_input = False + scancode = True + + lic_dict, _lic_errors = model.pre_process_and_fetch_license_dict( + abouts) + errors, result = attrib.generate_from_file( + abouts, is_about_input, lic_dict, scancode, min_license_score=0) + assert not errors + + expected_file = get_test_loc( + 'test_attrib/scancode_input/sc-dup-lic.html') + with open(expected_file) as exp: + expected = exp.read() + + # strip the timestamp: the timestamp is wrapped in italic block + result = remove_timestamp(result) + expected = remove_timestamp(expected) + # For whatever reasons, the directly comparison between the result and the + # expected doesn't work well, it works after removed all the newline and spaces + # assert expected == result + # assert expected.splitlines(False) == result.splitlines(False) + actual = result.replace('\n', '').replace(' ', '').replace('\t', '') + exp = expected.replace('\n', '').replace(' ', '').replace('\t', '') + if actual != exp: + print('---EXPECTED---') + print(expected) + print('---ACTUAL---') + print(result) +> assert exp == actual +E assert '' == '' +E +E Skipping 768 identical leading characters in diff, use -v to show +E - ct

End

+E + ctzlib
Thissoftwareisprovided'as-is',withoutanyexpressorimpliedwarranty.Innoeventwilltheauthorsbeheldliableforanydamagesarisingfromtheuseofthissoftware.Permissionisgrantedtoanyonetousethissoftwareforanypurpose,includingcommercialapplications,andtoalteritandredistributeitfreely,subjecttothefollowingrestrictions:1.Theoriginofthissoftwaremustnotbemisrepresented;youmustnotclaimthatyouwrotetheoriginalsoftwar...
+E         
+E         ...Full output truncated (1 line hidden), use '-vv' to show
+
+tests/test_attrib.py:261: AssertionError
+________________ GenerateTest.test_scancode_input_dup_lic_match ________________
+
+self = 
+
+    def test_scancode_input_dup_lic_match(self):
+        test_file = get_test_loc(
+            'test_attrib/scancode_input/sc-dup-lic-match.json')
+        errors, abouts = gen.load_inventory(test_file, scancode=True)
+        print("############################")
+        print(errors)
+        # Check if there is error's level > INFO
+        result = [(level, e) for level, e in errors if level > INFO]
+        assert result == []
+    
+        is_about_input = False
+        scancode = True
+    
+        lic_dict, _lic_errors = model.pre_process_and_fetch_license_dict(
+            abouts)
+        errors, result = attrib.generate_from_file(
+            abouts, is_about_input, lic_dict, scancode, min_license_score=0)
+        assert not errors
+    
+        expected_file = get_test_loc(
+            'test_attrib/scancode_input/sc-dup-lic-match.html')
+        with open(expected_file) as exp:
+            expected = exp.read()
+    
+        # strip the timestamp: the timestamp is wrapped in italic block
+        result = remove_timestamp(result)
+        expected = remove_timestamp(expected)
+        # For whatever reasons, the directly comparison between the result and the
+        # expected doesn't work well, it works after removed all the newline and spaces
+        # assert expected == result
+        # assert expected.splitlines(False) == result.splitlines(False)
+        actual = result.replace('\n', '').replace(' ', '').replace('\t', '')
+        exp = expected.replace('\n', '').replace(' ', '').replace('\t', '')
+        if actual != exp:
+            print('---EXPECTED---')
+            print(expected)
+            print('---ACTUAL---')
+            print(result)
+>       assert exp == actual
+E       assert '' == ''
+E         
+E         Skipping 846 identical leading characters in diff, use -v to show
+E         - ct

End

+E + ctboost-1.0
BoostSoftwareLicense-Version1.0-August17th,2003Permissionisherebygranted,freeofcharge,toanypersonororganizationobtainingacopyofthesoftwareandaccompanyingdocumentationcoveredbythislicense(the"Software")touse,reproduce,display,distribute,execute,andtransmittheSoftware,andtopreparederivativeworksoftheSoftware,andtopermitthird-partiestowhomtheSoftwareisfurnishedtodoso,allsubjecttothefollowi...
+E         
+E         ...Full output truncated (1 line hidden), use '-vv' to show
+
+tests/test_attrib.py:301: AssertionError
+_________________ GenerateTest.test_scancode_input_min_score_0 _________________
+
+self = 
+
+    def test_scancode_input_min_score_0(self):
+        test_file = get_test_loc(
+            'test_attrib/scancode_input/sc-2-licenses.json')
+        errors, abouts = gen.load_inventory(test_file, scancode=True)
+        # Check if there is error's level > INFO
+        result = [(level, e) for level, e in errors if level > INFO]
+        assert result == []
+    
+        is_about_input = False
+        scancode = True
+    
+        lic_dict, _lic_errors = model.pre_process_and_fetch_license_dict(
+            abouts)
+        errors, result = attrib.generate_from_file(
+            abouts, is_about_input, lic_dict, scancode, min_license_score=0)
+        assert not errors
+    
+        expected_file = get_test_loc(
+            'test_attrib/scancode_input/sc-min_score-0.html')
+        with open(expected_file) as exp:
+            expected = exp.read()
+    
+        # strip the timestamp: the timestamp is wrapped in italic block
+        result = remove_timestamp(result)
+        expected = remove_timestamp(expected)
+        # For whatever reasons, the directly comparison between the result and the
+        # expected doesn't work well, it works after removed all the newline and spaces
+        # assert expected == result
+        # assert expected.splitlines(False) == result.splitlines(False)
+        actual = result.replace('\n', '').replace(' ', '').replace('\t', '')
+        exp = expected.replace('\n', '').replace(' ', '').replace('\t', '')
+        if actual != exp:
+            print('---EXPECTED---')
+            print(expected)
+            print('---ACTUAL---')
+            print(result)
+>       assert exp == actual
+E       assert '' == ''
+E         
+E         Skipping 729 identical leading characters in diff, use -v to show
+E         - ment.

Fulltextofgpl-1.0-plusisavailableattheendofthisdocument.


CommonLicensesUsedinThisProduct

End

+E + ment.

bsd-axis-nomod
Redistributionanduseinsourceandbinaryforms,withorwithoutmodification,arepermittedprovidedthatthefollowingconditionsaremet:1.Redistributionsofsourcecodemustretaintheabovecopyrightnotice,thislistofcondition...
+E         
+E         ...Full output truncated (1 line hidden), use '-vv' to show
+
+tests/test_attrib.py:186: AssertionError
+________________ GenerateTest.test_scancode_input_min_score_100 ________________
+
+self = 
+
+    def test_scancode_input_min_score_100(self):
+        test_file = get_test_loc(
+            'test_attrib/scancode_input/sc-2-licenses.json')
+        errors, abouts = gen.load_inventory(test_file, scancode=True)
+        # Check if there is error's level > INFO
+        result = [(level, e) for level, e in errors if level > INFO]
+        assert result == []
+    
+        is_about_input = False
+        scancode = True
+    
+        lic_dict, _lic_errors = model.pre_process_and_fetch_license_dict(
+            abouts)
+        errors, result = attrib.generate_from_file(
+            abouts, is_about_input, lic_dict, scancode, min_license_score=100)
+        assert not errors
+    
+        expected_file = get_test_loc(
+            'test_attrib/scancode_input/sc.html')
+        with open(expected_file) as exp:
+            expected = exp.read()
+    
+        # strip the timestamp: the timestamp is wrapped in italic block
+        result = remove_timestamp(result)
+        expected = remove_timestamp(expected)
+        # For whatever reasons, the directly comparison between the result and the
+        # expected doesn't work well, it works after removed all the newline and spaces
+        # assert expected == result
+        # assert expected.splitlines(False) == result.splitlines(False)
+        actual = result.replace('\n', '').replace(' ', '').replace('\t', '')
+        exp = expected.replace('\n', '').replace(' ', '').replace('\t', '')
+        if actual != exp:
+            print('---EXPECTED---')
+            print(expected)
+            print('---ACTUAL---')
+            print(result)
+>       assert exp == actual
+E       assert '' == ''
+E         
+E         Skipping 719 identical leading characters in diff, use -v to show
+E         - ct

End

+E + ctmit
Permissionisherebygranted,freeofcharge,toanypersonobtainingacopyofthissoftwareandassociateddocumentationfiles(the"Software"),todealintheSoftwarewithoutrestriction,includingwithoutlimitationtherightstouse,copy,modify,merge,publish,distribute,sublicense,and/orsellcopiesoftheSoftware,andtopermitpersonstowhomtheSoftwareisfurnishedtodoso,subjecttothefollowingconditions:Theabovecopyrightnoticeandthisperm...
+E         
+E         ...Full output truncated (1 line hidden), use '-vv' to show
+
+tests/test_attrib.py:224: AssertionError
+__________________ GenerateTest.test_scancode_input_multi_lic __________________
+
+self = 
+
+    def test_scancode_input_multi_lic(self):
+        test_file = get_test_loc(
+            'test_attrib/scancode_input/sc-multi-lic.json')
+        errors, abouts = gen.load_inventory(test_file, scancode=True)
+        # Check if there is error's level > INFO
+        result = [(level, e) for level, e in errors if level > INFO]
+        assert result == []
+    
+        is_about_input = False
+        scancode = True
+    
+        lic_dict, _lic_errors = model.pre_process_and_fetch_license_dict(
+            abouts)
+        errors, result = attrib.generate_from_file(
+            abouts, is_about_input, lic_dict, scancode, min_license_score=0)
+        assert not errors
+    
+        expected_file = get_test_loc(
+            'test_attrib/scancode_input/sc-multi-lic.html')
+        with open(expected_file) as exp:
+            expected = exp.read()
+    
+        # strip the timestamp: the timestamp is wrapped in italic block
+        result = remove_timestamp(result)
+        expected = remove_timestamp(expected)
+        # For whatever reasons, the directly comparison between the result and the
+        # expected doesn't work well, it works after removed all the newline and spaces
+        # assert expected == result
+        # assert expected.splitlines(False) == result.splitlines(False)
+        actual = result.replace('\n', '').replace(' ', '').replace('\t', '')
+        exp = expected.replace('\n', '').replace(' ', '').replace('\t', '')
+        if actual != exp:
+            print('---EXPECTED---')
+            print(expected)
+            print('---ACTUAL---')
+            print(result)
+>       assert exp == actual
+E       assert '' == ''
+E         
+E         Skipping 644 identical leading characters in diff, use -v to show
+E         - aimer


CommonLicensesUsedinThisProduct

End

+E + aimer

public-domain
public-domain-disclaimer
Thiscodeisherebyplacedinthepublicdomain.THISSOFTWAREISPROVIDEDBYTHEAUTHORS''ASIS''ANDANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THEIMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAREDISCLAIMED.INNO...
+E         
+E         ...Full output truncated (1 line hidden), use '-vv' to show
+
+tests/test_attrib.py:339: AssertionError
+=========================== short test summary info ============================
+FAILED tests/test_attrib.py::GenerateTest::test_scancode_input_dup_lic - asse...
+FAILED tests/test_attrib.py::GenerateTest::test_scancode_input_dup_lic_match
+FAILED tests/test_attrib.py::GenerateTest::test_scancode_input_min_score_0 - ...
+FAILED tests/test_attrib.py::GenerateTest::test_scancode_input_min_score_100
+FAILED tests/test_attrib.py::GenerateTest::test_scancode_input_multi_lic - as...
+========================= 5 failed, 9 passed in 3.10s ==========================