github.com/sanposhiho/openapi2proto@v0.0.0-20230521044535-d1080a134e37/proto_test.go (about) 1 package openapi2proto_test 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "net/http" 7 "os" 8 "strings" 9 "testing" 10 11 "github.com/sanposhiho/openapi2proto" 12 "github.com/sanposhiho/openapi2proto/compiler" 13 "github.com/sanposhiho/openapi2proto/protobuf" 14 "github.com/pmezard/go-difflib/difflib" 15 ) 16 17 type genProtoTestCase struct { 18 options bool 19 fixturePath string 20 wantProto string 21 remoteFiles []string 22 wrapPrimitives bool 23 skipDeprecatedRpcs bool 24 addAutogeneratedComment bool 25 } 26 27 func testGenProto(t *testing.T, tests ...genProtoTestCase) { 28 t.Helper() 29 origin, _ := os.Getwd() 30 for _, test := range tests { 31 t.Run(test.fixturePath, func(t *testing.T) { 32 for _, remoteFile := range test.remoteFiles { 33 res, err := http.Get(remoteFile) 34 if err != nil || res.StatusCode != http.StatusOK { 35 t.Skip(`Remote file ` + remoteFile + ` is not available`) 36 } 37 } 38 39 var generated bytes.Buffer 40 var compilerOptions []compiler.Option 41 var encoderOptions []protobuf.Option 42 if test.options { 43 compilerOptions = append(compilerOptions, compiler.WithAnnotation(true)) 44 } 45 if test.wrapPrimitives { 46 compilerOptions = append(compilerOptions, compiler.WithWrapPrimitives(true)) 47 } 48 if test.skipDeprecatedRpcs { 49 compilerOptions = append(compilerOptions, compiler.WithSkipDeprecatedRpcs(true)) 50 } 51 if test.addAutogeneratedComment { 52 encoderOptions = append(encoderOptions, protobuf.WithAutogeneratedComment(true)) 53 } 54 if err := openapi2proto.Transpile(&generated, test.fixturePath, openapi2proto.WithCompilerOptions(compilerOptions...), openapi2proto.WithEncoderOptions(encoderOptions...)); err != nil { 55 t.Errorf(`failed to transpile: %s`, err) 56 return 57 } 58 59 os.Chdir(origin) 60 // if test.wantProto is empty, guess file name from the original 61 // fixture path 62 wantProtoFile := test.wantProto 63 if wantProtoFile == "" { 64 i := strings.LastIndexByte(test.fixturePath, '.') 65 if i > -1 { 66 wantProtoFile = test.fixturePath[:i] + `.proto` 67 } else { 68 t.Fatalf(`unable to guess proto file name from %s`, test.fixturePath) 69 } 70 } 71 want, err := ioutil.ReadFile(wantProtoFile) 72 if err != nil { 73 t.Fatal("unable to open test fixture: ", err) 74 } 75 76 if string(want) != generated.String() { 77 diff := difflib.UnifiedDiff{ 78 A: difflib.SplitLines(string(want)), 79 B: difflib.SplitLines(generated.String()), 80 FromFile: wantProtoFile, 81 ToFile: "Generated", 82 Context: 3, 83 } 84 text, _ := difflib.GetUnifiedDiffString(diff) 85 t.Errorf("testYaml (%s) differences:\n%s", 86 test.fixturePath, text) 87 } 88 }) 89 } 90 } 91 92 func TestNetwork(t *testing.T) { 93 testGenProto(t, genProtoTestCase{ 94 fixturePath: "fixtures/petstore/swagger.yaml", 95 remoteFiles: []string{ 96 "https://raw.githubusercontent.com/NYTimes/openapi2proto/master/fixtures/petstore/Pet.yaml", 97 }, 98 }) 99 } 100 101 func TestGenerateProto(t *testing.T) { 102 tests := []genProtoTestCase{ 103 { 104 fixturePath: "fixtures/cats.yaml", 105 }, 106 { 107 fixturePath: "fixtures/catsanddogs.yaml", 108 }, 109 { 110 fixturePath: "fixtures/semantic_api.json", 111 }, 112 { 113 fixturePath: "fixtures/semantic_api.yaml", 114 }, 115 { 116 fixturePath: "fixtures/most_popular.json", 117 }, 118 { 119 fixturePath: "fixtures/spec.yaml", 120 }, 121 { 122 fixturePath: "fixtures/spec.json", 123 }, 124 { 125 options: true, 126 fixturePath: "fixtures/semantic_api.json", 127 wantProto: "fixtures/semantic_api-options.proto", 128 }, 129 { 130 options: true, 131 fixturePath: "fixtures/most_popular.json", 132 wantProto: "fixtures/most_popular-options.proto", 133 }, 134 { 135 options: true, 136 fixturePath: "fixtures/spec.yaml", 137 wantProto: "fixtures/spec-options.proto", 138 }, 139 { 140 options: true, 141 fixturePath: "fixtures/spec.json", 142 wantProto: "fixtures/spec-options.proto", 143 }, 144 145 { 146 fixturePath: "fixtures/includes_query.json", 147 }, 148 { 149 fixturePath: "fixtures/lowercase_def.json", 150 }, 151 { 152 fixturePath: "fixtures/missing_type.json", 153 }, 154 { 155 fixturePath: "fixtures/kubernetes.json", 156 }, 157 { 158 fixturePath: "fixtures/accountv1-0.json", 159 }, 160 { 161 fixturePath: "fixtures/refs.json", 162 }, 163 { 164 fixturePath: "fixtures/refs.yaml", 165 }, 166 { 167 fixturePath: "fixtures/integers.yaml", 168 }, 169 { 170 wrapPrimitives: true, 171 fixturePath: "fixtures/integers_required.yaml", 172 }, 173 { 174 fixturePath: "fixtures/global_options.yaml", 175 }, 176 { 177 fixturePath: "fixtures/naming_conversion.yaml", 178 }, 179 { 180 options: true, 181 fixturePath: "fixtures/custom_options.yaml", 182 }, 183 { 184 fixturePath: "fixtures/string_proto_tag.yaml", 185 }, 186 { 187 skipDeprecatedRpcs: true, 188 fixturePath: "fixtures/skip_deprecated_rpcs.yaml", 189 }, 190 { 191 addAutogeneratedComment: true, 192 fixturePath: "fixtures/add_autogenerated_comment.yaml", 193 }, 194 { 195 fixturePath: "fixtures/global_responses.yaml", 196 }, 197 } 198 testGenProto(t, tests...) 199 }