about summary refs log tree commit diff
diff options
context:
space:
mode:
authorzsloan2021-05-05 15:07:02 +0000
committerzsloan2021-05-05 15:07:02 +0000
commita85b41367b420c732b867e777a2d771c4677c360 (patch)
tree41bcffb57f1225f5652b1ff16b63823335994272
parent6ace222ee7fdf6d24d4baa12b0f71e7d8ce453b5 (diff)
parentdad8ae99812555fbb3d7e680f146c98de3322a57 (diff)
downloadgenenetwork2-a85b41367b420c732b867e777a2d771c4677c360.tar.gz
Merge branch 'testing' of github.com:genenetwork/genenetwork2 into testing
-rw-r--r--wqflask/base/species.py83
-rw-r--r--wqflask/tests/unit/base/test_species.py116
-rw-r--r--wqflask/wqflask/api/gen_menu.py10
3 files changed, 166 insertions, 43 deletions
diff --git a/wqflask/base/species.py b/wqflask/base/species.py
index e3c29916..f303aabb 100644
--- a/wqflask/base/species.py
+++ b/wqflask/base/species.py
@@ -1,59 +1,66 @@
-import collections
-
-from flask import Flask, g
-
-
-from utility.logger import getLogger
-logger = getLogger(__name__)
+from collections import OrderedDict
+from dataclasses import dataclass
+from dataclasses import InitVar
+from typing import Optional, Dict
+from flask import g
 
 
+@dataclass
 class TheSpecies:
-    def __init__(self, dataset=None, species_name=None):
-        if species_name != None:
-            self.name = species_name
+    """Data related to species."""
+    dataset: Optional[Dict] = None
+    species_name: Optional[str] = None
+
+    def __post_init__(self):
+        if self.species_name is not None:
+            self.name = self.species_name
             self.chromosomes = Chromosomes(species=self.name)
         else:
-            self.dataset = dataset
             self.chromosomes = Chromosomes(dataset=self.dataset)
 
 
+@dataclass
 class IndChromosome:
-    def __init__(self, name, length):
-        self.name = name
-        self.length = length
+    """Data related to IndChromosome"""
+    name: str
+    length: int
 
     @property
     def mb_length(self):
-        """Chromosome length in megabases"""
+        """Chromosome length in mega-bases"""
         return self.length / 1000000
 
 
+@dataclass
 class Chromosomes:
-    def __init__(self, dataset=None, species=None):
-        self.chromosomes = collections.OrderedDict()
-        if species != None:
-            query = """
-                Select
-                        Chr_Length.Name, Chr_Length.OrderId, Length from Chr_Length, Species
-                where
-                        Chr_Length.SpeciesId = Species.SpeciesId AND
-                        Species.Name = '%s'
-                Order by OrderId
-                """ % species.capitalize()
-        else:
+    """Data related to a chromosome"""
+    dataset: InitVar[Dict] = None
+    species: Optional[str] = None
+
+    def __post_init__(self, dataset):
+        if self.species is None:
             self.dataset = dataset
 
-            query = """
-                Select
-                        Chr_Length.Name, Chr_Length.OrderId, Length from Chr_Length, InbredSet
-                where
-                        Chr_Length.SpeciesId = InbredSet.SpeciesId AND
-                        InbredSet.Name = '%s'
-                Order by OrderId
-                """ % self.dataset.group.name
-        logger.sql(query)
+    @property
+    def chromosomes(self):
+        """Lazily fetch the chromosomes"""
+        chromosomes = OrderedDict()
+        if self.species is not None:
+            query = (
+                "SELECT Chr_Length.Name, Chr_Length.OrderId, Length "
+                "FROM Chr_Length, Species WHERE "
+                "Chr_Length.SpeciesId = Species.SpeciesId AND "
+                "Species.Name = "
+                "'%s' ORDER BY OrderId" % self.species.capitalize())
+        else:
+            query = (
+                "SELECT Chr_Length.Name, Chr_Length.OrderId, "
+                "Length FROM Chr_Length, InbredSet WHERE "
+                "Chr_Length.SpeciesId = InbredSet.SpeciesId AND "
+                "InbredSet.Name = "
+                "'%s' ORDER BY OrderId" % self.dataset.group.name)
         results = g.db.execute(query).fetchall()
-
         for item in results:
