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
2 changes: 2 additions & 0 deletions .github/workflows/release-nuget-pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
uses: actions/checkout@v4
- name: Setup .NET SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.x'
- name: Build
run: dotnet build ObjectSemantics.NET/ObjectSemantics.NET.csproj -c Release
- name: Test
Expand Down
117 changes: 117 additions & 0 deletions ObjectSemantics.NET.Tests/IfConditionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using ObjectSemantics.NET.Tests.MoqModels;
using System.Collections.Generic;
using Xunit;

namespace ObjectSemantics.NET.Tests
{
public class IfConditionTests
{
[Theory]
[InlineData(1, "Valid")]
[InlineData(0, "Invalid")]
public void Should_Render_If_Block_When_Condition_Is_True(int id, string expected)
{
var model = new Invoice { Id = id };

var template = new ObjectSemanticsTemplate
{
FileContents = @"{{ #if(Id == 1) }}Valid{{ #else }}Invalid{{ #endif }}"
};

string result = template.Map(model);
Assert.Equal(expected, result);
}


[Theory]
[InlineData(18, "Minor")]
[InlineData(21, "Adult")]
[InlineData(5, "Minor")]
public void Should_Handle_LessThan_Or_Equal(int age, string expected)
{
var model = new Student { Age = age };

var template = new ObjectSemanticsTemplate
{
FileContents = @"{{ #if(Age <= 18) }}Minor{{ #else }}Adult{{ #endif }}"
};

var result = template.Map(model);
Assert.Equal(expected, result);
}


[Theory]
[InlineData(1, "1")]
[InlineData(0, "Error")]
[InlineData(-1, "Error")]
[InlineData(5, "5")]
[InlineData(+2, "2")]
public void Should_Handle_Whitespace_And_Case_Insensitive_Condition(int id, string expected)
{
var model = new Invoice { Id = id };

var template = new ObjectSemanticsTemplate
{
FileContents = @"{{ #if( id > 0 ) }}{{id}}{{ #else }}Error{{ #endif }}"
};

var result = template.Map(model);
Assert.Equal(expected, result);
}


[Fact]
public void Should_Render_If_Block_Without_Else_When_True()
{
var model = new Student { IsActive = true };

var template = new ObjectSemanticsTemplate
{
FileContents = @"Student: John {{ #if(IsActive == true) }}[Is Active]{{ #endif }}"
};

var result = template.Map(model);
Assert.Equal("Student: John [Is Active]", result);
}

[Fact]
public void Should_Evaluate_If_Enumerable_Count()
{
var model = new Student
{
Invoices = new List<Invoice>
{
new Invoice{ Id = 2, RefNo = "INV_002" },
new Invoice{ Id = 1, RefNo = "INV_001" }
}
};

var template = new ObjectSemanticsTemplate
{
FileContents = @"{{ #if(Invoices == 2) }}Matched{{ #else }}Not Matched{{ #endif }}"
};

var result = template.Map(model);
Assert.Equal("Matched", result);
}

[Fact]
public void Should_Evaluate_Empty_Enumerable_As_Zero()
{
var model = new Student
{
Invoices = new List<Invoice>()
};

var template = new ObjectSemanticsTemplate
{
FileContents = @"{{ #if(Invoices == 0) }}No invoices available{{ #else }}Invoices Found{{ #endif }}"
};

var result = template.Map(model);
Assert.Equal("No invoices available", result);
}

}
}
2 changes: 2 additions & 0 deletions ObjectSemantics.NET.Tests/MoqModels/Student.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ internal class Student
public Guid Id { get; set; } = Guid.NewGuid();
public string StudentName { get; set; }
public double Balance { get; set; }
public int Age { get; set; }
public DateTime RegDate { get; set; } = DateTime.Now;
public List<Invoice> Invoices { get; set; } = new List<Invoice>();
public string[] ArrayOfString { get; set; } = new string[] { };
public double[] ArrayOfDouble { get; set; } = new double[] { };
public bool IsActive { get; set; }
public List<StudentClockInDetail> StudentClockInDetails { get; set; } = new List<StudentClockInDetail>();
}
class StudentClockInDetail
Expand Down
49 changes: 49 additions & 0 deletions ObjectSemantics.NET.Tests/StringFormattingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,31 @@ public void Should_Accept_String_To_UpperCase_or_LowerCase_Formatting()
Assert.Equal(expectedString, generatedTemplate, false, true, true);
}

