Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/NJsonSchema.CodeGeneration.CSharp.Tests/AnnotationsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,39 @@ public async Task When_array_property_is_not_nullable_then_it_does_not_have_a_se
await VerifyHelper.Verify(code);
CSharpCompiler.AssertCompile(code);
}

[Fact]
public async Task When_custom_class_and_property_annotation_templates_are_used_then_annotations_are_on_separate_lines()
{
// Arrange
var json = @"{ 'properties': { 'name': { 'type': 'string' } } }";
var schema = await JsonSchema.FromJsonAsync(json);

var tempDir = Path.Combine(Path.GetTempPath(), "NJsonSchema_AnnotationTest_" + Guid.NewGuid());
Directory.CreateDirectory(tempDir);
try
{
File.WriteAllText(Path.Combine(tempDir, "Class.Annotations.liquid"), "[System.Runtime.Serialization.DataContract]");
File.WriteAllText(Path.Combine(tempDir, "Class.Property.Annotations.liquid"), "[System.Runtime.Serialization.DataMember]");

var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
ClassStyle = CSharpClassStyle.Poco,
Namespace = "TestNs",
TemplateDirectory = tempDir
});

// Act
var code = generator.GenerateFile("MyClass");

// Assert - annotations should be on their own lines, not on the same line as class/property declarations
Assert.Contains("[System.Runtime.Serialization.DataContract]\n public partial class MyClass", code);
Assert.Contains("[System.Runtime.Serialization.DataMember]\n public string Name", code);
}
finally
{
Directory.Delete(tempDir, true);
}
}
}
}
4 changes: 2 additions & 2 deletions src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
{%- if IsDeprecated -%}
[System.Obsolete{% if HasDeprecatedMessage %}({{ DeprecatedMessage | literal }}){% endif %}]
{% endif -%}
{%- template Class.Annotations -%}
{%- template Class.Annotations %}
{{ TypeAccessModifier }} {% if IsAbstract %}abstract {% endif %}partial {{ ClassType }} {{ClassName}} {%- template Class.Inheritance %}
{
{%- if IsTuple -%}
Expand Down Expand Up @@ -106,7 +106,7 @@
{%- if property.IsDeprecated -%}
[System.Obsolete{% if property.HasDeprecatedMessage %}({{ property.DeprecatedMessage | literal }}){% endif %}]
{%- endif -%}
{%- template Class.Property.Annotations -%}
{%- template Class.Property.Annotations %}
public {% if UseRequiredKeyword and property.IsRequired %}required {% endif %}{{ property.Type }} {{ property.PropertyName }}{% if RenderInpc == false and RenderPrism == false %} { get; {% if property.HasSetter and RenderRecord == false %}{{ WriteAccessor }}; {% elsif RenderRecord and GenerateNativeRecords %}init; {% endif %}}{% if property.HasDefaultValue and RenderRecord == false and UseRequiredKeyword == false %} = {{ property.DefaultValue }};{% elsif GenerateNullableReferenceTypes and RenderRecord == false and UseRequiredKeyword == false %} = default!;{% endif %}
{%- else -%}
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{%- if IsEnumAsBitFlags -%}
[System.Flags]
{%- endif -%}
{%- template Enum.Annotations -%}
{%- template Enum.Annotations %}
{{ TypeAccessModifier }} enum {{ Name }}{%- if HasExtendedValueRange %} : long{% endif %}
{
{%- for enum in Enums %}
Expand Down
3 changes: 2 additions & 1 deletion src/NJsonSchema.CodeGeneration/DefaultTemplateFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ public string Render()
var withoutEmptyWhiteSpace = _emptyTemplateCleanupRegex.Replace(trimmed, string.Empty);

// just to make sure we don't leak out marker
return withoutEmptyWhiteSpace.Replace("__EMPTY-TEMPLATE__", "");
// also handle case where empty annotation template marker is on its own line (e.g. when annotation templates are empty)
return withoutEmptyWhiteSpace.Replace("\n__EMPTY-TEMPLATE__\n", "\n").Replace("__EMPTY-TEMPLATE__", "");
}
catch (Exception exception)
{
Expand Down