this repo has no description
at master 153 lines 3.7 kB view raw
1// Copyright 2019 CUE Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package openapi_test 16 17import ( 18 "bytes" 19 "io/fs" 20 "os" 21 "path" 22 "path/filepath" 23 "strings" 24 "testing" 25 26 "github.com/go-quicktest/qt" 27 "github.com/google/go-cmp/cmp" 28 "golang.org/x/tools/txtar" 29 30 "cuelang.org/go/cue" 31 "cuelang.org/go/cue/ast" 32 "cuelang.org/go/cue/cuecontext" 33 "cuelang.org/go/cue/errors" 34 "cuelang.org/go/cue/format" 35 "cuelang.org/go/encoding/json" 36 "cuelang.org/go/encoding/openapi" 37 "cuelang.org/go/encoding/yaml" 38 "cuelang.org/go/internal" 39 "cuelang.org/go/internal/cuetest" 40) 41 42// TestDecode reads the testdata/script/*.txtar files, converts the 43// contained JSON (or YAML) schema to CUE and compares it against the 44// output. 45// 46// The first .json or .yaml file in the txtar archive (with no / in 47// the name) is used as the input. The first .cue file in the archive 48// (with no / in the name) is used as the expected output. 49// 50// Set CUE_UPDATE=1 to update test files with the corresponding output. 51func TestDecode(t *testing.T) { 52 t.Parallel() 53 err := filepath.WalkDir("testdata/script", func(fullpath string, entry fs.DirEntry, err error) error { 54 if err != nil { 55 return err 56 } 57 if !strings.HasSuffix(fullpath, ".txtar") { 58 return nil 59 } 60 61 t.Run(fullpath, func(t *testing.T) { 62 t.Parallel() 63 a, err := txtar.ParseFile(fullpath) 64 if err != nil { 65 t.Fatal(err) 66 } 67 68 cfg := &openapi.Config{PkgName: "foo"} 69 70 var inFile *ast.File 71 var out, errout []byte 72 outIndex := -1 73 74 for i, f := range a.Files { 75 if strings.Contains(f.Name, "/") { 76 continue 77 } 78 switch path.Ext(f.Name) { 79 case ".json": 80 if inFile == nil { 81 var inExpr ast.Expr 82 inExpr, err = json.Extract(f.Name, f.Data) 83 inFile = internal.ToFile(inExpr) 84 } 85 case ".yaml": 86 if inFile == nil { 87 inFile, err = yaml.Extract(f.Name, f.Data) 88 } 89 case ".cue": 90 if out == nil { 91 out = f.Data 92 outIndex = i 93 } 94 case ".err": 95 if errout == nil { 96 errout = f.Data 97 } 98 } 99 } 100 if err != nil { 101 t.Fatal(err) 102 } 103 ctx := cuecontext.New() 104 in := ctx.BuildFile(inFile) 105 if err := in.Err(); err != nil { 106 t.Fatal(err) 107 } 108 109 gotFile, err := openapi.Extract(in, cfg) 110 if err != nil && errout == nil { 111 t.Fatal(errors.Details(err, nil)) 112 } 113 got := []byte(nil) 114 if err != nil { 115 got = []byte(err.Error()) 116 } 117 if diff := cmp.Diff(errout, got); diff != "" { 118 t.Error(diff) 119 } 120 121 if gotFile != nil { 122 // verify the generated CUE. 123 v := ctx.BuildFile(gotFile, cue.Filename(fullpath)) 124 if err := v.Err(); err != nil { 125 t.Fatal(errors.Details(err, nil)) 126 } 127 128 b, err := format.Node(gotFile, format.Simplify()) 129 if err != nil { 130 t.Fatal(err) 131 } 132 133 b = bytes.TrimSpace(b) 134 out = bytes.TrimSpace(out) 135 136 if diff := cmp.Diff(b, out); diff != "" { 137 if cuetest.UpdateGoldenFiles { 138 a.Files[outIndex].Data = b 139 b = txtar.Format(a) 140 err = os.WriteFile(fullpath, b, 0666) 141 if err != nil { 142 t.Fatal(err) 143 } 144 return 145 } 146 t.Error(cmp.Diff(string(out), string(b))) 147 } 148 } 149 }) 150 return nil 151 }) 152 qt.Assert(t, qt.IsNil(err)) 153}