diff --git a/README.md b/README.md index 0cea1c715e7acb1a8903120ed32b2a8729e8d2d1..5b96f4955893864649629add527c277330b93496 100644 --- a/README.md +++ b/README.md @@ -150,4 +150,6 @@ to be used later. The `edu.unl.cse.soft160.json_connections.connector.OpenWeatherConnector` class provides a wrapper for `RestConnection` and `FileConnection` to simplify client -code that uses data from [OpenWeathermap.org](https://openweathermap.org). \ No newline at end of file +code that uses data from [OpenWeathermap.org](https://openweathermap.org). + +**In a typical project, you should only need to directly use `OpenWeatherConnector`.** \ No newline at end of file diff --git a/src/main/java/edu/unl/cse/soft160/json_connections/connector/OpenWeatherConnector.java b/src/main/java/edu/unl/cse/soft160/json_connections/connector/OpenWeatherConnector.java index 0d9cdf42a43dd25d721354a244e75aaab9700f0b..3d64643d9b9174ddfc858545cf2a571fc43220eb 100644 --- a/src/main/java/edu/unl/cse/soft160/json_connections/connector/OpenWeatherConnector.java +++ b/src/main/java/edu/unl/cse/soft160/json_connections/connector/OpenWeatherConnector.java @@ -591,11 +591,10 @@ public class OpenWeatherConnector { public long getVisibility(Date timestamp) { checkForDataReadiness(Set.of("forecast", "onecall")); if (dataSet.equals("onecall") && !getTimestamps("hourly").contains(timestamp)) { - return Long.MIN_VALUE; - } else { - String listName = dataSet.equals("onecall") ? "hourly" : "list"; - return extractLongFromJSON(getListEntry(listName, timestamp), "visibility", Long.MIN_VALUE); + throw new UnsupportedOperationException("This onecall datum is only available for hourly timestamps."); } + String listName = dataSet.equals("onecall") ? "hourly" : "list"; + return extractLongFromJSON(getListEntry(listName, timestamp), "visibility", Long.MIN_VALUE); } /** @@ -626,7 +625,7 @@ public class OpenWeatherConnector { } else if (dataSet.equals("onecall") && getTimestamps("hourly").contains(timestamp)) { return extractDoubleFromJSON(getListEntry("hourly", timestamp), "temp", Double.NaN); } else { - return Double.NaN; + throw new UnsupportedOperationException("This onecall datum is only available for hourly timestamps."); } } @@ -641,6 +640,9 @@ public class OpenWeatherConnector { */ public double getMorningTemperature(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "temp", "morn", Double.NaN); } @@ -655,6 +657,9 @@ public class OpenWeatherConnector { */ public double getDaytimeTemperature(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "temp", "day", Double.NaN); } @@ -669,6 +674,9 @@ public class OpenWeatherConnector { */ public double getEveningTemperature(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "temp", "eve", Double.NaN); } @@ -684,6 +692,9 @@ public class OpenWeatherConnector { */ public double getNighttimeTemperature(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "temp", "night", Double.NaN); } @@ -699,6 +710,9 @@ public class OpenWeatherConnector { */ public double getLowTemperature(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "temp", "min", Double.NaN); } @@ -714,6 +728,9 @@ public class OpenWeatherConnector { */ public double getHighTemperature(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "temp", "max", Double.NaN); } @@ -806,7 +823,7 @@ public class OpenWeatherConnector { } else if (dataSet.equals("onecall") && getTimestamps("hourly").contains(timestamp)) { return extractDoubleFromJSON(getListEntry("hourly", timestamp), "feels_like", Double.NaN); } else { - return Double.NaN; + throw new UnsupportedOperationException("This onecall datum is only available for hourly timestamps."); } } @@ -822,6 +839,9 @@ public class OpenWeatherConnector { */ public double getMorningFeelsLike(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "feels_like", "morn", Double.NaN); } @@ -837,6 +857,9 @@ public class OpenWeatherConnector { */ public double getDaytimeFeelsLike(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "feels_like", "day", Double.NaN); } @@ -852,6 +875,9 @@ public class OpenWeatherConnector { */ public double getEveningFeelsLike(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "feels_like", "eve", Double.NaN); } @@ -868,6 +894,9 @@ public class OpenWeatherConnector { */ public double getNighttimeFeelsLike(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("daily").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for daily timestamps."); + } return extractDoubleFromJSON(getListEntry("daily", timestamp), "feels_like", "night", Double.NaN); } @@ -1105,6 +1134,9 @@ public class OpenWeatherConnector { */ public double getOneHourRainfall(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("hourly").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for hourly timestamps."); + } return extractDoubleFromJSON(getListEntry("hourly", timestamp), "rain", "1h", 0.0); } @@ -1154,6 +1186,9 @@ public class OpenWeatherConnector { */ public double getOneHourSnowfall(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("hourly").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for hourly timestamps."); + } return extractDoubleFromJSON(getListEntry("hourly", timestamp), "snow", "1h", 0.0); } @@ -1192,6 +1227,9 @@ public class OpenWeatherConnector { */ public double getMinutelyPrecipitation(Date timestamp) { checkForDataReadiness(Set.of("onecall")); + if (!getTimestamps("minutely").contains(timestamp)) { + throw new UnsupportedOperationException("This onecall datum is only available for minutely timestamps."); + } return extractDoubleFromJSON(getListEntry("minutely", timestamp), "precipitation", 0.0); } diff --git a/src/test/java/edu/unl/cse/soft160/json_connections/ExceptionsTest.java b/src/test/java/edu/unl/cse/soft160/json_connections/ExceptionsTest.java index a095bf8d496eca43376bd5fd42abd63a2c7836c0..47195af130ba8026280fde25f22a865bce9f8840 100644 --- a/src/test/java/edu/unl/cse/soft160/json_connections/ExceptionsTest.java +++ b/src/test/java/edu/unl/cse/soft160/json_connections/ExceptionsTest.java @@ -7,8 +7,7 @@ import org.junit.Test; import java.io.IOException; import java.util.Date; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; public class ExceptionsTest { OpenWeatherConnector weather, forecast, airPollution, airPollutionHistory, airPollutionForecast, oneCall, dataLess; @@ -2194,4 +2193,233 @@ public class ExceptionsTest { } // pass } + + @Test + public void testOnlyMinutelyMethods() { + OpenWeatherConnector connector = oneCall; + Date timestamp = connector.getTimestamps("minutely").get(0); + String failMessage = "Expected UnsupportedOperationException"; + connector.getMinutelyPrecipitation(timestamp); + try { + connector.getVisibility(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getOneHourRainfall(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getOneHourSnowfall(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getMorningTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getDaytimeTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getEveningTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getNighttimeTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getLowTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getHighTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getMorningFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getDaytimeFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getEveningFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getNighttimeFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + } + + @Test + public void testOnlyHourlyMethods() { + OpenWeatherConnector connector = oneCall; + Date timestamp = connector.getTimestamps("hourly").get(0); + String failMessage = "Expected UnsupportedOperationException"; + try { + connector.getMinutelyPrecipitation(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for minutely timestamps.", exception.getMessage()); + } + connector.getVisibility(timestamp); + connector.getTemperature(timestamp); + connector.getFeelsLike(timestamp); + connector.getOneHourRainfall(timestamp); + connector.getOneHourSnowfall(timestamp); + try { + connector.getMorningTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getDaytimeTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getEveningTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getNighttimeTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getLowTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getHighTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getMorningFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getDaytimeFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getEveningFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + try { + connector.getNighttimeFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for daily timestamps.", exception.getMessage()); + } + } + + @Test + public void testOnlyDailyMethods() { + OpenWeatherConnector connector = oneCall; + Date timestamp = connector.getTimestamps("daily").get(0); + String failMessage = "Expected UnsupportedOperationException"; + try { + connector.getMinutelyPrecipitation(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for minutely timestamps.", exception.getMessage()); + } + try { + connector.getVisibility(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getTemperature(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getFeelsLike(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getOneHourRainfall(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + try { + connector.getOneHourSnowfall(timestamp); + fail(failMessage); + } catch (UnsupportedOperationException exception) { + assertEquals("This onecall datum is only available for hourly timestamps.", exception.getMessage()); + } + connector.getMorningTemperature(timestamp); + connector.getDaytimeTemperature(timestamp); + connector.getEveningTemperature(timestamp); + connector.getNighttimeTemperature(timestamp); + connector.getLowTemperature(timestamp); + connector.getHighTemperature(timestamp); + connector.getMorningFeelsLike(timestamp); + connector.getDaytimeFeelsLike(timestamp); + connector.getEveningFeelsLike(timestamp); + connector.getNighttimeFeelsLike(timestamp); + } } diff --git a/src/test/java/edu/unl/cse/soft160/json_connections/OneCall_WebsiteExampleTest.java b/src/test/java/edu/unl/cse/soft160/json_connections/OneCall_WebsiteExampleTest.java index b648d6e37b3cb5bc3582eeb5140f481d6d430ce3..81883c21a7a873ba488e0da0ff165583015a08d4 100644 --- a/src/test/java/edu/unl/cse/soft160/json_connections/OneCall_WebsiteExampleTest.java +++ b/src/test/java/edu/unl/cse/soft160/json_connections/OneCall_WebsiteExampleTest.java @@ -181,22 +181,13 @@ public class OneCall_WebsiteExampleTest { assertEquals(expectedDewPoint, actualDewPoint, 0.0001); assertEquals(expectedUVI, actualUVI, 0.0001); - expectedVisibility = Long.MIN_VALUE; - expectedAmbientTemperature = Double.NaN; expectedHumidity = 81; - expectedFeelsLikeTemperature = Double.NaN; expectedPressure = 1020; - actualVisibility = connector.getVisibility(daily); expectedDewPoint = 276.77; expectedUVI = 1.93; - actualAmbientTemperature = connector.getTemperature(daily); actualHumidity = connector.getHumidity(daily); - actualFeelsLikeTemperature = connector.getFeelsLike(daily); actualPressure = connector.getPressure(daily); - assertEquals(expectedVisibility, actualVisibility); - assertEquals(expectedAmbientTemperature, actualAmbientTemperature, 0.0001); assertEquals(expectedHumidity, actualHumidity); - assertEquals(expectedFeelsLikeTemperature, actualFeelsLikeTemperature, 0.0001); assertEquals(expectedPressure, actualPressure); actualDewPoint = connector.getDewPoint(daily); actualUVI = connector.getUltravioletIndex(daily);