def test_different_frames_error(self): from pysd.tools.benchmarking import load_outputs, assert_frames_close with self.assertRaises(AssertionError) as err: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv"))) self.assertIn("Following columns are not close:\n\tTeacup Temperature", str(err.exception)) self.assertNotIn("Column 'Teacup Temperature' is not close.", str(err.exception)) self.assertNotIn("Actual values:\n\t", str(err.exception)) self.assertNotIn("Expected values:\n\t", str(err.exception)) with self.assertRaises(AssertionError) as err: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv")), verbose=True) self.assertIn("Following columns are not close:\n\tTeacup Temperature", str(err.exception)) self.assertIn("Column 'Teacup Temperature' is not close.", str(err.exception)) self.assertIn("Actual values:\n\t", str(err.exception)) self.assertIn("Expected values:\n\t", str(err.exception))
def test_repeated_subscript(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") output, canon = runner( test_models + '/repeated_subscript/test_repeated_subscript.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_delay_pipeline(self): # issue https://github.com/JamesPHoughton/pysd/issues/147 with warnings.catch_warnings(): warnings.simplefilter("ignore") output, canon = runner(test_models + '/delay_pipeline/test_pipeline_delays.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_get_lookups_subscripted_args(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") output, canon = runner(test_models + '/get_lookups_subscripted_args/' + 'test_get_lookups_subscripted_args.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_subscript_mapping_vensim(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") output, canon = runner( test_models + '/subscript_mapping_vensim/test_subscript_mapping_vensim.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_transposed_frame(self): from pysd.py_backend.utils import load_outputs assert_frames_close( load_outputs(_root.joinpath("data/out_teacup.csv")), load_outputs( _root.joinpath("data/out_teacup_transposed.csv"), transpose=True))
def test_get_with_missing_values_xlsx(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") output, canon = runner(test_models + '/get_with_missing_values_xlsx/' + 'test_get_with_missing_values_xlsx.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_invalid_input(self): from pysd.tools.benchmarking import assert_frames_close with self.assertRaises(TypeError) as err: assert_frames_close(actual=[1, 2], expected=[1, 2]) self.assertIn("Inputs must both be pandas DataFrames.", str(err.exception))
def test_read_vensim_split_model_subviews(self): import pysd from pysd.tools.benchmarking import assert_frames_close root_dir = os.path.join(_root, "more-tests/split_model/") model_name = "test_split_model_subviews" model_name_mdl = root_dir + model_name + ".mdl" model_split = pysd.read_vensim(root_dir + model_name + ".mdl", split_views=True, subview_sep=["."]) namespace_filename = "_namespace_" + model_name + ".json" subscript_filename = "_subscripts_" + model_name + ".json" dependencies_filename = "_dependencies_" + model_name + ".json" modules_dirname = "modules_" + model_name separator = "." command = f"{call} --translate --split-views "\ f"--subview-sep={separator} {model_name_mdl}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) # check that the modules folders were created self.assertTrue(os.path.isdir(root_dir + modules_dirname + "/view_1")) # check creation of module files self.assertTrue( os.path.isfile(root_dir + modules_dirname + "/view_1/" + "submodule_1.py")) self.assertTrue( os.path.isfile(root_dir + modules_dirname + "/view_1/" + "submodule_2.py")) self.assertTrue( os.path.isfile(root_dir + modules_dirname + "/view_2.py")) # check that the results of the split model are the same than those # without splitting model_non_split = pysd.read_vensim(root_dir + model_name + ".mdl", split_views=False) result_split = model_split.run() result_non_split = model_non_split.run() # results of a split model are the same that those of the regular # model (un-split) assert_frames_close(result_split, result_non_split, atol=0, rtol=0) # remove newly created files os.remove(root_dir + model_name + ".py") os.remove(root_dir + namespace_filename) os.remove(root_dir + subscript_filename) os.remove(root_dir + dependencies_filename) # remove newly created modules folder shutil.rmtree(root_dir + modules_dirname)
def test_read_vensim_split_model(self, model_file, subview_sep, expected_files, modules, original_vars, py_vars, stateful_objs): # assert that the files don't exist in the temporary directory for file in expected_files: assert not file.is_file(), f"File {file} already exists..." # translate split model model_split = pysd.read_vensim(model_file, split_views=True, subview_sep=subview_sep) # assert that all the files have been created for file in expected_files: assert file.is_file(), f"File {file} has not been created..." # check the dictionaries assert isinstance(model_split.components._namespace, dict) assert isinstance(model_split.components._subscript_dict, dict) assert isinstance(model_split.components._dependencies, dict) assert isinstance(model_split.components._modules, dict) # assert taht main modules are dictionary keys for module in modules: assert module.split("/")[0]\ in model_split.components._modules.keys() # assert that original variables are in the namespace for var in original_vars: assert var in model_split.components._namespace.keys() # assert that the functions are not defined in the main file model_py_file = model_file.with_suffix(".py") with open(model_py_file, 'r') as file: file_content = file.read() for var in py_vars: assert "def %s()" % var not in file_content for var in stateful_objs: assert "%s = " % var not in file_content # translation without splitting model_non_split = pysd.read_vensim(model_file, split_views=False) # assert that the functions are defined in the main file with open(model_py_file, 'r') as file: file_content = file.read() for var in py_vars: assert "def %s()" % var in file_content for var in stateful_objs: assert "%s = " % var in file_content # check that both models give the same result assert_frames_close(model_split.run(), model_non_split.run(), atol=0, rtol=0)
def test_get_lookups_data_3d_xls(self): """ Test for usage of GET DIRECT/XLS LOOKUPS/DATA from a Excel file All the possible combinations of lentgh-wise and different dimensions are tested in unit_test_external.py, this test want to test only the good working of the builder """ output, canon = runner(test_models + '/get_lookups_data_3d_xls/' + 'test_get_lookups_data_3d_xls.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_get_subscript_3d_arrays_xls(self): """ Test for usage of GET DIRECT/XLS SUBSCRIPTS/CONSTANTS from a Excel file All the possible combinations of lentgh-wise and different dimensions are tested in unit_test_external.py, this test want to test only the good working of the builder """ output, canon = runner(test_models + '/get_subscript_3d_arrays_xls/' + 'test_get_subscript_3d_arrays_xls.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_different_frames_warning(self): from warnings import catch_warnings from pysd.tools.benchmarking import load_outputs, assert_frames_close with catch_warnings(record=True) as ws: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv")), assertion="warn") # use only user warnings wu = [w for w in ws if issubclass(w.category, UserWarning)] self.assertEqual(len(wu), 1) self.assertIn( "Following columns are not close:\n\tTeacup Temperature", str(wu[0].message)) self.assertNotIn("Column 'Teacup Temperature' is not close.", str(wu[0].message)) self.assertNotIn("Actual values:\n\t", str(wu[0].message)) self.assertNotIn("Expected values:\n\t", str(wu[0].message)) with catch_warnings(record=True) as ws: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv")), assertion="warn", verbose=True) # use only user warnings wu = [w for w in ws if issubclass(w.category, UserWarning)] self.assertEqual(len(wu), 1) self.assertIn( "Following columns are not close:\n\tTeacup Temperature", str(wu[0].message)) self.assertIn("Column 'Teacup Temperature' is not close.", str(wu[0].message)) self.assertIn("Actual values:\n\t", str(wu[0].message)) self.assertIn("Expected values:\n\t", str(wu[0].message))
def test_different_cols(self): from warnings import catch_warnings from pysd.tools.benchmarking import assert_frames_close import pandas as pd d1 = pd.DataFrame({'a': [1, 2], 'b': [3, 4], 'd': [6, 7]}) d2 = pd.DataFrame({'a': [1, 2]}) d3 = pd.DataFrame({'a': [1, 2], 'c': [3, 4]}) with self.assertRaises(ValueError) as err: assert_frames_close(actual=d1, expected=d2) self.assertIn("Columns from actual and expected values must be equal.", str(err.exception)) with catch_warnings(record=True) as ws: assert_frames_close(actual=d1, expected=d2, assertion="warn") # use only user warnings wu = [w for w in ws if issubclass(w.category, UserWarning)] self.assertEqual(len(wu), 1) self.assertIn("'b'", str(wu[0].message)) self.assertIn("'d'", str(wu[0].message)) self.assertIn("from actual values not found in expected values.", str(wu[0].message)) with catch_warnings(record=True) as ws: assert_frames_close(expected=d1, actual=d2, assertion="warn") # use only user warnings wu = [w for w in ws if issubclass(w.category, UserWarning)] self.assertEqual(len(wu), 1) self.assertIn("'b'", str(wu[0].message)) self.assertIn("'d'", str(wu[0].message)) self.assertIn("from expected values not found in actual values.", str(wu[0].message)) with catch_warnings(record=True) as ws: assert_frames_close(actual=d1, expected=d3, assertion="warn") # use only user warnings wu = [w for w in ws if issubclass(w.category, UserWarning)] self.assertEqual(len(wu), 1) self.assertIn("'b'", str(wu[0].message)) self.assertIn("'d'", str(wu[0].message)) self.assertIn("from actual values not found in expected values.", str(wu[0].message)) self.assertIn( "Columns 'c' from expected values not found in actual " "values.", str(wu[0].message))
def test_make_flat_df(self): import pysd df = pd.DataFrame(index=[1], columns=['elem1']) df.at[1] = [xr.DataArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]], {'Dim1': ['A', 'B', 'C'], 'Dim2': ['D', 'E', 'F']}, dims=['Dim1', 'Dim2'])] expected = pd.DataFrame(index=[1], data={'Elem1[B,F]': 6.}) return_addresses = { 'Elem1[B,F]': ('elem1', {'Dim1': ['B'], 'Dim2': ['F']})} actual = pysd.utils.make_flat_df(df, return_addresses) # check all columns are in the DataFrame self.assertEqual(set(actual.columns), set(expected.columns)) assert_frames_close(actual, expected, rtol=1e-8, atol=1e-8)
def test_initial_conditions_tuple_pysafe_names(self): import pysd model = pysd.read_vensim(test_model) initial_time = 3000 return_timestamps = np.arange(initial_time, initial_time + 10) stocks = model.run(initial_condition=(initial_time, { "teacup_temperature": 33 }), return_timestamps=return_timestamps) command = f"{call} -o {out_tab_file} -I {initial_time} -R "\ f"'{', '.join(return_timestamps.astype(str))}'"\ f" {test_model.replace('.mdl', '.py')}"\ f" teacup_temperature:33" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks2 = load_outputs(out_tab_file) assert_frames_close(stocks2, stocks) os.remove(out_tab_file)
def test_run_model_with_data(self): data_file = os.path.join( _root, "test-models/tests/data_from_other_model/data.tab") model_file = os.path.join( _root, "test-models/tests/data_from_other_model/" + "test_data_from_other_model.mdl") command = f"{call} -o {out_tab_file} -D {data_file}"\ f" {model_file}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) canon = load_outputs( os.path.join(_root, "test-models/tests/data_from_other_model/output.tab")) assert_frames_close(stocks[canon.columns], canon) # invalid data file command = f"{call} -o {out_tab_file} -D my_file.txt"\ f" {model_file}" out = subprocess.run(split_bash(command), capture_output=True) self.assertNotEqual(out.returncode, 0) stderr = out.stderr.decode(encoding_stderr) self.assertIn("PySD: error: when parsing my_file.txt", stderr) self.assertIn("The data file name must be .tab or .csv...", stderr) # not found data file command = f"{call} -o {out_tab_file} -D my_file.tab"\ f" {model_file}" out = subprocess.run(split_bash(command), capture_output=True) self.assertNotEqual(out.returncode, 0) stderr = out.stderr.decode(encoding_stderr) self.assertIn("PySD: error: when parsing my_file.tab", stderr) self.assertIn("The data file does not exist...", stderr)
def test_export_import(self): import pysd from pysd.tools.benchmarking import assert_frames_close exp_file = "teacup15.pic" model = pysd.read_vensim(test_model) stocks = model.run(return_timestamps=[0, 10, 20, 30]) self.assertTrue((stocks["INITIAL TIME"] == 0).all().all()) command = f"{call} -o {out_tab_file} -e {exp_file} -F 15 -R 0,10"\ f" {test_model}" command2 = f"{call} -o {out_tab_file} -i {exp_file} -R 20,30"\ f" {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks1 = load_outputs(out_tab_file) out = subprocess.run(split_bash(command2), capture_output=True) self.assertEqual(out.returncode, 0) stocks2 = load_outputs(out_tab_file) os.remove(exp_file) os.remove(out_tab_file) self.assertTrue((stocks1["INITIAL TIME"] == 0).all().all()) self.assertTrue((stocks1["FINAL TIME"] == 15).all().all()) self.assertTrue((stocks2["INITIAL TIME"] == 15).all().all()) stocks.drop("INITIAL TIME", axis=1, inplace=True) stocks1.drop("INITIAL TIME", axis=1, inplace=True) stocks2.drop("INITIAL TIME", axis=1, inplace=True) stocks.drop("FINAL TIME", axis=1, inplace=True) stocks1.drop("FINAL TIME", axis=1, inplace=True) stocks2.drop("FINAL TIME", axis=1, inplace=True) assert_frames_close(stocks1, stocks.loc[[0, 10]]) assert_frames_close(stocks2, stocks.loc[[20, 30]])
def test_unicode_characters(self): output, canon = runner(test_models + '/unicode_characters/unicode_test_model.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_delay_parentheses(self): output, canon = runner(test_models + '/delay_parentheses/test_delay_parentheses.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_delay_numeric_error(self): # issue https://github.com/JamesPHoughton/pysd/issues/225 output, canon = runner( test_models + '/delay_numeric_error/test_delay_numeric_error.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_data_from_other_model(self): output, canon = runner( test_models + '/data_from_other_model/test_data_from_other_model.mdl', data_files=test_models + '/data_from_other_model/data.tab') assert_frames_close(output, canon, rtol=rtol)
def test_constant_expressions(self): output, canon = runner( test_models + '/constant_expressions/test_constant_expressions.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_odd_number_quotes(self): output, canon = runner(test_models + '/odd_number_quotes/teacup_3quotes.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_run_uppercase(self): output, canon = runner(test_models + '/case_sensitive_extension/teacup-upper.MDL') assert_frames_close(output, canon, rtol=rtol)
def test_xidz_zidz(self): output, canon = runner(test_models + '/xidz_zidz/xidz_zidz.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_variable_ranges(self): output, canon = runner(test_models + '/variable_ranges/test_variable_ranges.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_trig(self): output, canon = runner(test_models + '/trig/test_trig.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_subset_duplicated_coord(self): output, canon = runner(test_models + '/subset_duplicated_coord/' + 'test_subset_duplicated_coord.mdl') assert_frames_close(output, canon, rtol=rtol)
def test_subscripted_xidz(self): output, canon = runner(test_models + '/subscripted_xidz/test_subscripted_xidz.mdl') assert_frames_close(output, canon, rtol=rtol)