From 8a5517ddd9859df99ff51a1fede02fdf4a297e88 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Tue, 23 May 2023 20:35:00 +0200 Subject: [PATCH] More testing and Dewpoint added to curweather.go --- curweather.go | 26 ++++++++++++++++---- curweather_test.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++ source_test.go | 56 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 source_test.go diff --git a/curweather.go b/curweather.go index 63537cb..ec392e1 100644 --- a/curweather.go +++ b/curweather.go @@ -30,9 +30,9 @@ type CurrentWeather struct { // all values are represented as pointer type returning nil if the data point in question // is not returned for the requested Station. type APICurrentWeatherData struct { + // Dewpoint represents the dewpoint in °C + Dewpoint *APIValue `json:"dewpoint,omitempty"` /* - // Dewpoint represents the dewpoint in °C - Dewpoint *APIValue `json:"dewpoint,omitempty"` // DewPointMean represents the mean dewpoint in °C DewpointMean *APIValue `json:"dewpointMean,omitempty"` // GlobalRadiation10m represents the sum of global radiation over the last @@ -119,8 +119,7 @@ func (c *Client) CurrentWeatherByLocation(lo string) (CurrentWeather, error) { // Temperature returns the temperature data point as Temperature. // If the data point is not available in the CurrentWeather it will return -// Temperature in which the "not available" field will be -// true. +// Temperature in which the "not available" field will be true. func (cw CurrentWeather) Temperature() Temperature { if cw.Data.Temperature == nil { return Temperature{na: true} @@ -136,3 +135,22 @@ func (cw CurrentWeather) Temperature() Temperature { } return v } + +// Dewpoint returns the dewpoint data point as Temperature. +// If the data point is not available in the CurrentWeather it will return +// Temperature in which the "not available" field will be true. +func (cw CurrentWeather) Dewpoint() Temperature { + if cw.Data.Dewpoint == nil { + return Temperature{na: true} + } + v := Temperature{ + dt: cw.Data.Dewpoint.DateTime, + n: FieldDewpoint, + s: SourceUnknown, + v: cw.Data.Dewpoint.Value, + } + if cw.Data.Dewpoint.Source != nil { + v.s = StringToSource(*cw.Data.Dewpoint.Source) + } + return v +} diff --git a/curweather_test.go b/curweather_test.go index aa31fe0..d7eeda3 100644 --- a/curweather_test.go +++ b/curweather_test.go @@ -101,6 +101,10 @@ func TestClient_CurrentWeatherByLocation_Fail(t *testing.T) { if err == nil { t.Errorf("CurrentWeatherByCoordinates was supposed to fail, but didn't") } + _, err = c.CurrentWeatherByLocation("") + if err == nil { + t.Errorf("CurrentWeatherByCoordinates was supposed to fail, but didn't") + } } func TestClient_CurrentWeatherByLocation_Temperature(t *testing.T) { @@ -158,3 +162,59 @@ func TestClient_CurrentWeatherByLocation_Temperature(t *testing.T) { }) } } + +func TestClient_CurrentWeatherByLocation_Dewpoint(t *testing.T) { + tt := []struct { + // Location name + loc string + // Observation dewpoint + t *Temperature + }{ + {"Ehrenfeld, Germany", &Temperature{ + dt: time.Date(2023, 5, 23, 7, 0, 0, 0, time.Local), + s: SourceObservation, + v: 11.5, + }}, + {"Berlin, Germany", &Temperature{ + dt: time.Date(2023, 5, 23, 7, 0, 0, 0, time.Local), + s: SourceAnalysis, + v: 11.0, + }}, + } + c := New(withMockAPI()) + if c == nil { + t.Errorf("failed to create new Client, got nil") + return + } + for _, tc := range tt { + t.Run(tc.loc, func(t *testing.T) { + o, err := c.CurrentWeatherByLocation(tc.loc) + if err != nil { + t.Errorf("CurrentWeatherByLocation failed: %s", err) + return + } + if tc.t != nil && tc.t.String() != o.Dewpoint().String() { + t.Errorf("CurrentWeatherByLocation failed, expected dewpoint "+ + "string: %s, got: %s", tc.t.String(), o.Dewpoint()) + } + if tc.t != nil && tc.t.Value() != o.Dewpoint().Value() { + t.Errorf("CurrentWeatherByLocation failed, expected dewpoint "+ + "float: %f, got: %f", tc.t.Value(), o.Dewpoint().Value()) + } + if o.Dewpoint().Source() != tc.t.s { + t.Errorf("CurrentWeatherByLocation failed, expected source: %s, but got: %s", + tc.t.s, o.Dewpoint().Source()) + } + if tc.t == nil { + if o.Dewpoint().IsAvailable() { + t.Errorf("CurrentWeatherByLocation failed, expected dewpoint "+ + "to have no data, but got: %s", o.Dewpoint()) + } + if !math.IsNaN(o.Dewpoint().Value()) { + t.Errorf("CurrentWeatherByLocation failed, expected dewpoint "+ + "to return NaN, but got: %s", o.Dewpoint().String()) + } + } + }) + } +} diff --git a/source_test.go b/source_test.go new file mode 100644 index 0000000..ab42235 --- /dev/null +++ b/source_test.go @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: 2023 Winni Neessen +// +// SPDX-License-Identifier: MIT + +package meteologix + +import ( + "testing" +) + +func TestSource_String(t *testing.T) { + tt := []struct { + // Original source + os Source + // Expected string + es string + }{ + {SourceObservation, "Observation"}, + {SourceAnalysis, "Analysis"}, + {SourceForecast, "Forecast"}, + {SourceMixed, "Mixed"}, + {SourceUnknown, "Unknown"}, + {999, "Unknown"}, + } + for _, tc := range tt { + t.Run(tc.os.String(), func(t *testing.T) { + if tc.os.String() != tc.es { + t.Errorf("String for Source failed, expected: %s, got: %s", + tc.es, tc.os.String()) + } + }) + } +} + +func TestStringToSource(t *testing.T) { + tt := []struct { + // Original string + os string + // Expected source + es Source + }{ + {"Observation", SourceObservation}, + {"Analysis", SourceAnalysis}, + {"Forecast", SourceForecast}, + {"Mixed", SourceMixed}, + {"Unknown", SourceUnknown}, + } + for _, tc := range tt { + t.Run(tc.es.String(), func(t *testing.T) { + if r := StringToSource(tc.os); r != tc.es { + t.Errorf("StringToSource failed, expected: %s, got: %s", + tc.es.String(), r.String()) + } + }) + } +}