diff options
Diffstat (limited to 'tests/unit/computations')
-rw-r--r-- | tests/unit/computations/test_correlation.py | 48 | ||||
-rw-r--r-- | tests/unit/computations/test_heatmap.py | 143 | ||||
-rw-r--r-- | tests/unit/computations/test_slink.py | 311 |
3 files changed, 492 insertions, 10 deletions
diff --git a/tests/unit/computations/test_correlation.py b/tests/unit/computations/test_correlation.py index b1bc6ef..fc52ec1 100644 --- a/tests/unit/computations/test_correlation.py +++ b/tests/unit/computations/test_correlation.py @@ -1,5 +1,4 @@ """Module contains the tests for correlation""" -import unittest from unittest import TestCase from unittest import mock @@ -16,9 +15,10 @@ from gn3.computations.correlations import fetch_lit_correlation_data from gn3.computations.correlations import query_formatter from gn3.computations.correlations import map_to_mouse_gene_id from gn3.computations.correlations import compute_all_lit_correlation -from gn3.computations.correlations import compute_all_tissue_correlation +from gn3.computations.correlations import compute_tissue_correlation from gn3.computations.correlations import map_shared_keys_to_values from gn3.computations.correlations import process_trait_symbol_dict +from gn3.computations.correlations2 import compute_correlation class QueryableMixin: @@ -172,7 +172,6 @@ class TestCorrelation(TestCase): self.assertEqual(results, (filtered_this_samplelist, filtered_target_samplelist)) - @unittest.skip("Test needs to be refactored ") @mock.patch("gn3.computations.correlations.compute_sample_r_correlation") @mock.patch("gn3.computations.correlations.filter_shared_sample_keys") def test_compute_all_sample(self, filter_shared_samples, sample_r_corr): @@ -180,7 +179,7 @@ class TestCorrelation(TestCase): filter_shared_samples.return_value = (["1.23", "6.565", "6.456"], [ "6.266", "6.565", "6.456"]) - sample_r_corr.return_value = ([-1.0, 0.9, 6]) + sample_r_corr.return_value = (["1419792_at", -1.0, 0.9, 6]) this_trait_data = { "trait_id": "1455376_at", @@ -203,13 +202,14 @@ class TestCorrelation(TestCase): } ] - sample_all_results = [{"1419792_at": {"corr_coeffient": -1.0, + sample_all_results = [{"1419792_at": {"corr_coefficient": -1.0, "p_value": 0.9, "num_overlap": 6}}] self.assertEqual(compute_all_sample_correlation( this_trait=this_trait_data, target_dataset=traits_dataset), sample_all_results) sample_r_corr.assert_called_once_with( + trait_name='1419792_at', corr_method="pearson", trait_vals=['1.23', '6.565', '6.456'], target_samples_vals=['6.266', '6.565', '6.456']) filter_shared_samples.assert_called_once_with( @@ -406,17 +406,17 @@ class TestCorrelation(TestCase): target_tissue_data = {"trait_symbol_dict": target_trait_symbol, "symbol_tissue_vals_dict": target_symbol_tissue_vals} - mock_tissue_corr.side_effect = [{"tissue_corr": -0.5, "tissue_p_val": 0.9, - "tissue_number": 3}, - {"tissue_corr": 1.11, "tissue_p_val": 0.2, - "tissue_number": 3}] + mock_tissue_corr.side_effect = [{"1418702_a_at": {"tissue_corr": -0.5, "tissue_p_val": 0.9, + "tissue_number": 3}}, + {"1412_at": {"tissue_corr": 1.11, "tissue_p_val": 0.2, + "tissue_number": 3}}] expected_results = [{"1412_at": {"tissue_corr": 1.11, "tissue_p_val": 0.2, "tissue_number": 3}}, {"1418702_a_at": {"tissue_corr": -0.5, "tissue_p_val": 0.9, "tissue_number": 3}}] - results = compute_all_tissue_correlation( + results = compute_tissue_correlation( primary_tissue_dict=primary_tissue_dict, target_tissues_data=target_tissue_data, corr_method="pearson") @@ -464,3 +464,31 @@ class TestCorrelation(TestCase): trait_symbol_dict, tissue_values_dict) self.assertEqual(results, [expected_results]) + + def test_compute_correlation(self): + """Test that the new correlation function works the same as the original + from genenetwork1.""" + for dbdata, userdata, expected in [ + [[None, None, None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None, None, None], + (0.0, 0)], + [[None, None, None, None, None, None, None, None, None, 0], + [None, None, None, None, None, None, None, None, None, None], + (0.0, 0)], + [[None, None, None, None, None, None, None, None, None, 0], + [None, None, None, None, None, None, None, None, None, 0], + (0.0, 1)], + [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + (0, 10)], + [[9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87], + [9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87, 9.87], + (0.9999999999999998, 10)], + [[9.3, 2.2, 5.4, 7.2, 6.4, 7.6, 3.8, 1.8, 8.4, 0.2], + [0.6, 3.97, 5.82, 8.21, 1.65, 4.55, 6.72, 9.5, 7.33, 2.34], + (-0.12720361919462056, 10)], + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [None, None, None, None, 2, None, None, 3, None, None], + (0.0, 2)]]: + with self.subTest(dbdata=dbdata, userdata=userdata): + self.assertEqual(compute_correlation( + dbdata, userdata), expected) diff --git a/tests/unit/computations/test_heatmap.py b/tests/unit/computations/test_heatmap.py new file mode 100644 index 0000000..650cb45 --- /dev/null +++ b/tests/unit/computations/test_heatmap.py @@ -0,0 +1,143 @@ +"""Module contains tests for gn3.computations.heatmap""" +from unittest import TestCase +from gn3.computations.heatmap import cluster_traits, export_trait_data + +strainlist = ["B6cC3-1", "BXD1", "BXD12", "BXD16", "BXD19", "BXD2"] +trait_data = { + "mysqlid": 36688172, + "data": { + "B6cC3-1": {"strain_name": "B6cC3-1", "value": 7.51879, "variance": None, "ndata": None}, + "BXD1": {"strain_name": "BXD1", "value": 7.77141, "variance": None, "ndata": None}, + "BXD12": {"strain_name": "BXD12", "value": 8.39265, "variance": None, "ndata": None}, + "BXD16": {"strain_name": "BXD16", "value": 8.17443, "variance": None, "ndata": None}, + "BXD19": {"strain_name": "BXD19", "value": 8.30401, "variance": None, "ndata": None}, + "BXD2": {"strain_name": "BXD2", "value": 7.80944, "variance": None, "ndata": None}, + "BXD21": {"strain_name": "BXD21", "value": 8.93809, "variance": None, "ndata": None}, + "BXD24": {"strain_name": "BXD24", "value": 7.99415, "variance": None, "ndata": None}, + "BXD27": {"strain_name": "BXD27", "value": 8.12177, "variance": None, "ndata": None}, + "BXD28": {"strain_name": "BXD28", "value": 7.67688, "variance": None, "ndata": None}, + "BXD32": {"strain_name": "BXD32", "value": 7.79062, "variance": None, "ndata": None}, + "BXD39": {"strain_name": "BXD39", "value": 8.27641, "variance": None, "ndata": None}, + "BXD40": {"strain_name": "BXD40", "value": 8.18012, "variance": None, "ndata": None}, + "BXD42": {"strain_name": "BXD42", "value": 7.82433, "variance": None, "ndata": None}, + "BXD6": {"strain_name": "BXD6", "value": 8.09718, "variance": None, "ndata": None}, + "BXH14": {"strain_name": "BXH14", "value": 7.97475, "variance": None, "ndata": None}, + "BXH19": {"strain_name": "BXH19", "value": 7.67223, "variance": None, "ndata": None}, + "BXH2": {"strain_name": "BXH2", "value": 7.93622, "variance": None, "ndata": None}, + "BXH22": {"strain_name": "BXH22", "value": 7.43692, "variance": None, "ndata": None}, + "BXH4": {"strain_name": "BXH4", "value": 7.96336, "variance": None, "ndata": None}, + "BXH6": {"strain_name": "BXH6", "value": 7.75132, "variance": None, "ndata": None}, + "BXH7": {"strain_name": "BXH7", "value": 8.12927, "variance": None, "ndata": None}, + "BXH8": {"strain_name": "BXH8", "value": 6.77338, "variance": None, "ndata": None}, + "BXH9": {"strain_name": "BXH9", "value": 8.03836, "variance": None, "ndata": None}, + "C3H/HeJ": {"strain_name": "C3H/HeJ", "value": 7.42795, "variance": None, "ndata": None}, + "C57BL/6J": {"strain_name": "C57BL/6J", "value": 7.50606, "variance": None, "ndata": None}, + "DBA/2J": {"strain_name": "DBA/2J", "value": 7.72588, "variance": None, "ndata": None}}} + +class TestHeatmap(TestCase): + """Class for testing heatmap computation functions""" + + def test_export_trait_data_dtype(self): + """ + Test `export_trait_data` with different values for the `dtype` keyword + argument + """ + for dtype, expected in [ + ["val", (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944)], + ["var", (None, None, None, None, None, None)], + ["N", (None, None, None, None, None, None)], + ["all", (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944)]]: + with self.subTest(dtype=dtype): + self.assertEqual( + export_trait_data(trait_data, strainlist, dtype=dtype), + expected) + + def test_export_trait_data_dtype_all_flags(self): + """ + Test `export_trait_data` with different values for the `dtype` keyword + argument and the different flags set up + """ + for dtype, vflag, nflag, expected in [ + ["val", False, False, + (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944)], + ["val", False, True, + (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944)], + ["val", True, False, + (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944)], + ["val", True, True, + (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944)], + ["var", False, False, (None, None, None, None, None, None)], + ["var", False, True, (None, None, None, None, None, None)], + ["var", True, False, (None, None, None, None, None, None)], + ["var", True, True, (None, None, None, None, None, None)], + ["N", False, False, (None, None, None, None, None, None)], + ["N", False, True, (None, None, None, None, None, None)], + ["N", True, False, (None, None, None, None, None, None)], + ["N", True, True, (None, None, None, None, None, None)], + ["all", False, False, + (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944)], + ["all", False, True, + (7.51879, None, 7.77141, None, 8.39265, None, 8.17443, None, + 8.30401, None, 7.80944, None)], + ["all", True, False, + (7.51879, None, 7.77141, None, 8.39265, None, 8.17443, None, + 8.30401, None, 7.80944, None)], + ["all", True, True, + (7.51879, None, None, 7.77141, None, None, 8.39265, None, None, + 8.17443, None, None, 8.30401, None, None, 7.80944, None, None)] + ]: + with self.subTest(dtype=dtype, vflag=vflag, nflag=nflag): + self.assertEqual( + export_trait_data( + trait_data, strainlist, dtype=dtype, var_exists=vflag, + n_exists=nflag), + expected) + + def test_cluster_traits(self): + """ + Test that the clustering is working as expected. + """ + traits_data_list = [ + (7.51879, 7.77141, 8.39265, 8.17443, 8.30401, 7.80944), + (6.1427, 6.50588, 7.73705, 6.68328, 7.49293, 7.27398), + (8.4211, 8.30581, 9.24076, 8.51173, 9.18455, 8.36077), + (10.0904, 10.6509, 9.36716, 9.91202, 8.57444, 10.5731), + (10.188, 9.76652, 9.54813, 9.05074, 9.52319, 9.10505), + (6.74676, 7.01029, 7.54169, 6.48574, 7.01427, 7.26815), + (6.39359, 6.85321, 5.78337, 7.11141, 6.22101, 6.16544), + (6.84118, 7.08432, 7.59844, 7.08229, 7.26774, 7.24991), + (9.45215, 10.6943, 8.64719, 10.1592, 7.75044, 8.78615), + (7.04737, 6.87185, 7.58586, 6.92456, 6.84243, 7.36913)] + self.assertEqual( + cluster_traits(traits_data_list), + ((0.0, 0.20337048635536847, 0.16381088984330505, 1.7388553629398245, + 1.5025235756329178, 0.6952839500255574, 1.271661230252733, + 0.2100487290977544, 1.4699690641062024, 0.7934461515867415), + (0.20337048635536847, 0.0, 0.2198321044997198, 1.5753041735592204, + 1.4815755944537086, 0.26087293140686374, 1.6939790104301427, + 0.06024619831474998, 1.7430082449189215, 0.4497104244247795), + (0.16381088984330505, 0.2198321044997198, 0.0, 1.9073926868549234, + 1.0396738891139845, 0.5278328671176757, 1.6275069061182947, + 0.2636503792482082, 1.739617877037615, 0.7127042590637039), + (1.7388553629398245, 1.5753041735592204, 1.9073926868549234, 0.0, + 0.9936846292920328, 1.1169999189889366, 0.6007483980555253, + 1.430209221053372, 0.25879514152086425, 0.9313185954797953), + (1.5025235756329178, 1.4815755944537086, 1.0396738891139845, + 0.9936846292920328, 0.0, 1.027827186339337, 1.1441743109173244, + 1.4122477962364253, 0.8968250491499363, 1.1683723389247052), + (0.6952839500255574, 0.26087293140686374, 0.5278328671176757, + 1.1169999189889366, 1.027827186339337, 0.0, 1.8420471110023269, + 0.19179284676938602, 1.4875072385631605, 0.23451785425383564), + (1.271661230252733, 1.6939790104301427, 1.6275069061182947, + 0.6007483980555253, 1.1441743109173244, 1.8420471110023269, 0.0, + 1.6540234785929928, 0.2140799896286565, 1.7413442197913358), + (0.2100487290977544, 0.06024619831474998, 0.2636503792482082, + 1.430209221053372, 1.4122477962364253, 0.19179284676938602, + 1.6540234785929928, 0.0, 1.5225640692832796, 0.33370067057028485), + (1.4699690641062024, 1.7430082449189215, 1.739617877037615, + 0.25879514152086425, 0.8968250491499363, 1.4875072385631605, + 0.2140799896286565, 1.5225640692832796, 0.0, 1.3256191648260216), + (0.7934461515867415, 0.4497104244247795, 0.7127042590637039, + 0.9313185954797953, 1.1683723389247052, 0.23451785425383564, + 1.7413442197913358, 0.33370067057028485, 1.3256191648260216, + 0.0))) diff --git a/tests/unit/computations/test_slink.py b/tests/unit/computations/test_slink.py new file mode 100644 index 0000000..995393b --- /dev/null +++ b/tests/unit/computations/test_slink.py @@ -0,0 +1,311 @@ +"""Module contains tests for slink""" +from unittest import TestCase + +from gn3.computations.slink import slink +from gn3.computations.slink import nearest +from gn3.computations.slink import LengthError +from gn3.computations.slink import MirrorError + +class TestSlink(TestCase): + """Class for testing slink functions""" + + def test_nearest_expects_list_of_lists(self): + """Test that function only accepts a list of lists.""" + # This might be better handled with type-hints and mypy + for item in [9, "some string", 5.432, + [1, 2, 3], ["test", 7.4]]: + with self.subTest(item=item): + with self.assertRaises(ValueError, msg="Expected list or tuple"): + nearest(item, 1, 1) + + def test_nearest_does_not_allow_empty_lists(self): + """Test that function does not accept an empty list, or any of the child + lists to be empty.""" + for lst in [[], + [[], []], + [[], [], []], + [[0, 1, 2], [], [1, 2, 0]]]: + with self.subTest(lst=lst): + with self.assertRaises(ValueError): + nearest(lst, 1, 1) + + def test_nearest_expects_children_are_same_length_as_parent(self): + """Test that children lists are same length as parent list.""" + for lst in [[[0, 1]], + [[0, 1, 2], [3, 4, 5]], + [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9, 0]], + [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3], + [3, 4, 5, 6, 7]]]: + with self.subTest(lst=lst): + with self.assertRaises(LengthError): + nearest(lst, 1, 1) + + def test_nearest_expects_member_is_zero_distance_from_itself(self): + """Test that distance of a member from itself is zero""" + for lst in [[[1]], + [[1, 2], [3, 4]], + [1, 0, 0], [0, 0, 5], [0, 3, 4], + [0, 0, 0, 0], [0, 0, 3, 3], [0, 1, 2, 3], [0, 3, 2, 0]]: + with self.subTest(lst=lst): + with self.assertRaises(ValueError): + nearest(lst, 1, 1) + + def test_nearest_expects_distance_atob_is_equal_to_distance_btoa(self): + """Test that the distance from member A to member B is the same as that + from member B to member A.""" + for lst in [[[0, 1], [2, 0]], + [[0, 1, 2], [1, 0, 3], [9, 7, 0]], + [[0, 1, 2, 3], [7, 0, 2, 3], [2, 3, 0, 1], [8, 9, 5, 0]]]: + with self.subTest(lst=lst): + with self.assertRaises(MirrorError): + nearest(lst, 1, 1) + + def test_nearest_expects_zero_or_positive_distances(self): + """Test that all distances are either zero, or greater than zero.""" + # Based on: + # https://github.com/genenetwork/genenetwork1/blob/master/web/webqtl/heatmap/slink.py#L87-L89 + for lst in [[[0, -1, 2, 3], [-1, 0, 3, 4], [2, 3, 0, 5], [3, 4, 5, 0]], + [[0, 1, -2, 3], [1, 0, 3, 4], [-2, 3, 0, 5], [3, 4, 5, 0]], + [[0, 1, 2, 3], [1, 0, -3, 4], [2, -3, 0, 5], [3, 4, 5, 0]], + [[0, 1, 2, -3], [1, 0, 3, 4], [2, 3, 0, 5], [-3, 4, 5, 0]], + [[0, 1, 2, 3], [1, 0, 3, -4], [2, 3, 0, 5], [3, -4, 5, 0]], + [[0, 1, 2, 3], [1, 0, 3, 4], [2, 3, 0, -5], [3, 4, -5, 0]]]: + with self.subTest(lst=lst): + with self.assertRaises(ValueError, msg="Distances should be positive."): + nearest(lst, 1, 1) + + def test_nearest_returns_shortest_distance_given_coordinates_to_both_group_members(self): + """Test that the shortest distance is returned.""" + # This test is named wrong - at least I think it is, from the expected results + # This tests distance when both `i`, and `j` are integers + # We still need to add tests for when (either one/both) (is/are) not (an) integer(s) + # https://github.com/genenetwork/genenetwork1/blob/master/web/webqtl/heatmap/slink.py#L39-L40 + for lst, i, j, expected in [ + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 0, 0, 0], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 0, 1, 9], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 0, 2, 3], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 0, 3, 6], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 0, 4, 11], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 1, 0, 9], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 1, 1, 0], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 1, 2, 7], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 1, 3, 5], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 1, 4, 10], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 2, 0, 3], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 2, 1, 7], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 2, 2, 0], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 2, 3, 9], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 2, 4, 2], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 3, 0, 6], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 3, 1, 5], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 3, 2, 9], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 3, 3, 0], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 3, 4, 8], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 4, 0, 11], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 4, 1, 10], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 4, 2, 2], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 4, 3, 8], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + 4, 4, 0], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 0, 0, 0], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 0, 1, 9], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 0, 2, 5.5], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 0, 3, 6], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 0, 4, 11], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 1, 0, 9], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 1, 1, 0], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 1, 2, 7], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 1, 3, 5], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 1, 4, 10], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 2, 0, 5.5], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 2, 1, 7], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 2, 2, 0], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 2, 3, 9], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 2, 4, 2], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 3, 0, 6], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 3, 1, 5], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 3, 2, 9], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 3, 3, 0], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 3, 4, 3], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 4, 0, 11], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 4, 1, 10], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 4, 2, 2], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 4, 3, 3], + [[[0, 9, 5.5, 6, 11], [9, 0, 7, 5, 10], [5.5, 7, 0, 9, 2], + [6, 5, 9, 0, 3], [11, 10, 2, 3, 0]], + 4, 4, 0]]: + with self.subTest(lst=lst): + self.assertEqual(nearest(lst, i, j), expected) + + def test_nearest_gives_shortest_distance_between_list_of_members_and_member(self): + """Test that the shortest distance is returned.""" + for members_distances, members_list, member_coordinate, expected_distance in [ + [[[0, 9, 3], [9, 0, 7], [3, 7, 0]], (0, 2, 3), 1, 7], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], [0, 1, 2, 3, 4], 3, 0], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], [0, 1, 2, 4], 3, 5], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], [0, 2, 4], 3, 6], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], [2, 4], 3, 9]]: + with self.subTest( + members_distances=members_distances, + members_list=members_list, + member_coordinate=member_coordinate, + expected_distance=expected_distance): + self.assertEqual( + nearest( + members_distances, members_list, member_coordinate), + expected_distance) + self.assertEqual( + nearest( + members_distances, member_coordinate, members_list), + expected_distance) + + def test_nearest_returns_shortest_distance_given_two_lists_of_members(self): + """Test that the shortest distance is returned.""" + for members_distances, members_list, member_list2, expected_distance in [ + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], 0], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + [0, 1], [3, 4], 6], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + [0, 1], [2, 3, 4], 3], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], [11, 10, 2, 8, 0]], + [0, 2], [3, 4], 6]]: + with self.subTest( + members_distances=members_distances, + members_list=members_list, + member_list2=member_list2, + expected_distance=expected_distance): + self.assertEqual( + nearest( + members_distances, members_list, member_list2), + expected_distance) + self.assertEqual( + nearest( + members_distances, member_list2, members_list), + expected_distance) + + def test_slink_wrong_data_returns_empty_list(self): + """Test that empty list is returned for wrong data.""" + for data in [1, "test", [], 2.945, nearest, [0]]: + with self.subTest(data=data): + self.assertEqual(slink(data), []) + + def test_slink_with_data(self): + """Test slink with example data, and expected results for each data + sample.""" + for data, expected in [ + [[[0, 9], [9, 0]], [0, 1, 9]], + [[[0, 9, 3], [9, 0, 7], [3, 7, 0]], [(0, 2, 3), 1, 7]], + [[[0, 9, 3, 6], [9, 0, 7, 5], [3, 7, 0, 9], [6, 5, 9, 0]], + [(0, 2, 3), (1, 3, 5), 6]], + [[[0, 9, 3, 6, 11], [9, 0, 7, 5, 10], [3, 7, 0, 9, 2], + [6, 5, 9, 0, 8], + [11, 10, 2, 8, 0]], + [(0, (2, 4, 2), 3), (1, 3, 5), 6]]]: + with self.subTest(data=data): + self.assertEqual(slink(data), expected) |