Example #1
0
    def test_search_quick(self):
        """Perform search and check found caches"""
        rect = Rectangle(Point(49.73, 13.38), Point(49.74, 13.40))
        caches = list(self.g.search_quick(rect))
        strict_caches = list(self.g.search_quick(rect, strict=True))
        precise_caches = list(self.g.search_quick(rect, precision=45.))

        # Check for known geocaches
        expected = ["GC41FJC", "GC17E8Y", "GC5ND9F"]
        for i in expected:
            found = False
            for c in caches:
                if c.wp == i:
                    found = True
                    break
            with self.subTest("Check if {} is in results".format(c.wp)):
                self.assertTrue(found)

        with self.subTest("Precision is in assumed range"):
            self.assertLess(caches[0].location.precision, 49.5)
            self.assertGreater(caches[0].location.precision, 49.3)

        with self.subTest("Found roughly correct amount of caches"):
            # At time of writing, there were 108 caches inside inspected tile
            self.assertLess(len(caches), 130)
            self.assertGreater(len(caches), 90)

        with self.subTest("Strict handling of cache coordinates"):
            # ...but only 12 inside this stricter area
            self.assertLess(len(strict_caches), 16)
            self.assertGreater(len(strict_caches), 7)

        with self.subTest("Precision grows when asking for it"):
            self.assertLess(precise_caches[0].location.precision, 45.)
Example #2
0
    def test_search_quick(self):
        """Perform search and check found caches"""
        # at time of writing, there were exactly 16 caches in this area + one PM only
        expected_cache_num = 16
        tolerance = 7
        rect = Rectangle(Point(49.73, 13.38), Point(49.74, 13.40))

        with self.subTest("normal"):
            res = [c.wp for c in self.g.search_quick(rect)]
            for wp in ["GC41FJC", "GC17E8Y", "GC5ND9F"]:
                self.assertIn(wp, res)
            # but 108 caches larger tile
            self.assertLess(len(res), 130)
            self.assertGreater(len(res), 90)

        with self.subTest("strict handling of cache coordinates"):
            res = list(self.g.search_quick(rect, strict=True))
            self.assertLess(len(res), expected_cache_num + tolerance)
            self.assertGreater(len(res), expected_cache_num - tolerance)

        with self.subTest("larger zoom - more precise"):
            res1 = list(self.g.search_quick(rect, strict=True, zoom=15))
            res2 = list(self.g.search_quick(rect, strict=True, zoom=14))
            for res in res1, res2:
                self.assertLess(len(res), expected_cache_num + tolerance)
                self.assertGreater(len(res), expected_cache_num - tolerance)
            for c1, c2 in itertools.product(res1, res2):
                self.assertLess(c1.location.precision, c2.location.precision)
Example #3
0
    def test_search_quick(self):
        """Perform quick search and check found caches"""
        # at time of writing, there were exactly 16 caches in this area + one PM only
        expected_cache_num = 16
        tolerance = 7
        rect = Rectangle(Point(49.73, 13.38), Point(49.74, 13.40))

        with self.subTest("normal"):
            with self.recorder.use_cassette('geocaching_quick_normal'):
                # Once this feature is fixed, the corresponding cassette will have to be deleted
                # and re-recorded.
                res = [c.wp for c in self.gc.search_quick(rect)]
            for wp in ["GC41FJC", "GC17E8Y", "GC383XN"]:
                self.assertIn(wp, res)
            # but 108 caches larger tile
            self.assertLess(len(res), 130)
            self.assertGreater(len(res), 90)

        with self.subTest("strict handling of cache coordinates"):
            with self.recorder.use_cassette('geocaching_quick_strictness'):
                res = list(self.gc.search_quick(rect, strict=True))
            self.assertLess(len(res), expected_cache_num + tolerance)
            self.assertGreater(len(res), expected_cache_num - tolerance)

        with self.subTest("larger zoom - more precise"):
            with self.recorder.use_cassette('geocaching_quick_zoom'):
                res1 = list(self.gc.search_quick(rect, strict=True, zoom=15))
                res2 = list(self.gc.search_quick(rect, strict=True, zoom=14))
            for res in res1, res2:
                self.assertLess(len(res), expected_cache_num + tolerance)
                self.assertGreater(len(res), expected_cache_num - tolerance)
            for c1, c2 in itertools.product(res1, res2):
                self.assertLess(c1.location.precision, c2.location.precision)
