Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
"appsettings*.json": "jsonc",
"web.config": "xml"
},
"markdown.extension.toc.levels": "2..6",
"markdownlint.config": {
"MD024": false
},
"omnisharp.enableAsyncCompletion": true,
"omnisharp.enableEditorConfigSupport": true,
"omnisharp.enableMsBuildLoadProjectsOnDemand": true,
"remote.autoForwardPortsFallback": 0
"omnisharp.enableMsBuildLoadProjectsOnDemand": true
}
4 changes: 2 additions & 2 deletions examples-dotnet.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<Project Path="src/Examples.DependencyInjection.Mef.Tests/Examples.DependencyInjection.Mef.Tests.csproj" />
<Project Path="src/Examples.DependencyInjection.Tests/Examples.DependencyInjection.Tests.csproj" />
<Project Path="src/Examples.DependencyInjection/Examples.DependencyInjection.csproj" />
<Project Path="src/Examples.Fluency.Tests/Examples.Fluency.Tests.csproj" />
<Project Path="src/Examples.Fluency/Examples.Fluency.csproj" />
<Project Path="src/Examples.Graphics.Console/Examples.Graphics.Console.csproj" />
<Project Path="src/Examples.Hosting.Console/Examples.Hosting.Console.csproj" />
<Project Path="src/Examples.Hosting.Workers/Examples.Hosting.Workers.csproj" />
<Project Path="src/Examples.Metaprogramming.Tests/Examples.Metaprogramming.Tests.csproj" />
<Project Path="src/Examples.Serialization.Tests/Examples.Serialization.Tests.csproj" />
<Project Path="src/Examples.Shared.Tests/Examples.Shared.Tests.csproj" />
<Project Path="src/Examples.Shared/Examples.Shared.csproj" />
<Project Path="src/Examples.T4.CodeGenerator/Examples.T4.CodeGenerator.csproj" />
<Project Path="src/Examples.Various.Tests/Examples.Various.Tests.csproj" />
<Project Path="src/Examples.Xunit/Examples.Xunit.csproj" />
Expand Down
10 changes: 0 additions & 10 deletions src/Examples.DependencyInjection.Tests/UnitTest1.cs

This file was deleted.

6 changes: 0 additions & 6 deletions src/Examples.DependencyInjection/Class1.cs

This file was deleted.

29 changes: 29 additions & 0 deletions src/Examples.Fluency.Tests/Examples.Fluency.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(LatestFramework)</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Examples</RootNamespace>
</PropertyGroup>

<ItemGroup>
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="xunit.v3" Version="3.2.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Examples.Fluency\Examples.Fluency.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ public class DateTimeExtensionsTests
[InlineData("2023-01-02T12:34:56.7891234Z", "2023-01-02T12:34:00.0000000Z", TimeSpan.TicksPerMinute)]
[InlineData("2023-01-02T12:34:56.7891234Z", "2023-01-02T12:00:00.0000000Z", TimeSpan.TicksPerHour)]
[InlineData("2023-01-02T12:34:56.7891234Z", "2023-01-02T00:00:00.0000000Z", TimeSpan.TicksPerDay)]
public void WhenCallingTruncate_ReturnsAsExpected(string input, string expected, long tickSpan)
public void When_CallingTruncate_Then_ReturnsAsExpected(string input, string expected, long tickSpan)
{
DateTime.Parse(input).Truncate(tickSpan).Is(DateTime.Parse(expected));
DateTimeOffset.Parse(input).Truncate(tickSpan).Is(DateTimeOffset.Parse(expected));

return;
Assert.Equal(DateTime.Parse(expected), DateTime.Parse(input).Truncate(tickSpan));
Assert.Equal(DateTimeOffset.Parse(expected), DateTimeOffset.Parse(input).Truncate(tickSpan));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ namespace Examples.Fluency.Tests;
public class EncodingExtensionsTests
{
[Fact]
public void WhenCallingRemovePreamble_WithUTF8Encoding_ReturnsAsExpected()
public void When_CallingRemovePreamble_WithUTF8Encoding_Then_ReturnsAsExpected()
{
// ### Arrange ###
// Create a UTF8 string with BOM added at the beginning
const string baseString = "TEST文字列😄";
byte[] original;
Expand All @@ -20,24 +19,23 @@ public void WhenCallingRemovePreamble_WithUTF8Encoding_ReturnsAsExpected()
original = stream.ToArray();
}

// ### Act ###
// The default is UTF8, so the result will be the same whether you specify it or not.
var actual1 = original.RemovePreamble();
var actual2 = original.RemovePreamble(Encoding.UTF8);

// ### Assert ###
// Removed BOM.
actual1.Is(Encoding.UTF8.GetBytes(baseString));
actual2.Is(Encoding.UTF8.GetBytes(baseString));
Assert.Equal(Encoding.UTF8.GetBytes(baseString), actual1);
Assert.Equal(Encoding.UTF8.GetBytes(baseString), actual2);

// Encoding.UTF8.GetString() is auto remove?
{
var decoded = Encoding.UTF8.GetString(original);
var actual = Encoding.UTF8.GetBytes(decoded);

var bom = Encoding.UTF8.GetPreamble();
actual[..bom.Length].Is(bom); // not removed.
actual[bom.Length..].Is(Encoding.UTF8.GetBytes(baseString));

Assert.Equal(bom, actual[..bom.Length]); // not removed.
Assert.Equal(Encoding.UTF8.GetBytes(baseString), actual[bom.Length..]);
}

// Binary reader obediently reads from the preamble.
Expand All @@ -47,30 +45,32 @@ public void WhenCallingRemovePreamble_WithUTF8Encoding_ReturnsAsExpected()
var actual = reader.ReadBytes((int)stream.Length);

var bom = Encoding.UTF8.GetPreamble();
actual[..bom.Length].Is(bom); // not removed.
actual[bom.Length..].Is(Encoding.UTF8.GetBytes(baseString));

Assert.Equal(bom, actual[..bom.Length]); // not removed.
Assert.Equal(Encoding.UTF8.GetBytes(baseString), actual[bom.Length..]);
}

// StreamReader is auto remove?
// Binary reader obediently reads from the preamble.
using (var stream = new MemoryStream(original))
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
Span<char> buffer = stackalloc char[(int)stream.Length];
reader.ReadBlock(buffer);
buffer[0].Is(baseString[0]); // removed.

Assert.Equal(baseString[0], buffer[0]); // removed.

var actual = buffer.ToString();
actual.IsNot(baseString); // null-terminated.
actual.TrimEnd('\0').Is(baseString);
Assert.NotEqual(baseString, actual); // null-terminated.
Assert.Equal(baseString, actual.TrimEnd('\0'));
}

