Update go dependencies

This commit is contained in:
Manuel de Brito Fontes 2018-05-26 11:27:53 -04:00 committed by Manuel Alejandro de Brito Fontes
parent 15ffb51394
commit bb4d483837
No known key found for this signature in database
GPG key ID: 786136016A8BA02A
1621 changed files with 86368 additions and 284392 deletions

View file

@ -1,3 +1,5 @@
# IntelliJ IDEA
.idea
# Eclipse
.checkstyle
.project
@ -5,6 +7,10 @@
# Swift
.build
Packages
# Node
node_modules
package-lock.json
bundle.json
# vi
*.swp
# vscode
@ -12,3 +18,4 @@ Packages
.DS_Store
*~
Package.resolved
extensions/sample/generated

View file

@ -32,13 +32,16 @@ script:
- pushd plugins/gnostic-go-generator/examples/v2.0/bookstore
- make test
- popd
- pushd plugins/gnostic-go-generator/examples/v2.0/sample
- make test
- popd
- pushd plugins/gnostic-go-generator/examples/v3.0/bookstore
- make test
- popd
- export PATH=.:$HOME/local/bin:$PATH
- export LD_LIBRARY_PATH=$HOME/local/lib
- pushd plugins/gnostic-swift-generator
- make
- make install
- cd examples/bookstore
- make
- .build/debug/Server &

View file

