Skip to content

Commit

Permalink
add string and generic type extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
tarek-iraqi committed Jul 6, 2023
1 parent c8e185d commit 8808dc1
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 2 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ soon as well.
| ExtractUrls() | Extract any valid url from the specified string |
| IsValidEmail() | Return `true` if the value is valid email otherwise return `false` |
| ExtractEmails() | Extract any valid email from the specified string |
| FromJsonTo\<T>() | Parses the text representing a single JSON value into a type|

### DateTime Extensions:
| Method | Description |
| -- | -- |
| ToUnixTimeStamp() | Convert any `DateTime` to unix timestamp |
| GetDateRangeTo() | Create a DateTime range between from and to DateTime |

### Long Extensions:
| Method | Description |
Expand Down Expand Up @@ -66,5 +68,9 @@ soon as well.
| -- | -- |
| GetAttribute\<T>() | Direct way to retrieve any attribute data associated with `enum` type whether it is built in attribute as `DescriptionAttribute` or any custom attribute |

### Generic Type Extensions:
| Method | Description |
| -- | -- |
| ToJson\<T>() | Converts the provided value into a string |

You can refer to the unit tests in the repo to see some basic usage for each method.
22 changes: 22 additions & 0 deletions Simple.Extensions/Extensions/DateTimeExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

namespace Simple.Extensions
{
Expand All @@ -15,5 +16,26 @@ public static long ToUnixTimeStamp(this DateTime dateTime)
{
return (long)(dateTime - _unixEpoch).TotalSeconds;
}

/// <summary>
/// Create a DateTime range between from and to
/// </summary>
/// <param name="fromDate">The start date of the range</param>
/// <param name="toDate">The end date of the range</param>
/// <param name="inclusiveStartAndEnd">Specify whether to include start and end dates in the range, default is true</param>
/// <returns>An <see cref="IEnumerable{DateTime}"/> collection of dates</returns>
public static IEnumerable<DateTime> GetDateRangeTo(this DateTime fromDate, DateTime toDate, bool inclusiveStartAndEnd = true)
{
if (toDate < fromDate) throw new ArgumentOutOfRangeException(nameof(toDate));

int days = (toDate - fromDate).Days;
int start = inclusiveStartAndEnd ? 0 : 1;
int end = inclusiveStartAndEnd ? days : days - 1;

for (var i = start; i <= end; i++)
yield return fromDate.AddDays(i);
}
}


}
20 changes: 20 additions & 0 deletions Simple.Extensions/Extensions/GenericTypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Text.Json;

namespace Simple.Extensions
{
public static class GenericTypeExtensions
{
/// <summary>
/// Converts the provided value into a <see cref="string"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="instance">The value to convert</param>
/// <param name="options">Options to control the conversion behavior</param>
/// <returns>A <see cref="string"/> representation of the value</returns>
public static string ToJson<T>(this T instance, JsonSerializerOptions options = null)
=> instance == null
? throw new ArgumentNullException(nameof(instance))
: JsonSerializer.Serialize(instance, options);
}
}
16 changes: 15 additions & 1 deletion Simple.Extensions/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.RegularExpressions;

namespace Simple.Extensions
Expand Down Expand Up @@ -153,5 +155,17 @@ public static IEnumerable<string> ExtractEmails(this string str)

return regex.Matches(str).Cast<Match>().Select(m => m.Value);
}

/// <summary>
/// Parses the text representing a single JSON value into a <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The type to deserialize the JSON value into</typeparam>
/// <param name="json">JSON text to parse</param>
/// <param name="options">Options to control the behavior during parsing</param>
/// <returns>The value converted from JSON text</returns>
public static T FromJsonTo<T>(this string json, JsonSerializerOptions options = null)
=> string.IsNullOrWhiteSpace(json)
? throw new ArgumentNullException(nameof(json))
: JsonSerializer.Deserialize<T>(json, options);
}
}
40 changes: 39 additions & 1 deletion Testing/Simple.Extensions.Testing/DateTimeExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Globalization;
using FluentAssertions;
using System.Globalization;

