Skip to content

Commit 561bd16

Browse files
authored
Merge 4322614 into 1d002a7
2 parents 1d002a7 + 4322614 commit 561bd16

10 files changed

+254
-25
lines changed

dotnet-decode-base64.sln.DotSettings

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gabo/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

src/dotnet-decode-base64/Base64Decoder.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace DotNet.DecodeBase64;
1+
namespace Gabo.DotNet.DecodeBase64;
22

33
public static class Base64Decoder
44
{

src/dotnet-decode-base64/IConsole.cs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Gabo.DotNet.DecodeBase64;
2+
3+
internal interface IConsole
4+
{
5+
void WriteFancyLine(string line);
6+
void WriteBoringLine(string line);
7+
void WriteErrorLine(string line);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace Gabo.DotNet.DecodeBase64;
2+
3+
internal class NonThreadSafeConsole : IConsole
4+
{
5+
public void WriteFancyLine(string line)
6+
{
7+
WriteColoredLine(ConsoleColor.Green, line);
8+
}
9+
10+
public void WriteBoringLine(string line)
11+
{
12+
Console.WriteLine(line);
13+
}
14+
15+
public void WriteErrorLine(string line)
16+
{
17+
WriteColoredLine(ConsoleColor.Red, line);
18+
}
19+
20+
private static void WriteColoredLine(ConsoleColor color, string line)
21+
{
22+
Console.ForegroundColor = color;
23+
Console.WriteLine(line);
24+
Console.ResetColor();
25+
}
26+
}

src/dotnet-decode-base64/Program.cs

+18-16
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
1-
namespace DotNet.DecodeBase64;
1+
namespace Gabo.DotNet.DecodeBase64;
22

3-
internal class Program
3+
internal static class Program
44
{
5-
private static void Main(string[] args)
5+
internal const int SuccessExitCode = 0;
6+
internal const int FailureExitCode = 1;
7+
8+
internal static IConsole AbstractedConsole;
9+
10+
internal static int Main(string[] args)
611
{
12+
AbstractedConsole ??= new NonThreadSafeConsole();
13+
714
if (args.Length != 1)
815
{
9-
Console.WriteLine("A single argument should be provided:");
10-
Console.WriteLine("dotnet decode-base64 SGVsbG8gV29ybGQh");
11-
return;
16+
AbstractedConsole.WriteBoringLine("A single argument should be provided:");
17+
AbstractedConsole.WriteBoringLine("dotnet decode-base64 SGVsbG8gV29ybGQh");
18+
return FailureExitCode;
1219
}
1320

1421
try
1522
{
1623
var decodedString = Base64Decoder.Decode(args[0]);
1724

18-
Console.ForegroundColor = ConsoleColor.Green;
19-
Console.WriteLine("Decoded string:");
20-
Console.ResetColor();
21-
Console.WriteLine(decodedString);
25+
AbstractedConsole.WriteFancyLine("Decoded string:");
26+
AbstractedConsole.WriteBoringLine(decodedString);
27+
return SuccessExitCode;
2228
}
2329
catch (FormatException e)
2430
{
25-
Console.ForegroundColor = ConsoleColor.Red;
26-
Console.WriteLine(e.Message);
27-
}
28-
finally
29-
{
30-
Console.ResetColor();
31+
AbstractedConsole.WriteErrorLine(e.Message);
32+
return FailureExitCode;
3133
}
3234
}
3335
}

src/dotnet-decode-base64/dotnet-decode-base64.csproj

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<ImplicitUsings>enable</ImplicitUsings>
77
<EmbedUntrackedSources>true</EmbedUntrackedSources>
88
<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'True'">true</ContinuousIntegrationBuild>
9-
<RootNamespace>DotNet.DecodeBase64</RootNamespace>
9+
<RootNamespace>Gabo.DotNet.DecodeBase64</RootNamespace>
1010
<PackAsTool>true</PackAsTool>
1111
<PackageId>dotnet-decode-base64</PackageId>
1212
<Authors>Gabriel Weyer</Authors>
@@ -21,6 +21,9 @@
2121
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
2222
<NoWarn>CS7035</NoWarn>
2323
</PropertyGroup>
24+
<ItemGroup>
25+
<InternalsVisibleTo Include="Gabo.DotNet.DecodeBase64.Tests" />
26+
</ItemGroup>
2427
<ItemGroup>
2528
<Using Include="System.Text" />
2629
</ItemGroup>
@@ -31,6 +34,6 @@
3134
</PackageReference>
3235
</ItemGroup>
3336
<ItemGroup>
34-
<None Include="README.md" Pack="true" PackagePath="\"/>
37+
<None Include="README.md" Pack="true" PackagePath="\" />
3538
</ItemGroup>
3639
</Project>

tests/dotnet-decode-base64-tests/Base64DecoderTests.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace DotNet.DecodeBase64.Tests;
1+
namespace Gabo.DotNet.DecodeBase64.Tests;
22

33
public class Base64DecoderTests
44
{
@@ -13,7 +13,7 @@ public void GivenValidBase64String_WhenDecode_ThenReturnDecodedString()
1313
var actual = Base64Decoder.Decode(input);
1414

1515
// Assert
16-
Assert.Equal(expected, actual);
16+
actual.Should().Be(expected);
1717
}
1818

1919
[Theory]
@@ -25,7 +25,7 @@ public void GivenMinusAndUnderscore_WhenDecode_ThenReturnDecodedString(string in
2525
var actual = Base64Decoder.Decode(input);
2626

2727
// Assert
28-
Assert.Equal(expected, actual);
28+
actual.Should().Be(expected);
2929
}
3030

3131
[Theory]
@@ -37,6 +37,6 @@ public void GivenRemovedPadding_WhenDecode_ThenReturnDecodedString(string input,
3737
var actual = Base64Decoder.Decode(input);
3838

3939
// Assert
40-
Assert.Equal(expected, actual);
40+
actual.Should().Be(expected);
4141
}
4242
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
namespace Gabo.DotNet.DecodeBase64.Tests;
2+
3+
public class ProgramTests
4+
{
5+
private readonly MockConsole _console;
6+
private const string ValidBase64Input = "SGVsbG8gV29ybGQh";
7+
private const string DecodedValidBase64Input = "Hello World!";
8+
private const string InvalidBase64Input = "#";
9+
10+
public ProgramTests()
11+
{
12+
_console = new MockConsole();
13+
Program.AbstractedConsole = _console;
14+
}
15+
16+
[Fact]
17+
public void GivenNoArgumentProvided_ThenDisplayInstructions()
18+
{
19+
// Arrange
20+
var input = Array.Empty<string>();
21+
22+
// Act
23+
Program.Main(input);
24+
25+
// Assert
26+
var expectedLines = new List<ColoredLine>
27+
{
28+
new("A single argument should be provided:", MockConsole.BoringColor),
29+
new("dotnet decode-base64 SGVsbG8gV29ybGQh", MockConsole.BoringColor)
30+
};
31+
_console.Lines.Should().BeEquivalentTo(expectedLines);
32+
}
33+
34+
[Fact]
35+
public void GivenNoArgumentProvided_ThenFailureExitCode()
36+
{
37+
// Arrange
38+
var input = Array.Empty<string>();
39+
40+
// Act
41+
var actualExitCode = Program.Main(input);
42+
43+
// Assert
44+
actualExitCode.Should().Be(Program.FailureExitCode);
45+
}
46+
47+
[Fact]
48+
public void GivenMoreThanOneArgumentProvided_ThenDisplayInstructions()
49+
{
50+
// Arrange
51+
var input = new[] { ValidBase64Input, ValidBase64Input };
52+
53+
// Act
54+
Program.Main(input);
55+
56+
// Assert
57+
var expectedLines = new List<ColoredLine>
58+
{
59+
new("A single argument should be provided:", MockConsole.BoringColor),
60+
new("dotnet decode-base64 SGVsbG8gV29ybGQh", MockConsole.BoringColor)
61+
};
62+
_console.Lines.Should().BeEquivalentTo(expectedLines);
63+
}
64+
65+
[Fact]
66+
public void GivenMoreThanOneArgumentProvided_ThenFailureExitCode()
67+
{
68+
// Arrange
69+
var input = new[] { ValidBase64Input, ValidBase64Input };
70+
71+
// Act
72+
var actualExitCode = Program.Main(input);
73+
74+
// Assert
75+
actualExitCode.Should().Be(Program.FailureExitCode);
76+
}
77+
78+
[Fact]
79+
public void GivenInvalidBase64Input_ThenDisplayErrorMessage()
80+
{
81+
// Arrange
82+
var input = new[] { InvalidBase64Input };
83+
84+
// Act
85+
Program.Main(input);
86+
87+
// Assert
88+
const string errorMessage =
89+
"The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.";
90+
var expectedLines = new List<ColoredLine>
91+
{
92+
new(errorMessage, MockConsole.ErrorColor)
93+
};
94+
_console.Lines.Should().BeEquivalentTo(expectedLines);
95+
}
96+
97+
[Fact]
98+
public void GivenInvalidBase64Input_ThenFailureExitCode()
99+
{
100+
// Arrange
101+
var input = new[] { InvalidBase64Input };
102+
103+
// Act
104+
var actualExitCode = Program.Main(input);
105+
106+
// Assert
107+
actualExitCode.Should().Be(Program.FailureExitCode);
108+
}
109+
110+
[Fact]
111+
public void GivenValidBase64Input_ThenDisplayDecodedInput()
112+
{
113+
// Arrange
114+
var input = new[] { ValidBase64Input };
115+
116+
// Act
117+
Program.Main(input);
118+
119+
// Assert
120+
var expectedLines = new List<ColoredLine>
121+
{
122+
new("Decoded string:", MockConsole.FancyColor),
123+
new(DecodedValidBase64Input, MockConsole.BoringColor)
124+
};
125+
_console.Lines.Should().BeEquivalentTo(expectedLines);
126+
}
127+
128+
[Fact]
129+
public void GivenValidBase64Input_ThenSuccessExitCode()
130+
{
131+
// Arrange
132+
var input = new[] { ValidBase64Input };
133+
134+
// Act
135+
var actualExitCode = Program.Main(input);
136+
137+
// Assert
138+
actualExitCode.Should().Be(Program.SuccessExitCode);
139+
}
140+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace Gabo.DotNet.DecodeBase64.Tests.TestInfrastructure;
2+
3+
internal class MockConsole : IConsole
4+
{
5+
public const ConsoleColor FancyColor = ConsoleColor.Cyan;
6+
public const ConsoleColor BoringColor = ConsoleColor.Yellow;
7+
public const ConsoleColor ErrorColor = ConsoleColor.Magenta;
8+
public IReadOnlyList<ColoredLine> Lines => _lines;
9+
10+
private readonly List<ColoredLine> _lines;
11+
12+
public MockConsole()
13+
{
14+
_lines = new List<ColoredLine>();
15+
}
16+
17+
public void WriteFancyLine(string line)
18+
{
19+
_lines.Add(new ColoredLine(line, FancyColor));
20+
}
21+
22+
public void WriteBoringLine(string line)
23+
{
24+
_lines.Add(new ColoredLine(line, BoringColor));
25+
}
26+
27+
public void WriteErrorLine(string line)
28+
{
29+
_lines.Add(new ColoredLine(line, ErrorColor));
30+
}
31+
}
32+
33+
internal class ColoredLine
34+
{
35+
public ColoredLine(string line, ConsoleColor color)
36+
{
37+
Line = line;
38+
Color = color;
39+
}
40+
41+
public ConsoleColor Color { get; }
42+
public string Line { get; }
43+
}

tests/dotnet-decode-base64-tests/dotnet-decode-base64-tests.csproj

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
<TargetFrameworks>netcoreapp3.1;net6.0</TargetFrameworks>
55
<LangVersion>latest</LangVersion>
66
<ImplicitUsings>enable</ImplicitUsings>
7-
<RootNamespace>DotNet.DecodeBase64.Tests</RootNamespace>
7+
<RootNamespace>Gabo.DotNet.DecodeBase64.Tests</RootNamespace>
8+
<AssemblyName>Gabo.DotNet.DecodeBase64.Tests</AssemblyName>
89
<IsPackable>false</IsPackable>
910
<NoWarn>CS7035</NoWarn>
1011
</PropertyGroup>
11-
12+
1213
<ItemGroup>
14+
<Using Include="FluentAssertions" />
15+
<Using Include="Gabo.DotNet.DecodeBase64" />
16+
<Using Include="Gabo.DotNet.DecodeBase64.Tests.TestInfrastructure" />
1317
<Using Include="Xunit" />
1418
</ItemGroup>
1519

@@ -18,6 +22,7 @@
1822
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1923
<PrivateAssets>all</PrivateAssets>
2024
</PackageReference>
25+
<PackageReference Include="FluentAssertions" Version="6.6.0" />
2126
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
2227
<PackageReference Include="xunit" Version="2.4.1" />
2328
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">

0 commit comments

Comments
 (0)