Skip to content

Add generic job support for assemblyQualifiedNameWithoutVersion method #64

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
142 changes: 142 additions & 0 deletions src/Horarium.Test/TypeName/AssemblyQualifiedNameWithoutVersionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
using System;
using Xunit;

namespace Horarium.Test.TypeName
{
public class AssemblyQualifiedNameWithoutVersionTests
{
[Fact]
public void GetName_ForNonGenericJob_ShouldRemoveVersion()
{
var jobName = new FirstNonGenericJob().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<FirstNonGenericJob>(instance);
Assert.Equal("Horarium.Test.TypeName.FirstNonGenericJob, Horarium.Test", jobName);
}

[Fact]
public void GetName_ForNonGenericJobWithAttribute_ShouldRemoveVersion()
{
var jobName = new FirstNonGenericJobWithAttribute().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<FirstNonGenericJobWithAttribute>(instance);
Assert.Equal("Horarium.Test.TypeName.FirstNonGenericJobWithAttribute, Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithTwoArguments_ShouldNotRemoveVersionForAllTypes()
{
var jobName = new GenericJobWithTwoArguments<FirstNonGenericJob, SecondNonGenericJob>().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJobWithTwoArguments<FirstNonGenericJob, SecondNonGenericJob>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJobWithTwoArguments`2[[Horarium.Test.TypeName.FirstNonGenericJob, Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithTwoArgumentsWithAttribute_ShouldRemoveVersionForAllTypes()
{
var jobName = new GenericJobWithTwoArgumentsWithAttribute<FirstNonGenericJob, SecondNonGenericJob>().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJobWithTwoArgumentsWithAttribute<FirstNonGenericJob, SecondNonGenericJob>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJobWithTwoArgumentsWithAttribute`2[[Horarium.Test.TypeName.FirstNonGenericJob, Horarium.Test], [Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test]], Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithTwoNestedGenericArguments_ShouldNotRemoveVersionForAllTypes()
{
var jobName = new GenericJobWithTwoArguments<GenericJob<FirstNonGenericJob>, GenericJob<SecondNonGenericJob>>()
.GetType()
.AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJobWithTwoArguments<GenericJob<FirstNonGenericJob>, GenericJob<SecondNonGenericJob>>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJobWithTwoArguments`2[[Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.FirstNonGenericJob, Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithTwoNestedGenericArgumentsWithAttribute_ShouldRemoveVersionForAllTypes()
{
var jobName = new GenericJobWithTwoArgumentsWithAttribute<GenericJob<FirstNonGenericJob>, GenericJob<SecondNonGenericJob>>()
.GetType()
.AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJobWithTwoArgumentsWithAttribute<GenericJob<FirstNonGenericJob>, GenericJob<SecondNonGenericJob>>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJobWithTwoArgumentsWithAttribute`2[[Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.FirstNonGenericJob, Horarium.Test]], Horarium.Test], [Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test]], Horarium.Test]], Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithSingleGenericArgument_ShouldNotRemoveVersionForAllTypes()
{
var jobName = new GenericJob<SecondNonGenericJob>().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJob<SecondNonGenericJob>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithSingleGenericArgumentWithAttribute_ShouldRemoveVersionForAllTypes()
{
var jobName = new GenericJobWithAttribute<SecondNonGenericJob>().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJobWithAttribute<SecondNonGenericJob>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJobWithAttribute`1[[Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test]], Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithSingleNestedGenericArgument_ShouldNotRemoveVersionForAllTypes()
{
var jobName = new GenericJob<GenericJob<SecondNonGenericJob>>().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJob<GenericJob<SecondNonGenericJob>>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Horarium.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Horarium.Test", jobName);
}

[Fact]
public void GetName_ForGenericJobWithSingleNestedGenericArgumentWithAttribute_ShouldRemoveVersionForAllTypes()
{
var jobName = new GenericJobWithAttribute<GenericJob<SecondNonGenericJob>>().GetType().AssemblyQualifiedNameWithoutVersion();

var type = Type.GetType(jobName, true);
var instance = Activator.CreateInstance(type);

Assert.NotNull(instance);
Assert.IsType<GenericJobWithAttribute<GenericJob<SecondNonGenericJob>>>(instance);
Assert.Equal("Horarium.Test.TypeName.GenericJobWithAttribute`1[[Horarium.Test.TypeName.GenericJob`1[[Horarium.Test.TypeName.SecondNonGenericJob, Horarium.Test]], Horarium.Test]], Horarium.Test", jobName);
}
}
}
4 changes: 4 additions & 0 deletions src/Horarium.Test/TypeName/FirstNonGenericJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Horarium.Test.TypeName
{
public class FirstNonGenericJob { }
}
7 changes: 7 additions & 0 deletions src/Horarium.Test/TypeName/FirstNonGenericJobWithAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Horarium.Attributes;

namespace Horarium.Test.TypeName
{
[GenericJob]
public class FirstNonGenericJobWithAttribute {}
}
4 changes: 4 additions & 0 deletions src/Horarium.Test/TypeName/GenericJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Horarium.Test.TypeName
{
public class GenericJob<TFirst> { }
}
7 changes: 7 additions & 0 deletions src/Horarium.Test/TypeName/GenericJobWithAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Horarium.Attributes;

namespace Horarium.Test.TypeName
{
[GenericJob]
public class GenericJobWithAttribute<TFirst> { }
}
4 changes: 4 additions & 0 deletions src/Horarium.Test/TypeName/GenericJobWithTwoArguments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Horarium.Test.TypeName
{
public class GenericJobWithTwoArguments<TFirst, TSecond> { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Horarium.Attributes;

namespace Horarium.Test.TypeName
{
[GenericJob]
public class GenericJobWithTwoArgumentsWithAttribute<TFirst, TSecond> { }
}
4 changes: 4 additions & 0 deletions src/Horarium.Test/TypeName/SecondNonGenericJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Horarium.Test.TypeName
{
public class SecondNonGenericJob { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Horarium.Attributes;

namespace Horarium.Test.TypeName
{
[GenericJob]
public class SecondNonGenericJobWithAttribute { }
}
7 changes: 7 additions & 0 deletions src/Horarium/Attributes/GenericJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using System;

namespace Horarium.Attributes
{
[AttributeUsage(AttributeTargets.Class)]
public class GenericJob : Attribute { }
}
42 changes: 38 additions & 4 deletions src/Horarium/Utils.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Cronos;
using Horarium.Attributes;
using Newtonsoft.Json;

[assembly:InternalsVisibleTo("Horarium.Test")]
namespace Horarium
{
internal static class Utils
Expand All @@ -19,14 +23,44 @@ public static object FromJson(this string json, Type type, JsonSerializerSetting

public static string AssemblyQualifiedNameWithoutVersion(this Type type)
{
string retValue = type.FullName + ", " + type.GetTypeInfo().Assembly.GetName().Name;
return retValue;
var hasGenericJobAttribute = type.GetCustomAttributes<GenericJob>().Any();

if (!hasGenericJobAttribute)
{
return $"{type.FullName}, {type.GetTypeInfo().Assembly.GetName().Name}";
}

return type.AssemblyQualifiedNameWithoutVersionForGenericType();
}

private static string AssemblyQualifiedNameWithoutVersionForGenericType(this Type type)
{
if (string.IsNullOrWhiteSpace(type.FullName))
{
throw new ArgumentException($"Unable to receive FullName for type {type}");
}

if (!type.IsGenericType)
{
return $"{type.FullName}, {type.GetTypeInfo().Assembly.GetName().Name}";
}

var genericArguments = type
.GetGenericArguments()
.Select(typeArgument => $"[{typeArgument.AssemblyQualifiedNameWithoutVersionForGenericType()}]")
.ToArray();

var genericPart = string.Join(", ", genericArguments);

var bracketIndex = type.FullName.IndexOf("[", StringComparison.Ordinal);

return $"{type.FullName.Substring(0, bracketIndex)}[{genericPart}], {type.GetTypeInfo().Assembly.GetName().Name}";
}

public static DateTime? ParseAndGetNextOccurrence(string cron)
{
var expression = CronExpression.Parse(cron, CronFormat.IncludeSeconds);

return expression.GetNextOccurrence(DateTime.UtcNow, TimeZoneInfo.Local);
}
}
Expand Down