namespace Simple.Extensions.Testing;
public class DateTimeExtensionsTests
Expand All @@ -14,4 +15,41 @@ public void ToUnixTimeStamp_ReturnValidNumber(string input, long expected)

Assert.Equal(expected, date.ToUnixTimeStamp());
}

[Fact]
public void GetDateRangeTo_InvlaidEndDate_ThrowException()
{
var date = new DateTime(2023, 7, 6);

var act = () => date.GetDateRangeTo(new DateTime(2023, 7, 5)).ToList();

act.Should().Throw<ArgumentOutOfRangeException>()
.WithParameterName("toDate");
}

[Fact]
public void GetDateRangeTo_VlaidEndDateWithInclusiveStartAndEnd_ReturnDateRange()
{
var start = new DateTime(2023, 7, 6);
var end = new DateTime(2023, 7, 15);

var range = start.GetDateRangeTo(end).ToList();

range.Should().HaveCount(10);
range.First().Should().Be(start);
range.Last().Should().Be(end);
}

[Fact]
public void GetDateRangeTo_VlaidEndDateWithExeclusiveStartAndEnd_ReturnDateRange()
{
var start = new DateTime(2023, 7, 6);
var end = new DateTime(2023, 7, 15);

var range = start.GetDateRangeTo(end, false).ToList();

range.Should().HaveCount(8);
range.First().Should().Be(start.AddDays(1));
range.Last().Should().Be(end.AddDays(-1));
}
}
26 changes: 26 additions & 0 deletions Testing/Simple.Extensions.Testing/GenericTypeExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using FluentAssertions;
using Simple.Extensions.Testing.Helpers;

namespace Simple.Extensions.Testing;
public class GenericTypeExtensionsTests
{
[Fact]
public void ToJson_EmptyValue_ThrowException()
{
SampleData.Person user = null!;

var act = () => user.ToJson();

act.Should().Throw<ArgumentNullException>().WithParameterName("instance");
}

[Fact]
public void ToJson_ObjectValue_ConvertToJsonString()
{
SampleData.Person user = new(1, "tarek");

var result = user.ToJson();

result.Should().Be(""""{"Id":1,"Name":"tarek"}"""");
}
}
43 changes: 43 additions & 0 deletions Testing/Simple.Extensions.Testing/StringExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using FluentAssertions;
using System.Text.Json;
using static Simple.Extensions.Testing.Helpers.SampleData;

namespace Simple.Extensions.Testing;

Expand Down Expand Up @@ -417,4 +419,45 @@ public void RemoveHTMLTags_TextWithHTML_ReturnTextWithoutHTML(string str, string
{
str.RemoveHTMLTags().Should().Be(expected);
}

[Theory]
[InlineData("")]
[InlineData(null)]
[InlineData(" ")]
public void FromJsonTo_EmptyOrNullJson_ThrowException(string str)
{
var act = () => str.FromJsonTo<Person>();

act.Should().Throw<ArgumentNullException>().WithParameterName("json");
}

[Fact]
public void FromJsonTo_DifferentTypeValue_ObjectWithDefaultValues()
{
var data = """{"Address":"abc","IsCurrent":true}""";

var result = data.FromJsonTo<Person>();

result.Should().BeEquivalentTo(new Person(0, null!));
}

[Fact]
public void FromJsonTo_RandomStringValue_ThrowException()
{
var data = "abc dfdfdfdf";

var act = () => data.FromJsonTo<Person>();

act.Should().Throw<JsonException>();
}

[Fact]
public void FromJsonTo_ValidTypeValue_ValidObject()
{
var data = """"{"Id":1,"Name":"tarek"}"""";

var result = data.FromJsonTo<Person>();

result.Should().BeEquivalentTo(new Person(1, "tarek"));
}
}

0 comments on commit 8808dc1

Please sign in to comment.