Added tests for astronomical data. Let's merge this for now as 0.0.7

This commit is contained in:
Winni Neessen 2023-05-28 23:31:53 +02:00
parent 7ffd3943e0
commit 0608c4ecaa
Signed by: wneessen
GPG key ID: 5F3AF39B820C119D
4 changed files with 189 additions and 14 deletions

141
astroinfo_test.go Normal file
View file

@ -0,0 +1,141 @@
// SPDX-FileCopyrightText: 2023 Winni Neessen <wn@neessen.dev>
//
// SPDX-License-Identifier: MIT
package meteologix
import (
"testing"
"time"
)
func TestClient_AstronomicalInfoByCoordinates(t *testing.T) {
la := 52.5067296
lo := 13.2599306
loc, err := time.LoadLocation("Europe/Berlin")
if err != nil {
t.Errorf("failed to load time location data for Europe/Berlin: %s", err)
return
}
rt := time.Date(2023, 5, 28, 15, 8, 33, 0, loc)
nfmt := time.Date(2023, 6, 4, 5, 43, 56, 0, loc)
nnmt := time.Date(2023, 6, 18, 6, 39, 10, 0, loc)
c := New(withMockAPI())
ai, err := c.AstronomicalInfoByCoordinates(la, lo)
if err != nil {
t.Errorf("failed to fetch astronomical information: %s", err)
return
}
if ai.Latitude != la {
t.Errorf("AstronomicalInfoByCoordinates failed, expected lat: %f, got: %f", la,
ai.Latitude)
}
if ai.Longitude != lo {
t.Errorf("AstronomicalInfoByCoordinates failed, expected lon: %f, got: %f", lo,
ai.Longitude)
}
if ai.Run.UnixMilli() != rt.UnixMilli() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected run time: %s, got: %s",
rt.String(), ai.Run.String())
}
if ai.TimeZone != loc.String() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected time zone: %s, got: %s",
loc.String(), ai.TimeZone)
}
if ai.NextFullMoon.UnixMilli() != nfmt.UnixMilli() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected next full moon: %s, got: %s",
nfmt.String(), ai.NextFullMoon.String())
}
if ai.NextNewMoon.UnixMilli() != nnmt.UnixMilli() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected next new moon: %s, got: %s",
nnmt.String(), ai.NextNewMoon.String())
}
}
func TestClient_AstronomicalInfoByLocation(t *testing.T) {
la := 52.5067296
lo := 13.2599306
loc, err := time.LoadLocation("Europe/Berlin")
if err != nil {
t.Errorf("failed to load time location data for Europe/Berlin: %s", err)
return
}
rt := time.Date(2023, 5, 28, 15, 8, 33, 0, loc)
nfmt := time.Date(2023, 6, 4, 5, 43, 56, 0, loc)
nnmt := time.Date(2023, 6, 18, 6, 39, 10, 0, loc)
c := New(withMockAPI())
ai, err := c.AstronomicalInfoByLocation("Berlin, Germany")
if err != nil {
t.Errorf("failed to fetch astronomical information: %s", err)
return
}
if ai.Latitude != la {
t.Errorf("AstronomicalInfoByCoordinates failed, expected lat: %f, got: %f", la,
ai.Latitude)
}
if ai.Longitude != lo {
t.Errorf("AstronomicalInfoByCoordinates failed, expected lon: %f, got: %f", lo,
ai.Longitude)
}
if ai.Run.UnixMilli() != rt.UnixMilli() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected run time: %s, got: %s",
rt.String(), ai.Run.String())
}
if ai.TimeZone != loc.String() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected time zone: %s, got: %s",
loc.String(), ai.TimeZone)
}
if ai.NextFullMoon.UnixMilli() != nfmt.UnixMilli() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected next full moon: %s, got: %s",
nfmt.String(), ai.NextFullMoon.String())
}
if ai.NextNewMoon.UnixMilli() != nnmt.UnixMilli() {
t.Errorf("AstronomicalInfoByCoordinates failed, expected next new moon: %s, got: %s",
nnmt.String(), ai.NextNewMoon.String())
}
}
func TestAstronomicalInfo_SunsetByDateString(t *testing.T) {
la := 52.5067296
lo := 13.2599306
loc, err := time.LoadLocation("Europe/Berlin")
if err != nil {
t.Errorf("failed to load time location data for Europe/Berlin: %s", err)
return
}
ti := time.Date(2023, 5, 28, 21, 16, 37, 0, loc)
c := New(withMockAPI())
ai, err := c.AstronomicalInfoByCoordinates(la, lo)
if err != nil {
t.Errorf("failed to fetch astronomical information: %s", err)
return
}
if !ai.SunsetByTime(ti).IsAvailable() {
t.Errorf("SunsetByTime failed, expected entry, but got 'not available'")
return
}
if ai.SunsetByTime(ti).Value().UnixMilli() != ti.UnixMilli() {
t.Errorf("SunsetByTime failed, expected sunset: %s, got: %s",
ti.String(), ai.SunsetByTime(ti).Value().String())
}
if !ai.SunsetByDateString(ti.Format(DateFormat)).IsAvailable() {
t.Errorf("SunsetByDateString failed, expected entry, but got 'not available'")
return
}
if ai.SunsetByTime(ti).String() != ti.String() {
t.Errorf("SunsetByTime failed, expected sunset: %s, got: %s",
ti.String(), ai.SunsetByTime(ti).String())
}
if ai.SunsetByDateString(ti.Format(DateFormat)).Value().UnixMilli() != ti.UnixMilli() {
t.Errorf("SunsetByDateString failed, expected sunset: %s, got: %s",
ti.String(), ai.SunsetByDateString(ti.Format(DateFormat)).Value().String())
}
ti = time.Time{}
if ai.SunsetByTime(ti).IsAvailable() {
t.Errorf("SunsetByTime failed, expected no entry, but got: %s",
ai.SunsetByTime(ti).Value().String())
}
if !ai.SunsetByTime(ti).Value().IsZero() {
t.Errorf("SunsetByTime failed, expected no entry, but got: %s",
ai.SunsetByTime(ti).Value().String())
}
}