-            self.chromosomes[item.OrderId] = IndChromosome(
+            chromosomes[item.OrderId] = IndChromosome(
                 item.Name, item.Length)
+        return chromosomes
diff --git a/wqflask/tests/unit/base/test_species.py b/wqflask/tests/unit/base/test_species.py
new file mode 100644
index 00000000..9b5c023c
--- /dev/null
+++ b/wqflask/tests/unit/base/test_species.py
@@ -0,0 +1,116 @@
+"""Tests wqflask/base/species.py"""
+
+import unittest
+from unittest import mock
+from base.species import TheSpecies
+from base.species import IndChromosome
+from base.species import Chromosomes
+from collections import OrderedDict
+from wqflask import app
+from dataclasses import dataclass
+
+
+@dataclass
+class MockChromosome:
+    OrderId: int
+    Name: str
+    Length: int
+
+
+@dataclass
+class MockGroup:
+    name: str
+
+
+@dataclass
+class MockDataset:
+    group: MockGroup
+
+
+class TestTheSpecies(unittest.TestCase):
+    """Tests for TheSpecies class"""
+    @mock.patch('base.species.Chromosomes')
+    def test_create_species_with_null_species_name(self, mock_chromosome):
+        """Test that TheSpecies is instantiated correctly when the
+species_name is provided."""
+        mock_chromosome.return_value = 1
+        test_species = TheSpecies(dataset="random_dataset", species_name="a")
+        self.assertEqual(test_species.name, "a")
+        self.assertEqual(test_species.chromosomes, 1)
+
+    @mock.patch('base.species.Chromosomes')
+    def test_create_species_with_species_name(self, mock_chromosome):
+        """Test that TheSpecies is instantiated correctly when the
+species_name is not provided."""
+        mock_chromosome.return_value = 1
+        test_species = TheSpecies(dataset="random_dataset")
+        self.assertEqual(test_species.dataset, "random_dataset")
+        self.assertEqual(test_species.chromosomes, 1)
+        mock_chromosome.assert_called_once_with(dataset="random_dataset")
+
+
+class TestIndChromosome(unittest.TestCase):
+    """Tests for IndChromosome class"""
+
+    def test_create_ind_chromosome(self):
+        """Test that IndChromosome is instantiated correctly"""
+        test_ind_chromosome = IndChromosome(name="Test", length=10000000)
+        self.assertEqual(test_ind_chromosome.name, "Test")
+        self.assertEqual(test_ind_chromosome.length, 10000000)
+        self.assertEqual(test_ind_chromosome.mb_length, 10)
+
+
+class TestChromosomes(unittest.TestCase):
+    """Tests for Chromosomes class"""
+    maxDiff = None
+
+    def setUp(self):
+        self.app_context = app.app_context()
+        self.app_context.push()
+
+    def tearDown(self):
+        self.app_context.pop()
+
+    @mock.patch("base.species.g")
+    def test_create_chromosomes_with_no_species(self, mock_db):
+        """Test instantiating a chromosome without a species"""
+        mock_db.db.execute.return_value.fetchall.return_value = [
+            MockChromosome(1, "X", 100),
+            MockChromosome(2, "Y", 1000),
+            MockChromosome(3, "Z", 10000),
+        ]
+        mock_dataset = MockDataset(MockGroup("Random"))
+        test_chromosomes = Chromosomes(dataset=mock_dataset)
+        self.assertEqual(
+            list(test_chromosomes.chromosomes.keys()),
+            [1, 2, 3]
+        )
+        self.assertEqual(test_chromosomes.dataset, mock_dataset)
+        mock_db.db.execute.assert_called_with(
+            "SELECT Chr_Length.Name, Chr_Length.OrderId, Length "
+            "FROM Chr_Length, InbredSet WHERE "
+            "Chr_Length.SpeciesId = InbredSet.SpeciesId AND "
+            "InbredSet.Name = 'Random' ORDER BY OrderId"
+        )
+
+    @mock.patch("base.species.g")
+    def test_create_chromosomes_with_species(self, mock_db):
+        """Test instantiating a chromosome with a species"""
+        mock_db.db.execute.return_value.fetchall.return_value = [
+            MockChromosome(1, "X", 100),
+            MockChromosome(2, "Y", 1000),
+            MockChromosome(3, "Z", 10000),
+        ]
+        mock_dataset = MockDataset(MockGroup("Random"))
+        test_chromosomes = Chromosomes(dataset=mock_dataset,
+                                       species="testSpecies")
+        self.assertEqual(
+            list(test_chromosomes.chromosomes.keys()),
+            [1, 2, 3]
+        )
+        mock_db.db.execute.assert_called_with(
+            "SELECT Chr_Length.Name, Chr_Length.OrderId, Length "
+            "FROM Chr_Length, Species WHERE "
+            "Chr_Length.SpeciesId = Species.SpeciesId AND "
+            "Species.Name = 'Testspecies' ORDER BY OrderId"
+        )
diff --git a/wqflask/wqflask/api/gen_menu.py b/wqflask/wqflask/api/gen_menu.py
index e65b36e4..7f4ec1bc 100644
--- a/wqflask/wqflask/api/gen_menu.py
+++ b/wqflask/wqflask/api/gen_menu.py
@@ -178,12 +178,12 @@ def build_datasets(species, group, type_name):
 
     elif type_name == "Genotypes":
         results = g.db.execute(
-            ("SELECT InfoFiles.GN_AccesionId " +
+            ("SELECT InfoFiles.GN_AccesionId "
              "FROM InfoFiles, GenoFreeze, InbredSet "
-             + "WHERE InbredSet.Name = '{}' AND "
-             + "GenoFreeze.InbredSetId = InbredSet.Id AND "
-             + "InfoFiles.InfoPageName = GenoFreeze.ShortName "
-             + "ORDER BY GenoFreeze.CreateTime DESC").format(group)).fetchone()
+             "WHERE InbredSet.Name = '{}' AND "
+             "GenoFreeze.InbredSetId = InbredSet.Id AND "
+             "InfoFiles.InfoPageName = GenoFreeze.ShortName "
+             "ORDER BY GenoFreeze.CreateTime DESC").format(group)).fetchone()
 
         dataset_id = "None"
         if bool(results):