Skip to content

Commit

Permalink
Merge branch 'wezz-feature/translate-to-dictionary'
Browse files Browse the repository at this point in the history
  • Loading branch information
Valdis Iljuconoks committed Nov 3, 2024
2 parents 9fe7a0b + a949a68 commit ebd8ac0
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using DbLocalizationProvider.Internal;
using DbLocalizationProvider.Queries;
using DbLocalizationProvider.Refactoring;
using DbLocalizationProvider.Sync;
using DbLocalizationProvider.Tests.DataAnnotations;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using DbLocalizationProvider.Abstractions;
using Xunit;

namespace DbLocalizationProvider.Tests.DictionaryConvertTests;

public class _Tests
{
private readonly LocalizationProvider _provider;

public _Tests()
{
var state = new ScanState();
var ctx = new ConfigurationContext();
var wrapper = new OptionsWrapper<ConfigurationContext>(ctx);
var keyBuilder = new ResourceKeyBuilder(state, wrapper);

ctx.TypeFactory
.ForQuery<DetermineDefaultCulture.Query>()
.SetHandler<DetermineDefaultCulture.Handler>()
.ForQuery<GetTranslation.Query>()
.SetHandler<GetTranslationReturnResourceKeyHandler>();

var queryExecutor = new QueryExecutor(ctx.TypeFactory);

var expressHelper = new ExpressionHelper(keyBuilder);
_provider = new LocalizationProvider(keyBuilder,
expressHelper,
wrapper,
queryExecutor,
new ScanState());
}

[Fact]
public void ConvertToDictionary()
{
var result = _provider.ToDictionary(typeof(ResourceToDictionaryModel));

Assert.NotNull(result);
Assert.Single(result);
Assert.True(result.ContainsKey("DbLocalizationProvider.Tests.DictionaryConvertTests.ResourceToDictionaryModel.Property1"));
}


[Fact]
public void ConvertToDictionary_HiddenResource_ShouldNotInclude()
{
var result = _provider.ToDictionary<ResourceToDictionaryModelWithHiddenProperty>();

Assert.Single(result);
Assert.True(result.ContainsKey("DbLocalizationProvider.Tests.DictionaryConvertTests.ResourceToDictionaryModelWithHiddenProperty.Property1"));
}
}

[LocalizedResource]
public class ResourceToDictionaryModel
{
public string Property1 { get; set; }
}

[LocalizedResource]
public class ResourceToDictionaryModelWithHiddenProperty
{
public string Property1 { get; set; }

[Hidden]
public string Property2 { get; set; }
}
34 changes: 34 additions & 0 deletions src/DbLocalizationProvider/ILocalizationProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,38 @@ public interface ILocalizationProvider
/// <param name="formatArguments">If you need to format the message and substitute placeholders.</param>
/// <returns>Translation for current language or in invariant language.</returns>
string GetStringWithInvariantFallback(Expression<Func<object>> resource, params object[] formatArguments);

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <param name="type">The type to retrieve localized resources for.</param>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
IDictionary<string, string> ToDictionary(Type type);

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <typeparam name="T">The type to retrieve localized resources for.</typeparam>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
IDictionary<string, string> ToDictionary<T>();

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <typeparam name="T">The type to retrieve localized resources for.</typeparam>
/// <param name="culture">Culture to get translations in.</param>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
IDictionary<string, string> ToDictionary<T>(CultureInfo culture);

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <param name="type">The type to retrieve localized resources for.</param>
/// <param name = "culture" > Culture to get translations in.</param>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
IDictionary<string, string> ToDictionary(Type type, CultureInfo culture);
}
22 changes: 22 additions & 0 deletions src/DbLocalizationProvider/Internal/PropertyInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Linq;
using System.Reflection;
using DbLocalizationProvider.Abstractions;

namespace DbLocalizationProvider.Internal;

/// <summary>
/// Some extensions for properties
/// </summary>
public static class PropertyInfoExtensions
{
/// <summary>
/// Checks whether property is hidden or not.
/// </summary>
/// <param name="property">Property to check for.</param>
/// <returns><c>true</c> if property is hidden, otherwise <c>false</c>.</returns>
public static bool IsHidden(this PropertyInfo property)
{
return Attribute.GetCustomAttributes(property).FirstOrDefault(a => a is HiddenAttribute) != null;
}
}
65 changes: 65 additions & 0 deletions src/DbLocalizationProvider/LocalizationProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using DbLocalizationProvider.Abstractions;
using DbLocalizationProvider.Internal;
using DbLocalizationProvider.Json;
using DbLocalizationProvider.Queries;
Expand Down Expand Up @@ -348,6 +349,70 @@ public virtual string GetStringByCulture(
return GetStringByCulture(resourceKey, culture, formatArguments);
}

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <typeparam name="T">The type to retrieve localized resources for.</typeparam>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
public IDictionary<string, string> ToDictionary<T>()
{
return ToDictionary(typeof(T));
}

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <typeparam name="T">The type to retrieve localized resources for.</typeparam>
/// <param name="culture">Culture to get translations in.</param>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
public IDictionary<string, string> ToDictionary<T>(CultureInfo culture)
{
return ToDictionary(typeof(T), culture);
}

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <param name="type">The type to retrieve localized resources for.</param>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
public IDictionary<string, string> ToDictionary(Type type)
{
return ToDictionary(type, _queryExecutor.Execute(new GetCurrentUICulture.Query()));
}

/// <summary>
/// Converts a localized resource dictionary to a translated dictionary based on the specified type.
/// </summary>
/// <param name="type">The type to retrieve localized resources for.</param>
/// <param name = "culture" > Culture to get translations in.</param>
/// <returns>A dictionary containing the localized resources translated to the current culture.</returns>
/// <exception cref="ArgumentException">Thrown when the object does not have a LocalizedResourceAttribute.</exception>
public IDictionary<string, string> ToDictionary(Type type, CultureInfo culture)
{
_ = Attribute.GetCustomAttribute(type, typeof(LocalizedResourceAttribute)) ?? throw new ArgumentException($"Object needs to have a {nameof(LocalizedResourceAttribute)} to be converted");

return GetLocalizedResourceTranslations(type, culture)
.ToDictionary(k => k.Key, v => v.Value);
}

internal IEnumerable<KeyValuePair<string, string>> GetLocalizedResourceTranslations(Type type, CultureInfo culture)
{
foreach (var property in type.GetProperties())
{
if (property.IsHidden())
{
continue;
}

var resourceKey = _keyBuilder.BuildResourceKey(type, property.Name);

yield return new(resourceKey, GetString(property.Name, culture));
}
}

internal static string Format(string message, params object[] formatArguments)
{
if (formatArguments == null || !formatArguments.Any())
Expand Down

0 comments on commit ebd8ac0

Please sign in to comment.