mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2026-01-06 10:05:45 -08:00
37
00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt
Normal file
37
00_Utilities/jvmTestUtils/kotlin/test/ConsoleTest.kt
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.pcholt.console.testutils
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import org.junit.Rule
|
||||
import org.junit.contrib.java.lang.system.SystemOutRule
|
||||
import org.junit.contrib.java.lang.system.TextFromStandardInputStream
|
||||
|
||||
abstract class ConsoleTest {
|
||||
@get:Rule
|
||||
val inputRule = TextFromStandardInputStream.emptyStandardInputStream()
|
||||
|
||||
@get:Rule
|
||||
val systemOutRule = SystemOutRule().enableLog()
|
||||
|
||||
val regexInputCommand = "\\{(.*)}".toRegex()
|
||||
|
||||
fun assertConversation(conversation: String, runMain: () -> Unit) {
|
||||
|
||||
inputRule.provideLines(*regexInputCommand
|
||||
.findAll(conversation)
|
||||
.map { it.groupValues[1] }
|
||||
.toList().toTypedArray())
|
||||
|
||||
runMain()
|
||||
|
||||
Truth.assertThat(
|
||||
systemOutRule.log.trimWhiteSpace()
|
||||
)
|
||||
.isEqualTo(
|
||||
regexInputCommand
|
||||
.replace(conversation, "").trimWhiteSpace()
|
||||
)
|
||||
}
|
||||
|
||||
private fun String.trimWhiteSpace() =
|
||||
replace("[\\s]+".toRegex(), " ")
|
||||
}
|
||||
@@ -74,11 +74,11 @@ public class Animal {
|
||||
private static void askForInformationAndSave(Scanner scan, AnimalNode current, QuestionNode previous, boolean previousToCurrentDecisionChoice) {
|
||||
//Failed to get it right and ran out of questions
|
||||
//Let's ask the user for the new information
|
||||
System.out.print("THE ANIMAL YOU WERE THINKING OF WAS A ");
|
||||
System.out.print("THE ANIMAL YOU WERE THINKING OF WAS A ? ");
|
||||
String animal = scan.nextLine();
|
||||
System.out.printf("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A %s FROM A %s ", animal, current.getAnimal());
|
||||
System.out.printf("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A %s FROM A %s ? ", animal, current.getAnimal());
|
||||
String newQuestion = scan.nextLine();
|
||||
System.out.printf("FOR A %s THE ANSWER WOULD BE ", animal);
|
||||
System.out.printf("FOR A %s THE ANSWER WOULD BE ? ", animal);
|
||||
boolean newAnswer = readYesOrNo(scan);
|
||||
//Add it to our question store
|
||||
addNewAnimal(current, previous, animal, newQuestion, newAnswer, previousToCurrentDecisionChoice);
|
||||
55
03_Animal/java/test/AnimalJavaTest.kt
Normal file
55
03_Animal/java/test/AnimalJavaTest.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
import com.pcholt.console.testutils.ConsoleTest
|
||||
import org.junit.Test
|
||||
|
||||
class AnimalJavaTest : ConsoleTest() {
|
||||
|
||||
@Test
|
||||
fun `given a standard setup, find the fish`() {
|
||||
assertConversation(
|
||||
"""
|
||||
$title
|
||||
ARE YOU THINKING OF AN ANIMAL ? {YES}
|
||||
DOES IT SWIM ? {YES}
|
||||
IS IT A FISH ? {YES}
|
||||
WHY NOT TRY ANOTHER ANIMAL?
|
||||
ARE YOU THINKING OF AN ANIMAL ? {QUIT}
|
||||
"""
|
||||
) {
|
||||
Animal.main(emptyArray())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a standard setup, create a cow, and verify`() {
|
||||
assertConversation(
|
||||
"""
|
||||
$title
|
||||
ARE YOU THINKING OF AN ANIMAL ? {YES}
|
||||
DOES IT SWIM ? {NO}
|
||||
IS IT A BIRD ? {NO}
|
||||
THE ANIMAL YOU WERE THINKING OF WAS A ? {COW}
|
||||
PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A
|
||||
COW FROM A BIRD
|
||||
? {DOES IT EAT GRASS}
|
||||
FOR A COW THE ANSWER WOULD BE ? {YES}
|
||||
ARE YOU THINKING OF AN ANIMAL ? {YES}
|
||||
DOES IT SWIM ? {NO}
|
||||
DOES IT EAT GRASS ? {YES}
|
||||
IS IT A COW ? {YES}
|
||||
WHY NOT TRY ANOTHER ANIMAL?
|
||||
ARE YOU THINKING OF AN ANIMAL ? {QUIT}
|
||||
"""
|
||||
) {
|
||||
Animal.main(emptyArray())
|
||||
}
|
||||
}
|
||||
|
||||
private val title = """
|
||||
ANIMAL
|
||||
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
|
||||
|
||||
PLAY 'GUESS THE ANIMAL'
|
||||
THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT.
|
||||
"""
|
||||
}
|
||||
|
||||
55
03_Animal/kotlin/test/AnimalKtTest.kt
Normal file
55
03_Animal/kotlin/test/AnimalKtTest.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
import com.pcholt.console.testutils.ConsoleTest
|
||||
import org.junit.Test
|
||||
|
||||
class AnimalKtTest : ConsoleTest() {
|
||||
|
||||
@Test
|
||||
fun `given a standard setup, find the fish`() {
|
||||
assertConversation(
|
||||
"""
|
||||
$title
|
||||
ARE YOU THINKING OF AN ANIMAL? {YES}
|
||||
DOES IT SWIM? {YES}
|
||||
IS IT A FISH? {YES}
|
||||
WHY NOT TRY ANOTHER ANIMAL?
|
||||
ARE YOU THINKING OF AN ANIMAL? {QUIT}
|
||||
"""
|
||||
) {
|
||||
main()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a standard setup, create a cow, and verify`() {
|
||||
assertConversation(
|
||||
"""
|
||||
$title
|
||||
ARE YOU THINKING OF AN ANIMAL? {YES}
|
||||
DOES IT SWIM? {NO}
|
||||
IS IT A BIRD? {NO}
|
||||
THE ANIMAL YOU WERE THINKING OF WAS A? {COW}
|
||||
PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A
|
||||
COW FROM A BIRD
|
||||
? {DOES IT EAT GRASS}
|
||||
FOR A COW THE ANSWER WOULD BE? {YES}
|
||||
ARE YOU THINKING OF AN ANIMAL? {YES}
|
||||
DOES IT SWIM? {NO}
|
||||
DOES IT EAT GRASS? {YES}
|
||||
IS IT A COW? {YES}
|
||||
WHY NOT TRY ANOTHER ANIMAL?
|
||||
ARE YOU THINKING OF AN ANIMAL? {QUIT}
|
||||
"""
|
||||
) {
|
||||
main()
|
||||
}
|
||||
}
|
||||
|
||||
private val title = """
|
||||
ANIMAL
|
||||
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
|
||||
|
||||
PLAY 'GUESS THE ANIMAL'
|
||||
THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT.
|
||||
"""
|
||||
}
|
||||
|
||||
@@ -67,16 +67,16 @@ directory for the java or kotlin file, and the class that contains the `main` me
|
||||
The `build.gradle` file **should** be identical to all the other `build.gradle` files
|
||||
in all the other subprojects:
|
||||
```groovy
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDirs "../../$gameSource"
|
||||
}
|
||||
}
|
||||
}
|
||||
application {
|
||||
mainClass = gameMain
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDirs "../../$gameSource"
|
||||
}
|
||||
}
|
||||
}
|
||||
application {
|
||||
mainClass = gameMain
|
||||
}
|
||||
```
|
||||
|
||||
The `gradle.properties` file should look like this:
|
||||
@@ -92,3 +92,84 @@ project to the list.
|
||||
```groovy
|
||||
include ":build_91_Train_java"
|
||||
```
|
||||
|
||||
### Adding a game with tests
|
||||
|
||||
You can add tests for JVM games with a `build.gradle` looking a little different.
|
||||
Use the build files from `03_Animal` as a template to add tests:
|
||||
|
||||
```groovy
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDirs "../../$gameSource"
|
||||
}
|
||||
}
|
||||
test {
|
||||
java {
|
||||
srcDirs "../../$gameTest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass = gameMain
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation(project(":build_00_utilities").sourceSets.test.output)
|
||||
}
|
||||
```
|
||||
|
||||
The gradle.properties needs an additional directory name for the tests, as `gameTest` :
|
||||
```
|
||||
gameSource=03_Animal/java/src
|
||||
gameTest=03_Animal/java/test
|
||||
gameMain=Animal
|
||||
```
|
||||
|
||||
Each project should have its own test, and shouldn't share test source directories
|
||||
with other projects, even if they are for the same game.
|
||||
|
||||
Tests are constructed by subclassing `ConsoleTest`. This allows you to use the
|
||||
`assertConversation` function to check for correct interactive conversations.
|
||||
```kotlin
|
||||
import com.pcholt.console.testutils.ConsoleTest
|
||||
import org.junit.Test
|
||||
|
||||
class AnimalJavaTest : ConsoleTest() {
|
||||
@Test
|
||||
fun `should have a simple conversation`() {
|
||||
assertConversation(
|
||||
"""
|
||||
WHAT'S YOUR NAME? {PAUL}
|
||||
YOUR NAME IS PAUL? {YES}
|
||||
THANKS FOR PLAYING
|
||||
"""
|
||||
) {
|
||||
// The game's Main method
|
||||
main()
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Curly brackets are the expected user input.
|
||||
Note - this is actually just a way of defining the expected input as "PAUL" and "YES"
|
||||
and not that the input happens at the exact prompt position. Thus this is equivalent:
|
||||
```kotlin
|
||||
"""
|
||||
{PAUL} {YES} WHAT'S YOUR NAME?
|
||||
YOUR NAME IS PAUL?
|
||||
THANKS FOR PLAYING
|
||||
"""
|
||||
```
|
||||
|
||||
Amounts of whitespace are not counted, but whitespace is significant: You will get a failure if
|
||||
your game emits `"NAME?"` when it expects `"NAME ?"`.
|
||||
|
||||
Run all the tests from within the buildJvm project directory:
|
||||
```bash
|
||||
cd buildJvm
|
||||
./gradlew test
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user