// UTF-8 encoding BOM is...
Encoding.UTF8.GetPreamble().Is(new byte[] { 0xEF, 0xBB, 0xBF });
Assert.Equal(new byte[] { 0xEF, 0xBB, 0xBF }, Encoding.UTF8.GetPreamble());
}

[Fact]
public void WhenCallingRemovePreamble_WithUTF16Encoding_ReturnsAsExpected()
public void When_CallingRemovePreamble_WithUTF16Encoding_Then_ReturnsAsExpected()
{
// ### Arrange ###
// Create a UTF8 string with BOM added at the beginning

var utf16 = Encoding.GetEncoding("UTF-16");
Expand All @@ -86,15 +86,13 @@ public void WhenCallingRemovePreamble_WithUTF16Encoding_ReturnsAsExpected()
original = stream.ToArray();
}

// ### Act ###
// The default is UTF8, so the result will be the same whether you specify it or not.
var actual = original.RemovePreamble(utf16);

// ### Assert ###
// Removed BOM.
actual.Is(utf16.GetBytes(baseString));
Assert.Equal(utf16.GetBytes(baseString), actual);

// UTF-16 Little Endian encoding is...
utf16.GetPreamble().Is(new byte[] { 0xFF, 0xFE });
Assert.Equal(new byte[] { 0xFF, 0xFE }, utf16.GetPreamble());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ public class EnumerableStringExtensionsTests

[Theory]
[MemberData(nameof(DataForToSeparatedString))]
public void WhenCallingToSeparatedString_ReturnsConcatenatedString(
public void When_CallingToSeparatedString_Then_ReturnsConcatenatedString(
IEnumerable<string> inputs,
string separator,
string expected)
{
inputs.ToSeparatedString(separator).Is(expected);
Assert.Equal(expected, inputs.ToSeparatedString(separator));
}

public static IEnumerable<object[]> DataForToSeparatedString()
Expand All @@ -24,15 +24,15 @@ public static IEnumerable<object[]> DataForToSeparatedString()
}

[Fact]
public void WhenCallingToSeparatedString_WithNullElements_ReturnsConcatenatedString()
public void When_CallingToSeparatedStringWithNullElements_Then_ReturnsConcatenatedString()
{
(new string?[] { null, null, null, null, null }).ToSeparatedString("").Is("");
Assert.Equal("", (new string?[] { null, null, null, null, null }).ToSeparatedString(""));
}

