8000 interfaces-to-funs.0 : Baseline · test-driven-development/code@165b104 · GitHub
[go: up one dir, main page]

Skip to content

Commit 165b104

Browse files
Duncan McGregordmcg
authored andcommitted
interfaces-to-funs.0 : Baseline
1 parent 1d281b0 commit 165b104

File tree

11 files changed

+376
-0
lines changed

11 files changed

+376
-0
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ dependencies {
2525
testImplementation "org.junit.jupiter:junit-jupiter-params:5.4.2"
2626
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.5.2"
2727
testRuntimeOnly "org.junit.platform:junit-platform-launcher:1.4.2"
28+
testImplementation "org.mockito:mockito-core:2.+"
2829
}
2930

3031
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {

src/main/java/travelator/Id.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package travelator;
2+
3+
import java.util.Objects;
4+
import java.util.UUID;
5+
6+
public class Id<T> {
7+
private final String raw;
8+
9+
private Id(String raw) {
10+
this.raw = raw;
11+
}
12+
13+
public static <T> Id<T> of(String raw) {
14+
return new Id<T>(raw);
15+
}
16+
17+
public static <T> String raw(Id<T> id) {
18+
return id.raw;
19+
}
20+
21+
public static <T> Id<T> mint() {
22+
return Id.of(UUID.randomUUID().toString());
23+
}
24+
25+
@Override
26+
public boolean equals(Object o) {
27+
if (this == o) return true;
28+
if (o == null || getClass() != o.getClass()) return false;
29+
Id<?> id = (Id<?>) o;
30+
return raw.equals(id.raw);
31+
}
32+
33+
@Override
34+
public int hashCode() {
35+
return Objects.hash(raw);
36+
}
37+
38+
@Override
39+
public String toString() {
40+
return raw;
41+
}
42+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package travelator.destinations
2+
3+
import travelator.domain.Location
4+
5+
data class FeaturedDestination(
6+
val name: String,
7+
val location: Location
8+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package travelator.destinations;
2+
3+
public class FeaturedDestinationData {
4+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package travelator.destinations;
2+
3+
import travelator.domain.Location;
4+
5+
import java.util.List;
6+
7+
public interface FeaturedDestinations {
8+
List<FeaturedDestination> findCloseTo(Location location);
9+
FeaturedDestination findClosest(Location location);
10+
11+
FeaturedDestination add(FeaturedDestinationData destination);
12+
void remove(FeaturedDestination destination);
13+
void update(FeaturedDestination destination);
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package travelator.domain
2+
3+
interface DistanceCalculator {
4+
fun distanceInMetersBetween(
5+
start: Location,
6+
end: Location
7+
): Int
8+
9+
fun travelTimeInSecondsBetween(
10+
start: Location,
11+
end: Location
12+
): Int
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package travelator.domain
2+
3+
class Itinerary {
4+
val locations: List<Location> = TODO()
5+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package travelator.domain;
2+
3+
import travelator.Id;
4+
5+
import java.util.Objects;
6+
7+
public class Location {
8+
private final Id<Location> id;
9+
private final String localName;
10+
private final String userReadableName;
11+
12+
public Location(Id<Location> id, String localName, String userReadableName) {
13+
this.id = id;
14+
this.localName = localName;
15+
this.userReadableName = userReadableName;
16+
}
17+
18+
public Id<Location> getId() {
19+
return id;
20+
}
21+
22+
public String getLocalName() {
23+
return localName;
24+
}
25+
26+
public String getUserReadableName() {
27+
return userReadableName;
28+
}
29+
30+
@Override
31+
public boolean equals(Object o) {
32+
if (this == o) return true;
33+
if (o == null || getClass() != o.getClass()) return false;
34+
Location location = (Location) o;
35+
return id.equals(location.id) &&
36+
localName.equals(location.localName) &&
37+
userReadableName.equals(location.userReadableName);
38+
}
39+
40+
@Override
41+
public int hashCode() {
42+
return Objects.hash(id, localName, userReadableName);
43+
}
44+
45+
@Override
46+
public String toString() {
47+
return "Location(" + id + ": " + userReadableName + ")";
48+
}
49+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package travelator.recommendations
2+
3+
import travelator.destinations.FeaturedDestination
4+
import travelator.domain.Location
5+
6+
data class FeaturedDestinationSuggestion(
7+
val routeLocation: Location,
8+
val suggestion: FeaturedDestination,
9+
val distanceMeters: Int
10+
)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package travelator.recommendations;
2+
3+
import travelator.destinations.FeaturedDestinations;
4+
import travelator.domain.DistanceCalculator;
5+
import travelator.domain.Location;
6+
7+
import java.util.Comparator;
8+
import java.util.List;
9+
import java.util.Set;
10+
import java.util.stream.Stream;
11+
12+
import static java.util.Comparator.comparing;
13+
import static java.util.stream.Collectors.groupingBy;
14+
import static java.util.stream.Collectors.toList;
15+
16+
public class Recommendations {
17+
private final FeaturedDestinations featuredDestinations;
18+
private final DistanceCalculator distanceCalculator;
19+
20+
public Recommendations(
21+
FeaturedDestinations featuredDestinations,
22+
DistanceCalculator distanceCalculator
23+
) {
24+
this.featuredDestinations = featuredDestinations;
25+
this.distanceCalculator = distanceCalculator;
26+
}
27+
private final Comparator<FeaturedDestinationSuggestion> distanceComparator =
28+
comparing(FeaturedDestinationSuggestion::getDistanceMeters);
29+
30+
31+
public List<FeaturedDestinationSuggestion> recommendationsFor(
32+
Set<Location> journey
33+
) {
34+
var results = removeDuplicates(
35+
journey.stream()
36+
.flatMap(location ->
37+
recommendationsFor(location).stream()
38+
)
39+
);
40+
results.sort(distanceComparator);
41+
return results;
42+
}
43+
44+
public List<FeaturedDestinationSuggestion> recommendationsFor(
45+
Location location
46+
) {
47+
return featuredDestinations
48+
.findCloseTo(location) // <1>
49+
.stream()
50+
.map(featuredDestination ->
51+
new FeaturedDestinationSuggestion(
52+
location,
53+
featuredDestination,
54+
distanceCalculator.distanceInMetersBetween( // <2>
55+
location,
56+
featuredDestination.getLocation()
57+
)
58+
)
59+
).collect(toList());
60+
}
61+
62+
63+
private List<FeaturedDestinationSuggestion> removeDuplicates(
64+
Stream<FeaturedDestinationSuggestion> suggestions
65+
) {
66+
return suggestions
67+
.collect(
68+
groupingBy(FeaturedDestinationSuggestion::getSuggestion)
69+
).values().stream()
70+
.map(this::closestToJourneyLocation)
71+
.collect(toList());
72+
}
73+
74+
private FeaturedDestinationSuggestion closestToJourneyLocation(
75+
List<FeaturedDestinationSuggestion> suggestionsWithSameDestination
76+
) {
77+
return suggestionsWithSameDestination.stream().min(distanceComparator).orElseThrow();
78+
}
79+
}

0 commit comments

Comments
 (0)
0