github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/format/internal/testutil/snapshot.go (about) 1 package testutil 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/google/go-cmp/cmp" 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 11 "github.com/anchore/go-testutils" 12 "github.com/anchore/stereoscope/pkg/imagetest" 13 "github.com/anchore/syft/syft/sbom" 14 ) 15 16 type imageCfg struct { 17 fromSnapshot bool 18 } 19 20 type ImageOption func(cfg *imageCfg) 21 22 func FromSnapshot() ImageOption { 23 return func(cfg *imageCfg) { 24 cfg.fromSnapshot = true 25 } 26 } 27 28 type EncoderSnapshotTestConfig struct { 29 Subject sbom.SBOM 30 Format sbom.FormatEncoder 31 UpdateSnapshot bool 32 PersistRedactionsInSnapshot bool 33 IsJSON bool 34 Redactor Redactor 35 } 36 37 func AssertEncoderAgainstGoldenSnapshot(t *testing.T, cfg EncoderSnapshotTestConfig) { 38 t.Helper() 39 var buffer bytes.Buffer 40 41 err := cfg.Format.Encode(&buffer, cfg.Subject) 42 assert.NoError(t, err) 43 actual := buffer.Bytes() 44 45 if cfg.UpdateSnapshot && !cfg.PersistRedactionsInSnapshot { 46 // replace the expected snapshot contents with the current (unredacted) encoder contents 47 testutils.UpdateGoldenFileContents(t, actual) 48 return 49 } 50 51 if cfg.Redactor != nil { 52 actual = cfg.Redactor.Redact(actual) 53 } 54 55 if cfg.UpdateSnapshot && cfg.PersistRedactionsInSnapshot { 56 // replace the expected snapshot contents with the current (redacted) encoder contents 57 testutils.UpdateGoldenFileContents(t, actual) 58 return 59 } 60 61 var expected []byte 62 if cfg.Redactor != nil { 63 expected = cfg.Redactor.Redact(testutils.GetGoldenFileContents(t)) 64 } else { 65 expected = testutils.GetGoldenFileContents(t) 66 } 67 68 if cfg.IsJSON { 69 require.JSONEq(t, string(expected), string(actual)) 70 } else { 71 requireEqual(t, expected, actual) 72 } 73 } 74 75 func requireEqual(t *testing.T, expected any, actual any) { 76 if diff := cmp.Diff(expected, actual); diff != "" { 77 // uncomment to debug 78 // t.Logf("expected: %s", expected) 79 // t.Logf("actual: %s", actual) 80 t.Fatalf("mismatched output: %s", diff) 81 } 82 } 83 84 type ImageSnapshotTestConfig struct { 85 Image string 86 UpdateImageSnapshot bool 87 } 88 89 func AssertEncoderAgainstGoldenImageSnapshot(t *testing.T, imgCfg ImageSnapshotTestConfig, cfg EncoderSnapshotTestConfig) { 90 if imgCfg.UpdateImageSnapshot { 91 defer changeToDirectoryWithGoldenFixture(t, imgCfg.Image)() 92 93 // grab the latest image contents and persist 94 imagetest.UpdateGoldenFixtureImage(t, imgCfg.Image) 95 } 96 97 AssertEncoderAgainstGoldenSnapshot(t, cfg) 98 }