Added tests project

This commit is contained in:
Zev Spitz
2022-01-21 04:31:55 +02:00
parent 311776e3a8
commit e8d753ada8
6 changed files with 181 additions and 14 deletions

View File

@@ -3,12 +3,12 @@
<PropertyGroup>
<RootNamespace>Animal.Tests</RootNamespace>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<OptionStrict>On</OptionStrict>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -20,4 +20,8 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Animal\Animal.vbproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,65 @@
Imports System.IO
Public Class MockConsole
Inherits ConsoleAdapterBase
Private inputs As Queue(Of String)
Public ReadOnly Lines As New List(Of (line As String, centered As Boolean)) From {
("", False)
}
' TODO it's possible to clear all the lines, and we'd have to check once again in WriteString and WriteCenteredLine if there are any lines
Sub New(Inputs As IEnumerable(Of String))
Me.inputs = New Queue(Of String)(Inputs)
End Sub
Private Sub CheckLinesInitialized()
If Lines.Count = 0 Then Lines.Add(("", False))
End Sub
Private Sub WriteString(s As String, Optional centered As Boolean = False)
If s Is Nothing Then Return
CheckLinesInitialized()
s.Split(Environment.NewLine).ForEach(Sub(line, index)
If index = 0 Then
Dim currentLast = Lines(Lines.Count - 1)
' centered should never come from the current last line
' if WriteCenteredLine is called, it immediately creates a new line
Lines(Lines.Count - 1) = (currentLast.line + line, centered)
Else
Lines.Add((line, centered))
End If
End Sub)
End Sub
Public Overrides Sub Write(value As Object)
WriteString(value?.ToString)
End Sub
Public Overrides Sub WriteLine(value As Object)
WriteString(value?.ToString)
WriteLine()
End Sub
Public Overrides Sub WriteLine()
Lines.Add(("", False))
End Sub
Public Overrides Sub WriteCenteredLine(value As Object)
If Lines.Count = 0 Then Lines.Add(("", False))
Dim currentLast = Lines(Lines.Count - 1).line
If currentLast.Length > 0 Then Throw New InvalidOperationException("Can only write centered line if cursor is at start of line.")
WriteString(value?.ToString, True)
WriteLine()
End Sub
Public Overrides Function ReadLine() As String
' Indicates the end of a test run, for programs which loop endlessly
If inputs.Count = 0 Then Throw New EndOfStreamException("End of inputs")
Dim nextInput = inputs.Dequeue.Trim
WriteLine(nextInput)
Return nextInput
End Function
End Class

View File

@@ -0,0 +1,80 @@
Imports Xunit
Imports Animal
Imports System.IO
Public Class TestContainer
Private Shared Function ResponseVariantExpander(src As IEnumerable(Of String)) As TheoryData(Of String)
Dim theoryData = New TheoryData(Of String)
src.
SelectMany(Function(x) {x, x.Substring(0, 1)}).
SelectMany(Function(x) {
x,
x.ToUpperInvariant,
x.ToLowerInvariant,
x.ToTitleCase,
x.ToReverseCase
}).
Distinct.
ForEach(Sub(x) theoryData.Add(x))
Return theoryData
End Function
Private Shared YesVariantsThepryData As TheoryData(Of String) = ResponseVariantExpander({"yes", "true", "1"})
Private Shared Function YesVariants() As TheoryData(Of String)
Return YesVariantsThepryData
End Function
Private Shared NoVariantsThepryData As TheoryData(Of String) = ResponseVariantExpander({"no", "false", "0"})
Private Shared Function NoVariants() As TheoryData(Of String)
Return NoVariantsThepryData
End Function
''' <summary>Test LIST variants</summary>
<Theory>
<InlineData("LIST")>
<InlineData("list")>
<InlineData("List")>
<InlineData("lIST")>
Sub List(listResponse As String)
Dim console As New MockConsole({listResponse})
Dim game As New Game(console)
Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop())
Assert.Equal(
{
"ANIMALS I ALREADY KNOW ARE:",
"FISH BIRD "
},
console.Lines.Slice(-4, -2).Select(Function(x) x.line)
)
End Sub
'' <summary>Test YES variants</summary>
<Theory>
<MemberData(NameOf(YesVariants))>
Sub YesVariant(yesVariant As String)
Dim console As New MockConsole({yesVariant})
Dim game As New Game(console)
Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop())
Assert.Equal(
{
$"ARE YOU THINKING OF AN ANIMAL? {yesVariant}",
"DOES IT SWIM? "
},
console.Lines.Slice(-2, 0).Select(Function(x) x.line)
)
End Sub
'' <summary>Test NO variants</summary>
<Theory>
<MemberData(NameOf(NoVariants))>
Sub NoVariant(noVariant As String)
Dim console As New MockConsole({"y", noVariant})
Dim game As New Game(console)
Assert.Throws(Of EndOfStreamException)(Sub() game.BeginLoop())
Assert.Equal(
{
$"DOES IT SWIM? {noVariant}",
"IS IT A BIRD? "
},
console.Lines.Slice(-2, 0).Select(Function(x) x.line)
)
End Sub
End Class

View File

@@ -1,12 +0,0 @@
Imports System
Imports Xunit
Namespace Animal.Tests
Public Class UnitTest1
<Fact>
Sub TestSub()
End Sub
End Class
End Namespace

View File

@@ -14,6 +14,7 @@
End Sub
Public Overrides Sub WriteCenteredLine(value As Object)
If Console.CursorLeft <> 0 Then Throw New InvalidOperationException("Can only write centered line if cursor is at start of line.")
Dim toWrite = If(value?.ToString, "")
Console.WriteLine($"{Space((Console.WindowWidth - toWrite.Length) \ 2)}{toWrite}")
End Sub

View File

@@ -1,6 +1,11 @@
Imports System.Runtime.CompilerServices
Public Module Extensions
<Extension> Public Sub ForEach(Of T)(src As IEnumerable(Of T), action As Action(Of T))
For Each x In src
action(x)
Next
End Sub
<Extension> Public Sub ForEach(Of T)(src As IEnumerable(Of T), action As Action(Of T, Integer))
Dim index As Integer
For Each x In src
@@ -18,4 +23,28 @@ Public Module Extensions
If Not s.EndsWith(toAppend, StringComparison.OrdinalIgnoreCase) Then s += toAppend
Return s
End Function
<Extension> Public Function ToTitleCase(s As String) As String
If s Is Nothing Then Return Nothing
Return Char.ToUpperInvariant(s(0)) + s.Substring(1).ToUpperInvariant
End Function
' https://stackoverflow.com/a/3681580/111794
<Extension> Public Function ToReverseCase(s As String) As String
If s Is Nothing Then Return Nothing
Return New String(s.Select(Function(c) If(
Not Char.IsLetter(c),
c,
If(
Char.IsUpper(c), Char.ToLowerInvariant(c), Char.ToUpperInvariant(c)
)
)).ToArray)
End Function
' https://stackoverflow.com/a/58132204/111794
<Extension> Public Function Slice(Of T)(lst As IList(Of T), start As Integer, [end] As Integer) As T()
start = If(start >= 0, start, lst.Count + start)
[end] = If([end] > 0, [end], lst.Count + [end])
Return lst.Skip(start).Take([end] - start).ToArray
End Function
End Module