[Fact]
public void WhenCallingToSeparatedString_WithEmpty_ReturnsEmptyString()
public void When_CallingToSeparatedString_WithEmpty_Then_ReturnsEmptyString()
{
Array.Empty<string>().ToSeparatedString(",").Is("");
Assert.Equal("", Array.Empty<string>().ToSeparatedString(","));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
namespace Examples.Fluency.Text.Tests;

/// <summary>
/// Tests <see cref="JapaneseCharacters" /> methods.
/// </summary>
public class JapaneseCharactersTests(ITestOutputHelper output)
{

[Fact]
public void When_CallingIsHiragana_WithValidValues_Then_ReturnsTrue()
{
foreach (var input in JapaneseCharacters.EnumerateHiragana())
{
output.Write($"{input}");
Assert.True(JapaneseCharacters.IsHiragana(input));
}
output.WriteLine(".");
}

[Fact]
public void When_CallingIsHiragana_WithInvalidValues_Then_ReturnsFalse()
{
// value < \u3040.
const char ideographicHalfFillSpace = '\u303F';
output.WriteLine($"{ideographicHalfFillSpace}");

Assert.False(JapaneseCharacters.IsFullWidthKatakana(ideographicHalfFillSpace));

// \u309F < value.
const char katakanaHiraganaDoubleHyphen = '\u30A0';
output.WriteLine($"{katakanaHiraganaDoubleHyphen}");

Assert.False(JapaneseCharacters.IsHiragana(katakanaHiraganaDoubleHyphen));
}

[Fact]
public void When_CallingIsFullWidthKatakana_WithValidValues_Then_ReturnsTrue()
{
foreach (var input in JapaneseCharacters.EnumerateFullWidthKatakana())
{
output.Write($"{input}");

Assert.True(JapaneseCharacters.IsFullWidthKatakana(input));
}
output.WriteLine(".");
}

[Fact]
public void WhenCallingIsFullWidthKatakana_WithInvalidValues_ReturnsFalse()
{
// value < \u30A0 (HIRAGANA DIGRAPH YORI).
const char hiraganaDigraphYori = '\u309F';
output.WriteLine($"{hiraganaDigraphYori}");

Assert.False(JapaneseCharacters.IsFullWidthKatakana(hiraganaDigraphYori));

// \u30FF (Bopomofo - 1) < value.
const char bopomofoUndefined = '\u3100';
output.WriteLine($"{bopomofoUndefined}");

Assert.False(JapaneseCharacters.IsFullWidthKatakana(bopomofoUndefined));
}

[Fact]
public void WhenCallingIsHalfWidthKatakana_WithValidValues_ReturnsTrue()
{
foreach (var input in JapaneseCharacters.EnumerateHalfWidthKatakana())
{
output.Write($"{input}");
Assert.True(JapaneseCharacters.IsHalfWidthKatakana(input));
}
output.WriteLine(".");
}

[Fact]
public void WhenCallingIsHalfWidthKatakana_WithInvalidValues_ReturnsFalse()
{
// value < \uFF60.
const char fullWidthRightWhiteParenthesis = '\uFF60';
output.WriteLine($"{fullWidthRightWhiteParenthesis}");
Assert.False(JapaneseCharacters.IsHalfWidthKatakana(fullWidthRightWhiteParenthesis));

// \uFF9F < value.
const char halfWidthHangulFiller = '\uFFA0';
output.WriteLine($"{halfWidthHangulFiller}");
Assert.False(JapaneseCharacters.IsHalfWidthKatakana(halfWidthHangulFiller));
}

}
37 changes: 37 additions & 0 deletions src/Examples.Fluency.Tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Examples.Fluency.Tests

## Table of Contents <!-- omit in toc -->

- [Development](#development)
- [How the project was initialized](#how-the-project-was-initialized)

## Development

### How the project was initialized

This project was initialized with the following command:

```shell
## Solution
dotnet new sln -o .

## Examples.Fluency
dotnet new classlib -o src/Examples.Fluency
dotnet sln add src/Examples.Fluency/
cd src/Examples.Fluency
cd ../../

## Examples.Fluency.Tests
dotnet new xunit -o src/Examples.Fluency.Tests
dotnet sln add src/Examples.Fluency.Tests/
cd src/Examples.Fluency.Tests
dotnet add reference ../../src/Examples.Fluency
dotnet add package Microsoft.NET.Test.Sdk
dotnet add package xunit.v3
dotnet add package xunit.runner.visualstudio
dotnet add package coverlet.collector
cd ../../

# Update outdated package
dotnet list package --outdated
```
14 changes: 14 additions & 0 deletions src/Examples.Fluency.Tests/cspell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"version": "0.2",
"ignorePaths": [],
"dictionaryDefinitions": [],
"dictionaries": [],
"words": [
"Bopomofo",
"Yori"
],
"ignoreWords": [],
"import": [
"../../.vscode/cspell.json"
]
}
3 changes: 3 additions & 0 deletions src/Examples.Fluency.Tests/xunit.runner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json"
}
Loading