Skip to content

Commit

Permalink
Add tests for Equality
Browse files Browse the repository at this point in the history
  • Loading branch information
Ygg01 committed Jan 7, 2024
1 parent f4df5d0 commit 27fc5ef
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 11 deletions.
35 changes: 35 additions & 0 deletions Linguini.Bundle.Test/Unit/BundleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -358,5 +358,40 @@ public void TestDynamicSelectors()
Assert.That(bundle.TryGetMessage("you-see", args, out _, out var message2));
Assert.That("You see a fairy.", Is.EqualTo(message2));
}

[Test]
public void TestDeepClone()
{
var originalBundleOption = new FluentBundleOption
{
Locales = { "en-US" },
MaxPlaceable = 123,
UseIsolating = false,
TransformFunc = _transform,
FormatterFunc = _formatter,
Functions = new Dictionary<string, ExternalFunction>()
{
["zero"] = _zeroFunc,
["id"] = _idFunc,
}
};

// Assume FluentBundle object has DeepClone method
FluentBundle originalBundle = FluentBundle.MakeUnchecked(originalBundleOption);
FluentBundle clonedBundle = originalBundle.DeepClone();

// Assert that the original and cloned objects are not the same reference
Assert.That(originalBundle, Is.Not.SameAs(clonedBundle));

// Assert that the properties are copied properly
Assert.That(originalBundle, Is.EqualTo(clonedBundle));

// Assert that if original property is changed, new property isn't.
originalBundle.AddFunctionOverriding("zero", _idFunc);
clonedBundle.TryGetFunction("zero", out var clonedZero);
Assert.That((FluentFunction) _zeroFunc, Is.EqualTo(clonedZero));
originalBundle.TryGetFunction("zero", out var originalZero);
Assert.That((FluentFunction) _idFunc, Is.EqualTo(originalZero));
}
}
}
30 changes: 25 additions & 5 deletions Linguini.Bundle/ConcurrentBundle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Linguini.Bundle
{
public sealed class ConcurrentBundle : FluentBundle
public sealed class ConcurrentBundle : FluentBundle, IEquatable<ConcurrentBundle>
{
internal ConcurrentDictionary<string, FluentFunction> FuncList = new();
private ConcurrentDictionary<string, AstTerm> _terms = new();
Expand Down Expand Up @@ -49,7 +49,7 @@ protected override bool TryAddMessage(AstMessage message, List<FluentError>? err
return false;
}


/// <inheritdoc />
public override bool TryAddFunction(string funcName, ExternalFunction fluentFunction)
{
Expand All @@ -74,7 +74,7 @@ public override bool HasMessage(string identifier)
{
return _messages.ContainsKey(identifier);
}

/// <inheritdoc />
public override bool TryGetAstMessage(string ident, [NotNullWhen(true)] out AstMessage? message)
{
Expand Down Expand Up @@ -111,7 +111,7 @@ public override IEnumerable<string> GetTermEnumerable()
{
return _terms.Keys.ToArray();
}

/// <inheritdoc/>
public override FluentBundle DeepClone()
{
Expand All @@ -120,7 +120,7 @@ public override FluentBundle DeepClone()
FuncList = new ConcurrentDictionary<string, FluentFunction>(FuncList),
_terms = new ConcurrentDictionary<string, AstTerm>(_terms),
_messages = new ConcurrentDictionary<string, AstMessage>(_messages),
Culture = (CultureInfo) Culture.Clone(),
Culture = (CultureInfo)Culture.Clone(),
Locales = new List<string>(Locales),
UseIsolating = UseIsolating,
TransformFunc = (Func<string, string>?)TransformFunc?.Clone(),
Expand All @@ -129,6 +129,26 @@ public override FluentBundle DeepClone()
EnableExtensions = EnableExtensions,
};
}

/// <inheritdoc/>
public bool Equals(ConcurrentBundle? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && FuncList.SequenceEqual(other.FuncList) && _terms.SequenceEqual(other._terms) &&
_messages.SequenceEqual(other._messages);
}

/// <inheritdoc/>
public override bool Equals(object? obj)
{
return ReferenceEquals(this, obj) || obj is ConcurrentBundle other && Equals(other);
}

/// <inheritdoc/>
public override int GetHashCode()
{
return HashCode.Combine(base.GetHashCode(), FuncList, _terms, _messages);
}
}
}
44 changes: 42 additions & 2 deletions Linguini.Bundle/FluentBundle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace Linguini.Bundle
{
public abstract class FluentBundle
public abstract class FluentBundle : IEquatable<FluentBundle>
{
/// <summary>
/// <see cref="CultureInfo"/> of the bundle. Primary bundle locale
Expand Down Expand Up @@ -60,7 +60,7 @@ public abstract class FluentBundle
/// </summary>
// ReSharper disable once MemberCanBeProtected.Global
public bool EnableExtensions { get; init; }

public bool AddResource(string input, [NotNullWhen(false)] out List<FluentError>? errors)
{
var res = new LinguiniParser(input, EnableExtensions).Parse();
Expand Down Expand Up @@ -123,10 +123,23 @@ private void InternalResourceOverriding(Resource resource)
}
}

/// <summary>
/// Adds the given AstMessage to the collection of messages, by overriding any existing messages with the same name.
/// </summary>
/// <param name="message">The AstMessage to be added.</param>
protected abstract void AddMessageOverriding(AstMessage message);

/// <summary>
/// Adds a term to the AstTerm list, overriding any existing term with the same name.
/// </summary>
/// <param name="term">The term to be added.</param>
protected abstract void AddTermOverriding(AstTerm term);

/// <summary>
/// Adds a resource.
/// Any messages or terms in bundle will be overriden by the existing ones.
/// </summary>
/// <param name="input">The input string containing the resource data.</param>
public void AddResourceOverriding(string input)
{
var res = new LinguiniParser(input, EnableExtensions).Parse();
Expand Down Expand Up @@ -387,5 +400,32 @@ public static FluentBundle MakeUnchecked(FluentBundleOption option)
}
};
}