Example #4
0
    def test_search(self):
        with self.subTest("normal"):
            expected = ["GC41FJC", "GC17E8Y", "GC5ND9F"]
            caches = self.g.search(Point(49.733867, 13.397091), 3)
            for cache in caches:
                self.assertIn(cache.wp, expected)

        with self.subTest("pagging"):
            caches = list(self.g.search(Point(49.733867, 13.397091), 25))
            self.assertNotEqual(caches[0], caches[20])
Example #5
0
 def test_search_quick_match_load(self):
     """Test if search results matches exact cache locations."""
     rect = Rectangle(Point(49.73, 13.38), Point(49.74, 13.39))
     caches = list(self.g.search_quick(rect, strict=True, zoom=15))
     for cache in caches:
         try:
             cache.load()
             self.assertIn(cache.location, rect)
         except PMOnlyException:
             pass
Example #6
0
    def test_from_string(self):
        with self.subTest("normal"):
            self.assertEqual(Point.from_string("N 49 45.123 E 013 22.123"), Point(49.75205, 13.36872))

        with self.subTest("south and west"):
            self.assertEqual(Point.from_string("S 49 45.123 W 013 22.123"), Point(-48.24795, -12.63128))

        with self.subTest("letter together"):
            self.assertEqual(Point.from_string("N49 45.123 E013 22.123"), Point(49.75205, 13.36872))

        with self.subTest("letter after"):
            self.assertEqual(Point.from_string("49N 45.123 013E 22.123"), Point(49.75205, 13.36872))

        with self.subTest("south and west letter after"):
            self.assertEqual(Point.from_string("49S 45.123 013W 22.123"), Point(-48.24795, -12.63128))

        with self.subTest("decimal separator: coma"):
            self.assertEqual(Point.from_string("N 49 45,123 E 013 22,123"), Point(49.75205, 13.36872))

        with self.subTest("degree symbol"):
            self.assertEqual(Point.from_string("N 49° 45.123 E 013° 22.123"), Point(49.75205, 13.36872))

        with self.subTest("coma between lat and lon"):
            self.assertEqual(Point.from_string("N 49 45.123, E 013 22.123"), Point(49.75205, 13.36872))

        with self.subTest("marginal values: zeroes"):
            self.assertEqual(Point.from_string("N 49 45.000 E 13 0.0"), Point(49.75, 13.0))

        with self.assertRaises(ValueError):
            Point.from_string("123")
Example #7
0
 def test_calculate_initial_tiles(self):
     expect_tiles = [(2331, 1185, 12), (2331, 1186, 12), (2332, 1185, 12),
                     (2332, 1186, 12)]
     expect_precision = 76.06702024121832
     r = Rectangle(Point(60.15, 24.95), Point(60.17, 25.00))
     tiles, starting_precision = self.g._calculate_initial_tiles(r)
     for t in tiles:
         with self.subTest("Tile {} expected as initial tile".format(t)):
             self.assertIn(t, expect_tiles)
     with self.subTest("Expected precision"):
         self.assertAlmostEqual(starting_precision, expect_precision)
Example #8
0
    def test_search(self):
        with self.subTest("normal"):
            expected = ["GC41FJC", "GC17E8Y", "GC1ZAQV"]
            caches = self.g.search(Point(49.733867, 13.397091), len(expected))
            for wp, cache in zip(expected, caches):
                self.assertEqual(wp, cache.wp)

        with self.subTest("pagging"):
            caches = self.g.search(Point(49.733867, 13.397091), 25)
            res = [c for c in caches]
            self.assertNotEqual(res[0], res[20])
Example #9
0
    def test_search(self):
        with self.subTest("normal"):
            tolerance = 2
            expected = {"GC5VJ0P", "GC41FJC", "GC50AQ6", "GC167Y7", "GC7RR74", "GC167Y7"}
            with self.recorder.use_cassette("geocaching_search"):
                found = {cache.wp for cache in self.gc.search(Point(49.733867, 13.397091), 20)}
            self.assertGreater(len(expected & found), len(expected) - tolerance)

        with self.subTest("pagging"):
            with self.recorder.use_cassette("geocaching_search_pagination"):
                caches = list(self.gc.search(Point(49.733867, 13.397091), 100))
            self.assertNotEqual(caches[0], caches[50])
