From 010de0cfbb6714039b86643eed965a201e8e97c6 Mon Sep 17 00:00:00 2001 From: Minuk Song Date: Sun, 17 Sep 2023 18:02:03 +0900 Subject: [PATCH] feat: add testcases --- go.mod | 4 +- go.sum | 7 +- pkg/modules/1_middleend_generator.go | 24 ++- pkg/modules/4_backend_serializer.go | 2 +- pkg/proto/options.go | 4 +- proto/jsonschema.proto | 1 + testdata/{cases => }/README.md | 5 +- testdata/cases/jsonschema-array/test.proto | 54 +++++ .../cases/jsonschema-array/test.schema.json | 138 ++++++++++++ testdata/cases/jsonschema-array/test.yaml | 11 + .../cases/jsonschema-description/test.proto | 43 ++++ .../jsonschema-description/test.schema.json | 55 +++++ .../cases/jsonschema-description/test.yaml | 11 + testdata/cases/jsonschema-nullable/test.proto | 29 +++ .../jsonschema-nullable/test.schema.json | 98 +++++++++ testdata/cases/jsonschema-nullable/test.yaml | 11 + testdata/cases/jsonschema-number/test.proto | 33 +++ .../cases/jsonschema-number/test.schema.json | 91 ++++++++ testdata/cases/jsonschema-number/test.yaml | 11 + testdata/cases/jsonschema-object/test.proto | 41 ++++ .../cases/jsonschema-object/test.schema.json | 82 ++++++++ testdata/cases/jsonschema-object/test.yaml | 11 + testdata/cases/jsonschema-string/test.proto | 26 +++ .../cases/jsonschema-string/test.schema.json | 60 ++++++ testdata/cases/jsonschema-string/test.yaml | 11 + testdata/cases/plugin-draft-04/test.proto | 21 ++ .../cases/plugin-draft-04/test.schema.json | 52 +++++ testdata/cases/plugin-draft-04/test.yaml | 12 ++ testdata/cases/plugin-draft-06/test.proto | 21 ++ .../cases/plugin-draft-06/test.schema.json | 50 +++++ testdata/cases/plugin-draft-06/test.yaml | 12 ++ testdata/cases/plugin-draft-07/test.proto | 21 ++ .../cases/plugin-draft-07/test.schema.json | 50 +++++ testdata/cases/plugin-draft-07/test.yaml | 12 ++ testdata/cases/plugin-draft-201909/test.proto | 21 ++ .../plugin-draft-201909/test.schema.json | 50 +++++ testdata/cases/plugin-draft-201909/test.yaml | 12 ++ testdata/cases/plugin-draft-202012/test.proto | 21 ++ .../plugin-draft-202012/test.schema.json | 50 +++++ testdata/cases/plugin-draft-202012/test.yaml | 12 ++ testdata/cases/plugin-entrypoint/test.proto | 32 +++ .../cases/plugin-entrypoint/test.schema.json | 50 +++++ testdata/cases/plugin-entrypoint/test.yaml | 12 ++ testdata/cases/plugin-output-yaml/test.proto | 54 +++++ .../cases/plugin-output-yaml/test.schema.yaml | 95 +++++++++ testdata/cases/plugin-output-yaml/test.yaml | 12 ++ testdata/cases/proto-enum/test.proto | 60 ++++++ testdata/cases/proto-enum/test.schema.json | 99 +++++++++ testdata/cases/proto-enum/test.yaml | 11 + testdata/cases/proto-jsonname/test.proto | 32 +++ .../cases/proto-jsonname/test.schema.json | 131 ++++++++++++ testdata/cases/proto-jsonname/test.yaml | 11 + testdata/cases/proto-map/test.proto | 36 ++++ testdata/cases/proto-map/test.schema.json | 105 ++++++++++ .../test.yaml | 4 +- .../{entry.proto => test.proto} | 0 .../{entry.schema.json => test.schema.json} | 36 +--- testdata/cases/proto-oneof-multiple/test.yaml | 11 + .../{entry.proto => test.proto} | 0 .../{entry.schema.json => test.schema.json} | 28 +-- testdata/cases/proto-oneof-single/test.yaml | 11 + testdata/cases/proto-optional/test.proto | 40 ++++ .../cases/proto-optional/test.schema.json | 197 ++++++++++++++++++ testdata/cases/proto-optional/test.yaml | 11 + .../cases/proto-repeated-scala/test.proto | 17 -- .../proto-repeated-scala/test.schema.json | 42 ---- testdata/cases/wellknown-k8s/test.proto | 14 ++ testdata/cases/wellknown-k8s/test.schema.json | 12 ++ testdata/cases/wellknown-k8s/test.yaml | 11 + testdata/cases/wellknown-proto/test.proto | 21 ++ .../cases/wellknown-proto/test.schema.json | 37 ++++ testdata/cases/wellknown-proto/test.yaml | 11 + testdata/do_test.go | 179 ++++++++++++++++ testdata/go.mod | 28 +++ testdata/go.sum | 64 ++++++ testdata/hack/generate_all_test_result.sh | 43 +++- testdata/hack/generate_test_result.sh | 45 +++- 77 files changed, 2728 insertions(+), 154 deletions(-) rename testdata/{cases => }/README.md (94%) create mode 100644 testdata/cases/jsonschema-array/test.proto create mode 100644 testdata/cases/jsonschema-array/test.schema.json create mode 100644 testdata/cases/jsonschema-array/test.yaml create mode 100644 testdata/cases/jsonschema-description/test.proto create mode 100644 testdata/cases/jsonschema-description/test.schema.json create mode 100644 testdata/cases/jsonschema-description/test.yaml create mode 100644 testdata/cases/jsonschema-nullable/test.proto create mode 100644 testdata/cases/jsonschema-nullable/test.schema.json create mode 100644 testdata/cases/jsonschema-nullable/test.yaml create mode 100644 testdata/cases/jsonschema-number/test.proto create mode 100644 testdata/cases/jsonschema-number/test.schema.json create mode 100644 testdata/cases/jsonschema-number/test.yaml create mode 100644 testdata/cases/jsonschema-object/test.proto create mode 100644 testdata/cases/jsonschema-object/test.schema.json create mode 100644 testdata/cases/jsonschema-object/test.yaml create mode 100644 testdata/cases/jsonschema-string/test.proto create mode 100644 testdata/cases/jsonschema-string/test.schema.json create mode 100644 testdata/cases/jsonschema-string/test.yaml create mode 100644 testdata/cases/plugin-draft-04/test.proto create mode 100644 testdata/cases/plugin-draft-04/test.schema.json create mode 100644 testdata/cases/plugin-draft-04/test.yaml create mode 100644 testdata/cases/plugin-draft-06/test.proto create mode 100644 testdata/cases/plugin-draft-06/test.schema.json create mode 100644 testdata/cases/plugin-draft-06/test.yaml create mode 100644 testdata/cases/plugin-draft-07/test.proto create mode 100644 testdata/cases/plugin-draft-07/test.schema.json create mode 100644 testdata/cases/plugin-draft-07/test.yaml create mode 100644 testdata/cases/plugin-draft-201909/test.proto create mode 100644 testdata/cases/plugin-draft-201909/test.schema.json create mode 100644 testdata/cases/plugin-draft-201909/test.yaml create mode 100644 testdata/cases/plugin-draft-202012/test.proto create mode 100644 testdata/cases/plugin-draft-202012/test.schema.json create mode 100644 testdata/cases/plugin-draft-202012/test.yaml create mode 100644 testdata/cases/plugin-entrypoint/test.proto create mode 100644 testdata/cases/plugin-entrypoint/test.schema.json create mode 100644 testdata/cases/plugin-entrypoint/test.yaml create mode 100644 testdata/cases/plugin-output-yaml/test.proto create mode 100644 testdata/cases/plugin-output-yaml/test.schema.yaml create mode 100644 testdata/cases/plugin-output-yaml/test.yaml create mode 100644 testdata/cases/proto-enum/test.proto create mode 100644 testdata/cases/proto-enum/test.schema.json create mode 100644 testdata/cases/proto-enum/test.yaml create mode 100644 testdata/cases/proto-jsonname/test.proto create mode 100644 testdata/cases/proto-jsonname/test.schema.json create mode 100644 testdata/cases/proto-jsonname/test.yaml create mode 100644 testdata/cases/proto-map/test.proto create mode 100644 testdata/cases/proto-map/test.schema.json rename testdata/cases/{proto-repeated-scala => proto-map}/test.yaml (71%) rename testdata/cases/proto-oneof-multiple/{entry.proto => test.proto} (100%) rename testdata/cases/proto-oneof-multiple/{entry.schema.json => test.schema.json} (75%) create mode 100644 testdata/cases/proto-oneof-multiple/test.yaml rename testdata/cases/proto-oneof-single/{entry.proto => test.proto} (100%) rename testdata/cases/proto-oneof-single/{entry.schema.json => test.schema.json} (75%) create mode 100644 testdata/cases/proto-oneof-single/test.yaml create mode 100644 testdata/cases/proto-optional/test.proto create mode 100644 testdata/cases/proto-optional/test.schema.json create mode 100644 testdata/cases/proto-optional/test.yaml delete mode 100644 testdata/cases/proto-repeated-scala/test.proto delete mode 100644 testdata/cases/proto-repeated-scala/test.schema.json create mode 100644 testdata/cases/wellknown-k8s/test.proto create mode 100644 testdata/cases/wellknown-k8s/test.schema.json create mode 100644 testdata/cases/wellknown-k8s/test.yaml create mode 100644 testdata/cases/wellknown-proto/test.proto create mode 100644 testdata/cases/wellknown-proto/test.schema.json create mode 100644 testdata/cases/wellknown-proto/test.yaml create mode 100644 testdata/do_test.go create mode 100644 testdata/go.mod create mode 100644 testdata/go.sum diff --git a/go.mod b/go.mod index 1091a9a..c4f10e6 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,10 @@ go 1.21.1 require ( github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 - github.com/invopop/jsonschema v0.8.0 github.com/lyft/protoc-gen-star/v2 v2.0.3 github.com/samber/lo v1.38.1 google.golang.org/protobuf v1.30.0 - gopkg.in/yaml.v3 v3.0.1 + sigs.k8s.io/yaml v1.3.0 ) require ( @@ -20,4 +19,5 @@ require ( golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/text v0.11.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 1c9b528..fd228e5 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= -github.com/invopop/jsonschema v0.8.0 h1:9Vblm5uNqURXUSaX0QUYcI/Hcu5rrvOz5MbpWgw0VkM= -github.com/invopop/jsonschema v0.8.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -35,7 +33,6 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -59,6 +56,10 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/modules/1_middleend_generator.go b/pkg/modules/1_middleend_generator.go index dacd654..84b579f 100644 --- a/pkg/modules/1_middleend_generator.go +++ b/pkg/modules/1_middleend_generator.go @@ -13,8 +13,8 @@ import ( func buildFromMessage(message pgs.Message, mo *proto.MessageOptions) *jsonschema.Schema { schema := &jsonschema.Schema{} schema.Type = "object" - schema.Title = message.Name().UpperCamelCase().String() - schema.Description = message.SourceCodeInfo().LeadingComments() + schema.Title = proto.GetTitleOrEmpty(mo) + schema.Description = proto.GetDescriptionOrComment(message, mo) schema.Properties = jsonschema.NewOrderedSchemaMap() fillSchemaByObjectKeywords(schema, mo.GetObject()) @@ -26,7 +26,14 @@ func buildFromMessage(message pgs.Message, mo *proto.MessageOptions) *jsonschema //} propName := toPropertyName(field.Name()) - schema.Properties.Set(propName, &jsonschema.Schema{Ref: toRefId(field)}) + fieldSchema := &jsonschema.Schema{Ref: toRefId(field)} + if proto.GetFieldOptions(field).GetNullable() { + fieldSchema = &jsonschema.Schema{AnyOf: []*jsonschema.Schema{ + {Type: "null"}, + fieldSchema, + }} + } + schema.Properties.Set(propName, fieldSchema) // If field is not a member of oneOf if !field.InRealOneOf() && !field.HasOptionalKeyword() { @@ -70,7 +77,6 @@ func buildFromMessageField(field pgs.Field, fo *proto.FieldOptions) *jsonschema. } } -// TODO: 미완성 func buildFromMapField(field pgs.Field, fo *proto.FieldOptions) *jsonschema.Schema { schema := &jsonschema.Schema{} schema.Title = proto.GetTitleOrEmpty(fo) @@ -80,10 +86,12 @@ func buildFromMapField(field pgs.Field, fo *proto.FieldOptions) *jsonschema.Sche valueSchema := &jsonschema.Schema{} value := field.Type().Element() protoType := value.ProtoType() - if protoType == pgs.MessageT { - valueSchema.Ref = toRefId(value.Embed()) + if protoType.IsInt() { + schema.Type = "integer" } else if protoType.IsNumeric() { valueSchema.Type = "number" + } else if protoType == pgs.MessageT { + valueSchema.Ref = toRefId(value.Embed()) } else if protoType == pgs.BoolT { valueSchema.Type = "boolean" } else if protoType == pgs.EnumT { @@ -156,7 +164,7 @@ func buildFromEnum(enum pgs.Enum) (*jsonschema.Schema, error) { case proto.EnumOptions_MapToCustom: evo := proto.GetEnumValueOptions(enumValue) - customValue, err := parseScalaValueFromAny(evo.CustomValue) + customValue, err := parseScalaValueFromAny(evo.GetCustomValue()) if err != nil { return nil, err } @@ -263,7 +271,7 @@ func getWellKnownType(field pgs.Field) WellKnownType { } func parseScalaValueFromAny(anyValue *anypb.Any) (any, error) { - if anyValue.Value == nil { + if anyValue == nil || anyValue.Value == nil { return nil, nil } diff --git a/pkg/modules/4_backend_serializer.go b/pkg/modules/4_backend_serializer.go index d1b78bc..942d270 100644 --- a/pkg/modules/4_backend_serializer.go +++ b/pkg/modules/4_backend_serializer.go @@ -7,7 +7,7 @@ import ( pgs "github.com/lyft/protoc-gen-star/v2" "github.com/pubg/protoc-gen-jsonschema/pkg/proto" - "gopkg.in/yaml.v3" + "sigs.k8s.io/yaml" ) type BackendSerializer interface { diff --git a/pkg/proto/options.go b/pkg/proto/options.go index f686e55..2b00b83 100644 --- a/pkg/proto/options.go +++ b/pkg/proto/options.go @@ -99,12 +99,10 @@ func GetDescriptionOrComment(name NameWithSourceResolver, description Descriptio } builder := &strings.Builder{} - builder.WriteString(name.SourceCodeInfo().LeadingComments()) - builder.WriteString("\n") for _, comment := range name.SourceCodeInfo().LeadingDetachedComments() { builder.WriteString(comment) - builder.WriteString("\n") } + builder.WriteString(name.SourceCodeInfo().LeadingComments()) builder.WriteString(name.SourceCodeInfo().TrailingComments()) comment := strings.TrimSpace(strings.Trim(builder.String(), "\n")) diff --git a/proto/jsonschema.proto b/proto/jsonschema.proto index 28ba4d5..a191259 100644 --- a/proto/jsonschema.proto +++ b/proto/jsonschema.proto @@ -72,6 +72,7 @@ message FileOptions { default: inherit from PluginOptions.entrypoint_message */ string entrypoint_message = 2; + /** output_file_suffix is used to determine output file name suffix. Values should end with '.json' or '.yaml' or '.yml'. diff --git a/testdata/cases/README.md b/testdata/README.md similarity index 94% rename from testdata/cases/README.md rename to testdata/README.md index 47b9b18..5755412 100644 --- a/testdata/cases/README.md +++ b/testdata/README.md @@ -17,8 +17,9 @@ jsonschema-number number validation keyword 테스트 jsonschema-string string validation keyword 테스트 jsonschema-array array validation keyword 테스트 jsonschema-object object validation keyword 테스트 -jsonschema-enum enum validation keyword 테스트 -jsonschema-const const validation keyword 테스트 + +[//]: # (jsonschema-enum enum validation keyword 테스트) +[//]: # (jsonschema-const const validation keyword 테스트) plugin-entrypoint-options plugin entrypoint가 잘 작동하는지 테스트 plugin-output-options output 관련 옵션이 잘 작동하는지 테스트 diff --git a/testdata/cases/jsonschema-array/test.proto b/testdata/cases/jsonschema-array/test.proto new file mode 100644 index 0000000..855315d --- /dev/null +++ b/testdata/cases/jsonschema-array/test.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + repeated string val1 = 1; + + repeated int64 val2 = 2 + [(pubg.jsonschema.field) = { + title: "My Title" + description: "My Description" + nullable: true + }]; + + repeated float optioned1 = 3 + [(pubg.jsonschema.field) = {array:{ + max_items: 3 + min_items: 1 + }}]; + + repeated double optioned2 = 4 + [(pubg.jsonschema.field) = {array:{ + max_items: 3 + min_items: 1 + unique_items: true + }}]; + + repeated double optioned3 = 5 + [(pubg.jsonschema.field) = {array:{ + max_items: 3 + min_items: 1 + unique_items: false + }}]; + + repeated MyMessage message = 6; + + repeated MyEnum enum = 7; +} + +message MyMessage { + repeated string val1 = 1; + + repeated int64 val2 = 2; +} + +enum MyEnum { + FOO = 0; + BAR = 1; + BAZ = 2; +} diff --git a/testdata/cases/jsonschema-array/test.schema.json b/testdata/cases/jsonschema-array/test.schema.json new file mode 100644 index 0000000..9f5e17c --- /dev/null +++ b/testdata/cases/jsonschema-array/test.schema.json @@ -0,0 +1,138 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.MyEnum": { + "type": "string", + "enum": [ + "FOO", + "BAR", + "BAZ" + ] + }, + ".tests.Values": { + "properties": { + "val1": { + "$ref": "#/$defs/.tests.Values.val1" + }, + "val2": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/.tests.Values.val2" + } + ] + }, + "optioned1": { + "$ref": "#/$defs/.tests.Values.optioned1" + }, + "optioned2": { + "$ref": "#/$defs/.tests.Values.optioned2" + }, + "optioned3": { + "$ref": "#/$defs/.tests.Values.optioned3" + }, + "message": { + "$ref": "#/$defs/.tests.Values.message" + }, + "enum": { + "$ref": "#/$defs/.tests.Values.enum" + } + }, + "type": "object", + "required": [ + "val1", + "val2", + "optioned1", + "optioned2", + "optioned3", + "message", + "enum" + ] + }, + ".tests.Values.val1": { + "items": { + "type": "string" + }, + "type": "array" + }, + ".tests.Values.val2": { + "items": { + "type": "integer", + "title": "My Title", + "description": "My Description" + }, + "type": "array", + "title": "My Title", + "description": "My Description" + }, + ".tests.Values.optioned1": { + "items": { + "type": "number" + }, + "type": "array", + "maxItems": 3, + "minItems": 1 + }, + ".tests.Values.optioned2": { + "items": { + "type": "number" + }, + "type": "array", + "maxItems": 3, + "minItems": 1, + "uniqueItems": true + }, + ".tests.Values.optioned3": { + "items": { + "type": "number" + }, + "type": "array", + "maxItems": 3, + "minItems": 1, + "uniqueItems": false + }, + ".tests.Values.message": { + "items": { + "$ref": "#/$defs/.tests.MyMessage" + }, + "type": "array" + }, + ".tests.Values.enum": { + "items": { + "$ref": "#/$defs/.tests.MyEnum" + }, + "type": "array" + }, + ".tests.MyMessage": { + "properties": { + "val1": { + "$ref": "#/$defs/.tests.MyMessage.val1" + }, + "val2": { + "$ref": "#/$defs/.tests.MyMessage.val2" + } + }, + "type": "object", + "required": [ + "val1", + "val2" + ] + }, + ".tests.MyMessage.val1": { + "items": { + "type": "string" + }, + "type": "array" + }, + ".tests.MyMessage.val2": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/jsonschema-array/test.yaml b/testdata/cases/jsonschema-array/test.yaml new file mode 100644 index 0000000..41d8384 --- /dev/null +++ b/testdata/cases/jsonschema-array/test.yaml @@ -0,0 +1,11 @@ +name: "jsonschema-array" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/jsonschema-description/test.proto b/testdata/cases/jsonschema-description/test.proto new file mode 100644 index 0000000..17bb229 --- /dev/null +++ b/testdata/cases/jsonschema-description/test.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +// 1. Leading Comment of Values +message Values { +// 2. Trailing Comment of Values + + // 1. Leading Detached Comment of default + + // 2. Leading Comment of default + Default default = 1; + // 3. Trailing Comment of default + + // 1. Leading Detached Comment of inline_enum + + // 2. Leading Comment of inline_enum + InlineEnum inline_enum = 6; + // 3. Trailing Comment of inline_enum + + // 1. Leading Comment of InlineEnum + enum InlineEnum { + FOO = 0; + BAR = 1; + } + + // A Leading Comment will be override + string str = 7 [(pubg.jsonschema.field) = {description:"This description "}]; +} + +// 1. Leading Detached Comment of Default + +// 2. Leading Comment of Default +enum Default { + // 3. Trailing Comment of Default + + FOODefault0 = 0; + FOODefault1 = 1; +} diff --git a/testdata/cases/jsonschema-description/test.schema.json b/testdata/cases/jsonschema-description/test.schema.json new file mode 100644 index 0000000..b926e44 --- /dev/null +++ b/testdata/cases/jsonschema-description/test.schema.json @@ -0,0 +1,55 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Default": { + "type": "string", + "enum": [ + "FOODefault0", + "FOODefault1" + ], + "description": "1. Leading Detached Comment of Default\n 2. Leading Comment of Default\n 3. Trailing Comment of Default" + }, + ".tests.Values": { + "properties": { + "default": { + "$ref": "#/$defs/.tests.Values.default" + }, + "inline_enum": { + "$ref": "#/$defs/.tests.Values.inline_enum" + }, + "str": { + "$ref": "#/$defs/.tests.Values.str" + } + }, + "type": "object", + "required": [ + "default", + "inline_enum", + "str" + ], + "description": "1. Leading Comment of Values\n 2. Trailing Comment of Values" + }, + ".tests.Values.InlineEnum": { + "type": "string", + "enum": [ + "FOO", + "BAR" + ], + "description": "1. Leading Comment of InlineEnum" + }, + ".tests.Values.default": { + "$ref": "#/$defs/.tests.Default", + "description": "1. Leading Detached Comment of default\n 2. Leading Comment of default\n 3. Trailing Comment of default" + }, + ".tests.Values.inline_enum": { + "$ref": "#/$defs/.tests.Values.InlineEnum", + "description": "1. Leading Detached Comment of inline_enum\n 2. Leading Comment of inline_enum\n 3. Trailing Comment of inline_enum" + }, + ".tests.Values.str": { + "type": "string", + "description": "This description " + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/jsonschema-description/test.yaml b/testdata/cases/jsonschema-description/test.yaml new file mode 100644 index 0000000..1bbe454 --- /dev/null +++ b/testdata/cases/jsonschema-description/test.yaml @@ -0,0 +1,11 @@ +name: "jsonschema-description" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/jsonschema-nullable/test.proto b/testdata/cases/jsonschema-nullable/test.proto new file mode 100644 index 0000000..385164d --- /dev/null +++ b/testdata/cases/jsonschema-nullable/test.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + MyMessage messages = 1 [(pubg.jsonschema.field) = {nullable:true}]; + + MyEnum enums = 2 [(pubg.jsonschema.field) = {nullable:true}]; + + string strings = 3 [(pubg.jsonschema.field) = {nullable:true}]; + + int64 ints = 4 [(pubg.jsonschema.field) = {nullable:false}]; +} + +message MyMessage { + repeated string val1 = 1; + + repeated int64 val2 = 2; +} + +enum MyEnum { + FOO = 0; + BAR = 1; + BAZ = 2; +} diff --git a/testdata/cases/jsonschema-nullable/test.schema.json b/testdata/cases/jsonschema-nullable/test.schema.json new file mode 100644 index 0000000..2eeaf87 --- /dev/null +++ b/testdata/cases/jsonschema-nullable/test.schema.json @@ -0,0 +1,98 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.MyEnum": { + "type": "string", + "enum": [ + "FOO", + "BAR", + "BAZ" + ] + }, + ".tests.Values": { + "properties": { + "messages": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/.tests.Values.messages" + } + ] + }, + "enums": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/.tests.Values.enums" + } + ] + }, + "strings": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/.tests.Values.strings" + } + ] + }, + "ints": { + "$ref": "#/$defs/.tests.Values.ints" + } + }, + "type": "object", + "required": [ + "messages", + "enums", + "strings", + "ints" + ] + }, + ".tests.Values.messages": { + "$ref": "#/$defs/.tests.MyMessage" + }, + ".tests.Values.enums": { + "$ref": "#/$defs/.tests.MyEnum" + }, + ".tests.Values.strings": { + "type": "string" + }, + ".tests.Values.ints": { + "type": "integer" + }, + ".tests.MyMessage": { + "properties": { + "val1": { + "$ref": "#/$defs/.tests.MyMessage.val1" + }, + "val2": { + "$ref": "#/$defs/.tests.MyMessage.val2" + } + }, + "type": "object", + "required": [ + "val1", + "val2" + ] + }, + ".tests.MyMessage.val1": { + "items": { + "type": "string" + }, + "type": "array" + }, + ".tests.MyMessage.val2": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/jsonschema-nullable/test.yaml b/testdata/cases/jsonschema-nullable/test.yaml new file mode 100644 index 0000000..1bbe454 --- /dev/null +++ b/testdata/cases/jsonschema-nullable/test.yaml @@ -0,0 +1,11 @@ +name: "jsonschema-description" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/jsonschema-number/test.proto b/testdata/cases/jsonschema-number/test.proto new file mode 100644 index 0000000..5b95793 --- /dev/null +++ b/testdata/cases/jsonschema-number/test.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + // default option + int32 int321 = 1; + + // inclusive min/max + int32 int322 = 2 [(pubg.jsonschema.field) = {numeric: {inclusive_minimum: 1, inclusive_maximum: 100}}]; + + // exclusive min/max + int32 int323 = 3 [(pubg.jsonschema.field) = {numeric: {exclusive_minimum: 1, exclusive_maximum: 100}}]; + + // Inclusive Min/Max with zero value + int32 int324 = 4 [(pubg.jsonschema.field) = {numeric: {inclusive_minimum: 0, inclusive_maximum: 0}}]; + + // Exclusive Min/Max with zero value + int32 int325 = 5 [(pubg.jsonschema.field) = {numeric: {exclusive_minimum: 0, exclusive_maximum: 0}}]; + + // Inclusive Min/Max with negative value + int32 int326 = 6 [(pubg.jsonschema.field) = {numeric: {inclusive_minimum: -1, inclusive_maximum: -100}}]; + + // Exclusive Min/Max with negative value + int32 int327 = 7 [(pubg.jsonschema.field) = {numeric: {exclusive_minimum: -1, exclusive_maximum: -100}}]; + + // multiple of + int32 int328 = 8 [(pubg.jsonschema.field) = {numeric: {multiple_of: 2}}]; +} diff --git a/testdata/cases/jsonschema-number/test.schema.json b/testdata/cases/jsonschema-number/test.schema.json new file mode 100644 index 0000000..b04b73e --- /dev/null +++ b/testdata/cases/jsonschema-number/test.schema.json @@ -0,0 +1,91 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Values": { + "properties": { + "int321": { + "$ref": "#/$defs/.tests.Values.int321" + }, + "int322": { + "$ref": "#/$defs/.tests.Values.int322" + }, + "int323": { + "$ref": "#/$defs/.tests.Values.int323" + }, + "int324": { + "$ref": "#/$defs/.tests.Values.int324" + }, + "int325": { + "$ref": "#/$defs/.tests.Values.int325" + }, + "int326": { + "$ref": "#/$defs/.tests.Values.int326" + }, + "int327": { + "$ref": "#/$defs/.tests.Values.int327" + }, + "int328": { + "$ref": "#/$defs/.tests.Values.int328" + } + }, + "type": "object", + "required": [ + "int321", + "int322", + "int323", + "int324", + "int325", + "int326", + "int327", + "int328" + ] + }, + ".tests.Values.int321": { + "type": "integer", + "description": "default option" + }, + ".tests.Values.int322": { + "type": "integer", + "maximum": 1, + "minimum": 100, + "description": "inclusive min/max" + }, + ".tests.Values.int323": { + "type": "integer", + "exclusiveMaximum": 100, + "exclusiveMinimum": 1, + "description": "exclusive min/max" + }, + ".tests.Values.int324": { + "type": "integer", + "maximum": 0, + "minimum": 0, + "description": "Inclusive Min/Max with zero value" + }, + ".tests.Values.int325": { + "type": "integer", + "exclusiveMaximum": 0, + "exclusiveMinimum": 0, + "description": "Exclusive Min/Max with zero value" + }, + ".tests.Values.int326": { + "type": "integer", + "maximum": -1, + "minimum": -100, + "description": "Inclusive Min/Max with negative value" + }, + ".tests.Values.int327": { + "type": "integer", + "exclusiveMaximum": -100, + "exclusiveMinimum": -1, + "description": "Exclusive Min/Max with negative value" + }, + ".tests.Values.int328": { + "type": "integer", + "multipleOf": 2, + "description": "multiple of" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/jsonschema-number/test.yaml b/testdata/cases/jsonschema-number/test.yaml new file mode 100644 index 0000000..c672dc1 --- /dev/null +++ b/testdata/cases/jsonschema-number/test.yaml @@ -0,0 +1,11 @@ +name: "jsonschema-number" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/jsonschema-object/test.proto b/testdata/cases/jsonschema-object/test.proto new file mode 100644 index 0000000..9084847 --- /dev/null +++ b/testdata/cases/jsonschema-object/test.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + MyMessage messages = 1; + + MyMessage2 messages2 = 2; +} + +message MyMessage { + option (pubg.jsonschema.message) = { + title: "MyMessage"; + object:{ + additional_properties: true + } + }; + + string val1 = 1; + + repeated int64 val2 = 2; +} + +message MyMessage2 { + option (pubg.jsonschema.message) = { + title: "MyMessage"; + object:{ + additional_properties: true + min_properties: 0 + max_properties: 10 + } + }; + + string val1 = 1; + + repeated int64 val2 = 2; +} diff --git a/testdata/cases/jsonschema-object/test.schema.json b/testdata/cases/jsonschema-object/test.schema.json new file mode 100644 index 0000000..cc2613a --- /dev/null +++ b/testdata/cases/jsonschema-object/test.schema.json @@ -0,0 +1,82 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Values": { + "properties": { + "messages": { + "$ref": "#/$defs/.tests.Values.messages" + }, + "messages2": { + "$ref": "#/$defs/.tests.Values.messages2" + } + }, + "type": "object", + "required": [ + "messages", + "messages2" + ] + }, + ".tests.Values.messages": { + "$ref": "#/$defs/.tests.MyMessage" + }, + ".tests.Values.messages2": { + "$ref": "#/$defs/.tests.MyMessage2" + }, + ".tests.MyMessage": { + "properties": { + "val1": { + "$ref": "#/$defs/.tests.MyMessage.val1" + }, + "val2": { + "$ref": "#/$defs/.tests.MyMessage.val2" + } + }, + "additionalProperties": {}, + "type": "object", + "required": [ + "val1", + "val2" + ], + "title": "MyMessage" + }, + ".tests.MyMessage.val1": { + "type": "string" + }, + ".tests.MyMessage.val2": { + "items": { + "type": "integer" + }, + "type": "array" + }, + ".tests.MyMessage2": { + "properties": { + "val1": { + "$ref": "#/$defs/.tests.MyMessage2.val1" + }, + "val2": { + "$ref": "#/$defs/.tests.MyMessage2.val2" + } + }, + "additionalProperties": {}, + "type": "object", + "maxProperties": 10, + "minProperties": 0, + "required": [ + "val1", + "val2" + ], + "title": "MyMessage" + }, + ".tests.MyMessage2.val1": { + "type": "string" + }, + ".tests.MyMessage2.val2": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/jsonschema-object/test.yaml b/testdata/cases/jsonschema-object/test.yaml new file mode 100644 index 0000000..c04094d --- /dev/null +++ b/testdata/cases/jsonschema-object/test.yaml @@ -0,0 +1,11 @@ +name: "jsonschema-object" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/jsonschema-string/test.proto b/testdata/cases/jsonschema-string/test.proto new file mode 100644 index 0000000..dd713b5 --- /dev/null +++ b/testdata/cases/jsonschema-string/test.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + // default option + string string1 = 1; + + // min/max + string string2 = 2 [(pubg.jsonschema.field) = {string: {min_length: 1, max_length: 100, }}]; + + // min/max with zero value + string string3 = 3 [(pubg.jsonschema.field) = {string: {min_length: 0, max_length: 0, }}]; + + // pattern + // TODO: pattern이 regex가 아닌 경우 에러내야 함 + string string4 = 4 [(pubg.jsonschema.field) = {string: {pattern: "^[a-zA-Z0-9]+$", }}]; + + // format + // TODO: 논의) pre-defined format이 아니면 경고해야 하나? + string string6 = 6 [(pubg.jsonschema.field) = {string: {format: "date-time", }}]; +} diff --git a/testdata/cases/jsonschema-string/test.schema.json b/testdata/cases/jsonschema-string/test.schema.json new file mode 100644 index 0000000..7e6b39b --- /dev/null +++ b/testdata/cases/jsonschema-string/test.schema.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Values": { + "properties": { + "string1": { + "$ref": "#/$defs/.tests.Values.string1" + }, + "string2": { + "$ref": "#/$defs/.tests.Values.string2" + }, + "string3": { + "$ref": "#/$defs/.tests.Values.string3" + }, + "string4": { + "$ref": "#/$defs/.tests.Values.string4" + }, + "string6": { + "$ref": "#/$defs/.tests.Values.string6" + } + }, + "type": "object", + "required": [ + "string1", + "string2", + "string3", + "string4", + "string6" + ] + }, + ".tests.Values.string1": { + "type": "string", + "description": "default option" + }, + ".tests.Values.string2": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "min/max" + }, + ".tests.Values.string3": { + "type": "string", + "maxLength": 0, + "minLength": 0, + "description": "min/max with zero value" + }, + ".tests.Values.string4": { + "type": "string", + "pattern": "^[a-zA-Z0-9]+$", + "description": "pattern\n TODO: pattern이 regex가 아닌 경우 에러내야 함" + }, + ".tests.Values.string6": { + "type": "string", + "format": "date-time", + "description": "format\n TODO: 논의) pre-defined format이 아니면 경고해야 하나?" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/jsonschema-string/test.yaml b/testdata/cases/jsonschema-string/test.yaml new file mode 100644 index 0000000..2cc7806 --- /dev/null +++ b/testdata/cases/jsonschema-string/test.yaml @@ -0,0 +1,11 @@ +name: "jsonschema-string" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/plugin-draft-04/test.proto b/testdata/cases/plugin-draft-04/test.proto new file mode 100644 index 0000000..6510390 --- /dev/null +++ b/testdata/cases/plugin-draft-04/test.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + // default option + string string1 = 1; + + // min/max + string string2 = 2 [(pubg.jsonschema.field) = {string: {min_length: 1, max_length: 100, }}]; + + // min/max with zero value + string string3 = 3 [(pubg.jsonschema.field) = {string: {min_length: 0, max_length: 0, }}]; + + // Exclusive maximum should convert to maximum: 10 and exclusive_maximum: true + int64 int64 = 4 [(pubg.jsonschema.field) = {numeric:{exclusive_maximum: 10}}]; +} diff --git a/testdata/cases/plugin-draft-04/test.schema.json b/testdata/cases/plugin-draft-04/test.schema.json new file mode 100644 index 0000000..63f1a48 --- /dev/null +++ b/testdata/cases/plugin-draft-04/test.schema.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/.tests.Values", + "definitions": { + ".tests.Values": { + "properties": { + "string1": { + "$ref": "#/definitions/.tests.Values.string1" + }, + "string2": { + "$ref": "#/definitions/.tests.Values.string2" + }, + "string3": { + "$ref": "#/definitions/.tests.Values.string3" + }, + "int64": { + "$ref": "#/definitions/.tests.Values.int64" + } + }, + "type": "object", + "required": [ + "string1", + "string2", + "string3", + "int64" + ] + }, + ".tests.Values.string1": { + "type": "string", + "description": "default option" + }, + ".tests.Values.string2": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "min/max" + }, + ".tests.Values.string3": { + "type": "string", + "maxLength": 0, + "minLength": 0, + "description": "min/max with zero value" + }, + ".tests.Values.int64": { + "type": "integer", + "maximum": 10, + "exclusiveMaximum": true, + "description": "Exclusive maximum should convert to maximum: 10 and exclusive_maximum: true" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/plugin-draft-04/test.yaml b/testdata/cases/plugin-draft-04/test.yaml new file mode 100644 index 0000000..d83a024 --- /dev/null +++ b/testdata/cases/plugin-draft-04/test.yaml @@ -0,0 +1,12 @@ +name: "plugin-draft-04" +description: "" + +inputFiles: ["test.proto"] +inputParameters: + draft: Draft04 + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/plugin-draft-06/test.proto b/testdata/cases/plugin-draft-06/test.proto new file mode 100644 index 0000000..a99efee --- /dev/null +++ b/testdata/cases/plugin-draft-06/test.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + // default option + string string1 = 1; + + // min/max + string string2 = 2 [(pubg.jsonschema.field) = {string: {min_length: 1, max_length: 100, }}]; + + // min/max with zero value + string string3 = 3 [(pubg.jsonschema.field) = {string: {min_length: 0, max_length: 0, }}]; + + + int64 int64 = 4 [(pubg.jsonschema.field) = {numeric:{exclusive_maximum: 10}}]; +} diff --git a/testdata/cases/plugin-draft-06/test.schema.json b/testdata/cases/plugin-draft-06/test.schema.json new file mode 100644 index 0000000..b1888d5 --- /dev/null +++ b/testdata/cases/plugin-draft-06/test.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/.tests.Values", + "definitions": { + ".tests.Values": { + "properties": { + "string1": { + "$ref": "#/definitions/.tests.Values.string1" + }, + "string2": { + "$ref": "#/definitions/.tests.Values.string2" + }, + "string3": { + "$ref": "#/definitions/.tests.Values.string3" + }, + "int64": { + "$ref": "#/definitions/.tests.Values.int64" + } + }, + "type": "object", + "required": [ + "string1", + "string2", + "string3", + "int64" + ] + }, + ".tests.Values.string1": { + "type": "string", + "description": "default option" + }, + ".tests.Values.string2": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "min/max" + }, + ".tests.Values.string3": { + "type": "string", + "maxLength": 0, + "minLength": 0, + "description": "min/max with zero value" + }, + ".tests.Values.int64": { + "type": "integer", + "exclusiveMaximum": 10 + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/plugin-draft-06/test.yaml b/testdata/cases/plugin-draft-06/test.yaml new file mode 100644 index 0000000..081e87c --- /dev/null +++ b/testdata/cases/plugin-draft-06/test.yaml @@ -0,0 +1,12 @@ +name: "plugin-draft-06" +description: "" + +inputFiles: ["test.proto"] +inputParameters: + draft: Draft06 + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/plugin-draft-07/test.proto b/testdata/cases/plugin-draft-07/test.proto new file mode 100644 index 0000000..a99efee --- /dev/null +++ b/testdata/cases/plugin-draft-07/test.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + // default option + string string1 = 1; + + // min/max + string string2 = 2 [(pubg.jsonschema.field) = {string: {min_length: 1, max_length: 100, }}]; + + // min/max with zero value + string string3 = 3 [(pubg.jsonschema.field) = {string: {min_length: 0, max_length: 0, }}]; + + + int64 int64 = 4 [(pubg.jsonschema.field) = {numeric:{exclusive_maximum: 10}}]; +} diff --git a/testdata/cases/plugin-draft-07/test.schema.json b/testdata/cases/plugin-draft-07/test.schema.json new file mode 100644 index 0000000..1927559 --- /dev/null +++ b/testdata/cases/plugin-draft-07/test.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/.tests.Values", + "definitions": { + ".tests.Values": { + "properties": { + "string1": { + "$ref": "#/definitions/.tests.Values.string1" + }, + "string2": { + "$ref": "#/definitions/.tests.Values.string2" + }, + "string3": { + "$ref": "#/definitions/.tests.Values.string3" + }, + "int64": { + "$ref": "#/definitions/.tests.Values.int64" + } + }, + "type": "object", + "required": [ + "string1", + "string2", + "string3", + "int64" + ] + }, + ".tests.Values.string1": { + "type": "string", + "description": "default option" + }, + ".tests.Values.string2": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "min/max" + }, + ".tests.Values.string3": { + "type": "string", + "maxLength": 0, + "minLength": 0, + "description": "min/max with zero value" + }, + ".tests.Values.int64": { + "type": "integer", + "exclusiveMaximum": 10 + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/plugin-draft-07/test.yaml b/testdata/cases/plugin-draft-07/test.yaml new file mode 100644 index 0000000..1fead84 --- /dev/null +++ b/testdata/cases/plugin-draft-07/test.yaml @@ -0,0 +1,12 @@ +name: "plugin-draft-07" +description: "" + +inputFiles: ["test.proto"] +inputParameters: + draft: Draft07 + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/plugin-draft-201909/test.proto b/testdata/cases/plugin-draft-201909/test.proto new file mode 100644 index 0000000..a99efee --- /dev/null +++ b/testdata/cases/plugin-draft-201909/test.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + // default option + string string1 = 1; + + // min/max + string string2 = 2 [(pubg.jsonschema.field) = {string: {min_length: 1, max_length: 100, }}]; + + // min/max with zero value + string string3 = 3 [(pubg.jsonschema.field) = {string: {min_length: 0, max_length: 0, }}]; + + + int64 int64 = 4 [(pubg.jsonschema.field) = {numeric:{exclusive_maximum: 10}}]; +} diff --git a/testdata/cases/plugin-draft-201909/test.schema.json b/testdata/cases/plugin-draft-201909/test.schema.json new file mode 100644 index 0000000..17db504 --- /dev/null +++ b/testdata/cases/plugin-draft-201909/test.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Values": { + "properties": { + "string1": { + "$ref": "#/$defs/.tests.Values.string1" + }, + "string2": { + "$ref": "#/$defs/.tests.Values.string2" + }, + "string3": { + "$ref": "#/$defs/.tests.Values.string3" + }, + "int64": { + "$ref": "#/$defs/.tests.Values.int64" + } + }, + "type": "object", + "required": [ + "string1", + "string2", + "string3", + "int64" + ] + }, + ".tests.Values.string1": { + "type": "string", + "description": "default option" + }, + ".tests.Values.string2": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "min/max" + }, + ".tests.Values.string3": { + "type": "string", + "maxLength": 0, + "minLength": 0, + "description": "min/max with zero value" + }, + ".tests.Values.int64": { + "type": "integer", + "exclusiveMaximum": 10 + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/plugin-draft-201909/test.yaml b/testdata/cases/plugin-draft-201909/test.yaml new file mode 100644 index 0000000..ca8caab --- /dev/null +++ b/testdata/cases/plugin-draft-201909/test.yaml @@ -0,0 +1,12 @@ +name: "plugin-draft-201909" +description: "" + +inputFiles: ["test.proto"] +inputParameters: + draft: Draft201909 + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/plugin-draft-202012/test.proto b/testdata/cases/plugin-draft-202012/test.proto new file mode 100644 index 0000000..a99efee --- /dev/null +++ b/testdata/cases/plugin-draft-202012/test.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + // default option + string string1 = 1; + + // min/max + string string2 = 2 [(pubg.jsonschema.field) = {string: {min_length: 1, max_length: 100, }}]; + + // min/max with zero value + string string3 = 3 [(pubg.jsonschema.field) = {string: {min_length: 0, max_length: 0, }}]; + + + int64 int64 = 4 [(pubg.jsonschema.field) = {numeric:{exclusive_maximum: 10}}]; +} diff --git a/testdata/cases/plugin-draft-202012/test.schema.json b/testdata/cases/plugin-draft-202012/test.schema.json new file mode 100644 index 0000000..fb1e621 --- /dev/null +++ b/testdata/cases/plugin-draft-202012/test.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Values": { + "properties": { + "string1": { + "$ref": "#/$defs/.tests.Values.string1" + }, + "string2": { + "$ref": "#/$defs/.tests.Values.string2" + }, + "string3": { + "$ref": "#/$defs/.tests.Values.string3" + }, + "int64": { + "$ref": "#/$defs/.tests.Values.int64" + } + }, + "type": "object", + "required": [ + "string1", + "string2", + "string3", + "int64" + ] + }, + ".tests.Values.string1": { + "type": "string", + "description": "default option" + }, + ".tests.Values.string2": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "min/max" + }, + ".tests.Values.string3": { + "type": "string", + "maxLength": 0, + "minLength": 0, + "description": "min/max with zero value" + }, + ".tests.Values.int64": { + "type": "integer", + "exclusiveMaximum": 10 + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/plugin-draft-202012/test.yaml b/testdata/cases/plugin-draft-202012/test.yaml new file mode 100644 index 0000000..b75a1ca --- /dev/null +++ b/testdata/cases/plugin-draft-202012/test.yaml @@ -0,0 +1,12 @@ +name: "plugin-draft-202012" +description: "" + +inputFiles: ["test.proto"] +inputParameters: + draft: Draft202012 + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/plugin-entrypoint/test.proto b/testdata/cases/plugin-entrypoint/test.proto new file mode 100644 index 0000000..4bac663 --- /dev/null +++ b/testdata/cases/plugin-entrypoint/test.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +// This is values1 message +message Values { + // default option + string string1 = 1; + + // min/max + string string2 = 2 [(pubg.jsonschema.field) = {string: {min_length: 1, max_length: 100, }}]; + + // min/max with zero value + string string3 = 3 [(pubg.jsonschema.field) = {string: {min_length: 0, max_length: 0, }}]; + + + int64 int64 = 4 [(pubg.jsonschema.field) = {numeric:{exclusive_maximum: 10}}]; +} + +// This is values2 message +message Values2 { + + int32 int32 = 1 [(pubg.jsonschema.field) = {numeric:{exclusive_minimum: 10}}]; + + int32 int32_2 = 2 [(pubg.jsonschema.field) = {numeric:{exclusive_minimum: 10, exclusive_maximum: 20}}]; + + string string = 3 [(pubg.jsonschema.field) = {string:{pattern: "^[a-zA-Z0-9]+$"}}]; + + map map = 4 [(pubg.jsonschema.field) = {}]; +} diff --git a/testdata/cases/plugin-entrypoint/test.schema.json b/testdata/cases/plugin-entrypoint/test.schema.json new file mode 100644 index 0000000..4ad0c6d --- /dev/null +++ b/testdata/cases/plugin-entrypoint/test.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values2", + "$defs": { + ".tests.Values2": { + "properties": { + "int32": { + "$ref": "#/$defs/.tests.Values2.int32" + }, + "int32_2": { + "$ref": "#/$defs/.tests.Values2.int32_2" + }, + "string": { + "$ref": "#/$defs/.tests.Values2.string" + }, + "map": { + "$ref": "#/$defs/.tests.Values2.map" + } + }, + "type": "object", + "required": [ + "int32", + "int32_2", + "string", + "map" + ], + "description": "This is values2 message" + }, + ".tests.Values2.int32": { + "type": "integer", + "exclusiveMinimum": 10 + }, + ".tests.Values2.int32_2": { + "type": "integer", + "exclusiveMaximum": 20, + "exclusiveMinimum": 10 + }, + ".tests.Values2.string": { + "type": "string", + "pattern": "^[a-zA-Z0-9]+$" + }, + ".tests.Values2.map": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/plugin-entrypoint/test.yaml b/testdata/cases/plugin-entrypoint/test.yaml new file mode 100644 index 0000000..044632e --- /dev/null +++ b/testdata/cases/plugin-entrypoint/test.yaml @@ -0,0 +1,12 @@ +name: "plugin-entrypoint" +description: "" + +inputFiles: ["test.proto"] +inputParameters: + entrypoint_message: "Values2" + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/plugin-output-yaml/test.proto b/testdata/cases/plugin-output-yaml/test.proto new file mode 100644 index 0000000..855315d --- /dev/null +++ b/testdata/cases/plugin-output-yaml/test.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + repeated string val1 = 1; + + repeated int64 val2 = 2 + [(pubg.jsonschema.field) = { + title: "My Title" + description: "My Description" + nullable: true + }]; + + repeated float optioned1 = 3 + [(pubg.jsonschema.field) = {array:{ + max_items: 3 + min_items: 1 + }}]; + + repeated double optioned2 = 4 + [(pubg.jsonschema.field) = {array:{ + max_items: 3 + min_items: 1 + unique_items: true + }}]; + + repeated double optioned3 = 5 + [(pubg.jsonschema.field) = {array:{ + max_items: 3 + min_items: 1 + unique_items: false + }}]; + + repeated MyMessage message = 6; + + repeated MyEnum enum = 7; +} + +message MyMessage { + repeated string val1 = 1; + + repeated int64 val2 = 2; +} + +enum MyEnum { + FOO = 0; + BAR = 1; + BAZ = 2; +} diff --git a/testdata/cases/plugin-output-yaml/test.schema.yaml b/testdata/cases/plugin-output-yaml/test.schema.yaml new file mode 100644 index 0000000..a00a7fa --- /dev/null +++ b/testdata/cases/plugin-output-yaml/test.schema.yaml @@ -0,0 +1,95 @@ +$defs: + .tests.MyEnum: + enum: + - FOO + - BAR + - BAZ + type: string + .tests.MyMessage: + properties: + val1: + $ref: '#/$defs/.tests.MyMessage.val1' + val2: + $ref: '#/$defs/.tests.MyMessage.val2' + required: + - val1 + - val2 + type: object + .tests.MyMessage.val1: + items: + type: string + type: array + .tests.MyMessage.val2: + items: + type: integer + type: array + .tests.Values: + properties: + enum: + $ref: '#/$defs/.tests.Values.enum' + message: + $ref: '#/$defs/.tests.Values.message' + optioned1: + $ref: '#/$defs/.tests.Values.optioned1' + optioned2: + $ref: '#/$defs/.tests.Values.optioned2' + optioned3: + $ref: '#/$defs/.tests.Values.optioned3' + val1: + $ref: '#/$defs/.tests.Values.val1' + val2: + anyOf: + - type: "null" + - $ref: '#/$defs/.tests.Values.val2' + required: + - val1 + - val2 + - optioned1 + - optioned2 + - optioned3 + - message + - enum + type: object + .tests.Values.enum: + items: + $ref: '#/$defs/.tests.MyEnum' + type: array + .tests.Values.message: + items: + $ref: '#/$defs/.tests.MyMessage' + type: array + .tests.Values.optioned1: + items: + type: number + maxItems: 3 + minItems: 1 + type: array + .tests.Values.optioned2: + items: + type: number + maxItems: 3 + minItems: 1 + type: array + uniqueItems: true + .tests.Values.optioned3: + items: + type: number + maxItems: 3 + minItems: 1 + type: array + uniqueItems: false + .tests.Values.val1: + items: + type: string + type: array + .tests.Values.val2: + description: My Description + items: + description: My Description + title: My Title + type: integer + title: My Title + type: array +$ref: '#/$defs/.tests.Values' +$schema: https://json-schema.org/draft/2020-12/schema +type: object diff --git a/testdata/cases/plugin-output-yaml/test.yaml b/testdata/cases/plugin-output-yaml/test.yaml new file mode 100644 index 0000000..68995f1 --- /dev/null +++ b/testdata/cases/plugin-output-yaml/test.yaml @@ -0,0 +1,12 @@ +name: "plugin-output-yaml" +description: "" + +inputFiles: ["test.proto"] +inputParameters: + output_file_suffix: ".schema.yaml" + +expectResultFiles: ["test.schema.yaml"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/proto-enum/test.proto b/testdata/cases/proto-enum/test.proto new file mode 100644 index 0000000..610cea5 --- /dev/null +++ b/testdata/cases/proto-enum/test.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + Default default = 1; + + MapToNumber map_to_number = 2; + + MapToString map_to_string = 3; + + MapToCustom map_to_custom = 4; + + MapToCustomIncomplete map_to_custom_incomplete = 5; + + InlineEnum inline_enum = 6; + + enum InlineEnum { + FOO = 0; + BAR = 1; + } +} + +enum Default { + FOODefault0 = 0; + FOODefault1 = 1; +} + +enum MapToNumber { + option (pubg.jsonschema.enum) = {mapping_type: MapToNumber}; + + FOOMapToNumber0 = 0; + FOOMapToNumber1 = 1; +} + +enum MapToString { + option (pubg.jsonschema.enum) = {mapping_type: MapToString}; + + FOOMapToString0 = 0; + FOOMapToString1 = 1; +} + +enum MapToCustom { + option (pubg.jsonschema.enum) = {mapping_type: MapToCustom}; + + FOOMapToCustom0 = 0 [(pubg.jsonschema.enum_value) = {custom_value: {value:"\"foo\""}}]; + FOOMapToCustom1 = 1 [(pubg.jsonschema.enum_value) = {custom_value: {value:"123"}}]; +} + +enum MapToCustomIncomplete { + option (pubg.jsonschema.enum) = {mapping_type: MapToCustom}; + + FOOMapToCustomIncomplete0 = 0 [(pubg.jsonschema.enum_value) = {custom_value: {value:"\"foo\""}}]; + FOOMapToCustomIncomplete1 = 1 [(pubg.jsonschema.enum_value) = {custom_value: {value:"123"}}]; + FOOMapToCustomIncomplete2 = 2; +} diff --git a/testdata/cases/proto-enum/test.schema.json b/testdata/cases/proto-enum/test.schema.json new file mode 100644 index 0000000..f69b7c0 --- /dev/null +++ b/testdata/cases/proto-enum/test.schema.json @@ -0,0 +1,99 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Default": { + "type": "string", + "enum": [ + "FOODefault0", + "FOODefault1" + ] + }, + ".tests.MapToNumber": { + "type": "number", + "enum": [ + 0, + 1 + ] + }, + ".tests.MapToString": { + "type": "string", + "enum": [ + "FOOMapToString0", + "FOOMapToString1" + ] + }, + ".tests.MapToCustom": { + "type": "string", + "enum": [ + "foo", + 123 + ] + }, + ".tests.MapToCustomIncomplete": { + "type": "string", + "enum": [ + "foo", + 123, + "FOOMapToCustomIncomplete2" + ] + }, + ".tests.Values": { + "properties": { + "default": { + "$ref": "#/$defs/.tests.Values.default" + }, + "map_to_number": { + "$ref": "#/$defs/.tests.Values.map_to_number" + }, + "map_to_string": { + "$ref": "#/$defs/.tests.Values.map_to_string" + }, + "map_to_custom": { + "$ref": "#/$defs/.tests.Values.map_to_custom" + }, + "map_to_custom_incomplete": { + "$ref": "#/$defs/.tests.Values.map_to_custom_incomplete" + }, + "inline_enum": { + "$ref": "#/$defs/.tests.Values.inline_enum" + } + }, + "type": "object", + "required": [ + "default", + "map_to_number", + "map_to_string", + "map_to_custom", + "map_to_custom_incomplete", + "inline_enum" + ] + }, + ".tests.Values.InlineEnum": { + "type": "string", + "enum": [ + "FOO", + "BAR" + ] + }, + ".tests.Values.default": { + "$ref": "#/$defs/.tests.Default" + }, + ".tests.Values.map_to_number": { + "$ref": "#/$defs/.tests.MapToNumber" + }, + ".tests.Values.map_to_string": { + "$ref": "#/$defs/.tests.MapToString" + }, + ".tests.Values.map_to_custom": { + "$ref": "#/$defs/.tests.MapToCustom" + }, + ".tests.Values.map_to_custom_incomplete": { + "$ref": "#/$defs/.tests.MapToCustomIncomplete" + }, + ".tests.Values.inline_enum": { + "$ref": "#/$defs/.tests.Values.InlineEnum" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/proto-enum/test.yaml b/testdata/cases/proto-enum/test.yaml new file mode 100644 index 0000000..d3e7be0 --- /dev/null +++ b/testdata/cases/proto-enum/test.yaml @@ -0,0 +1,11 @@ +name: "proto-enum" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/proto-jsonname/test.proto b/testdata/cases/proto-jsonname/test.proto new file mode 100644 index 0000000..e7bbb03 --- /dev/null +++ b/testdata/cases/proto-jsonname/test.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + optional string string_value = 1 [json_name = "string-value"]; + + optional int32 int32_value = 2 [json_name = "int32-value"]; + + optional int64 int64_value = 3 [json_name = "int64-value"]; + + Nested nested_value = 6; + + Enum enum_value = 7; +} + +message Nested { + string value = 1; +} + +enum Enum { + UNKNOWN = 0; + ONE = 1; + TWO = 2; + THREE = 3; +} + + diff --git a/testdata/cases/proto-jsonname/test.schema.json b/testdata/cases/proto-jsonname/test.schema.json new file mode 100644 index 0000000..b1a947f --- /dev/null +++ b/testdata/cases/proto-jsonname/test.schema.json @@ -0,0 +1,131 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Enum": { + "type": "string", + "enum": [ + "UNKNOWN", + "ONE", + "TWO", + "THREE" + ] + }, + ".tests.Values": { + "allOf": [ + { + "oneOf": [ + { + "required": [ + "string_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "string_value" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "required": [ + "int32_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "int32_value" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "required": [ + "int64_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "int64_value" + ] + } + ] + } + } + ] + } + ], + "properties": { + "string_value": { + "$ref": "#/$defs/.tests.Values.string_value" + }, + "int32_value": { + "$ref": "#/$defs/.tests.Values.int32_value" + }, + "int64_value": { + "$ref": "#/$defs/.tests.Values.int64_value" + }, + "nested_value": { + "$ref": "#/$defs/.tests.Values.nested_value" + }, + "enum_value": { + "$ref": "#/$defs/.tests.Values.enum_value" + } + }, + "type": "object", + "required": [ + "nested_value", + "enum_value" + ] + }, + ".tests.Values.string_value": { + "type": "string" + }, + ".tests.Values.int32_value": { + "type": "integer" + }, + ".tests.Values.int64_value": { + "type": "integer" + }, + ".tests.Values.nested_value": { + "$ref": "#/$defs/.tests.Nested" + }, + ".tests.Values.enum_value": { + "$ref": "#/$defs/.tests.Enum" + }, + ".tests.Nested": { + "properties": { + "value": { + "$ref": "#/$defs/.tests.Nested.value" + } + }, + "type": "object", + "required": [ + "value" + ] + }, + ".tests.Nested.value": { + "type": "string" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/proto-jsonname/test.yaml b/testdata/cases/proto-jsonname/test.yaml new file mode 100644 index 0000000..1995a31 --- /dev/null +++ b/testdata/cases/proto-jsonname/test.yaml @@ -0,0 +1,11 @@ +name: "proto-jsonname" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/proto-map/test.proto b/testdata/cases/proto-map/test.proto new file mode 100644 index 0000000..b494416 --- /dev/null +++ b/testdata/cases/proto-map/test.proto @@ -0,0 +1,36 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + map basic_map = 1; + + map int_map = 2; + + map float_map = 3; + + map bool_map = 4; + + map string_map = 5; + + map nested_map = 6; + + map enum_map = 7; +} + +message Nested { + string value = 1; +} + +enum Enum { + UNKNOWN = 0; + ONE = 1; + TWO = 2; + THREE = 3; +} + + diff --git a/testdata/cases/proto-map/test.schema.json b/testdata/cases/proto-map/test.schema.json new file mode 100644 index 0000000..7055597 --- /dev/null +++ b/testdata/cases/proto-map/test.schema.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Enum": { + "type": "string", + "enum": [ + "UNKNOWN", + "ONE", + "TWO", + "THREE" + ] + }, + ".tests.Values": { + "properties": { + "basic_map": { + "$ref": "#/$defs/.tests.Values.basic_map" + }, + "int_map": { + "$ref": "#/$defs/.tests.Values.int_map" + }, + "float_map": { + "$ref": "#/$defs/.tests.Values.float_map" + }, + "bool_map": { + "$ref": "#/$defs/.tests.Values.bool_map" + }, + "string_map": { + "$ref": "#/$defs/.tests.Values.string_map" + }, + "nested_map": { + "$ref": "#/$defs/.tests.Values.nested_map" + }, + "enum_map": { + "$ref": "#/$defs/.tests.Values.enum_map" + } + }, + "type": "object", + "required": [ + "basic_map", + "int_map", + "float_map", + "bool_map", + "string_map", + "nested_map", + "enum_map" + ] + }, + ".tests.Values.basic_map": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + ".tests.Values.int_map": { + "additionalProperties": {}, + "type": "integer" + }, + ".tests.Values.float_map": { + "additionalProperties": { + "type": "number" + }, + "type": "object" + }, + ".tests.Values.bool_map": { + "additionalProperties": { + "type": "boolean" + }, + "type": "object" + }, + ".tests.Values.string_map": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + ".tests.Values.nested_map": { + "additionalProperties": { + "$ref": "#/$defs/.tests.Nested" + }, + "type": "object" + }, + ".tests.Values.enum_map": { + "additionalProperties": { + "$ref": "#/$defs/.tests.Enum" + }, + "type": "object" + }, + ".tests.Nested": { + "properties": { + "value": { + "$ref": "#/$defs/.tests.Nested.value" + } + }, + "type": "object", + "required": [ + "value" + ] + }, + ".tests.Nested.value": { + "type": "string" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/proto-repeated-scala/test.yaml b/testdata/cases/proto-map/test.yaml similarity index 71% rename from testdata/cases/proto-repeated-scala/test.yaml rename to testdata/cases/proto-map/test.yaml index 5fc473a..3d17ac2 100644 --- a/testdata/cases/proto-repeated-scala/test.yaml +++ b/testdata/cases/proto-map/test.yaml @@ -1,10 +1,10 @@ -name: "array of enums" +name: "proto-map" description: "" inputFiles: ["test.proto"] inputParameters: {} -expectResultFiles: ["test.schema"] +expectResultFiles: ["test.schema.json"] expectResultIsNull: false expectFail: false diff --git a/testdata/cases/proto-oneof-multiple/entry.proto b/testdata/cases/proto-oneof-multiple/test.proto similarity index 100% rename from testdata/cases/proto-oneof-multiple/entry.proto rename to testdata/cases/proto-oneof-multiple/test.proto diff --git a/testdata/cases/proto-oneof-multiple/entry.schema.json b/testdata/cases/proto-oneof-multiple/test.schema.json similarity index 75% rename from testdata/cases/proto-oneof-multiple/entry.schema.json rename to testdata/cases/proto-oneof-multiple/test.schema.json index c106159..f9a5111 100644 --- a/testdata/cases/proto-oneof-multiple/entry.schema.json +++ b/testdata/cases/proto-oneof-multiple/test.schema.json @@ -3,36 +3,28 @@ "$ref": "#/$defs/.samples.Values", "$defs": { ".samples.Values": { - "$ref": "#/$defs/", "allOf": [ { - "$ref": "#/$defs/", "oneOf": [ { - "$ref": "#/$defs/", "required": [ "string_value" ] }, { - "$ref": "#/$defs/", "required": [ "int_value" ] }, { - "$ref": "#/$defs/", "not": { - "$ref": "#/$defs/", "anyOf": [ { - "$ref": "#/$defs/", "required": [ "string_value" ] }, { - "$ref": "#/$defs/", "required": [ "int_value" ] @@ -43,33 +35,26 @@ ] }, { - "$ref": "#/$defs/", "oneOf": [ { - "$ref": "#/$defs/", "required": [ "type_name" ] }, { - "$ref": "#/$defs/", "required": [ "type_id" ] }, { - "$ref": "#/$defs/", "not": { - "$ref": "#/$defs/", "anyOf": [ { - "$ref": "#/$defs/", "required": [ "type_name" ] }, { - "$ref": "#/$defs/", "required": [ "type_id" ] @@ -116,46 +101,35 @@ "timestamp", "unit", "description" - ], - "title": "Values" + ] }, ".samples.Values.value": { - "$ref": "#/$defs/", "type": "string" }, ".samples.Values.count": { - "$ref": "#/$defs/", - "type": "number" + "type": "integer" }, ".samples.Values.string_value": { - "$ref": "#/$defs/", "type": "string" }, ".samples.Values.int_value": { - "$ref": "#/$defs/", - "type": "number" + "type": "integer" }, ".samples.Values.timestamp": { - "$ref": "#/$defs/", - "type": "number" + "type": "integer" }, ".samples.Values.unit": { - "$ref": "#/$defs/", "type": "string" }, ".samples.Values.description": { - "$ref": "#/$defs/", "type": "string" }, ".samples.Values.type_name": { - "$ref": "#/$defs/", "type": "string" }, ".samples.Values.type_id": { - "$ref": "#/$defs/", "type": "string" } }, - "type": "object", - "description": "Generated by protoc-gen-jsonschema" + "type": "object" } \ No newline at end of file diff --git a/testdata/cases/proto-oneof-multiple/test.yaml b/testdata/cases/proto-oneof-multiple/test.yaml new file mode 100644 index 0000000..eb2a82d --- /dev/null +++ b/testdata/cases/proto-oneof-multiple/test.yaml @@ -0,0 +1,11 @@ +name: "proto-onoof-multiple" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/proto-oneof-single/entry.proto b/testdata/cases/proto-oneof-single/test.proto similarity index 100% rename from testdata/cases/proto-oneof-single/entry.proto rename to testdata/cases/proto-oneof-single/test.proto diff --git a/testdata/cases/proto-oneof-single/entry.schema.json b/testdata/cases/proto-oneof-single/test.schema.json similarity index 75% rename from testdata/cases/proto-oneof-single/entry.schema.json rename to testdata/cases/proto-oneof-single/test.schema.json index 0b58696..36fe063 100644 --- a/testdata/cases/proto-oneof-single/entry.schema.json +++ b/testdata/cases/proto-oneof-single/test.schema.json @@ -3,60 +3,48 @@ "$ref": "#/$defs/.samples.Values", "$defs": { ".samples.Values": { - "$ref": "#/$defs/", "allOf": [ { - "$ref": "#/$defs/", "oneOf": [ { - "$ref": "#/$defs/", "required": [ "string_value" ] }, { - "$ref": "#/$defs/", "required": [ "int_value" ] }, { - "$ref": "#/$defs/", "required": [ "bool_value" ] }, { - "$ref": "#/$defs/", "required": [ "double_value" ] }, { - "$ref": "#/$defs/", "not": { - "$ref": "#/$defs/", "anyOf": [ { - "$ref": "#/$defs/", "required": [ "string_value" ] }, { - "$ref": "#/$defs/", "required": [ "int_value" ] }, { - "$ref": "#/$defs/", "required": [ "bool_value" ] }, { - "$ref": "#/$defs/", "required": [ "double_value" ] @@ -91,34 +79,26 @@ "required": [ "value", "count" - ], - "title": "Values" + ] }, ".samples.Values.value": { - "$ref": "#/$defs/", "type": "string" }, ".samples.Values.count": { - "$ref": "#/$defs/", - "type": "number" + "type": "integer" }, ".samples.Values.string_value": { - "$ref": "#/$defs/", "type": "string" }, ".samples.Values.int_value": { - "$ref": "#/$defs/", - "type": "number" + "type": "integer" }, ".samples.Values.bool_value": { - "$ref": "#/$defs/", "type": "boolean" }, ".samples.Values.double_value": { - "$ref": "#/$defs/", "type": "number" } }, - "type": "object", - "description": "Generated by protoc-gen-jsonschema" + "type": "object" } \ No newline at end of file diff --git a/testdata/cases/proto-oneof-single/test.yaml b/testdata/cases/proto-oneof-single/test.yaml new file mode 100644 index 0000000..9ac005a --- /dev/null +++ b/testdata/cases/proto-oneof-single/test.yaml @@ -0,0 +1,11 @@ +name: "proto-oneof-single" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/proto-optional/test.proto b/testdata/cases/proto-optional/test.proto new file mode 100644 index 0000000..5e686f7 --- /dev/null +++ b/testdata/cases/proto-optional/test.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +message Values { + optional string string_value = 1; + + optional int32 int32_value = 2; + + optional int64 int64_value = 3; + + string string_value2 = 4; + + int32 int32_value2 = 5; + + Nested nested_value = 6; + + Enum enum_value = 7; + + optional Nested optional_nested_value = 8; + + optional Enum optional_enum_value = 9; +} + +message Nested { + string value = 1; +} + +enum Enum { + UNKNOWN = 0; + ONE = 1; + TWO = 2; + THREE = 3; +} + + diff --git a/testdata/cases/proto-optional/test.schema.json b/testdata/cases/proto-optional/test.schema.json new file mode 100644 index 0000000..d389ea4 --- /dev/null +++ b/testdata/cases/proto-optional/test.schema.json @@ -0,0 +1,197 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Enum": { + "type": "string", + "enum": [ + "UNKNOWN", + "ONE", + "TWO", + "THREE" + ] + }, + ".tests.Values": { + "allOf": [ + { + "oneOf": [ + { + "required": [ + "string_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "string_value" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "required": [ + "int32_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "int32_value" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "required": [ + "int64_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "int64_value" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "required": [ + "optional_nested_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "optional_nested_value" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "required": [ + "optional_enum_value" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "optional_enum_value" + ] + } + ] + } + } + ] + } + ], + "properties": { + "string_value": { + "$ref": "#/$defs/.tests.Values.string_value" + }, + "int32_value": { + "$ref": "#/$defs/.tests.Values.int32_value" + }, + "int64_value": { + "$ref": "#/$defs/.tests.Values.int64_value" + }, + "string_value2": { + "$ref": "#/$defs/.tests.Values.string_value2" + }, + "int32_value2": { + "$ref": "#/$defs/.tests.Values.int32_value2" + }, + "nested_value": { + "$ref": "#/$defs/.tests.Values.nested_value" + }, + "enum_value": { + "$ref": "#/$defs/.tests.Values.enum_value" + }, + "optional_nested_value": { + "$ref": "#/$defs/.tests.Values.optional_nested_value" + }, + "optional_enum_value": { + "$ref": "#/$defs/.tests.Values.optional_enum_value" + } + }, + "type": "object", + "required": [ + "string_value2", + "int32_value2", + "nested_value", + "enum_value" + ] + }, + ".tests.Values.string_value": { + "type": "string" + }, + ".tests.Values.int32_value": { + "type": "integer" + }, + ".tests.Values.int64_value": { + "type": "integer" + }, + ".tests.Values.string_value2": { + "type": "string" + }, + ".tests.Values.int32_value2": { + "type": "integer" + }, + ".tests.Values.nested_value": { + "$ref": "#/$defs/.tests.Nested" + }, + ".tests.Values.enum_value": { + "$ref": "#/$defs/.tests.Enum" + }, + ".tests.Values.optional_nested_value": { + "$ref": "#/$defs/.tests.Nested" + }, + ".tests.Values.optional_enum_value": { + "$ref": "#/$defs/.tests.Enum" + }, + ".tests.Nested": { + "properties": { + "value": { + "$ref": "#/$defs/.tests.Nested.value" + } + }, + "type": "object", + "required": [ + "value" + ] + }, + ".tests.Nested.value": { + "type": "string" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/proto-optional/test.yaml b/testdata/cases/proto-optional/test.yaml new file mode 100644 index 0000000..04d67d5 --- /dev/null +++ b/testdata/cases/proto-optional/test.yaml @@ -0,0 +1,11 @@ +name: "proto-optional" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/proto-repeated-scala/test.proto b/testdata/cases/proto-repeated-scala/test.proto deleted file mode 100644 index 9d588b4..0000000 --- a/testdata/cases/proto-repeated-scala/test.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package tests; - -import "jsonschema.proto"; - -option (pubg.jsonschema.file) = {entrypoint_message: "ArrayOfEnums"}; - -message ArrayOfEnums { - string description = 1; - enum inline { - FOO = 0; - BAR = 1; - FIZZ = 2; - BUZZ = 3; - } - repeated inline stuff = 2; -} diff --git a/testdata/cases/proto-repeated-scala/test.schema.json b/testdata/cases/proto-repeated-scala/test.schema.json deleted file mode 100644 index 9605088..0000000 --- a/testdata/cases/proto-repeated-scala/test.schema.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "#/$defs/.tests.ArrayOfEnums", - "$defs": { - ".tests.ArrayOfEnums": { - "properties": { - "description": { - "$ref": "#/$defs/.tests.ArrayOfEnums.description" - }, - "stuff": { - "$ref": "#/$defs/.tests.ArrayOfEnums.stuff" - } - }, - "type": "object", - "required": [ - "description", - "stuff" - ], - "title": "ArrayOfEnums" - }, - ".tests.ArrayOfEnums.inline": { - "type": "string", - "enum": [ - "FOO", - "BAR", - "FIZZ", - "BUZZ" - ] - }, - ".tests.ArrayOfEnums.description": { - "type": "string" - }, - ".tests.ArrayOfEnums.stuff": { - "items": { - "$ref": "#/$defs/.tests.ArrayOfEnums.inline" - }, - "type": "array" - } - }, - "type": "object", - "description": "Generated by protoc-gen-jsonschema" -} \ No newline at end of file diff --git a/testdata/cases/wellknown-k8s/test.proto b/testdata/cases/wellknown-k8s/test.proto new file mode 100644 index 0000000..6f214a7 --- /dev/null +++ b/testdata/cases/wellknown-k8s/test.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +// TODO: import k8s proto files +message Values { + // corev1 int or string + // corev1 volumes + // corev1 ... +} diff --git a/testdata/cases/wellknown-k8s/test.schema.json b/testdata/cases/wellknown-k8s/test.schema.json new file mode 100644 index 0000000..d13700a --- /dev/null +++ b/testdata/cases/wellknown-k8s/test.schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Values": { + "properties": {}, + "type": "object", + "description": "TODO: import k8s proto files\n corev1 int or string\n corev1 volumes\n corev1 ..." + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/wellknown-k8s/test.yaml b/testdata/cases/wellknown-k8s/test.yaml new file mode 100644 index 0000000..1f1d613 --- /dev/null +++ b/testdata/cases/wellknown-k8s/test.yaml @@ -0,0 +1,11 @@ +name: "wellknown-k8s" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/cases/wellknown-proto/test.proto b/testdata/cases/wellknown-proto/test.proto new file mode 100644 index 0000000..625f898 --- /dev/null +++ b/testdata/cases/wellknown-proto/test.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package tests; + +import "jsonschema.proto"; + +option (pubg.jsonschema.file) = {entrypoint_message: "Values"}; + +import "google/protobuf/any.proto"; + +import "google/protobuf/timestamp.proto"; + +import "google/protobuf/duration.proto"; + +message Values { + google.protobuf.Any any = 1; + + google.protobuf.Duration duration = 2; + + google.protobuf.Timestamp timestamp = 3; +} diff --git a/testdata/cases/wellknown-proto/test.schema.json b/testdata/cases/wellknown-proto/test.schema.json new file mode 100644 index 0000000..c2a320b --- /dev/null +++ b/testdata/cases/wellknown-proto/test.schema.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "#/$defs/.tests.Values", + "$defs": { + ".tests.Values": { + "properties": { + "any": { + "$ref": "#/$defs/.tests.Values.any" + }, + "duration": { + "$ref": "#/$defs/.tests.Values.duration" + }, + "timestamp": { + "$ref": "#/$defs/.tests.Values.timestamp" + } + }, + "type": "object", + "required": [ + "any", + "duration", + "timestamp" + ] + }, + ".tests.Values.any": { + "type": "object" + }, + ".tests.Values.duration": { + "type": "string", + "format": "duration" + }, + ".tests.Values.timestamp": { + "type": "string", + "format": "date-time" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/testdata/cases/wellknown-proto/test.yaml b/testdata/cases/wellknown-proto/test.yaml new file mode 100644 index 0000000..b62faa5 --- /dev/null +++ b/testdata/cases/wellknown-proto/test.yaml @@ -0,0 +1,11 @@ +name: "wellknown-proto" +description: "" + +inputFiles: ["test.proto"] +inputParameters: {} + +expectResultFiles: ["test.schema.json"] +expectResultIsNull: false +expectFail: false + +expectedBehaviorDescription: "" diff --git a/testdata/do_test.go b/testdata/do_test.go new file mode 100644 index 0000000..c306b7d --- /dev/null +++ b/testdata/do_test.go @@ -0,0 +1,179 @@ +package testdata + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "testing" + + pgs "github.com/lyft/protoc-gen-star/v2" + "github.com/lyft/protoc-gen-star/v2/testutils" + "github.com/pubg/protoc-gen-jsonschema/pkg/modules" + "github.com/samber/lo" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/util/yaml" +) + +type Testcase struct { + // Testcase Identifier + Name string `json:"name"` + + // Testcase Description + Description string `json:"description"` + ExpectedBehaviorDescription string `json:"expectedBehaviorDescription"` + + // Testcase Input + InputFiles []string `json:"inputFiles"` + InputParameters map[string]string `json:"inputParameters"` + + // Expected result + ExpectResultFiles []string `json:"expectResultFiles"` + ExpectResultIsNull bool `json:"expectResultIsNull"` + ExpectFail bool `json:"expectFail"` +} + +const testdataDir = "./cases" +const optionsDir = "../proto" + +func TestPlugin(t *testing.T) { + dirs, err := os.ReadDir(testdataDir) + if err != nil { + t.Fatal(err) + } + optionsImportPath, _ := filepath.Abs(optionsDir) + + for _, dir := range dirs { + tc, err := loadTestcase(testdataDir, dir) + if err != nil { + t.Fatal(err) + } + + t.Run(dir.Name(), func(t *testing.T) { + // Load testcase + dirPath := filepath.Join(testdataDir, dir.Name()) + module, debugger := newModule(tc, dirPath) + ast := loadInput(t, tc, dirPath, optionsImportPath) + + // Execute testcase + artifacts := module.Execute(ast.Targets(), ast.Packages()) + + // Check testcase result + if tc.ExpectFail { + if !debugger.Failed() { + t.Errorf("Expect failed, but got success") + } + return + } + + if tc.ExpectResultIsNull { + if len(artifacts) != 0 { + t.Errorf("Expect result is null, but got %d of results", len(artifacts)) + } + return + } + + expectedResult, err := loadExpectedResult(dirPath, tc.ExpectResultFiles) + if err != nil { + t.Errorf("failed to load expected result: %s", err.Error()) + return + } + if len(artifacts) != len(tc.ExpectResultFiles) { + t.Errorf("Expect %d of results, but got %d of results", len(tc.ExpectResultFiles), len(artifacts)) + return + } + for _, artifact := range artifacts { + fArtifact, ok := artifact.(pgs.GeneratorFile) + if !ok { + t.Errorf("artifact is not GeneratorFile, but %T", artifact) + return + } + + var actual any + err := yaml.Unmarshal([]byte(fArtifact.Contents), &actual) + if err != nil { + t.Errorf("failed to convert to comparable component: %s", err.Error()) + return + } + expected := expectedResult.results[fArtifact.Name] + + require.Equal(t, expected, actual, "not equals at index %s: %s", tc.Name, tc.Description) + } + }) + } +} + +func loadTestcase(parentDir string, dir os.DirEntry) (*Testcase, error) { + if !dir.IsDir() { + return nil, fmt.Errorf("dir %s is not directory", dir.Name()) + } + + dirPath := filepath.Join(parentDir, dir.Name()) + + buf, err := os.ReadFile(filepath.Join(dirPath, "test.yaml")) + if err != nil { + return nil, err + } + testcase := &Testcase{} + if err := yaml.Unmarshal(buf, testcase); err != nil { + return nil, err + } + return testcase, nil +} + +func loadInput(t *testing.T, tc *Testcase, dirPath string, optionsImportPath string) pgs.AST { + loader := &testutils.Loader{ImportPaths: []string{dirPath, optionsImportPath}} + inputFiles := lo.Map[string, string](tc.InputFiles, func(item string, _ int) string { return filepath.Join(dirPath, item) }) + ast := loader.LoadProtos(t, inputFiles...) + + protoFiles := map[string]pgs.File{} + for _, pkg := range ast.Packages() { + for _, file := range pkg.Files() { + protoFiles[file.InputPath().String()] = file + } + } + for _, inputFile := range tc.InputFiles { + ast.Targets()[inputFile] = protoFiles[inputFile] + } + return ast +} + +func newModule(tc *Testcase, dirPath string) (*modules.Module, pgs.MockDebugger) { + debugger := pgs.InitMockDebugger() + module := modules.NewModule() + module.InitContext(pgs.Context(debugger, tc.InputParameters, dirPath)) + return module, debugger +} + +type ExpectedResult struct { + results map[string]any +} + +func loadExpectedResult(dirPath string, files []string) (*ExpectedResult, error) { + result := &ExpectedResult{results: map[string]any{}} + for _, file := range files { + buf, err := os.ReadFile(filepath.Join(dirPath, file)) + if err != nil { + return nil, err + } + + var a any + err = yaml.Unmarshal(buf, &a) + if err != nil { + return nil, err + } + + result.results[file] = a + } + return result, nil +} + +func convertToComparableComponent(buf []byte) ([]any, error) { + containers := [][]any{} + err := json.Unmarshal(buf, &containers) + if err != nil { + return nil, err + } + + return lo.FlatMap[[]any, any](containers, func(container []any, _ int) []any { return container }), nil +} diff --git a/testdata/go.mod b/testdata/go.mod new file mode 100644 index 0000000..09ba8aa --- /dev/null +++ b/testdata/go.mod @@ -0,0 +1,28 @@ +module github.com/pubg/protoc-gen-jsonschema/testdata + +go 1.21.1 + +require ( + github.com/lyft/protoc-gen-star/v2 v2.0.3 + github.com/pubg/protoc-gen-jsonschema v0.0.0 + github.com/samber/lo v1.38.1 + github.com/stretchr/testify v1.8.2 + k8s.io/apimachinery v0.28.1 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/afero v1.3.3 // indirect + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/text v0.11.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) + +replace github.com/pubg/protoc-gen-jsonschema => ../ diff --git a/testdata/go.sum b/testdata/go.sum new file mode 100644 index 0000000..8f5c6d3 --- /dev/null +++ b/testdata/go.sum @@ -0,0 +1,64 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk= +github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lyft/protoc-gen-star/v2 v2.0.3 h1:/3+/2sWyXeMLzKd1bX+ixWKgEMsULrIivpDsuaF441o= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= +github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/spf13/afero v1.3.3 h1:p5gZEKLYoL7wh8VrJesMaYeNxdEd1v3cb4irOk9zB54= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/apimachinery v0.28.1 h1:EJD40og3GizBSV3mkIoXQBsws32okPOy+MkRyzh6nPY= +k8s.io/apimachinery v0.28.1/go.mod h1:X0xh/chESs2hP9koe+SdIAcXWcQ+RM5hy0ZynB+yEvw= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/testdata/hack/generate_all_test_result.sh b/testdata/hack/generate_all_test_result.sh index 082582e..d95fb32 100755 --- a/testdata/hack/generate_all_test_result.sh +++ b/testdata/hack/generate_all_test_result.sh @@ -3,19 +3,40 @@ set -eux cd $(dirname $0) - -go build -o protoc-gen-jsonschema ../../main.go - proto_dirs=$(ls ../cases) +cd $(git rev-parse --show-toplevel) +go build -o ./testdata/hack/protoc-gen-jsonschema main.go + for proto_dir in $proto_dirs; do - protoc \ - --plugin=protoc-gen-jsonschema=./protoc-gen-jsonschema \ - --jsonschema_out=../cases/$proto_dir \ - --jsonschema_opt=pretty_json_output=true \ - -I ../../proto \ - -I ../cases/$proto_dir \ - ../cases/$proto_dir/*.proto + + command="protoc \ + --plugin=protoc-gen-jsonschema=./testdata/hack/protoc-gen-jsonschema \ + --jsonschema_out=./testdata/cases/$proto_dir " # 결과 문자열 초기화 + + # test.yaml 파일의 존재 여부 확인 + if [[ -f "./testdata/cases/$proto_dir/test.yaml" ]]; then + # test.yaml에서 inputParameters 부분을 읽고 JSON 형식으로 파싱 + parameters=$(yq eval '.inputParameters' ./testdata/cases/$proto_dir/test.yaml) + + # inputParameters가 없거나 비어 있지 않은지 확인 + if [[ "$parameters" != "null" && "$parameters" != "{}" ]]; then + # key-value 쌍을 반복하면서 --jsonschema_opt== 형태로 문자열 결합 + while IFS=":" read -r key value; do + key=$(echo $key | tr -d ' "') + value=$(echo $value | tr -d ' "') + command="${command} --jsonschema_opt=${key}=${value}" + done <<< "$parameters" + fi + fi + + command="$command \ + -I proto \ + -I testdata/cases/$proto_dir \ + testdata/cases/$proto_dir/*.proto + " + + $command done -rm protoc-gen-jsonschema +rm ./testdata/hack/protoc-gen-jsonschema diff --git a/testdata/hack/generate_test_result.sh b/testdata/hack/generate_test_result.sh index 88768c6..bf14aff 100755 --- a/testdata/hack/generate_test_result.sh +++ b/testdata/hack/generate_test_result.sh @@ -6,13 +6,42 @@ proto_dir=$1 cd $(dirname $0) -go build -o protoc-gen-venus ../../main.go +cd $(git rev-parse --show-toplevel) -protoc \ - --plugin=protoc-gen-venus=./protoc-gen-venus \ - --venus_out=../cases/$proto_dir \ - -I ../../proto \ - -I ../cases/$proto_dir \ - ../cases/$proto_dir/*.proto +go build -o ./testdata/hack/protoc-gen-jsonschema main.go -rm protoc-gen-venus +function generateProtoFile() { + proto_dir=$1 + + command="protoc \ + --plugin=protoc-gen-jsonschema=./testdata/hack/protoc-gen-jsonschema \ + --jsonschema_out=./testdata/cases/$proto_dir " # 초기 명령어 추가 + + # test.yaml 파일의 존재 여부 확인 + if [[ -f "./testdata/cases/$proto_dir/test.yaml" ]]; then + # test.yaml에서 inputParameters 부분을 읽고 JSON 형식으로 파싱 + parameters=$(yq eval '.inputParameters' ./testdata/cases/$proto_dir/test.yaml) + + # inputParameters가 없거나 비어 있지 않은지 확인 + if [[ "$parameters" != "null" && "$parameters" != "{}" ]]; then + # key-value 쌍을 반복하면서 --jsonschema_opt== 형태로 문자열 결합 + while IFS=":" read -r key value; do + key=$(echo $key | tr -d ' "') + value=$(echo $value | tr -d ' "') + command="${command} --jsonschema_opt=${key}=${value}" + done <<< "$parameters" + fi + fi + + command="$command \ + -I proto \ + -I testdata/cases/$proto_dir \ + testdata/cases/$proto_dir/*.proto + " + + $command +} + +generateProtoFile $proto_dir + +rm ./testdata/hack/protoc-gen-jsonschema