|
4 | 4 | package libopenapi |
5 | 5 |
|
6 | 6 | import ( |
| 7 | + "reflect" |
| 8 | + "sync" |
7 | 9 | "testing" |
| 10 | + "unsafe" |
8 | 11 |
|
| 12 | + "github.com/pb33f/libopenapi/datamodel/low" |
| 13 | + lowArazzo "github.com/pb33f/libopenapi/datamodel/low/arazzo" |
9 | 14 | "github.com/stretchr/testify/assert" |
10 | 15 | "github.com/stretchr/testify/require" |
| 16 | + "go.yaml.in/yaml/v4" |
11 | 17 | ) |
12 | 18 |
|
| 19 | +//go:linkname arazzoLowBuildModelFieldCache github.com/pb33f/libopenapi/datamodel/low.buildModelFieldCache |
| 20 | +var arazzoLowBuildModelFieldCache sync.Map |
| 21 | + |
13 | 22 | func TestNewArazzoDocument_ValidFull(t *testing.T) { |
14 | 23 | yml := []byte(`arazzo: 1.0.1 |
15 | 24 | info: |
@@ -177,6 +186,67 @@ func TestNewArazzoDocument_ArrayYAML(t *testing.T) { |
177 | 186 | assert.Contains(t, err.Error(), "expected YAML mapping") |
178 | 187 | } |
179 | 188 |
|
| 189 | +func TestNewArazzoDocument_BuildModelError(t *testing.T) { |
| 190 | + yml := []byte(`arazzo: 1.0.1 |
| 191 | +`) |
| 192 | + var root yaml.Node |
| 193 | + require.NoError(t, yaml.Unmarshal(yml, &root)) |
| 194 | + |
| 195 | + var seed lowArazzo.Arazzo |
| 196 | + require.NoError(t, low.BuildModel(root.Content[0], &seed)) |
| 197 | + |
| 198 | + arazzoType := reflect.TypeOf(lowArazzo.Arazzo{}) |
| 199 | + original, ok := arazzoLowBuildModelFieldCache.Load(arazzoType) |
| 200 | + require.True(t, ok) |
| 201 | + |
| 202 | + origType := reflect.TypeOf(original) |
| 203 | + elemType := origType.Elem() |
| 204 | + replacement := reflect.MakeSlice(origType, 1, 1) |
| 205 | + elem := reflect.New(elemType).Elem() |
| 206 | + setArazzoUnexportedField(elem.FieldByName("lookupKey"), "arazzo") |
| 207 | + setArazzoUnexportedField(elem.FieldByName("index"), 0) |
| 208 | + setArazzoUnexportedField(elem.FieldByName("kind"), reflect.Bool) |
| 209 | + replacement.Index(0).Set(elem) |
| 210 | + |
| 211 | + arazzoLowBuildModelFieldCache.Store(arazzoType, replacement.Interface()) |
| 212 | + t.Cleanup(func() { |
| 213 | + arazzoLowBuildModelFieldCache.Store(arazzoType, original) |
| 214 | + }) |
| 215 | + |
| 216 | + doc, err := NewArazzoDocument(yml) |
| 217 | + assert.Error(t, err) |
| 218 | + assert.Nil(t, doc) |
| 219 | + assert.Contains(t, err.Error(), "failed to build low-level model") |
| 220 | + assert.Contains(t, err.Error(), "unsupported type") |
| 221 | +} |
| 222 | + |
| 223 | +func TestNewArazzoDocument_BuildError(t *testing.T) { |
| 224 | + yml := []byte(`arazzo: 1.0.1 |
| 225 | +info: |
| 226 | + title: Build Error |
| 227 | + version: 1.0.0 |
| 228 | +sourceDescriptions: |
| 229 | + - name: api |
| 230 | + url: https://example.com/openapi.yaml |
| 231 | +workflows: |
| 232 | + - workflowId: wf1 |
| 233 | + steps: |
| 234 | + - stepId: s1 |
| 235 | + operationId: op1 |
| 236 | +components: |
| 237 | + failureActions: |
| 238 | + badRetry: |
| 239 | + name: retry |
| 240 | + type: retry |
| 241 | + retryAfter: nope |
| 242 | +`) |
| 243 | + doc, err := NewArazzoDocument(yml) |
| 244 | + assert.Error(t, err) |
| 245 | + assert.Nil(t, doc) |
| 246 | + assert.Contains(t, err.Error(), "failed to build arazzo document") |
| 247 | + assert.Contains(t, err.Error(), "invalid retryAfter") |
| 248 | +} |
| 249 | + |
180 | 250 | func TestNewArazzoDocument_MultipleWorkflows(t *testing.T) { |
181 | 251 | yml := []byte(`arazzo: 1.0.1 |
182 | 252 | info: |
@@ -467,3 +537,7 @@ workflows: |
467 | 537 | assert.Len(t, doc2.Workflows, len(doc1.Workflows)) |
468 | 538 | assert.Equal(t, doc1.Workflows[0].WorkflowId, doc2.Workflows[0].WorkflowId) |
469 | 539 | } |
| 540 | + |
| 541 | +func setArazzoUnexportedField(field reflect.Value, value any) { |
| 542 | + reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Set(reflect.ValueOf(value)) |
| 543 | +} |
0 commit comments