Repository: ogen-go/ogen
Pull request #540 (2022-08-19 23:06:52)

chore(gen): log filtered content entries


Patch:
diff --git a/gen/gen_contents.go b/gen/gen_contents.go
index 5e0740bf..9fd8d55d 100644
--- a/gen/gen_contents.go
+++ b/gen/gen_contents.go
@@ -12,30 +12,40 @@ import (
 	"github.com/ogen-go/ogen/openapi"
 )
 
-func filterMostSpecific(contents map[string]*openapi.MediaType) error {
-	initialLength := len(contents)
-	keep := func(current, mask string) bool {
+func filterMostSpecific(contents map[string]*openapi.MediaType, log *zap.Logger) error {
+	keep := func(current, mask string) (string, bool) {
 		// Special case for "*", "**", etc.
-		var nonStar bool
+		var notOnlyStar bool
 		for _, c := range mask {
 			if c != '*' {
-				nonStar = true
+				notOnlyStar = true
 				break
 			}
 		}
-		if !nonStar {
-			return initialLength < 2
+		if !notOnlyStar {
+			for k := range contents {
+				if k == current {
+					continue
+				}
+				// There is at least one another media type, so delete "*".
+				return k, false
+			}
+			// There is no other media type, so keep "*".
+			return "", true
 		}
 
 		for contentType := range contents {
+			// Do not try to match mask against itself.
 			if contentType == current {
 				continue
 			}
+			// Found more specific media type that matches the mask, so delete the mask.
 			if matched, _ := path.Match(mask, contentType); matched {
-				return false
+				return contentType, false
 			}
 		}
-		return true
+		// Found no more specific media type, so keep the mask.
+		return "", true
 	}
 
 	for k := range contents {
@@ -44,7 +54,11 @@ func filterMostSpecific(contents map[string]*openapi.MediaType) error {
 			return errors.Wrapf(err, "parse content type %q", k)
 		}
 
-		if !keep(k, contentType) {
+		if replacement, keep := keep(k, contentType); !keep {
+			log.Info("Filter common content type",
+				zap.String("mask", k),
+				zap.String("replacement", replacement),
+			)
 			delete(contents, k)
 		}
 	}
@@ -139,7 +153,7 @@ func (g *Generator) generateContents(
 	optional bool,
 	contents map[string]*openapi.MediaType,
 ) (_ map[ir.ContentType]ir.Media, err error) {
-	if err := filterMostSpecific(contents); err != nil {
+	if err := filterMostSpecific(contents, g.log); err != nil {
 		return nil, errors.Wrap(err, "filter most specific")
 	}
 


Test patch:
diff --git a/gen/gen_contents_test.go b/gen/gen_contents_test.go
index cc58e97a..f39cb528 100644
--- a/gen/gen_contents_test.go
+++ b/gen/gen_contents_test.go
@@ -5,6 +5,9 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+	"go.uber.org/zap/zaptest/observer"
 
 	"github.com/ogen-go/ogen/openapi"
 )
@@ -38,16 +41,27 @@ func Test_filterMostSpecific(t *testing.T) {
 	for i, tt := range tests {
 		tt := tt
 		t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
+			a := require.New(t)
+			core, logs := observer.New(zapcore.DebugLevel)
+
+			// Make a copy of the testdata to avoid modifying it.
 			contents := map[string]*openapi.MediaType{}
 			for k, v := range tt.contents {
 				contents[k] = v
 			}
-			err := filterMostSpecific(contents)
+
+			err := filterMostSpecific(contents, zap.New(core))
 			if tt.wantErr {
-				require.Error(t, err)
+				a.Error(err)
 			} else {
-				require.NoError(t, err)
-				require.Equal(t, tt.expected, contents)
+				a.NoError(err)
+				a.Equal(tt.expected, contents)
+				// Ensure that there is a log message for every filtered media type.
+				if before, after := len(tt.contents), len(tt.expected); after < before {
+					entries := logs.FilterMessage("Filter common content type").All()
+					a.NotEmpty(entries)
+					a.Len(entries, before-after)
+				}
 			}
 		})
 	}