From fd4a187e4262e9a6b002aee24042f9f1fca53f84 Mon Sep 17 00:00:00 2001 From: Sam Lown Date: Tue, 31 Dec 2024 11:54:59 +0000 Subject: [PATCH] Testing support for full comments --- fixtures/go_comments_full.json | 113 +++++++++++++++++++++++++++++++++ reflect_comments.go | 5 +- reflect_comments_test.go | 37 +++++++++++ reflect_test.go | 11 ---- 4 files changed, 153 insertions(+), 13 deletions(-) create mode 100644 fixtures/go_comments_full.json create mode 100644 reflect_comments_test.go diff --git a/fixtures/go_comments_full.json b/fixtures/go_comments_full.json new file mode 100644 index 0000000..d1a5219 --- /dev/null +++ b/fixtures/go_comments_full.json @@ -0,0 +1,113 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/invopop/jsonschema/examples/user", + "$ref": "#/$defs/User", + "$defs": { + "NamedPets": { + "additionalProperties": { + "$ref": "#/$defs/Pet" + }, + "type": "object", + "description": "NamedPets is a map of animal names to pets." + }, + "Pet": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name of the animal." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name" + ], + "description": "Pet defines the user's fury friend." + }, + "Pets": { + "items": { + "$ref": "#/$defs/Pet" + }, + "type": "array", + "description": "Pets is a collection of Pet objects." + }, + "Plant": { + "properties": { + "variant": { + "type": "string", + "title": "Variant", + "description": "This comment will be used" + }, + "multicellular": { + "type": "boolean", + "title": "Multicellular", + "description": "Multicellular is true if the plant is multicellular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "variant" + ], + "description": "Plant represents the plants the user might have and serves as a test\nof structs inside a `type` set." + }, + "User": { + "properties": { + "id": { + "type": "integer", + "description": "Unique sequential identifier." + }, + "name": { + "type": "string", + "maxLength": 20, + "minLength": 1, + "pattern": ".*", + "title": "the name", + "description": "this is a property", + "default": "alex", + "examples": [ + "joe", + "lucy" + ] + }, + "friends": { + "items": { + "type": "integer" + }, + "type": "array", + "description": "list of IDs, omitted when empty" + }, + "tags": { + "type": "object" + }, + "pets": { + "$ref": "#/$defs/Pets", + "description": "An array of pets the user cares for." + }, + "named_pets": { + "$ref": "#/$defs/NamedPets", + "description": "Set of animal names to pets" + }, + "plants": { + "items": { + "$ref": "#/$defs/Plant" + }, + "type": "array", + "title": "Plants", + "description": "Set of plants that the user likes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "name", + "pets", + "named_pets", + "plants" + ], + "description": "User is used as a base to provide tests for comments.\nDon't forget to checkout the nested path." + } + } +} \ No newline at end of file diff --git a/reflect_comments.go b/reflect_comments.go index cfb3df1..eaa498a 100644 --- a/reflect_comments.go +++ b/reflect_comments.go @@ -40,8 +40,9 @@ func WithFullComment() CommentOption { // parameter, the URL used to import that package, is thus required to be able to match // reflected types. // -// When parsing type comments, we use the `go/doc`'s Synopsis method to extract the first -// phrase only. Field comments, which tend to be much shorter, will include everything. +// When parsing type comments, by default we use the `go/doc`'s Synopsis method to extract +// the first phrase only. Field comments, which tend to be much shorter, will include everything. +// This behavior can be changed by using the `WithFullComment` option. func (r *Reflector) AddGoComments(base, path string, opts ...CommentOption) error { if r.CommentMap == nil { r.CommentMap = make(map[string]string) diff --git a/reflect_comments_test.go b/reflect_comments_test.go new file mode 100644 index 0000000..e162b2b --- /dev/null +++ b/reflect_comments_test.go @@ -0,0 +1,37 @@ +package jsonschema + +import ( + "path/filepath" + "strings" + "testing" + + "github.com/invopop/jsonschema/examples" + "github.com/stretchr/testify/require" +) + +func TestCommentsSchemaGeneration(t *testing.T) { + tests := []struct { + typ any + reflector *Reflector + fixture string + }{ + {&examples.User{}, prepareCommentReflector(t), "fixtures/go_comments.json"}, + {&examples.User{}, prepareCommentReflector(t, WithFullComment()), "fixtures/go_comments_full.json"}, + } + for _, tt := range tests { + name := strings.TrimSuffix(filepath.Base(tt.fixture), ".json") + t.Run(name, func(t *testing.T) { + compareSchemaOutput(t, + tt.fixture, tt.reflector, tt.typ, + ) + }) + } +} + +func prepareCommentReflector(t *testing.T, opts ...CommentOption) *Reflector { + t.Helper() + r := new(Reflector) + err := r.AddGoComments("github.com/invopop/jsonschema", "./examples", opts...) + require.NoError(t, err, "did not expect error while adding comments") + return r +} diff --git a/reflect_test.go b/reflect_test.go index 3358fc2..93bee67 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -13,8 +13,6 @@ import ( "testing" "time" - "github.com/invopop/jsonschema/examples" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -446,7 +444,6 @@ func TestSchemaGeneration(t *testing.T) { {&CustomMapOuter{}, &Reflector{}, "fixtures/custom_map_type.json"}, {&CustomTypeFieldWithInterface{}, &Reflector{}, "fixtures/custom_type_with_interface.json"}, {&PatternTest{}, &Reflector{}, "fixtures/commas_in_pattern.json"}, - {&examples.User{}, prepareCommentReflector(t), "fixtures/go_comments.json"}, {&RecursiveExample{}, &Reflector{}, "fixtures/recursive.json"}, {&KeyNamed{}, &Reflector{ KeyNamer: func(s string) string { @@ -488,14 +485,6 @@ func TestSchemaGeneration(t *testing.T) { } } -func prepareCommentReflector(t *testing.T) *Reflector { - t.Helper() - r := new(Reflector) - err := r.AddGoComments("github.com/invopop/jsonschema", "./examples") - require.NoError(t, err, "did not expect error while adding comments") - return r -} - func TestBaselineUnmarshal(t *testing.T) { r := &Reflector{} compareSchemaOutput(t, "fixtures/test_user.json", r, &TestUser{})