@@ -143,8 +143,10 @@ func TestMergeSBOMs(t *testing.T) {
143143 createTestPackage ("pkg3" , "3.0.0" , "" ),
144144 }),
145145 },
146- expectedPackageCount : 4 ,
147- expectedRelationshipCount : 2 ,
146+ // 4 original packages + 2 source packages (test1, test2) = 6
147+ // 2 original relationships + 4 contains relationships (2 pkgs × 2 sources) = 6
148+ expectedPackageCount : 6 ,
149+ expectedRelationshipCount : 6 ,
148150 },
149151 {
150152 name : "empty SBOM slice" ,
@@ -259,3 +261,122 @@ func createTestPackagePtr(name, version, cpeStr string) *pkg.Package {
259261 p := createTestPackage (name , version , cpeStr )
260262 return & p
261263}
264+
265+ func TestSourceToPackage (t * testing.T ) {
266+ // GIVEN: Various source descriptions
267+ // WHEN: sourceToPackage is called
268+ // THEN: Appropriate packages should be created
269+
270+ tests := []struct {
271+ name string
272+ src source.Description
273+ expectNil bool
274+ expectName string
275+ expectVer string
276+ }{
277+ {
278+ name : "valid source with name and version" ,
279+ src : source.Description {Name : "libelf" , Version : "0.194" },
280+ expectNil : false ,
281+ expectName : "libelf" ,
282+ expectVer : "0.194" ,
283+ },
284+ {
285+ name : "valid source with name only" ,
286+ src : source.Description {Name : "mypackage" },
287+ expectNil : false ,
288+ expectName : "mypackage" ,
289+ expectVer : "" ,
290+ },
291+ {
292+ name : "empty source" ,
293+ src : source.Description {},
294+ expectNil : true ,
295+ },
296+ {
297+ name : "source with empty name" ,
298+ src : source.Description {Name : "" , Version : "1.0" },
299+ expectNil : true ,
300+ },
301+ }
302+
303+ for _ , tt := range tests {
304+ t .Run (tt .name , func (t * testing.T ) {
305+ result := sourceToPackage (tt .src )
306+
307+ if tt .expectNil {
308+ if result != nil {
309+ t .Errorf ("expected nil, got package with name %s" , result .Name )
310+ }
311+ return
312+ }
313+
314+ if result == nil {
315+ t .Fatal ("expected package, got nil" )
316+ }
317+
318+ if result .Name != tt .expectName {
319+ t .Errorf ("expected name %s, got %s" , tt .expectName , result .Name )
320+ }
321+
322+ if result .Version != tt .expectVer {
323+ t .Errorf ("expected version %s, got %s" , tt .expectVer , result .Version )
324+ }
325+ })
326+ }
327+ }
328+
329+ func TestMergeSBOMsPreservesSource (t * testing.T ) {
330+ // GIVEN: Multiple SBOMs with Source (metadata.component) set
331+ // WHEN: mergeSBOMs is called
332+ // THEN: Source from each SBOM should be converted to a package with contains relationships
333+
334+ sbom1 := createTestSBOM ("sbom1" , []pkg.Package {
335+ createTestPackage ("pkg1" , "1.0.0" , "" ),
336+ })
337+ sbom1 .Source = source.Description {Name : "libelf" , Version : "0.194" }
338+
339+ sbom2 := createTestSBOM ("sbom2" , []pkg.Package {
340+ createTestPackage ("pkg2" , "2.0.0" , "" ),
341+ })
342+ sbom2 .Source = source.Description {Name : "glibc" , Version : "2.38" }
343+
344+ _ , packages , relationships := mergeSBOMs ([]* sbom.SBOM {sbom1 , sbom2 })
345+
346+ // Should have: pkg1, pkg2, libelf (from source), glibc (from source) = 4 packages
347+ if len (packages ) != 4 {
348+ t .Errorf ("expected 4 packages (2 original + 2 from source), got %d" , len (packages ))
349+ }
350+
351+ // Verify libelf and glibc are in the packages
352+ foundLibelf := false
353+ foundGlibc := false
354+ for _ , p := range packages {
355+ if p .Name == "libelf" && p .Version == "0.194" {
356+ foundLibelf = true
357+ }
358+ if p .Name == "glibc" && p .Version == "2.38" {
359+ foundGlibc = true
360+ }
361+ }
362+
363+ if ! foundLibelf {
364+ t .Error ("expected libelf package from source, not found" )
365+ }
366+ if ! foundGlibc {
367+ t .Error ("expected glibc package from source, not found" )
368+ }
369+
370+ // Verify contains relationships were created
371+ // Each SBOM has 1 package + 1 existing relationship from createTestSBOM
372+ // Plus 1 contains relationship from source to package = 2 contains relationships total
373+ containsCount := 0
374+ for _ , rel := range relationships {
375+ if rel .Type == artifact .ContainsRelationship {
376+ containsCount ++
377+ }
378+ }
379+ if containsCount != 2 {
380+ t .Errorf ("expected 2 contains relationships (one per source), got %d" , containsCount )
381+ }
382+ }
0 commit comments