github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/license_set_test.go (about)

     1  package pkg
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/google/go-cmp/cmp"
     7  
     8  	"github.com/anchore/syft/syft/file"
     9  	"github.com/anchore/syft/syft/license"
    10  )
    11  
    12  func TestLicenseSet_Add(t *testing.T) {
    13  	tests := []struct {
    14  		name     string
    15  		licenses []License
    16  		want     []License
    17  	}{
    18  		{
    19  			name: "add one simple license",
    20  			licenses: []License{
    21  				NewLicense("MIT"),
    22  			},
    23  			want: []License{
    24  				NewLicense("MIT"),
    25  			},
    26  		},
    27  		{
    28  			name: "add multiple simple licenses",
    29  			licenses: []License{
    30  				NewLicense("MIT"),
    31  				NewLicense("MIT"),
    32  				NewLicense("Apache-2.0"),
    33  			},
    34  			want: []License{
    35  				NewLicense("Apache-2.0"),
    36  				NewLicense("MIT"),
    37  			},
    38  		},
    39  		{
    40  			name: "attempt to add a license with no name",
    41  			licenses: []License{
    42  				NewLicense(""),
    43  			},
    44  			want: nil,
    45  		},
    46  		{
    47  			name: "keep multiple licenses sorted",
    48  			licenses: []License{
    49  				NewLicense("MIT"),
    50  				NewLicense("Apache-2.0"),
    51  			},
    52  			want: []License{
    53  				NewLicense("Apache-2.0"),
    54  				NewLicense("MIT"),
    55  			},
    56  		},
    57  		{
    58  			name: "deduplicate licenses with locations",
    59  			licenses: []License{
    60  				NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})),
    61  				NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})),
    62  				NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"})),
    63  			},
    64  			want: []License{
    65  				NewLicenseFromLocations(
    66  					"MIT",
    67  					file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"}),
    68  					file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"}),
    69  				),
    70  			},
    71  		},
    72  		{
    73  			name: "same licenses with different locations",
    74  			licenses: []License{
    75  				NewLicense("MIT"),
    76  				NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"})),
    77  				NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})),
    78  			},
    79  			want: []License{
    80  				NewLicenseFromLocations(
    81  					"MIT",
    82  					file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"}),
    83  					file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"}),
    84  				),
    85  			},
    86  		},
    87  		{
    88  			name: "same license from different sources",
    89  			licenses: []License{
    90  				NewLicense("MIT"),
    91  				NewLicenseFromLocations("MIT", file.NewLocation("/place")),
    92  				NewLicenseFromURLs("MIT", "https://example.com"),
    93  			},
    94  			want: []License{
    95  				{
    96  					Value:          "MIT",
    97  					SPDXExpression: "MIT",
    98  					Type:           license.Declared,
    99  					URLs:           []string{"https://example.com"},
   100  					Locations:      file.NewLocationSet(file.NewLocation("/place")),
   101  				},
   102  			},
   103  		},
   104  		{
   105  			name: "different licenses from different sources with different types constitute two licenses",
   106  			licenses: []License{
   107  				NewLicenseFromType("MIT", license.Concluded),
   108  				NewLicenseFromType("MIT", license.Declared),
   109  				NewLicenseFromLocations("MIT", file.NewLocation("/place")),
   110  				NewLicenseFromURLs("MIT", "https://example.com"),
   111  			},
   112  			want: []License{
   113  				{
   114  					Value:          "MIT",
   115  					SPDXExpression: "MIT",
   116  					Type:           license.Concluded,
   117  					Locations:      file.NewLocationSet(),
   118  				},
   119  				{
   120  					Value:          "MIT",
   121  					SPDXExpression: "MIT",
   122  					Type:           license.Declared,
   123  					URLs:           []string{"https://example.com"},
   124  					Locations:      file.NewLocationSet(file.NewLocation("/place")),
   125  				},
   126  			},
   127  		},
   128  	}
   129  	for _, tt := range tests {
   130  		t.Run(tt.name, func(t *testing.T) {
   131  			s := NewLicenseSet()
   132  			s.Add(tt.licenses...)
   133  			testMe := s.ToSlice()
   134  			if d := cmp.Diff(tt.want, testMe, cmp.Comparer(defaultLicenseComparer)); d != "" {
   135  				t.Errorf("unexpected license set (-want +got):\n%s", d)
   136  			}
   137  		})
   138  	}
   139  }
   140  
   141  func defaultLocationComparer(x, y file.Location) bool {
   142  	return cmp.Equal(x.Coordinates, y.Coordinates) && cmp.Equal(x.AccessPath, y.AccessPath)
   143  }
   144  
   145  func defaultLicenseComparer(x, y License) bool {
   146  	return cmp.Equal(x, y, cmp.Comparer(defaultLocationComparer), cmp.Comparer(
   147  		func(x, y file.LocationSet) bool {
   148  			xs := x.ToSlice()
   149  			ys := y.ToSlice()
   150  			if len(xs) != len(ys) {
   151  				return false
   152  			}
   153  			for i, xe := range xs {
   154  				ye := ys[i]
   155  				if !defaultLocationComparer(xe, ye) {
   156  					return false
   157  				}
   158  			}
   159  			return true
   160  		},
   161  	))
   162  }