View file

@ -16,7 +16,7 @@ const DataUnavailable = "Data unavailable"
// DateFormat is the parsing format that is used for datetime strings
// that only hold the date but no time
const DateFormat = "2006-02-01"
const DateFormat = "2006-01-02"
// Enum for different Fieldname values
const (
@ -120,7 +120,8 @@ type WeatherData struct {
// of an Observation
type Fieldname int
// UnmarshalJSON interprets the API datestamp and converts it into a time.Time type
// UnmarshalJSON interprets the API datestamp and converts it into a
// time.Time type
func (a *APIDate) UnmarshalJSON(s []byte) error {
d := string(s)
d = strings.ReplaceAll(d, `"`, ``)
@ -128,17 +129,7 @@ func (a *APIDate) UnmarshalJSON(s []byte) error {
return nil
}
var pd time.Time
var err error
switch len(d) {
case 10:
pd, err = time.Parse(DateFormat, d)
case 20:
pd, err = time.Parse(time.RFC3339, d)
default:
return fmt.Errorf("failed to parse JSON string as API date: " +
"unknown input date format")
}
pd, err := time.Parse(DateFormat, d)
if err != nil {
return fmt.Errorf("failed to parse JSON string as APIDate string: %w", err)
}

37
datatype_test.go Normal file
View file

@ -0,0 +1,37 @@
// SPDX-FileCopyrightText: 2023 Winni Neessen <wn@neessen.dev>
//
// SPDX-License-Identifier: MIT
package meteologix
import (
"encoding/json"
"testing"
)
func TestAPIDate_UnmarshalJSON(t *testing.T) {
type x struct {
Date APIDate `json:"date"`
}
okd := []byte(`{"date":"2023-05-28"}`)
nokd := []byte(`{"date":"2023-05-32"}`)
null := []byte(`{"date":null}`)
var d x
if err := json.Unmarshal(okd, &d); err != nil {
t.Errorf("APIDate_UnmarshalJSON failed: %s", err)
}
if d.Date.Format(DateFormat) != "2023-05-28" {
t.Errorf("APIDate_UnmarshalJSON failed, expected: %s, but got: %s",
"2023-05-28", d.Date.String())
}
if err := json.Unmarshal(nokd, &d); err == nil {
t.Errorf("APIDate_UnmarshalJSON was supposed to fail, but didn't")
}
d = x{}
if err := json.Unmarshal(null, &d); err != nil {
t.Errorf("APIDate_UnmarshalJSON failed: %s", err)
}
if !d.Date.IsZero() {
t.Errorf("APIDate_UnmarshalJSON with null was supposed to be empty, but got: %s",
d.Date.String())
}
}

View file

@ -23,7 +23,13 @@ func (dt DateTime) IsAvailable() bool {
// Value will return time.Time with a zero value instead.
func (dt DateTime) Value() time.Time {
if dt.na {
return time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)
return time.Time{}
}
return dt.dv
}
// String satisfies the fmt.Stringer interface for the DateTime
// type
func (dt DateTime) String() string {
return dt.dv.String()
}