diff --git a/docs/SNAPSHOT.md b/docs/SNAPSHOT.md index 63e2c60..7e330a9 100644 --- a/docs/SNAPSHOT.md +++ b/docs/SNAPSHOT.md @@ -352,22 +352,25 @@ You are able to set preferable options(via chain methods) and execute appropriat `com.github.prominence.openweathermap.api.model.onecall.current.Daily`'s useful public methods(setters are not listed): -| Method | Description | -|-----------------------------------------------|---------------------------------------------------------------------------------------------------| -| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. | -| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. | -| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. | -| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. | -| `getTemperature()` | Returns `DailyTemperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. | -| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. | -| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. | -| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. | -| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. | -| `getUvIndex()` | Returns UV index value. | -| `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). | -| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. | -| `getRain()` | Returns `DailyRain` object. Available fields: `value`. | -| `getSnow()` | Returns `DailySnow` object. Available fields: `value`. | +| Method | Description | +|---------------------------------------------|---------------------------------------------------------------------------------------------------| +| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. | +| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. | +| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. | +| `getMoonriseTime()` | Returns `LocalDateTime` object with moonrise time. | +| `getMoonsetTime()` | Returns `LocalDateTime` object with moonset time. | +| `getMoonPhase()` | Returns `MoonPhase` object with `MoonType` info and value. | +| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. | +| `getTemperature()` | Returns `DailyTemperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. | +| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. | +| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. | +| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. | +| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. | +| `getUvIndex()` | Returns UV index value. | +| `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). | +| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. | +| `getRain()` | Returns `DailyRain` object. Available fields: `value`. | +| `getSnow()` | Returns `DailySnow` object. Available fields: `value`. | `com.github.prominence.openweathermap.api.model.onecall.current.Alert`'s useful public methods(setters are not listed): @@ -475,54 +478,54 @@ final AirPollutionDetails airPollutionDetails = openWeatherClient ### Constants and options #### Language -| Constant | Description | -|-----------------------------------|-------------------------------| -| Language.AFRIKAANS | Afrikaans language. | -| Language.ALBANIAN | ALBANIAN language. | -| Language.ARABIC | Arabic language. | -| Language.AZERBAIJANI | Azerbaijani language. | -| Language.BULGARIAN | Bulgarian language. | -| Language.CATALAN | Catalan language. | -| Language.CZECH | Czech language. | -| Language.DANISH | Danish language. | -| Language.GERMAN | German language. | -| Language.GREEK | Greek language. | -| Language.ENGLISH | English language. | -| Language.BASQUE | Basque language. | -| Language.PERSIAN | Persian (Farsi) language. | -| Language.FINNISH | Finnish language. | -| Language.FRENCH | French language. | -| Language.GALICIAN | Galician language. | -| Language.HEBREW | Hebrew language. | -| Language.HINDI | Hindi language. | -| Language.CROATIAN | Croatian language. | -| Language.HUNGARIAN | Hungarian language. | -| Language.INDONESIAN | Indonesian language. | -| Language.ITALIAN | Italian language. | -| Language.JAPANESE | Japanese language. | -| Language.KOREAN | Korean language. | -| Language.LATVIAN | Latvian language. | -| Language.LITHUANIAN | Lithuanian language. | -| Language.MACEDONIAN | Macedonian language. | -| Language.NORWEGIAN | Norwegian language. | -| Language.DUTCH | Dutch language. | -| Language.POLISH | Polish language. | -| Language.PORTUGUESE | Portuguese language. | -| Language.PORTUGUES_BRAZIL | Português Brasil language. | -| Language.ROMANIAN | Romanian language. | -| Language.RUSSIAN | Russian language. | -| Language.SWEDISH | Swedish language. | -| Language.SLOVAK | Slovak language. | -| Language.SLOVENIAN | Slovenian language. | -| Language.SPANISH | Spanish language. | -| Language.SERBIAN | Serbian language. | -| Language.THAI | Thai language. | -| Language.TURKISH | Turkish language. | -| Language.UKRANIAN | Ukrainian language. | -| Language.VIETNAMESE | Vietnamese language. | -| Language.CHINESE_SIMPLIFIED | Chinese Simplified language. | -| Language.CHINESE_TRADITIONAL | Chinese Traditional language. | -| Language.ZULU | Zulu language. | +| Constant | Description | +|------------------------------|-------------------------------| +| Language.AFRIKAANS | Afrikaans language. | +| Language.ALBANIAN | ALBANIAN language. | +| Language.ARABIC | Arabic language. | +| Language.AZERBAIJANI | Azerbaijani language. | +| Language.BULGARIAN | Bulgarian language. | +| Language.CATALAN | Catalan language. | +| Language.CZECH | Czech language. | +| Language.DANISH | Danish language. | +| Language.GERMAN | German language. | +| Language.GREEK | Greek language. | +| Language.ENGLISH | English language. | +| Language.BASQUE | Basque language. | +| Language.PERSIAN | Persian (Farsi) language. | +| Language.FINNISH | Finnish language. | +| Language.FRENCH | French language. | +| Language.GALICIAN | Galician language. | +| Language.HEBREW | Hebrew language. | +| Language.HINDI | Hindi language. | +| Language.CROATIAN | Croatian language. | +| Language.HUNGARIAN | Hungarian language. | +| Language.INDONESIAN | Indonesian language. | +| Language.ITALIAN | Italian language. | +| Language.JAPANESE | Japanese language. | +| Language.KOREAN | Korean language. | +| Language.LATVIAN | Latvian language. | +| Language.LITHUANIAN | Lithuanian language. | +| Language.MACEDONIAN | Macedonian language. | +| Language.NORWEGIAN | Norwegian language. | +| Language.DUTCH | Dutch language. | +| Language.POLISH | Polish language. | +| Language.PORTUGUESE | Portuguese language. | +| Language.PORTUGUES_BRAZIL | Português Brasil language. | +| Language.ROMANIAN | Romanian language. | +| Language.RUSSIAN | Russian language. | +| Language.SWEDISH | Swedish language. | +| Language.SLOVAK | Slovak language. | +| Language.SLOVENIAN | Slovenian language. | +| Language.SPANISH | Spanish language. | +| Language.SERBIAN | Serbian language. | +| Language.THAI | Thai language. | +| Language.TURKISH | Turkish language. | +| Language.UKRAINIAN | Ukrainian language. | +| Language.VIETNAMESE | Vietnamese language. | +| Language.CHINESE_SIMPLIFIED | Chinese Simplified language. | +| Language.CHINESE_TRADITIONAL | Chinese Traditional language. | +| Language.ZULU | Zulu language. | #### Unit | Constant | Description | @@ -532,7 +535,7 @@ final AirPollutionDetails airPollutionDetails = openWeatherClient | Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow). | ### Dependencies -* com.fasterxml.jackson.core:jackson-databind:2.12.2 -* org.slf4j:slf4j-api:1.7.30 (*compile*) -* org.junit.jupiter:junit-jupiter-engine:5.7.1 (*test*) -* org.junit.platform:junit-platform-runner:1.7.1 (*test*) \ No newline at end of file +* com.fasterxml.jackson.core:jackson-databind:2.13.2.2 +* org.slf4j:slf4j-api:1.7.36 (*compile*) +* org.junit.jupiter:junit-jupiter-engine:5.8.2 (*test*) +* org.junit.platform:junit-platform-runner:1.8.2 (*test*) \ No newline at end of file diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java b/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java index 47a82ba..5a84c30 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java @@ -233,9 +233,9 @@ public enum Language { TURKISH("tr"), /** - * Ukranian language. + * Ukrainian language. */ - UKRANIAN("uk"), + UKRAINIAN("uk"), /** * Vietnamese language. diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/MoonType.java b/src/main/java/com/github/prominence/openweathermap/api/enums/MoonType.java new file mode 100644 index 0000000..7fdaa8a --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/MoonType.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Alexey Zinchenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.prominence.openweathermap.api.enums; + +public enum MoonType { + NEW_MOON, + WAXING_CRESCENT, + FIRST_QUARTER_MOON, + WAXING_GIBBOUS, + FULL_MOON, + WANING_GIBBOUS, + LAST_QUARTER_MOON, + WANING_CRESCENT, + INVALID; + + private static final double precision = 0.000001d; + + public static MoonType valueOf(double numericValue) { + if (equals(numericValue, 0) || equals(numericValue, 1)) { + return NEW_MOON; + } else if (equals(numericValue, 0.25)) { + return FIRST_QUARTER_MOON; + } else if (equals(numericValue, 0.5)) { + return FULL_MOON; + } else if (equals(numericValue, 0.75)) { + return LAST_QUARTER_MOON; + } else if (numericValue > 0 && numericValue < 0.25) { + return WAXING_CRESCENT; + } else if (numericValue > 0.25 && numericValue < 0.5) { + return WAXING_GIBBOUS; + } else if (numericValue > 0.5 && numericValue < 0.75) { + return WANING_GIBBOUS; + } else if (numericValue > 0.75 && numericValue < 1) { + return WANING_CRESCENT; + } + return INVALID; + } + + private static boolean equals(double d1, double d2) { + return Math.abs(d1 - d2) < precision; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java b/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java index d4bfaff..d3477b4 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java +++ b/src/main/java/com/github/prominence/openweathermap/api/mapper/OneCallWeatherResponseMapper.java @@ -200,6 +200,18 @@ public class OneCallWeatherResponseMapper { daily.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(dailyNode.get("dt").asInt()), TimeZone.getDefault().toZoneId())); daily.setSunriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(dailyNode.get("sunrise").asInt()), TimeZone.getDefault().toZoneId())); daily.setSunsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(dailyNode.get("sunset").asInt()), TimeZone.getDefault().toZoneId())); + final JsonNode moonriseTimeNode = dailyNode.get("moonrise"); + if (moonriseTimeNode != null) { + daily.setMoonriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(moonriseTimeNode.asInt()), TimeZone.getDefault().toZoneId())); + } + final JsonNode moonsetTimeNode = dailyNode.get("moonset"); + if (moonsetTimeNode != null) { + daily.setMoonsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(moonsetTimeNode.asInt()), TimeZone.getDefault().toZoneId())); + } + final JsonNode moonPhaseNode = dailyNode.get("moon_phase"); + if (moonPhaseNode != null) { + daily.setMoonPhase(new MoonPhase(moonPhaseNode.asDouble())); + } daily.setWeatherState(parseWeatherState(dailyNode.get("weather").get(0))); daily.setTemperature(parseDailyTemperature(dailyNode)); diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java b/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java index 4829ce3..e2f8b45 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/Daily.java @@ -39,6 +39,10 @@ public class Daily { private LocalDateTime sunriseTime; private LocalDateTime sunsetTime; + private LocalDateTime moonriseTime; + private LocalDateTime moonsetTime; + private MoonPhase moonPhase; + private WeatherState weatherState; private DailyTemperature temperature; private AtmosphericPressure atmosphericPressure; @@ -104,6 +108,60 @@ public class Daily { this.sunsetTime = sunsetTime; } + /** + * Gets moonrise time. + * + * @return the moonrise time + */ + public LocalDateTime getMoonriseTime() { + return moonriseTime; + } + + /** + * Sets moonrise time. + * + * @param moonriseTime the moonrise time + */ + public void setMoonriseTime(LocalDateTime moonriseTime) { + this.moonriseTime = moonriseTime; + } + + /** + * Gets moonset time. + * + * @return the moonset time + */ + public LocalDateTime getMoonsetTime() { + return moonsetTime; + } + + /** + * Sets moonset time. + * + * @param moonsetTime the moonset time + */ + public void setMoonsetTime(LocalDateTime moonsetTime) { + this.moonsetTime = moonsetTime; + } + + /** + * Gets moon phase. + * + * @return the moon phase + */ + public MoonPhase getMoonPhase() { + return moonPhase; + } + + /** + * Sets moon phase. + * + * @param moonPhase the moon phase + */ + public void setMoonPhase(MoonPhase moonPhase) { + this.moonPhase = moonPhase; + } + /** * Gets weather state. * @@ -311,6 +369,9 @@ public class Daily { return Objects.equals(forecastTime, daily.forecastTime) && Objects.equals(sunriseTime, daily.sunriseTime) && Objects.equals(sunsetTime, daily.sunsetTime) && + Objects.equals(moonriseTime, daily.moonriseTime) && + Objects.equals(moonsetTime, daily.moonsetTime) && + Objects.equals(moonPhase, daily.moonPhase) && Objects.equals(weatherState, daily.weatherState) && Objects.equals(temperature, daily.temperature) && Objects.equals(atmosphericPressure, daily.atmosphericPressure) && @@ -325,7 +386,7 @@ public class Daily { @Override public int hashCode() { - return Objects.hash(forecastTime, sunriseTime, sunsetTime, weatherState, temperature, atmosphericPressure, humidity, wind, clouds, uvIndex, probabilityOfPrecipitation, rain, snow); + return Objects.hash(forecastTime, sunriseTime, sunsetTime, moonriseTime, moonsetTime, moonPhase, weatherState, temperature, atmosphericPressure, humidity, wind, clouds, uvIndex, probabilityOfPrecipitation, rain, snow); } @Override @@ -355,7 +416,7 @@ public class Daily { } if (clouds != null) { stringBuilder.append(" Clouds: "); - stringBuilder.append(clouds.toString()); + stringBuilder.append(clouds); stringBuilder.append('.'); } if (rain != null) { diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/MoonPhase.java b/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/MoonPhase.java new file mode 100644 index 0000000..62a277f --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/onecall/current/MoonPhase.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Alexey Zinchenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.prominence.openweathermap.api.model.onecall.current; + +import com.github.prominence.openweathermap.api.enums.MoonType; + +import java.util.Objects; + +public class MoonPhase { + private final double value; + private final MoonType type; + + public MoonPhase(Double value) { + this.value = value; + this.type = MoonType.valueOf(value); + } + + public Double getValue() { + return value; + } + + public MoonType getType() { + return type; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MoonPhase moonPhase = (MoonPhase) o; + return Double.compare(moonPhase.value, value) == 0 && type == moonPhase.type; + } + + @Override + public int hashCode() { + return Objects.hash(value, type); + } + + @Override + public String toString() { + return type.name() + "(" + value + ")"; + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/onecall/current/MoonPhaseUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/onecall/current/MoonPhaseUnitTest.java new file mode 100644 index 0000000..e8b0644 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/onecall/current/MoonPhaseUnitTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022 Alexey Zinchenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.prominence.openweathermap.api.model.onecall.current; + +import com.github.prominence.openweathermap.api.enums.MoonType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class MoonPhaseUnitTest { + + @Test + public void getValue() { + final MoonPhase moonPhase = new MoonPhase(0.67); + + assertEquals(0.67, moonPhase.getValue(), 0.000001); + } + + @Test + public void getType() { + final MoonPhase newMoon1 = new MoonPhase(0d); + assertEquals(MoonType.NEW_MOON, newMoon1.getType()); + + final MoonPhase newMoon2 = new MoonPhase(1d); + assertEquals(MoonType.NEW_MOON, newMoon2.getType()); + + final MoonPhase firstQuarterMoon = new MoonPhase(0.25d); + assertEquals(MoonType.FIRST_QUARTER_MOON, firstQuarterMoon.getType()); + + final MoonPhase fullMoon = new MoonPhase(0.5d); + assertEquals(MoonType.FULL_MOON, fullMoon.getType()); + + final MoonPhase lastQuarterMoon = new MoonPhase(0.75d); + assertEquals(MoonType.LAST_QUARTER_MOON, lastQuarterMoon.getType()); + + final MoonPhase waxingCrescentMoon = new MoonPhase(0.1d); + assertEquals(MoonType.WAXING_CRESCENT, waxingCrescentMoon.getType()); + + final MoonPhase waxingGibbousMoon = new MoonPhase(0.4d); + assertEquals(MoonType.WAXING_GIBBOUS, waxingGibbousMoon.getType()); + + final MoonPhase waningGibbousMoon = new MoonPhase(0.623d); + assertEquals(MoonType.WANING_GIBBOUS, waningGibbousMoon.getType()); + + final MoonPhase waningCrescentMoon = new MoonPhase(0.9999d); + assertEquals(MoonType.WANING_CRESCENT, waningCrescentMoon.getType()); + } + + @Test + public void getEquals() { + final MoonPhase phase1 = new MoonPhase(0d); + final MoonPhase phase2 = new MoonPhase(0.5d); + + assertNotEquals(phase1, phase2); + + final MoonPhase phase3 = new MoonPhase(0d); + + assertEquals(phase1, phase3); + } + + @Test + public void getHashCode() { + final MoonPhase phase1 = new MoonPhase(0d); + final MoonPhase phase2 = new MoonPhase(0.5d); + + assertNotEquals(phase1.hashCode(), phase2.hashCode()); + + final MoonPhase phase3 = new MoonPhase(0d); + + assertEquals(phase1.hashCode(), phase3.hashCode()); + } + + @Test + public void getToString() { + final MoonPhase phase2 = new MoonPhase(0.5d); + + assertEquals("FULL_MOON(0.5)", phase2.toString()); + } +}