From acb7687d1cc09ff50fa4b85572f7f931e0e82e2a Mon Sep 17 00:00:00 2001 From: Steve Ognibene Date: Wed, 26 Jul 2023 20:38:44 -0400 Subject: [PATCH] Fix TypeScript enum default generation in StringLiteral mode --- .../DefaultValueGeneratorTests.cs | 31 +++++++++++++- .../TypeScriptGeneratorTests.cs | 42 +++++++++++++++++++ .../TypeScriptValueGenerator.cs | 17 ++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/NJsonSchema.CodeGeneration.Tests/DefaultValueGeneratorTests.cs b/src/NJsonSchema.CodeGeneration.Tests/DefaultValueGeneratorTests.cs index b277d98f3..c092a4a81 100644 --- a/src/NJsonSchema.CodeGeneration.Tests/DefaultValueGeneratorTests.cs +++ b/src/NJsonSchema.CodeGeneration.Tests/DefaultValueGeneratorTests.cs @@ -218,7 +218,36 @@ public void When_schema_has_default_value_of_enum_it_is_generated_in_CSharp_and_ Assert.Equal("Ns.MyEnum.bar", csharpValue); Assert.Equal("MyEnum.bar", typescriptValue); } - + + /// + /// This test asserts the fix for issue #1618 + /// + [Fact] + public void When_schema_has_a_default_value_for_an_enum_and_uses_enumstyle_stringliteral_it_defaults_to_the_stringliteral() + { + //// Arrange + var schema = new JsonSchema() + { + Type = JsonObjectType.String, + Enumeration = + { + "Foo", + "Bar" + }, + Default = "Bar" + }; + + var typescriptSettings = new TypeScriptGeneratorSettings { EnumStyle = TypeScriptEnumStyle.StringLiteral }; + var typescriptGenerator = new TypeScriptValueGenerator(typescriptSettings); + var typescriptTypeResolver = new TypeScriptTypeResolver(typescriptSettings); + + //// Act + var typescriptValue = typescriptGenerator.GetDefaultValue(schema, true, "MyEnum", "MyEnum", true, typescriptTypeResolver); + + //// Assert + Assert.Equal("\"Bar\"", typescriptValue); + } + [Fact] public void When_schema_has_required_abstract_class_it_generates_no_default_value_for_in_CSharp_and_TypeScript() { diff --git a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs index 0bcebffab..b1680d06c 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs @@ -140,6 +140,48 @@ public async Task When_enum_has_description_then_typescript_has_comment() Assert.Contains(@"/** EnumDesc. *", output); } + /// + /// This test asserts the fix for issue #1618 + /// + [Fact] + public async Task When_enum_has_default_and_using_enumstyle_stringliteral_it_defaults_to_stringliteral() + { + //// Arrange + var jsonSchema = """ + { + "$schema": "http://json-schema.org/draft-04/schema#", + "openapi": "3.1.0", + "title": "TShirt", + "type": "object", + "properties": { + "color": { + "type": "string", + "default": "green", + "enum": ["red", "green", "blue", "black"] + } + } + } + """; + + var schema = await JsonSchema.FromJsonAsync(jsonSchema); + var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings + { + EnumStyle = TypeScriptEnumStyle.StringLiteral, + TypeScriptVersion = 5m, + }); + + //// Act + var code = generator.GenerateFile("MyFile"); + + //// Assert + Assert.Contains("export type MyFileColor = \"red\" | \"green\" | \"blue\" | \"black\";", code); + Assert.Contains("this.color = _data[\"color\"] !== undefined ? _data[\"color\"] : \"green\";", code); + Assert.Contains("this.color = \"green\";", code); + + // This is the old code gen that used the enum prior to the fix for #1618 + Assert.DoesNotContain("Color.Green", code); + } + [Fact] public async Task When_class_has_description_then_typescript_has_comment() { diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptValueGenerator.cs b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptValueGenerator.cs index e3829f950..390d00a7d 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptValueGenerator.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptValueGenerator.cs @@ -29,6 +29,23 @@ public TypeScriptValueGenerator(TypeScriptGeneratorSettings settings) { } + /// Gets the enum default value. + /// The schema. + /// The actual schema. + /// The type name hint. + /// The type resolver. + /// The enum default value. + protected override string GetEnumDefaultValue(JsonSchema schema, JsonSchema actualSchema, string typeNameHint, TypeResolverBase typeResolver) + { + if (schema?.Default is not null && + typeResolver is TypeScriptTypeResolver { Settings.EnumStyle: TypeScriptEnumStyle.StringLiteral }) + { + return GetDefaultAsStringLiteral(schema); + } + + return base.GetEnumDefaultValue(schema, actualSchema, typeNameHint, typeResolver); + } + /// Gets the default value code. /// The schema. /// Specifies whether the default value assignment also allows null.