1# -*- coding: utf-8 -*-
2import pytz
3from pytest import raises, approx
4
5import astral.geocoder
6
7
8def location_count(name, locations):
9    return len(list(filter(lambda item: item.name == name, locations)))
10
11
12class TestDatabase:
13    """Test database access functions"""
14
15    def test_all_locations(self, test_database):
16        for loc in astral.geocoder.all_locations(test_database):
17            assert loc.name
18
19        location_list = astral.geocoder.all_locations(test_database)
20        all_locations = list(location_list)
21        assert location_count("London", all_locations) == 1
22        assert location_count("Abu Dhabi", all_locations) == 2
23
24    def test_lookup(self, test_database):
25        loc = astral.geocoder.lookup("London", test_database)
26        assert loc.name == "London"
27        assert loc.region == "England"
28        assert loc.latitude == approx(51.4733, abs=0.001)
29        assert loc.longitude == approx(-0.0008333, abs=0.000001)
30        tz = pytz.timezone("Europe/London")
31        tzl = pytz.timezone(loc.timezone)
32        assert tz == tzl
33
34    def test_city_in_db(self, test_database):
35        astral.geocoder.lookup("london", test_database)
36
37    def test_group_in_db(self, test_database):
38        astral.geocoder.lookup("africa", test_database)
39
40    def test_location_not_in_db(self, test_database):
41        with raises(KeyError):
42            astral.geocoder.lookup("Nowhere", test_database)
43
44    def test_group_not_in_db(self, test_database):
45        with raises(KeyError):
46            astral.geocoder.group("wallyland", test_database)
47
48    def test_lookup_city_and_region(self, test_database):
49        city_name = "Birmingham,England"
50
51        city = astral.geocoder.lookup(city_name, test_database)
52        assert city.name == "Birmingham"
53        assert city.region == "England"
54
55    def test_country_with_multiple_entries_no_country(self, test_database):
56        city = astral.geocoder.lookup("Abu Dhabi", test_database)
57        assert city.name == "Abu Dhabi"
58
59    def test_country_with_multiple_entries_with_country(self, test_database):
60        """Test for fix made due to bug report from Klaus Alexander Seistrup"""
61
62        city = astral.geocoder.lookup("Abu Dhabi,United Arab Emirates", test_database)
63        assert city.name == "Abu Dhabi"
64
65        city = astral.geocoder.lookup("Abu Dhabi,UAE", test_database)
66        assert city.name == "Abu Dhabi"
67
68
69class TestBugReports:
70    """Test for bug report fixes"""
71
72    def test_Adelaide(self, test_database):
73        """Test for fix made due to bug report from Klaus Alexander Seistrup"""
74
75        astral.geocoder.lookup("Adelaide", test_database)
76
77    def test_CandianCities(self, test_database):
78        astral.geocoder.lookup("Fredericton", test_database)
79
80
81class TestDatabaseAddLocations:
82    """Test adding locations to database"""
83
84    def test_newline_at_end(self, test_database):
85        count = astral.geocoder._location_count(test_database)
86        astral.geocoder.add_locations(
87            "A Place,A Region,Asia/Nicosia,35°10'N,33°25'E,162.0\n", test_database
88        )
89        assert astral.geocoder._location_count(test_database) == count + 1
90
91    def test_from_list_of_strings(self, test_database):
92        count = astral.geocoder._location_count(test_database)
93        astral.geocoder.add_locations(
94            [
95                "A Place,A Region,Asia/Nicosia,35°10'N,33°25'E,162.0",
96                "Another Place,Somewhere else,Asia/Nicosia,35°10'N,33°25'E,162.0",
97            ],
98            test_database,
99        )
100        assert astral.geocoder._location_count(test_database) == count + 2
101
102    def test_from_list_of_lists(self, test_database):
103        count = astral.geocoder._location_count(test_database)
104        astral.geocoder.add_locations(
105            [
106                ["A Place", "A Region", "Asia/Nicosia", "35°10'N", "33°25'E", "162.0"],
107                [
108                    "Another Place",
109                    "Somewhere else",
110                    "Asia/Nicosia",
111                    "35°10'N",
112                    "33°25'E",
113                    "162.0",
114                ],
115            ],
116            test_database,
117        )
118        assert astral.geocoder._location_count(test_database) == count + 2
119
120
121def test_SanitizeKey():
122    assert astral.geocoder._sanitize_key("Los Angeles") == "los_angeles"
123