Use a single hour state for all weather services
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 29 May 2016 17:35:20 +0000 (19:35 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 29 May 2016 17:35:20 +0000 (19:35 +0200)
14 files changed:
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/HourState.kt [new file with mode: 0644]
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/HourState.kt [deleted file]
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/WetterComFilter.kt
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/WetterComState.kt
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/HourState.kt [deleted file]
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/WetterDeFilter.kt
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/WetterDeState.kt
src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/WetterDeTrigger.kt
src/test/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/WetterComFilterTest.kt
src/test/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/WetterComStateTest.kt
src/test/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/WetterComTriggerTest.kt
src/test/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/WetterDeFilterTest.kt
src/test/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/WetterDeStateTest.kt
src/test/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/WetterDeTriggerTest.kt

diff --git a/src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/HourState.kt b/src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/HourState.kt
new file mode 100644 (file)
index 0000000..1a14783
--- /dev/null
@@ -0,0 +1,22 @@
+package net.pterodactylus.rhynodge.webpages.weather
+
+import com.fasterxml.jackson.annotation.JsonProperty
+import net.pterodactylus.rhynodge.webpages.weather.WindDirection
+
+/**
+ * Container for weather conditions of a single hour.
+ *
+ * @author [David ‘Bombe’ Roden](mailto:bombe@pterodactylus.net)
+ */
+data class HourState(
+        @JsonProperty("hourIndex") val hourIndex: Int,
+        @JsonProperty("temperature") val temperature: Int,
+        @JsonProperty("feltTemperature") val feltTemperature: Int? = null,
+        @JsonProperty("rainProbability") val rainProbability: Double,
+        @JsonProperty("rainAmount") val rainAmount: Double,
+        @JsonProperty("windDirection") val windDirection: WindDirection,
+        @JsonProperty("windSpeed") val windSpeed: Int,
+        @JsonProperty("gustSpeed") val gustSpeed: Int? = null,
+        @JsonProperty("humidity") val humidity: Double? = null,
+        @JsonProperty("description") val description: String,
+        @JsonProperty("image") val image: String)
diff --git a/src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/HourState.kt b/src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wettercom/HourState.kt
deleted file mode 100644 (file)
index cd21a92..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-package net.pterodactylus.rhynodge.webpages.weather.wettercom
-
-import com.fasterxml.jackson.annotation.JsonProperty
-import net.pterodactylus.rhynodge.webpages.weather.WindDirection
-
-/**
- * Container for weather conditions of a single hour.
- *
- * @author [David ‘Bombe’ Roden](mailto:bombe@pterodactylus.net)
- */
-data class HourState(
-        @JsonProperty("hourIndex") val hourIndex: Int,
-        @JsonProperty("temperature") val temperature: Double,
-        @JsonProperty("rainProbability") val rainProbability: Double,
-        @JsonProperty("rainAmount") val rainAmount: Double,
-        @JsonProperty("windDirection") val windDirection: WindDirection,
-        @JsonProperty("windSpeed") val windSpeed: Double,
-        @JsonProperty("description") val description: String,
-        @JsonProperty("image") val image: String) {
-
-    class Builder(private val hourIndex: Int) {
-
-        fun temperature(temperature: Double) = _1(temperature)
-
-        inner class _1(private val temperature: Double) {
-
-            fun rainProbability(rainProbability: Double) = _2(rainProbability)
-
-            inner class _2(private val rainProbability: Double) {
-
-                fun rainAmount(rainAmount: Double) = _3(rainAmount)
-
-                inner class _3(private val rainAmount: Double) {
-
-                    fun windFrom(windDirection: WindDirection) = _4(windDirection);
-
-                    inner class _4(private val windDirection: WindDirection) {
-
-                        fun at(windSpeed: Double) = _5(windSpeed)
-
-                        inner class _5(private val windSpeed: Double) {
-
-                            fun describedAs(description: String) = _6(description)
-
-                            inner class _6(private val description: String) {
-
-                                fun withImage(imageUrl: String) = _7(imageUrl)
-
-                                inner class _7(private val imageUrl: String) {
-
-                                    fun build(): HourState {
-                                        return HourState(hourIndex, temperature, rainProbability, rainAmount, windDirection, windSpeed, description, imageUrl)
-                                    }
-
-                                }
-
-                            }
-
-                        }
-
-                    }
-
-                }
-
-            }
-
-        }
-
-    }
-
-    companion object {
-
-        fun atHour(hourIndex: Int) = Builder(hourIndex)
-
-    }
-
-}
index dc33b65..d6e1a08 100644 (file)
@@ -4,6 +4,8 @@ import net.pterodactylus.rhynodge.Filter
 import net.pterodactylus.rhynodge.State
 import net.pterodactylus.rhynodge.states.FailedState
 import net.pterodactylus.rhynodge.states.HtmlState
+import net.pterodactylus.rhynodge.webpages.weather.HourState
+import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import net.pterodactylus.rhynodge.webpages.weather.toWindDirection
 import org.jsoup.nodes.Document
 import org.jsoup.nodes.Element
@@ -35,7 +37,7 @@ class WetterComFilter : Filter {
     private fun parseWetterComState(state: HtmlState): State {
         val dateTime = parseDateTime(state.document()) ?: return FailedState(IllegalArgumentException("no date present"))
         val wetterComState = WetterComState(dateTime)
-        parseHourStates(state.document()).forEach { wetterComState.addHour(it) }
+        parseHourStates(state.document()).forEach { wetterComState += it }
         return wetterComState
     }
 
@@ -52,37 +54,38 @@ class WetterComFilter : Filter {
     }
 
     private fun parseHourState(index: Int, hourElement: Element): HourState {
-        return HourState.atHour(index)
-                .temperature(parseTemperature(hourElement))
-                .rainProbability(parseRainProbability(hourElement))
-                .rainAmount(parseRainAmount(hourElement))
-                .windFrom(parseWindDirection(hourElement))
-                .at(parseWindSpeed(hourElement))
-                .describedAs(parseDescription(hourElement))
-                .withImage(parseImageUrl(hourElement))
-                .build()
+        return HourState(
+                hourIndex = index,
+                temperature = hourElement.temperature,
+                rainProbability = hourElement.rainProbability,
+                rainAmount = hourElement.rainAmount,
+                windDirection = hourElement.windDirection,
+                windSpeed = hourElement.windSpeed,
+                description = hourElement.description,
+                image = hourElement.imageUrl
+        )
     }
 
-    private fun parseTemperature(hourElement: Element) =
-            hourElement.extractText(".weather-strip__2 .item-weathericon .palm-hide").filter { (it >= '0') and (it <= '9') }.toDouble()
+    private val Element.temperature: Int
+        get() = extractText(".weather-strip__2 .item-weathericon .palm-hide").filter { (it >= '0') and (it <= '9') }.toInt()
 
-    private fun parseRainProbability(hourElement: Element) =
-            hourElement.extractText(".weather-strip__3 .text--left:eq(0) .flag__body span:eq(0)").filter { (it >= '0') and (it <= '9') }.toDouble() / 100.0
+    private val Element.rainProbability: Double
+        get() = extractText(".weather-strip__3 .text--left:eq(0) .flag__body span:eq(0)").filter { (it >= '0') and (it <= '9') }.toDouble() / 100.0
 
-    private fun parseRainAmount(hourElement: Element) =
-            hourElement.extractText(".weather-strip__3 .text--left:eq(0) .flag__body span:eq(1)").trim().split(" ").getOrNull(1)?.toDouble() ?: 0.0
+    private val Element.rainAmount: Double
+        get() = extractText(".weather-strip__3 .text--left:eq(0) .flag__body span:eq(1)").trim().split(" ").getOrNull(1)?.toDouble() ?: 0.0
 
-    private fun parseWindDirection(hourElement: Element) =
-            hourElement.extractText(".weather-strip__3 .text--left:eq(1) .flag__body span:eq(0)").trim().split(",")[0].toWindDirection()
+    private val Element.windDirection: WindDirection
+        get() = extractText(".weather-strip__3 .text--left:eq(1) .flag__body span:eq(0)").trim().split(",")[0].toWindDirection()
 
-    private fun parseWindSpeed(hourElement: Element) =
-            hourElement.extractText(".weather-strip__3 .text--left:eq(1) .flag__body span:eq(0)").split(Regex("[, ]+"))[1].toDouble()
+    private val Element.windSpeed: Int
+        get() = extractText(".weather-strip__3 .text--left:eq(1) .flag__body span:eq(0)").split(Regex("[, ]+"))[1].toInt()
 
-    private fun parseDescription(hourElement: Element) =
-            hourElement.extractText(".weather-strip__1 .vhs-text--small")
+    private val Element.description: String
+        get() = extractText(".weather-strip__1 .vhs-text--small")
 
-    private fun parseImageUrl(hourElement: Element) =
-            hourElement.select(".weather-strip__2 img").firstOrNull()?.attr("src") ?: ""
+    private val Element.imageUrl: String
+        get() = select(".weather-strip__2 img").firstOrNull()?.attr("src") ?: ""
 
     private fun Element.extractText(selector: String) = select(selector).firstOrNull()?.text() ?: ""
 
index be18847..e6c2b5e 100644 (file)
@@ -3,6 +3,7 @@ package net.pterodactylus.rhynodge.webpages.weather.wettercom
 import com.fasterxml.jackson.annotation.JsonGetter
 import com.fasterxml.jackson.annotation.JsonProperty
 import net.pterodactylus.rhynodge.states.AbstractState
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import java.time.Instant
 import java.time.ZoneId
 import java.time.ZonedDateTime
@@ -24,7 +25,7 @@ class WetterComState(val dateTime: ZonedDateTime) : AbstractState(true), Iterabl
         @JsonGetter("dateTime")
         get() = dateTime.toInstant().toEpochMilli()
 
-    fun addHour(hourState: HourState) {
+    operator fun plusAssign(hourState: HourState) {
         (hours as MutableList<HourState>).add(hourState)
     }
 
diff --git a/src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/HourState.kt b/src/main/kotlin/net/pterodactylus/rhynodge/webpages/weather/wetterde/HourState.kt
deleted file mode 100644 (file)
index f8e7dc6..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.pterodactylus.rhynodge.webpages.weather.wetterde
-
-import com.fasterxml.jackson.annotation.JsonProperty
-import net.pterodactylus.rhynodge.webpages.weather.WindDirection
-
-/**
- * Container for weather conditions of a single hour.
- *
- * @author [David ‘Bombe’ Roden](mailto:bombe@pterodactylus.net)
- */
-data class HourState(
-        @JsonProperty("hourIndex") val hourIndex: Int,
-        @JsonProperty("temperature") val temperature: Int,
-        @JsonProperty("feltTemperature") val feltTemperature: Int,
-        @JsonProperty("rainProbability") val rainProbability: Double,
-        @JsonProperty("rainAmount") val rainAmount: Double,
-        @JsonProperty("windDirection") val windDirection: WindDirection,
-        @JsonProperty("windSpeed") val windSpeed: Int,
-        @JsonProperty("gustSpeed") val gustSpeed: Int,
-        @JsonProperty("humidity") val humidity: Double,
-        @JsonProperty("description") val description: String,
-        @JsonProperty("image") val image: String) {
-
-}
index 4e7010e..245a8a4 100644 (file)
@@ -4,6 +4,7 @@ import net.pterodactylus.rhynodge.Filter
 import net.pterodactylus.rhynodge.State
 import net.pterodactylus.rhynodge.states.FailedState
 import net.pterodactylus.rhynodge.states.HtmlState
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import net.pterodactylus.rhynodge.webpages.weather.toWindDirection
 import org.jsoup.nodes.Document
index 2651ed5..74b7ef0 100644 (file)
@@ -2,6 +2,7 @@ package net.pterodactylus.rhynodge.webpages.weather.wetterde
 
 import com.fasterxml.jackson.annotation.JsonProperty
 import net.pterodactylus.rhynodge.states.AbstractState
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import java.time.Instant
 import java.time.ZoneId.of
 import java.time.ZonedDateTime
index 39ec116..178fce4 100644 (file)
@@ -62,13 +62,19 @@ class WetterDeTrigger : Trigger {
                     div("hour-state") {
                         div("time") { +"%tH:%<tM".format(startTime.plus(it.hourIndex.toLong(), ChronoUnit.HOURS).toEpochMilli()) }
                         div("temperature") { +"%d °C".format(it.temperature) }
-                        div("felt-temperature") { +"(%d °C)".format(it.feltTemperature) }
+                        it.feltTemperature?.let {
+                            div("felt-temperature") { +"(%d °C)".format(it) }
+                        }
                         div("rain-probability") { +"%d%%".format((it.rainProbability * 100).toInt()) }
                         div("rain-amount") { +"%s l/m²".format(it.rainAmount.minDigits()) }
                         div("wind-direction") { +it.windDirection.arrow }
                         div("wind-speed") { +"%d km/h".format(it.windSpeed) }
-                        div("gust-speed") { +"(up to %d km/h)".format(it.gustSpeed) }
-                        div("humidity") { +"%d%%".format((it.humidity * 100).toInt()) }
+                        it.gustSpeed?.let {
+                            div("gust-speed") { +"(up to %d km/h)".format(it) }
+                        }
+                        it.humidity?.let {
+                            div("humidity") { +"%d%%".format((it * 100).toInt()) }
+                        }
                         div("description") { +it.description }
                         div("image") { img(src = it.image) }
                     }
index 75b471a..8f28c0b 100644 (file)
@@ -4,6 +4,7 @@ import net.pterodactylus.rhynodge.State
 import net.pterodactylus.rhynodge.filters.ResourceLoader.loadDocument
 import net.pterodactylus.rhynodge.states.FailedState
 import net.pterodactylus.rhynodge.states.HtmlState
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.`is`
@@ -53,30 +54,30 @@ class WetterComFilterTest {
         val newState = filter.filter(htmlState) as WetterComState
         assertThat(newState.dateTime, `is`(LocalDateTime.of(2016, Month.MAY, 23, 5, 0).atZone(ZoneId.of("Europe/Berlin"))))
         assertThat(newState.hours, contains(
-                HourState(0, 15.0, 0.65, 0.8, WindDirection.NORTH, 5.0, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
-                HourState(1, 15.0, 0.7, 0.9, WindDirection.NONE, 5.0, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
-                HourState(2, 17.0, 0.75, 1.0, WindDirection.NORTHWEST, 5.0, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
-                HourState(3, 17.0, 0.85, 0.3, WindDirection.NORTHWEST, 5.0, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
-                HourState(4, 19.0, 0.9, 0.3, WindDirection.SOUTHWEST, 5.0, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
-                HourState(5, 20.0, 0.85, 0.3, WindDirection.SOUTHWEST, 7.0, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
-                HourState(6, 20.0, 0.75, 0.3, WindDirection.SOUTHWEST, 11.0, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
-                HourState(7, 20.0, 0.70, 0.3, WindDirection.WEST, 11.0, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
-                HourState(8, 20.0, 0.70, 0.2, WindDirection.WEST, 9.0, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
-                HourState(9, 20.0, 0.70, 0.4, WindDirection.WEST, 5.0, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
-                HourState(10, 20.0, 0.70, 0.4, WindDirection.WEST, 7.0, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
-                HourState(11, 19.0, 0.70, 0.4, WindDirection.WEST, 11.0, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
-                HourState(12, 18.0, 0.70, 0.4, WindDirection.NORTHWEST, 12.0, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
-                HourState(13, 17.0, 0.70, 0.4, WindDirection.NORTHWEST, 11.0, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
-                HourState(14, 16.0, 0.75, 0.4, WindDirection.NORTHWEST, 12.0, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
-                HourState(15, 15.0, 0.85, 0.2, WindDirection.WEST, 12.0, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
-                HourState(16, 14.0, 0.9, 0.2, WindDirection.WEST, 14.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
-                HourState(17, 14.0, 0.9, 0.0, WindDirection.NORTHWEST, 12.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
-                HourState(18, 14.0, 0.9, 0.2, WindDirection.WEST, 12.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
-                HourState(19, 13.0, 0.85, 0.1, WindDirection.NORTHWEST, 11.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
-                HourState(20, 13.0, 0.8, 0.01, WindDirection.WEST, 11.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
-                HourState(21, 12.0, 0.75, 0.2, WindDirection.WEST, 12.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
-                HourState(22, 12.0, 0.75, 0.2, WindDirection.NORTHWEST, 12.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
-                HourState(23, 11.0, 0.75, 0.2, WindDirection.NORTHWEST, 12.0, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518")
+                HourState(0, 15, null, 0.65, 0.8, WindDirection.NORTH, 5, null, null, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
+                HourState(1, 15, null, 0.7, 0.9, WindDirection.NONE, 5, null, null, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
+                HourState(2, 17, null, 0.75, 1.0, WindDirection.NORTHWEST, 5, null, null, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
+                HourState(3, 17, null, 0.85, 0.3, WindDirection.NORTHWEST, 5, null, null, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
+                HourState(4, 19, null, 0.9, 0.3, WindDirection.SOUTHWEST, 5, null, null, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
+                HourState(5, 20, null, 0.85, 0.3, WindDirection.SOUTHWEST, 7, null, null, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
+                HourState(6, 20, null, 0.75, 0.3, WindDirection.SOUTHWEST, 11, null, null, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
+                HourState(7, 20, null, 0.70, 0.3, WindDirection.WEST, 11, null, null, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
+                HourState(8, 20, null, 0.70, 0.2, WindDirection.WEST, 9, null, null, "leichter Regen-schauer", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_80_S.png?201605201518"),
+                HourState(9, 20, null, 0.70, 0.4, WindDirection.WEST, 5, null, null, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
+                HourState(10, 20, null, 0.70, 0.4, WindDirection.WEST, 7, null, null, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
+                HourState(11, 19, null, 0.70, 0.4, WindDirection.WEST, 11, null, null, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
+                HourState(12, 18, null, 0.70, 0.4, WindDirection.NORTHWEST, 12, null, null, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
+                HourState(13, 17, null, 0.70, 0.4, WindDirection.NORTHWEST, 11, null, null, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
+                HourState(14, 16, null, 0.75, 0.4, WindDirection.NORTHWEST, 12, null, null, "Regenschauer", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/d_81_S.png?201605201518"),
+                HourState(15, 15, null, 0.85, 0.2, WindDirection.WEST, 12, null, null, "leichter Regen", "http://ls1.wettercomassets.com/wcomv5/images/icons/small/d_61_S.png?201605201518"),
+                HourState(16, 14, null, 0.9, 0.2, WindDirection.WEST, 14, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
+                HourState(17, 14, null, 0.9, 0.0, WindDirection.NORTHWEST, 12, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
+                HourState(18, 14, null, 0.9, 0.2, WindDirection.WEST, 12, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
+                HourState(19, 13, null, 0.85, 0.1, WindDirection.NORTHWEST, 11, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
+                HourState(20, 13, null, 0.8, 0.01, WindDirection.WEST, 11, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
+                HourState(21, 12, null, 0.75, 0.2, WindDirection.WEST, 12, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
+                HourState(22, 12, null, 0.75, 0.2, WindDirection.NORTHWEST, 12, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518"),
+                HourState(23, 11, null, 0.75, 0.2, WindDirection.NORTHWEST, 12, null, null, "leichter Regen", "http://ls2.wettercomassets.com/wcomv5/images/icons/small/n_61_S.png?201605201518")
         ))
     }
 
index 93667ea..d32e563 100644 (file)
@@ -1,6 +1,7 @@
 package net.pterodactylus.rhynodge.webpages.weather.wettercom
 
 import com.fasterxml.jackson.databind.ObjectMapper
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.`is`
@@ -28,11 +29,11 @@ class WetterComStateTest {
     fun statesWithTheSameHoursAreEqual() {
         val now = Instant.now().atZone(ZoneId.of("Europe/Berlin"))
         val firstState = WetterComState(ZonedDateTime.from(now))
-        firstState.addHour(HourState(0, 10.0, 0.05, 0.0, WindDirection.NORTH, 5.0, "Fine", "http://1"))
-        firstState.addHour(HourState(1, 12.0, 0.1, 2.0, WindDirection.WEST, 8.0, "Superb", "http://2"))
+        firstState += HourState(0, 10, null, 0.05, 0.0, WindDirection.NORTH, 5, null, null, "Fine", "http://1")
+        firstState += HourState(1, 12, null, 0.1, 2.0, WindDirection.WEST, 8, null, null, "Superb", "http://2")
         val secondState = WetterComState(ZonedDateTime.from(now))
-        secondState.addHour(HourState(0, 10.0, 0.05, 0.0, WindDirection.NORTH, 5.0, "Fine", "http://1"))
-        secondState.addHour(HourState(1, 12.0, 0.1, 2.0, WindDirection.WEST, 8.0, "Superb", "http://2"))
+        secondState += HourState(0, 10, null, 0.05, 0.0, WindDirection.NORTH, 5, null, null, "Fine", "http://1")
+        secondState += HourState(1, 12, null, 0.1, 2.0, WindDirection.WEST, 8, null, null, "Superb", "http://2")
         assertThat(firstState, `is`(secondState))
     }
 
@@ -40,8 +41,8 @@ class WetterComStateTest {
     fun iteratingDeliversHourStates() {
         val now = Instant.now().atZone(ZoneId.of("Europe/Berlin"))
         val firstState = WetterComState(ZonedDateTime.from(now))
-        firstState.addHour(HourState(0, 10.0, 0.05, 0.0, WindDirection.NORTH, 5.0, "Fine", "http://1"))
-        firstState.addHour(HourState(1, 12.0, 0.1, 2.0, WindDirection.WEST, 8.0, "Superb", "http://2"))
+        firstState += HourState(0, 10, null, 0.05, 0.0, WindDirection.NORTH, 5, null, null, "Fine", "http://1")
+        firstState += HourState(1, 12, null, 0.1, 2.0, WindDirection.WEST, 8, null, null, "Superb", "http://2")
         assertThat(firstState.iterator().asSequence().toList(), `is`(firstState.hours as Iterable<HourState>))
     }
 
@@ -50,8 +51,8 @@ class WetterComStateTest {
         val objectMapper = ObjectMapper()
         val now = Instant.now().atZone(ZoneId.of("Europe/Berlin"))
         val originalState = WetterComState(ZonedDateTime.from(now))
-        originalState.addHour(HourState(0, 10.0, 0.05, 0.0, WindDirection.NORTH, 5.0, "Fine", "http://1"))
-        originalState.addHour(HourState(1, 12.0, 0.1, 2.0, WindDirection.WEST, 8.0, "Superb", "http://2"))
+        originalState += HourState(0, 10, null, 0.05, 0.0, WindDirection.NORTH, 5, null, null, "Fine", "http://1")
+        originalState += HourState(1, 12, null, 0.1, 2.0, WindDirection.WEST, 8, null, null, "Superb", "http://2")
         val json = objectMapper.writeValueAsString(originalState)
         println(json)
         val parsedState = objectMapper.readValue(json, WetterComState::class.java)
index 5cc3f06..aa69a07 100644 (file)
@@ -1,6 +1,7 @@
 package net.pterodactylus.rhynodge.webpages.weather.wettercom
 
 import net.pterodactylus.rhynodge.Reaction
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.`is`
@@ -62,8 +63,8 @@ class WetterComTriggerTest {
     @Test
     fun outputHtmlContainsHourStates() {
         val currentState = WetterComState(now.minusDays(1))
-        currentState.addHour(HourState(0, 10.0, 0.11, 12.0, WindDirection.NORTH, 13.0, "Rain", "http://1"))
-        currentState.addHour(HourState(1, 14.0, 0.15, 16.0, WindDirection.SOUTH, 17.0, "Sun", "http://2"))
+        currentState += HourState(0, 10, null, 0.11, 12.0, WindDirection.NORTH, 13, null, null, "Rain", "http://1")
+        currentState += HourState(1, 14, null, 0.15, 16.0, WindDirection.SOUTH, 17, null, null, "Sun", "http://2")
         trigger.mergeStates(previousState, currentState) as WetterComState
         val reaction = Mockito.mock(Reaction::class.java)
         val output = trigger.output(reaction)
index 3e7a25a..fc435c2 100644 (file)
@@ -4,6 +4,7 @@ import net.pterodactylus.rhynodge.filters.ResourceLoader
 import net.pterodactylus.rhynodge.states.AbstractState
 import net.pterodactylus.rhynodge.states.FailedState
 import net.pterodactylus.rhynodge.states.HtmlState
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.`is`
index b3de810..aa21c0c 100644 (file)
@@ -1,6 +1,7 @@
 package net.pterodactylus.rhynodge.webpages.weather.wetterde
 
 import com.fasterxml.jackson.databind.ObjectMapper
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.`is`
index ba5bf46..1dac1ab 100644 (file)
@@ -2,6 +2,7 @@ package net.pterodactylus.rhynodge.webpages.weather.wetterde
 
 import net.pterodactylus.rhynodge.Reaction
 import net.pterodactylus.rhynodge.State
+import net.pterodactylus.rhynodge.webpages.weather.HourState
 import net.pterodactylus.rhynodge.webpages.weather.WindDirection
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.`is`