1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2024 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import unittest 17from unittest.mock import patch, MagicMock 18import os 19import json 20from src.validate_readme_opensource import OpenSourceValidator, REQUIRED_FIELDS 21 22 23class TestOpenSourceValidator(unittest.TestCase): 24 25 @patch("os.walk") 26 def test_find_all_readmes(self, mock_os_walk): 27 # 模拟 os.walk 返回值 28 mock_os_walk.return_value = [ 29 ("/project", ["subdir1", "subdir2"], ["README.OpenSource"]), 30 ("/project/subdir1", [], ["README.OpenSource"]), 31 ("/project/subdir2", [], ["README.OpenSource"]), 32 ] 33 34 validator = OpenSourceValidator(project_root="/project") 35 readme_paths = validator.find_all_readmes() 36 37 # 断言所有的 README.OpenSource 文件都被正确地找到 38 self.assertEqual(readme_paths, [ 39 "/project/README.OpenSource", 40 "/project/subdir1/README.OpenSource", 41 "/project/subdir2/README.OpenSource" 42 ]) 43 44 @patch("builtins.open", new_callable=MagicMock) 45 def test_validate_format_valid(self, mock_open): 46 # 模拟文件内容是一个包含正确格式的 JSON 数据 47 mock_open.return_value.__enter__.return_value.read.return_value = json.dumps([ 48 { 49 "Name": "Software A", 50 "License": "MIT", 51 "License File": "LICENSE", 52 "Version Number": "1.0.0", 53 "Owner": "Owner A", 54 "Upstream URL": "https://example.com", 55 "Description": "A software project", 56 "Dependencies": [] 57 } 58 ]) 59 60 validator = OpenSourceValidator(project_root="/project") 61 valid = validator.validate_format("/project/README.OpenSource") 62 63 # 断言格式验证通过 64 self.assertTrue(valid) 65 66 @patch("builtins.open", new_callable=MagicMock) 67 def test_validate_format_invalid_missing_field(self, mock_open): 68 # 模拟文件内容是一个包含缺失字段的 JSON 数据 69 mock_open.return_value.__enter__.return_value.read.return_value = json.dumps([ 70 { 71 "Name": "Software A", 72 "License": "MIT", 73 "License File": "LICENSE", 74 "Version Number": "1.0.0", 75 "Owner": "Owner A", 76 "Upstream URL": "https://example.com", 77 # "Description" 字段缺失 78 "Dependencies": [] 79 } 80 ]) 81 82 validator = OpenSourceValidator(project_root="/project") 83 valid = validator.validate_format("/project/README.OpenSource") 84 85 # 断言格式验证失败 86 self.assertFalse(valid) 87 88 @patch("builtins.open", new_callable=MagicMock) 89 def test_validate_content_valid(self, mock_open): 90 # 模拟读取到的 README 文件数据 91 mock_open.return_value.__enter__.return_value.read.return_value = json.dumps([ 92 { 93 "Name": "Software A", 94 "License": "MIT", 95 "License File": "LICENSE", 96 "Version Number": "1.0.0", 97 "Owner": "Owner A", 98 "Upstream URL": "https://example.com", 99 "Description": "A software project", 100 "Dependencies": [] 101 } 102 ]) 103 104 # 模拟参考数据 105 reference_data = [ 106 { 107 "Name": "Software A", 108 "License": "MIT", 109 "License File": "LICENSE", 110 "Version Number": "1.0.0", 111 "Owner": "Owner A", 112 "Upstream URL": "https://example.com", 113 "Description": "A software project" 114 } 115 ] 116 117 validator = OpenSourceValidator(project_root="/project") 118 validator.reference_data = reference_data # 设置参考数据 119 120 valid = validator.validate_content("/project/README.OpenSource") 121 122 # 断言内容验证通过 123 self.assertTrue(valid) 124 125 @patch("builtins.open", new_callable=MagicMock) 126 @patch("os.path.exists", return_value=True) # 模拟许可证文件存在 127 def test_validate_content_valid(self, mock_exists, mock_open): 128 # 模拟读取到的 README 文件数据 129 mock_open.return_value.__enter__.return_value.read.return_value = json.dumps([ 130 { 131 "Name": "Software A", 132 "License": "MIT", 133 "License File": "LICENSE", # 许可证文件 134 "Version Number": "1.0.0", 135 "Owner": "Owner A", 136 "Upstream URL": "https://example.com", 137 "Description": "A software project", 138 "Dependencies": [] 139 } 140 ]) 141 142 # 模拟参考数据 143 reference_data = [ 144 { 145 "Name": "Software A", 146 "License": "MIT", 147 "License File": "LICENSE", 148 "Version Number": "1.0.0", 149 "Owner": "Owner A", 150 "Upstream URL": "https://example.com", 151 "Description": "A software project" 152 } 153 ] 154 155 validator = OpenSourceValidator(project_root="/project") 156 validator.reference_data = reference_data # 设置参考数据 157 158 valid = validator.validate_content("/project/README.OpenSource") 159 160 # 断言内容验证通过 161 self.assertTrue(valid) 162 163 @patch("os.path.exists") 164 def test_validate_license_file_valid(self, mock_exists): 165 # 模拟文件存在 166 mock_exists.return_value = True 167 168 validator = OpenSourceValidator(project_root="/project") 169 valid = validator.validate_license_file("/project/README.OpenSource", "LICENSE") 170 171 # 断言许可证文件存在并且校验通过 172 self.assertTrue(valid) 173 174 @patch("os.path.exists") 175 def test_validate_license_file_invalid(self, mock_exists): 176 # 模拟文件不存在 177 mock_exists.return_value = False 178 179 validator = OpenSourceValidator(project_root="/project") 180 valid = validator.validate_license_file("/project/README.OpenSource", "LICENSE") 181 182 # 断言许可证文件不存在并且校验失败 183 self.assertFalse(valid) 184 185 @patch("builtins.open", new_callable=MagicMock) 186 @patch("os.path.exists") 187 def test_validate_dependencies_valid(self, mock_exists, mock_open): 188 # 模拟文件内容是有效的 JSON 数据 189 mock_open.return_value.__enter__.return_value.read.return_value = json.dumps([ 190 { 191 "Name": "Software A", 192 "License": "MIT", 193 "License File": "LICENSE", 194 "Version Number": "1.0.0", 195 "Owner": "Owner A", 196 "Upstream URL": "https://example.com", 197 "Description": "A software project", 198 "Dependencies": ["dep1", "dep2"] 199 } 200 ]) 201 # 模拟依赖文件存在 202 mock_exists.return_value = True 203 204 validator = OpenSourceValidator(project_root="/project") 205 valid = validator.validate_dependencies(["dep1", "dep2"], "/project/README.OpenSource") 206 207 # 断言依赖项验证通过 208 self.assertTrue(valid) 209 210 @patch("builtins.open", new_callable=MagicMock) 211 def test_validate_dependencies_invalid(self, mock_open): 212 # 模拟文件内容是包含非法依赖项格式的 JSON 数据 213 mock_open.return_value.__enter__.return_value.read.return_value = json.dumps([ 214 { 215 "Name": "Software A", 216 "License": "MIT", 217 "License File": "LICENSE", 218 "Version Number": "1.0.0", 219 "Owner": "Owner A", 220 "Upstream URL": "https://example.com", 221 "Description": "A software project", 222 "Dependencies": ["dep1", 123] # 非字符串依赖项 223 } 224 ]) 225 226 validator = OpenSourceValidator(project_root="/project") 227 valid = validator.validate_dependencies(["dep1", 123], "/project/README.OpenSource") 228 229 # 断言依赖项验证失败 230 self.assertFalse(valid) 231 232 233if __name__ == "__main__": 234 unittest.main() 235 236