Repository: victools/jsonschema-generator
Pull request #467 (2024-08-07 22:43:32)

Fix: Edge case where raw Enum is defined as field/method type
Avoiding a `NullPointerException` being thrown in this case and rather generating a too-open type definition without explicit `enum` values.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b4330df..5c83261 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,8 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
-
--
+### `jsonschema-generator`
+#### Fixed
+- avoid exception when trying to collect supported enum values from raw `Enum` type (i.e., missing type parameter)
 
 ## [4.36.0] - 2024-07-20
 ### `jsonschema-generator`
diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/EnumModule.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/EnumModule.java
index 559e594..234fc90 100644
--- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/EnumModule.java
+++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/EnumModule.java
@@ -26,6 +26,7 @@ import com.github.victools.jsonschema.generator.SchemaGenerationContext;
 import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
 import com.github.victools.jsonschema.generator.SchemaKeyword;
 import com.github.victools.jsonschema.generator.impl.AttributeCollector;
+import com.github.victools.jsonschema.generator.impl.Util;
 import java.util.List;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -103,7 +104,10 @@ public class EnumModule implements Module {
     private static List<String> extractEnumValues(MethodScope method) {
         ResolvedType declaringType = method.getDeclaringType();
         if (EnumModule.isEnum(declaringType)) {
-            return EnumModule.extractEnumValues(declaringType.getTypeParameters().get(0), Enum::name);
+            ResolvedType enumType = declaringType.getTypeParameters().stream().findFirst().orElse(null);
+            if (enumType != null) {
+                return EnumModule.extractEnumValues(enumType, Enum::name);
+            }
         }
         return null;
     }
@@ -117,7 +121,7 @@ public class EnumModule implements Module {
      */
     private static List<String> extractEnumValues(ResolvedType enumType, Function<Enum<?>, String> enumConstantToString) {
         Class<?> erasedType = enumType.getErasedType();
-        if (erasedType.getEnumConstants() == null) {
+        if (Util.isNullOrEmpty(erasedType.getEnumConstants())) {
             return null;
         }
         return Stream.of(erasedType.getEnumConstants())


Test patch:
diff --git a/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/impl/module/EnumModuleTest.java b/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/impl/module/EnumModuleTest.java
index 6e74991..06489da 100644
--- a/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/impl/module/EnumModuleTest.java
+++ b/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/impl/module/EnumModuleTest.java
@@ -26,21 +26,27 @@ import com.github.victools.jsonschema.generator.CustomDefinition;
 import com.github.victools.jsonschema.generator.CustomDefinitionProviderV2;
 import com.github.victools.jsonschema.generator.FieldScope;
 import com.github.victools.jsonschema.generator.MethodScope;
+import com.github.victools.jsonschema.generator.Option;
 import com.github.victools.jsonschema.generator.OptionPreset;
+import com.github.victools.jsonschema.generator.SchemaGenerator;
 import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
 import com.github.victools.jsonschema.generator.SchemaGeneratorConfigPart;
 import com.github.victools.jsonschema.generator.SchemaGeneratorGeneralConfigPart;
 import com.github.victools.jsonschema.generator.SchemaKeyword;
 import com.github.victools.jsonschema.generator.SchemaVersion;
 import java.util.stream.Stream;
+import org.json.JSONException;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.EnumSource;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.skyscreamer.jsonassert.JSONCompareMode;
 
 /**
  * Test for the {@link EnumModule} class.
@@ -162,6 +168,31 @@ public class EnumModuleTest extends AbstractTypeAwareTest {
         Assertions.assertEquals(value3, enumNode.get(2).textValue());
     }
 
+    @Test
+    public void testRawEnumType_asString() throws JSONException {
+        this.initConfigBuilder(SchemaVersion.DRAFT_2020_12);
+        this.builder.with(Option.PUBLIC_NONSTATIC_FIELDS, Option.NONSTATIC_NONVOID_NONGETTER_METHODS);
+        instanceAsStringsFromName.applyToConfigBuilder(this.builder);
+
+        JsonNode enumSchema = new SchemaGenerator(this.builder.build()).generateSchema(TestType.class)
+                .get(SchemaKeyword.TAG_PROPERTIES.forVersion(SchemaVersion.DRAFT_2020_12))
+                .get("rawEnum");
+        JSONAssert.assertEquals("{\"type\":\"string\"}", enumSchema.toString(), JSONCompareMode.STRICT);
+    }
+
+    @Test
+    public void testRawEnumType_asObject() throws JSONException {
+        this.initConfigBuilder(SchemaVersion.DRAFT_2020_12);
+        this.builder.with(Option.PUBLIC_NONSTATIC_FIELDS, Option.NONSTATIC_NONVOID_NONGETTER_METHODS);
+        instanceAsObjects.applyToConfigBuilder(this.builder);
+
+        JsonNode enumSchema = new SchemaGenerator(this.builder.build()).generateSchema(TestType.class)
+                .get(SchemaKeyword.TAG_PROPERTIES.forVersion(SchemaVersion.DRAFT_2020_12))
+                .get("rawEnum");
+        JSONAssert.assertEquals("{\"type\":\"object\",\"properties\":{\"compareTo(Enum<Object>)\":{\"type\":\"integer\"},\"name()\":{\"type\":\"string\"}}}",
+                enumSchema.toString(), JSONCompareMode.STRICT);
+    }
+
     private enum TestEnum {
         VALUE1, VALUE2, VALUE3;
 
@@ -170,4 +201,8 @@ public class EnumModuleTest extends AbstractTypeAwareTest {
             return this.name().toLowerCase() + "_toString";
         }
     }
+
+    private static class TestType {
+        public Enum rawEnum;
+    }
 }