Example #10
0
 def test_search_quick_match_load(self):
     """Test if quick search results matches exact cache locations."""
     rect = Rectangle(Point(49.73, 13.38), Point(49.74, 13.39))
     with self.recorder.use_cassette('geocaching_matchload'):
         # at commit time, this test is an allowed failure. Once this feature is fixed, the
         # corresponding cassette will have to be deleted and re-recorded.
         caches = list(self.gc.search_quick(rect, strict=True, zoom=15))
         for cache in caches:
             try:
                 cache.load()
                 self.assertIn(cache.location, rect)
             except PMOnlyException:
                 pass
Example #11
0
    def test_to_map_tile(self):
        t = (8800, 5574, 14)
        point_in_t = Point(49.75, 13.36)

        with self.subTest("From tile and back"):
            self.assertEqual(Point.from_tile(*t).to_map_tile(t[-1]), t)

        with self.subTest("Random point"):
            self.assertEqual(point_in_t.to_map_tile(14), t)

        with self.subTest("Increase in latitude: decrease in y value"):
            self.assertLess(Point(50., 13.36).to_map_tile(14)[1], t[1])

        with self.subTest("Increase in longitude: increase in x value"):
            self.assertGreater(Point(49.75, 14.).to_map_tile(14)[0], t[0])
Example #12
0
 def setUp(self):
     self.gc = Geocaching()
     self.t = Trackable("TB1234", self.gc, name="TrackMe")
     self.c = Cache("GC12345",
                    self.gc,
                    name="Testing",
                    cache_type="Traditional Cache",
                    location=Point(),
                    state=True,
                    found=False,
                    size="micro",
                    difficulty=1.5,
                    terrain=5,
                    author="human",
                    hidden=date(2000, 1, 1),
                    attributes={
                        "onehour": True,
                        "kids": False,
                        "available": True
                    },
                    summary="text",
                    description="long text",
                    hint="rot13",
                    favorites=0,
                    pm_only=False,
                    trackables=self.t)
Example #13
0
    def test_from_tile(self):
        """Test coordinate creation from tile"""
        p = Point.from_tile(8800, 5574, 14)
        p_pos = Point(49.752879934150215, 13.359375, 0.0)
        p2 = Point.from_tile(x=8801, y=5575, z=14)
        p_half = Point.from_tile(8800, 5574, 14, 1, 1, 2)

        # Check creation
        for att in ['latitude', 'longitude']:
            with self.subTest("Assumed location: {}".format(att)):
                self.assertAlmostEqual(getattr(p, att), getattr(p_pos, att))

        with self.subTest("Fractional tiles: y-axis addition"):
            self.assertEqual(Point.from_tile(8800, 5574, 14, 0, 32, 32),
                             Point.from_tile(x=8800, y=5575, z=14))
        with self.subTest("Fractional tiles: x-axis addition"):
            self.assertAlmostEqual(Point.from_tile(8800, 5574, 14, 32, 0, 32),
                                   Point.from_tile(x=8801, y=5574, z=14))
        with self.subTest("Fractional tiles: addition on both axes"):
            self.assertEqual(Point.from_tile(8800, 5574, 14, 32, 32, 32), p2)

        with self.subTest("y increases -> latitude decreases"):
            self.assertGreater(p.latitude, p_half.latitude)
        with self.subTest("x increases -> latitude increases"):
            self.assertLess(p.longitude, p_half.longitude)
Example #14
0
    def test_search(self):
        with self.subTest("normal"):
            tolerance = 2
            expected = {
                "GC5VJ0P", "GC41FJC", "GC17E8Y", "GC14AV5", "GC50AQ6",
                "GC167Y7"
            }
            found = {
                cache.wp
                for cache in self.g.search(Point(49.733867, 13.397091), 20)
            }
            self.assertGreater(len(expected & found),
                               len(expected) - tolerance)

        with self.subTest("pagging"):
            caches = list(self.g.search(Point(49.733867, 13.397091), 100))
            self.assertNotEqual(caches[0], caches[50])
Example #15
0
    def test_recover_from_rate_limit(self):
        """Test recovering from API rate limit exception."""
        rect = Rectangle(Point(50.74, 13.38), Point(49.73, 14.40))  # large rectangle

        with self.recorder.use_cassette("geocaching_api_rate_limit") as vcr:
            orig_wait_for = TooManyRequestsError.wait_for

            with patch.object(TooManyRequestsError, "wait_for", autospec=True) as wait_for:
                # If we are recording, we must perform real wait, otherwise we skip waiting
                wait_for.side_effect = orig_wait_for if vcr.current_cassette.is_recording() else None

                for i, _cache in enumerate(self.gc.search_rect(rect, per_query=1)):
                    if wait_for.called:
                        self.assertEqual(wait_for.call_count, 1)
                        break

                    if i > 20:  # rate limit should be released after ~10 requests
                        self.fail("API Rate Limit not released")
