Skip to content

Commit

Permalink
Rewrote tests that reported on potentially null dereferences.
Browse files Browse the repository at this point in the history
  • Loading branch information
Corniel committed Jan 21, 2024
1 parent 2d053d4 commit f5232cb
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 282 deletions.
15 changes: 15 additions & 0 deletions specs/Qowaiv.Specs/Date_span_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,18 @@ public void two_date_onlys_based_on_settings(int months, int days, Date d1, Date
}
#endif
}

public class Throws_when
{
[Test]
public void Mutatation_overflows()
=> 1.Invoking(DateSpan.MaxValue.AddDays)
.Should().Throw<OverflowException>()
.WithMessage("DateSpan overflowed because the resulting duration is too long.");

[Test]
public void Ctor_arguments_are_out_of_range()
=> int.MaxValue.Invoking(n => new DateSpan(n, n))
.Should().Throw<ArgumentOutOfRangeException>()
.WithMessage("The specified years, months and days results in an un-representable DateSpan.");
}
5 changes: 3 additions & 2 deletions specs/Qowaiv.Specs/Email_address_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ public void from_valid_input_only_otherwise_throws_on_Parse()
{
using (TestCultures.en_GB.Scoped())
{
var exception = Assert.Throws<FormatException>(() => EmailAddress.Parse("invalid input"));
exception.Message.Should().Be("Not a valid email address");
"invalid input".Invoking(EmailAddress.Parse)
.Should().Throw<FormatException>()
.WithMessage("Not a valid email address");
}
}

Expand Down
25 changes: 25 additions & 0 deletions specs/Qowaiv.Specs/Financial/Money_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,28 @@ public void to_divide_money_by_money_with_different_currencies_is_not_supported(
division.Should().Throw<CurrencyMismatchException>();
}
}