@ -22,6 +22,7 @@ protoc \
OpenAPIv2/OpenAPIv2.proto
protoc \
-I.:$GOPATH/src \
--go_out=:. \
plugins/plugin.proto

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,5 @@
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: OpenAPIv2/OpenAPIv2.proto
// DO NOT EDIT!
/*
Package openapi_v2 is a generated protocol buffer package.
@ -4257,7 +4256,7 @@ func init() { proto.RegisterFile("OpenAPIv2/OpenAPIv2.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 3129 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x3b, 0x4b, 0x73, 0x1c, 0x57,
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3b, 0x4b, 0x73, 0x1c, 0x57,
0xd5, 0xf3, 0x7e, 0x1c, 0x69, 0x46, 0xa3, 0x96, 0x2c, 0xb7, 0x24, 0xc7, 0x71, 0xe4, 0x3c, 0x6c,
0xe7, 0xb3, 0x9c, 0x4f, 0x29, 0x48, 0x05, 0x2a, 0x05, 0xf2, 0xab, 0xc6, 0xc4, 0x44, 0x4a, 0xcb,
0x0e, 0x09, 0x04, 0xba, 0xae, 0x66, 0xee, 0x48, 0x9d, 0x74, 0xf7, 0x6d, 0x77, 0xf7, 0xc8, 0x1a,

View file

@ -61,8 +61,14 @@ buffers. Pre-generated versions of these files are in the OpenAPIv2 directory.
3. [Optional] Generate Protocol Buffer support code.
A pre-generated version of this file is checked into the OpenAPIv2 directory.
This step requires a local installation of protoc, the Protocol Buffer Compiler.
This step requires a local installation of protoc, the Protocol Buffer Compiler,
and the Go protoc plugin.
You can get protoc [here](https://github.com/google/protobuf).
You can install the plugin with this command:
go get -u github.com/golang/protobuf/protoc-gen-go
Then use the following to recompile the Gnostic Protocol Buffer models:
./COMPILE-PROTOS.sh
@ -74,7 +80,7 @@ You can get protoc [here](https://github.com/google/protobuf).
5. Run **gnostic**. This will create a file in the current directory named "petstore.pb" that contains a binary
Protocol Buffer description of a sample API.
gnostic --pb-out=. examples/petstore.json
gnostic --pb-out=. examples/v2.0/json/petstore.json
6. You can also compile files that you specify with a URL. Here's another way to compile the previous
example. This time we're creating "petstore.text", which contains a textual representation of the
@ -92,7 +98,7 @@ that reports some basic information about an API. The "-" causes the plugin to
write its output to stdout.
go install github.com/googleapis/gnostic/plugins/gnostic-go-sample
gnostic examples/petstore.json --go-sample-out=-
gnostic examples/v2.0/json/petstore.json --go-sample-out=-
## Copyright

View file

@ -110,7 +110,9 @@ func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
if err != nil {
return nil, err
}
infoCache[filename] = info
if len(filename) > 0 {
infoCache[filename] = info
}
return info, nil
}

View file

@ -1,6 +1,5 @@
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: extension.proto
// DO NOT EDIT!
/*
Package openapiextension_v1 is a generated protocol buffer package.
@ -78,7 +77,7 @@ func (m *Version) GetSuffix() string {
// An encoded Request is written to the ExtensionHandler's stdin.
type ExtensionHandlerRequest struct {
// The OpenAPI descriptions that were explicitly listed on the command line.
// The specifications will appear in the order they are specified to openapic.
// The specifications will appear in the order they are specified to gnostic.
Wrapper *Wrapper `protobuf:"bytes,1,opt,name=wrapper" json:"wrapper,omitempty"`
// The version number of openapi compiler.
CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"`
@ -192,28 +191,28 @@ func init() {
func init() { proto.RegisterFile("extension.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 355 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0xf3, 0x40,
0x1c, 0xc4, 0x49, 0xdf, 0xf2, 0x64, 0x1f, 0xb4, 0xb2, 0x16, 0x8d, 0xe2, 0xa1, 0x04, 0x84, 0x22,
0xb8, 0xa5, 0x0a, 0xde, 0x5b, 0x28, 0xea, 0xc5, 0x96, 0x3d, 0xd4, 0x9b, 0x65, 0x9b, 0xfe, 0xdb,
0x46, 0x92, 0xdd, 0x75, 0xf3, 0x62, 0xfb, 0x55, 0x3c, 0xfa, 0x49, 0x25, 0xbb, 0xd9, 0x7a, 0x50,
0x6f, 0x99, 0x1f, 0x93, 0xfc, 0x67, 0x26, 0xa8, 0x0d, 0xdb, 0x0c, 0x78, 0x1a, 0x09, 0x4e, 0xa4,
0x12, 0x99, 0xc0, 0xc7, 0x42, 0x02, 0x67, 0x32, 0xfa, 0xe6, 0xc5, 0xe0, 0xfc, 0x6c, 0x2d, 0xc4,
0x3a, 0x86, 0xbe, 0xb6, 0x2c, 0xf2, 0x55, 0x9f, 0xf1, 0x9d, 0xf1, 0x07, 0x21, 0x72, 0x67, 0xa0,
0x4a, 0x23, 0xee, 0xa0, 0x66, 0xc2, 0x5e, 0x85, 0xf2, 0x9d, 0xae, 0xd3, 0x6b, 0x52, 0x23, 0x34,
0x8d, 0xb8, 0x50, 0x7e, 0xad, 0xa2, 0xa5, 0x28, 0xa9, 0x64, 0x59, 0xb8, 0xf1, 0xeb, 0x86, 0x6a,
0x81, 0x4f, 0x50, 0x2b, 0xcd, 0x57, 0xab, 0x68, 0xeb, 0x37, 0xba, 0x4e, 0xcf, 0xa3, 0x95, 0x0a,
0x3e, 0x1c, 0x74, 0x3a, 0xb6, 0x81, 0x1e, 0x18, 0x5f, 0xc6, 0xa0, 0x28, 0xbc, 0xe5, 0x90, 0x66,
0xf8, 0x0e, 0xb9, 0xef, 0x8a, 0x49, 0x09, 0xe6, 0xee, 0xff, 0x9b, 0x0b, 0xf2, 0x4b, 0x05, 0xf2,
0x6c, 0x3c, 0xd4, 0x9a, 0xf1, 0x3d, 0x3a, 0x0a, 0x45, 0x22, 0xa3, 0x18, 0xd4, 0xbc, 0x30, 0x0d,
0x74, 0x98, 0xbf, 0x3e, 0x50, 0xb5, 0xa4, 0x6d, 0xfb, 0x56, 0x05, 0x82, 0x02, 0xf9, 0x3f, 0xb3,
0xa5, 0x52, 0xf0, 0x14, 0xb0, 0x8f, 0xdc, 0x8d, 0x46, 0x4b, 0x1d, 0xee, 0x1f, 0xb5, 0xb2, 0x1c,
0x00, 0x94, 0xd2, 0xb3, 0xd4, 0x7b, 0x1e, 0x35, 0x02, 0x5f, 0xa1, 0x66, 0xc1, 0xe2, 0x1c, 0xaa,
0x24, 0x1d, 0x62, 0x86, 0x27, 0x76, 0x78, 0x32, 0xe4, 0x3b, 0x6a, 0x2c, 0xc1, 0x0b, 0x72, 0xab,
0x52, 0xe5, 0x19, 0x5b, 0xc1, 0xd1, 0xc3, 0x59, 0x89, 0x2f, 0xd1, 0xe1, 0xbe, 0xc5, 0x9c, 0xb3,
0x04, 0xf4, 0x6f, 0xf0, 0xe8, 0xc1, 0x9e, 0x3e, 0xb1, 0x04, 0x30, 0x46, 0x8d, 0x1d, 0x4b, 0x62,
0x7d, 0xd6, 0xa3, 0xfa, 0x79, 0x74, 0x8d, 0xda, 0x42, 0xad, 0xed, 0x16, 0x21, 0x29, 0x06, 0x23,
0x3c, 0x91, 0xc0, 0x87, 0xd3, 0xc7, 0x7d, 0xdf, 0xd9, 0x60, 0xea, 0x7c, 0xd6, 0xea, 0x93, 0xe1,
0x78, 0xd1, 0xd2, 0x19, 0x6f, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x56, 0x40, 0x4d, 0x52,
0x02, 0x00, 0x00,
// 357 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0xc3, 0x40,
0x18, 0x84, 0x49, 0xbf, 0x62, 0x56, 0x6c, 0x65, 0x2d, 0x1a, 0xc5, 0x43, 0x09, 0x08, 0x45, 0x64,
0x4b, 0x15, 0xbc, 0xb7, 0x50, 0xd4, 0x8b, 0x2d, 0x7b, 0xa8, 0x37, 0xcb, 0x36, 0x7d, 0x9b, 0x46,
0x92, 0xdd, 0x75, 0xf3, 0x61, 0xfb, 0x57, 0x3c, 0xfa, 0x4b, 0x25, 0xbb, 0x49, 0x3d, 0xa8, 0xb7,
0xcc, 0xc3, 0x24, 0xef, 0xcc, 0x04, 0x75, 0x60, 0x9b, 0x02, 0x4f, 0x42, 0xc1, 0x89, 0x54, 0x22,
0x15, 0xf8, 0x44, 0x48, 0xe0, 0x4c, 0x86, 0x3f, 0x3c, 0x1f, 0x5e, 0x9c, 0x07, 0x42, 0x04, 0x11,
0x0c, 0xb4, 0x65, 0x99, 0xad, 0x07, 0x8c, 0xef, 0x8c, 0xdf, 0xf3, 0x91, 0x3d, 0x07, 0x55, 0x18,
0x71, 0x17, 0x35, 0x63, 0xf6, 0x26, 0x94, 0x6b, 0xf5, 0xac, 0x7e, 0x93, 0x1a, 0xa1, 0x69, 0xc8,
0x85, 0x72, 0x6b, 0x25, 0x2d, 0x44, 0x41, 0x25, 0x4b, 0xfd, 0x8d, 0x5b, 0x37, 0x54, 0x0b, 0x7c,
0x8a, 0x5a, 0x49, 0xb6, 0x5e, 0x87, 0x5b, 0xb7, 0xd1, 0xb3, 0xfa, 0x0e, 0x2d, 0x95, 0xf7, 0x69,
0xa1, 0xb3, 0x49, 0x15, 0xe8, 0x91, 0xf1, 0x55, 0x04, 0x8a, 0xc2, 0x7b, 0x06, 0x49, 0x8a, 0xef,
0x91, 0xfd, 0xa1, 0x98, 0x94, 0x60, 0xee, 0x1e, 0xde, 0x5e, 0x92, 0x3f, 0x2a, 0x90, 0x17, 0xe3,
0xa1, 0x95, 0x19, 0x3f, 0xa0, 0x63, 0x5f, 0xc4, 0x32, 0x8c, 0x40, 0x2d, 0x72, 0xd3, 0x40, 0x87,
0xf9, 0xef, 0x03, 0x65, 0x4b, 0xda, 0xa9, 0xde, 0x2a, 0x81, 0x97, 0x23, 0xf7, 0x77, 0xb6, 0x44,
0x0a, 0x9e, 0x00, 0x76, 0x91, 0xbd, 0xd1, 0x68, 0xa5, 0xc3, 0x1d, 0xd0, 0x4a, 0x16, 0x03, 0x80,
0x52, 0x7a, 0x96, 0x7a, 0xdf, 0xa1, 0x46, 0xe0, 0x6b, 0xd4, 0xcc, 0x59, 0x94, 0x41, 0x99, 0xa4,
0x4b, 0xcc, 0xf0, 0xa4, 0x1a, 0x9e, 0x8c, 0xf8, 0x8e, 0x1a, 0x8b, 0xf7, 0x8a, 0xec, 0xb2, 0x54,
0x71, 0xa6, 0xaa, 0x60, 0xe9, 0xe1, 0x2a, 0x89, 0xaf, 0x50, 0x7b, 0xdf, 0x62, 0xc1, 0x59, 0x0c,
0xfa, 0x37, 0x38, 0xf4, 0x68, 0x4f, 0x9f, 0x59, 0x0c, 0x18, 0xa3, 0xc6, 0x8e, 0xc5, 0x91, 0x3e,
0xeb, 0x50, 0xfd, 0x3c, 0xbe, 0x41, 0x6d, 0xa1, 0x02, 0x12, 0x70, 0x91, 0xa4, 0xa1, 0x4f, 0xf2,
0xe1, 0x18, 0x4f, 0x25, 0xf0, 0xd1, 0xec, 0x69, 0x5f, 0x77, 0x3e, 0x9c, 0x59, 0x5f, 0xb5, 0xfa,
0x74, 0x34, 0x59, 0xb6, 0x74, 0xc4, 0xbb, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x84, 0x5c, 0x6b,
0x80, 0x51, 0x02, 0x00, 0x00,
}

View file

@ -29,7 +29,7 @@ option java_multiple_files = true;
option java_outer_classname = "OpenAPIExtensionV1";
// The Java package name must be proto package name with proper prefix.
option java_package = "org.openapic.v1";
option java_package = "org.gnostic.v1";
// A reasonable prefix for the Objective-C symbols generated from the package.
// It should at a minimum be 3 characters long, all uppercase, and convention
@ -53,7 +53,7 @@ message Version {
message ExtensionHandlerRequest {
// The OpenAPI descriptions that were explicitly listed on the command line.
// The specifications will appear in the order they are specified to openapic.
// The specifications will appear in the order they are specified to gnostic.
Wrapper wrapper = 1;
// The version number of openapi compiler.

View file

@ -41,6 +41,7 @@ import (
"path/filepath"
"regexp"
"strings"
"time"
"github.com/golang/protobuf/proto"
"github.com/googleapis/gnostic/OpenAPIv2"
@ -92,7 +93,7 @@ type pluginCall struct {
}
// Invokes a plugin.
func (p *pluginCall) perform(document proto.Message, sourceFormat int, sourceName string) error {
func (p *pluginCall) perform(document proto.Message, sourceFormat int, sourceName string, timePlugins bool) ([]*plugins.Message, error) {
if p.Name != "" {
request := &plugins.Request{}
@ -112,7 +113,7 @@ func (p *pluginCall) perform(document proto.Message, sourceFormat int, sourceNam
//
invocationRegex := regexp.MustCompile(`^([\w-_\/\.]+=[\w-_\/\.]+(,[\w-_\/\.]+=[\w-_\/\.]+)*:)?[^,:=]+$`)
if !invocationRegex.Match([]byte(p.Invocation)) {
return fmt.Errorf("Invalid invocation of %s: %s", executableName, invocation)
return nil, fmt.Errorf("Invalid invocation of %s: %s", executableName, invocation)
}
invocationParts := strings.Split(p.Invocation, ":")
@ -145,11 +146,21 @@ func (p *pluginCall) perform(document proto.Message, sourceFormat int, sourceNam
request.SourceName = sourceName
switch sourceFormat {
case SourceFormatOpenAPI2:
request.Openapi2 = document.(*openapi_v2.Document)
request.Surface, _ = surface.NewModelFromOpenAPI2(request.Openapi2)
request.AddModel("openapi.v2.Document", document)
// include experimental API surface model
surfaceModel, err := surface.NewModelFromOpenAPI2(document.(*openapi_v2.Document))
if err == nil {
request.AddModel("surface.v1.Model", surfaceModel)
}
case SourceFormatOpenAPI3:
request.Openapi3 = document.(*openapi_v3.Document)
request.Surface, _ = surface.NewModelFromOpenAPI3(request.Openapi3)
request.AddModel("openapi.v3.Document", document)
// include experimental API surface model
surfaceModel, err := surface.NewModelFromOpenAPI3(document.(*openapi_v3.Document))
if err == nil {
request.AddModel("surface.v1.Model", surfaceModel)
}
case SourceFormatDiscovery:
request.AddModel("discovery.v1.Document", document)
default:
}
@ -158,19 +169,27 @@ func (p *pluginCall) perform(document proto.Message, sourceFormat int, sourceNam
cmd := exec.Command(executableName, "-plugin")
cmd.Stdin = bytes.NewReader(requestBytes)
cmd.Stderr = os.Stderr
pluginStartTime := time.Now()
output, err := cmd.Output()
pluginElapsedTime := time.Since(pluginStartTime)
if timePlugins {
fmt.Printf("> %s (%s)\n", executableName, pluginElapsedTime)
}
if err != nil {
return err
return nil, err
}
response := &plugins.Response{}
err = proto.Unmarshal(output, response)
if err != nil {
return err
// Gnostic expects plugins to only write the
// response message to stdout. Be sure that
// any logging messages are written to stderr only.
return nil, errors.New("Invalid plugin response (plugins must write log messages to stderr, not stdout).")
}
plugins.HandleResponse(response, outputLocation)
return response.Messages, nil
}
return nil
return nil, nil
}
func isFile(path string) bool {
@ -233,10 +252,12 @@ type Gnostic struct {
yamlOutputPath string
jsonOutputPath string
errorOutputPath string
messageOutputPath string
resolveReferences bool
pluginCalls []*pluginCall
extensionHandlers []compiler.ExtensionHandler
sourceFormat int
timePlugins bool
}
// Initialize a structure to store global application state.
@ -244,20 +265,27 @@ func newGnostic() *Gnostic {
g := &Gnostic{}
// Option fields initialize to their default values.
g.usage = `
Usage: gnostic OPENAPI_SOURCE [OPTIONS]
OPENAPI_SOURCE is the filename or URL of an OpenAPI description to read.
Usage: gnostic SOURCE [OPTIONS]
SOURCE is the filename or URL of an API description.
Options:
--pb-out=PATH Write a binary proto to the specified location.
--text-out=PATH Write a text proto to the specified location.
--json-out=PATH Write a json API description to the specified location.
--yaml-out=PATH Write a yaml API description to the specified location.
--errors-out=PATH Write compilation errors to the specified location.
--PLUGIN-out=PATH Run the plugin named gnostic_PLUGIN and write results
--messages-out=PATH Write messages generated by plugins to the specified
location. Messages from all plugin invocations are
written to a single common file.
--PLUGIN-out=PATH Run the plugin named gnostic-PLUGIN and write results
to the specified location.
--PLUGIN Run the plugin named gnostic-PLUGIN but don't write any
results. Used for plugins that return messages only.
PLUGIN must not match any other gnostic option.
--x-EXTENSION Use the extension named gnostic-x-EXTENSION
to process OpenAPI specification extensions.
--resolve-refs Explicitly resolve $ref references.
This could have problems with recursive definitions.
--time-plugins Report plugin runtimes.
`
// Initialize internal structures.
g.pluginCalls = make([]*pluginCall, 0)
@ -292,6 +320,8 @@ func (g *Gnostic) readOptions() {
g.yamlOutputPath = invocation
case "errors":
g.errorOutputPath = invocation
case "messages":
g.messageOutputPath = invocation
default:
p := &pluginCall{Name: pluginName, Invocation: invocation}
g.pluginCalls = append(g.pluginCalls, p)
@ -302,6 +332,13 @@ func (g *Gnostic) readOptions() {
g.extensionHandlers = append(g.extensionHandlers, extensionHandler)
} else if arg == "--resolve-refs" {
g.resolveReferences = true
} else if arg == "--time-plugins" {
g.timePlugins = true
} else if arg[0] == '-' && arg[1] == '-' {
// try letting the option specify a plugin with no output files (or unwanted output files)
// this is useful for calling plugins like linters that only return messages
p := &pluginCall{Name: arg[2:len(arg)], Invocation: "!"}
g.pluginCalls = append(g.pluginCalls, p)
} else if arg[0] == '-' {
fmt.Fprintf(os.Stderr, "Unknown option: %s.\n%s\n", arg, g.usage)
os.Exit(-1)
@ -467,6 +504,17 @@ func (g *Gnostic) writeJSONYAMLOutput(message proto.Message) {
}
}
// Write messages.
func (g *Gnostic) writeMessagesOutput(message proto.Message) {
protoBytes, err := proto.Marshal(message)
if err != nil {
writeFile(g.messageOutputPath, g.errorBytes(err), g.sourceName, "errors")
defer os.Exit(-1)
} else {
writeFile(g.messageOutputPath, protoBytes, g.sourceName, "messages.pb")
}
}
// Perform all actions specified in the command-line options.
func (g *Gnostic) performActions(message proto.Message) (err error) {
// Optionally resolve internal references.
@ -490,17 +538,29 @@ func (g *Gnostic) performActions(message proto.Message) (err error) {
if g.textOutputPath != "" {
g.writeTextOutput(message)
}
// Optionaly write document in yaml and/or json formats.
// Optionally write document in yaml and/or json formats.
if g.yamlOutputPath != "" || g.jsonOutputPath != "" {
g.writeJSONYAMLOutput(message)
}
// Call all specified plugins.
messages := make([]*plugins.Message, 0)
for _, p := range g.pluginCalls {
err := p.perform(message, g.sourceFormat, g.sourceName)
pluginMessages, err := p.perform(message, g.sourceFormat, g.sourceName, g.timePlugins)
if err != nil {
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
defer os.Exit(-1) // run all plugins, even when some have errors
}
messages = append(messages, pluginMessages...)
}
if g.messageOutputPath != "" {
g.writeMessagesOutput(&plugins.Messages{Messages: messages})
} else {
// Print any messages from the plugins
if len(messages) > 0 {
for _, message := range messages {
fmt.Printf("%+v\n", message)
}
}
}
return nil
}

View file

@ -1,453 +0,0 @@
package main
import (
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
func testCompiler(t *testing.T, inputFile string, referenceFile string, expectErrors bool) {
textFile := strings.Replace(filepath.Base(inputFile), filepath.Ext(inputFile), ".text", 1)
errorsFile := strings.Replace(filepath.Base(inputFile), filepath.Ext(inputFile), ".errors", 1)
// remove any preexisting output files
os.Remove(textFile)
os.Remove(errorsFile)
// run the compiler
var err error
var cmd = exec.Command(
"gnostic",
inputFile,
"--text-out=.",
"--errors-out=.",
"--resolve-refs")
//t.Log(cmd.Args)
err = cmd.Run()
if err != nil && !expectErrors {
t.Logf("Compile failed: %+v", err)
t.FailNow()
}
// verify the output against a reference
var outputFile string
if expectErrors {
outputFile = errorsFile
} else {
outputFile = textFile
}
err = exec.Command("diff", outputFile, referenceFile).Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
} else {
// if the test succeeded, clean up
os.Remove(textFile)
os.Remove(errorsFile)
}
}
func testNormal(t *testing.T, inputFile string, referenceFile string) {
testCompiler(t, inputFile, referenceFile, false)
}
func testErrors(t *testing.T, inputFile string, referenceFile string) {
testCompiler(t, inputFile, referenceFile, true)
}
func TestPetstoreJSON(t *testing.T) {
testNormal(t,
"examples/v2.0/json/petstore.json",
"test/v2.0/petstore.text")
}
func TestPetstoreYAML(t *testing.T) {
testNormal(t,
"examples/v2.0/yaml/petstore.yaml",
"test/v2.0/petstore.text")
}
func TestSeparateYAML(t *testing.T) {
testNormal(t,
"examples/v2.0/yaml/petstore-separate/spec/swagger.yaml",
"test/v2.0/yaml/petstore-separate/spec/swagger.text")
}
func TestSeparateJSON(t *testing.T) {
testNormal(t,
"examples/v2.0/json/petstore-separate/spec/swagger.json",
"test/v2.0/yaml/petstore-separate/spec/swagger.text") // yaml and json results should be identical
}
func TestRemotePetstoreJSON(t *testing.T) {
testNormal(t,
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/json/petstore.json",
"test/v2.0/petstore.text")
}
func TestRemotePetstoreYAML(t *testing.T) {
testNormal(t,
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/yaml/petstore.yaml",
"test/v2.0/petstore.text")
}
func TestRemoteSeparateYAML(t *testing.T) {
testNormal(t,
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/yaml/petstore-separate/spec/swagger.yaml",
"test/v2.0/yaml/petstore-separate/spec/swagger.text")
}
func TestRemoteSeparateJSON(t *testing.T) {
testNormal(t,
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/json/petstore-separate/spec/swagger.json",
"test/v2.0/yaml/petstore-separate/spec/swagger.text")
}
func TestErrorBadProperties(t *testing.T) {
testErrors(t,
"examples/errors/petstore-badproperties.yaml",
"test/errors/petstore-badproperties.errors")
}
func TestErrorUnresolvedRefs(t *testing.T) {
testErrors(t,
"examples/errors/petstore-unresolvedrefs.yaml",
"test/errors/petstore-unresolvedrefs.errors")
}
func TestErrorMissingVersion(t *testing.T) {
testErrors(t,
"examples/errors/petstore-missingversion.yaml",
"test/errors/petstore-missingversion.errors")
}
func testPlugin(t *testing.T, plugin string, inputFile string, outputFile string, referenceFile string) {
// remove any preexisting output files
os.Remove(outputFile)
// run the compiler
var err error
output, err := exec.Command(
"gnostic",
"--"+plugin+"-out=-",
inputFile).Output()
if err != nil {
t.Logf("Compile failed: %+v", err)
t.FailNow()
}
_ = ioutil.WriteFile(outputFile, output, 0644)
err = exec.Command("diff", outputFile, referenceFile).Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
} else {
// if the test succeeded, clean up
os.Remove(outputFile)
}
}
func TestSamplePluginWithPetstore(t *testing.T) {
testPlugin(t,
"summary",
"examples/v2.0/yaml/petstore.yaml",
"sample-petstore.out",
"test/v2.0/yaml/sample-petstore.out")
}
func TestErrorInvalidPluginInvocations(t *testing.T) {
var err error
output, err := exec.Command(
"gnostic",
"examples/v2.0/yaml/petstore.yaml",
"--errors-out=-",
"--plugin-out=foo=bar,:abc",
"--plugin-out=,foo=bar:abc",
"--plugin-out=foo=:abc",
"--plugin-out==bar:abc",
"--plugin-out=,,:abc",
"--plugin-out=foo=bar=baz:abc",
).Output()
if err == nil {
t.Logf("Invalid invocations were accepted")
t.FailNow()
}
outputFile := "invalid-plugin-invocation.errors"
_ = ioutil.WriteFile(outputFile, output, 0644)
err = exec.Command("diff", outputFile, "test/errors/invalid-plugin-invocation.errors").Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
} else {
// if the test succeeded, clean up
os.Remove(outputFile)
}
}
func TestValidPluginInvocations(t *testing.T) {
var err error
output, err := exec.Command(
"gnostic",
"examples/v2.0/yaml/petstore.yaml",
"--errors-out=-",
// verify an invocation with no parameters
"--summary-out=!", // "!" indicates that no output should be generated
// verify single pair of parameters
"--summary-out=a=b:!",
// verify multiple parameters
"--summary-out=a=b,c=123,xyz=alphabetagammadelta:!",
// verify that special characters / . - _ can be included in parameter keys and values
"--summary-out=a/b/c=x/y/z:!",
"--summary-out=a.b.c=x.y.z:!",
"--summary-out=a-b-c=x-y-z:!",
"--summary-out=a_b_c=x_y_z:!",
).Output()
if len(output) != 0 {
t.Logf("Valid invocations generated invalid errors\n%s", string(output))
t.FailNow()
}
if err != nil {
t.Logf("Valid invocations were not accepted")
t.FailNow()
}
}
func TestExtensionHandlerWithLibraryExample(t *testing.T) {
outputFile := "library-example-with-ext.text.out"
inputFile := "test/library-example-with-ext.json"
referenceFile := "test/library-example-with-ext.text.out"
os.Remove(outputFile)
// run the compiler
var err error
command := exec.Command(
"gnostic",
"--x-sampleone",
"--x-sampletwo",
"--text-out="+outputFile,
"--resolve-refs",
inputFile)
_, err = command.Output()
if err != nil {
t.Logf("Compile failed for command %v: %+v", command, err)
t.FailNow()
}
//_ = ioutil.WriteFile(outputFile, output, 0644)
err = exec.Command("diff", outputFile, referenceFile).Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
} else {
// if the test succeeded, clean up
os.Remove(outputFile)
}
}
func TestJSONOutput(t *testing.T) {
inputFile := "test/library-example-with-ext.json"
textFile := "sample.text"
jsonFile := "sample.json"
textFile2 := "sample2.text"
jsonFile2 := "sample2.json"
os.Remove(textFile)
os.Remove(jsonFile)
os.Remove(textFile2)
os.Remove(jsonFile2)
var err error
// Run the compiler once.
command := exec.Command(
"gnostic",
"--text-out="+textFile,
"--json-out="+jsonFile,
inputFile)
_, err = command.Output()
if err != nil {
t.Logf("Compile failed for command %v: %+v", command, err)
t.FailNow()
}
// Run the compiler again, this time on the generated output.
command = exec.Command(
"gnostic",
"--text-out="+textFile2,
"--json-out="+jsonFile2,
jsonFile)
_, err = command.Output()
if err != nil {
t.Logf("Compile failed for command %v: %+v", command, err)
t.FailNow()
}
// Verify that both models have the same internal representation.
err = exec.Command("diff", textFile, textFile2).Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
} else {
// if the test succeeded, clean up
os.Remove(textFile)
os.Remove(jsonFile)
os.Remove(textFile2)
os.Remove(jsonFile2)
}
}
func TestYAMLOutput(t *testing.T) {
inputFile := "test/library-example-with-ext.json"
textFile := "sample.text"
yamlFile := "sample.yaml"
textFile2 := "sample2.text"
yamlFile2 := "sample2.yaml"
os.Remove(textFile)
os.Remove(yamlFile)
os.Remove(textFile2)
os.Remove(yamlFile2)
var err error
// Run the compiler once.
command := exec.Command(
"gnostic",
"--text-out="+textFile,
"--yaml-out="+yamlFile,
inputFile)
_, err = command.Output()
if err != nil {
t.Logf("Compile failed for command %v: %+v", command, err)
t.FailNow()
}
// Run the compiler again, this time on the generated output.
command = exec.Command(
"gnostic",
"--text-out="+textFile2,
"--yaml-out="+yamlFile2,
yamlFile)
_, err = command.Output()
if err != nil {
t.Logf("Compile failed for command %v: %+v", command, err)
t.FailNow()
}
// Verify that both models have the same internal representation.
err = exec.Command("diff", textFile, textFile2).Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
} else {
// if the test succeeded, clean up
os.Remove(textFile)
os.Remove(yamlFile)
os.Remove(textFile2)
os.Remove(yamlFile2)
}
}
func testBuilder(version string, t *testing.T) {
var err error
pbFile := "petstore-" + version + ".pb"
yamlFile := "petstore.yaml"
jsonFile := "petstore.json"
textFile := "petstore.text"
textReference := "test/" + version + ".0/petstore.text"
os.Remove(pbFile)
os.Remove(textFile)
os.Remove(yamlFile)
os.Remove(jsonFile)
// Generate petstore.pb.
command := exec.Command(
"petstore-builder",
"--"+version)
_, err = command.Output()
if err != nil {
t.Logf("Command %v failed: %+v", command, err)
t.FailNow()
}
// Convert petstore.pb to yaml and json.
command = exec.Command(
"gnostic",
pbFile,
"--json-out="+jsonFile,
"--yaml-out="+yamlFile)
_, err = command.Output()
if err != nil {
t.Logf("Command %v failed: %+v", command, err)
t.FailNow()
}
// Read petstore.yaml, resolve references, and export text.
command = exec.Command(
"gnostic",
yamlFile,
"--resolve-refs",
"--text-out="+textFile)
_, err = command.Output()
if err != nil {
t.Logf("Command %v failed: %+v", command, err)
t.FailNow()
}
// Verify that the generated text matches our reference.
err = exec.Command("diff", textFile, textReference).Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
}
// Read petstore.json, resolve references, and export text.
command = exec.Command(
"gnostic",
jsonFile,
"--resolve-refs",
"--text-out="+textFile)
_, err = command.Output()
if err != nil {
t.Logf("Command %v failed: %+v", command, err)
t.FailNow()
}
// Verify that the generated text matches our reference.
err = exec.Command("diff", textFile, textReference).Run()
if err != nil {
t.Logf("Diff failed: %+v", err)
t.FailNow()
}
// if the test succeeded, clean up
os.Remove(pbFile)
os.Remove(textFile)
os.Remove(yamlFile)
os.Remove(jsonFile)
}
func TestBuilderV2(t *testing.T) {
testBuilder("v2", t)
}
func TestBuilderV3(t *testing.T) {
testBuilder("v3", t)
}
// OpenAPI 3.0 tests
func TestPetstoreYAML_30(t *testing.T) {
testNormal(t,
"examples/v3.0/yaml/petstore.yaml",
"test/v3.0/petstore.text")
}
func TestPetstoreJSON_30(t *testing.T) {
testNormal(t,
"examples/v3.0/json/petstore.json",
"test/v3.0/petstore.text")
}