aboutsummaryrefslogtreecommitdiff
path: root/gn2/tests/wqflask
diff options
context:
space:
mode:
authorArun Isaac2023-12-29 18:55:37 +0000
committerArun Isaac2023-12-29 19:01:46 +0000
commit204a308be0f741726b9a620d88fbc22b22124c81 (patch)
treeb3cf66906674020b530c844c2bb4982c8a0e2d39 /gn2/tests/wqflask
parent83062c75442160427b50420161bfcae2c5c34c84 (diff)
downloadgenenetwork2-204a308be0f741726b9a620d88fbc22b22124c81.tar.gz
Namespace all modules under gn2.
We move all modules under a gn2 directory. This is important for "correct" packaging and deployment as a Guix service.
Diffstat (limited to 'gn2/tests/wqflask')
-rw-r--r--gn2/tests/wqflask/show_trait/testSampleList.py17
-rw-r--r--gn2/tests/wqflask/show_trait/test_show_trait.py255
2 files changed, 272 insertions, 0 deletions
diff --git a/gn2/tests/wqflask/show_trait/testSampleList.py b/gn2/tests/wqflask/show_trait/testSampleList.py
new file mode 100644
index 00000000..1c5478bb
--- /dev/null
+++ b/gn2/tests/wqflask/show_trait/testSampleList.py
@@ -0,0 +1,17 @@
+import unittest
+import re
+from unittest import mock
+from gn2.wqflask.show_trait.SampleList import natural_sort
+
+
+class TestSampleList(unittest.TestCase):
+ def test_natural_sort(self):
+ "Sort the list into natural alphanumeric order."
+
+ characters_list = ["z", "f", "q", "s", "t", "a", "g"]
+ names_list = ["temp1", "publish", "Sample", "Dataset"]
+ sorted_list_a = natural_sort(characters_list)
+ sorted_list_b = natural_sort(names_list)
+ self.assertEqual(sorted_list_a, ["a", "f", "g", "q", "s", "t", "z"])
+ self.assertEqual(
+ sorted_list_b, ["Dataset", "Sample", "publish", "temp1"])
diff --git a/gn2/tests/wqflask/show_trait/test_show_trait.py b/gn2/tests/wqflask/show_trait/test_show_trait.py
new file mode 100644
index 00000000..97618d31
--- /dev/null
+++ b/gn2/tests/wqflask/show_trait/test_show_trait.py
@@ -0,0 +1,255 @@
+"""test for wqflask/show_trait/test_show_trait.py"""
+import unittest
+import pytest
+from unittest import mock
+from gn2.wqflask.show_trait.show_trait import check_if_attr_exists
+from gn2.wqflask.show_trait.show_trait import get_ncbi_summary
+from gn2.wqflask.show_trait.show_trait import has_num_cases
+from gn2.wqflask.show_trait.show_trait import get_table_widths
+from gn2.wqflask.show_trait.show_trait import get_categorical_variables
+from gn2.wqflask.show_trait.show_trait import get_trait_units
+from gn2.wqflask.show_trait.show_trait import get_nearest_marker
+from gn2.wqflask.show_trait.show_trait import get_genotype_scales
+from gn2.wqflask.show_trait.show_trait import get_scales_from_genofile
+
+
+class TraitObject:
+ def __init__(self, obj):
+ self.distinct_values = []
+ self.id = ""
+ for key, value in obj.items():
+ setattr(self, key, value)
+ self.id += str(value)
+
+
+@pytest.mark.parametrize(
+ ('trait', 'id_type', 'expected'),
+ (
+ (TraitObject({"id_type": "id"}), "id_type", True),
+ (TraitObject({"sample_name": ['samp1']}), "id_type", False),
+ (TraitObject({"sample": ""}), "sample", False),
+ (TraitObject({"group": None}), "group", False),
+ (TraitObject({}), "any", False)
+ ),
+)
+def test_check_if_attr_exists(trait, id_type, expected):
+ """"test check_if_attr_exists"""
+ assert check_if_attr_exists(trait, id_type) == expected
+
+
+def test_get_ncbi_summary_request(mocker):
+ trait = TraitObject({"geneid": "id"})
+ mocker.patch("wqflask.show_trait.show_trait.check_if_attr_exists",
+ return_value=True)
+ mock_get = mocker.patch(
+ "wqflask.show_trait.show_trait.requests.get",
+ return_value=TraitObject({"content": """{
+ "result":{
+ "id":{
+ "summary":"this is a summary of the geneid"
+ }
+ }
+ }
+ """}))
+ assert get_ncbi_summary(trait) == "this is a summary of the geneid"
+ mock_get.assert_called_once_with(
+ "http://eutils.ncbi.nlm.nih.gov/entrez/"
+ "eutils/esummary.fcgi?db=gene&id="
+ f"{trait.geneid}&retmode=json"
+ )
+ mock_get.side_effect = Exception("an error occurred")
+ assert get_ncbi_summary(trait) == None
+
+
+class TestTraits(unittest.TestCase):
+ def test_hash_num_cases_is_probeset(self):
+ """test for hash num_cases with dataset.type set to Probeset"""
+ create_dataset = TraitObject({"type": "ProbeSet"})
+ create_trait = TraitObject({"dataset": create_dataset})
+ self.assertFalse(has_num_cases(create_trait))
+
+ def test_hash_num_cases_no_probeset(self):
+ """test for hash num cases with dataset.type not Probeset"""
+ create_dataset = TraitObject({"type": "Temp"})
+ construct_data = {
+ "nm1": TraitObject({"num_cases": False}),
+ "nm2": TraitObject({"num_cases": True}),
+ "nm3": TraitObject({"num_cases": False})
+ }
+ construct_data2 = {
+ "nm1": TraitObject({"num_cases": False}),
+ "nm2": TraitObject({"num_cases": False}),
+ "nm3": TraitObject({"num_cases": False})
+ }
+ create_trait = TraitObject(
+ {"dataset": create_dataset, "data": construct_data})
+ create_trait2 = TraitObject(
+ {"dataset": create_dataset, "data": construct_data2})
+
+ results = has_num_cases(create_trait)
+ self.assertTrue(has_num_cases(create_trait))
+ self.assertFalse(has_num_cases(create_trait2))
+
+ def test_get_table_widths(self):
+ """test for getting table widths"""
+ sample_groups = [TraitObject({'se_exists': True, "attributes": ["attr1", "attr2", "attr3"]}
+ ), TraitObject(
+ {"se_exists": False, "attributes": ["at1", "at2"]
+ })]
+
+ results_with_numcase = get_table_widths(sample_groups, True)
+ result_no_numcase = get_table_widths(sample_groups, False)
+
+ results_one_sample = get_table_widths(
+ [TraitObject({"se_exists": True, "attributes": []})], True)
+ expected_with_numcase = (450, 645)
+ expected_no_numcase = (450, 644)
+ expected_one_sample = (250, 381)
+ self.assertEqual(results_with_numcase, expected_with_numcase)
+ self.assertEqual(result_no_numcase, expected_no_numcase)
+ self.assertEqual(results_one_sample,
+ expected_one_sample)
+
+ def test_get_categorical_variables_no_sample_attributes(self):
+ """test for getting categorical variable names with no samples"""
+ trait = TraitObject({})
+ sample_list = TraitObject({"se_exists": True, "attributes": []})
+ self.assertEqual(get_categorical_variables(trait, sample_list), [])
+
+ def test_get_categorical_variables_with_sample_attributes(self):
+ """test for getting categorical variable names with no samples"""
+ this_trait = TraitObject({"data": {
+ "Gene1": TraitObject({"extra_attributes": {"ex1": "ex1value"}}),
+ "Gene2": TraitObject({"extra_attributes": {"ex2": "ex2value"}}),
+ "Gene3": TraitObject({"extra_attributes": {"ex3": "ex3value"}})
+ }})
+ sample_list = TraitObject({"attributes": {
+ "sample_attribute_1": TraitObject({"name": "ex1"}),
+ "sample_attribute_2": TraitObject({"name": "ex2"}),
+ "sample_attribute_3": TraitObject({"name": "ex3"}),
+ "sample_attribute_4": TraitObject({"name": "not_in_extra_attributes"})
+ }})
+ results = get_categorical_variables(this_trait, sample_list)
+ self.assertEqual(
+ ["ex1", "ex2", "ex3", "not_in_extra_attributes"], results)
+
+ def test_get_trait_units(self):
+ """test for getting trait units"""
+ trait = TraitObject(
+ {"description_fmt": "[this is a description] another test [N/A]"})
+ trait_no_unit_type = TraitObject({"description_fmt": ""})
+ results = get_trait_units(trait)
+ results_no_unit = get_trait_units(trait_no_unit_type)
+ self.assertEqual(results, "this is a descriptionN/A")
+ self.assertEqual(results_no_unit, "value")
+
+ @mock.patch("wqflask.show_trait.show_trait.database_connection")
+ def test_get_nearest_marker(self, mock_db):
+ """test for getting nearest marker with non-empty db"""
+ conn = mock.MagicMock()
+ mock_db.return_value.__enter__.return_value = conn
+ with conn.cursor() as cursor:
+ cursor.fetchall.return_value = [
+ ["Geno1", "Geno2"], ["Geno3"]]
+
+ trait = TraitObject({
+ "locus_chr": "test_chr",
+ "locus_mb": "test_mb"
+ })
+ group_name = TraitObject({"name": "group_name"})
+ this_db = TraitObject({"group": group_name})
+ results_with_item_db = get_nearest_marker(trait, this_db)
+ cursor.execute.assert_called_with(
+ "SELECT Geno.Name FROM Geno, GenoXRef, "
+ "GenoFreeze WHERE Geno.Chr = %s "
+ "AND GenoXRef.GenoId = Geno.Id AND "
+ "GenoFreeze.Id = GenoXRef.GenoFreezeId "
+ "AND GenoFreeze.Name = %s "
+ "ORDER BY ABS( Geno.Mb - %s) LIMIT 1",
+ ('test_chr', 'group_nameGeno', 'test_mb'))
+
+ self.assertEqual(results_with_item_db, "Geno1")
+
+ @mock.patch("wqflask.show_trait.show_trait.database_connection")
+ def test_get_nearest_marker_empty_db(self, mock_db):
+ """test for getting nearest marker with empty db"""
+ conn = mock.MagicMock()
+ mock_db.return_value.__enter__.return_value = conn
+ with conn.cursor() as cursor:
+ cursor.fetchall.return_value = []
+ trait = TraitObject({
+ "locus_chr": "test_chr",
+ "locus_mb": "test_mb"
+ })
+ group_name = TraitObject({"name": "group_name"})
+ this_db = TraitObject({"group": group_name})
+ results_empty_db = get_nearest_marker(trait, this_db)
+ cursor.execute.assert_called_once()
+ self.assertEqual(results_empty_db, "")
+
+ @mock.patch("wqflask.show_trait.show_trait.get_scales_from_genofile")
+ def test_get_genotype_scales_with_genofile_is_list(self, mock_get_scales):
+ """test for getting genotype scales with genofile as list """
+ # where genofile is instance of list
+ genofiles_list = [{"filename": "file1", "location": "~/data/files/f1"},
+ {"filename": "file2", "location": "~/data/files/f2"},
+ {"filename": "file3", "location": "~/data/files/f3"}]
+
+ mock_get_scales.side_effect = [[["morgan", "cM"]],
+ [["morgan", "cM"]],
+ [["physic", "Mb"]]]
+
+ results = get_genotype_scales(genofiles_list)
+ expected_results = {
+ "~/data/files/f1": [["morgan", "cM"]],
+ "~/data/files/f2": [["morgan", "cM"]],
+ "~/data/files/f3": [["physic", "Mb"]]
+ }
+
+ multiple_calls = [mock.call('~/data/files/f1'), mock.call('~/data/files/f2'),
+ mock.call('~/data/files/f3')]
+ mock_get_scales.assert_has_calls(multiple_calls)
+ self.assertEqual(results, expected_results)
+
+ @mock.patch("wqflask.show_trait.show_trait.get_scales_from_genofile")
+ def test_genotype_scales_with_genofile_other(self, mock_get_scales):
+ """test for getting genotype scales with genofile as a string"""
+ file_location = "~/another_file_location"
+ mock_get_scales.return_value = [["physic", "Mb"]]
+ expected_results = {f"{file_location}": [["physic", "Mb"]]}
+ self.assertEqual(get_genotype_scales(file_location), expected_results)
+ mock_get_scales.assert_called_once_with(file_location)
+
+ @mock.patch("wqflask.show_trait.show_trait.locate_ignore_error")
+ def test_get_scales_from_genofile_found(self, mock_ignore_location):
+ """"add test for get scales from genofile where file is found"""
+ mock_ignore_location.return_value = True
+ geno_file = """
+ #sample line with no @scales:other\n
+ #sample line @scales and :separated by semicolon\n
+ This attempts to check whether\n
+ """
+
+ geno_file_string = "@line start with @ and has @scale:morgan"
+
+ file_location = "~/data/file.geno"
+
+ mock_open_geno_file = mock.mock_open(read_data=geno_file)
+ with mock.patch("builtins.open", mock_open_geno_file):
+ results = get_scales_from_genofile(file_location)
+ self.assertEqual(results, [["morgan", "cM"]])
+
+ mock_open_string = mock.mock_open(read_data=geno_file_string)
+
+ with mock.patch("builtins.open", mock_open_string):
+ result2 = get_scales_from_genofile(file_location)
+ self.assertEqual([['morgan', 'cM']], result2)
+
+ @mock.patch("wqflask.show_trait.show_trait.locate_ignore_error")
+ def test_get_scales_from_genofile_not_found(self, mock_location_ignore):
+ mock_location_ignore.return_value = False
+
+ expected_results = [["physic", "Mb"]]
+ results = get_scales_from_genofile("~/data/file")
+ mock_location_ignore.assert_called_once_with("~/data/file", "genotype")
+ self.assertEqual(results, expected_results)