public class Throws_when
{
[Test]
public void adding_multiple_currencies()
{
var euros = 16 + Currency.EUR;
var dollars = 666 + Currency.USD;
var operation = () => euros + dollars;

operation.Should().Throw<CurrencyMismatchException>()
.WithMessage("The addition operation could not be applied. There is a mismatch between EUR and USD.");
}

[Test]
public void subtracting_multiple_currencies()
{
var euros = 16 + Currency.EUR;
var dollars = 666 + Currency.USD;
var operation = () => euros - dollars;

operation.Should().Throw<CurrencyMismatchException>()
.WithMessage("The subtraction operation could not be applied. There is a mismatch between EUR and USD.");
}
}
2 changes: 1 addition & 1 deletion specs/Qowaiv.Specs/Globalization/Countries_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class All
{
private static readonly Country[] all = Country.All.ToArray();
private static readonly Country[] all = [.. Country.All];

[TestCaseSource(nameof(all))]
public void Has_constant(Country country)
Expand Down
93 changes: 93 additions & 0 deletions specs/Qowaiv.Specs/Identifiers/ID_Cast_specs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
namespace Identifiers.Id_specs;

public class Create
{
[Test]
public void string_from_null_is_empty()
=> StringId.Create(null).Should().Be(StringId.Empty);

[Test]
public void Guid_from_null_is_empty()
=> CustomGuid.Create(null).Should().Be(CustomGuid.Empty);
[Test]
public void long_from_null_is_empty()
=> Int64Id.Create(null).Should().Be(Int64Id.Empty);
}

public class Casts_from
{
[Test]
public void GUID_to_GUID_based_id()
{
var guid = Guid.Parse("AD38ECD4-020F-475C-9318-DFF2067DA1D4");
var casted = (CustomGuid)guid;
casted.Should().Be(CustomGuid.Parse("AD38ECD4-020F-475C-9318-DFF2067DA1D4"));
}

[Test]
public void GUID_to_string_based_id()
{
var guid = Guid.Parse("ad38ecd4-020f-475c-9318-dff2067da1d4");
var casted = (StringId)guid;
casted.Should().Be(StringId.Parse("ad38ecd4-020f-475c-9318-dff2067da1d4"));
}

[Test]
public void long_to_long_based_id()
{
var id = 12345L;
var casted = (Int64Id)id;
casted.Should().Be(Int64Id.Create(12345L));
}

[Test]
public void long_to_string_based_id()
{
var id = 12345L;
var casted = (StringId)id;
casted.Should().Be(StringId.Parse("12345"));
}

[Test]
public void string_to_long_based_id()
{
var id = "12345";
var casted = (Int64Id)id;
casted.Should().Be(Int64Id.Create(12345L));
}
}

public class Can_not_cast_from
{
[Test]
public void invalid_string_for_long()
=> "NaN".Invoking(Int64Id.Create)
.Should().Throw<InvalidCastException>()
.WithMessage("Cast from string to Qowaiv.Identifiers.Id<Qowaiv.TestTools.ForInt64> is not valid.");

[Test]
public void non_numeric_string_to_long()
=> "ABC".Invoking(id => (Int64Id)id)
.Should().Throw<InvalidCastException>();

[Test]
public void GUID_to_long()
=> Guid.NewGuid().Invoking(id => (Int64Id)id)
.Should().Throw<InvalidCastException>();

[Test]
public void non_GUID_string_to_GUID()
=> "ABC".Invoking(id => (CustomGuid)id)
.Should().Throw<InvalidCastException>();

[Test]
public void long_to_GUID()
=> ((object)123546L).Invoking(id => (CustomGuid)id)
.Should().Throw<InvalidCastException>();

[Test]
public void invalid_JSON_input()
=> (-1L).Invoking(Int64Id.FromJson)
.Should().Throw<InvalidCastException>();
}

5 changes: 3 additions & 2 deletions specs/Qowaiv.Specs/Month_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,9 @@ public void from_valid_input_only_otherwise_throws_on_Parse()
{
using (TestCultures.en_GB.Scoped())
{
var exception = Assert.Throws<FormatException>(() => Month.Parse("invalid input"));
exception.Message.Should().Be("Not a valid month");
"invalid input".Invoking(Month.Parse)
.Should().Throw<FormatException>()
.WithMessage("Not a valid month");
}
}

Expand Down
5 changes: 3 additions & 2 deletions specs/Qowaiv.Specs/Percentage_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,9 @@ public void from_valid_input_only_otherwise_throws_on_Parse()
{
using (TestCultures.en_GB.Scoped())
{
var exception = Assert.Throws<FormatException>(() => Percentage.Parse("invalid input"));
exception.Message.Should().Be("Not a valid percentage");
"invalid input".Invoking(Percentage.Parse)
.Should().Throw<FormatException>()
.WithMessage("Not a valid percentage");
}
}

Expand Down
2 changes: 1 addition & 1 deletion specs/Qowaiv.Specs/TestTools/Resx/XResourceFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public XResourceFile(params XResourceFileData[] data)
XResourceFileHeader.Reader,
XResourceFileHeader.Writer,
];
Data = data.ToList();
Data = [.. data];
}
/// <summary>Gets the headers.</summary>
Expand Down
14 changes: 4 additions & 10 deletions specs/Qowaiv.Specs/TestTools/Wikipedia/WikiLink.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
namespace Qowaiv.TestTools.Wikipedia;

public sealed class WikiLink
public sealed class WikiLink(string lemma, string? display)
{
public WikiLink(string lemma, string? display)
{
Lemma = lemma;
Display = display ?? lemma;
}
public string Lemma { get; } = lemma;

public string Lemma { get; }

public string Display { get; }
public string Display { get; } = display ?? lemma;

/// <inheritdoc />
[Pure]
Expand All @@ -26,7 +20,7 @@ public override string ToString()
.Select(AsLink);

private static WikiLink AsLink(Match m)
=> new(m.Groups[nameof(Lemma)].Value, m.Groups[nameof(Display)].Value is { Length: > 0 } display ? display : null);
=> new(m.Groups[nameof(Lemma)].Value, m.Groups[nameof(Display)].Value is { Length: > 0 } dis ? dis : null);

private static readonly Regex Pattern = new(@"\[\[(?<Lemma>.+?)(\|(?<Display>.*?))?\]\]", RegexOptions.None, TimeSpan.FromMinutes(2));
}
8 changes: 3 additions & 5 deletions specs/Qowaiv.Specs/Text/Base32_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,9 @@ public void Throws_on_invalid_input()
{
using (TestCultures.en_GB.Scoped())
{
var act = Assert.Catch<FormatException>(() =>
{
Base32.GetBytes("Q!waiv");
});
act.Message.Should().Be("Not a valid Base32 string");
"Q!waiv".Invoking(Base32.GetBytes)
.Should().Throw<FormatException>()
.WithMessage("Not a valid Base32 string");
}
}
}
87 changes: 87 additions & 0 deletions specs/Qowaiv.Specs/Threading/Thread_domain_specs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Qowaiv.Threading;
using System.Threading;

namespace Threading.Thread_domain_specs;