[Theory]
[InlineData("john doe", "John Doe")]
[InlineData("JANE DOE", "Jane Doe")]
[InlineData("aLiCe joHNsOn", "Alice Johnson")]
[InlineData("", "")]
[InlineData(null, "")]
public void Should_Convert_StudentName_To_TitleCase(string studentName, string expectedTitleCase)
{
// Create Model
Student student = new Student
{
StudentName = studentName
};

// Template
var template = new ObjectSemanticsTemplate
{
FileContents = @"{{ StudentName:titlecase }}"
};

string generatedTemplate = template.Map(student);

Assert.Equal(expectedTitleCase, generatedTemplate, ignoreCase: false, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true);
}


[Fact]
public void Should_Accept_Number_To_String_Formatting()
Expand Down Expand Up @@ -116,5 +141,29 @@ public void Should_Accept_String_From_BASE64_Formatting()
string expectedString = "Original String: Sm9obiBET0U= | From BASE64 String: John DOE";
Assert.Equal(expectedString, generatedTemplate, false, true, true);
}

[Theory]
[InlineData("Alice Johnson", "13")]
[InlineData("Bob", "3")]
[InlineData("", "0")]
[InlineData(null, "")]
public void Should_Return_Correct_Length_Of_StudentName(string studentName, string expectedLength)
{
// Create Model
Student student = new Student
{
StudentName = studentName
};

// Template
var template = new ObjectSemanticsTemplate
{
FileContents = @"{{ StudentName:length }}"
};

string generatedTemplate = template.Map(student);

Assert.Equal(expectedLength, generatedTemplate, ignoreCase: false, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true);
}
}
}
2 changes: 0 additions & 2 deletions ObjectSemantics.NET/Algorithim/GavinsAlgorithim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,4 @@ private static List<ExtractedObjProperty> GetObjPropertiesFromUnknown(object val
}
return list;
}


}
16 changes: 16 additions & 0 deletions ObjectSemantics.NET/Extensions/ExtractedObjPropertyExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security;

Expand Down Expand Up @@ -43,6 +44,10 @@ private static string GetAppliedPropertyFormatting(this ExtractedObjProperty p,
return p.StringFormatted.ToBase64String();
else if (customFormattingValue.ToLower().Equals("frombase64"))
return p.StringFormatted.FromBase64String();
else if (customFormattingValue.ToLower().Equals("length"))
return p.StringFormatted?.Length.ToString();
else if (customFormattingValue.ToLower().Equals("titlecase"))
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(p.StringFormatted?.ToLower() ?? string.Empty);
else
return p.StringFormatted;
}
Expand Down Expand Up @@ -98,6 +103,17 @@ public static bool IsPropertyValueConditionPassed(this ExtractedObjProperty prop
default: return false;
}
}
else if (property.Type == typeof(bool))
{
bool v1 = Convert.ToBoolean(property.OriginalValue);
bool v2 = Convert.ToBoolean(GetConvertibleValue<bool>(valueComparer));
switch (criteria)
{
case "==": return v1 == v2;
case "!=": return v1 != v2;
default: return false;
}
}
else if (property.IsEnumerableObject)
{
int v1 = (property.OriginalValue == null) ? 0 : ((IEnumerable<object>)property.OriginalValue).Count();
Expand Down
6 changes: 3 additions & 3 deletions ObjectSemantics.NET/ObjectSemantics.NET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
ToBase64
FromBase64
. Added template extension method to allow mapping directly from Template</PackageReleaseNotes>
<AssemblyVersion>6.0.4</AssemblyVersion>
<FileVersion>6.0.4</FileVersion>
<Version>6.0.4</Version>
<AssemblyVersion>6.0.5</AssemblyVersion>
<FileVersion>6.0.5</FileVersion>
<Version>6.0.5</Version>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<ApplicationIcon></ApplicationIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down