github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/cmd/syft/cli/options/output_test.go (about)

     1  package options
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/scylladb/go-set/strset"
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/anchore/syft/syft/format"
    11  	"github.com/anchore/syft/syft/format/cyclonedxjson"
    12  	"github.com/anchore/syft/syft/format/cyclonedxxml"
    13  	"github.com/anchore/syft/syft/format/github"
    14  	"github.com/anchore/syft/syft/format/spdxjson"
    15  	"github.com/anchore/syft/syft/format/spdxtagvalue"
    16  	"github.com/anchore/syft/syft/format/syftjson"
    17  	"github.com/anchore/syft/syft/format/table"
    18  	"github.com/anchore/syft/syft/format/template"
    19  	"github.com/anchore/syft/syft/format/text"
    20  	"github.com/anchore/syft/syft/sbom"
    21  )
    22  
    23  func Test_getEncoders(t *testing.T) {
    24  	allDefaultEncoderNames := strset.New()
    25  	for _, id := range supportedIDs() {
    26  		allDefaultEncoderNames.Add(id.String())
    27  	}
    28  
    29  	opts := DefaultOutput()
    30  	require.NoError(t, opts.Format.PostLoad())
    31  	opts.Format.Template.Path = "somewhere"
    32  
    33  	encoders, err := opts.Encoders()
    34  	require.NoError(t, err)
    35  	require.NotEmpty(t, encoders)
    36  
    37  	encoderNames := strset.New()
    38  	for _, e := range encoders {
    39  		encoderNames.Add(e.ID().String())
    40  	}
    41  
    42  	assert.ElementsMatch(t, allDefaultEncoderNames.List(), encoderNames.List(), "not all encoders are expressed")
    43  }
    44  
    45  func Test_EncoderCollection_ByString_IDOnly_Defaults(t *testing.T) {
    46  	tests := []struct {
    47  		name string
    48  		want sbom.FormatID
    49  	}{
    50  		// SPDX Tag-Value
    51  		{
    52  			name: "spdx",
    53  			want: spdxtagvalue.ID,
    54  		},
    55  		{
    56  			name: "spdx-tag-value",
    57  			want: spdxtagvalue.ID,
    58  		},
    59  		{
    60  			name: "spdx-tv",
    61  			want: spdxtagvalue.ID,
    62  		},
    63  		{
    64  			name: "spdxtv", // clean variant
    65  			want: spdxtagvalue.ID,
    66  		},
    67  
    68  		// SPDX JSON
    69  		{
    70  			name: "spdx-json",
    71  			want: spdxjson.ID,
    72  		},
    73  		{
    74  			name: "spdxjson", // clean variant
    75  			want: spdxjson.ID,
    76  		},
    77  
    78  		// Cyclonedx JSON
    79  		{
    80  			name: "cyclonedx-json",
    81  			want: cyclonedxjson.ID,
    82  		},
    83  		{
    84  			name: "cyclonedxjson", // clean variant
    85  			want: cyclonedxjson.ID,
    86  		},
    87  
    88  		// Cyclonedx XML
    89  		{
    90  			name: "cdx",
    91  			want: cyclonedxxml.ID,
    92  		},
    93  		{
    94  			name: "cyclone",
    95  			want: cyclonedxxml.ID,
    96  		},
    97  		{
    98  			name: "cyclonedx",
    99  			want: cyclonedxxml.ID,
   100  		},
   101  		{
   102  			name: "cyclonedx-xml",
   103  			want: cyclonedxxml.ID,
   104  		},
   105  		{
   106  			name: "cyclonedxxml", // clean variant
   107  			want: cyclonedxxml.ID,
   108  		},
   109  
   110  		// Syft Table
   111  		{
   112  			name: "table",
   113  			want: table.ID,
   114  		},
   115  		{
   116  			name: "syft-table",
   117  			want: table.ID,
   118  		},
   119  
   120  		// Syft Text
   121  		{
   122  			name: "text",
   123  			want: text.ID,
   124  		},
   125  		{
   126  			name: "syft-text",
   127  			want: text.ID,
   128  		},
   129  
   130  		// Syft JSON
   131  		{
   132  			name: "json",
   133  			want: syftjson.ID,
   134  		},
   135  		{
   136  			name: "syft-json",
   137  			want: syftjson.ID,
   138  		},
   139  		{
   140  			name: "syftjson", // clean variant
   141  			want: syftjson.ID,
   142  		},
   143  
   144  		// GitHub JSON
   145  		{
   146  			name: "github",
   147  			want: github.ID,
   148  		},
   149  		{
   150  			name: "github-json",
   151  			want: github.ID,
   152  		},
   153  
   154  		// Syft template
   155  		{
   156  			name: "template",
   157  			want: template.ID,
   158  		},
   159  	}
   160  
   161  	opts := DefaultOutput()
   162  	require.NoError(t, opts.Format.PostLoad())
   163  	opts.Format.Template.Path = "somewhere"
   164  
   165  	defaultEncoders, err := opts.Encoders()
   166  	require.NoError(t, err)
   167  
   168  	encoders := format.NewEncoderCollection(defaultEncoders...)
   169  
   170  	for _, tt := range tests {
   171  		t.Run(tt.name, func(t *testing.T) {
   172  			f := encoders.GetByString(tt.name)
   173  			if tt.want == "" {
   174  				require.Nil(t, f)
   175  				return
   176  			}
   177  			require.NotNil(t, f)
   178  			assert.Equal(t, tt.want, f.ID())
   179  		})
   180  	}
   181  }
   182  
   183  func Test_OutputHonorsAllowFile(t *testing.T) {
   184  	o := DefaultOutput()
   185  
   186  	t.Run("file is not allowed", func(t *testing.T) {
   187  		o.AllowToFile = false
   188  		o.Outputs = []string{"table=/tmp/somefile"}
   189  
   190  		w, err := o.SBOMWriter()
   191  		assert.Nil(t, w)
   192  		assert.ErrorContains(t, err, "file output is not allowed")
   193  	})
   194  
   195  	t.Run("file is allowed", func(t *testing.T) {
   196  		o.AllowToFile = true
   197  		o.Outputs = []string{"table=/tmp/somefile"}
   198  
   199  		w, err := o.SBOMWriter()
   200  		assert.NotNil(t, w)
   201  		assert.NoError(t, err)
   202  	})
   203  }