public class Gets
{
[Test]
public void Country_based_on_current_culture()
{
using (TestCultures.pt_PT.Scoped())
{
ThreadDomain.Current.Get<Country>().Should().Be(Country.PT);
}
}

[Test]
public void default_value_for_type_without_registered_factory()
=> ThreadDomain.Current.Get<InternationalBankAccountNumber>()
.Should().Be(default);

[Test]
public void value_that_has_been_set_for_the_current_thread()
{
ThreadDomain.Current.Set(Currency.ALL);

ThreadDomain.Current.Get<Currency>()
.Should().Be(Currency.ALL);
}

[Test]
public void value_only_for_current_thread()
{
ThreadDomain.Current.Set(3.1418.Percent());

Task.Factory.StartNew
(
() => ThreadDomain.Current.Get<Percentage>().Should().Be(0.Percent(), because: "Retrieved in another thread.")
);

ThreadDomain.Current.Get<Percentage>().Should().Be(3.1418.Percent(), because: "This thread has a set value.");
}

[Test]
public void Gets_updated_value_when_overwritten()
{
using (TestCultures.nl_BE.Scoped())
{
Thread.CurrentThread.GetValue<Country>().Should().Be(Country.BE, because: "Default for current thread.");
Thread.CurrentThread.SetValue(Country.PT);
Thread.CurrentThread.GetValue<Country>().Should().Be(Country.PT, because: "Default has been overwritten.");
}
}

[Test]
public void Gets_default_value_when_reset()
{
using (TestCultures.nl_BE.Scoped())
{
Thread.CurrentThread.SetValue(Country.PT);
Thread.CurrentThread.GetValue<Country>().Should().Be(Country.PT, because: "Default has been overwritten.");
Thread.CurrentThread.RemoveValue(typeof(Country));
Thread.CurrentThread.GetValue<Country>().Should().Be(Country.BE, because: "Default for current thread.");
}
}

[TearDown]
public void TearDown() => ThreadDomain.Current.Clear();
}

public class Does_not_support
{
[Test]
public void Getting_a_nulable_value()
=> ThreadDomain.Current.Invoking(c => c.Get<decimal?>())
.Should().Throw<NotSupportedException>()
.WithMessage("Type must be a none generic type.");

[Test]
public void Getting_an_type_without_a_string_converter()
=> ThreadDomain.Current.Invoking(c => c.Get<object>())
.Should().Throw<NotSupportedException>()
.WithMessage("Converter can not convert from System.String.");

[TearDown]
public void TearDown() => ThreadDomain.Current.Clear();
}
5 changes: 3 additions & 2 deletions specs/Qowaiv.Specs/UUID_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,9 @@ public void from_valid_input_only_otherwise_throws_on_Parse()
{
using (TestCultures.en_GB.Scoped())
{
var exception = Assert.Throws<FormatException>(() => Uuid.Parse("invalid input"));
exception.Message.Should().Be("Not a valid GUID");
"invalid input".Invoking(Uuid.Parse)
.Should().Throw<FormatException>()
.WithMessage("Not a valid GUID");
}
}

Expand Down
5 changes: 3 additions & 2 deletions specs/Qowaiv.Specs/Year_specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ public void from_valid_input_only_otherwise_throws_on_Parse()
{
using (TestCultures.en_GB.Scoped())
{
var exception = Assert.Throws<FormatException>(() => Year.Parse("invalid input"));
exception.Message.Should().Be("Not a valid year");
"invalid input".Invoking(Year.Parse)
.Should().Throw<FormatException>()
.WithMessage("Not a valid year");
}
}

Expand Down
18 changes: 0 additions & 18 deletions specs/Qowaiv.Specs/_Legacy/DateSpanTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,24 +493,6 @@ public void TotalMonths(int total, int years, int months, int days)

#endregion

#region Operations

[Test]
public void Mutate_Overflows()
{
var x = Assert.Catch<OverflowException>(() => DateSpan.MaxValue.AddDays(1));
x.Message.Should().Be("DateSpan overflowed because the resulting duration is too long.");
}

#endregion

[Test]
public void Ctor_OutOfRange_Throws()
{
var x = Assert.Catch<ArgumentOutOfRangeException>(() => new DateSpan(int.MaxValue, int.MaxValue));
Assert.AreEqual("The specified years, months and days results in an un-representable DateSpan.", x.Message);
}

[Test]
public void FromDays_4_4Days()
{
Expand Down

0 comments on commit f5232cb

Please sign in to comment.