/// <inheritdoc/>
public bool Equals(FluentBundle? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Culture.Equals(other.Culture) && Locales.SequenceEqual(other.Locales) &&
UseIsolating == other.UseIsolating && Equals(TransformFunc, other.TransformFunc) &&
Equals(FormatterFunc, other.FormatterFunc) && MaxPlaceable == other.MaxPlaceable &&
EnableExtensions == other.EnableExtensions;
}

/// <inheritdoc/>
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((FluentBundle)obj);
}

/// <inheritdoc/>
public override int GetHashCode()
{
return HashCode.Combine(Culture, Locales, UseIsolating, TransformFunc, FormatterFunc, MaxPlaceable,
EnableExtensions);
}
}
}
26 changes: 22 additions & 4 deletions Linguini.Bundle/NonConcurrentBundle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace Linguini.Bundle
{
public sealed class NonConcurrentBundle : FluentBundle
public sealed class NonConcurrentBundle : FluentBundle, IEquatable<NonConcurrentBundle>
{
internal Dictionary<string, FluentFunction> FuncList = new();
private Dictionary<string, AstTerm> _terms = new();
Expand Down Expand Up @@ -48,7 +48,7 @@ protected override bool TryAddMessage(AstMessage message, List<FluentError>? err
return false;
}


/// <inheritdoc />
public override bool TryAddFunction(string funcName, ExternalFunction fluentFunction)
{
Expand All @@ -72,7 +72,7 @@ public override bool HasMessage(string identifier)
{
return _messages.ContainsKey(identifier);
}

/// <inheritdoc />
public override bool TryGetAstMessage(string ident, [NotNullWhen(true)] out AstMessage? message)
{
Expand Down Expand Up @@ -119,7 +119,7 @@ public override FluentBundle DeepClone()
FuncList = new Dictionary<string, FluentFunction>(FuncList),
_terms = new Dictionary<string, AstTerm>(_terms),
_messages = new Dictionary<string, AstMessage>(_messages),
Culture = (CultureInfo) Culture.Clone(),
Culture = (CultureInfo)Culture.Clone(),
Locales = new List<string>(Locales),
UseIsolating = UseIsolating,
TransformFunc = (Func<string, string>?)TransformFunc?.Clone(),
Expand All @@ -128,5 +128,23 @@ public override FluentBundle DeepClone()
EnableExtensions = EnableExtensions,
};
}

public bool Equals(NonConcurrentBundle? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && FuncList.SequenceEqual(other.FuncList) && _terms.SequenceEqual(other._terms) &&
_messages.SequenceEqual(other._messages);
}

public override bool Equals(object? obj)
{
return ReferenceEquals(this, obj) || obj is NonConcurrentBundle other && Equals(other);
}

public override int GetHashCode()
{
return HashCode.Combine(base.GetHashCode(), FuncList, _terms, _messages);
}
}
}

0 comments on commit 27fc5ef

Please sign in to comment.