diff --git a/main.go b/main.go index 38dd16d..da29a2c 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,4 @@ package main -func main() {} +func main() { +} diff --git a/repository/distance/calculate.go b/repository/distance/calculate.go new file mode 100644 index 0000000..248f252 --- /dev/null +++ b/repository/distance/calculate.go @@ -0,0 +1,40 @@ +package distance + +import ( + "math" + "mock-shipping-provider/primitive" + "mock-shipping-provider/repository" +) + +type CalculateDistance struct { + Radius float64 + ServicableDistance float64 +} + +func NewCalculateDistance() repository.DistanceCalculation { + return &CalculateDistance{ + Radius: 6371.0, + ServicableDistance: 5245.0, + } +} + +func (c *CalculateDistance) Calculate(from primitive.Coordinate, to primitive.Coordinate) (distance float64, serviceable bool) { + lat1Rad := from.Latitude * math.Pi / 180 + lon1Rad := from.Longitude * math.Pi / 180 + lat2Rad := to.Latitude * math.Pi / 180 + lon2Rad := to.Longitude * math.Pi / 180 + + dlat := lat2Rad - lat1Rad + dlon := lon2Rad - lon1Rad + + a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Cos(lat1Rad)*math.Cos(lat2Rad)*math.Sin(dlon/2)*math.Sin(dlon/2) + cal := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a)) + + distanceCalculation := c.Radius * cal + + if distanceCalculation > c.ServicableDistance { + return distanceCalculation, false + } + + return distanceCalculation, true +} diff --git a/repository/distance/calculate_test.go b/repository/distance/calculate_test.go new file mode 100644 index 0000000..98c1e00 --- /dev/null +++ b/repository/distance/calculate_test.go @@ -0,0 +1,44 @@ +package distance_test + +import ( + "mock-shipping-provider/primitive" + "mock-shipping-provider/repository/distance" + "testing" +) + +func TestDistanceCalculation(t *testing.T) { + distanceCalculation := distance.NewCalculateDistance() + + t.Run("test distance not service", func(t *testing.T) { + from := primitive.Coordinate{ + Latitude: -4.5387718, + Longitude: 120.3146973, + } + + to := primitive.Coordinate{ + Latitude: 40.7128, + Longitude: -74.0060, + } + distance, serviceable := distanceCalculation.Calculate(from, to) + if serviceable { + t.Errorf("must not servicable: %v", distance) + } + }) + + t.Run("test distance serviceable", func(t *testing.T) { + from := primitive.Coordinate{ + Latitude: -6.1601629, + Longitude: 106.6793193, + } + + to := primitive.Coordinate{ + Latitude: -4.5387718, + Longitude: 120.3146973, + } + distance, serviceable := distanceCalculation.Calculate(from, to) + if !serviceable { + t.Errorf("must be servicable: %v", distance) + } + }) + +}