github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/formats/formats_test.go (about)

     1  package formats
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/nextlinux/gosbom/gosbom/formats/cyclonedxjson"
    10  	"github.com/nextlinux/gosbom/gosbom/formats/cyclonedxxml"
    11  	"github.com/nextlinux/gosbom/gosbom/formats/github"
    12  	"github.com/nextlinux/gosbom/gosbom/formats/gosbomjson"
    13  	"github.com/nextlinux/gosbom/gosbom/formats/spdxjson"
    14  	"github.com/nextlinux/gosbom/gosbom/formats/spdxtagvalue"
    15  	"github.com/nextlinux/gosbom/gosbom/formats/table"
    16  	"github.com/nextlinux/gosbom/gosbom/formats/template"
    17  	"github.com/nextlinux/gosbom/gosbom/formats/text"
    18  	"github.com/nextlinux/gosbom/gosbom/sbom"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestIdentify(t *testing.T) {
    24  	tests := []struct {
    25  		fixture  string
    26  		expected sbom.FormatID
    27  	}{
    28  		{
    29  			fixture:  "test-fixtures/alpine-gosbom.json",
    30  			expected: gosbomjson.ID,
    31  		},
    32  	}
    33  	for _, test := range tests {
    34  		t.Run(test.fixture, func(t *testing.T) {
    35  			f, err := os.Open(test.fixture)
    36  			assert.NoError(t, err)
    37  			by, err := io.ReadAll(f)
    38  			assert.NoError(t, err)
    39  			frmt := Identify(by)
    40  			assert.NotNil(t, frmt)
    41  			assert.Equal(t, test.expected, frmt.ID())
    42  		})
    43  	}
    44  }
    45  
    46  func TestFormats_EmptyInput(t *testing.T) {
    47  	for _, format := range Formats() {
    48  		t.Run(format.ID().String(), func(t *testing.T) {
    49  			t.Run("format.Decode", func(t *testing.T) {
    50  				input := bytes.NewReader(nil)
    51  
    52  				assert.NotPanics(t, func() {
    53  					decodedSBOM, err := format.Decode(input)
    54  					assert.Error(t, err)
    55  					assert.Nil(t, decodedSBOM)
    56  				})
    57  			})
    58  
    59  			t.Run("format.Validate", func(t *testing.T) {
    60  				input := bytes.NewReader(nil)
    61  
    62  				assert.NotPanics(t, func() {
    63  					err := format.Validate(input)
    64  					assert.Error(t, err)
    65  				})
    66  			})
    67  		})
    68  	}
    69  }
    70  
    71  func TestByName(t *testing.T) {
    72  
    73  	tests := []struct {
    74  		name string
    75  		want sbom.FormatID
    76  	}{
    77  		// SPDX Tag-Value
    78  		{
    79  			name: "spdx",
    80  			want: spdxtagvalue.ID,
    81  		},
    82  		{
    83  			name: "spdx-tag-value",
    84  			want: spdxtagvalue.ID,
    85  		},
    86  		{
    87  			name: "spdx-tv",
    88  			want: spdxtagvalue.ID,
    89  		},
    90  		{
    91  			name: "spdxtv", // clean variant
    92  			want: spdxtagvalue.ID,
    93  		},
    94  
    95  		// SPDX JSON
    96  		{
    97  			name: "spdx-json",
    98  			want: spdxjson.ID,
    99  		},
   100  		{
   101  			name: "spdxjson", // clean variant
   102  			want: spdxjson.ID,
   103  		},
   104  
   105  		// Cyclonedx JSON
   106  		{
   107  			name: "cyclonedx-json",
   108  			want: cyclonedxjson.ID,
   109  		},
   110  		{
   111  			name: "cyclonedxjson", // clean variant
   112  			want: cyclonedxjson.ID,
   113  		},
   114  
   115  		// Cyclonedx XML
   116  		{
   117  			name: "cyclonedx",
   118  			want: cyclonedxxml.ID,
   119  		},
   120  		{
   121  			name: "cyclonedx-xml",
   122  			want: cyclonedxxml.ID,
   123  		},
   124  		{
   125  			name: "cyclonedxxml", // clean variant
   126  			want: cyclonedxxml.ID,
   127  		},
   128  
   129  		// Gosbom Table
   130  		{
   131  			name: "table",
   132  			want: table.ID,
   133  		},
   134  		{
   135  			name: "gosbom-table",
   136  			want: table.ID,
   137  		},
   138  
   139  		// Gosbom Text
   140  		{
   141  			name: "text",
   142  			want: text.ID,
   143  		},
   144  		{
   145  			name: "gosbom-text",
   146  			want: text.ID,
   147  		},
   148  
   149  		// Gosbom JSON
   150  		{
   151  			name: "json",
   152  			want: gosbomjson.ID,
   153  		},
   154  		{
   155  			name: "gosbom-json",
   156  			want: gosbomjson.ID,
   157  		},
   158  		{
   159  			name: "gosbomjson", // clean variant
   160  			want: gosbomjson.ID,
   161  		},
   162  
   163  		// GitHub JSON
   164  		{
   165  			name: "github",
   166  			want: github.ID,
   167  		},
   168  		{
   169  			name: "github-json",
   170  			want: github.ID,
   171  		},
   172  
   173  		// Gosbom template
   174  		{
   175  			name: "template",
   176  			want: template.ID,
   177  		},
   178  	}
   179  	for _, tt := range tests {
   180  		t.Run(tt.name, func(t *testing.T) {
   181  			f := ByName(tt.name)
   182  			if tt.want == "" {
   183  				require.Nil(t, f)
   184  				return
   185  			}
   186  			require.NotNil(t, f)
   187  			assert.Equal(t, tt.want, f.ID())
   188  		})
   189  	}
   190  }
   191  
   192  func Test_versionMatches(t *testing.T) {
   193  	tests := []struct {
   194  		name    string
   195  		version string
   196  		match   string
   197  		matches bool
   198  	}{
   199  		{
   200  			name:    "any version matches number",
   201  			version: string(sbom.AnyVersion),
   202  			match:   "6",
   203  			matches: true,
   204  		},
   205  		{
   206  			name:    "number matches any version",
   207  			version: "6",
   208  			match:   string(sbom.AnyVersion),
   209  			matches: true,
   210  		},
   211  		{
   212  			name:    "same number matches",
   213  			version: "3",
   214  			match:   "3",
   215  			matches: true,
   216  		},
   217  		{
   218  			name:    "same major number matches",
   219  			version: "3.1",
   220  			match:   "3",
   221  			matches: true,
   222  		},
   223  		{
   224  			name:    "same minor number matches",
   225  			version: "3.1",
   226  			match:   "3.1",
   227  			matches: true,
   228  		},
   229  		{
   230  			name:    "wildcard-version matches minor",
   231  			version: "7.1.3",
   232  			match:   "7.*",
   233  			matches: true,
   234  		},
   235  		{
   236  			name:    "wildcard-version matches patch",
   237  			version: "7.4.8",
   238  			match:   "7.4.*",
   239  			matches: true,
   240  		},
   241  		{
   242  			name:    "sub-version matches major",
   243  			version: "7.19.11",
   244  			match:   "7",
   245  			matches: true,
   246  		},
   247  		{
   248  			name:    "sub-version matches minor",
   249  			version: "7.55.2",
   250  			match:   "7.55",
   251  			matches: true,
   252  		},
   253  		{
   254  			name:    "sub-version matches patch",
   255  			version: "7.32.6",
   256  			match:   "7.32.6",
   257  			matches: true,
   258  		},
   259  		// negative tests
   260  		{
   261  			name:    "different number does not match",
   262  			version: "3",
   263  			match:   "4",
   264  			matches: false,
   265  		},
   266  		{
   267  			name:    "sub-version doesn't match major",
   268  			version: "7.2.5",
   269  			match:   "8.2.5",
   270  			matches: false,
   271  		},
   272  		{
   273  			name:    "sub-version doesn't match minor",
   274  			version: "7.2.9",
   275  			match:   "7.1",
   276  			matches: false,
   277  		},
   278  		{
   279  			name:    "sub-version doesn't match patch",
   280  			version: "7.32.6",
   281  			match:   "7.32.5",
   282  			matches: false,
   283  		},
   284  	}
   285  
   286  	for _, test := range tests {
   287  		t.Run(test.name, func(t *testing.T) {
   288  			matches := versionMatches(test.version, test.match)
   289  			assert.Equal(t, test.matches, matches)
   290  		})
   291  	}
   292  }