github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/cmd/gosbom/cli/options/writer_test.go (about) 1 package options 2 3 import ( 4 "io" 5 "path/filepath" 6 "strings" 7 "testing" 8 9 "github.com/docker/docker/pkg/homedir" 10 "github.com/nextlinux/gosbom/gosbom/sbom" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func Test_MakeSBOMWriter(t *testing.T) { 15 tests := []struct { 16 outputs []string 17 wantErr assert.ErrorAssertionFunc 18 }{ 19 { 20 outputs: []string{"json"}, 21 wantErr: assert.NoError, 22 }, 23 { 24 outputs: []string{"table", "json"}, 25 wantErr: assert.NoError, 26 }, 27 { 28 outputs: []string{"unknown"}, 29 wantErr: func(t assert.TestingT, err error, bla ...interface{}) bool { 30 return assert.ErrorContains(t, err, `unsupported output format "unknown", supported formats are: [`) 31 }, 32 }, 33 } 34 35 for _, tt := range tests { 36 _, err := MakeSBOMWriter(tt.outputs, "", "") 37 tt.wantErr(t, err) 38 } 39 } 40 41 func dummyEncoder(io.Writer, sbom.SBOM) error { 42 return nil 43 } 44 45 func dummyFormat(name string) sbom.Format { 46 return sbom.NewFormat(sbom.AnyVersion, dummyEncoder, nil, nil, sbom.FormatID(name)) 47 } 48 49 func Test_newSBOMMultiWriter(t *testing.T) { 50 type writerConfig struct { 51 format string 52 file string 53 } 54 55 tmp := t.TempDir() 56 57 testName := func(options []sbomWriterDescription, err bool) string { 58 var out []string 59 for _, opt := range options { 60 out = append(out, string(opt.Format.ID())+"="+opt.Path) 61 } 62 errs := "" 63 if err { 64 errs = "(err)" 65 } 66 return strings.Join(out, ", ") + errs 67 } 68 69 tests := []struct { 70 outputs []sbomWriterDescription 71 err bool 72 expected []writerConfig 73 }{ 74 { 75 outputs: []sbomWriterDescription{}, 76 err: true, 77 }, 78 { 79 outputs: []sbomWriterDescription{ 80 { 81 Format: dummyFormat("table"), 82 Path: "", 83 }, 84 }, 85 expected: []writerConfig{ 86 { 87 format: "table", 88 }, 89 }, 90 }, 91 { 92 outputs: []sbomWriterDescription{ 93 { 94 Format: dummyFormat("json"), 95 }, 96 }, 97 expected: []writerConfig{ 98 { 99 format: "json", 100 }, 101 }, 102 }, 103 { 104 outputs: []sbomWriterDescription{ 105 { 106 Format: dummyFormat("json"), 107 Path: "test-2.json", 108 }, 109 }, 110 expected: []writerConfig{ 111 { 112 format: "json", 113 file: "test-2.json", 114 }, 115 }, 116 }, 117 { 118 outputs: []sbomWriterDescription{ 119 { 120 Format: dummyFormat("json"), 121 Path: "test-3/1.json", 122 }, 123 { 124 Format: dummyFormat("spdx-json"), 125 Path: "test-3/2.json", 126 }, 127 }, 128 expected: []writerConfig{ 129 { 130 format: "json", 131 file: "test-3/1.json", 132 }, 133 { 134 format: "spdx-json", 135 file: "test-3/2.json", 136 }, 137 }, 138 }, 139 { 140 outputs: []sbomWriterDescription{ 141 { 142 Format: dummyFormat("text"), 143 }, 144 { 145 Format: dummyFormat("spdx-json"), 146 Path: "test-4.json", 147 }, 148 }, 149 expected: []writerConfig{ 150 { 151 format: "text", 152 }, 153 { 154 format: "spdx-json", 155 file: "test-4.json", 156 }, 157 }, 158 }, 159 } 160 161 for _, test := range tests { 162 t.Run(testName(test.outputs, test.err), func(t *testing.T) { 163 outputs := test.outputs 164 for i := range outputs { 165 if outputs[i].Path != "" { 166 outputs[i].Path = tmp + outputs[i].Path 167 } 168 } 169 170 mw, err := newSBOMMultiWriter(outputs...) 171 172 if test.err { 173 assert.Error(t, err) 174 return 175 } else { 176 assert.NoError(t, err) 177 } 178 179 assert.Len(t, mw.writers, len(test.expected)) 180 181 for i, e := range test.expected { 182 switch w := mw.writers[i].(type) { 183 case *sbomStreamWriter: 184 assert.Equal(t, string(w.format.ID()), e.format) 185 if e.file != "" { 186 assert.NotNil(t, w.out) 187 } else { 188 assert.NotNil(t, w.out) 189 } 190 if e.file != "" { 191 assert.FileExists(t, tmp+e.file) 192 } 193 default: 194 t.Fatalf("unknown writer type: %T", w) 195 } 196 197 } 198 }) 199 } 200 } 201 202 func Test_newSBOMWriterDescription(t *testing.T) { 203 tests := []struct { 204 name string 205 path string 206 expected string 207 }{ 208 { 209 name: "expand home dir", 210 path: "~/place.txt", 211 expected: filepath.Join(homedir.Get(), "place.txt"), 212 }, 213 { 214 name: "passthrough other paths", 215 path: "/other/place.txt", 216 expected: "/other/place.txt", 217 }, 218 { 219 name: "no path", 220 path: "", 221 expected: "", 222 }, 223 } 224 for _, tt := range tests { 225 t.Run(tt.name, func(t *testing.T) { 226 o := newSBOMWriterDescription(dummyFormat("table"), tt.path) 227 assert.Equal(t, tt.expected, o.Path) 228 }) 229 } 230 }