Example #16
0
 def setUp(self):
     self.gc = Geocaching()
     self.t = Trackable("TB123AB",
                        self.gc,
                        name="Testing",
                        type="Travel Bug",
                        location=Point(),
                        owner="human",
                        description="long text",
                        goal="short text")
Example #17
0
    def test_search_rect(self):
        """Perform search by rect and check found caches."""
        rect = Rectangle(Point(49.73, 13.38), Point(49.74, 13.39))

        expected = {"GC1TYYG", "GC11PRW", "GC7JRR5", "GC161KR", "GC1GW54", "GC7KDWE", "GC93HA6", "GCZC5D"}

        orig_wait_for = TooManyRequestsError.wait_for
        with self.recorder.use_cassette("geocaching_search_rect") as vcr:
            with patch.object(TooManyRequestsError, "wait_for", autospec=True) as wait_for:
                wait_for.side_effect = orig_wait_for if vcr.current_cassette.is_recording() else None

                with self.subTest("default use"):
                    caches = self.gc.search_rect(rect)
                    waypoints = {cache.wp for cache in caches}
                    self.assertSetEqual(waypoints, expected)

                with self.subTest("sort by distance"):
                    with self.assertRaises(AssertionError):
                        caches = list(self.gc.search_rect(rect, sort_by="distance"))

                    origin = Point.from_string("N 49° 44.230 E 013° 22.858")
                    caches = list(self.gc.search_rect(rect, sort_by=SortOrder.distance, origin=origin))
                    waypoints = {cache.wp for cache in caches}
                    self.assertSetEqual(waypoints, expected)

                    # Check if caches are sorted by distance to origin
                    distances = []
                    for cache in caches:
                        try:
                            distances.append(great_circle(cache.location, origin).meters)
                        except PMOnlyException:
                            # can happend when getting accurate location
                            continue
                    self.assertEqual(distances, sorted(distances))

                with self.subTest("sort by different criteria"):
                    for sort_by in SortOrder:
                        if sort_by is SortOrder.distance:
                            continue
                        caches = self.gc.search_rect(rect, sort_by=sort_by)
                        waypoints = {cache.wp for cache in caches}
                        self.assertSetEqual(waypoints, expected)
Example #18
0
    def test_location(self):
        self.assertEqual(self.c.location, Point())

        with self.subTest("automatic str conversion"):
            self.c.location = "S 36 51.918 E 174 46.725"
            self.assertEqual(self.c.location,
                             Point.from_string("S 36 51.918 E 174 46.725"))

        with self.subTest("filter invalid"):
            with self.assertRaises(ValueError):
                self.c.location = "somewhere"
Example #19
0
    def test_recover_from_rate_limit_without_sleep(self):
        """Test recovering from API rate limit exception without sleep."""
        rect = Rectangle(Point(50.74, 13.38), Point(49.73, 14.40))

        with self.recorder.use_cassette('geocaching_api_rate_limit_with_none') as vcr:
            with patch.object(TooManyRequestsError, 'wait_for', autospec=True) as wait_for:
                caches = self.gc.search_rect(rect, per_query=1, wait_sleep=False)
                for i, cache in enumerate(caches):
                    if cache is None:
                        import time
                        while cache is None:
                            if vcr.current_cassette.is_recording():
                                time.sleep(10)
                            cache = next(caches)
                        self.assertIsInstance(cache, Cache)
                        break

                    if i > 20:
                        self.fail("API Rate Limit not released")

                self.assertEqual(wait_for.call_count, 0)
