1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package parser2v3 4 5import ( 6 "reflect" 7 "sort" 8 "testing" 9 10 gordfParser "github.com/spdx/gordf/rdfloader/parser" 11) 12 13func Test_rdfParser2_3_getAnyLicenseFromNode(t *testing.T) { 14 // since this function is a mux, we just have to make sure that with each 15 // type of input, it is able to redirect the request to an appropriate 16 // license getter. 17 18 // TestCase 1: input node is just a node string without any associated 19 // triple (either a NONE|NOASSERTION) because for other case, 20 // the license should've been associated with other triples 21 parser, _ := parserFromBodyContent(``) 22 inputNode := &gordfParser.Node{ 23 NodeType: gordfParser.IRI, 24 ID: NS_SPDX + "NONE", 25 } 26 lic, err := parser.getAnyLicenseFromNode(inputNode) 27 if err != nil { 28 t.Errorf("error parsing a valid license input: %v", err) 29 } 30 // checking if the return type is a SpecialLicense 31 switch lic.(type) { 32 case SpecialLicense: 33 default: 34 t.Errorf("expected license to be of type SpecialLicense, found %v", reflect.TypeOf(lic)) 35 } 36 37 // TestCase 2: DisjunctiveLicenseSet: 38 parser, _ = parserFromBodyContent(` 39 <spdx:DisjunctiveLicenseSet> 40 <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/> 41 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 42 </spdx:DisjunctiveLicenseSet> 43 `) 44 inputNode = parser.gordfParserObj.Triples[0].Subject 45 lic, err = parser.getAnyLicenseFromNode(inputNode) 46 if err != nil { 47 t.Errorf("error parsing a valid license input: %v", err) 48 } 49 // checking if the return type is a DisjunctiveLicenseSet 50 switch lic.(type) { 51 case DisjunctiveLicenseSet: 52 default: 53 t.Errorf("expected license to be of type DisjunctiveLicenseSet, found %v", reflect.TypeOf(lic)) 54 } 55 56 // TestCase 3: ConjunctiveLicenseSet: 57 parser, _ = parserFromBodyContent(` 58 <spdx:ConjunctiveLicenseSet> 59 <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/> 60 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 61 </spdx:ConjunctiveLicenseSet> 62 `) 63 inputNode = parser.gordfParserObj.Triples[0].Subject 64 lic, err = parser.getAnyLicenseFromNode(inputNode) 65 if err != nil { 66 t.Errorf("error parsing a valid license input: %v", err) 67 } 68 // checking if the return type is a ConjunctiveLicenseSet 69 switch lic.(type) { 70 case ConjunctiveLicenseSet: 71 default: 72 t.Errorf("expected license to be of type ConjunctiveLicenseSet, found %v", reflect.TypeOf(lic)) 73 } 74 75 // TestCase 4: ExtractedLicensingInfo 76 parser, _ = parserFromBodyContent(` 77 <spdx:ExtractedLicensingInfo rdf:about="http://spdx.dev/spdx.rdf#LicenseRef-Freeware"> 78 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 79 <spdx:name>freeware</spdx:name> 80 <spdx:extractedText><![CDATA[...]]></spdx:extractedText> 81 </spdx:ExtractedLicensingInfo> 82 `) 83 inputNode = parser.gordfParserObj.Triples[0].Subject 84 lic, err = parser.getAnyLicenseFromNode(inputNode) 85 if err != nil { 86 t.Errorf("error parsing a valid license input: %v", err) 87 } 88 // checking if the return type is a ExtractedLicensingInfo 89 switch lic.(type) { 90 case ExtractedLicensingInfo: 91 default: 92 t.Errorf("expected license to be of type ExtractedLicensingInfo, found %v", reflect.TypeOf(lic)) 93 } 94 95 // TestCase 4: ExtractedLicensingInfo 96 parser, _ = parserFromBodyContent(` 97 <spdx:ExtractedLicensingInfo rdf:about="http://spdx.dev/spdx.rdf#LicenseRef-Freeware"> 98 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 99 <spdx:name>freeware</spdx:name> 100 <spdx:extractedText><![CDATA[...]]></spdx:extractedText> 101 </spdx:ExtractedLicensingInfo> 102 `) 103 inputNode = parser.gordfParserObj.Triples[0].Subject 104 lic, err = parser.getAnyLicenseFromNode(inputNode) 105 if err != nil { 106 t.Errorf("error parsing a valid license input: %v", err) 107 } 108 // checking if the return type is a ExtractedLicensingInfo 109 switch lic.(type) { 110 case ExtractedLicensingInfo: 111 default: 112 t.Errorf("expected license to be of type ExtractedLicensingInfo, found %v", reflect.TypeOf(lic)) 113 } 114 115 // TestCase 5: License 116 parser, _ = parserFromBodyContent(` 117 <spdx:License rdf:about="http://spdx.org/licenses/Apache-2.0"> 118 <spdx:standardLicenseTemplate><> Apache License Version 2.0, January 2004 http://www.apache.org/licenses/<><> TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION<> <> Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. <> Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. <> Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. <> Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: <> You must give any other recipients of the Work or Derivative Works a copy of this License; and <> You must cause any modified files to carry prominent notices stating that You changed the files; and <> You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and <> If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. <> Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. <> Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. <> Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. <> Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. <> Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.<> END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright <> 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 http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.<></spdx:standardLicenseTemplate> 119 <rdfs:seeAlso>http://www.apache.org/licenses/LICENSE-2.0</rdfs:seeAlso> 120 <spdx:name>Apache License 2.0</spdx:name> 121 <spdx:licenseId>Apache-2.0</spdx:licenseId> 122 <spdx:isOsiApproved>true</spdx:isOsiApproved> 123 <rdfs:seeAlso>http://www.opensource.org/licenses/Apache-2.0</rdfs:seeAlso> 124 <spdx:licenseText>...</spdx:licenseText> 125 <spdx:standardLicenseHeader>...</spdx:standardLicenseHeader> 126 </spdx:License> 127 `) 128 inputNode = parser.gordfParserObj.Triples[0].Subject 129 lic, err = parser.getAnyLicenseFromNode(inputNode) 130 if err != nil { 131 t.Errorf("error parsing a valid license input: %v", err) 132 } 133 // checking if the return type is a License 134 switch lic.(type) { 135 case License: 136 default: 137 t.Errorf("expected license to be of type License, found %v", reflect.TypeOf(lic)) 138 } 139 140 // TestCase 5: WithExceptionOperator 141 parser, _ = parserFromBodyContent(` 142 <spdx:WithExceptionOperator> 143 <spdx:licenseException> 144 <spdx:LicenseException rdf:nodeID="A1"> 145 <spdx:example></spdx:example> 146 <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId> 147 <rdfs:comment></rdfs:comment> 148 </spdx:LicenseException> 149 </spdx:licenseException> 150 <spdx:member rdf:resource="http://spdx.org/licenses/GPL-2.0-or-later"/> 151 </spdx:WithExceptionOperator> 152 `) 153 inputNode = parser.gordfParserObj.Triples[0].Subject 154 lic, err = parser.getAnyLicenseFromNode(inputNode) 155 if err != nil { 156 t.Errorf("error parsing a valid license input: %v", err) 157 } 158 // checking if the return type is a WithExceptionOperator 159 switch lic.(type) { 160 case WithExceptionOperator: 161 default: 162 t.Errorf("expected license to be of type WithExceptionOperator, found %v", reflect.TypeOf(lic)) 163 } 164 165 // TestCase 6: OrLaterOperator 166 parser, _ = parserFromBodyContent(` 167 <spdx:OrLaterOperator> 168 <spdx:member> 169 <spdx:SimpleLicensingInfo> 170 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 171 <spdx:name>freeware</spdx:name> 172 </spdx:SimpleLicensingInfo> 173 </spdx:member> 174 </spdx:OrLaterOperator> 175 `) 176 inputNode = parser.gordfParserObj.Triples[0].Subject 177 lic, err = parser.getAnyLicenseFromNode(inputNode) 178 if err != nil { 179 t.Errorf("error parsing a valid license input: %v", err) 180 } 181 // checking if the return type is a OrLaterOperator 182 switch lic.(type) { 183 case OrLaterOperator: 184 default: 185 t.Errorf("expected license to be of type OrLaterOperator, found %v", reflect.TypeOf(lic)) 186 } 187 188 // TestCase 7: checking if an unknown license raises an error. 189 parser, _ = parserFromBodyContent(` 190 <spdx:UnknownLicense> 191 <spdx:unknownTag /> 192 </spdx:UnknownLicense> 193 `) 194 node := parser.gordfParserObj.Triples[0].Subject 195 _, err = parser.getAnyLicenseFromNode(node) 196 t.Log(err) 197 if err == nil { 198 t.Errorf("should've raised an error for invalid input") 199 } 200 201 // TestCase 8: cyclic dependent license must raise an error. 202 parser, _ = parserFromBodyContent(` 203 <spdx:ConjunctiveLicenseSet rdf:about="#SPDXRef-RecursiveLicense"> 204 <spdx:member rdf:resource="http://spdx.org/licenses/GPL-2.0-or-later"/> 205 <spdx:member> 206 <spdx:ConjunctiveLicenseSet rdf:about="#SPDXRef-RecursiveLicense"> 207 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 208 <spdx:member rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-RecursiveLicense"/> 209 </spdx:ConjunctiveLicenseSet> 210 </spdx:member> 211 </spdx:ConjunctiveLicenseSet> 212 `) 213 node = parser.gordfParserObj.Triples[0].Subject 214 _, err = parser.getAnyLicenseFromNode(node) 215 if err == nil { 216 t.Errorf("expected an error due to cyclic dependent license. found %v", err) 217 } 218} 219 220func Test_rdfParser2_3_getConjunctiveLicenseSetFromNode(t *testing.T) { 221 var parser *rdfParser2_3 222 var err error 223 var licenseNode *gordfParser.Node 224 var license ConjunctiveLicenseSet 225 226 // TestCase 1: invalid license member 227 parser, _ = parserFromBodyContent(` 228 <spdx:ConjunctiveLicenseSet> 229 <spdx:member rdf:resource="http://spdx.org/licenses/Unknown"/> 230 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 231 </spdx:ConjunctiveLicenseSet> 232 `) 233 licenseNode = parser.gordfParserObj.Triples[0].Subject 234 _, err = parser.getConjunctiveLicenseSetFromNode(licenseNode) 235 if err == nil { 236 t.Errorf("expected an error saying invalid license member, found <nil>") 237 } 238 239 // TestCase 2: invalid predicate in the licenseSet. 240 parser, _ = parserFromBodyContent(` 241 <spdx:ConjunctiveLicenseSet> 242 <spdx:member rdf:resource="http://spdx.org/licenses/CC0-1.0"/> 243 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 244 <spdx:unknownTag /> 245 </spdx:ConjunctiveLicenseSet> 246 `) 247 licenseNode = parser.gordfParserObj.Triples[0].Subject 248 _, err = parser.getConjunctiveLicenseSetFromNode(licenseNode) 249 if err == nil { 250 t.Errorf("expected an error saying invalid predicate found") 251 } 252 253 // TestCase 3: valid example. 254 parser, _ = parserFromBodyContent(` 255 <spdx:ConjunctiveLicenseSet> 256 <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/> 257 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 258 </spdx:ConjunctiveLicenseSet> 259 `) 260 licenseNode = parser.gordfParserObj.Triples[0].Subject 261 license, err = parser.getConjunctiveLicenseSetFromNode(licenseNode) 262 if err != nil { 263 t.Errorf("unexpected error parsing licenseSet: %v", err) 264 } 265 nMembers := len(license.members) 266 if nMembers != 2 { 267 t.Errorf("expected licenseSet to have 2 members, found %d", nMembers) 268 } 269 licenseMembers := mapLicensesToStrings(license.members) 270 expectedLicenseMembers := []string{"LGPL-2.0", "Nokia"} 271 sort.Strings(licenseMembers) 272 if !reflect.DeepEqual(licenseMembers, expectedLicenseMembers) { 273 t.Errorf("expected %v, found %v", expectedLicenseMembers, licenseMembers) 274 } 275} 276 277func Test_rdfParser2_3_getDisjunctiveLicenseSetFromNode(t *testing.T) { 278 var parser *rdfParser2_3 279 var err error 280 var licenseNode *gordfParser.Node 281 var license DisjunctiveLicenseSet 282 283 // TestCase 1: invalid license member 284 parser, _ = parserFromBodyContent(` 285 <spdx:DisjunctiveLicenseSet> 286 <spdx:member rdf:resource="http://spdx.org/licenses/Unknown"/> 287 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 288 </spdx:DisjunctiveLicenseSet> 289 `) 290 licenseNode = parser.gordfParserObj.Triples[0].Subject 291 _, err = parser.getDisjunctiveLicenseSetFromNode(licenseNode) 292 if err == nil { 293 t.Errorf("expected an error saying invalid license member, found <nil>") 294 } 295 296 // TestCase 2: invalid predicate in the licenseSet. 297 parser, _ = parserFromBodyContent(` 298 <spdx:DisjunctiveLicenseSet> 299 <spdx:member rdf:resource="http://spdx.org/licenses/Unknown"/> 300 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 301 <spdx:unknownTag /> 302 </spdx:DisjunctiveLicenseSet> 303 `) 304 licenseNode = parser.gordfParserObj.Triples[0].Subject 305 _, err = parser.getDisjunctiveLicenseSetFromNode(licenseNode) 306 if err == nil { 307 t.Errorf("expected an error saying invalid predicate found") 308 } 309 310 // TestCase 3: valid example. 311 parser, _ = parserFromBodyContent(` 312 <spdx:DisjunctiveLicenseSet> 313 <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/> 314 <spdx:member rdf:resource="http://spdx.org/licenses/LGPL-2.0"/> 315 </spdx:DisjunctiveLicenseSet> 316 `) 317 licenseNode = parser.gordfParserObj.Triples[0].Subject 318 license, err = parser.getDisjunctiveLicenseSetFromNode(licenseNode) 319 if err != nil { 320 t.Errorf("unexpected error parsing licenseSet: %v", err) 321 } 322 nMembers := len(license.members) 323 if nMembers != 2 { 324 t.Errorf("expected licenseSet to have 2 members, found %d", nMembers) 325 } 326 licenseMembers := mapLicensesToStrings(license.members) 327 expectedLicenseMembers := []string{"LGPL-2.0", "Nokia"} 328 sort.Strings(licenseMembers) 329 if !reflect.DeepEqual(licenseMembers, expectedLicenseMembers) { 330 t.Errorf("expected %v, found %v", expectedLicenseMembers, licenseMembers) 331 } 332} 333 334func Test_rdfParser2_3_getLicenseExceptionFromNode(t *testing.T) { 335 var licenseException LicenseException 336 var err error 337 var node *gordfParser.Node 338 var parser *rdfParser2_3 339 340 // TestCase 1: invalid value for rdf:seeAlso 341 parser, _ = parserFromBodyContent(` 342 <spdx:LicenseException> 343 <rdfs:seeAlso>see-also</rdfs:seeAlso> 344 <spdx:example></spdx:example> 345 <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId> 346 <rdfs:comment></rdfs:comment> 347 </spdx:LicenseException> 348 `) 349 node = parser.gordfParserObj.Triples[0].Subject 350 _, err = parser.getLicenseExceptionFromNode(node) 351 if err == nil { 352 t.Errorf("should've raised an error due to invalid uri for rdfs:seeAlso") 353 } 354 355 // TestCase 2: invalid predicate for licenseException 356 // TestCase 1: invalid value for rdf:seeAlso 357 parser, _ = parserFromBodyContent(` 358 <spdx:LicenseException> 359 <spdx:example></spdx:example> 360 <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId> 361 <rdfs:unknown></rdfs:unknown> 362 </spdx:LicenseException> 363 `) 364 node = parser.gordfParserObj.Triples[0].Subject 365 _, err = parser.getLicenseExceptionFromNode(node) 366 if err == nil { 367 t.Errorf("should've raised an error due to invalid predicate") 368 } 369 370 // TestCase 3: everything valid 371 // TestCase 1: invalid value for rdf:seeAlso 372 parser, _ = parserFromBodyContent(` 373 <spdx:LicenseException> 374 <rdfs:seeAlso rdf:resource="http://www.opensource.org/licenses/GPL-3.0"/> 375 <spdx:example>no example</spdx:example> 376 <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId> 377 <rdfs:comment>no comments</rdfs:comment> 378 <spdx:licenseExceptionText>text</spdx:licenseExceptionText> 379 <spdx:name>name</spdx:name> 380 </spdx:LicenseException> 381 `) 382 node = parser.gordfParserObj.Triples[0].Subject 383 licenseException, err = parser.getLicenseExceptionFromNode(node) 384 if err != nil { 385 t.Fatalf("unexpected error while parsing a valid licenseException") 386 } 387 expectedCrossReference := "http://www.opensource.org/licenses/GPL-3.0" 388 if licenseException.seeAlso != expectedCrossReference { 389 t.Errorf("expected: %s, found: %s", expectedCrossReference, licenseException.seeAlso) 390 } 391 expectedExample := "no example" 392 if licenseException.example != expectedExample { 393 t.Errorf("expected: %s, got: %s", expectedExample, licenseException.example) 394 } 395 if licenseException.licenseExceptionId != "Libtool-exception" { 396 t.Errorf("expected: %s, got: %s", "Libtool-exception", licenseException.licenseExceptionId) 397 } 398 if licenseException.comment != "no comments" { 399 t.Errorf("expected: %s, got: %s", "no comments", licenseException.comment) 400 } 401 if licenseException.licenseExceptionText != "text" { 402 t.Errorf("expected: '%s', got: '%s'", "text", licenseException.licenseExceptionText) 403 } 404 if licenseException.name != "name" { 405 t.Errorf("expected: '%s', got: '%s'", "name", licenseException.name) 406 } 407} 408 409func Test_rdfParser2_3_getLicenseFromNode(t *testing.T) { 410 var parser *rdfParser2_3 411 var node *gordfParser.Node 412 var license License 413 var err error 414 415 // TestCase 1: isOsiApproved is not a valid boolean 416 parser, _ = parserFromBodyContent(` 417 <spdx:License> 418 <spdx:isOsiApproved>no</spdx:isOsiApproved> 419 </spdx:License> 420 `) 421 node = parser.gordfParserObj.Triples[0].Subject 422 license, err = parser.getLicenseFromNode(node) 423 if err == nil { 424 t.Errorf("expected function to raise an error stating isOsiApproved should be a valid boolean type") 425 } 426 427 // TestCase 2: rdf:seeAlso not a valid uri must raise an error 428 parser, _ = parserFromBodyContent(` 429 <spdx:License> 430 <rdfs:seeAlso>uri</rdfs:seeAlso> 431 </spdx:License> 432 `) 433 node = parser.gordfParserObj.Triples[0].Subject 434 license, err = parser.getLicenseFromNode(node) 435 if err == nil { 436 t.Errorf("expected function to raise an error stating invalid uri for rdfs:seeAlso") 437 } 438 439 // TestCase 3: isDeprecatedLicenseId is not a valid boolean 440 parser, _ = parserFromBodyContent(` 441 <spdx:License> 442 <spdx:isDeprecatedLicenseId>yes</spdx:isDeprecatedLicenseId> 443 </spdx:License> 444 `) 445 node = parser.gordfParserObj.Triples[0].Subject 446 license, err = parser.getLicenseFromNode(node) 447 if err == nil { 448 t.Errorf("expected function to raise an error stating isDeprecatedLicenseId should be a valid boolean type") 449 } 450 451 // TestCase 4: isFsfLibre is not a valid boolean 452 parser, _ = parserFromBodyContent(` 453 <spdx:License> 454 <spdx:isFsfLibre>no</spdx:isFsfLibre> 455 </spdx:License> 456 `) 457 node = parser.gordfParserObj.Triples[0].Subject 458 license, err = parser.getLicenseFromNode(node) 459 if err == nil { 460 t.Errorf("expected function to raise an error stating isFsfLibre should be a valid boolean type") 461 } 462 463 // TestCase 5: invalid triple for License: 464 parser, _ = parserFromBodyContent(` 465 <spdx:License> 466 <spdx:unknown /> 467 </spdx:License> 468 `) 469 node = parser.gordfParserObj.Triples[0].Subject 470 license, err = parser.getLicenseFromNode(node) 471 if err == nil { 472 t.Errorf("invalid predicate should've raised an error, got <nil>") 473 } 474 475 // TestCase 5: everything valid: 476 parser, _ = parserFromBodyContent(` 477 <spdx:License rdf:about="http://spdx.org/licenses/GPL-3.0-or-later"> 478 <rdfs:seeAlso>http://www.opensource.org/licenses/GPL-3.0</rdfs:seeAlso> 479 <spdx:isOsiApproved>true</spdx:isOsiApproved> 480 <spdx:licenseText>GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007</spdx:licenseText> 481 <spdx:name>GNU General Public License v3.0 or later</spdx:name> 482 <spdx:standardLicenseHeaderTemplate>...</spdx:standardLicenseHeaderTemplate> 483 <spdx:licenseId>GPL-3.0-or-later</spdx:licenseId> 484 <rdfs:comment>This license was released: 29 June 2007</rdfs:comment> 485 <spdx:isFsfLibre>true</spdx:isFsfLibre> 486 <spdx:standardLicenseHeader>...</spdx:standardLicenseHeader> 487 <spdx:standardLicenseTemplate>....</spdx:standardLicenseTemplate> 488 </spdx:License> 489 `) 490 node = parser.gordfParserObj.Triples[0].Subject 491 license, err = parser.getLicenseFromNode(node) 492 if err != nil { 493 t.Errorf("error parsing a valid input: %v", err) 494 } 495 expectedSeeAlso := "http://www.opensource.org/licenses/GPL-3.0" 496 if len(license.seeAlso) != 1 { 497 t.Fatalf("expected seeAlso to have 1 element, got %d", len(license.seeAlso)) 498 } 499 if license.seeAlso[len(license.seeAlso)-1] != expectedSeeAlso { 500 t.Errorf("expected %s, got %s", expectedSeeAlso, license.seeAlso) 501 } 502 if license.isOsiApproved != true { 503 t.Errorf("expected %t, got %t", true, license.isOsiApproved) 504 } 505 expectedLicenseText := "GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007" 506 if license.licenseText != expectedLicenseText { 507 t.Errorf("expected %s, got %s", expectedSeeAlso, license.licenseText) 508 } 509 expectedName := "GNU General Public License v3.0 or later" 510 if license.name != expectedName { 511 t.Errorf("expected %s, got %s", expectedName, license.name) 512 } 513 expectedstdLicHeader := "..." 514 if license.standardLicenseHeader != expectedstdLicHeader { 515 t.Errorf("expected %s, got %s", expectedstdLicHeader, license.standardLicenseHeader) 516 } 517 expectedLicenseId := "GPL-3.0-or-later" 518 if expectedLicenseId != license.licenseID { 519 t.Errorf("expected %s, got %s", expectedLicenseId, license.licenseID) 520 } 521 expectedLicenseComment := "This license was released: 29 June 2007" 522 if expectedLicenseComment != license.comment { 523 t.Errorf("expected %s, got %s", expectedLicenseComment, license.comment) 524 } 525 expectedstdLicTemplate := "..." 526 if license.standardLicenseHeader != expectedstdLicTemplate { 527 t.Errorf("expected %s, got %s", expectedstdLicTemplate, license.standardLicenseTemplate) 528 } 529 expectedstdLicHeaderTemplate := "..." 530 if license.standardLicenseHeaderTemplate != expectedstdLicHeaderTemplate { 531 t.Errorf("expected %s, got %s", expectedstdLicHeaderTemplate, license.standardLicenseHeaderTemplate) 532 } 533 if license.isFsfLibre != true { 534 t.Errorf("expected %t, got %t", true, license.isFsfLibre) 535 } 536} 537 538func Test_rdfParser2_3_getOrLaterOperatorFromNode(t *testing.T) { 539 var parser *rdfParser2_3 540 var node *gordfParser.Node 541 var err error 542 543 // TestCase 1: more than one member in the OrLaterOperator tag must raise an error 544 parser, _ = parserFromBodyContent(` 545 <spdx:OrLaterOperator> 546 <spdx:member> 547 <spdx:SimpleLicensingInfo> 548 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 549 <spdx:name>freeware</spdx:name> 550 </spdx:SimpleLicensingInfo> 551 </spdx:member> 552 <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/> 553 </spdx:OrLaterOperator> 554 `) 555 node = parser.gordfParserObj.Triples[0].Subject 556 _, err = parser.getOrLaterOperatorFromNode(node) 557 if err == nil { 558 t.Error("expected an error due to more than one members, got <nil>") 559 } 560 561 // TestCase 2: Invalid predicate must raise an error 562 parser, _ = parserFromBodyContent(` 563 <spdx:OrLaterOperator> 564 <spdx:members> 565 <spdx:SimpleLicensingInfo> 566 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 567 <spdx:name>freeware</spdx:name> 568 </spdx:SimpleLicensingInfo> 569 </spdx:members> 570 </spdx:OrLaterOperator> 571 `) 572 node = parser.gordfParserObj.Triples[0].Subject 573 _, err = parser.getOrLaterOperatorFromNode(node) 574 if err == nil { 575 t.Error("expected an error due to invalid predicate, got <nil>") 576 } 577 578 // TestCase 5: invalid member 579 parser, _ = parserFromBodyContent(` 580 <spdx:OrLaterOperator> 581 <spdx:member> 582 <spdx:SimpleLicensingInfo> 583 <spdx:invalidTag /> 584 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 585 <spdx:name>freeware</spdx:name> 586 </spdx:SimpleLicensingInfo> 587 </spdx:member> 588 </spdx:OrLaterOperator> 589 `) 590 node = parser.gordfParserObj.Triples[0].Subject 591 _, err = parser.getOrLaterOperatorFromNode(node) 592 if err == nil { 593 t.Errorf("expected an error parsing invalid license member, got %v", err) 594 } 595 596 // TestCase 4: valid input 597 parser, _ = parserFromBodyContent(` 598 <spdx:OrLaterOperator> 599 <spdx:member> 600 <spdx:SimpleLicensingInfo> 601 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 602 <spdx:name>freeware</spdx:name> 603 </spdx:SimpleLicensingInfo> 604 </spdx:member> 605 </spdx:OrLaterOperator> 606 `) 607 node = parser.gordfParserObj.Triples[0].Subject 608 _, err = parser.getOrLaterOperatorFromNode(node) 609 if err != nil { 610 t.Errorf("unexpected error parsing a valid input: %v", err) 611 } 612} 613 614func Test_rdfParser2_3_getSimpleLicensingInfoFromNode(t *testing.T) { 615 // nothing to test. The just provides an interface to call function that 616 // uses triples to render a SimpleLicensingInfo. 617 parser, _ := parserFromBodyContent(` 618 <spdx:SimpleLicensingInfo> 619 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 620 <spdx:name>freeware</spdx:name> 621 </spdx:SimpleLicensingInfo> 622 `) 623 node := parser.gordfParserObj.Triples[0].Subject 624 _, err := parser.getSimpleLicensingInfoFromNode(node) 625 if err != nil { 626 t.Errorf("error parsing a valid input: %v", err) 627 } 628} 629 630func Test_rdfParser2_3_getSimpleLicensingInfoFromTriples(t *testing.T) { 631 var parser *rdfParser2_3 632 var err error 633 var license SimpleLicensingInfo 634 635 // TestCase 1: invalid rdf:seeAlso attribute 636 parser, _ = parserFromBodyContent(` 637 <spdx:SimpleLicensingInfo> 638 <rdfs:seeAlso>an invalid uri</rdfs:seeAlso> 639 </spdx:SimpleLicensingInfo> 640 `) 641 _, err = parser.getSimpleLicensingInfoFromTriples(parser.gordfParserObj.Triples) 642 if err == nil { 643 t.Error("expected an error reporting invalid uri for rdf:seeAlso, got <nil>") 644 } 645 646 // TestCase 2: invalid predicate must raise an error 647 parser, _ = parserFromBodyContent(` 648 <spdx:SimpleLicensingInfo> 649 <rdfs:invalidPredicate /> 650 </spdx:SimpleLicensingInfo> 651 `) 652 _, err = parser.getSimpleLicensingInfoFromTriples(parser.gordfParserObj.Triples) 653 if err == nil { 654 t.Error("expected an error reporting invalid predicate, got <nil>") 655 } 656 657 // TestCase 3: valid example 658 parser, _ = parserFromBodyContent(` 659 <spdx:SimpleLicensingInfo> 660 <rdfs:comment>comment</rdfs:comment> 661 <spdx:licenseId>lid</spdx:licenseId> 662 <spdx:name>name</spdx:name> 663 <rdfs:seeAlso>https://opensource.org/licenses/MPL-1.0</rdfs:seeAlso> 664 <spdx:example>example</spdx:example> 665 </spdx:SimpleLicensingInfo> 666 `) 667 license, err = parser.getSimpleLicensingInfoFromTriples(parser.gordfParserObj.Triples) 668 if err != nil { 669 t.Fatalf("unexpected error: %v", err) 670 } 671 expectedComment := "comment" 672 expectedLicenseId := "lid" 673 expectedName := "name" 674 expectedSeeAlso := "https://opensource.org/licenses/MPL-1.0" 675 expectedExample := "example" 676 if expectedComment != license.comment { 677 t.Errorf("expected %v, got %v", expectedComment, license.comment) 678 } 679 if expectedLicenseId != license.licenseID { 680 t.Errorf("expected %v, got %v", expectedLicenseId, license.licenseID) 681 } 682 if expectedName != license.name { 683 t.Errorf("expected %v, got %v", expectedName, license.name) 684 } 685 if len(license.seeAlso) != 1 { 686 t.Fatalf("expected seeAlso to have 1 element, found %d", len(license.seeAlso)) 687 } 688 if license.seeAlso[0] != expectedSeeAlso { 689 t.Errorf("expected %v, got %v", expectedSeeAlso, license.seeAlso[0]) 690 } 691 if license.example != expectedExample { 692 t.Errorf("expected %v, got %v", expectedExample, license.example) 693 } 694} 695 696func Test_rdfParser2_3_getSpecialLicenseFromNode(t *testing.T) { 697 var parser *rdfParser2_3 698 var node *gordfParser.Node 699 var license SpecialLicense 700 701 // TestCase 1: NONE 702 parser, _ = parserFromBodyContent(``) 703 node = &gordfParser.Node{ 704 NodeType: gordfParser.IRI, 705 ID: NS_SPDX + "NONE", 706 } 707 license, err := parser.getSpecialLicenseFromNode(node) 708 if err != nil { 709 t.Errorf("error parsing a valid node: %v", err) 710 } 711 if license.value != "NONE" { 712 t.Errorf("expected %s, got %s", "NONE", license.value) 713 } 714 715 // TestCase 2: NOASSERTION 716 parser, _ = parserFromBodyContent(``) 717 node = &gordfParser.Node{ 718 NodeType: gordfParser.IRI, 719 ID: NS_SPDX + "NOASSERTION", 720 } 721 license, err = parser.getSpecialLicenseFromNode(node) 722 if err != nil { 723 t.Errorf("error parsing a valid node: %v", err) 724 } 725 if license.value != "NOASSERTION" { 726 t.Errorf("expected %s, got %s", "NOASSERTION", license.value) 727 } 728 729 // TestCase 4: undefined standard license 730 parser, _ = parserFromBodyContent(``) 731 node = &gordfParser.Node{ 732 NodeType: gordfParser.IRI, 733 ID: "https://opensource.org/licenses/unknown", 734 } 735 _, err = parser.getSpecialLicenseFromNode(node) 736 if err == nil { 737 t.Errorf("expected an error saying invalid license") 738 } 739 740 // TestCase 4: valid standard license 741 parser, _ = parserFromBodyContent(``) 742 node = &gordfParser.Node{ 743 NodeType: gordfParser.IRI, 744 ID: "https://opensource.org/licenses/MPL-1.0", 745 } 746 license, err = parser.getSpecialLicenseFromNode(node) 747 if err != nil { 748 t.Errorf("error parsing a valid node: %v", err) 749 } 750 if license.value != "MPL-1.0" { 751 t.Errorf("expected %s, got %s", "MPL-1.0", license.value) 752 } 753} 754 755func Test_rdfParser2_3_getWithExceptionOperatorFromNode(t *testing.T) { 756 var parser *rdfParser2_3 757 var node *gordfParser.Node 758 var err error 759 760 // TestCase 1: more than one member in the OrLaterOperator tag must raise an error 761 parser, _ = parserFromBodyContent(` 762 <spdx:WithExceptionOperator> 763 <spdx:member> 764 <spdx:SimpleLicensingInfo> 765 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 766 <spdx:name>freeware</spdx:name> 767 </spdx:SimpleLicensingInfo> 768 </spdx:member> 769 <spdx:member rdf:resource="http://spdx.org/licenses/Nokia"/> 770 </spdx:WithExceptionOperator> 771 `) 772 node = parser.gordfParserObj.Triples[0].Subject 773 _, err = parser.getWithExceptionOperatorFromNode(node) 774 if err == nil { 775 t.Error("expected an error due to more than one members, got <nil>") 776 } 777 778 // TestCase 2: Invalid predicate must raise an error 779 parser, _ = parserFromBodyContent(` 780 <spdx:WithExceptionOperator> 781 <spdx:members> 782 <spdx:SimpleLicensingInfo> 783 <spdx:licenseId>LicenseRef-Freeware</spdx:licenseId> 784 <spdx:name>freeware</spdx:name> 785 </spdx:SimpleLicensingInfo> 786 </spdx:members> 787 </spdx:WithExceptionOperator> 788 `) 789 node = parser.gordfParserObj.Triples[0].Subject 790 _, err = parser.getWithExceptionOperatorFromNode(node) 791 if err == nil { 792 t.Error("expected an error due to invalid predicate, got <nil>") 793 } 794 795 // TestCase 3: Invalid member 796 parser, _ = parserFromBodyContent(` 797 <spdx:WithExceptionOperator> 798 <spdx:member> 799 <spdx:License rdf:about="http://spdx.org/licenses/GPL-2.0-or-later"> 800 <spdx:unknownTag /> 801 </spdx:License> 802 </spdx:member> 803 </spdx:WithExceptionOperator> 804 `) 805 node = parser.gordfParserObj.Triples[0].Subject 806 _, err = parser.getWithExceptionOperatorFromNode(node) 807 if err == nil { 808 t.Error("expected an error due to error parsing a member, got <nil>") 809 } 810 811 // TestCase 4: Invalid licenseException 812 parser, _ = parserFromBodyContent(` 813 <spdx:WithExceptionOperator> 814 <spdx:member> 815 <spdx:License rdf:about="http://spdx.org/licenses/GPL-2.0-or-later"/> 816 </spdx:member> 817 <spdx:licenseException> 818 <spdx:LicenseException> 819 <spdx:invalidTag /> 820 <spdx:example>example</spdx:example> 821 <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId> 822 <rdfs:comment>comment</rdfs:comment> 823 </spdx:LicenseException> 824 </spdx:licenseException> 825 </spdx:WithExceptionOperator> 826 `) 827 node = parser.gordfParserObj.Triples[0].Subject 828 _, err = parser.getWithExceptionOperatorFromNode(node) 829 if err == nil { 830 t.Error("expected an error due to invalid licenseException, got <nil>") 831 } 832 833 // TestCase 5: valid input 834 parser, _ = parserFromBodyContent(` 835 <spdx:WithExceptionOperator> 836 <spdx:member> 837 <spdx:License rdf:about="http://spdx.org/licenses/GPL-2.0-or-later"/> 838 </spdx:member> 839 <spdx:licenseException> 840 <spdx:LicenseException> 841 <spdx:example>example</spdx:example> 842 <spdx:licenseExceptionId>Libtool-exception</spdx:licenseExceptionId> 843 <rdfs:comment>comment</rdfs:comment> 844 </spdx:LicenseException> 845 </spdx:licenseException> 846 </spdx:WithExceptionOperator> 847 `) 848 node = parser.gordfParserObj.Triples[0].Subject 849 _, err = parser.getWithExceptionOperatorFromNode(node) 850 if err != nil { 851 t.Errorf("error parsing a valid input: %v", err) 852 } 853} 854