def test_check_for_dup_layers_and_mapframs(self): cmf = CrashMoveFolder( os.path.join(self.parent_dir, 'example', 'cmf_description_relative_paths_test.json')) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_layer_properties_for_atlas.json') # Fail with multiple layer with the same name in the same mapframe. test_cookbooks = (('fixture_cookbook_with_dup_layers.json', 'mainmap_tran_por_pt_s0_allmaps'), ('fixture_cookbook_with_dup_mapframes.json', 'Main map')) for cb_filename, fail_msg in test_cookbooks: cmf.map_definitions = os.path.join(self.parent_dir, 'tests', 'testfiles', 'cookbooks', cb_filename) test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) with self.assertRaises(ValueError) as ve: MapCookbook(cmf, test_lp, verify_on_creation=True) if six.PY2: self.assertRegexpMatches(str(ve.exception), fail_msg) else: self.assertRegex(str(ve.exception), fail_msg)
def test_check_for_dup_text_elements(self): cmf = CrashMoveFolder( os.path.join(self.parent_dir, 'example', 'cmf_description_relative_paths_test.json')) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_layer_properties_for_atlas.json') # 1) Pass with "good" text elements in just one map_frame cmf.map_definitions = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_cookbook_good_with_atlas.json') test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) MapCookbook(cmf, test_lp, verify_on_creation=True) self.assertTrue(True) # 2) Fail with duplicate text elements in multiple map_frames cmf.map_definitions = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_cookbook_with_dup_text_elements.json') test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) with self.assertRaises(ValueError) as ve: MapCookbook(cmf, test_lp, verify_on_creation=True) fail_msg = 'More than one "map_frame" is linked to the Scale text element "scale"' if six.PY2: self.assertRegexpMatches(str(ve.exception), fail_msg) else: self.assertRegex(str(ve.exception), fail_msg)
def test_recipe_atlas_constructor(self): cmf = CrashMoveFolder( os.path.join(self.parent_dir, 'example', 'cmf_description_relative_paths_test.json')) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_layer_properties_for_atlas.json') # 1) atlas matches other sections 'fixture_cookbook_good_with_atlas.json' cmf.map_definitions = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_cookbook_good_with_atlas.json') test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) MapCookbook(cmf, test_lp, verify_on_creation=True) self.assertTrue(True) # 2) mismatch map_frame name 'fixture_cookbook_atlas_mismatch_map_frame.json' # 3) mismatch layer name (but present in other map frame) 'fixture_cookbook_atlas_mismatch_layer1.json' # 4) mismatch layer name, not present elsewhere in the recipe. 'fixture_cookbook_atlas_mismatch_layer2.json' # 5) mismatch column_names test_cb_names = ('fixture_cookbook_atlas_mismatch_map_frame.json', 'fixture_cookbook_atlas_mismatch_layer1.json', 'fixture_cookbook_atlas_mismatch_layer2.json', 'fixture_cookbook_atlas_mismatch_column_name.json') for test_cb in test_cb_names: cmf.map_definitions = os.path.join(self.parent_dir, 'tests', 'testfiles', 'cookbooks', test_cb) test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) with self.assertRaises(ValueError): MapCookbook(cmf, test_lp, verify_on_creation=True)
def test_zero_length_file_extention(self): test_cmf = CrashMoveFolder(self.path_to_valid_cmf_des) test_lp1 = LayerProperties(test_cmf, '', verify_on_creation=False) self.assertIsInstance(test_lp1, LayerProperties) layer_rendering_test_root = os.path.join(self.parent_dir, 'tests', 'testfiles', 'test_layer_rendering') test_cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'fixture_layer_properties_four_layers.json') test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'four_files_exact_match') test_lp2 = LayerProperties(test_cmf, '', verify_on_creation=True) self.assertIsInstance(test_lp2, LayerProperties)
def test_layer_props_and_cookbook_mismatch(self): cmf = CrashMoveFolder(self.path_to_valid_cmf_des) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'fixture_layer_properties_four_layers.json') cmf.map_definitions = os.path.join( self.parent_dir, 'tests', 'testfiles', 'fixture_cookbook_1map_4layers.json') test_lp = LayerProperties(cmf, "test", verify_on_creation=False) # 1) map_cb and lp match test_mcb = MapCookbook(cmf, test_lp, verify_on_creation=True) self.assertIsInstance(test_mcb, MapCookbook) # 2) layer in map_cb but not in lp # 3) layer in lp but not in map_cb # 4) unmatched layers in both lp and map_cb testcases = ( ('fixture_cookbook_1map_5layers.json', ("mainmap-tran-rds-ln-s0-allmaps")), ('fixture_cookbook_1map_3layers.json', ("locationmap_stle_stl_pt_s0_locationmaps")), ('fixture_cookbook_1map_mismatch_layers.json', ("mainmap-tran-rds-ln-s0-allmaps", "locationmap_stle_stl_pt_s0_locationmaps")), ) for cb_file, strings_in_ex_msg in testcases: cmf.map_definitions = os.path.join(self.parent_dir, 'tests', 'testfiles', cb_file) with self.assertRaises(ValueError) as ve: MapCookbook(cmf, test_lp, verify_on_creation=True) if six.PY2: self.assertRegexpMatches( str(ve.exception), "One or more layer names occur in only one of these files") for s in strings_in_ex_msg: self.assertRegexpMatches(str(ve.exception), s) else: self.assertRegex( str(ve.exception), "One or more layer names occur in only one of these files") for s in strings_in_ex_msg: self.assertRegex(str(ve.exception), s)
def test_layer_props_and_cmf_mismatch(self): # create and test_cmf and test_lp which refer different layer_prop.json files cmf1 = CrashMoveFolder(self.path_to_valid_cmf_des) test_lp = LayerProperties(cmf1, "test", verify_on_creation=False) # now point the test_cmf to a different layer_props.json cmf2 = CrashMoveFolder(self.path_to_valid_cmf_des) cmf2.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'fixture_layer_properties_four_layers.json') # check that a ValueError is raised when `verify_on_creation=True` with self.assertRaises(ValueError) as ve: MapCookbook(cmf2, test_lp, verify_on_creation=True) if six.PY2: self.assertRegexpMatches(str(ve.exception), "strange results") else: self.assertRegex(str(ve.exception), "strange results") # check that a ValueError is not raised when `verify_on_creation=False` test_mcb = MapCookbook(cmf2, test_lp, verify_on_creation=False) self.assertIsInstance(test_mcb, MapCookbook)
def test_load_recipe_with_layer_props_inc(self): # Test that a MapRecipe read form json with only a layername, combined with the # relevant LayerProperties is equal to a MapRecipe with all of the layerdetails embeded. # layerpros with cmf = CrashMoveFolder( os.path.join(self.parent_dir, 'example', 'cmf_description_relative_paths_test.json')) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_layer_properties_for_atlas.json') test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) # recipe with layer name only recipe1 = MapRecipe(fixtures.recipe_with_layer_name_only, test_lp) # combined recipe with layer props recipe2 = MapRecipe(fixtures.recipe_with_layer_details_embedded, test_lp) self.assertEqual(recipe1, recipe2) # 2) with non-matching layer props schema recipe3 = MapRecipe(fixtures.recipe_with_positive_iso3_code, test_lp) self.assertNotEqual(recipe1, recipe3)
def test_verify_with_rendering_files(self): # self.fail() # load a valid CMF test_cmf = CrashMoveFolder(self.path_to_valid_cmf_des) # Overwright the Layer Properties file path with # mapactionpy_controller\tests\testfiles\fixture_layer_properties_four_layers.json test_cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'fixture_layer_properties_four_layers.json') layer_rendering_test_root = os.path.join(self.parent_dir, 'tests', 'testfiles', 'test_layer_rendering') test_cmf.layer_rendering # 1) Exact match of .lyr files and layer properties test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'four_files_exact_match') lyr_lp = LayerProperties(test_cmf, '.lyr', verify_on_creation=True) self.assertFalse(lyr_lp.is_difference_with_layer_rendering_dir()) qml_lp = LayerProperties(test_cmf, '.qml', verify_on_creation=True) self.assertFalse(qml_lp.is_difference_with_layer_rendering_dir()) # 2) .lyr files which don't have layer properties entries test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'five_files') self.assertRaises(ValueError, LayerProperties, test_cmf, '.lyr') self.assertRaises(ValueError, LayerProperties, test_cmf, '.qml') # 3) layer properties entries which don't have cooresponding .lyr files. test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'three_files') self.assertRaises(ValueError, LayerProperties, test_cmf, '.lyr') self.assertRaises(ValueError, LayerProperties, test_cmf, '.qml') # 4) Both 2 & 3 combined test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'four_files_mis_match') self.assertRaises(ValueError, LayerProperties, test_cmf, '.lyr') self.assertRaises(ValueError, LayerProperties, test_cmf, '.qml') # 6) Overrided validation checks in constructor test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'four_files_mis_match') long_lived_lp = LayerProperties(test_cmf, '.lyr', verify_on_creation=False) self.assertTrue(long_lived_lp.is_difference_with_layer_rendering_dir()) long_lived_lp.cmf.layer_rendering = os.path.join( layer_rendering_test_root, 'four_files_exact_match') self.assertFalse( long_lived_lp.is_difference_with_layer_rendering_dir()) # 7) Same results whether or not the '.' character is included in the file extension test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'four_files_exact_match') # passing example with dot lyr_lp = LayerProperties(test_cmf, '.lyr', verify_on_creation=True) self.assertFalse(lyr_lp.is_difference_with_layer_rendering_dir()) # passing example without dot lyr_lp = LayerProperties(test_cmf, 'lyr', verify_on_creation=True) self.assertFalse(lyr_lp.is_difference_with_layer_rendering_dir()) # failing example with dot test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'four_files_mis_match') self.assertRaises(ValueError, LayerProperties, test_cmf, '.lyr') # failing example without dot test_cmf.layer_rendering = os.path.join(layer_rendering_test_root, 'four_files_mis_match') self.assertRaises(ValueError, LayerProperties, test_cmf, 'lyr')
def test_get_map_frame_extents(self): cmf = CrashMoveFolder( os.path.join(self.parent_dir, 'example', 'cmf_description_relative_paths_test.json')) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_layer_properties_for_atlas.json') test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) # recipe with layer name only with open( os.path.join( self.parent_dir, 'tests', 'testfiles', 'fixture_cookbook_1map_5layers_1frame.json')) as rf: cookbook_def = json.load(rf) # get the first (only) recipe in the cookbook recipe_def = cookbook_def['recipes'].pop() generic_lyr_def = json.loads('''{ "name": "the_name", "reg_exp": "^wrl_admn_ad0_py_(.*?)_(.*?)_([phm][phm])(.+)shp$", "schema_definition": "admin1_reference.yml", "definition_query": "", "display": true, "add_to_legend": true, "label_classes": [] }''') # Case 1 # One or more layers does not have it's extent defined case1_list = [('case1_lyrA', (35, 33, 36, 34), 'epsg:4326'), ('case1_lyrB', None, None)] case1_result = (35, 33, 36, 34) # Case 2 # Simple union with two lyrs of same crs case2_list = [('case2_lyrA', (33, 51, 36, 58), 'epsg:4326'), ('case2_lyrB', (15, 52, 35, 55), 'epsg:4326')] case2_result = (15, 51, 36, 58) # Case 3 # Union with two lyrs of with different crs # 'epsg:4326'== WGS1984, 'epsg:3785' == Web Mercator case3_list = [('case3_lyrA', (33, 51, 36, 58), 'epsg:4326'), ('case3_lyrB', (1669792.36, 6800125.45, 3896182.18, 7361866.11), 'epsg:3785')] case3_result = (15, 51, 36, 58) # Case 4 # One layer which stradles 180 degree meridian all_test_params = [(case1_list, case1_result), (case2_list, case2_result), (case3_list, case3_result)] for test_list, expected_result in all_test_params: test_recipe = MapRecipe(recipe_def, test_lp) # Build up a mock list of layer to test replacement_lyrs = [] for name, extent, crs in test_list: new_lyr = RecipeLayer(generic_lyr_def, test_lp, verify_on_creation=False) new_lyr.name = name new_lyr.use_for_frame_extent = bool(extent) # vaugely near Lebanon new_lyr.extent = extent new_lyr.crs = crs replacement_lyrs.append(new_lyr) # print('test_get_map_frame_extents') # print('expected_result = {}'.format(expected_result)) test_frame = test_recipe.map_frames.pop() test_frame.crs = 'epsg:4326' test_frame.layers = replacement_lyrs test_frame.calc_extent(state=test_recipe) actual_result = test_frame.extent # print('actual_result = {}'.format(actual_result)) for actual, expected in zip(actual_result, expected_result): self.assertAlmostEqual(actual, expected)
def test_filter_lyr_for_use_in_frame_extent(self): # Have included the digit at the start of the string, so that can be sorted easily. cmf = CrashMoveFolder( os.path.join(self.parent_dir, 'example', 'cmf_description_relative_paths_test.json')) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_layer_properties_for_atlas.json') test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) # recipe with layer name only with open( os.path.join( self.parent_dir, 'tests', 'testfiles', 'fixture_cookbook_1map_5layers_1frame.json')) as rf: cookbook_def = json.load(rf) # get the first (only) recipe in the cookbook recipe_def = cookbook_def['recipes'].pop() generic_lyr_def = json.loads('''{ "name": "the_name", "reg_exp": "^wrl_admn_ad0_py_(.*?)_(.*?)_([phm][phm])(.+)shp$", "schema_definition": "admin1_reference.yml", "definition_query": "", "display": true, "add_to_legend": true, "label_classes": [] }''') # Case 1 # test white list test_white_list1 = [('1a', True), ('1b', False), ('1c', None), ('1d', True), ('1e', False)] expected_white_result1 = ['1a', '1d'] test_white_list2 = [('2a', True), ('2b', None), ('2c', None), ('2d', True), ('2e', None)] expected_white_result2 = ['2a', '2d'] # Case 2 # Black List test_black_list = [('3a', None), ('3b', False), ('3c', None), ('3d', None), ('3e', False)] expected_black_result = ['3a', '3c', '3d'] # Case 3 # Default test_default_list = [('4a', None), ('4b', None), ('4c', None), ('4d', None), ('4e', None)] expected_default_result = ['4a', '4b', '4c', '4d', '4e'] all_test_params = [(test_white_list1, expected_white_result1), (test_white_list2, expected_white_result2), (test_black_list, expected_black_result), (test_default_list, expected_default_result)] for test_list, expected_result in all_test_params: test_recipe = MapRecipe(recipe_def, test_lp) # Build up a mock list of layer to test replacement_lyrs = [] for test_lyr_details in test_list: new_lyr = RecipeLayer(generic_lyr_def, test_lp, verify_on_creation=False) new_lyr.name = test_lyr_details[0] new_lyr.use_for_frame_extent = test_lyr_details[1] # vaugely near Lebanon new_lyr.extent = (35, 33, 36, 34) new_lyr.crs = 'epsg:4326' replacement_lyrs.append(new_lyr) test_frame = test_recipe.map_frames.pop() test_frame.layers = replacement_lyrs result_lyrs = test_frame._filter_lyr_for_use_in_frame_extent() actual_result = [lyr.name for lyr in result_lyrs] self.assertEqual(actual_result, expected_result)
def test_layer_data_schema(self): null_schema = True passing_schema = yaml.safe_load(r""" required: - name_en properties: geometry_type: items: enum: - MultiPolygon - Polygon additionalItems: false crs: items: enum: - EPSG:2090 additionalItems: false """) # Note the missing `enum` blocks failing_schema = yaml.safe_load(r""" required: - name_en properties: geometry_type: items: - MultiPolygon - Polygon additionalItems: false crs: items: - EPSG:2090 additionalItems: false """) cmf = CrashMoveFolder( os.path.join(self.parent_dir, 'example', 'cmf_description_relative_paths_test.json')) cmf.layer_properties = os.path.join( self.parent_dir, 'tests', 'testfiles', 'cookbooks', 'fixture_layer_properties_for_atlas.json' ) # Two cases where data schema is valid yaml for test_schema in [null_schema, passing_schema]: with mock.patch('mapactionpy_controller.data_schemas.yaml.safe_load') as mock_safe_load: mock_safe_load.return_value = test_schema test_lp = LayerProperties(cmf, ".lyr", verify_on_creation=False) MapRecipe(fixtures.recipe_with_positive_iso3_code, test_lp) self.assertTrue(True, 'validated jsonschema') # case where data schema file itself malformed somehow with mock.patch('mapactionpy_controller.data_schemas.yaml.safe_load') as mock_safe_load: mock_safe_load.return_value = failing_schema self.assertRaises( jsonschema.exceptions.SchemaError, MapRecipe, fixtures.recipe_with_positive_iso3_code, test_lp )