def setUpClass(cls): # preparations which have to be made only once print("\nSTARTING PACKAGE TESTS\n\n") cls.print_tf_class_props(cls) global in_memory_mode in_memory_mode = cls.in_memory_mode t = timeit.timeit("TimezoneFinder(in_memory=in_memory_mode)", globals=globals(), number=1) print('startup time:', time_preprocess(t), '\n') cls.timezone_finder = TimezoneFinder(in_memory=cls.in_memory_mode) # create an array of points where timezone_finder finds something (realistic queries) print('collecting and storing', N, 'realistic points for the tests...') cls.realistic_points = [] ps_for_10percent = int(N / 10) percent_done = 0 i = 0 while i < N: lng, lat = random_point() # a realistic point is a point where certain_timezone_at() finds something if cls.timezone_finder.certain_timezone_at(lng=lng, lat=lat): i += 1 cls.realistic_points.append((lng, lat)) if i % ps_for_10percent == 0: percent_done += 10 print(percent_done, '%') print("Done.\n")
def setUpClass(cls): # preparations which have to be made only once cls.print_tf_class_props(cls) global in_memory_mode, class_under_test in_memory_mode = cls.in_memory_mode class_under_test = cls.class_under_test t = timeit.timeit("class_under_test(in_memory=in_memory_mode)", globals=globals(), number=10) print('startup time:', time_preprocess(t), '\n') cls.test_instance = cls.class_under_test(bin_file_location=cls.bin_file_dir, in_memory=cls.in_memory_mode) # create an array of points where timezone_finder finds something (realistic queries) print('collecting and storing', N, 'realistic points for the tests...') cls.realistic_points = [] ps_for_10percent = int(N / 10) percent_done = 0 i = 0 realistic_pt_fct = getattr(cls.test_instance, cls.realistic_pt_fct_name) while i < N: lng, lat = random_point() # a realistic point is a point where certain_timezone_at() finds something if realistic_pt_fct(lng=lng, lat=lat): i += 1 cls.realistic_points.append((lng, lat)) if i % ps_for_10percent == 0: percent_done += 10 print(percent_done, '%') print("Done.\n")
def test_distance_computation(self): distance_to_point_on_equator = self.fct_dict[ 'distance_to_point_on_equator'] haversine = self.fct_dict['haversine'] coord2int = self.fct_dict['coord2int'] distance_to_polygon_exact = self.fct_dict['distance_to_polygon_exact'] distance_to_polygon = self.fct_dict['distance_to_polygon'] if distance_to_point_on_equator is None: print('test distance computation skipped.') return def km2rad(km): return km / 6371 def km2deg(km): return degrees(km2rad(km)) p_test_cases = [ # (x,y), (0, 1), (1, 0), (0, -1), (-1, 0), # on the line test cases # (-0.5, 0.5), # (0, 0.5), # (-0.5, 0), # (0.5, 0), ] p1_lng_rad = radians(0.0) p1_lat_rad = radians(0.0) for x, y in p_test_cases: result = distance_to_point_on_equator(radians(x), radians(y), p1_lng_rad) if km2deg(result) != 1: raise AssertionError('should be equal:', km2deg(result), 1) hav_result = haversine(radians(x), radians(y), p1_lng_rad, 0) if km2deg(hav_result) != 1.0: raise AssertionError('should be equal:', km2deg(hav_result), 1.0) for i in range(1000): rnd_point = random_point() lng_rnd_point2 = random_point()[0] hav_result = degrees( haversine(radians(rnd_point[0]), radians(rnd_point[1]), lng_rnd_point2, 0)) result = degrees( distance_to_point_on_equator(radians(rnd_point[0]), radians(rnd_point[1]), lng_rnd_point2)) self.assertAlmostEqual(hav_result, result, places=DECIMAL_PLACES_ACCURACY) # if abs(hav_result - result) > 0.000001: # raise AssertionError(i, 'should be equal:', hav_result, result, rnd_point, lng_rnd_point2) x_coords = [0.5, -0.5, -0.5, 0.5] y_coords = [0.5, 0.5, -0.5, -0.5] points = [ [coord2int(x) for x in x_coords], [coord2int(x) for x in y_coords], ] trans_points = [ [None for x in x_coords], [None for x in y_coords], ] x_rad = radians(1.0) y_rad = radians(0.0) # print(km2deg(haversine(x_rad, y_rad, p1_lng_rad, p1_lat_rad))) assert km2deg(haversine(x_rad, y_rad, p1_lng_rad, p1_lat_rad)) == 1 distance_exact = distance_to_polygon_exact( x_rad, y_rad, len(x_coords), np.array(points, dtype=DTYPE_FORMAT_SIGNED_I_NUMPY), np.array(trans_points, dtype=DTYPE_FORMAT_F_NUMPY)) # print(km2deg(distance_exact)) assert km2deg(distance_exact) == 0.5 # print('=====') distance = distance_to_polygon( x_rad, y_rad, len(x_coords), np.array(points, dtype=DTYPE_FORMAT_SIGNED_I_NUMPY)) # print(km2deg(distance)) assert abs(km2deg(distance) - sqrt(2) / 2) < 0.00001
def test_distance_computation(self): distance_to_point_on_equator = self.fct_dict['distance_to_point_on_equator'] haversine = self.fct_dict['haversine'] coord2int = self.fct_dict['coord2int'] distance_to_polygon_exact = self.fct_dict['distance_to_polygon_exact'] distance_to_polygon = self.fct_dict['distance_to_polygon'] if distance_to_point_on_equator is None: print('test distance computation skipped.') return def km2rad(km): return km / 6371 def km2deg(km): return degrees(km2rad(km)) p_test_cases = [ # (x,y), (0, 1), (1, 0), (0, -1), (-1, 0), # on the line test cases # (-0.5, 0.5), # (0, 0.5), # (-0.5, 0), # (0.5, 0), ] p1_lng_rad = radians(0.0) p1_lat_rad = radians(0.0) for x, y in p_test_cases: result = distance_to_point_on_equator(radians(x), radians(y), p1_lng_rad) if km2deg(result) != 1: raise AssertionError('should be equal:', km2deg(result), 1) hav_result = haversine(radians(x), radians(y), p1_lng_rad, 0) if km2deg(hav_result) != 1.0: raise AssertionError('should be equal:', km2deg(hav_result), 1.0) for i in range(1000): rnd_point = random_point() lng_rnd_point2 = random_point()[0] hav_result = degrees(haversine(radians(rnd_point[0]), radians(rnd_point[1]), lng_rnd_point2, 0)) result = degrees(distance_to_point_on_equator(radians(rnd_point[0]), radians(rnd_point[1]), lng_rnd_point2)) self.assertAlmostEqual(hav_result, result, places=DECIMAL_PLACES_ACCURACY) # if abs(hav_result - result) > 0.000001: # raise AssertionError(i, 'should be equal:', hav_result, result, rnd_point, lng_rnd_point2) x_coords = [0.5, -0.5, -0.5, 0.5] y_coords = [0.5, 0.5, -0.5, -0.5] points = [ [coord2int(x) for x in x_coords], [coord2int(x) for x in y_coords], ] trans_points = [ [None for x in x_coords], [None for x in y_coords], ] x_rad = radians(1.0) y_rad = radians(0.0) # print(km2deg(haversine(x_rad, y_rad, p1_lng_rad, p1_lat_rad))) assert km2deg(haversine(x_rad, y_rad, p1_lng_rad, p1_lat_rad)) == 1 distance_exact = distance_to_polygon_exact(x_rad, y_rad, len(x_coords), np.array(points, dtype=DTYPE_FORMAT_SIGNED_I_NUMPY), np.array(trans_points, dtype=DTYPE_FORMAT_F_NUMPY)) # print(km2deg(distance_exact)) assert km2deg(distance_exact) == 0.5 # print('=====') distance = distance_to_polygon(x_rad, y_rad, len(x_coords), np.array(points, dtype=DTYPE_FORMAT_SIGNED_I_NUMPY)) # print(km2deg(distance)) assert abs(km2deg(distance) - sqrt(2) / 2) < 0.00001
class MainPackageTest(unittest.TestCase): # do the preparations which have to be made only once print("startup time:") if TimezoneFinder.using_numba(): print('Numba: ON (precompiled functions in use)') else: print('Numba: OFF (precompiled functions NOT in use)') start_time = datetime.now() timezone_finder = TimezoneFinder() end_time = datetime.now() my_time = end_time - start_time print_time(timezoefinder_time=my_time) print('\n') # create an array of points where timezone_finder finds something (realistic queries) print('collecting and storing', N, 'realistic points for the tests...') realistic_points = [] ps_for_10percent = int(N / 10) percent_done = 0 i = 0 while i < N: lng, lat = random_point() # a realistic point is a point where certain_timezone_at() finds something if timezone_finder.certain_timezone_at(lng=lng, lat=lat): i += 1 realistic_points.append((lng, lat)) if i % ps_for_10percent == 0: percent_done += 10 print(percent_done, '%') print("Done.\n") def setUp(self): self.timezone_finder = TimezoneFinder() def test_speed(self): print("\n\nSpeed Tests:\n-------------") def check_speed_of_algorithm(list_of_points): start_time = datetime.now() for point in list_of_points: self.timezone_finder.timezone_at(lng=point[0], lat=point[1]) end_time = datetime.now() return end_time - start_time def print_speed_test(type_of_points, list_of_points): my_time = check_speed_of_algorithm(list_of_points) print('\nrequired time for ', N, type_of_points) print_time(timezoefinder_time=my_time) if TimezoneFinder.using_numba(): print('Numba: ON (timezonefinder)') else: print('Numba: OFF (timezonefinder)') print_speed_test('realistic points', self.realistic_points) print_speed_test('random points', list_of_random_points(length=N)) def test_shortcut_boundary(self): # at the boundaries of the shortcut grid (coordinate system) the algorithms should still be well defined! assert self.timezone_finder.timezone_at(lng=-180.0, lat=90.0) is None assert self.timezone_finder.timezone_at(lng=180.0, lat=90.0) is None assert self.timezone_finder.timezone_at( lng=180.0, lat=-90.0) == 'Antarctica/McMurdo' assert self.timezone_finder.timezone_at( lng=-180.0, lat=-90.0) == 'Antarctica/McMurdo' with pytest.raises(ValueError): self.timezone_finder.timezone_at(lng=180.0 + INT2COORD_FACTOR, lat=90.0) self.timezone_finder.timezone_at(lng=-180.0 - INT2COORD_FACTOR, lat=90.0 + INT2COORD_FACTOR) self.timezone_finder.timezone_at(lng=-180.0, lat=90.0 + INT2COORD_FACTOR) self.timezone_finder.timezone_at(lng=180.0 + INT2COORD_FACTOR, lat=-90.0) self.timezone_finder.timezone_at(lng=180.0, lat=-90.0 - INT2COORD_FACTOR) self.timezone_finder.timezone_at(lng=-180.0 - INT2COORD_FACTOR, lat=-90.0) self.timezone_finder.timezone_at(lng=-180.0 - INT2COORD_FACTOR, lat=-90.01 - INT2COORD_FACTOR) def test_kwargs_only(self): # calling timezonefinder fcts without keyword arguments should raise an error with pytest.raises(TypeError): self.timezone_finder.timezone_at(23.0, 42.0) self.timezone_finder.timezone_at(23.0, lng=42.0) self.timezone_finder.timezone_at(23.0, lat=42.0) def test_correctness(self): no_mistakes_made = True template = '{0:20s} | {1:20s} | {2:20s} | {3:2s}' print('\nresults timezone_at()') print(template.format('LOCATION', 'EXPECTED', 'COMPUTED', '==')) print( '====================================================================' ) for (lat, lng, loc, expected) in TEST_LOCATIONS: computed = self.timezone_finder.timezone_at(lng=lng, lat=lat) if computed == expected: ok = 'OK' else: print(lat, lng) ok = 'XX' no_mistakes_made = False print(template.format(loc, str(expected), str(computed), ok)) print('\ncertain_timezone_at():') print(template.format('LOCATION', 'EXPECTED', 'COMPUTED', 'Status')) print( '====================================================================' ) for (lat, lng, loc, expected) in TEST_LOCATIONS_CERTAIN: computed = self.timezone_finder.certain_timezone_at(lng=lng, lat=lat) if computed == expected: ok = 'OK' else: print(lat, lng) ok = 'XX' no_mistakes_made = False print(template.format(loc, str(expected), str(computed), ok)) print('\nclosest_timezone_at():') print(template.format('LOCATION', 'EXPECTED', 'COMPUTED', 'Status')) print( '====================================================================' ) print( 'testing this function does not make sense any more, because the tz polygons do not follow the shoreline' ) for (lat, lng, loc, expected) in TEST_LOCATIONS_PROXIMITY: computed = self.timezone_finder.closest_timezone_at(lng=lng, lat=lat) if computed == expected: ok = 'OK' else: print(lat, lng) ok = 'XX' no_mistakes_made = False print(template.format(loc, str(expected), str(computed), ok)) assert no_mistakes_made def test_overflow(self): longitude = -123.2 latitude = 48.4 # make numpy overflow runtime warning raise an error import numpy as np np.seterr(all='warn') import warnings warnings.filterwarnings('error') # must not raise a warning self.timezone_finder.certain_timezone_at(lat=float(latitude), lng=float(longitude))