github.com/anchore/syft@v1.38.2/internal/cmptest/common_options.go (about)

     1  package cmptest
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/google/go-cmp/cmp"
     7  	"github.com/google/go-cmp/cmp/cmpopts"
     8  
     9  	"github.com/anchore/syft/internal/evidence"
    10  	"github.com/anchore/syft/syft/file"
    11  	"github.com/anchore/syft/syft/pkg"
    12  )
    13  
    14  func DefaultOptions() []cmp.Option {
    15  	return BuildOptions(nil, nil)
    16  }
    17  
    18  func DefaultIgnoreLocationLayerOptions() []cmp.Option {
    19  	return BuildOptions(LicenseComparerWithoutLocationLayer, LocationComparerWithoutLayer)
    20  }
    21  
    22  func BuildOptions(licenseCmp LicenseComparer, locationCmp LocationComparer) []cmp.Option {
    23  	if licenseCmp == nil {
    24  		licenseCmp = DefaultLicenseComparer
    25  	}
    26  
    27  	if locationCmp == nil {
    28  		locationCmp = DefaultLocationComparer
    29  	}
    30  
    31  	return []cmp.Option{
    32  		cmpopts.IgnoreFields(pkg.Package{}, "id"), // note: ID is not deterministic for test purposes
    33  		cmpopts.SortSlices(pkg.Less),
    34  		cmpopts.SortSlices(DefaultRelationshipComparer),
    35  		cmp.Comparer(buildSetComparer[file.Location, file.LocationSet](locationCmp, locationSorter)),
    36  		cmp.Comparer(buildSetComparer[pkg.License, pkg.LicenseSet](licenseCmp)),
    37  		cmp.Comparer(locationCmp),
    38  		cmp.Comparer(licenseCmp),
    39  	}
    40  }
    41  
    42  // LocationSorter always sorts by evidence annotations first, then by access path, then by real path.
    43  // This intentionally does not consider layer details since some test fixtures have no layer information
    44  // on the left side of the comparison (expected) and does on the right side (actual).
    45  func locationSorter(a, b file.Location) int {
    46  	// compare by evidence annotations first...
    47  	aEvidence := a.Annotations[evidence.AnnotationKey]
    48  	bEvidence := b.Annotations[evidence.AnnotationKey]
    49  
    50  	if aEvidence != bEvidence {
    51  		if aEvidence == evidence.PrimaryAnnotation {
    52  			return -1
    53  		}
    54  		if bEvidence == evidence.PrimaryAnnotation {
    55  			return 1
    56  		}
    57  
    58  		if aEvidence > bEvidence {
    59  			return -1
    60  		}
    61  		if bEvidence > aEvidence {
    62  			return 1
    63  		}
    64  	}
    65  
    66  	// ...then by paths
    67  	if a.AccessPath != b.AccessPath {
    68  		return strings.Compare(a.AccessPath, b.AccessPath)
    69  	}
    70  
    71  	return strings.Compare(a.RealPath, b.RealPath)
    72  }