-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathEffectsSpec.scala
111 lines (94 loc) · 3.44 KB
/
EffectsSpec.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package com.evolutiongaming.bootcamp.effects
import cats.effect.{ExitCode, IO}
import cats.effect.testing.scalatest.AsyncIOSpec
import com.evolutiongaming.bootcamp.effects.v3.Console
import org.scalatest.Assertion
import org.scalatest.freespec.AsyncFreeSpec
import org.scalatest.matchers.should.Matchers
class EffectsSpec extends AsyncFreeSpec with AsyncIOSpec with Matchers {
final class TestConsole(var providedInput: List[String] = Nil, var expectedOutput: List[String] = Nil)
extends Console {
def expectOutput(x: String): TestConsole = {
expectedOutput = expectedOutput :+ x
this
}
def provideInput(x: String): TestConsole = {
providedInput = providedInput :+ x
this
}
def expectEmpty: IO[Unit] =
if (providedInput.isEmpty && expectedOutput.isEmpty) IO.unit
else IO.raiseError(sys.error(s"Non empty console: $providedInput, $expectedOutput"))
override def putString(value: String): IO[Unit] = expectedOutput match {
case Nil =>
IO.raiseError(sys.error(s"Writing `$value` unexpectedly"))
case x :: xs if x == value =>
expectedOutput = xs
IO.unit
case x :: xs =>
IO.raiseError(sys.error(s"Writing `$value` but expected `$x` (remaining in buffer $xs)"))
}
override def readString: IO[String] = providedInput match {
case Nil =>
IO.raiseError(sys.error(s"Cannot read - out of provided input"))
case x :: xs =>
providedInput = xs
IO.pure(x)
}
}
import com.evolutiongaming.bootcamp.effects.v3.Exercise1_Functional._
private def check(f: TestConsole => TestConsole, exitCode: ExitCode): IO[Assertion] = {
val console = f(new TestConsole)
val program = for {
result <- process(console)
_ <- console.expectEmpty
} yield result
program.asserting(_ shouldBe exitCode)
}
"Exercise 1" - {
"dogs" in {
check(
_.expectOutput("What is your favourite animal?")
.provideInput("dogs")
.expectOutput("Be the person your dog thinks you are."),
ExitCode.Success,
)
}
"cats" in {
check(
_.expectOutput("What is your favourite animal?")
.provideInput("cats")
.expectOutput("In ancient times cats were worshipped as gods; they have not forgotten this."),
ExitCode.Success,
)
}
"some wrong answers" in {
check(
_.expectOutput("What is your favourite animal?")
.provideInput("")
.expectOutput("Empty input is not valid, try again...")
.expectOutput("What is your favourite animal?")
.provideInput(" ")
.expectOutput("Empty input is not valid, try again...")
.expectOutput("What is your favourite animal?")
.provideInput("elephants")
.expectOutput("I don't know what to say about 'elephants'."),
ExitCode.Success,
)
}
"too many wrong answers" in {
check(
_.expectOutput("What is your favourite animal?")
.provideInput("")
.expectOutput("Empty input is not valid, try again...")
.expectOutput("What is your favourite animal?")
.provideInput(" ")
.expectOutput("Empty input is not valid, try again...")
.expectOutput("What is your favourite animal?")
.provideInput(" ")
.expectOutput("I am disappoint. You have failed to answer too many times."),
ExitCode.Error,
)
}
}
}