github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/internal/inspectimage/writer/structured_format_test.go (about) 1 package writer_test 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "testing" 8 9 "github.com/heroku/color" 10 "github.com/sclevine/spec" 11 "github.com/sclevine/spec/report" 12 13 "github.com/buildpacks/lifecycle/buildpack" 14 15 "github.com/buildpacks/pack/internal/config" 16 "github.com/buildpacks/pack/internal/inspectimage" 17 "github.com/buildpacks/pack/internal/inspectimage/writer" 18 "github.com/buildpacks/pack/pkg/client" 19 "github.com/buildpacks/pack/pkg/dist" 20 "github.com/buildpacks/pack/pkg/logging" 21 h "github.com/buildpacks/pack/testhelpers" 22 ) 23 24 func TestStructuredFormat(t *testing.T) { 25 color.Disable(true) 26 defer color.Disable(false) 27 spec.Run(t, "StructuredFormat Writer", testStructuredFormat, spec.Parallel(), spec.Report(report.Terminal{})) 28 } 29 30 func testStructuredFormat(t *testing.T, when spec.G, it spec.S) { 31 var ( 32 assert = h.NewAssertionManager(t) 33 outBuf bytes.Buffer 34 35 remoteInfo *client.ImageInfo 36 localInfo *client.ImageInfo 37 remoteWithExtensionInfo *client.ImageInfo 38 localWithExtensionInfo *client.ImageInfo 39 localInfoWithExtensionDisplay *inspectimage.InfoDisplay 40 ) 41 42 when("Print", func() { 43 it.Before(func() { 44 remoteInfo = &client.ImageInfo{} 45 localInfo = &client.ImageInfo{} 46 remoteWithExtensionInfo = &client.ImageInfo{} 47 localWithExtensionInfo = &client.ImageInfo{ 48 StackID: "test.stack.id.local", 49 Buildpacks: []buildpack.GroupElement{ 50 {ID: "test.bp.one.local", Version: "1.0.0", Homepage: "https://some-homepage-one"}, 51 }, 52 Extensions: []buildpack.GroupElement{ 53 {ID: "test.bp.one.local", Version: "1.0.0", Homepage: "https://some-homepage-one"}, 54 }, 55 } 56 localInfoWithExtensionDisplay = &inspectimage.InfoDisplay{ 57 StackID: "test.stack.id.local", 58 Buildpacks: []dist.ModuleInfo{ 59 { 60 ID: "test.bp.one.local", 61 Version: "1.0.0", 62 Homepage: "https://some-homepage-one", 63 }, 64 }, 65 Extensions: []dist.ModuleInfo{ 66 { 67 ID: "test.bp.one.local", 68 Version: "1.0.0", 69 Homepage: "https://some-homepage-one", 70 }, 71 }, 72 } 73 outBuf = bytes.Buffer{} 74 }) 75 76 // Just test error cases, all error-free cases will be tested in JSON, TOML, and YAML subclasses. 77 when("failure cases", func() { 78 when("both info objects are nil", func() { 79 it("displays a 'missing image' error message'", func() { 80 sharedImageInfo := inspectimage.GeneralInfo{ 81 Name: "missing-image", 82 RunImageMirrors: []config.RunImage{}, 83 } 84 85 structuredWriter := writer.StructuredFormat{ 86 MarshalFunc: testMarshalFunc, 87 } 88 89 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 90 err := structuredWriter.Print(logger, sharedImageInfo, nil, nil, nil, nil) 91 assert.ErrorWithMessage(err, fmt.Sprintf("unable to find image '%s' locally or remotely", "missing-image")) 92 }) 93 }) 94 when("a localErr is passed to Print", func() { 95 it("still prints remote information", func() { 96 sharedImageInfo := inspectimage.GeneralInfo{ 97 Name: "localErr-image", 98 RunImageMirrors: []config.RunImage{}, 99 } 100 structuredWriter := writer.StructuredFormat{ 101 MarshalFunc: testMarshalFunc, 102 } 103 104 localErr := errors.New("a local error occurred") 105 106 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 107 err := structuredWriter.Print(logger, sharedImageInfo, nil, remoteInfo, localErr, nil) 108 assert.ErrorWithMessage(err, "preparing output for 'localErr-image': a local error occurred") 109 }) 110 }) 111 112 when("a localWithExtension is passed to Print", func() { 113 it("prints localWithExtension information", func() { 114 var marshalInput interface{} 115 sharedImageInfo := inspectimage.GeneralInfo{ 116 Name: "localExtension-image", 117 RunImageMirrors: []config.RunImage{}, 118 } 119 structuredWriter := writer.StructuredFormat{ 120 MarshalFunc: func(i interface{}) ([]byte, error) { 121 marshalInput = i 122 return []byte("marshalled"), nil 123 }, 124 } 125 126 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 127 err := structuredWriter.Print(logger, sharedImageInfo, localWithExtensionInfo, nil, nil, nil) 128 assert.Nil(err) 129 assert.Equal(marshalInput, inspectimage.InspectOutput{ 130 ImageName: "localExtension-image", 131 Local: localInfoWithExtensionDisplay, 132 }) 133 }) 134 }) 135 136 when("a localErr is passed to Print", func() { 137 it("still prints remote information", func() { 138 sharedImageInfo := inspectimage.GeneralInfo{ 139 Name: "localErr-image", 140 RunImageMirrors: []config.RunImage{}, 141 } 142 structuredWriter := writer.StructuredFormat{ 143 MarshalFunc: testMarshalFunc, 144 } 145 146 localErr := errors.New("a local error occurred") 147 148 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 149 err := structuredWriter.Print(logger, sharedImageInfo, nil, remoteWithExtensionInfo, localErr, nil) 150 assert.ErrorWithMessage(err, "preparing output for 'localErr-image': a local error occurred") 151 }) 152 }) 153 154 when("a remoteErr is passed to print", func() { 155 it("still prints local information", func() { 156 sharedImageInfo := inspectimage.GeneralInfo{ 157 Name: "remoteErr-image", 158 RunImageMirrors: []config.RunImage{}, 159 } 160 structuredWriter := writer.StructuredFormat{ 161 MarshalFunc: testMarshalFunc, 162 } 163 164 remoteErr := errors.New("a remote error occurred") 165 166 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 167 err := structuredWriter.Print(logger, sharedImageInfo, localInfo, nil, nil, remoteErr) 168 assert.ErrorWithMessage(err, "preparing output for 'remoteErr-image': a remote error occurred") 169 }) 170 }) 171 172 when("a remoteErr is passed to print", func() { 173 it("still prints local information", func() { 174 sharedImageInfo := inspectimage.GeneralInfo{ 175 Name: "remoteErr-image", 176 RunImageMirrors: []config.RunImage{}, 177 } 178 structuredWriter := writer.StructuredFormat{ 179 MarshalFunc: testMarshalFunc, 180 } 181 182 remoteErr := errors.New("a remote error occurred") 183 184 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 185 err := structuredWriter.Print(logger, sharedImageInfo, localWithExtensionInfo, nil, nil, remoteErr) 186 assert.ErrorWithMessage(err, "preparing output for 'remoteErr-image': a remote error occurred") 187 }) 188 }) 189 }) 190 }) 191 } 192 193 // 194 // testfunctions and helpers 195 // 196 197 func testMarshalFunc(i interface{}) ([]byte, error) { 198 return []byte("marshalled"), nil 199 }