Example #20
0
    def test_search_rect(self):
        """Perform search by rect and check found caches."""
        rect = Rectangle(Point(49.73, 13.38), Point(49.74, 13.39))

        expected = {'GC1TYYG', 'GC11PRW', 'GC7JRR5', 'GC161KR', 'GC1GW54', 'GC7KDWE', 'GC8D303'}

        orig_wait_for = TooManyRequestsError.wait_for
        with self.recorder.use_cassette('geocaching_search_rect') as vcr:
            with patch.object(TooManyRequestsError, 'wait_for', autospec=True) as wait_for:
                wait_for.side_effect = orig_wait_for if vcr.current_cassette.is_recording() else None
                with self.subTest("default use"):
                    caches = self.gc.search_rect(rect)
                    waypoints = {cache.wp for cache in caches}

                    self.assertSetEqual(waypoints, expected)

                with self.subTest("sort by distance"):
                    with self.assertRaises(AssertionError):
                        caches = list(self.gc.search_rect(rect, sort_by='distance'))

                    origin = Point.from_string('N 49° 44.230 E 013° 22.858')

                    caches = list(self.gc.search_rect(rect, sort_by=SortOrder.distance, origin=origin))

                    waypoints = [cache.wp for cache in caches]
                    self.assertEqual(waypoints,  [
                        'GC11PRW', 'GC1TYYG', 'GC7JRR5', 'GC1GW54', 'GC161KR', 'GC7KDWE', 'GC8D303'
                    ])

                    # Check if caches are sorted by distance to origin
                    distances = [great_circle(cache.location, origin).meters for cache in caches]
                    self.assertEqual(distances, sorted(distances))

                with self.subTest("sort by different criteria"):
                    for sort_by in SortOrder:
                        if sort_by is SortOrder.distance:
                            continue
                        caches = self.gc.search_rect(rect, sort_by=sort_by)
                        waypoints = {cache.wp for cache in caches}
                        self.assertSetEqual(waypoints, expected)
Example #21
0
    def test_precision_from_tile_zoom(self):
        p = Point(49.75, 13.36)

        with self.subTest("Random point"):
            self.assertAlmostEqual(p.precision_from_tile_zoom(14),
                                   6.173474613462484)

        with self.subTest("Precision is larger on greater Z values"):
            self.assertGreater(p.precision_from_tile_zoom(13),
                               p.precision_from_tile_zoom(14))

        with self.subTest("Precision is larger when tile is divided less"):
            self.assertGreater(p.precision_from_tile_zoom(14, 10),
                               p.precision_from_tile_zoom(14, 100))
Example #22
0
    def test_geocode(self):
        pilsen = Point(49.74774, 13.37752)
        with self.subTest("existing location"):
            self.assertEqual(self.g.geocode("Pilsen"), pilsen)
            self.assertEqual(self.g.geocode("Plzeň"), pilsen)
            self.assertEqual(self.g.geocode("plzen"), pilsen)

        with self.subTest("non-existing location"):
            with self.assertRaises(GeocodeError):
                self.g.geocode("qwertzuiop")

        with self.subTest("empty request"):
            with self.assertRaises(GeocodeError):
                self.g.geocode("")
Example #23
0
    def test_get_zoom_by_distance(self):
        """Check that calculated zoom levels are correct"""
        with self.subTest("World map zoom level"):
            self.assertEqual(self.g._get_zoom_by_distance(40e6, 0., 1., 'le'),
                             0)

        with self.subTest("Next level"):
            self.assertEqual(self.g._get_zoom_by_distance(40e6, 0., 1., 'ge'),
                             1)

        with self.subTest("Tile width greater or equal to 1 km"):
            self.assertEqual(self.g._get_zoom_by_distance(1e3, 49., 1., 'le'),
                             14)

        with self.subTest("More accurate than 10 m"):
            self.assertEqual(self.g._get_zoom_by_distance(10., 49., 256, 'ge'),
                             14)

        with self.subTest("Previous test was correct"):
            p = Point(49., 13.)
            self.assertGreater(p.precision_from_tile_zoom(13), 10)
            self.assertLess(p.precision_from_tile_zoom(14), 10)
Example #24
0
 def test_geocode(self):
     ref_point = Point(50.08746, 14.42125)
     with self.recorder.use_cassette('geocaching_shortcut_geocode'):
         self.assertLess(
             great_circle(self.gc.geocode("Prague"), ref_point).miles, 10)
Example #25
0
 def test_distance(self):
     p1, p2 = Point(60.15, 24.95), Point(60.17, 25.00)
     self.assertAlmostEqual(p1.distance(p2), 3560.1077441805196)
Example #26
0
 def test_geocode(self):
     ref_point = Point(49.74774, 13.37752)
     self.assertLess(great_circle(self.g.geocode("Pilsen"), ref_point).miles, 10)