1
+ package com.xebia.functional.chains
2
+
3
+ import arrow.core.raise.either
4
+ import io.kotest.assertions.arrow.core.shouldBeLeft
5
+ import io.kotest.assertions.arrow.core.shouldBeRight
6
+ import io.kotest.core.spec.style.StringSpec
7
+
8
+ class SequenceChainSpec : StringSpec ({
9
+ " SequenceChain should return a prediction with one Chain" {
10
+ val chain1 = FakeChain (inputVariables = setOf("foo"), outputVariables = setOf("bar"))
11
+ val chains = listOf(chain1)
12
+
13
+ either {
14
+ val sc = SequenceChain (
15
+ chains = chains,
16
+ inputVariables = listOf("foo"),
17
+ outputVariables = listOf("bar"),
18
+ chainOutput = Chain .ChainOutput .InputAndOutput
19
+ )
20
+ sc.run(mapOf("foo" to "123")).bind()
21
+ } shouldBeRight mapOf("foo" to "123", "bar" to "123dr")
22
+ }
23
+
24
+ " SequenceChain should return a prediction on a single input chain" {
25
+ val chain1 = FakeChain (inputVariables = setOf("foo"), outputVariables = setOf("bar"))
26
+ val chain2 = FakeChain (inputVariables = setOf("bar"), outputVariables = setOf("baz"))
27
+ val chains = listOf(chain1, chain2)
28
+
29
+ either {
30
+ val sc = SequenceChain (
31
+ chains = chains,
32
+ inputVariables = listOf("foo"),
33
+ outputVariables = listOf("baz"),
34
+ chainOutput = Chain .ChainOutput .InputAndOutput
35
+ )
36
+ sc.run(mapOf("foo" to "123")).bind()
37
+ } shouldBeRight mapOf("foo" to "123", "baz" to "123drdr")
38
+ }
39
+
40
+ " SequenceChain should return a prediction on a multiple input chain" {
41
+ val chain1 = FakeChain (inputVariables = setOf("foo", "test"), outputVariables = setOf("bar"))
42
+ val chain2 = FakeChain (inputVariables = setOf("bar", "foo"), outputVariables = setOf("baz"))
43
+ val chains = listOf(chain1, chain2)
44
+
45
+ either {
46
+ val sc = SequenceChain (
47
+ chains = chains,
48
+ inputVariables = listOf("foo", "test"),
49
+ outputVariables = listOf("baz"),
50
+ chainOutput = Chain .ChainOutput .InputAndOutput
51
+ )
52
+ sc.run(mapOf("foo" to "123", "test" to "456")).bind()
53
+ } shouldBeRight mapOf("foo" to "123", "test" to "456", "baz" to "123456dr123dr")
54
+ }
55
+
56
+ " SequenceChain should return a prediction on a multiple output chain" {
57
+ val chain1 = FakeChain (inputVariables = setOf("foo"), outputVariables = setOf("bar", "test"))
58
+ val chain2 = FakeChain (inputVariables = setOf("bar", "foo"), outputVariables = setOf("baz"))
59
+ val chains = listOf(chain1, chain2)
60
+
61
+ either {
62
+ val sc = SequenceChain (
63
+ chains = chains,
64
+ inputVariables = listOf("foo"),
65
+ outputVariables = listOf("baz"),
66
+ chainOutput = Chain .ChainOutput .InputAndOutput
67
+ )
68
+ sc.run(mapOf("foo" to "123")).bind()
69
+ } shouldBeRight mapOf("foo" to "123", "baz" to "123dr123dr")
70
+ }
71
+
72
+ " SequenceChain should fail when input variables are missing" {
73
+ val chain1 = FakeChain (inputVariables = setOf("foo"), outputVariables = setOf("bar"))
74
+ val chain2 = FakeChain (inputVariables = setOf("bar", "test"), outputVariables = setOf("baz"))
75
+ val chains = listOf(chain1, chain2)
76
+
77
+ either {
78
+ val sc = SequenceChain (
79
+ chains = chains,
80
+ inputVariables = listOf("foo"),
81
+ outputVariables = listOf("baz"),
82
+ chainOutput = Chain .ChainOutput .InputAndOutput
83
+ )
84
+ sc.run(mapOf("foo" to "123")).bind()
85
+ } shouldBeLeft Chain .InvalidInputs ("The provided inputs: {foo}, {bar} do not match with chain's inputs: {bar}, {test}")
86
+ }
87
+
88
+ " SequenceChain should fail when output variables are missing" {
89
+ val chain1 = FakeChain (inputVariables = setOf("foo"), outputVariables = setOf("bar"))
90
+ val chain2 = FakeChain (inputVariables = setOf("bar"), outputVariables = setOf("baz"))
91
+ val chains = listOf(chain1, chain2)
92
+
93
+ either {
94
+ val sc = SequenceChain .either(
95
+ chains = chains,
96
+ inputVariables = listOf("foo"),
97
+ outputVariables = listOf("test"),
98
+ chainOutput = Chain .ChainOutput .InputAndOutput
99
+ ).bind()
100
+ sc.run(mapOf("foo" to "123")).bind()
101
+ } shouldBeLeft SequenceChain .InvalidKeys ("The provided outputs: {test} do not exist in chains' outputs: {bar}, {baz}")
102
+ }
103
+
104
+ " SequenceChain should fail when input variables are overlapping" {
105
+ val chain1 = FakeChain (inputVariables = setOf("foo"), outputVariables = setOf("bar", "test"))
106
+ val chain2 = FakeChain (inputVariables = setOf("bar"), outputVariables = setOf("baz"))
107
+ val chains = listOf(chain1, chain2)
108
+
109
+ either {
110
+ val sc = SequenceChain .either(
111
+ chains = chains,
112
+ inputVariables = listOf("foo", "test"),
113
+ outputVariables = listOf("baz"),
114
+ chainOutput = Chain .ChainOutput .InputAndOutput
115
+ ).bind()
116
+ sc.run(mapOf("foo" to "123")).bind()
117
+ } shouldBeLeft SequenceChain .InvalidKeys ("The provided inputs: {foo}, {test} overlap with chain's outputs: {bar}, {test}, {baz}")
118
+ }
119
+ })
0 commit comments