def test_from_dict_of_lists_when_no_results(self): result = Weather.from_dict_of_lists(json.loads(CITY_WEATHER_HISTORY_NO_RESULTS_JSON)) self.assertTrue(isinstance(result, list)) self.assertEqual(0, len(result)) result = Weather.from_dict_of_lists(json.loads(self.__no_items_json)) self.assertTrue(isinstance(result, list)) self.assertEqual(0, len(result))
def test_one_call_hourly_from_dic(self): hourly1 = { "dt": 1587675600, "temp": 294.16, "feels_like": 292.47, "pressure": 1009, "humidity": 88, "dew_point": 292.1, "clouds": 90, "wind_speed": 7, "wind_deg": 189, "weather": [ { "id": 501, "main": "Rain", "description": "moderate rain", "icon": "10d" } ], "rain": { "1h": 2.28 } } result1 = Weather.from_dict(hourly1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(292.47, result1.temperature()["feels_like"]) self.assertEqual(501, result1.weather_code) self.assertEqual(2.28, result1.rain["1h"]) self.assertEqual(294.16, result1.temperature()["temp"]) self.assertEqual(292.47, result1.temperature()["feels_like"]) hourly2 = { "dt": 1587682800, "temp": 279.64, "feels_like": 276.77, "pressure": 1020, "humidity": 54, "dew_point": 271.26, "clouds": 3, "wind_speed": 0.84, "wind_deg": 119, "weather": [ { "id": 800, "main": "Clear", "description": "clear sky", "icon": "01n" } ] } result2 = Weather.from_dict(hourly2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(3, result2.clouds) self.assertEqual(800, result2.weather_code) self.assertEqual(119, result2.wind()["deg"]) self.assertEqual(0, len(result2.rain)) self.assertEqual(279.64, result2.temperature()["temp"]) self.assertEqual(276.77, result2.temperature()["feels_like"])
def get_wind(w: Weather) -> str: wind = w.wind("meters_sec") wind_k = w.wind("knots") speed_kts = round(wind_k["speed"], 1) speed_m_s = round(wind["speed"], 1) degrees = None if 'deg' in wind: degrees = wind["deg"] if speed_kts < 1: description = 'Calm' elif speed_kts < 4: description = 'Light air' elif speed_kts < 7: description = 'Light breeze' elif speed_kts < 11: description = 'Gentle breeze' elif speed_kts < 16: description = 'Moderate breeze' elif speed_kts < 22: description = 'Fresh breeze' elif speed_kts < 28: description = 'Strong breeze' elif speed_kts < 34: description = 'Near gale' elif speed_kts < 41: description = 'Gale' elif speed_kts < 48: description = 'Strong gale' elif speed_kts < 56: description = 'Storm' elif speed_kts < 64: description = 'Violent storm' else: description = 'Hurricane' if degrees is not None: if (degrees <= 22.5) or (degrees > 337.5): degrees = u'\u2193' elif (degrees > 22.5) and (degrees <= 67.5): degrees = u'\u2199' elif (degrees > 67.5) and (degrees <= 112.5): degrees = u'\u2190' elif (degrees > 112.5) and (degrees <= 157.5): degrees = u'\u2196' elif (degrees > 157.5) and (degrees <= 202.5): degrees = u'\u2191' elif (degrees > 202.5) and (degrees <= 247.5): degrees = u'\u2197' elif (degrees > 247.5) and (degrees <= 292.5): degrees = u'\u2192' elif (degrees > 292.5) and (degrees <= 337.5): degrees = u'\u2198' else: degrees = 'Unknown direction' return "{} {}m/s ({})".format(description, speed_m_s, degrees)
def from_dict(cls, the_dict: dict): """ Parses a *OneCall* instance out of a data dictionary. Only certain properties of the data dictionary are used: if these properties are not found or cannot be parsed, an exception is issued. :param the_dict: the input dictionary :type the_dict: `dict` :returns: a *OneCall* instance or ``None`` if no data is available :raises: *ParseAPIResponseError* if it is impossible to find or parse the data needed to build the result, *APIResponseError* if the input dict embeds an HTTP status error """ if the_dict is None: raise exceptions.ParseAPIResponseError('Data is None') # Check if server returned errors: this check overcomes the lack of use # of HTTP error status codes by the OWM API 2.5. This mechanism is # supposed to be deprecated as soon as the API fully adopts HTTP for # conveying errors to the clients if 'message' in the_dict and 'cod' in the_dict: if the_dict['cod'] == "404": return None elif the_dict['cod'] == "429": raise exceptions.APIResponseError( "OWM API: error - Exceeded call limit", the_dict['cod']) else: raise exceptions.APIResponseError( "OWM API: error - response payload", the_dict['cod']) try: current = Weather.from_dict(the_dict["current"]) minutely = None if "minutely" in the_dict: minutely = [ Weather.from_dict(item) for item in the_dict["minutely"] ] hourly = None if "hourly" in the_dict: hourly = [ Weather.from_dict(item) for item in the_dict["hourly"] ] daily = None if "daily" in the_dict: daily = [Weather.from_dict(item) for item in the_dict["daily"]] except KeyError: raise exceptions.ParseAPIResponseError( f"{__name__}: impossible to read weather info from input data") return OneCall(lat=the_dict.get("lat", None), lon=the_dict.get("lon", None), timezone=the_dict.get("timezone", None), current=current, forecast_minutely=minutely, forecast_hourly=hourly, forecast_daily=daily)
def _parse_weather( self, weather: Weather) -> Tuple[int, float, float, float, float]: temperature = weather.get_temperature(unit=self.temperature_unit) humidity = weather.get_humidity() weather_code = weather.get_weather_code() return (weather_code, temperature.get('temp_min', temperature.get('min')), temperature.get('temp_max', temperature.get('max')), temperature.get('temp'), humidity)
def test_init_stores_negative_sunrise_time_as_none(self): instance = Weather( self.__test_reference_time, self.__test_sunset_time, -9876543210, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.sunrise_time())
def test_init_when_wind_is_none(self): instance = Weather( self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, None, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.wind())
def test_init_stores_negative_sunrise_time_as_none(self): instance = Weather(self.__test_reference_time, self.__test_sunset_time, -9876543210, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.get_sunrise_time())
def current_str(wt: Weather): wstr = "%s%s(%s)" % (weather_status[wt.weather_code][0], weather_status[wt.weather_code][2], weather_status[wt.weather_code][1]) wstr += "\n温度(temp)%s°C\n体感温度(feels like)%s°C\n湿度(humidity)%s%%" % ( wt.temperature('celsius')['temp'], wt.temperature('celsius')['feels_like'], wt.humidity) wstr += "\n能见度(visibility)%skm 💨%sm/s" % (wt.visibility_distance / 1000, wt.wind()['speed']) wstr += "\n🌅%s 🌇%s" % (get_local_time( wt.sunrise_time()), get_local_time(wt.sunset_time())) return wstr
def test_from_dict_of_lists(self): result = Weather.from_dict_of_lists( json.loads(CITY_WEATHER_HISTORY_JSON)) self.assertTrue(result) self.assertTrue(isinstance(result, list)) for weather in result: self.assertTrue(weather is not None)
def raw_weather_report(weather: Weather, location: str, unit_system: str) -> dict: """ Build a raw weather report feed dictionary. This method is useful for storing persistent data because the values contain no ANSI escape sequences or units. """ temperature = weather.temperature(_temperature_units[unit_system.upper()]) return { 'DateTime': weather.ref_time, 'Location': location, 'Temperature (Min)': temperature['temp_min'], 'Temperature (Now)': temperature['temp'], 'Temperature (Max)': temperature['temp_max'], 'Wind Speed': weather.wind(_speed_units[unit_system.upper()])['speed'], 'Humidity': weather.humidity, 'Cloud Coverage': weather.clouds }
def test_actualize(self): weathers = [ Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, { "deg": 252.002, "speed": 1.100 }, 57, { "press": 1030.119, "sea_level": 1038.589 }, { "temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0), # will this time ever be reached? Weather(9999999999, 1378496480, 1378449510, 23, {"all": 10}, {"all": 0}, { "deg": 103.4, "speed": 4.2 }, 12, { "press": 1070.119, "sea_level": 1078.589 }, { "temp": 297.199, "temp_kf": -1.899, "temp_max": 299.0, "temp_min": 295.6 }, "Clear", "Sky is clear", 804, "02d", 1000, 300.0, 298.0, 296.0) ] f = Forecast("daily", self.__test_reception_time, self.__test_location, weathers) self.assertEqual(2, len(f)) f.actualize() self.assertEqual(1, len(f))
class TestObservation(unittest.TestCase): __test_reception_time = 1234567 __test_iso_reception_time = "1970-01-15 06:56:07+00" __test_date_reception_time = datetime.strptime(__test_iso_reception_time, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_location = Location('test', 12.3, 43.7, 987, 'UK') __test_weather = Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, {"deg": 252.002, "speed": 1.100}, 57, {"press": 1030.119, "sea_level": 1038.589}, {"temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0) __test_instance = Observation(__test_reception_time, __test_location, __test_weather) def test_init_fails_when_reception_time_is_negative(self): self.assertRaises(ValueError, Observation, -1234567, \ self.__test_location, self.__test_weather) def test_getters_return_expected_data(self): self.assertEqual(self.__test_instance.get_reception_time(), self.__test_reception_time) self.assertEqual(self.__test_instance.get_location(), self.__test_location) self.assertEqual(self.__test_instance.get_weather(), self.__test_weather) def test_returning_different_formats_for_reception_time(self): self.assertEqual(self.__test_instance.get_reception_time(timeformat='iso'), \ self.__test_iso_reception_time) self.assertEqual(self.__test_instance.get_reception_time(timeformat='unix'), \ self.__test_reception_time) self.assertEqual(self.__test_instance.get_reception_time(timeformat='date'), \ self.__test_date_reception_time) # Test JSON and XML comparisons by ordering strings (this overcomes # interpeter-dependant serialization of XML/JSON objects) def test_to_JSON(self): ordered_base_json = ''.join(sorted(OBSERVATION_JSON_DUMP)) ordered_actual_json = ''.join(sorted(self.__test_instance.to_JSON())) self.assertEqual(ordered_base_json, ordered_actual_json) def test_to_XML(self): ordered_base_xml = ''.join(sorted(OBSERVATION_XML_DUMP)) ordered_actual_xml = ''.join(sorted(self.__test_instance.to_XML())) self.assertEqual(ordered_base_xml, ordered_actual_xml)
def weather_report(weather: Weather, location: str, unit_system: str) -> dict: """ Build a color-formatted weather report feed dictionary. """ temperature = weather.temperature(_temperature_units[unit_system.upper()]) padded_percentage = lambda value: "{:5}%".format(value) return { 'Location': location, 'Temperature (Min)': get_temperature_string(temperature['temp_min'], unit_system), 'Temperature (Now)': get_temperature_string(temperature['temp'], unit_system), 'Temperature (Max)': get_temperature_string(temperature['temp_max'], unit_system), 'Wind Speed': get_wind_string( weather.wind(_speed_units[unit_system.upper()])['speed'], unit_system), 'Humidity': padded_percentage(weather.humidity), 'Cloud Coverage': padded_percentage(weather.clouds) }
def _parse_weather_data(weather: Weather, temp_unit: str) -> Dict: temperature = weather.temperature(temp_unit) return { "date": weather.ref_time, # Current temperature is only available for the current weather "temp_cur": temperature.get("temp"), # Day/night temperatures are only available for forecast data, not # for the current weather. "temp_day": temperature.get("day"), "temp_night": temperature.get("night"), "status": weather.status, "detailed_status": weather.detailed_status, "sunrise_time": weather.srise_time, "sunset_time": weather.sset_time, # TODO For the forecast we don't need the "detailed" icon # (no need to differentiate between day/night) "icon": weather.weather_icon_name, }
class TestWeatherUtils(unittest.TestCase): __test_time_low = 1379090800 __test_time_low_iso = "2013-09-13 16:46:40+00" __test_time_high = 1379361400 __test_time_high_iso = "2013-09-16 19:56:40+00" __test_registry = WeatherCodeRegistry({ "rain": [{ "start": 1, "end": 100 }, { "start": 200, "end": 600 }], "sun": [{ "start": 750, "end": 850 }] }) __test_weather_rain = Weather(__test_time_low, 1378496400, 1378449600, 67, {"all": 30}, {"all": 0}, {"deg": 252.002, "speed": 4.100}, 57, {"press": 1030.119, "sea_level": 1038.589}, {"temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Rain", "Light rain", 500, "10d", 1000, 300.0, 298.0, 296.0) __test_weather_sun = Weather(__test_time_high, 1378496480, 1378449510, 5, {"all": 0}, {"all": 0}, {"deg": 103.4, "speed": 1.2}, 12, {"press": 1090.119, "sea_level": 1078.589}, {"temp": 299.199, "temp_kf": -1.899, "temp_max": 301.0, "temp_min": 297.6 }, "Clear", "Sky is clear", 800, "01d", 1000, 300.0, 298.0, 296.0) __test_weathers = [__test_weather_rain, __test_weather_sun] def test_status_is(self): self.assertTrue(weather.status_is(self.__test_weather_rain, "rain", self.__test_registry)) self.assertFalse(weather.status_is(self.__test_weather_sun, "rain", self.__test_registry)) def test_any_status_is(self): self.assertTrue(weather.any_status_is(self.__test_weathers, "sun", self.__test_registry)) self.assertFalse(weather.any_status_is(self.__test_weathers, "storm", self.__test_registry)) def test_filter_by_status(self): result_1 = weather.filter_by_status(self.__test_weathers, "rain", self.__test_registry) self.assertEqual(1, len(result_1)) self.assertTrue(weather.status_is(result_1[0], "rain", self.__test_registry)) result_2 = weather.filter_by_status(self.__test_weathers, "sun", self.__test_registry) self.assertEqual(1, len(result_2)) self.assertTrue(weather.status_is(result_2[0], "sun", self.__test_registry)) def test_find_closest_weather(self): self.assertEqual(self.__test_weather_rain, weather.find_closest_weather(self.__test_weathers, self.__test_time_low + 200)) self.assertEqual(self.__test_weather_sun, weather.find_closest_weather(self.__test_weathers, self.__test_time_high - 200)) def test_find_closest_weather_with_empty_list(self): self.assertFalse(weather.find_closest_weather([], self.__test_time_low + 200)) def test_find_closest_fails_when_unixtime_not_in_coverage(self): self.assertRaises(NotFoundError, weather.find_closest_weather, self.__test_weathers, self.__test_time_high + 200) def test_is_in_coverage(self): self.assertTrue(weather.is_in_coverage(self.__test_time_low + 200, self.__test_weathers)) self.assertTrue(weather.is_in_coverage(self.__test_time_high - 200, self.__test_weathers)) self.assertTrue(weather.is_in_coverage(self.__test_time_low, self.__test_weathers)) self.assertTrue(weather.is_in_coverage(self.__test_time_high, self.__test_weathers)) self.assertFalse(weather.is_in_coverage(self.__test_time_low - 200, self.__test_weathers)) self.assertFalse(weather.is_in_coverage(self.__test_time_high + 200, self.__test_weathers)) def test_is_in_coverage_with_empty_list(self): self.assertFalse(weather.is_in_coverage(1234567, []))
class TestForecast(unittest.TestCase): __test_reception_time = 1234567 __test_iso_reception_time = "1970-01-15 06:56:07+00" __test_date_reception_time = datetime.strptime( __test_iso_reception_time, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_location = Location('test', 12.3, 43.7, 987, 'IT') __test_weathers = [ Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, { "deg": 252.002, "speed": 1.100 }, 57, { "press": 1030.119, "sea_level": 1038.589 }, { "temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0), Weather(1378459690, 1378496480, 1378449510, 23, {"all": 10}, {"all": 0}, { "deg": 103.4, "speed": 4.2 }, 12, { "press": 1070.119, "sea_level": 1078.589 }, { "temp": 297.199, "temp_kf": -1.899, "temp_max": 299.0, "temp_min": 295.6 }, "Clear", "Sky is clear", 804, "02d", 1000, 300.0, 298.0, 296.0) ] __test_n_weathers = len(__test_weathers) __test_instance = Forecast("daily", __test_reception_time, __test_location, __test_weathers) def test_actualize(self): weathers = [ Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, { "deg": 252.002, "speed": 1.100 }, 57, { "press": 1030.119, "sea_level": 1038.589 }, { "temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0), # will this time ever be reached? Weather(9999999999, 1378496480, 1378449510, 23, {"all": 10}, {"all": 0}, { "deg": 103.4, "speed": 4.2 }, 12, { "press": 1070.119, "sea_level": 1078.589 }, { "temp": 297.199, "temp_kf": -1.899, "temp_max": 299.0, "temp_min": 295.6 }, "Clear", "Sky is clear", 804, "02d", 1000, 300.0, 298.0, 296.0) ] f = Forecast("daily", self.__test_reception_time, self.__test_location, weathers) self.assertEqual(2, len(f)) f.actualize() self.assertEqual(1, len(f)) def test_init_fails_when_reception_time_is_negative(self): self.assertRaises(ValueError, Forecast, "3h", -1234567, self.__test_location, self.__test_weathers) def test_get(self): index = 1 self.assertEqual(self.__test_weathers[index], self.__test_instance.get(index)) def test_accessors_interval_property(self): former_interval = self.__test_instance.get_interval() self.__test_instance.set_interval("3h") result = self.__test_instance.get_interval() self.__test_instance.set_interval(former_interval) self.assertEqual("3h", result) def test_getters_return_expected_3h_data(self): """ Test either for "3h" forecast and "daily" ones """ instance = Forecast("3h", self.__test_reception_time, self.__test_location, self.__test_weathers) self.assertEqual(instance.get_interval(), "3h") self.assertEqual(instance.get_reception_time(), self.__test_reception_time) self.assertEqual(instance.get_location(), self.__test_location) self.assertEqual(instance.get_weathers(), self.__test_weathers) def test_getters_return_expected_daily_data(self): instance = Forecast("daily", self.__test_reception_time, self.__test_location, self.__test_weathers) self.assertEqual(instance.get_interval(), "daily") self.assertEqual(instance.get_reception_time(), self.__test_reception_time) self.assertEqual(instance.get_location(), self.__test_location) self.assertEqual(instance.get_weathers(), self.__test_weathers) def test_returning_different_formats_for_reception_time(self): instance = self.__test_instance self.assertEqual(instance.get_reception_time(timeformat='iso'), self.__test_iso_reception_time) self.assertEqual(instance.get_reception_time(timeformat='unix'), self.__test_reception_time) self.assertEqual(instance.get_reception_time(timeformat='date'), self.__test_date_reception_time) def test_count_weathers(self): instance = self.__test_instance self.assertEqual(instance.count_weathers(), self.__test_n_weathers) def test_forecast_iterator(self): instance = self.__test_instance counter = 0 for weather in instance: self.assertTrue(isinstance(weather, Weather)) counter += 1 self.assertEqual(instance.count_weathers(), counter) def test__len__(self): self.assertEqual(len(self.__test_instance), len(self.__test_weathers)) # Test JSON and XML comparisons by ordering strings (this overcomes # interpeter-dependant serialization of XML/JSON objects) def test_to_JSON(self): ordered_base_json = ''.join(sorted(FORECAST_JSON_DUMP)) ordered_actual_json = ''.join(sorted(self.__test_instance.to_JSON())) self.assertEqual(ordered_base_json, ordered_actual_json) def test_to_XML(self): ordered_base_xml = ''.join(sorted(FORECAST_XML_DUMP)) ordered_actual_xml = ''.join(sorted(self.__test_instance.to_XML())) self.assertEqual(ordered_base_xml, ordered_actual_xml)
class TestForecaster(unittest.TestCase): __test_time_1 = 1379090800 __test_start_coverage_iso = "2013-09-13 16:46:40+00" __test_date_start_coverage = datetime.strptime( __test_start_coverage_iso, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_middle_1_coverage = 1379226100 __test_middle_1_coverage_iso = "2013-09-15 06:21:40+00" __test_date_middle_1_coverage = datetime.strptime( __test_middle_1_coverage_iso, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_time_2 = 1379361400 __test_middle_2_coverage_iso = "2013-09-16 19:56:40+00" __test_date_middle_2_coverage = datetime.strptime( __test_middle_2_coverage_iso, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_end_coverage = 1379902600 __test_end_coverage_iso = "2013-09-23 02:16:40+00" __test_date_end_coverage = datetime.strptime( __test_end_coverage_iso, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_location = Location('test', 12.3, 43.7, 987, 'IT') __test_weather_rainsnow = Weather(__test_time_1, 1378496400, 1378449600, 67, {"all": 30}, {"all": 1}, { "deg": 252.002, "speed": 4.100 }, 57, { "press": 1030.119, "sea_level": 1038.589 }, { "temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Rain", "Light rain", 500, "10d", 1000, 300.0, 298.0, 296.0) __test_weather_clouds = Weather(__test_middle_1_coverage, 1378496480, 1378449510, 23, {"all": 0}, {}, { "deg": 103.4, "speed": 1.2 }, 12, { "press": 1070.119, "sea_level": 1078.589 }, { "temp": 297.199, "temp_kf": -1.899, "temp_max": 299.0, "temp_min": 295.6 }, "Clouds", "Overcast clouds", 804, "02d", 1000, 300.0, 298.0, 296.0) __test_weather_sun_1 = Weather(__test_time_2, 1378496480, 1378449510, 5, {"all": 0}, {}, { "deg": 103.4, "speed": 1.2 }, 12, { "press": 1090.119, "sea_level": 1078.589 }, { "temp": 299.199, "temp_kf": -1.899, "temp_max": 301.0, "temp_min": 297.6 }, "Clear", "Sky is clear", 800, "01d", 1000, 300.0, 298.0, 296.0) __test_weather_sun_2 = Weather(__test_end_coverage, 1378496480, 1378449510, 5, {"all": 0}, {}, { "deg": 99.4, "speed": 0.8 }, 7, { "press": 1091.119, "sea_level": 1079.589 }, { "temp": 299.599, "temp_kf": -1.899, "temp_max": 301.9, "temp_min": 298.0 }, "Clear", "Sky is clear", 800, "01d", 1000, 300.0, 298.0, 296.0) __test_weather_storm = Weather(__test_end_coverage, 1378496480, 1378449510, 5, {"all": 0}, {}, { "deg": 99.4, "speed": 0.8 }, 7, { "press": 1071.119, "sea_level": 1059.589 }, { "temp": 299.599, "temp_kf": -1.899, "temp_max": 301.9, "temp_min": 298.0 }, "Storm", "Violent storm", 961, "01d", 1000, 300.0, 298.0, 296.0) __test_weather_hurricane = Weather(__test_end_coverage, 1378496480, 1378449510, 5, {"all": 0}, {}, { "deg": 99.4, "speed": 0.8 }, 7, { "press": 1071.119, "sea_level": 1059.589 }, { "temp": 299.599, "temp_kf": -1.899, "temp_max": 301.9, "temp_min": 298.0 }, "Hurricane", "Hurricane", 962, "01d", 1000, 300.0, 298.0, 296.0) __test_none_values = Weather(__test_end_coverage, 1378496480, 1378449510, 5, {}, {}, {}, 7, { "press": 1091.119, "sea_level": 1079.589 }, { "temp": 299.599, "temp_kf": -1.899 }, "Clear", "Sky is clear", 800, "01d", 1000, 300.0, 298.0, 296.0) __test_weathers = [ __test_weather_rainsnow, __test_weather_clouds, __test_weather_sun_1, __test_weather_sun_2, __test_weather_storm, __test_weather_hurricane ] __test_forecast = Forecast("daily", 1379089800, __test_location, __test_weathers) __test_instance = Forecaster(__test_forecast) def test_getter_returns_expected_data(self): self.assertEqual(self.__test_instance.get_forecast(), self.__test_forecast) def test_when_starts_returning_different_timeformats(self): self.assertEqual(self.__test_instance.when_starts(timeformat='iso'), self.__test_start_coverage_iso) self.assertEqual(self.__test_instance.when_starts(timeformat='unix'), self.__test_time_1) self.assertEqual(self.__test_instance.when_starts(timeformat='date'), self.__test_date_start_coverage) def test_when_ends_returning_different_timeformats(self): self.assertEqual(self.__test_instance.when_ends(timeformat='iso'), self.__test_end_coverage_iso) self.assertEqual(self.__test_instance.when_ends(timeformat='unix'), self.__test_end_coverage) self.assertEqual(self.__test_instance.when_ends(timeformat='date'), self.__test_date_end_coverage) def test_will_have_rain(self): self.assertTrue(self.__test_instance.will_have_rain()) def test_will_have_sun(self): self.assertTrue(self.__test_instance.will_have_sun()) def test_will_have_clear(self): self.assertTrue(self.__test_instance.will_have_clear()) def test_will_have_clouds(self): self.assertTrue(self.__test_instance.will_have_clouds()) def test_will_have_fog(self): self.assertFalse(self.__test_instance.will_have_fog()) def test_will_have_snow(self): self.assertFalse(self.__test_instance.will_have_snow()) def test_will_have_storm(self): self.assertTrue(self.__test_instance.will_have_storm()) def test_will_have_tornado(self): self.assertFalse(self.__test_instance.will_have_tornado()) def test_will_have_hurricane(self): self.assertTrue(self.__test_instance.will_have_hurricane()) def test_when_rain(self): self.assertEqual([self.__test_weather_rainsnow], self.__test_instance.when_rain()) def test_when_sun(self): self.assertEqual( [self.__test_weather_sun_1, self.__test_weather_sun_2], self.__test_instance.when_sun()) def test_when_clear(self): self.assertEqual( [self.__test_weather_sun_1, self.__test_weather_sun_2], self.__test_instance.when_clear()) def test_when_clouds(self): self.assertEqual([self.__test_weather_clouds], self.__test_instance.when_clouds()) def test_when_fog(self): self.assertFalse(self.__test_instance.when_fog()) def test_when_snow(self): self.assertFalse(self.__test_instance.when_snow()) def test_when_storm(self): self.assertTrue(self.__test_instance.when_storm()) def test_when_tornado(self): self.assertFalse(self.__test_instance.when_tornado()) def test_when_hurricane(self): self.assertTrue(self.__test_instance.when_hurricane()) def test_will_be_rainy_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertTrue(self.__test_instance.will_be_rainy_at(time_1)) self.assertFalse(self.__test_instance.will_be_rainy_at(time_2)) self.assertFalse(self.__test_instance.will_be_rainy_at(time_3)) def test_will_be_rainy_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_rainy_at, self.__test_instance, 45.7) def test_will_be_sunny_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_sunny_at(time_1)) self.assertFalse(self.__test_instance.will_be_sunny_at(time_2)) self.assertTrue(self.__test_instance.will_be_sunny_at(time_3)) def test_will_be_sunny_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_sunny_at, self.__test_instance, 45.7) def test_will_be_clear_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_clear_at(time_1)) self.assertFalse(self.__test_instance.will_be_clear_at(time_2)) self.assertTrue(self.__test_instance.will_be_clear_at(time_3)) def test_will_be_clear_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_clear_at, self.__test_instance, 45.7) def test_will_be_snowy_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_snowy_at(time_1)) self.assertFalse(self.__test_instance.will_be_snowy_at(time_2)) self.assertFalse(self.__test_instance.will_be_snowy_at(time_3)) def test_will_be_snowy_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_snowy_at, self.__test_instance, 45.7) def test_will_be_cloudy_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_cloudy_at(time_1)) self.assertTrue(self.__test_instance.will_be_cloudy_at(time_2)) self.assertFalse(self.__test_instance.will_be_cloudy_at(time_3)) def test_will_be_cloudy_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_cloudy_at, self.__test_instance, 45.7) def test_will_be_foggy_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_foggy_at(time_1)) self.assertFalse(self.__test_instance.will_be_foggy_at(time_2)) self.assertFalse(self.__test_instance.will_be_foggy_at(time_3)) def test_will_be_foggy_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_foggy_at, self.__test_instance, 45.7) def test_will_be_stormy_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_stormy_at(time_1)) self.assertFalse(self.__test_instance.will_be_stormy_at(time_2)) self.assertFalse(self.__test_instance.will_be_stormy_at(time_3)) def test_will_be_stormy_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_stormy_at, self.__test_instance, 45.7) def test_will_be_tornado_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_tornado_at(time_1)) self.assertFalse(self.__test_instance.will_be_tornado_at(time_2)) self.assertFalse(self.__test_instance.will_be_tornado_at(time_3)) def test_will_be_tornado_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_tornado_at, self.__test_instance, 45.7) def test_will_be_hurricane_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertFalse(self.__test_instance.will_be_hurricane_at(time_1)) self.assertFalse(self.__test_instance.will_be_hurricane_at(time_2)) self.assertFalse(self.__test_instance.will_be_hurricane_at(time_3)) def test_will_be_hurricane_at_fails_with_bad_parameters(self): self.assertRaises(TypeError, Forecaster.will_be_hurricane_at, self.__test_instance, 45.7) def test_get_weather_at(self): time_1 = datetime(2013, 9, 13, 16, 47, 0) time_2 = 1379226110 time_3 = "2013-09-16 19:56:50+00" self.assertEqual(self.__test_instance.get_weather_at(time_1), self.__test_weather_rainsnow) self.assertEqual(self.__test_instance.get_weather_at(time_2), self.__test_weather_clouds) self.assertEqual(self.__test_instance.get_weather_at(time_3), self.__test_weather_sun_1) def test_get_weather_at_fails_with_bad_parameter(self): self.assertRaises(TypeError, Forecaster.get_weather_at, self.__test_instance, 45.7) def test_most_hot(self): self.assertEqual(self.__test_weather_sun_2, self.__test_instance.most_hot()) def test_most_hot_returning_None(self): fcstr = Forecaster( Forecast("daily", 1379089800, self.__test_location, [self.__test_none_values])) self.assertFalse(fcstr.most_hot()) def test_most_cold(self): self.assertEqual(self.__test_weather_rainsnow, self.__test_instance.most_cold()) def test_most_cold_returning_None(self): fcstr = Forecaster( Forecast("daily", 1379089800, self.__test_location, [self.__test_none_values])) self.assertFalse(fcstr.most_hot()) def test_most_humid(self): self.assertEqual(self.__test_weather_rainsnow, self.__test_instance.most_humid()) def test_most_rainy(self): self.assertEqual(self.__test_weather_rainsnow, self.__test_instance.most_rainy()) def test_most_snowy(self): self.assertEqual(self.__test_weather_rainsnow, self.__test_instance.most_snowy()) def test_most_rainy_returning_None(self): fcstr = Forecaster( Forecast("daily", 1379089800, self.__test_location, [self.__test_none_values])) self.assertFalse(fcstr.most_rainy()) def test_most_windy(self): self.assertEqual(self.__test_weather_rainsnow, self.__test_instance.most_windy()) def test_most_windy_returning_None(self): fcstr = Forecaster( Forecast("daily", 1379089800, self.__test_location, [self.__test_none_values])) self.assertFalse(fcstr.most_windy())
def test_one_call_daily_from_dic(self): daily1 = { "dt": 1587747600, "sunrise": 1587725080, "sunset": 1587772792, "temp": { "day": 300.75, "min": 290.76, "max": 300.75, "night": 290.76, "eve": 295.22, "morn": 291.44 }, "feels_like": { "day": 300.69, "night": 291.63, "eve": 296.8, "morn": 292.73 }, "pressure": 1009, "humidity": 55, "dew_point": 291.24, "wind_speed": 3.91, "wind_deg": 262, "weather": [ { "id": 500, "main": "Rain", "description": "light rain", "icon": "10d" } ], "clouds": 95, "rain": 0.82, "uvi": 9.46 } result1 = Weather.from_dict(daily1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(9.46, result1.uvi) self.assertEqual(500, result1.weather_code) self.assertEqual(262, result1.wind()["deg"]) self.assertEqual(0.82, result1.rain["all"]) self.assertRaises(KeyError, lambda: result1.temperature()["temp"]) self.assertRaises(KeyError, lambda: result1.temperature()["feels_like"]) self.assertEqual(300.75, result1.temperature()["day"]) self.assertEqual(290.76, result1.temperature()["min"]) self.assertEqual(300.75, result1.temperature()["max"]) self.assertEqual(290.76, result1.temperature()["night"]) self.assertEqual(295.22, result1.temperature()["eve"]) self.assertEqual(291.44, result1.temperature()["morn"]) self.assertEqual(300.69, result1.temperature()["feels_like_day"]) self.assertEqual(291.63, result1.temperature()["feels_like_night"]) self.assertEqual(296.8, result1.temperature()["feels_like_eve"]) self.assertEqual(292.73, result1.temperature()["feels_like_morn"]) daily2 = { "dt": 1587639600, "sunrise": 1587615127, "sunset": 1587665513, "temp": { "day": 281.78, "min": 279.88, "max": 281.78, "night": 279.88, "eve": 281.78, "morn": 281.78 }, "feels_like": { "day": 278.55, "night": 276.84, "eve": 278.55, "morn": 278.55 }, "pressure": 1017, "humidity": 39, "dew_point": 269.13, "wind_speed": 0.96, "wind_deg": 116, "weather": [ { "id": 800, "main": "Clear", "description": "clear sky", "icon": "01n" } ], "clouds": 2, "uvi": 7.52 } result2 = Weather.from_dict(daily2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(7.52, result2.uvi) self.assertEqual(800, result2.weather_code) self.assertEqual(116, result2.wind()["deg"]) self.assertEqual(0, len(result2.rain)) self.assertRaises(KeyError, lambda: result2.temperature()["temp"]) self.assertRaises(KeyError, lambda: result2.temperature()["feels_like"]) self.assertEqual(281.78, result2.temperature()["day"]) self.assertEqual(279.88, result2.temperature()["min"]) self.assertEqual(281.78, result2.temperature()["max"]) self.assertEqual(279.88, result2.temperature()["night"]) self.assertEqual(281.78, result2.temperature()["eve"]) self.assertEqual(281.78, result2.temperature()["morn"]) self.assertEqual(278.55, result2.temperature()["feels_like_day"]) self.assertEqual(276.84, result2.temperature()["feels_like_night"]) self.assertEqual(278.55, result2.temperature()["feels_like_eve"]) self.assertEqual(278.55, result2.temperature()["feels_like_morn"])
class TestStation(unittest.TestCase): __test_name = 'KNGU' __test_station_type = 1 __test_status = 50 __test_station_ID = 2865 __test_lat = 36.9375 __test_lon = -76.2893 __test_distance = 18.95 __test_last_weather_instance = Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, { "deg": 252.002, "speed": 1.100 }, 57, { "press": 1030.119, "sea_level": 1038.589 }, { "temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0) __test_instance = Station(__test_name, __test_station_ID, __test_station_type, __test_status, __test_lat, __test_lon, __test_distance, __test_last_weather_instance) def test_init_fails_with_invalid_coords(self): self.assertRaises(ValueError, Station, self.__test_name, self.__test_station_ID, self.__test_station_type, self.__test_status, 120.0, self.__test_lon, self.__test_distance, self.__test_last_weather_instance) self.assertRaises(ValueError, Station, self.__test_name, self.__test_station_ID, self.__test_station_type, self.__test_status, self.__test_lat, 220.0, self.__test_distance, self.__test_last_weather_instance) def test_getters_return_expected_data(self): self.assertEqual(self.__test_name, self.__test_instance.get_name()) self.assertEqual(self.__test_station_type, self.__test_instance.get_station_type()) self.assertEqual(self.__test_status, self.__test_instance.get_status()) self.assertEqual(self.__test_station_ID, self.__test_instance.get_station_ID()) self.assertEqual(self.__test_lat, self.__test_instance.get_lat()) self.assertEqual(self.__test_lon, self.__test_instance.get_lon()) self.assertEqual(self.__test_last_weather_instance, self.__test_instance.get_last_weather()) # Test JSON and XML comparisons by ordering strings (this overcomes # interpeter-dependant serialization of XML/JSON objects) def test_to_JSON(self): ordered_base_json = ''.join(sorted(STATION_JSON_DUMP)) ordered_actual_json = ''.join(sorted(self.__test_instance.to_JSON())) self.assertEqual(ordered_base_json, ordered_actual_json) def test_to_XML(self): ordered_base_xml = ''.join(sorted(STATION_XML_DUMP)) ordered_actual_xml = ''.join(sorted(self.__test_instance.to_XML())) self.assertEqual(ordered_base_xml, ordered_actual_xml)
class TestObservation(unittest.TestCase): __test_reception_time = 1234567 __test_iso_reception_time = "1970-01-15 06:56:07+00" __test_date_reception_time = datetime.strptime(__test_iso_reception_time, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_location = Location('test', 12.3, 43.7, 987, 'UK') __test_weather = Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, {"deg": 252.002, "speed": 1.100}, 57, {"press": 1030.119, "sea_level": 1038.589}, {"temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0) __test_instance = Observation(__test_reception_time, __test_location, __test_weather) __bad_json = '{"a": "test", "b": 1.234, "c": [ "hello", "world"] }' __bad_json_2 = '{"message": "test", "cod": "500"}' __no_items_json = '{"cod": "200", "count": "0" }' __404_json = '{"cod": "404" }' OBSERVATION_JSON_DUMP = '{"reception_time": 1234567, "location": ' \ '{"country": "UK", "name": "test", "coordinates": ' \ '{"lat": 43.7, "lon": 12.3}, "ID": 987}, "weather": ' \ '{"status": "Clouds", "visibility_distance": 1000, ' \ '"humidity": 57, "clouds": 67, "temperature": ' \ '{"temp_kf": -1.899, "temp_max": 296.098, ' \ '"temp": 294.199, "temp_min": 294.199}, ' \ '"dewpoint": 300.0, "snow": {"all": 0}, ' \ '"detailed_status": "Overcast clouds", ' \ '"reference_time": 1378459200, "weather_code": 804, ' \ '"humidex": 298.0, "rain": {"all": 20}, ' \ '"sunset_time": 1378496400, "pressure": ' \ '{"press": 1030.119, "sea_level": 1038.589}, ' \ '"sunrise_time": 1378449600, "heat_index": 296.0, ' \ '"weather_icon_name": "04d", "wind": ' \ '{"speed": 1.1, "deg": 252.002}, "utc_offset": null, ' \ '"uvi": null}}' def test_init_fails_when_reception_time_is_negative(self): self.assertRaises(ValueError, Observation, -1234567, \ self.__test_location, self.__test_weather) def test_getters_return_expected_data(self): self.assertEqual(self.__test_instance.reception_time(), self.__test_reception_time) self.assertEqual(self.__test_instance.location, self.__test_location) self.assertEqual(self.__test_instance.weather, self.__test_weather) def test_returning_different_formats_for_reception_time(self): self.assertEqual(self.__test_instance.reception_time(timeformat='iso'), \ self.__test_iso_reception_time) self.assertEqual(self.__test_instance.reception_time(timeformat='unix'), \ self.__test_reception_time) self.assertEqual(self.__test_instance.reception_time(timeformat='date'), \ self.__test_date_reception_time) def test_from_dict(self): d = json.loads(OBSERVATION_JSON) result = Observation.from_dict(d) self.assertTrue(result is not None) self.assertFalse(result.reception_time() is None) loc = result.location self.assertFalse(loc is None) self.assertTrue(all(v is not None for v in loc.__dict__.values())) weat = result.weather self.assertFalse(weat is None) def test_from_dict_fails_when_JSON_data_is_None(self): with self.assertRaises(ParseAPIResponseError): Observation.from_dict(None) def test_from_dict_fails_with_malformed_JSON_data(self): with self.assertRaises(ParseAPIResponseError): Observation.from_dict(json.loads(self.__bad_json)) with self.assertRaises(APIResponseError): Observation.from_dict(json.loads(self.__bad_json_2)) with self.assertRaises(ParseAPIResponseError): Observation.from_dict(json.loads(OBSERVATION_MALFORMED_JSON)) def test_from_dict_when_server_error(self): result = self.__test_instance.from_dict(json.loads(OBSERVATION_NOT_FOUND_JSON)) self.assertTrue(result is None) def test_to_dict(self): expected = json.loads(self.OBSERVATION_JSON_DUMP) result = self.__test_instance.to_dict() self.assertEqual(expected, result) def test_from_dict_of_lists(self): result = self.__test_instance.from_dict_of_lists(json.loads(SEARCH_RESULTS_JSON)) self.assertFalse(result is None) self.assertTrue(isinstance(result, list)) for item in result: self.assertFalse(item is None) self.assertFalse(item.reception_time() is None) loc = item.location self.assertFalse(loc is None) self.assertTrue(all(v is not None for v in loc.__dict__.values())) weat = item.weather self.assertFalse(weat is None) def test_from_dict_of_lists_fails_when_JSON_data_is_None(self): with self.assertRaises(ParseAPIResponseError): Observation.from_dict_of_lists(None) def test_from_dict_of_lists_with_malformed_JSON_data(self): with self.assertRaises(ParseAPIResponseError): Observation.from_dict_of_lists(json.loads(self.__bad_json)) with self.assertRaises(APIResponseError): Observation.from_dict_of_lists(json.loads(self.__bad_json_2)) with self.assertRaises(ParseAPIResponseError): Observation.from_dict_of_lists(json.loads(OBSERVATION_MALFORMED_JSON)) def test_from_dict_of_lists_when_no_items_returned(self): self.assertFalse(Observation.from_dict_of_lists(json.loads(self.__no_items_json))) def test_from_dict_of_lists_when_resource_not_found(self): self.assertIsNone(Observation.from_dict_of_lists(json.loads(self.__404_json))) def test_from_dict_of_lists_when_no_results(self): result = Observation.from_dict_of_lists(json.loads(SEARCH_WITH_NO_RESULTS_1_JSON)) self.assertTrue(isinstance(result, list)) self.assertEqual(0, len(result)) result = Observation.from_dict_of_lists(json.loads(SEARCH_WITH_NO_RESULTS_2_JSON)) self.assertTrue(isinstance(result, list)) self.assertEqual(0, len(result)) def test_from_dict_of_lists_when_server_error(self): with self.assertRaises(APIResponseError): Observation.from_dict_of_lists(json.loads(INTERNAL_SERVER_ERROR_JSON)) def test__repr(self): print(self.__test_instance)
def test_from_dict_when_data_fields_are_none(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': None, 'visibility': {'distance': 1000}, 'calc': { 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 }, 'rain': None, 'snow': None } result1 = Weather.from_dict(dict1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(0, len(result1.wind())) self.assertEqual(0, len(result1.rain)) self.assertEqual(0, len(result1.snow)) dict2 = {"station": { "name": "KPPQ", "type": 1, "status": 50, "id": 1000, "coord": {"lon": -90.47, "lat": 39.38} }, "last": { "main": { "temp": 276.15, "pressure": 1031}, "wind": None, "visibility": { "distance": 11265, "prefix": 0 }, "calc": { "dewpoint": 273.15 }, "clouds": [ {"distance": 427, "condition": "SCT"} ], "dt": 1417977300 }, "params": ["temp", "pressure", "wind", "visibility"] } result2 = Weather.from_dict(dict2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(0, len(result2.wind()))
def test_from_dict(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'visibility': {'distance': 1000}, 'calc': { 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 } } dict2 = {"dt": 1378897200, "temp": {"day": 289.37, "min": 284.88, "max": 289.37, "night": 284.88, "eve": 287.53, "morn": 289.37 }, "pressure": 1025.35, "humidity": 71, "weather": [ {"id": 500, "main": "Rain", "description": "light rain", "icon": "u10d"} ], "speed": 3.76, "deg": 338, "clouds": 48, "rain": 3 } dict3 = {"station": { "name": "KPPQ", "type": 1, "status": 50, "id": 1000, "coord": {"lon": -90.47, "lat": 39.38} }, "last": { "main": { "temp": 276.15, "pressure": 1031}, "wind": { "speed": 3.1, "deg": 140 }, "visibility": { "distance": 11265, "prefix": 0 }, "calc": { "dewpoint": 273.15, "humidex": 57.8, "heatindex": 1.2 }, "clouds": [ {"distance": 427, "condition": "SCT"} ], "dt": 1417977300 }, "params": ["temp", "pressure", "wind", "visibility"], "timezone": 1234567 } dict4 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'calc': {}, 'last': {}, 'snow': {'tot': 76.3} } dict5 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'visibility': {'distance': 1000}, "last": {} } dict6 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'last': { "dt": 1417977300, "calc": {}, 'visibility': 2.34, 'main': { "humidity": 77.2 } }, 'snow': 66.1 } result1 = Weather.from_dict(dict1) self.assertTrue(isinstance(result1, Weather)) result2 = Weather.from_dict(dict2) self.assertTrue(isinstance(result2, Weather)) result3 = Weather.from_dict(dict3) self.assertTrue(isinstance(result3, Weather)) result4 = Weather.from_dict(dict4) self.assertTrue(isinstance(result4, Weather)) result5 = Weather.from_dict(dict5) self.assertTrue(isinstance(result5, Weather)) result6 = Weather.from_dict(dict6) self.assertTrue(isinstance(result6, Weather))
class TestWeather(unittest.TestCase): __test_reference_time = 1378459200 __test_iso_reference_time = "2013-09-06 09:20:00+00" __test_date_reference_time = datetime.strptime(__test_iso_reference_time, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_sunset_time = 1378496400 __test_iso_sunset_time = "2013-09-06 19:40:00+00" __test_date_sunset_time = datetime.strptime(__test_iso_sunset_time, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_sunrise_time = 1378449600 __test_iso_sunrise_time = "2013-09-06 06:40:00+00" __test_date_sunrise_time = datetime.strptime(__test_iso_sunrise_time, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_clouds = 67 __test_rain = {"all": 20} __test_snow = {"all": 0} __test_wind = {"deg": 252.002, "speed": 1.100, "gust": 2.09} __test_imperial_wind = {"deg": 252.002, "speed": 2.460634, "gust": 4.6752046} __test_knots_wind = {'deg': 252.002, 'speed': 2.138224, 'gust': 4.0626256} __test_beaufort_wind = {"deg": 252.002, "speed": 1, "gust": 2} __test_kmh_wind = {'deg': 252.002, 'speed': 3.9600000000000004, 'gust': 7.524} __test_humidity = 57 __test_pressure = {"press": 1030.119, "sea_level": 1038.589, "grnd_level": 1038.773} __test_temperature = {"temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199, "feels_like": 298.0} __test_celsius_temperature = {"temp": 21.049, "temp_kf": -1.899, "temp_max": 22.948, "temp_min": 21.049, "feels_like": 24.85} __test_fahrenheit_temperature = {"temp": 69.888, "temp_kf": -1.899, "temp_max": 73.306, "temp_min": 69.888, "feels_like": 76.73} __test_status = "Clouds" __test_detailed_status = "Overcast clouds" __test_weather_code = 804 __test_weather_icon_name = "04d" __test_visibility_distance = 1000 __test_dewpoint = 300.0 __test_humidex = 298.0 __test_heat_index = 40.0 __test_instance = Weather(__test_reference_time, __test_sunset_time, __test_sunrise_time, __test_clouds, __test_rain, __test_snow, __test_wind, __test_humidity, __test_pressure, __test_temperature, __test_status, __test_detailed_status, __test_weather_code, __test_weather_icon_name, __test_visibility_distance, __test_dewpoint, __test_humidex, __test_heat_index) __bad_json = '{"a": "test", "b": 1.234, "c": [ "hello", "world"] }' __bad_json_2 = '{"list": [{"test":"fake"}] }' __no_items_json = '{"cnt": "0"}' WEATHER_JSON_DUMP = '{"status": "Clouds", "visibility_distance": 1000, ' \ '"clouds": 67, "temperature": {"temp_kf": -1.899, ' \ '"temp_min": 294.199, "temp": 294.199, "temp_max": 296.098, "feels_like": 298.0},' \ ' "dewpoint": 300.0, "humidex": 298.0, "detailed_status": ' \ '"Overcast clouds", "reference_time": 1378459200, ' \ '"weather_code": 804, "sunset_time": 1378496400, "rain": ' \ '{"all": 20}, "snow": {"all": 0}, "pressure": ' \ '{"press": 1030.119, "sea_level": 1038.589, "grnd_level": 1038.773}, ' \ '"sunrise_time": 1378449600, "heat_index": 40.0, ' \ '"weather_icon_name": "04d", "humidity": 57, "wind": ' \ '{"speed": 1.1, "deg": 252.002, "gust": 2.09}, "utc_offset": null, "uvi": null}' def test_init_fails_when_wrong_data_provided(self): self.assertRaises(ValueError, Weather, -9876543210, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, -45, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, -16, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, -12, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, -10.0, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, -10.0) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index, uvi=-1) def test_init_when_wind_is_none(self): instance = Weather(self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, None, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.wind()) def test_init_stores_negative_sunset_time_as_none(self): instance = Weather(self.__test_reference_time, -9876543210, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.sunset_time()) def test_init_stores_negative_sunrise_time_as_none(self): instance = Weather(self.__test_reference_time, self.__test_sunset_time, -9876543210, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.sunrise_time()) def test_init_fails_with_non_integer_utc_offset(self): self.assertRaises(AssertionError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index, 'non_string_utc_offset') def test_from_dict_fails_when_dict_is_none(self): self.assertRaises(ParseAPIResponseError, Weather.from_dict, None) def test_from_dict(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'visibility': {'distance': 1000}, 'calc': { 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 } } dict2 = {"dt": 1378897200, "temp": {"day": 289.37, "min": 284.88, "max": 289.37, "night": 284.88, "eve": 287.53, "morn": 289.37 }, "pressure": 1025.35, "humidity": 71, "weather": [ {"id": 500, "main": "Rain", "description": "light rain", "icon": "u10d"} ], "speed": 3.76, "deg": 338, "clouds": 48, "rain": 3 } dict3 = {"station": { "name": "KPPQ", "type": 1, "status": 50, "id": 1000, "coord": {"lon": -90.47, "lat": 39.38} }, "last": { "main": { "temp": 276.15, "pressure": 1031}, "wind": { "speed": 3.1, "deg": 140 }, "visibility": { "distance": 11265, "prefix": 0 }, "calc": { "dewpoint": 273.15, "humidex": 57.8, "heatindex": 1.2 }, "clouds": [ {"distance": 427, "condition": "SCT"} ], "dt": 1417977300 }, "params": ["temp", "pressure", "wind", "visibility"], "timezone": 1234567 } dict4 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'calc': {}, 'last': {}, 'snow': {'tot': 76.3} } dict5 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'visibility': {'distance': 1000}, "last": {} } dict6 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'last': { "dt": 1417977300, "calc": {}, 'visibility': 2.34, 'main': { "humidity": 77.2 } }, 'snow': 66.1 } result1 = Weather.from_dict(dict1) self.assertTrue(isinstance(result1, Weather)) result2 = Weather.from_dict(dict2) self.assertTrue(isinstance(result2, Weather)) result3 = Weather.from_dict(dict3) self.assertTrue(isinstance(result3, Weather)) result4 = Weather.from_dict(dict4) self.assertTrue(isinstance(result4, Weather)) result5 = Weather.from_dict(dict5) self.assertTrue(isinstance(result5, Weather)) result6 = Weather.from_dict(dict6) self.assertTrue(isinstance(result6, Weather)) def test_from_dict_when_data_fields_are_none(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': None, 'visibility': {'distance': 1000}, 'calc': { 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 }, 'rain': None, 'snow': None } result1 = Weather.from_dict(dict1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(0, len(result1.wind())) self.assertEqual(0, len(result1.rain)) self.assertEqual(0, len(result1.snow)) dict2 = {"station": { "name": "KPPQ", "type": 1, "status": 50, "id": 1000, "coord": {"lon": -90.47, "lat": 39.38} }, "last": { "main": { "temp": 276.15, "pressure": 1031}, "wind": None, "visibility": { "distance": 11265, "prefix": 0 }, "calc": { "dewpoint": 273.15 }, "clouds": [ {"distance": 427, "condition": "SCT"} ], "dt": 1417977300 }, "params": ["temp", "pressure", "wind", "visibility"] } result2 = Weather.from_dict(dict2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(0, len(result2.wind())) def test_to_dict(self): expected = json.loads(self.WEATHER_JSON_DUMP) result = self.__test_instance.to_dict() self.assertEqual(expected, result) def test_from_dict_of_lists(self): result = Weather.from_dict_of_lists(json.loads(CITY_WEATHER_HISTORY_JSON)) self.assertTrue(result) self.assertTrue(isinstance(result, list)) for weather in result: self.assertTrue(weather is not None) def test_from_dict_of_lists_fails_when_JSON_data_is_None(self): self.assertRaises(ParseAPIResponseError, Weather.from_dict_of_lists, None) def test_from_dict_of_lists_with_malformed_JSON_data(self): self.assertRaises(ParseAPIResponseError, Weather.from_dict_of_lists, json.loads(self.__bad_json)) self.assertRaises(ParseAPIResponseError, Weather.from_dict_of_lists, json.loads(self.__bad_json_2)) def test_from_dict_of_lists_when_no_results(self): result = Weather.from_dict_of_lists(json.loads(CITY_WEATHER_HISTORY_NO_RESULTS_JSON)) self.assertTrue(isinstance(result, list)) self.assertEqual(0, len(result)) result = Weather.from_dict_of_lists(json.loads(self.__no_items_json)) self.assertTrue(isinstance(result, list)) self.assertEqual(0, len(result)) def test_parse_JSON_when_location_not_found(self): self.assertFalse(Weather.from_dict_of_lists(json.loads(CITY_WEATHER_HISTORY_NOT_FOUND_JSON))) def test_parse_JSON_when_server_error(self): self.assertRaises(APIResponseError, Weather.from_dict_of_lists, json.loads(INTERNAL_SERVER_ERROR_JSON)) def test_reference_time_returning_different_formats(self): self.assertEqual(self.__test_instance.reference_time(timeformat='iso'), self.__test_iso_reference_time) self.assertEqual(self.__test_instance.reference_time(timeformat='unix'), self.__test_reference_time) self.assertEqual(self.__test_instance.reference_time(timeformat='date'), self.__test_date_reference_time) def test_sunset_time_returning_different_formats(self): self.assertEqual(self.__test_instance.sunset_time(timeformat='iso'), self.__test_iso_sunset_time) self.assertEqual(self.__test_instance.sunset_time(timeformat='unix'), self.__test_sunset_time) self.assertEqual(self.__test_instance.sunset_time(timeformat='date'), self.__test_date_sunset_time) def test_sunrise_time_returning_different_formats(self): self.assertEqual(self.__test_instance.sunrise_time(timeformat='iso'), self.__test_iso_sunrise_time) self.assertEqual(self.__test_instance.sunrise_time(timeformat='unix'), self.__test_sunrise_time) self.assertEqual(self.__test_instance.sunrise_time(timeformat='date'), self.__test_date_sunrise_time) def test_get_reference_time_fails_with_unknown_timeformat(self): self.assertRaises(ValueError, Weather.reference_time, self.__test_instance, 'xyz') def test_sunset_time_fails_with_unknown_timeformat(self): self.assertRaises(ValueError, Weather.sunset_time, self.__test_instance, 'xyz') def test_sunrise_time_fails_with_unknown_timeformat(self): self.assertRaises(ValueError, Weather.sunrise_time, self.__test_instance, 'xyz') def test_returning_different_units_for_temperatures(self): result_kelvin = self.__test_instance.temperature(unit='kelvin') result_celsius = self.__test_instance.temperature(unit='celsius') result_fahrenheit = self.__test_instance.temperature( unit='fahrenheit') for item in self.__test_temperature: self.assertAlmostEqual(result_kelvin[item], self.__test_temperature[item], delta=0.1) self.assertAlmostEqual(result_celsius[item], self.__test_celsius_temperature[item], delta=0.1) self.assertAlmostEqual(result_fahrenheit[item], self.__test_fahrenheit_temperature[item], delta=0.1) def test_get_temperature_fails_with_unknown_units(self): self.assertRaises(ValueError, Weather.temperature, self.__test_instance, 'xyz') def test_returning_different_units_for_wind_values(self): result_imperial = self.__test_instance.wind(unit='miles_hour') result_metric_ms = self.__test_instance.wind(unit='meters_sec') result_metric_kmh = self.__test_instance.wind(unit='km_hour') result_knots = self.__test_instance.wind(unit='knots') result_beaufort = self.__test_instance.wind(unit='beaufort') result_unspecified = self.__test_instance.wind() self.assertEqual(result_unspecified, result_metric_ms) self.assertDictEqual(result_metric_kmh, self.__test_kmh_wind) for item in self.__test_wind: self.assertEqual(result_metric_ms[item], self.__test_wind[item]) self.assertEqual(result_imperial[item], self.__test_imperial_wind[item]) self.assertEqual(result_knots[item], self.__test_knots_wind[item]) self.assertEqual(result_beaufort[item], self.__test_beaufort_wind[item]) def test_get_wind_fails_with_unknown_units(self): self.assertRaises(ValueError, Weather.wind, self.__test_instance, 'xyz') def test_weather_icon_url(self): expected = ICONS_BASE_URI % self.__test_instance.weather_icon_name result = self.__test_instance.weather_icon_url() self.assertEqual(expected, result) def test_repr(self): print(self.__test_instance) def test_one_call_current_from_dic(self): current1 = { "dt": 1586001851, "sunrise": 1586003020, "sunset": 1586048382, "temp": 280.15, "feels_like": 277.75, "pressure": 1017, "humidity": 93, "uvi": 9.63, "clouds": 90, "visibility": 6437, "wind_speed": 2.1, "wind_deg": 70, "weather": [ { "id": 501, "main": "Rain", "description": "moderate rain", "icon": "10n" }, { "id": 701, "main": "Mist", "description": "mist", "icon": "50n" } ], "rain": { "1h": 1.02 } } result1 = Weather.from_dict(current1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(9.63, result1.uvi) self.assertEqual(501, result1.weather_code) self.assertEqual(1.02, result1.rain["1h"]) self.assertEqual(280.15, result1.temperature()["temp"]) self.assertEqual(277.75, result1.temperature()["feels_like"]) current2 = { "dt": 1587678355, "sunrise": 1587615127, "sunset": 1587665513, "temp": 281.78, "feels_like": 277.4, "pressure": 1017, "humidity": 39, "dew_point": 269.13, "uvi": 7.52, "clouds": 2, "visibility": 10000, "wind_speed": 2.6, "wind_deg": 170, "weather": [ { "id": 800, "main": "Clear", "description": "clear sky", "icon": "01n" } ] } result2 = Weather.from_dict(current2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(7.52, result2.uvi) self.assertEqual(800, result2.weather_code) self.assertEqual(170, result2.wind()["deg"]) self.assertEqual(0, len(result2.rain)) self.assertEqual(281.78, result2.temperature()["temp"]) self.assertEqual(277.4, result2.temperature()["feels_like"]) def test_one_call_hourly_from_dic(self): hourly1 = { "dt": 1587675600, "temp": 294.16, "feels_like": 292.47, "pressure": 1009, "humidity": 88, "dew_point": 292.1, "clouds": 90, "wind_speed": 7, "wind_deg": 189, "weather": [ { "id": 501, "main": "Rain", "description": "moderate rain", "icon": "10d" } ], "rain": { "1h": 2.28 } } result1 = Weather.from_dict(hourly1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(292.47, result1.temperature()["feels_like"]) self.assertEqual(501, result1.weather_code) self.assertEqual(2.28, result1.rain["1h"]) self.assertEqual(294.16, result1.temperature()["temp"]) self.assertEqual(292.47, result1.temperature()["feels_like"]) hourly2 = { "dt": 1587682800, "temp": 279.64, "feels_like": 276.77, "pressure": 1020, "humidity": 54, "dew_point": 271.26, "clouds": 3, "wind_speed": 0.84, "wind_deg": 119, "weather": [ { "id": 800, "main": "Clear", "description": "clear sky", "icon": "01n" } ] } result2 = Weather.from_dict(hourly2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(3, result2.clouds) self.assertEqual(800, result2.weather_code) self.assertEqual(119, result2.wind()["deg"]) self.assertEqual(0, len(result2.rain)) self.assertEqual(279.64, result2.temperature()["temp"]) self.assertEqual(276.77, result2.temperature()["feels_like"]) def test_one_call_daily_from_dic(self): daily1 = { "dt": 1587747600, "sunrise": 1587725080, "sunset": 1587772792, "temp": { "day": 300.75, "min": 290.76, "max": 300.75, "night": 290.76, "eve": 295.22, "morn": 291.44 }, "feels_like": { "day": 300.69, "night": 291.63, "eve": 296.8, "morn": 292.73 }, "pressure": 1009, "humidity": 55, "dew_point": 291.24, "wind_speed": 3.91, "wind_deg": 262, "weather": [ { "id": 500, "main": "Rain", "description": "light rain", "icon": "10d" } ], "clouds": 95, "rain": 0.82, "uvi": 9.46 } result1 = Weather.from_dict(daily1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(9.46, result1.uvi) self.assertEqual(500, result1.weather_code) self.assertEqual(262, result1.wind()["deg"]) self.assertEqual(0.82, result1.rain["all"]) self.assertRaises(KeyError, lambda: result1.temperature()["temp"]) self.assertRaises(KeyError, lambda: result1.temperature()["feels_like"]) self.assertEqual(300.75, result1.temperature()["day"]) self.assertEqual(290.76, result1.temperature()["min"]) self.assertEqual(300.75, result1.temperature()["max"]) self.assertEqual(290.76, result1.temperature()["night"]) self.assertEqual(295.22, result1.temperature()["eve"]) self.assertEqual(291.44, result1.temperature()["morn"]) self.assertEqual(300.69, result1.temperature()["feels_like_day"]) self.assertEqual(291.63, result1.temperature()["feels_like_night"]) self.assertEqual(296.8, result1.temperature()["feels_like_eve"]) self.assertEqual(292.73, result1.temperature()["feels_like_morn"]) daily2 = { "dt": 1587639600, "sunrise": 1587615127, "sunset": 1587665513, "temp": { "day": 281.78, "min": 279.88, "max": 281.78, "night": 279.88, "eve": 281.78, "morn": 281.78 }, "feels_like": { "day": 278.55, "night": 276.84, "eve": 278.55, "morn": 278.55 }, "pressure": 1017, "humidity": 39, "dew_point": 269.13, "wind_speed": 0.96, "wind_deg": 116, "weather": [ { "id": 800, "main": "Clear", "description": "clear sky", "icon": "01n" } ], "clouds": 2, "uvi": 7.52 } result2 = Weather.from_dict(daily2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(7.52, result2.uvi) self.assertEqual(800, result2.weather_code) self.assertEqual(116, result2.wind()["deg"]) self.assertEqual(0, len(result2.rain)) self.assertRaises(KeyError, lambda: result2.temperature()["temp"]) self.assertRaises(KeyError, lambda: result2.temperature()["feels_like"]) self.assertEqual(281.78, result2.temperature()["day"]) self.assertEqual(279.88, result2.temperature()["min"]) self.assertEqual(281.78, result2.temperature()["max"]) self.assertEqual(279.88, result2.temperature()["night"]) self.assertEqual(281.78, result2.temperature()["eve"]) self.assertEqual(281.78, result2.temperature()["morn"]) self.assertEqual(278.55, result2.temperature()["feels_like_day"]) self.assertEqual(276.84, result2.temperature()["feels_like_night"]) self.assertEqual(278.55, result2.temperature()["feels_like_eve"]) self.assertEqual(278.55, result2.temperature()["feels_like_morn"])
def get_temperature(w: Weather) -> str: temp_c = w.temperature('celsius') temp_f = w.temperature('fahrenheit') return "{}\u00B0C ({}\u00B0F)".format(round(temp_c['temp'], 1), round(temp_f['temp'], 1))
class TestForecast(unittest.TestCase): __test_reception_time = 1234567 __test_iso_reception_time = "1970-01-15 06:56:07+00:00" __test_date_reception_time = datetime.fromisoformat( __test_iso_reception_time) __test_location = Location('test', 12.3, 43.7, 987, 'IT') __test_weathers = [ Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, { "deg": 252.002, "speed": 1.100 }, 57, { "press": 1030.119, "sea_level": 1038.589 }, { "temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0), Weather(1378459690, 1378496480, 1378449510, 23, {"all": 10}, {"all": 0}, { "deg": 103.4, "speed": 4.2 }, 12, { "press": 1070.119, "sea_level": 1078.589 }, { "temp": 297.199, "temp_kf": -1.899, "temp_max": 299.0, "temp_min": 295.6 }, "Clear", "Sky is clear", 804, "02d", 1000, 300.0, 298.0, 296.0) ] __test_n_weathers = len(__test_weathers) __test_instance = Forecast("daily", __test_reception_time, __test_location, __test_weathers) __bad_json = '{"a": "test", "b": 1.234, "c": [ "hello", "world"] }' __bad_json_2 = '{ "city": {"id": 2643743,' \ '"name": "London","coord": {"lon": -0.12574,"lat": 51.50853},"country": ' \ '"GB","population": 1000000} }' __no_items_found_json = '{"count": "0", "city": {"id": 2643743,' \ '"name": "London","coord": {"lon": -0.12574,"lat": 51.50853},"country": ' \ '"GB","population": 1000000} }' FORECAST_JSON_DUMP = '{"reception_time": 1234567, "interval": "daily", ' \ '"location": {"country": "IT", "name": "test", ' \ '"coordinates": {"lat": 43.7, "lon": 12.3}, "ID": 987}, ' \ '"weathers": [{"status": "Clouds", ' \ '"visibility_distance": 1000, "humidity": 57, "clouds": 67,' \ ' "temperature": {"temp_kf": -1.899, "temp_max": 296.098, ' \ '"temp": 294.199, "temp_min": 294.199}, "dewpoint": 300.0,' \ ' "snow": {"all": 0}, "detailed_status": "Overcast clouds",' \ ' "reference_time": 1378459200, "weather_code": 804, ' \ '"humidex": 298.0, "rain": {"all": 20}, ' \ '"sunset_time": 1378496400, "pressure": {"press": 1030.119,' \ ' "sea_level": 1038.589}, "sunrise_time": 1378449600, ' \ '"heat_index": 296.0, "weather_icon_name": "04d", "wind": ' \ '{"speed": 1.1, "deg": 252.002}, "utc_offset": null, "uvi": null}, {"status": "Clear", ' \ '"visibility_distance": 1000, "humidity": 12, ' \ '"clouds": 23, "temperature": {"temp_kf": -1.899, ' \ '"temp_max": 299.0, "temp": 297.199, "temp_min": 295.6}, ' \ '"dewpoint": 300.0, "snow": {"all": 0}, "detailed_status": ' \ '"Sky is clear", "reference_time": 1378459690, ' \ '"weather_code": 804, "humidex": 298.0, "rain": {"all": 10},' \ ' "sunset_time": 1378496480, "pressure": ' \ '{"press": 1070.119, "sea_level": 1078.589}, ' \ '"sunrise_time": 1378449510, "heat_index": 296.0, ' \ '"weather_icon_name": "02d", "wind": {"speed": 4.2, ' \ '"deg": 103.4}, "utc_offset": null, "uvi": null}]}' def test_actualize(self): weathers = [ Weather(1378459200, 1378496400, 1378449600, 67, {"all": 20}, {"all": 0}, { "deg": 252.002, "speed": 1.100 }, 57, { "press": 1030.119, "sea_level": 1038.589 }, { "temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 }, "Clouds", "Overcast clouds", 804, "04d", 1000, 300.0, 298.0, 296.0), # will this time ever be reached? Weather(9999999999, 1378496480, 1378449510, 23, {"all": 10}, {"all": 0}, { "deg": 103.4, "speed": 4.2 }, 12, { "press": 1070.119, "sea_level": 1078.589 }, { "temp": 297.199, "temp_kf": -1.899, "temp_max": 299.0, "temp_min": 295.6 }, "Clear", "Sky is clear", 804, "02d", 1000, 300.0, 298.0, 296.0) ] f = Forecast("daily", self.__test_reception_time, self.__test_location, weathers) self.assertEqual(2, len(f)) f.actualize() self.assertEqual(1, len(f)) def test_init_fails_when_reception_time_is_negative(self): self.assertRaises(ValueError, Forecast, "3h", -1234567, self.__test_location, self.__test_weathers) def test_get(self): index = 1 self.assertEqual(self.__test_weathers[index], self.__test_instance.get(index)) def test_getters_return_expected_3h_data(self): """ Test either for "3h" forecast and "daily" ones """ instance = Forecast("3h", self.__test_reception_time, self.__test_location, self.__test_weathers) self.assertEqual(instance.interval, "3h") self.assertEqual(instance.reception_time(), self.__test_reception_time) self.assertEqual(instance.location, self.__test_location) self.assertEqual(instance.weathers, self.__test_weathers) def test_getters_return_expected_daily_data(self): instance = Forecast("daily", self.__test_reception_time, self.__test_location, self.__test_weathers) self.assertEqual(instance.interval, "daily") self.assertEqual(instance.reception_time(), self.__test_reception_time) self.assertEqual(instance.location, self.__test_location) self.assertEqual(instance.weathers, self.__test_weathers) def test_returning_different_formats_for_reception_time(self): instance = self.__test_instance self.assertEqual(instance.reception_time(timeformat='iso'), self.__test_iso_reception_time) self.assertEqual(instance.reception_time(timeformat='unix'), self.__test_reception_time) self.assertEqual(instance.reception_time(timeformat='date'), self.__test_date_reception_time) def test__iter__(self): instance = self.__test_instance counter = 0 for weather in instance: self.assertTrue(isinstance(weather, Weather)) counter += 1 self.assertEqual(len(instance.weathers), counter) def test__len__(self): self.assertEqual(len(self.__test_instance), len(self.__test_weathers)) def test_from_dict(self): result = self.__test_instance.from_dict( json.loads(THREE_HOURS_FORECAST_JSON)) self.assertTrue(result is not None) self.assertTrue(result.reception_time() is not None) self.assertFalse(result.interval is not None) loc = result.location self.assertTrue(loc is not None) self.assertTrue(all(v is not None for v in loc.__dict__.values())) self.assertTrue(isinstance(result.weathers, list)) for weather in result: self.assertTrue(weather is not None) def test_from_dict_fails_when_JSON_data_is_None(self): with self.assertRaises(ParseAPIResponseError): Forecast.from_dict(None) def test_from_dict_with_malformed_JSON_data(self): with self.assertRaises(ParseAPIResponseError): Forecast.from_dict(json.loads(self.__bad_json)) with self.assertRaises(ParseAPIResponseError): Forecast.from_dict(json.loads(self.__bad_json_2)) with self.assertRaises(ParseAPIResponseError): Forecast.from_dict(json.loads(FORECAST_MALFORMED_JSON)) def test_from_dict_when_no_results(self): result = Forecast.from_dict(json.loads(FORECAST_NOT_FOUND_JSON)) self.assertFalse(result is None) self.assertEqual(0, len(result)) result = Forecast.from_dict(json.loads(self.__no_items_found_json)) self.assertEqual(0, len(result)) def test_from_dict_when_server_error(self): with self.assertRaises(APIResponseError): Forecast.from_dict(json.loads(INTERNAL_SERVER_ERROR_JSON)) def test_to_dict(self): expected = json.loads(self.FORECAST_JSON_DUMP) result = self.__test_instance.to_dict() self.assertEqual(expected, result) def test__repr(self): print(self.__test_instance)
def test_one_call_current_from_dic(self): current1 = { "dt": 1586001851, "sunrise": 1586003020, "sunset": 1586048382, "temp": 280.15, "feels_like": 277.75, "pressure": 1017, "humidity": 93, "uvi": 9.63, "clouds": 90, "visibility": 6437, "wind_speed": 2.1, "wind_deg": 70, "weather": [ { "id": 501, "main": "Rain", "description": "moderate rain", "icon": "10n" }, { "id": 701, "main": "Mist", "description": "mist", "icon": "50n" } ], "rain": { "1h": 1.02 } } result1 = Weather.from_dict(current1) self.assertTrue(isinstance(result1, Weather)) self.assertEqual(9.63, result1.uvi) self.assertEqual(501, result1.weather_code) self.assertEqual(1.02, result1.rain["1h"]) self.assertEqual(280.15, result1.temperature()["temp"]) self.assertEqual(277.75, result1.temperature()["feels_like"]) current2 = { "dt": 1587678355, "sunrise": 1587615127, "sunset": 1587665513, "temp": 281.78, "feels_like": 277.4, "pressure": 1017, "humidity": 39, "dew_point": 269.13, "uvi": 7.52, "clouds": 2, "visibility": 10000, "wind_speed": 2.6, "wind_deg": 170, "weather": [ { "id": 800, "main": "Clear", "description": "clear sky", "icon": "01n" } ] } result2 = Weather.from_dict(current2) self.assertTrue(isinstance(result2, Weather)) self.assertEqual(7.52, result2.uvi) self.assertEqual(800, result2.weather_code) self.assertEqual(170, result2.wind()["deg"]) self.assertEqual(0, len(result2.rain)) self.assertEqual(281.78, result2.temperature()["temp"]) self.assertEqual(277.4, result2.temperature()["feels_like"])
def test_parse_JSON_when_location_not_found(self): self.assertFalse(Weather.from_dict_of_lists(json.loads(CITY_WEATHER_HISTORY_NOT_FOUND_JSON)))
class TestWeather(unittest.TestCase): __test_reference_time = 1378459200 __test_iso_reference_time = "2013-09-06 09:20:00+00" __test_date_reference_time = datetime.strptime(__test_iso_reference_time, '%Y-%m-%d %H:%M:%S+00').replace(tzinfo=UTC()) __test_sunset_time = 1378496400 __test_iso_sunset_time = "2013-09-06 19:40:00+00" __test_sunrise_time = 1378449600 __test_iso_sunrise_time = "2013-09-06 06:40:00+00" __test_clouds = 67 __test_rain = {"all": 20} __test_snow = {"all": 0} __test_wind = {"deg": 252.002, "speed": 1.100, "gust": 2.09} __test_imperial_wind = {"deg": 252.002, "speed": 2.460634, "gust": 4.6752046} __test_humidity = 57 __test_pressure = {"press": 1030.119, "sea_level": 1038.589} __test_temperature = {"temp": 294.199, "temp_kf": -1.899, "temp_max": 296.098, "temp_min": 294.199 } __test_celsius_temperature = {"temp": 21.049, "temp_kf": -1.899, "temp_max": 22.948, "temp_min": 21.049 } __test_fahrenheit_temperature = {"temp": 69.888, "temp_kf": -1.899, "temp_max": 73.306, "temp_min": 69.888 } __test_status = "Clouds" __test_detailed_status = "Overcast clouds" __test_weather_code = 804 __test_weather_icon_name = "04d" __test_visibility_distance = 1000 __test_dewpoint = 300.0 __test_humidex = 298.0 __test_heat_index = 40.0 __test_instance = Weather(__test_reference_time, __test_sunset_time, __test_sunrise_time, __test_clouds, __test_rain, __test_snow, __test_wind, __test_humidity, __test_pressure, __test_temperature, __test_status, __test_detailed_status, __test_weather_code, __test_weather_icon_name, __test_visibility_distance, __test_dewpoint, __test_humidex, __test_heat_index) def test_init_fails_when_negative_data_provided(self): self.assertRaises(ValueError, Weather, -9876543210, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, -45, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, -16, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, -12, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, -10.0, self.__test_heat_index) self.assertRaises(ValueError, Weather, self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, -10.0) def test_init_when_wind_is_none(self): instance = Weather(self.__test_reference_time, self.__test_sunset_time, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, None, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.get_wind()) def test_init_stores_negative_sunset_time_as_none(self): instance = Weather(self.__test_reference_time, -9876543210, self.__test_sunrise_time, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.get_sunset_time()) def test_init_stores_negative_sunrise_time_as_none(self): instance = Weather(self.__test_reference_time, self.__test_sunset_time, -9876543210, self.__test_clouds, self.__test_rain, self.__test_snow, self.__test_wind, self.__test_humidity, self.__test_pressure, self.__test_temperature, self.__test_status, self.__test_detailed_status, self.__test_weather_code, self.__test_weather_icon_name, self.__test_visibility_distance, self.__test_dewpoint, self.__test_humidex, self.__test_heat_index) self.assertIsNone(instance.get_sunrise_time()) def test_from_dictionary(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'visibility': {'distance': 1000}, 'calc':{ 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 } } dict2 = {"dt": 1378897200, "temp": {"day": 289.37, "min": 284.88, "max": 289.37, "night": 284.88, "eve": 287.53, "morn": 289.37 }, "pressure": 1025.35, "humidity": 71, "weather": [ {"id": 500, "main": "Rain", "description": "light rain", "icon": "u10d"} ], "speed": 3.76, "deg": 338, "clouds": 48, "rain": 3 } dict3 = {"station":{ "name":"KPPQ", "type":1, "status":50, "id":1000, "coord":{"lon":-90.47,"lat":39.38} }, "last":{ "main":{ "temp":276.15, "pressure":1031}, "wind":{ "speed":3.1, "deg":140 }, "visibility":{ "distance":11265, "prefix":0 }, "calc":{ "dewpoint":273.15 }, "clouds":[ {"distance":427, "condition":"SCT"} ], "dt":1417977300 }, "params":["temp","pressure","wind","visibility"] } result1 = weather_from_dictionary(dict1) self.assertTrue(isinstance(result1, Weather)) self.assertTrue(all(v is not None for v in result1.__dict__.values())) result2 = weather_from_dictionary(dict2) self.assertTrue(isinstance(result2, Weather)) self.assertFalse(all(v is not None for v in result2.__dict__.values())) result3 = weather_from_dictionary(dict3) self.assertTrue(isinstance(result3, Weather)) def test_from_dictionary_when_data_fields_are_none(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': None, 'visibility': {'distance': 1000}, 'calc':{ 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 }, 'rain': None, 'snow': None } result1 = weather_from_dictionary(dict1) self.assertTrue(isinstance(result1, Weather)) self.assertEquals(0, len(result1.get_wind())) self.assertEquals(0, len(result1.get_rain())) self.assertEquals(0, len(result1.get_snow())) dict2 = {"station":{ "name":"KPPQ", "type":1, "status":50, "id":1000, "coord":{"lon":-90.47,"lat":39.38} }, "last":{ "main":{ "temp":276.15, "pressure":1031}, "wind":None, "visibility":{ "distance":11265, "prefix":0 }, "calc":{ "dewpoint":273.15 }, "clouds":[ {"distance":427, "condition":"SCT"} ], "dt":1417977300 }, "params":["temp","pressure","wind","visibility"] } result2 = weather_from_dictionary(dict2) self.assertTrue(isinstance(result2, Weather)) self.assertEquals(0, len(result2.get_wind())) def test_getters_return_expected_data(self): self.assertEqual(self.__test_instance.get_reference_time(), self.__test_reference_time) self.assertEqual(self.__test_instance.get_sunset_time(), self.__test_sunset_time) self.assertEqual(self.__test_instance.get_sunrise_time(), self.__test_sunrise_time) self.assertEqual(self.__test_instance.get_clouds(), self.__test_clouds) self.assertEqual(self.__test_instance.get_rain(), self.__test_rain) self.assertEqual(self.__test_instance.get_snow(), self.__test_snow) self.assertEqual(self.__test_instance.get_wind(), self.__test_wind) self.assertEqual(self.__test_instance.get_humidity(), self.__test_humidity) self.assertEqual(self.__test_instance.get_pressure(), self.__test_pressure) self.assertEqual(self.__test_instance.get_temperature(), self.__test_temperature) self.assertEqual(self.__test_instance.get_status(), self.__test_status) self.assertEqual(self.__test_instance.get_detailed_status(), self.__test_detailed_status) self.assertEqual(self.__test_instance.get_weather_code(), self.__test_weather_code) self.assertEqual(self.__test_instance.get_weather_icon_name(), self.__test_weather_icon_name) self.assertEqual(self.__test_instance.get_visibility_distance(), self.__test_visibility_distance) self.assertEqual(self.__test_instance.get_dewpoint(), self.__test_dewpoint) self.assertEqual(self.__test_instance.get_humidex(), self.__test_humidex) self.assertEqual(self.__test_instance.get_heat_index(), self.__test_heat_index) def test_get_reference_time_returning_different_formats(self): self.assertEqual(self.__test_instance.get_reference_time(timeformat='iso'), self.__test_iso_reference_time) self.assertEqual(self.__test_instance.get_reference_time(timeformat='unix'), self.__test_reference_time) self.assertEqual(self.__test_instance.get_reference_time(timeformat='date'), self.__test_date_reference_time) def test_get_sunset_time_returning_different_formats(self): self.assertEqual(self.__test_instance.get_sunset_time(timeformat='iso'), self.__test_iso_sunset_time) self.assertEqual(self.__test_instance.get_sunset_time(timeformat='unix'), self.__test_sunset_time) def test_get_sunrise_time_returning_different_formats(self): self.assertEqual(self.__test_instance.get_sunrise_time(timeformat='iso'), self.__test_iso_sunrise_time) self.assertEqual(self.__test_instance.get_sunrise_time(timeformat='unix'), self.__test_sunrise_time) def test_get_reference_time_fails_with_unknown_timeformat(self): self.assertRaises(ValueError, Weather.get_reference_time, self.__test_instance, 'xyz') def test_get_sunset_time_fails_with_unknown_timeformat(self): self.assertRaises(ValueError, Weather.get_sunset_time, self.__test_instance, 'xyz') def test_get_sunrise_time_fails_with_unknown_timeformat(self): self.assertRaises(ValueError, Weather.get_sunrise_time, self.__test_instance, 'xyz') def test_returning_different_units_for_temperatures(self): result_kelvin = self.__test_instance.get_temperature(unit='kelvin') result_celsius = self.__test_instance.get_temperature(unit='celsius') result_fahrenheit = self.__test_instance.get_temperature( unit='fahrenheit') for item in self.__test_temperature: self.assertAlmostEqual(result_kelvin[item], self.__test_temperature[item], delta=0.1) self.assertAlmostEqual(result_celsius[item], self.__test_celsius_temperature[item], delta=0.1) self.assertAlmostEqual(result_fahrenheit[item], self.__test_fahrenheit_temperature[item], delta=0.1) def test_get_temperature_fails_with_unknown_units(self): self.assertRaises(ValueError, Weather.get_temperature, self.__test_instance, 'xyz') def test_returning_different_units_for_wind_values(self): result_imperial = self.__test_instance.get_wind(unit='miles_hour') result_metric = self.__test_instance.get_wind(unit='meters_sec') result_unspecified = self.__test_instance.get_wind() self.assertEqual(result_unspecified, result_metric) for item in self.__test_wind: self.assertEqual(result_metric[item], self.__test_wind[item]) self.assertEqual(result_imperial[item], self.__test_imperial_wind[item]) def test_get_wind_fails_with_unknown_units(self): self.assertRaises(ValueError, Weather.get_wind, self.__test_instance, 'xyz') # Test JSON and XML comparisons by ordering strings (this overcomes # interpeter-dependant serialization of XML/JSON objects) def test_to_JSON(self): ordered_base_json = ''.join(sorted(WEATHER_JSON_DUMP)) ordered_actual_json = ''.join(sorted(self.__test_instance.to_JSON())) self.assertEqual(ordered_base_json, ordered_actual_json) '''