8000 mocks-to-maps.5 : tests as data · test-driven-development/code@c7f10a8 · GitHub
[go: up one dir, main page]

Skip to content

Commit c7f10a8

Browse files
Duncan McGregordmcg
authored andcommitted
mocks-to-maps.5 : tests as data
1 parent f30d5c8 commit c7f10a8

File tree

1 file changed

+91
-82
lines changed

1 file changed

+91
-82
lines changed

src/test/java/travelator/recommendations/RecommendationsTests.kt

Lines changed: 91 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -7,127 +7,136 @@ import travelator.destinations.FeaturedDestination
77
import travelator.domain.Location
88

99
class RecommendationsTests {
10-
11-
private val featuredDestinations =
12-
mutableMapOf<Location, List<FeaturedDestination>>()
13-
.withDefault { emptyList() }
14-
private val distanceInMetersBetween =
15-
mutableMapOf<Pair<Location, Location>, Int>()
16-
.withDefault { -1 }
17-
18-
private val recommendations =
19-
Recommendations(
20-
featuredDestinations::getValue,
21-
distanceInMetersBetween::getValue
10+
companion object {
11+
val distances = mapOf(
12+
(paris to eiffelTower.location) to 5000,
13+
(paris to louvre.location) to 1000,
14+
(alton to flowerFarm.location) to 5300,
15+
(alton to watercressLine.location) to 320,
16+
(froyle to flowerFarm.location) to 0,
17+
(froyle to watercressLine.location) to 6300
2218
)
19+
}
2320

24-
private val paris = location("Paris")
25-
private val louvre = featured("Louvre", "Rue de Rivoli")
26-
private val eiffelTower = featured("Eiffel Tower", "Champ de Mars")
27-
private val alton = location("Alton")
28-
private val froyle = location("Froyle")
29-
private val watercressLine = featured("Watercress Line", "Alton Station")
30-
private val flowerFarm = featured("West End Flower Farm", froyle)
3121

3222
@Test
3323
fun returns_no_recommendations_when_no_locations() {
34-
assertEquals(
35-
emptyList<Any>(),
36-
recommendations.recommendationsFor(emptySet())
24+
check(
25+
featuredDestinations = emptyMap(),
26+
distances = distances,
27+
recommendations = emptySet(),
28+
shouldReturn = emptyList()
3729
)
3830
}
3931

32+
4033
@Test
4134
fun returns_no_recommendations_when_no_featured() {
42-
givenFeaturedDestinationsFor(paris, of())
43-
assertEquals(
44-
emptyList<Any>(),
45-
recommendations.recommendationsFor(setOf(paris))
35+
check(
36+
featuredDestinations = emptyMap(),
37+
distances = distances,
38+
recommendations = setOf(paris),
39+
shouldReturn = emptyList()
4640
)
4741
}
4842

43+
4944
@Test
5045
fun returns_recommendations_for_single_location() {
51-
givenFeaturedDestinationsFor(paris, of(eiffelTower, louvre))
52-
53-
givenADistanceFrom(paris, to = eiffelTower, of = 5000)
54-
givenADistanceFrom(paris, to = louvre, of = 1000)
55-
56-
assertEquals(
57-
listOf(
46+
check(
47+
featuredDestinations = mapOf(
48+
paris to listOf(eiffelTower, louvre),
49+
),
50+
distances = distances,
51+
recommendations = setOf(paris),
52+
shouldReturn = listOf(
5853
FeaturedDestinationSuggestion(paris, louvre, 1000),
5954
FeaturedDestinationSuggestion(paris, eiffelTower, 5000)
60-
),
61-
recommendations.recommendationsFor(setOf(paris))
55+
)
6256
)
6357
}
6458

59+
6560
@Test
6661
fun returns_recommendations_for_multi_location() {
67-
givenFeaturedDestinationsFor(paris, of(eiffelTower, louvre))
68-
givenADistanceFrom(paris, to = eiffelTower, of = 5000)
69-
givenADistanceFrom(paris, to = louvre, of = 1000)
70-
71-
givenFeaturedDestinationsFor(alton, of(flowerFarm, watercressLine))
72-
givenADistanceFrom(alton, to = flowerFarm, of = 5300)
73-
givenADistanceFrom(alton, to = watercressLine, of = 320)
74-
75-
assertEquals(
76-
listOf(
62+
check(
63+
featuredDestinations = mapOf(
64+
paris to listOf(eiffelTower, louvre),
65+
alton to listOf(flowerFarm, watercressLine),
66+
),
67+
distances = distances,
68+
recommendations = setOf(paris, alton),
69+
shouldReturn = listOf(
7770
FeaturedDestinationSuggestion(alton, watercressLine, 320),
7871
FeaturedDestinationSuggestion(paris, louvre, 1000),
7972
FeaturedDestinationSuggestion(paris, eiffelTower, 5000),
8073
FeaturedDestinationSuggestion(alton, flowerFarm, 5300)
81-
),
82-
recommendations.recommendationsFor(setOf(paris, alton))
74+
)
8375
)
8476
}
8577

8678
@Test
8779
fun deduplicates_using_smallest_distance() {
88-
givenFeaturedDestinationsFor(alton, of(flowerFarm, watercressLine))
89-
givenADistanceFrom(alton, to = flowerFarm, of = 5300)
90-
givenADistanceFrom(alton, to = watercressLine, of = 320)
91-
92-
givenFeaturedDestinationsFor(froyle, of(flowerFarm, watercressLine))
93-
givenADistanceFrom(froyle, to = flowerFarm, of = 0)
94-
givenADistanceFrom(froyle, to = watercressLine, of = 6300)
95-
96-
assertEquals(
97-
listOf(
80+
check(
81+
featuredDestinations = mapOf(
82+
alton to listOf(flowerFarm, watercressLine),
83+
froyle to listOf(flowerFarm, watercressLine)
84+
),
85+
distances = distances,
86+
recommendations = setOf(alton, froyle),
87+
shouldReturn = listOf(
9888
FeaturedDestinationSuggestion(froyle, flowerFarm, 0),
9989
FeaturedDestinationSuggestion(alton, watercressLine, 320)
100-
),
101-
recommendations.recommendationsFor(setOf(alton, froyle))
90+
)
10291
)
10392
}
93+
}
10494

105-
private fun givenFeaturedDestinationsFor(
106-
location: Location,
107-
of: List<FeaturedDestination>
108-
) {
109-
featuredDestinations[location] = of
110-
}
111-
112-
private fun givenADistanceFrom(
113-
from: Location,
114-
to: FeaturedDestination,
115-
of: Int
116-
) {
117-
distanceInMetersBetween[from to to.location] = of
118-
}
119-
120-
private fun location(name: String) = Location(Id.of(name), name, name)
121-
122-
private fun featured(name: String, locationName: String) =
123-
featured(name, location(locationName))
95+
private fun subjectFor(
96+
featuredDestinations: Map<Location, List<FeaturedDestination>>,
97+
distances: Map<Pair<Location, Location>, Int>
98+
): Recommendations {
99+
val destinationsLookup = featuredDestinations.withDefault { emptyList() }
100+
val distanceLookup = distances.withDefault { -1 }
101+
return Recommendations(destinationsLookup::getValue, distanceLookup::getValue)
102+
}
124103

125-
private fun featured(name: String, location: Location) =
126-
FeaturedDestination(name, location)
104+
private fun check(
105+
featuredDestinations: Map<Location, List<FeaturedDestination>>,
106+
distances: Map<Pair<Location, Location>, Int>,
107+
recommendations: Set<Location>,
108+
shouldReturn: List<FeaturedDestinationSuggestion>
109+
) {
110+
assertEquals(
111+
shouldReturn,
112+
resultFor(featuredDestinations, distances, recommendations)
113+
)
127114
}
128115

129-
private fun of(vararg destination: FeaturedDestination)
130-
= destination.toList()
116+
private fun resultFor(
117+
featuredDestinations: Map<Location, List<FeaturedDestination>>,
118+
distances: Map<Pair<Location, Location>, Int>,
119+
locations: Set<Location>
120+
): List<FeaturedDestinationSuggestion> {
121+
val subject = subjectFor(featuredDestinations, distances)
122+
return subject.recommendationsFor(locations)
123+
}
131124

132125
private fun <K1, K2, V> Map<Pair<K1, K2>, V>.getValue(k1: K1, k2: K2) =
133126
getValue(k1 to k2)
127+
128+
private val paris = location("Paris")
129+
private val louvre = featured("Louvre", "Rue de Rivoli")
130+
private val eiffelTower = featured("Eiffel Tower", "Champ de Mars")
131+
private val alton = location("Alton")
132+
private val froyle = location("Froyle")
133+
private val watercressLine = featured("Watercress Line", "Alton Station")
134+
private val flowerFarm = featured("West End Flower Farm", froyle)
135+
136+
private fun location(name: String) = Location(Id.of(name), name, name)
137+
138+
private fun featured(name: String, locationName: String) =
139+
featured(name, location(locationName))
140+
141+
private fun featured(name: String, location: Location) =
142+
FeaturedDestination(name, location)

0 commit comments

Comments
 (0)
0