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  }