--
cgit v1.2.3
From 64c0c61ee3842ea63921ebb73827333d91cf99cc Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 17 Jul 2020 02:47:31 +0300
Subject: Add basic unittests
---
test/unittest/__init__.py | 0
test/unittest/base/__init__.py | 0
test/unittest/base/test_data_set.py | 8 ++++++++
test/unittest/base/test_general_object.py | 21 +++++++++++++++++++++
4 files changed, 29 insertions(+)
create mode 100644 test/unittest/__init__.py
create mode 100644 test/unittest/base/__init__.py
create mode 100644 test/unittest/base/test_data_set.py
create mode 100644 test/unittest/base/test_general_object.py
diff --git a/test/unittest/__init__.py b/test/unittest/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/test/unittest/base/__init__.py b/test/unittest/base/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/test/unittest/base/test_data_set.py b/test/unittest/base/test_data_set.py
new file mode 100644
index 00000000..6537efa6
--- /dev/null
+++ b/test/unittest/base/test_data_set.py
@@ -0,0 +1,8 @@
+import unittest
+
+import wqflask.base.data_set
+print dir()
+
+class TestDataSet(unittest.TestCase):
+ def test_add(self):
+ self.assertEqual(3, 4)
diff --git a/test/unittest/base/test_general_object.py b/test/unittest/base/test_general_object.py
new file mode 100644
index 00000000..eaefdec9
--- /dev/null
+++ b/test/unittest/base/test_general_object.py
@@ -0,0 +1,21 @@
+import unittest
+
+from wqflask.base.GeneralObject import GeneralObject
+
+
+class TestGeneralObjectTests(unittest.TestCase):
+ """
+ Test the GeneralObject base class
+ """
+
+ def test_object_contents(self):
+ """Test whether base contents are stored properly"""
+ test_obj = GeneralObject("a", "b", "c")
+ self.assertEqual("abc", ''.join(test_obj.contents))
+
+ def test_object_dict(self):
+ """Test whether the base class is printed properly"""
+ test_obj = GeneralObject("a", name="test", value=1)
+ self.assertEqual(str(test_obj), "value = 1\nname = test\n")
+ self.assertEqual(
+ repr(test_obj), "value = 1\nname = test\ncontents = ['a']\n")
--
cgit v1.2.3
From b11d28f4cd90d7f5599324961ec405c5d026b309 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Sat, 18 Jul 2020 03:41:00 +0300
Subject: Remove unused import
---
wqflask/base/data_set.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index 2272b6ee..116d1d24 100644
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -47,8 +47,6 @@ from utility import chunks
from utility import gen_geno_ob
from utility.tools import locate, locate_ignore_error, flat_files
-from wqflask.api import gen_menu
-
from maintenance import get_group_samplelists
from MySQLdb import escape_string as escape
@@ -64,6 +62,9 @@ logger = getLogger(__name__ )
# Each subclass will add to this
DS_NAME_MAP = {}
+def my_add(x, y):
+ return x + y
+
def create_dataset(dataset_name, dataset_type = None, get_samplelist = True, group_name = None):
if dataset_name == "Temp":
dataset_type = "Temp"
--
cgit v1.2.3
From b362f2586c182c0400bd40e260c9d25240858790 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Sat, 18 Jul 2020 03:41:38 +0300
Subject: Remove unused config
---
wqflask/wqflask/__init__.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py
index 62e98b36..d729aef5 100644
--- a/wqflask/wqflask/__init__.py
+++ b/wqflask/wqflask/__init__.py
@@ -12,7 +12,6 @@ logging.basicConfig(level=logging.INFO)
app = Flask(__name__)
-app.config.from_object('cfg.default_settings') # Get the defaults from cfg.default_settings
app.config.from_envvar('GN2_SETTINGS') # See http://flask.pocoo.org/docs/config/#configuring-from-files
# Note no longer use the badly named WQFLASK_OVERRIDES (nyi)
@@ -22,4 +21,4 @@ app.jinja_env.globals.update(
)
from wqflask.api import router
-import wqflask.views
\ No newline at end of file
+import wqflask.views
--
cgit v1.2.3
From f4e61929d0eb490dbf7e8ddc03a20d42d44b6f5c Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 12:36:06 +0300
Subject: Add work-around for failed imports in unittest
* wqflask/utility/tools.py: Unittests will use `from wqflask.wqflask import app`
and the gn2 script will use `from wqflask import app`
---
wqflask/utility/tools.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py
index 77db5d53..37f9d8fe 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -5,7 +5,10 @@ import os
import sys
import json
-from wqflask import app
+try:
+ from wqflask import app
+except ImportError:
+ from wqflask.wqflask import app
# Use the standard logger here to avoid a circular dependency
import logging
--
cgit v1.2.3
From 5db20299b046e37fcb3517e89c3ecf527e7db657 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 12:40:37 +0300
Subject: Remove mock directory
* wqflask/mock: Delete it. Causes name conflicts with Python's mock module
---
wqflask/mock/__init__.py | 0
wqflask/mock/es_double.py | 15 ---------------
2 files changed, 15 deletions(-)
delete mode 100644 wqflask/mock/__init__.py
delete mode 100644 wqflask/mock/es_double.py
diff --git a/wqflask/mock/__init__.py b/wqflask/mock/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/wqflask/mock/es_double.py b/wqflask/mock/es_double.py
deleted file mode 100644
index 6ef8a1b9..00000000
--- a/wqflask/mock/es_double.py
+++ /dev/null
@@ -1,15 +0,0 @@
-class ESDouble(object):
- def __init__(self):
- self.items = {}
-
- def ping(self):
- return true
-
- def create(self, index, doc_type, body, id):
- self.items["index"] = {doc_type: {"id": id, "_source": data}}
-
- def search(self, index, doc_type, body):
- return {
- "hits": {
- "hits": self.items[index][doc_type][body]
- }}
--
cgit v1.2.3
From 244761531dd6f4f019add26d837b6b79530e0f17 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 12:42:52 +0300
Subject: Make test file a module
* test/__init__.py: Add it.
Makes the test folder discoverable by unittest
---
test/__init__.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test/__init__.py
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 00000000..e69de29b
--
cgit v1.2.3
From 511acaccdad93d2766f973ada11ae2b85367e6ef Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 13:22:46 +0300
Subject: Apply autopep-8
* wqflask/base/GeneralObject.py: Replace tabs with 4 spaces
---
wqflask/base/GeneralObject.py | 80 +++++++++++++++++++++----------------------
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/wqflask/base/GeneralObject.py b/wqflask/base/GeneralObject.py
index 02a1ef06..37bfeda3 100644
--- a/wqflask/base/GeneralObject.py
+++ b/wqflask/base/GeneralObject.py
@@ -25,44 +25,44 @@
# Last updated by GeneNetwork Core Team 2010/10/20
class GeneralObject:
- """
- Base class to define an Object.
- a = [Spam(1, 4), Spam(9, 3), Spam(4,6)]
- a.sort(lambda x, y: cmp(x.eggs, y.eggs))
- """
+ """
+ Base class to define an Object.
+ a = [Spam(1, 4), Spam(9, 3), Spam(4,6)]
+ a.sort(lambda x, y: cmp(x.eggs, y.eggs))
+ """
- def __init__(self, *args, **kw):
- self.contents = list(args)
- for name, value in kw.items():
- setattr(self, name, value)
-
- def __setitem__(self, key, value):
- setattr(self, key, value)
-
- def __getitem__(self, key):
- return getattr(self, key)
-
- def __getattr__(self, key):
- if key in self.__dict__.keys():
- return self.__dict__[key]
- else:
- return eval("self.__dict__.%s" % key)
-
- def __len__(self):
- return len(self.__dict__) - 1
-
- def __str__(self):
- s = ''
- for key in self.__dict__.keys():
- if key != 'contents':
- s += '%s = %s\n' % (key,self.__dict__[key])
- return s
-
- def __repr__(self):
- s = ''
- for key in self.__dict__.keys():
- s += '%s = %s\n' % (key,self.__dict__[key])
- return s
-
- def __cmp__(self,other):
- return len(self.__dict__.keys()).__cmp__(len(other.__dict__.keys()))
\ No newline at end of file
+ def __init__(self, *args, **kw):
+ self.contents = list(args)
+ for name, value in kw.items():
+ setattr(self, name, value)
+
+ def __setitem__(self, key, value):
+ setattr(self, key, value)
+
+ def __getitem__(self, key):
+ return getattr(self, key)
+
+ def __getattr__(self, key):
+ if key in self.__dict__.keys():
+ return self.__dict__[key]
+ else:
+ return eval("self.__dict__.%s" % key)
+
+ def __len__(self):
+ return len(self.__dict__) - 1
+
+ def __str__(self):
+ s = ''
+ for key in self.__dict__.keys():
+ if key != 'contents':
+ s += '%s = %s\n' % (key, self.__dict__[key])
+ return s
+
+ def __repr__(self):
+ s = ''
+ for key in self.__dict__.keys():
+ s += '%s = %s\n' % (key, self.__dict__[key])
+ return s
+
+ def __cmp__(self, other):
+ return len(self.__dict__.keys()).__cmp__(len(other.__dict__.keys()))
--
cgit v1.2.3
From 2cbda12fe9fa9fca4d27796b2a8eb719e659dc7f Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 21:53:30 +0300
Subject: Revert "Add work-around for failed imports in unittest"
This reverts commit d5e87fa6fe7546b46790f512d984a5501223082f.
---
wqflask/utility/tools.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py
index 37f9d8fe..77db5d53 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -5,10 +5,7 @@ import os
import sys
import json
-try:
- from wqflask import app
-except ImportError:
- from wqflask.wqflask import app
+from wqflask import app
# Use the standard logger here to avoid a circular dependency
import logging
--
cgit v1.2.3
From 7dff20b84aaab9c5c9e15269a1716cd14d953db1 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 22:40:14 +0300
Subject: Apply autopep-8
* wqflask/base/data_set.py: Apply autopep-8
---
wqflask/base/data_set.py | 261 +++++++++++++++++++++++++----------------------
1 file changed, 141 insertions(+), 120 deletions(-)
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index 116d1d24..f9705a22 100644
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -19,6 +19,23 @@
# This module is used by GeneNetwork project (www.genenetwork.org)
from __future__ import absolute_import, print_function, division
+from db.call import fetchall, fetchone, fetch1
+from utility.logger import getLogger
+from utility.tools import USE_GN_SERVER, USE_REDIS, flat_files, flat_file_exists, GN2_BASE_URL
+from db.gn_server import menu_main
+from pprint import pformat as pf
+from MySQLdb import escape_string as escape
+from maintenance import get_group_samplelists
+from utility.tools import locate, locate_ignore_error, flat_files
+from utility import gen_geno_ob
+from utility import chunks
+from utility.benchmark import Bench
+from utility import webqtlUtil
+from db import webqtlDatabaseFunction
+from base import species
+from base import webqtlConfig
+import reaper
+from flask import Flask, g
import os
import math
import string
@@ -34,38 +51,15 @@ import itertools
from redis import Redis
Redis = Redis()
-from flask import Flask, g
-
-import reaper
-
-from base import webqtlConfig
-from base import species
-from db import webqtlDatabaseFunction
-from utility import webqtlUtil
-from utility.benchmark import Bench
-from utility import chunks
-from utility import gen_geno_ob
-from utility.tools import locate, locate_ignore_error, flat_files
-
-from maintenance import get_group_samplelists
-from MySQLdb import escape_string as escape
-from pprint import pformat as pf
-from db.gn_server import menu_main
-from db.call import fetchall,fetchone,fetch1
-
-from utility.tools import USE_GN_SERVER, USE_REDIS, flat_files, flat_file_exists, GN2_BASE_URL
-from utility.logger import getLogger
-logger = getLogger(__name__ )
+logger = getLogger(__name__)
# Used by create_database to instantiate objects
# Each subclass will add to this
DS_NAME_MAP = {}
-def my_add(x, y):
- return x + y
-def create_dataset(dataset_name, dataset_type = None, get_samplelist = True, group_name = None):
+def create_dataset(dataset_name, dataset_type=None, get_samplelist=True, group_name=None):
if dataset_name == "Temp":
dataset_type = "Temp"
@@ -79,6 +73,7 @@ def create_dataset(dataset_name, dataset_type = None, get_samplelist = True, gro
else:
return dataset_class(dataset_name, get_samplelist)
+
class Dataset_Types(object):
def __init__(self):
@@ -101,9 +96,10 @@ Publish or ProbeSet. E.g.
data = Redis.get("dataset_structure")
if data:
self.datasets = json.loads(data)
- else: #ZS: I don't think this should ever run unless Redis is emptied
+ else: # ZS: I don't think this should ever run unless Redis is emptied
try:
- data = json.loads(requests.get(GN2_BASE_URL + "/api/v_pre1/gen_dropdown", timeout = 5).content)
+ data = json.loads(requests.get(
+ GN2_BASE_URL + "/api/v_pre1/gen_dropdown", timeout=5).content)
for species in data['datasets']:
for group in data['datasets'][species]:
for dataset_type in data['datasets'][species][group]:
@@ -122,7 +118,7 @@ Publish or ProbeSet. E.g.
Redis.set("dataset_structure", json.dumps(self.datasets))
# Set LOG_LEVEL_DEBUG=5 to see the following:
- logger.debugf(5, "datasets",self.datasets)
+ logger.debugf(5, "datasets", self.datasets)
def __call__(self, name):
if name not in self.datasets:
@@ -155,7 +151,7 @@ Publish or ProbeSet. E.g.
Redis.set("dataset_structure", json.dumps(self.datasets))
return self.datasets[name]
- #ZS: For when there isn't an InfoFiles ID; not sure if this and the preceding query are both necessary
+ # ZS: For when there isn't an InfoFiles ID; not sure if this and the preceding query are both necessary
other_pheno_query = """SELECT PublishFreeze.Name
FROM PublishFreeze, InbredSet
WHERE InbredSet.Name = '{}' AND
@@ -167,7 +163,7 @@ Publish or ProbeSet. E.g.
Redis.set("dataset_structure", json.dumps(self.datasets))
return self.datasets[name]
- geno_query = """
+ geno_query = """
SELECT
GenoFreeze.Id
FROM
@@ -182,14 +178,16 @@ Publish or ProbeSet. E.g.
Redis.set("dataset_structure", json.dumps(self.datasets))
return self.datasets[name]
- #ZS: It shouldn't ever reach this
+ # ZS: It shouldn't ever reach this
return None
else:
return self.datasets[name]
+
# Do the intensive work at startup one time only
Dataset_Getter = Dataset_Types()
+
def create_datasets_list():
if USE_REDIS:
key = "all_datasets"
@@ -209,10 +207,10 @@ def create_datasets_list():
for dataset_type in type_dict:
query = "SELECT Name FROM {}".format(type_dict[dataset_type])
for result in fetchall(query):
- #The query at the beginning of this function isn't
- #necessary here, but still would rather just reuse
- #it logger.debug("type: {}\tname:
- #{}".format(dataset_type, result.Name))
+ # The query at the beginning of this function isn't
+ # necessary here, but still would rather just reuse
+ # it logger.debug("type: {}\tname:
+ # {}".format(dataset_type, result.Name))
dataset = create_dataset(result.Name, dataset_type)
datasets.append(dataset)
@@ -239,8 +237,9 @@ def mescape(*items):
class Markers(object):
"""Todo: Build in cacheing so it saves us reading the same file more than once"""
+
def __init__(self, name):
- json_data_fh = open(locate(name + ".json",'genotype/json'))
+ json_data_fh = open(locate(name + ".json", 'genotype/json'))
markers = []
with open("%s/%s_snps.txt" % (flat_files('genotype/bimbam'), name), 'r') as bimbam_fh:
@@ -272,7 +271,7 @@ class Markers(object):
if type(p_values) is list:
# THIS IS only needed for the case when we are limiting the number of p-values calculated
- #if len(self.markers) > len(p_values):
+ # if len(self.markers) > len(p_values):
# self.markers = self.markers[:len(p_values)]
for marker, p_value in itertools.izip(self.markers, p_values):
@@ -284,7 +283,7 @@ class Markers(object):
marker['lrs_value'] = 0
else:
marker['lod_score'] = -math.log10(marker['p_value'])
- #Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values
+ # Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values
marker['lrs_value'] = -math.log10(marker['p_value']) * 4.61
elif type(p_values) is dict:
filtered_markers = []
@@ -299,18 +298,20 @@ class Markers(object):
marker['lrs_value'] = 0
else:
marker['lod_score'] = -math.log10(marker['p_value'])
- #Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values
- marker['lrs_value'] = -math.log10(marker['p_value']) * 4.61
+ # Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values
+ marker['lrs_value'] = - \
+ math.log10(marker['p_value']) * 4.61
filtered_markers.append(marker)
- #else:
+ # else:
#logger.debug("marker {} NOT in p_values".format(i))
- #self.markers.remove(marker)
+ # self.markers.remove(marker)
#del self.markers[i]
self.markers = filtered_markers
+
class HumanMarkers(Markers):
- def __init__(self, name, specified_markers = []):
+ def __init__(self, name, specified_markers=[]):
marker_data_fh = open(flat_files('mapping') + '/' + name + '.bim')
self.markers = []
for line in marker_data_fh:
@@ -333,7 +334,6 @@ class HumanMarkers(Markers):
#logger.debug("markers is: ", pf(self.markers))
-
def add_pvalues(self, p_values):
super(HumanMarkers, self).add_pvalues(p_values)
@@ -346,12 +346,15 @@ class DatasetGroup(object):
has multiple datasets associated with it.
"""
+
def __init__(self, dataset, name=None):
"""This sets self.group and self.group_id"""
if name == None:
- self.name, self.id, self.genetic_type = fetchone(dataset.query_for_group)
+ self.name, self.id, self.genetic_type = fetchone(
+ dataset.query_for_group)
else:
- self.name, self.id, self.genetic_type = fetchone("SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType FROM InbredSet where Name='%s'" % name)
+ self.name, self.id, self.genetic_type = fetchone(
+ "SELECT InbredSet.Name, InbredSet.Id, InbredSet.GeneticType FROM InbredSet where Name='%s'" % name)
if self.name == 'BXD300':
self.name = "BXD"
@@ -370,7 +373,8 @@ class DatasetGroup(object):
def get_mapping_methods(self):
- mapping_id = g.db.execute("select MappingMethodId from InbredSet where Name= '%s'" % self.name).fetchone()[0]
+ mapping_id = g.db.execute(
+ "select MappingMethodId from InbredSet where Name= '%s'" % self.name).fetchone()[0]
if mapping_id == "1":
mapping_names = ["GEMMA", "QTLReaper", "R/qtl"]
elif mapping_id == "2":
@@ -434,9 +438,10 @@ class DatasetGroup(object):
else:
logger.debug("Cache not hit")
- genotype_fn = locate_ignore_error(self.name+".geno",'genotype')
+ genotype_fn = locate_ignore_error(self.name+".geno", 'genotype')
if genotype_fn:
- self.samplelist = get_group_samplelists.get_samplelist("geno", genotype_fn)
+ self.samplelist = get_group_samplelists.get_samplelist(
+ "geno", genotype_fn)
else:
self.samplelist = None
@@ -452,15 +457,16 @@ class DatasetGroup(object):
def read_genotype_file(self, use_reaper=False):
'''Read genotype from .geno file instead of database'''
- #genotype_1 is Dataset Object without parents and f1
- #genotype_2 is Dataset Object with parents and f1 (not for intercross)
+ # genotype_1 is Dataset Object without parents and f1
+ # genotype_2 is Dataset Object with parents and f1 (not for intercross)
#genotype_1 = reaper.Dataset()
# reaper barfs on unicode filenames, so here we ensure it's a string
if self.genofile:
- if "RData" in self.genofile: #ZS: This is a temporary fix; I need to change the way the JSON files that point to multiple genotype files are structured to point to other file types like RData
- full_filename = str(locate(self.genofile.split(".")[0] + ".geno", 'genotype'))
+ if "RData" in self.genofile: # ZS: This is a temporary fix; I need to change the way the JSON files that point to multiple genotype files are structured to point to other file types like RData
+ full_filename = str(
+ locate(self.genofile.split(".")[0] + ".geno", 'genotype'))
else:
full_filename = str(locate(self.genofile, 'genotype'))
else:
@@ -473,11 +479,12 @@ class DatasetGroup(object):
genotype_1 = gen_geno_ob.genotype(full_filename)
if genotype_1.type == "group" and self.parlist:
- genotype_2 = genotype_1.add(Mat=self.parlist[0], Pat=self.parlist[1]) #, F1=_f1)
+ genotype_2 = genotype_1.add(
+ Mat=self.parlist[0], Pat=self.parlist[1]) # , F1=_f1)
else:
genotype_2 = genotype_1
- #determine default genotype object
+ # determine default genotype object
if self.incparentsf1 and genotype_1.type != "intercross":
genotype = genotype_2
else:
@@ -488,7 +495,8 @@ class DatasetGroup(object):
return genotype
-def datasets(group_name, this_group = None):
+
+def datasets(group_name, this_group=None):
key = "group_dataset_menu:v2:" + group_name
dataset_menu = []
the_results = fetchall('''
@@ -511,12 +519,13 @@ def datasets(group_name, this_group = None):
and InbredSet.Name like %s
ORDER BY Tissue.Name, ProbeSetFreeze.OrderList DESC)
''' % (group_name,
- group_name,
- "'" + group_name + "'"))
+ group_name,
+ "'" + group_name + "'"))
sorted_results = sorted(the_results, key=lambda kv: kv[0])
- pheno_inserted = False #ZS: This is kind of awkward, but need to ensure Phenotypes show up before Genotypes in dropdown
+ # ZS: This is kind of awkward, but need to ensure Phenotypes show up before Genotypes in dropdown
+ pheno_inserted = False
geno_inserted = False
for dataset_item in sorted_results:
tissue_name = dataset_item[0]
@@ -524,13 +533,16 @@ def datasets(group_name, this_group = None):
dataset_short = dataset_item[2]
if tissue_name in ['#PublishFreeze', '#GenoFreeze']:
if tissue_name == '#PublishFreeze' and (dataset_short == group_name + 'Publish'):
- dataset_menu.insert(0, dict(tissue=None, datasets=[(dataset, dataset_short)]))
+ dataset_menu.insert(
+ 0, dict(tissue=None, datasets=[(dataset, dataset_short)]))
pheno_inserted = True
elif pheno_inserted and tissue_name == '#GenoFreeze':
- dataset_menu.insert(1, dict(tissue=None, datasets=[(dataset, dataset_short)]))
+ dataset_menu.insert(
+ 1, dict(tissue=None, datasets=[(dataset, dataset_short)]))
geno_inserted = True
else:
- dataset_menu.append(dict(tissue=None, datasets=[(dataset, dataset_short)]))
+ dataset_menu.append(
+ dict(tissue=None, datasets=[(dataset, dataset_short)]))
else:
tissue_already_exists = False
for i, tissue_dict in enumerate(dataset_menu):
@@ -543,7 +555,7 @@ def datasets(group_name, this_group = None):
dataset_menu[i]['datasets'].append((dataset, dataset_short))
else:
dataset_menu.append(dict(tissue=tissue_name,
- datasets=[(dataset, dataset_short)]))
+ datasets=[(dataset, dataset_short)]))
if USE_REDIS:
Redis.set(key, pickle.dumps(dataset_menu, pickle.HIGHEST_PROTOCOL))
@@ -555,6 +567,7 @@ def datasets(group_name, this_group = None):
else:
return dataset_menu
+
class DataSet(object):
"""
DataSet class defines a dataset in webqtl, can be either Microarray,
@@ -562,7 +575,7 @@ class DataSet(object):
"""
- def __init__(self, name, get_samplelist = True, group_name = None):
+ def __init__(self, name, get_samplelist=True, group_name=None):
assert name, "Need a name"
self.name = name
@@ -570,22 +583,23 @@ class DataSet(object):
self.shortname = None
self.fullname = None
self.type = None
- self.data_scale = None #ZS: For example log2
+ self.data_scale = None # ZS: For example log2
self.setup()
- if self.type == "Temp": #Need to supply group name as input if temp trait
- self.group = DatasetGroup(self, name=group_name) # sets self.group and self.group_id and gets genotype
+ if self.type == "Temp": # Need to supply group name as input if temp trait
+ # sets self.group and self.group_id and gets genotype
+ self.group = DatasetGroup(self, name=group_name)
else:
self.check_confidentiality()
self.retrieve_other_names()
- self.group = DatasetGroup(self) # sets self.group and self.group_id and gets genotype
+ # sets self.group and self.group_id and gets genotype
+ self.group = DatasetGroup(self)
self.accession_id = self.get_accession_id()
if get_samplelist == True:
- self.group.get_samplelist()
+ self.group.get_samplelist()
self.species = species.TheSpecies(self)
-
def get_desc(self):
"""Gets overridden later, at least for Temp...used by trait's get_given_name"""
return None
@@ -645,8 +659,9 @@ class DataSet(object):
WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id
AND ProbeFreeze.TissueId = Tissue.Id
AND (ProbeSetFreeze.Name = '%s' OR ProbeSetFreeze.FullName = '%s' OR ProbeSetFreeze.ShortName = '%s')
- """ % (query_args),"/dataset/"+self.name+".json",
- lambda r: (r["id"],r["name"],r["full_name"],r["short_name"],r["data_scale"],r["tissue"])
+ """ % (query_args), "/dataset/"+self.name+".json",
+ lambda r: (r["id"], r["name"], r["full_name"],
+ r["short_name"], r["data_scale"], r["tissue"])
)
else:
query_args = tuple(escape(x) for x in (
@@ -663,7 +678,8 @@ class DataSet(object):
""" % (query_args))
except TypeError:
- logger.debug("Dataset {} is not yet available in GeneNetwork.".format(self.name))
+ logger.debug(
+ "Dataset {} is not yet available in GeneNetwork.".format(self.name))
pass
def get_trait_data(self, sample_list=None):
@@ -721,7 +737,7 @@ class DataSet(object):
and {}.Id = {}XRef.{}Id
order by {}.Id
""".format(*mescape(self.type, self.type, self.type, self.name,
- dataset_type, self.type, dataset_type, dataset_type))
+ dataset_type, self.type, dataset_type, dataset_type))
else:
query += """
WHERE {}XRef.{}FreezeId = {}Freeze.Id
@@ -729,7 +745,7 @@ class DataSet(object):
and {}.Id = {}XRef.{}Id
order by {}.Id
""".format(*mescape(self.type, self.type, self.type, self.type,
- self.name, dataset_type, self.type, self.type, dataset_type))
+ self.name, dataset_type, self.type, self.type, dataset_type))
#logger.debug("trait data query: ", query)
@@ -749,6 +765,7 @@ class DataSet(object):
self.trait_data[trait_name] += (
trait_sample_data[chunk_counter][trait_counter][data_start_pos:])
+
class PhenotypeDataSet(DataSet):
DS_NAME_MAP['Publish'] = 'PhenotypeDataSet'
@@ -758,16 +775,16 @@ class PhenotypeDataSet(DataSet):
# Fields in the database table
self.search_fields = ['Phenotype.Post_publication_description',
- 'Phenotype.Pre_publication_description',
- 'Phenotype.Pre_publication_abbreviation',
- 'Phenotype.Post_publication_abbreviation',
- 'PublishXRef.mean',
- 'Phenotype.Lab_code',
- 'Publication.PubMed_ID',
- 'Publication.Abstract',
- 'Publication.Title',
- 'Publication.Authors',
- 'PublishXRef.Id']
+ 'Phenotype.Pre_publication_description',
+ 'Phenotype.Pre_publication_abbreviation',
+ 'Phenotype.Post_publication_abbreviation',
+ 'PublishXRef.mean',
+ 'Phenotype.Lab_code',
+ 'Publication.PubMed_ID',
+ 'Publication.Abstract',
+ 'Publication.Title',
+ 'Publication.Authors',
+ 'PublishXRef.Id']
# Figure out what display_fields is
self.display_fields = ['name', 'group_code',
@@ -789,13 +806,13 @@ class PhenotypeDataSet(DataSet):
# Fields displayed in the search results table header
self.header_fields = ['Index',
- 'Record',
- 'Description',
- 'Authors',
- 'Year',
- 'Max LRS',
- 'Max LRS Location',
- 'Additive Effect']
+ 'Record',
+ 'Description',
+ 'Authors',
+ 'Year',
+ 'Max LRS',
+ 'Max LRS Location',
+ 'Additive Effect']
self.type = 'Publish'
@@ -813,7 +830,7 @@ class PhenotypeDataSet(DataSet):
# (Urgently?) Need to write this
pass
- def get_trait_info(self, trait_list, species = ''):
+ def get_trait_info(self, trait_list, species=''):
for this_trait in trait_list:
if not this_trait.haveinfo:
@@ -821,9 +838,9 @@ class PhenotypeDataSet(DataSet):
description = this_trait.post_publication_description
- #If the dataset is confidential and the user has access to confidential
- #phenotype traits, then display the pre-publication description instead
- #of the post-publication description
+ # If the dataset is confidential and the user has access to confidential
+ # phenotype traits, then display the pre-publication description instead
+ # of the post-publication description
if this_trait.confidential:
this_trait.description_display = ""
continue # for now, because no authorization features
@@ -848,7 +865,7 @@ class PhenotypeDataSet(DataSet):
if this_trait.pubmed_id:
this_trait.pubmed_link = webqtlConfig.PUBMEDLINK_URL % this_trait.pubmed_id
- #LRS and its location
+ # LRS and its location
this_trait.LRS_score_repr = "N/A"
this_trait.LRS_location_repr = "N/A"
@@ -868,7 +885,8 @@ class PhenotypeDataSet(DataSet):
LRS_Mb = result[1]
this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs
- this_trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb))
+ this_trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (
+ LRS_Chr, float(LRS_Mb))
def retrieve_sample_data(self, trait):
query = """
@@ -935,7 +953,8 @@ class GenotypeDataSet(DataSet):
this_trait.retrieveInfo()
if this_trait.chr and this_trait.mb:
- this_trait.location_repr = 'Chr%s: %.6f' % (this_trait.chr, float(this_trait.mb) )
+ this_trait.location_repr = 'Chr%s: %.6f' % (
+ this_trait.chr, float(this_trait.mb))
def retrieve_sample_data(self, trait):
query = """
@@ -1004,14 +1023,14 @@ class MrnaAssayDataSet(DataSet):
# Fields displayed in the search results table header
self.header_fields = ['Index',
- 'Record',
- 'Symbol',
- 'Description',
- 'Location',
- 'Mean',
- 'Max LRS',
- 'Max LRS Location',
- 'Additive Effect']
+ 'Record',
+ 'Symbol',
+ 'Description',
+ 'Location',
+ 'Mean',
+ 'Max LRS',
+ 'Max LRS Location',
+ 'Additive Effect']
# Todo: Obsolete or rename this field
self.type = 'ProbeSet'
@@ -1027,7 +1046,6 @@ class MrnaAssayDataSet(DataSet):
ProbeSetFreeze.Name = "%s"
''' % escape(self.name)
-
def check_confidentiality(self):
return geno_mrna_confidentiality(self)
@@ -1045,10 +1063,12 @@ class MrnaAssayDataSet(DataSet):
if not this_trait.symbol:
this_trait.symbol = "N/A"
- #XZ, 12/08/2008: description
- #XZ, 06/05/2009: Rob asked to add probe target description
- description_string = unicode(str(this_trait.description).strip(codecs.BOM_UTF8), 'utf-8')
- target_string = unicode(str(this_trait.probe_target_description).strip(codecs.BOM_UTF8), 'utf-8')
+ # XZ, 12/08/2008: description
+ # XZ, 06/05/2009: Rob asked to add probe target description
+ description_string = unicode(
+ str(this_trait.description).strip(codecs.BOM_UTF8), 'utf-8')
+ target_string = unicode(
+ str(this_trait.probe_target_description).strip(codecs.BOM_UTF8), 'utf-8')
if len(description_string) > 1 and description_string != 'None':
description_display = description_string
@@ -1063,11 +1083,12 @@ class MrnaAssayDataSet(DataSet):
this_trait.description_display = description_display
if this_trait.chr and this_trait.mb:
- this_trait.location_repr = 'Chr%s: %.6f' % (this_trait.chr, float(this_trait.mb))
+ this_trait.location_repr = 'Chr%s: %.6f' % (
+ this_trait.chr, float(this_trait.mb))
- #Get mean expression value
+ # Get mean expression value
query = (
- """select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet
+ """select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet
where ProbeSetXRef.ProbeSetFreezeId = %s and
ProbeSet.Id = ProbeSetXRef.ProbeSetId and
ProbeSet.Name = '%s'
@@ -1083,11 +1104,11 @@ class MrnaAssayDataSet(DataSet):
if mean:
this_trait.mean = "%2.3f" % mean
- #LRS and its location
+ # LRS and its location
this_trait.LRS_score_repr = 'N/A'
this_trait.LRS_location_repr = 'N/A'
- #Max LRS and its Locus location
+ # Max LRS and its Locus location
if this_trait.lrs and this_trait.locus:
query = """
select Geno.Chr, Geno.Mb from Geno, Species
@@ -1101,7 +1122,8 @@ class MrnaAssayDataSet(DataSet):
if result:
lrs_chr, lrs_mb = result
this_trait.LRS_score_repr = '%3.1f' % this_trait.lrs
- this_trait.LRS_location_repr = 'Chr%s: %.6f' % (lrs_chr, float(lrs_mb))
+ this_trait.LRS_location_repr = 'Chr%s: %.6f' % (
+ lrs_chr, float(lrs_mb))
return trait_list
@@ -1162,7 +1184,6 @@ class TempDataSet(DataSet):
self.fullname = 'Temporary Storage'
self.shortname = 'Temp'
-
@staticmethod
def handle_pca(desc):
if 'PCA' in desc:
@@ -1203,7 +1224,7 @@ def geno_mrna_confidentiality(ob):
#logger.debug("dataset_table [%s]: %s" % (type(dataset_table), dataset_table))
query = '''SELECT Id, Name, FullName, confidentiality,
- AuthorisedUsers FROM %s WHERE Name = "%s"''' % (dataset_table,ob.name)
+ AuthorisedUsers FROM %s WHERE Name = "%s"''' % (dataset_table, ob.name)
logger.sql(query)
result = g.db.execute(query)
--
cgit v1.2.3
From 3d6483e8fd59d2e77149aa5d78ec32448be7338c Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 22:46:49 +0300
Subject: Move tests to module
* test/unittest/: Move to wqflask/tests/
---
test/unittest/__init__.py | 0
test/unittest/base/__init__.py | 0
test/unittest/base/test_data_set.py | 8 --------
test/unittest/base/test_general_object.py | 21 ---------------------
wqflask/tests/__init__.py | 0
wqflask/tests/base/__init__.py | 0
wqflask/tests/base/test_general_object.py | 21 +++++++++++++++++++++
7 files changed, 21 insertions(+), 29 deletions(-)
delete mode 100644 test/unittest/__init__.py
delete mode 100644 test/unittest/base/__init__.py
delete mode 100644 test/unittest/base/test_data_set.py
delete mode 100644 test/unittest/base/test_general_object.py
create mode 100644 wqflask/tests/__init__.py
create mode 100644 wqflask/tests/base/__init__.py
create mode 100644 wqflask/tests/base/test_general_object.py
diff --git a/test/unittest/__init__.py b/test/unittest/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/test/unittest/base/__init__.py b/test/unittest/base/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/test/unittest/base/test_data_set.py b/test/unittest/base/test_data_set.py
deleted file mode 100644
index 6537efa6..00000000
--- a/test/unittest/base/test_data_set.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import unittest
-
-import wqflask.base.data_set
-print dir()
-
-class TestDataSet(unittest.TestCase):
- def test_add(self):
- self.assertEqual(3, 4)
diff --git a/test/unittest/base/test_general_object.py b/test/unittest/base/test_general_object.py
deleted file mode 100644
index eaefdec9..00000000
--- a/test/unittest/base/test_general_object.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import unittest
-
-from wqflask.base.GeneralObject import GeneralObject
-
-
-class TestGeneralObjectTests(unittest.TestCase):
- """
- Test the GeneralObject base class
- """
-
- def test_object_contents(self):
- """Test whether base contents are stored properly"""
- test_obj = GeneralObject("a", "b", "c")
- self.assertEqual("abc", ''.join(test_obj.contents))
-
- def test_object_dict(self):
- """Test whether the base class is printed properly"""
- test_obj = GeneralObject("a", name="test", value=1)
- self.assertEqual(str(test_obj), "value = 1\nname = test\n")
- self.assertEqual(
- repr(test_obj), "value = 1\nname = test\ncontents = ['a']\n")
diff --git a/wqflask/tests/__init__.py b/wqflask/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/wqflask/tests/base/__init__.py b/wqflask/tests/base/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/wqflask/tests/base/test_general_object.py b/wqflask/tests/base/test_general_object.py
new file mode 100644
index 00000000..699cb079
--- /dev/null
+++ b/wqflask/tests/base/test_general_object.py
@@ -0,0 +1,21 @@
+import unittest
+
+from base.GeneralObject import GeneralObject
+
+
+class TestGeneralObjectTests(unittest.TestCase):
+ """
+ Test the GeneralObject base class
+ """
+
+ def test_object_contents(self):
+ """Test whether base contents are stored properly"""
+ test_obj = GeneralObject("a", "b", "c")
+ self.assertEqual("abc", ''.join(test_obj.contents))
+
+ def test_object_dict(self):
+ """Test whether the base class is printed properly"""
+ test_obj = GeneralObject("a", name="test", value=1)
+ self.assertEqual(str(test_obj), "value = 1\nname = test\n")
+ self.assertEqual(
+ repr(test_obj), "value = 1\nname = test\ncontents = ['a']\n")
--
cgit v1.2.3
From b4d35b413df6ac11648030afd9ceb76e05e0e0f5 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 23:36:48 +0300
Subject: Test utility methods for chunking
* wqflask/tests/utility/test_chunks.py: New test
---
wqflask/tests/utility/__init__.py | 0
wqflask/tests/utility/test_chunks.py | 19 +++++++++++++++++++
2 files changed, 19 insertions(+)
create mode 100644 wqflask/tests/utility/__init__.py
create mode 100644 wqflask/tests/utility/test_chunks.py
diff --git a/wqflask/tests/utility/__init__.py b/wqflask/tests/utility/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/wqflask/tests/utility/test_chunks.py b/wqflask/tests/utility/test_chunks.py
new file mode 100644
index 00000000..8d90a1ec
--- /dev/null
+++ b/wqflask/tests/utility/test_chunks.py
@@ -0,0 +1,19 @@
+"""Test chunking"""
+
+import unittest
+
+from utility.chunks import divide_into_chunks
+
+
+class TestChunks(unittest.TestCase):
+ "Test Utility method for chunking"
+ def test_divide_into_chunks(self):
+ "Check that a list is chunked correctly"
+ self.assertEqual(divide_into_chunks([1, 2, 7, 3, 22, 8, 5, 22, 333], 3),
+ [[1, 2, 7], [3, 22, 8], [5, 22, 333]])
+ self.assertEqual(divide_into_chunks([1, 2, 7, 3, 22, 8, 5, 22, 333], 4),
+ [[1, 2, 7], [3, 22, 8], [5, 22, 333]])
+ self.assertEqual(divide_into_chunks([1, 2, 7, 3, 22, 8, 5, 22, 333], 5),
+ [[1, 2], [7, 3], [22, 8], [5, 22], [333]])
+ self.assertEqual(divide_into_chunks([], 5),
+ [[]])
--
cgit v1.2.3
From d26ca838b6e823303c4b903c286fcc452caed0ad Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 23:37:21 +0300
Subject: Remove unused doc-tests
* wqflask/utility/chunks.py: Remove test code from module
---
wqflask/utility/chunks.py | 63 -----------------------------------------------
1 file changed, 63 deletions(-)
diff --git a/wqflask/utility/chunks.py b/wqflask/utility/chunks.py
index b0e33c08..d91b9bf4 100644
--- a/wqflask/utility/chunks.py
+++ b/wqflask/utility/chunks.py
@@ -31,66 +31,3 @@ def divide_into_chunks(the_list, number_chunks):
chunks.append(the_list[counter:counter+chunksize])
return chunks
-
-def _confirm_chunk(original, result):
- all_chunked = []
- for chunk in result:
- all_chunked.extend(chunk)
- print("length of all chunked:", len(all_chunked))
- assert original == all_chunked, "You didn't chunk right"
-
-
-def _chunk_test(divide_func):
- import random
- random.seed(7)
-
- number_exact = 0
- total_amount_off = 0
-
- for test in range(1, 1001):
- print("\n\ntest:", test)
- number_chunks = random.randint(1, 20)
- number_elements = random.randint(0, 100)
- the_list = list(range(1, number_elements))
- result = divide_func(the_list, number_chunks)
-
- print("Dividing list of length {} into approximately {} chunks - got {} chunks".format(
- len(the_list), number_chunks, len(result)))
- print("result:", result)
-
- _confirm_chunk(the_list, result)
-
- amount_off = abs(number_chunks - len(result))
- if amount_off == 0:
- number_exact += 1
- else:
- total_amount_off += amount_off
-
-
- print("\n{} exact out of {} [Total amount off: {}]".format(number_exact,
- test,
- total_amount_off))
- assert number_exact == 558
- assert total_amount_off == 1580
- return number_exact, total_amount_off
-
-
-def _main():
- info = dict()
- #funcs = (("sam", sam_divide_into_chunks), ("zach", zach_divide_into_chunks))
- funcs = (("only one", divide_into_chunks),)
- for name, func in funcs:
- start = time.time()
- number_exact, total_amount_off = _chunk_test(func)
- took = time.time() - start
- info[name] = dict(number_exact=number_exact,
- total_amount_off=total_amount_off,
- took=took)
-
- print("info is:", info)
-
-if __name__ == '__main__':
- _main()
- print("\nConfirming doctests...")
- import doctest
- doctest.testmod()
--
cgit v1.2.3
From 539e6ac3f211391cf241f2f2b70ed7dbd327fc28 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 00:43:12 +0300
Subject: Add unittests for *utility/corestats*
---
wqflask/tests/utility/test_corestats.py | 55 +++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 wqflask/tests/utility/test_corestats.py
diff --git a/wqflask/tests/utility/test_corestats.py b/wqflask/tests/utility/test_corestats.py
new file mode 100644
index 00000000..cf91a248
--- /dev/null
+++ b/wqflask/tests/utility/test_corestats.py
@@ -0,0 +1,55 @@
+"""Test Core Stats"""
+
+import unittest
+
+from utility.corestats import Stats
+
+
+class TestChunks(unittest.TestCase):
+ "Test Utility method for chunking"
+
+ def setUp(self):
+ self.stat_test = Stats((x for x in range(1, 11)))
+
+ def test_stats_sum(self):
+ """ Test sequence sum """
+ self.assertEqual(self.stat_test.sum(), 55)
+ self.stat_test = Stats([])
+ self.assertEqual(self.stat_test.sum(), None)
+
+ def test_stats_count(self):
+ """ Test sequence count """
+ self.assertEqual(self.stat_test.count(), 10)
+ self.stat_test = Stats([])
+ self.assertEqual(self.stat_test.count(), 0)
+
+ def test_stats_min(self):
+ """ Test min value in sequence"""
+ self.assertEqual(self.stat_test.min(), 1)
+ self.stat_test = Stats([])
+ self.assertEqual(self.stat_test.min(), None)
+
+ def test_stats_max(self):
+ """ Test max value in sequence """
+ self.assertEqual(self.stat_test.max(), 10)
+ self.stat_test = Stats([])
+ self.assertEqual(self.stat_test.max(), None)
+
+ def test_stats_avg(self):
+ """ Test avg of sequence """
+ self.assertEqual(self.stat_test.avg(), 5.5)
+ self.stat_test = Stats([])
+ self.assertEqual(self.stat_test.avg(), None)
+
+ def test_stats_stdev(self):
+ """ Test standard deviation of sequence """
+ self.assertEqual(self.stat_test.stdev(), 3.0276503540974917)
+ self.stat_test = Stats([])
+ self.assertEqual(self.stat_test.stdev(), None)
+
+ def test_stats_percentile(self):
+ """ Test percentile of sequence """
+ self.assertEqual(self.stat_test.percentile(20), 3.0)
+ self.assertEqual(self.stat_test.percentile(101), None)
+ self.stat_test = Stats([])
+ self.assertEqual(self.stat_test.percentile(20), None)
--
cgit v1.2.3
From 01bbbc1ee82b43505e65446e4657ca7790453fdf Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 01:33:10 +0300
Subject: Add unittests for *utility/corr_result_helper*
---
wqflask/tests/utility/test_corr_result_helpers.py | 32 +++++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 wqflask/tests/utility/test_corr_result_helpers.py
diff --git a/wqflask/tests/utility/test_corr_result_helpers.py b/wqflask/tests/utility/test_corr_result_helpers.py
new file mode 100644
index 00000000..e196fbdf
--- /dev/null
+++ b/wqflask/tests/utility/test_corr_result_helpers.py
@@ -0,0 +1,32 @@
+""" Test correlation helper methods """
+
+import unittest
+from utility.corr_result_helpers import normalize_values, common_keys, normalize_values_with_samples
+
+
+class TestCorrelationHelpers(unittest.TestCase):
+ """Test methods for normalising lists"""
+
+ def test_normalize_values(self):
+ """Test that a list is normalised correctly"""
+ self.assertEqual(
+ normalize_values([2.3, None, None, 3.2, 4.1, 5], [
+ 3.4, 7.2, 1.3, None, 6.2, 4.1]),
+ ([2.3, 4.1, 5], [3.4, 6.2, 4.1], 3)
+ )
+
+ def test_common_keys(self):
+ """Test that common keys are returned as a list"""
+ a = dict(BXD1=9.113, BXD2=9.825, BXD14=8.985, BXD15=9.300)
+ b = dict(BXD1=9.723, BXD3=9.825, BXD14=9.124, BXD16=9.300)
+ self.assertEqual(sorted(common_keys(a, b)), ['BXD1', 'BXD14'])
+
+ def test_normalize_values_with_samples(self):
+ """Test that a sample(dict) is normalised correctly"""
+ self.assertEqual(
+ normalize_values_with_samples(
+ dict(BXD1=9.113, BXD2=9.825, BXD14=8.985,
+ BXD15=9.300, BXD20=9.300),
+ dict(BXD1=9.723, BXD3=9.825, BXD14=9.124, BXD16=9.300)),
+ (({'BXD1': 9.113, 'BXD14': 8.985}, {'BXD1': 9.723, 'BXD14': 9.124}, 2))
+ )
--
cgit v1.2.3
From b39ef1e464208cf8806dc73cfe9684183ce7c9a2 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 01:37:52 +0300
Subject: Simplify normalize_values
* wqflask/utility/corr_result_helpers.py(normalize_values): Replace loop with
zip form
---
wqflask/utility/corr_result_helpers.py | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py
index b543c589..69c6fe1b 100644
--- a/wqflask/utility/corr_result_helpers.py
+++ b/wqflask/utility/corr_result_helpers.py
@@ -14,15 +14,11 @@ def normalize_values(a_values, b_values):
min_length = min(len(a_values), len(b_values))
a_new = []
b_new = []
- for counter in range(min_length):
- if (a_values[counter] or a_values[counter] == 0) and (b_values[counter] or b_values[counter] == 0):
- a_new.append(a_values[counter])
- b_new.append(b_values[counter])
-
- num_overlap = len(a_new)
- assert num_overlap == len(b_new), "Lengths should be the same"
-
- return a_new, b_new, num_overlap
+ for a, b in zip(a_values, b_values):
+ if not (a == None or b == None):
+ a_new.append(a)
+ b_new.append(b)
+ return a_new, b_new, len(a_new)
def common_keys(a_samples, b_samples):
--
cgit v1.2.3
From f99df1fa0f2163a93f7e194beeb65f0e1d542594 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 01:40:03 +0300
Subject: Remove unused doc-tests
* wqflask/utility/corr_result_helpers.py: Delete doc-test
---
wqflask/utility/corr_result_helpers.py | 6 ------
1 file changed, 6 deletions(-)
diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py
index 69c6fe1b..09017e4a 100644
--- a/wqflask/utility/corr_result_helpers.py
+++ b/wqflask/utility/corr_result_helpers.py
@@ -44,9 +44,3 @@ def normalize_values_with_samples(a_samples, b_samples):
assert num_overlap == len(b_new), "Lengths should be the same"
return a_new, b_new, num_overlap
-
-
-
-if __name__ == '__main__':
- import doctest
- doctest.testmod()
\ No newline at end of file
--
cgit v1.2.3
From 2b7d50f9ac6d0f4f6a032e60053b5923c292a0a1 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 01:41:14 +0300
Subject: Remove unused assert
* wqflask/utility/corr_result_helpers.py(normalize_values):
At no one point will that assert be hit
---
wqflask/utility/corr_result_helpers.py | 4 ----
1 file changed, 4 deletions(-)
diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py
index 09017e4a..a43edbd4 100644
--- a/wqflask/utility/corr_result_helpers.py
+++ b/wqflask/utility/corr_result_helpers.py
@@ -33,14 +33,10 @@ def common_keys(a_samples, b_samples):
def normalize_values_with_samples(a_samples, b_samples):
common_samples = common_keys(a_samples, b_samples)
-
a_new = {}
b_new = {}
for sample in common_samples:
a_new[sample] = a_samples[sample]
b_new[sample] = b_samples[sample]
- num_overlap = len(a_new)
- assert num_overlap == len(b_new), "Lengths should be the same"
-
return a_new, b_new, num_overlap
--
cgit v1.2.3
From 82ee315583281b93e1eff9640ce04e44bc70ac58 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 01:41:45 +0300
Subject: Remove redundant variable
* wqflask/utility/corr_result_helpers.py(normalize_values_with_values):
Remove `num_overlap`
---
wqflask/utility/corr_result_helpers.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py
index a43edbd4..ea3ababf 100644
--- a/wqflask/utility/corr_result_helpers.py
+++ b/wqflask/utility/corr_result_helpers.py
@@ -39,4 +39,4 @@ def normalize_values_with_samples(a_samples, b_samples):
a_new[sample] = a_samples[sample]
b_new[sample] = b_samples[sample]
- return a_new, b_new, num_overlap
+ return a_new, b_new, len(a_new)
--
cgit v1.2.3
From aed1b7f12f653694c22ab389a403120e143a0669 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 17:03:37 +0300
Subject: Add zero to num_repr dictionary
* wqflask/utility/formatting.py(numify): Update `num_repr` to have a zero
---
wqflask/utility/formatting.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/wqflask/utility/formatting.py b/wqflask/utility/formatting.py
index e53dda22..1c0269e9 100644
--- a/wqflask/utility/formatting.py
+++ b/wqflask/utility/formatting.py
@@ -28,7 +28,8 @@ def numify(number, singular=None, plural=None):
'12,334 hippopotami'
"""
- num_repr = {1 : "one",
+ num_repr = {0 : "zero",
+ 1 : "one",
2 : "two",
3 : "three",
4 : "four",
--
cgit v1.2.3
From 073e8c9813505fc00372b2ec21f3e4a87b5be9aa Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 17:05:11 +0300
Subject: Apply autopep-8
* wqflask/utility/formatting.py: apply it
---
wqflask/utility/formatting.py | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/wqflask/utility/formatting.py b/wqflask/utility/formatting.py
index 1c0269e9..1da3e9b7 100644
--- a/wqflask/utility/formatting.py
+++ b/wqflask/utility/formatting.py
@@ -28,22 +28,20 @@ def numify(number, singular=None, plural=None):
'12,334 hippopotami'
"""
- num_repr = {0 : "zero",
- 1 : "one",
- 2 : "two",
- 3 : "three",
- 4 : "four",
- 5 : "five",
- 6 : "six",
- 7 : "seven",
- 8 : "eight",
- 9 : "nine",
- 10 : "ten",
- 11 : "eleven",
- 12 : "twelve"}
-
- #Below line commented out cause doesn't work in Python 2.4
- #assert all((singular, plural)) or not any((singular, plural)), "Need to pass two words or none"
+ num_repr = {0: "zero",
+ 1: "one",
+ 2: "two",
+ 3: "three",
+ 4: "four",
+ 5: "five",
+ 6: "six",
+ 7: "seven",
+ 8: "eight",
+ 9: "nine",
+ 10: "ten",
+ 11: "eleven",
+ 12: "twelve"}
+
if number == 1:
word = singular
else:
--
cgit v1.2.3
From 87fd995209aba0df1f95c1d5d5dd7eefd60d0906 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 17:22:14 +0300
Subject: Add unittests for *utility/test_numify*
---
wqflask/tests/utility/test_numify.py | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 wqflask/tests/utility/test_numify.py
diff --git a/wqflask/tests/utility/test_numify.py b/wqflask/tests/utility/test_numify.py
new file mode 100644
index 00000000..9d3033d1
--- /dev/null
+++ b/wqflask/tests/utility/test_numify.py
@@ -0,0 +1,33 @@
+import unittest
+from utility.formatting import numify, commify
+
+
+class TestFormatting(unittest.TestCase):
+ """Test formatting numbers by numifying or commifying"""
+
+ def test_numify(self):
+ "Test that a number is correctly converted to a English readable string"
+ self.assertEqual(numify(1, 'item', 'items'),
+ 'one item')
+ self.assertEqual(numify(2, 'book'), 'two')
+ self.assertEqual(numify(2, 'book', 'books'), 'two books')
+ self.assertEqual(numify(0, 'book', 'books'), 'zero books')
+ self.assertEqual(numify(0), 'zero')
+ self.assertEqual(numify(5), 'five')
+ self.assertEqual(numify(14, 'book', 'books'), '14 books')
+ self.assertEqual(numify(999, 'book', 'books'), '999 books')
+ self.assertEqual(numify(1000000, 'book', 'books'), '1,000,000 books')
+ self.assertEqual(numify(1956), '1956')
+
+ def test_commify(self):
+ "Test that commas are added correctly"
+ self.assertEqual(commify(1), '1')
+ self.assertEqual(commify(123), '123')
+ self.assertEqual(commify(1234), '1234')
+ self.assertEqual(commify(12345), '12,345')
+ self.assertEqual(commify(1234567890), '1,234,567,890')
+ self.assertEqual(commify(123.0), '123.0')
+ self.assertEqual(commify(1234.5), '1234.5')
+ self.assertEqual(commify(1234.56789), '1234.56789')
+ self.assertEqual(commify(123456.789), '123,456.789')
+ self.assertEqual(commify(None), None)
--
cgit v1.2.3
From 1a0380b9f778600f4ed0838a2dfaf4fc3d7bc768 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Thu, 23 Jul 2020 02:44:42 +0300
Subject: Inject redis instance into DatasetType class
* wqflask/base/data_set.py(DatasetType):
- Rename Redis instance to r to avoid confusion and name collisions
- Inject the redis instance into Dataset_Types class to make it easier to test
- Rename Dataset_Types class to DatasetType class
---
wqflask/base/data_set.py | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index f9705a22..21ace006 100644
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -49,8 +49,8 @@ import cPickle as pickle
import itertools
from redis import Redis
-Redis = Redis()
+r = Redis()
logger = getLogger(__name__)
@@ -74,9 +74,9 @@ def create_dataset(dataset_name, dataset_type=None, get_samplelist=True, group_n
return dataset_class(dataset_name, get_samplelist)
-class Dataset_Types(object):
+class DatasetType:
- def __init__(self):
+ def __init__(self, redis_instance):
"""Create a dictionary of samples where the value is set to Geno,
Publish or ProbeSet. E.g.
@@ -91,9 +91,9 @@ Publish or ProbeSet. E.g.
'B139_K_1206_R': 'ProbeSet' ...
"""
+ self.redis_instance = redis_instance
self.datasets = {}
-
- data = Redis.get("dataset_structure")
+ data = redis_instance.get("dataset_structure")
if data:
self.datasets = json.loads(data)
else: # ZS: I don't think this should ever run unless Redis is emptied
@@ -115,7 +115,7 @@ Publish or ProbeSet. E.g.
except:
pass
- Redis.set("dataset_structure", json.dumps(self.datasets))
+ redis_instance.set("dataset_structure", json.dumps(self.datasets))
# Set LOG_LEVEL_DEBUG=5 to see the following:
logger.debugf(5, "datasets", self.datasets)
@@ -134,7 +134,7 @@ Publish or ProbeSet. E.g.
results = g.db.execute(mrna_expr_query).fetchall()
if len(results):
self.datasets[name] = "ProbeSet"
- Redis.set("dataset_structure", json.dumps(self.datasets))
+ redis_instance.set("dataset_structure", json.dumps(self.datasets))
return self.datasets[name]
group_name = name.replace("Publish", "")
@@ -148,7 +148,7 @@ Publish or ProbeSet. E.g.
results = g.db.execute(pheno_query).fetchall()
if len(results):
self.datasets[name] = "Publish"
- Redis.set("dataset_structure", json.dumps(self.datasets))
+ redis_instance.set("dataset_structure", json.dumps(self.datasets))
return self.datasets[name]
# ZS: For when there isn't an InfoFiles ID; not sure if this and the preceding query are both necessary
@@ -160,7 +160,7 @@ Publish or ProbeSet. E.g.
results = g.db.execute(other_pheno_query).fetchall()
if len(results):
self.datasets[name] = "Publish"
- Redis.set("dataset_structure", json.dumps(self.datasets))
+ redis_instance.set("dataset_structure", json.dumps(self.datasets))
return self.datasets[name]
geno_query = """
@@ -175,7 +175,7 @@ Publish or ProbeSet. E.g.
results = g.db.execute(geno_query).fetchall()
if len(results):
self.datasets[name] = "Geno"
- Redis.set("dataset_structure", json.dumps(self.datasets))
+ self.redis_instance.set("dataset_structure", json.dumps(self.datasets))
return self.datasets[name]
# ZS: It shouldn't ever reach this
@@ -185,13 +185,13 @@ Publish or ProbeSet. E.g.
# Do the intensive work at startup one time only
-Dataset_Getter = Dataset_Types()
+Dataset_Getter = DatasetType(r)
def create_datasets_list():
if USE_REDIS:
key = "all_datasets"
- result = Redis.get(key)
+ result = r.get(key)
if result:
logger.debug("Redis cache hit")
@@ -215,8 +215,8 @@ def create_datasets_list():
datasets.append(dataset)
if USE_REDIS:
- Redis.set(key, pickle.dumps(datasets, pickle.HIGHEST_PROTOCOL))
- Redis.expire(key, 60*60)
+ r.set(key, pickle.dumps(datasets, pickle.HIGHEST_PROTOCOL))
+ r.expire(key, 60*60)
return datasets
@@ -431,7 +431,7 @@ class DatasetGroup(object):
result = None
key = "samplelist:v3:" + self.name
if USE_REDIS:
- result = Redis.get(key)
+ result = r.get(key)
if result is not None:
self.samplelist = json.loads(result)
@@ -446,8 +446,8 @@ class DatasetGroup(object):
self.samplelist = None
if USE_REDIS:
- Redis.set(key, json.dumps(self.samplelist))
- Redis.expire(key, 60*5)
+ r.set(key, json.dumps(self.samplelist))
+ r.expire(key, 60*5)
def all_samples_ordered(self):
result = []
@@ -558,8 +558,8 @@ def datasets(group_name, this_group=None):
datasets=[(dataset, dataset_short)]))
if USE_REDIS:
- Redis.set(key, pickle.dumps(dataset_menu, pickle.HIGHEST_PROTOCOL))
- Redis.expire(key, 60*5)
+ r.set(key, pickle.dumps(dataset_menu, pickle.HIGHEST_PROTOCOL))
+ r.expire(key, 60*5)
if this_group != None:
this_group._datasets = dataset_menu
--
cgit v1.2.3
From 16aaf9885971993863b5e2e8a1b99f8479e2bbb9 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Thu, 23 Jul 2020 02:52:41 +0300
Subject: Add unittests for *base/data_set*
---
wqflask/tests/base/test_data_set.py | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 wqflask/tests/base/test_data_set.py
diff --git a/wqflask/tests/base/test_data_set.py b/wqflask/tests/base/test_data_set.py
new file mode 100644
index 00000000..44a54c7e
--- /dev/null
+++ b/wqflask/tests/base/test_data_set.py
@@ -0,0 +1,35 @@
+import unittest
+import mock
+
+from wqflask import app
+
+from base.data_set import DatasetType
+
+
+class TestDataSetTypes(unittest.TestCase):
+ def setUp(self):
+ self.app_context = app.app_context()
+ self.app_context.push()
+
+ def tearDown(self):
+ self.app_context.pop()
+
+ @mock.patch('base.data_set.g')
+ def test_data_set_type(self, db_mock):
+ with app.app_context():
+ db_mock.get = mock.Mock()
+ r = mock.Mock()
+ r.get.return_value = """
+ {
+ "AD-cases-controls-MyersGeno": "Geno",
+ "AD-cases-controls-MyersPublish": "Publish",
+ "AKXDGeno": "Geno",
+ "AXBXAGeno": "Geno",
+ "AXBXAPublish": "Publish",
+ "Aging-Brain-UCIPublish": "Publish",
+ "All Phenotypes": "Publish",
+ "B139_K_1206_M": "ProbeSet",
+ "B139_K_1206_R": "ProbeSet"
+ }
+ """
+ self.assertEqual(DatasetType(r)("All Phenotypes"), "Publish")
--
cgit v1.2.3
From a6075ce879c338532de39e100f09d92c17b566e7 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Thu, 23 Jul 2020 02:54:59 +0300
Subject: Rename test_numify.py to test_formatting.py
---
wqflask/tests/utility/test_formatting.py | 33 ++++++++++++++++++++++++++++++++
wqflask/tests/utility/test_numify.py | 33 --------------------------------
2 files changed, 33 insertions(+), 33 deletions(-)
create mode 100644 wqflask/tests/utility/test_formatting.py
delete mode 100644 wqflask/tests/utility/test_numify.py
diff --git a/wqflask/tests/utility/test_formatting.py b/wqflask/tests/utility/test_formatting.py
new file mode 100644
index 00000000..9d3033d1
--- /dev/null
+++ b/wqflask/tests/utility/test_formatting.py
@@ -0,0 +1,33 @@
+import unittest
+from utility.formatting import numify, commify
+
+
+class TestFormatting(unittest.TestCase):
+ """Test formatting numbers by numifying or commifying"""
+
+ def test_numify(self):
+ "Test that a number is correctly converted to a English readable string"
+ self.assertEqual(numify(1, 'item', 'items'),
+ 'one item')
+ self.assertEqual(numify(2, 'book'), 'two')
+ self.assertEqual(numify(2, 'book', 'books'), 'two books')
+ self.assertEqual(numify(0, 'book', 'books'), 'zero books')
+ self.assertEqual(numify(0), 'zero')
+ self.assertEqual(numify(5), 'five')
+ self.assertEqual(numify(14, 'book', 'books'), '14 books')
+ self.assertEqual(numify(999, 'book', 'books'), '999 books')
+ self.assertEqual(numify(1000000, 'book', 'books'), '1,000,000 books')
+ self.assertEqual(numify(1956), '1956')
+
+ def test_commify(self):
+ "Test that commas are added correctly"
+ self.assertEqual(commify(1), '1')
+ self.assertEqual(commify(123), '123')
+ self.assertEqual(commify(1234), '1234')
+ self.assertEqual(commify(12345), '12,345')
+ self.assertEqual(commify(1234567890), '1,234,567,890')
+ self.assertEqual(commify(123.0), '123.0')
+ self.assertEqual(commify(1234.5), '1234.5')
+ self.assertEqual(commify(1234.56789), '1234.56789')
+ self.assertEqual(commify(123456.789), '123,456.789')
+ self.assertEqual(commify(None), None)
diff --git a/wqflask/tests/utility/test_numify.py b/wqflask/tests/utility/test_numify.py
deleted file mode 100644
index 9d3033d1..00000000
--- a/wqflask/tests/utility/test_numify.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import unittest
-from utility.formatting import numify, commify
-
-
-class TestFormatting(unittest.TestCase):
- """Test formatting numbers by numifying or commifying"""
-
- def test_numify(self):
- "Test that a number is correctly converted to a English readable string"
- self.assertEqual(numify(1, 'item', 'items'),
- 'one item')
- self.assertEqual(numify(2, 'book'), 'two')
- self.assertEqual(numify(2, 'book', 'books'), 'two books')
- self.assertEqual(numify(0, 'book', 'books'), 'zero books')
- self.assertEqual(numify(0), 'zero')
- self.assertEqual(numify(5), 'five')
- self.assertEqual(numify(14, 'book', 'books'), '14 books')
- self.assertEqual(numify(999, 'book', 'books'), '999 books')
- self.assertEqual(numify(1000000, 'book', 'books'), '1,000,000 books')
- self.assertEqual(numify(1956), '1956')
-
- def test_commify(self):
- "Test that commas are added correctly"
- self.assertEqual(commify(1), '1')
- self.assertEqual(commify(123), '123')
- self.assertEqual(commify(1234), '1234')
- self.assertEqual(commify(12345), '12,345')
- self.assertEqual(commify(1234567890), '1,234,567,890')
- self.assertEqual(commify(123.0), '123.0')
- self.assertEqual(commify(1234.5), '1234.5')
- self.assertEqual(commify(1234.56789), '1234.56789')
- self.assertEqual(commify(123456.789), '123,456.789')
- self.assertEqual(commify(None), None)
--
cgit v1.2.3
From 12d19ea8ca44ad1b8b483bc0a11f28c92a75de00 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 01:09:11 +0300
Subject: Add basic config for coverage tool
* .coveragerc: add it
---
.coveragerc | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 .coveragerc
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 00000000..8fbf85ce
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,28 @@
+[run]
+branch = True
+omit =
+ */site-packages/*
+ tests/*
+
+[report]
+# Regexes for lines to exclude from consideration
+exclude_lines =
+# Have to re-enable the standard pragma
+ pragma: no cover
+
+ # Don't complain about missing debug-only code:
+ def __repr__
+ if self\.debug
+
+ # Don't complain if tests don't hit defensive assertion code:
+ raise AssertionError
+ raise NotImplementedError
+
+ # Don't complain if non-runnable code isn't run:
+ if 0:
+ if __name__ == .__main__.:
+
+ignore_errors = False
+
+[html]
+directory = coverage_html_report
--
cgit v1.2.3
From 6fcac789a4664903b8588cfa1bb321fdb081ec05 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 01:12:33 +0300
Subject: Add generated coverage reports and binary to .gitignore
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
index 701623e7..8183b308 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,5 @@ dist/
EGG-INFO/
wqflask/output/*
wqflask/wqflask/static/output/*
+wqflask/.coverage
+wqflask/coverage_html_report
\ No newline at end of file
--
cgit v1.2.3
From a9282de4f07f37f120b165ff2650468e014f1984 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 01:40:31 +0300
Subject: Move .coveragerc to wqflask/
* .coveragerc: Move .coveragerc to wqflask so that the coverage test tool can
pick it up automatically without having to add an `--rc-file` flag
---
.coveragerc | 28 ----------------------------
wqflask/.coveragerc | 28 ++++++++++++++++++++++++++++
2 files changed, 28 insertions(+), 28 deletions(-)
delete mode 100644 .coveragerc
create mode 100644 wqflask/.coveragerc
diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index 8fbf85ce..00000000
--- a/.coveragerc
+++ /dev/null
@@ -1,28 +0,0 @@
-[run]
-branch = True
-omit =
- */site-packages/*
- tests/*
-
-[report]
-# Regexes for lines to exclude from consideration
-exclude_lines =
-# Have to re-enable the standard pragma
- pragma: no cover
-
- # Don't complain about missing debug-only code:
- def __repr__
- if self\.debug
-
- # Don't complain if tests don't hit defensive assertion code:
- raise AssertionError
- raise NotImplementedError
-
- # Don't complain if non-runnable code isn't run:
- if 0:
- if __name__ == .__main__.:
-
-ignore_errors = False
-
-[html]
-directory = coverage_html_report
diff --git a/wqflask/.coveragerc b/wqflask/.coveragerc
new file mode 100644
index 00000000..939e51b9
--- /dev/null
+++ b/wqflask/.coveragerc
@@ -0,0 +1,28 @@
+[run]
+branch = True
+
+[report]
+omit =
+ */site-packages/*
+ tests/*
+# Regexes for lines to exclude from consideration
+exclude_lines =
+# Have to re-enable the standard pragma
+ pragma: no cover
+
+ # Don't complain about missing debug-only code:
+ def __repr__
+ if self\.debug
+
+ # Don't complain if tests don't hit defensive assertion code:
+ raise AssertionError
+ raise NotImplementedError
+
+ # Don't complain if non-runnable code isn't run:
+ if 0:
+ if __name__ == .__main__.:
+
+ignore_errors = False
+
+[html]
+directory = coverage_html_report
\ No newline at end of file
--
cgit v1.2.3
From f95a42b0a9445a58e68fc83e9b1411bedef67904 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 01:43:26 +0300
Subject: Add more tests for GeneralObject
* wqflask/tests/base/test_general_object.py: test object's magic methods
---
wqflask/tests/base/test_general_object.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/wqflask/tests/base/test_general_object.py b/wqflask/tests/base/test_general_object.py
index 699cb079..df5791e0 100644
--- a/wqflask/tests/base/test_general_object.py
+++ b/wqflask/tests/base/test_general_object.py
@@ -12,6 +12,7 @@ class TestGeneralObjectTests(unittest.TestCase):
"""Test whether base contents are stored properly"""
test_obj = GeneralObject("a", "b", "c")
self.assertEqual("abc", ''.join(test_obj.contents))
+ self.assertEqual(len(test_obj), 0)
def test_object_dict(self):
"""Test whether the base class is printed properly"""
@@ -19,3 +20,8 @@ class TestGeneralObjectTests(unittest.TestCase):
self.assertEqual(str(test_obj), "value = 1\nname = test\n")
self.assertEqual(
repr(test_obj), "value = 1\nname = test\ncontents = ['a']\n")
+ self.assertEqual(len(test_obj), 2)
+ self.assertEqual(getattr(test_obj, "value"), 1)
+ self.assertEqual(test_obj["value"], 1)
+ test_obj["test"] = 1
+ self.assertEqual(test_obj["test"], 1)
--
cgit v1.2.3
From 09bc3137328fbefe41044b5124f3c6a7abaa8982 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 02:14:50 +0300
Subject: Add more tests for general_object
* wqflask/tests/base/test_general_object.py: test getattr() and `==`
---
wqflask/tests/base/test_general_object.py | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/wqflask/tests/base/test_general_object.py b/wqflask/tests/base/test_general_object.py
index df5791e0..c7701021 100644
--- a/wqflask/tests/base/test_general_object.py
+++ b/wqflask/tests/base/test_general_object.py
@@ -21,7 +21,21 @@ class TestGeneralObjectTests(unittest.TestCase):
self.assertEqual(
repr(test_obj), "value = 1\nname = test\ncontents = ['a']\n")
self.assertEqual(len(test_obj), 2)
- self.assertEqual(getattr(test_obj, "value"), 1)
self.assertEqual(test_obj["value"], 1)
test_obj["test"] = 1
self.assertEqual(test_obj["test"], 1)
+
+ def test_get_attribute(self):
+ "Test that getattr works"
+ test_obj = GeneralObject("a", name="test", value=1)
+ self.assertEqual(getattr(test_obj, "value", None), 1)
+ self.assertEqual(getattr(test_obj, "non-existent", None), None)
+
+ def test_object_comparisons(self):
+ "Test that 2 objects of the same length are equal"
+ test_obj1 = GeneralObject("a", name="test", value=1)
+ test_obj2 = GeneralObject("b", name="test2", value=2)
+ test_obj3 = GeneralObject("a", name="test", x=1, y=2)
+ self.assertTrue(test_obj1 == test_obj2 )
+ self.assertFalse(test_obj1 == test_obj3 )
+
--
cgit v1.2.3
From ef62b2c146bb1c8960a3ee700c544d61519998b2 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 02:15:59 +0300
Subject: Remove unreachable conditional
* wqflask/base/GeneralObject.py(__getattr__): remove if statement that is
unreachable
---
wqflask/base/GeneralObject.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/wqflask/base/GeneralObject.py b/wqflask/base/GeneralObject.py
index 37bfeda3..0fccaab3 100644
--- a/wqflask/base/GeneralObject.py
+++ b/wqflask/base/GeneralObject.py
@@ -43,10 +43,7 @@ class GeneralObject:
return getattr(self, key)
def __getattr__(self, key):
- if key in self.__dict__.keys():
- return self.__dict__[key]
- else:
- return eval("self.__dict__.%s" % key)
+ return eval("self.__dict__.%s" % key)
def __len__(self):
return len(self.__dict__) - 1
--
cgit v1.2.3
From 8e3756b8b8094c5d025da31c54c1d0d95a55b0dc Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 17 Jul 2020 02:47:31 +0300
Subject: Add basic unittests
---
test/unittest/__init__.py | 0
test/unittest/base/__init__.py | 0
test/unittest/base/test_general_object.py | 21 +++++++++++++++++++++
3 files changed, 21 insertions(+)
create mode 100644 test/unittest/__init__.py
create mode 100644 test/unittest/base/__init__.py
create mode 100644 test/unittest/base/test_general_object.py
diff --git a/test/unittest/__init__.py b/test/unittest/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/test/unittest/base/__init__.py b/test/unittest/base/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/test/unittest/base/test_general_object.py b/test/unittest/base/test_general_object.py
new file mode 100644
index 00000000..eaefdec9
--- /dev/null
+++ b/test/unittest/base/test_general_object.py
@@ -0,0 +1,21 @@
+import unittest
+
+from wqflask.base.GeneralObject import GeneralObject
+
+
+class TestGeneralObjectTests(unittest.TestCase):
+ """
+ Test the GeneralObject base class
+ """
+
+ def test_object_contents(self):
+ """Test whether base contents are stored properly"""
+ test_obj = GeneralObject("a", "b", "c")
+ self.assertEqual("abc", ''.join(test_obj.contents))
+
+ def test_object_dict(self):
+ """Test whether the base class is printed properly"""
+ test_obj = GeneralObject("a", name="test", value=1)
+ self.assertEqual(str(test_obj), "value = 1\nname = test\n")
+ self.assertEqual(
+ repr(test_obj), "value = 1\nname = test\ncontents = ['a']\n")
--
cgit v1.2.3
From b8e17aee9000943e0fd379b5ef006d76314733e4 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 12:36:06 +0300
Subject: Add work-around for failed imports in unittest
* wqflask/utility/tools.py: Unittests will use `from wqflask.wqflask import app`
and the gn2 script will use `from wqflask import app`
---
wqflask/utility/tools.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py
index 77db5d53..37f9d8fe 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -5,7 +5,10 @@ import os
import sys
import json
-from wqflask import app
+try:
+ from wqflask import app
+except ImportError:
+ from wqflask.wqflask import app
# Use the standard logger here to avoid a circular dependency
import logging
--
cgit v1.2.3
From 98035fccfd7960e6992e1e47afc32b56d54ff074 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Tue, 21 Jul 2020 21:53:30 +0300
Subject: Revert "Add work-around for failed imports in unittest"
This reverts commit d5e87fa6fe7546b46790f512d984a5501223082f.
---
wqflask/utility/tools.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py
index 37f9d8fe..77db5d53 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -5,10 +5,7 @@ import os
import sys
import json
-try:
- from wqflask import app
-except ImportError:
- from wqflask.wqflask import app
+from wqflask import app
# Use the standard logger here to avoid a circular dependency
import logging
--
cgit v1.2.3
From 70a8b445df32b7ed15612ffa745269959eb9159b Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Wed, 22 Jul 2020 17:22:14 +0300
Subject: Add unittests for *utility/test_numify*
---
wqflask/tests/utility/test_numify.py | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 wqflask/tests/utility/test_numify.py
diff --git a/wqflask/tests/utility/test_numify.py b/wqflask/tests/utility/test_numify.py
new file mode 100644
index 00000000..9d3033d1
--- /dev/null
+++ b/wqflask/tests/utility/test_numify.py
@@ -0,0 +1,33 @@
+import unittest
+from utility.formatting import numify, commify
+
+
+class TestFormatting(unittest.TestCase):
+ """Test formatting numbers by numifying or commifying"""
+
+ def test_numify(self):
+ "Test that a number is correctly converted to a English readable string"
+ self.assertEqual(numify(1, 'item', 'items'),
+ 'one item')
+ self.assertEqual(numify(2, 'book'), 'two')
+ self.assertEqual(numify(2, 'book', 'books'), 'two books')
+ self.assertEqual(numify(0, 'book', 'books'), 'zero books')
+ self.assertEqual(numify(0), 'zero')
+ self.assertEqual(numify(5), 'five')
+ self.assertEqual(numify(14, 'book', 'books'), '14 books')
+ self.assertEqual(numify(999, 'book', 'books'), '999 books')
+ self.assertEqual(numify(1000000, 'book', 'books'), '1,000,000 books')
+ self.assertEqual(numify(1956), '1956')
+
+ def test_commify(self):
+ "Test that commas are added correctly"
+ self.assertEqual(commify(1), '1')
+ self.assertEqual(commify(123), '123')
+ self.assertEqual(commify(1234), '1234')
+ self.assertEqual(commify(12345), '12,345')
+ self.assertEqual(commify(1234567890), '1,234,567,890')
+ self.assertEqual(commify(123.0), '123.0')
+ self.assertEqual(commify(1234.5), '1234.5')
+ self.assertEqual(commify(1234.56789), '1234.56789')
+ self.assertEqual(commify(123456.789), '123,456.789')
+ self.assertEqual(commify(None), None)
--
cgit v1.2.3
From bcf98cc6c1f0208cc8f9a21d36196627e1d6e6b6 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Thu, 23 Jul 2020 02:54:59 +0300
Subject: Rename test_numify.py to test_formatting.py
---
wqflask/tests/utility/test_numify.py | 33 ---------------------------------
1 file changed, 33 deletions(-)
delete mode 100644 wqflask/tests/utility/test_numify.py
diff --git a/wqflask/tests/utility/test_numify.py b/wqflask/tests/utility/test_numify.py
deleted file mode 100644
index 9d3033d1..00000000
--- a/wqflask/tests/utility/test_numify.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import unittest
-from utility.formatting import numify, commify
-
-
-class TestFormatting(unittest.TestCase):
- """Test formatting numbers by numifying or commifying"""
-
- def test_numify(self):
- "Test that a number is correctly converted to a English readable string"
- self.assertEqual(numify(1, 'item', 'items'),
- 'one item')
- self.assertEqual(numify(2, 'book'), 'two')
- self.assertEqual(numify(2, 'book', 'books'), 'two books')
- self.assertEqual(numify(0, 'book', 'books'), 'zero books')
- self.assertEqual(numify(0), 'zero')
- self.assertEqual(numify(5), 'five')
- self.assertEqual(numify(14, 'book', 'books'), '14 books')
- self.assertEqual(numify(999, 'book', 'books'), '999 books')
- self.assertEqual(numify(1000000, 'book', 'books'), '1,000,000 books')
- self.assertEqual(numify(1956), '1956')
-
- def test_commify(self):
- "Test that commas are added correctly"
- self.assertEqual(commify(1), '1')
- self.assertEqual(commify(123), '123')
- self.assertEqual(commify(1234), '1234')
- self.assertEqual(commify(12345), '12,345')
- self.assertEqual(commify(1234567890), '1,234,567,890')
- self.assertEqual(commify(123.0), '123.0')
- self.assertEqual(commify(1234.5), '1234.5')
- self.assertEqual(commify(1234.56789), '1234.56789')
- self.assertEqual(commify(123456.789), '123,456.789')
- self.assertEqual(commify(None), None)
--
cgit v1.2.3
From 54956208cad93565e555431845c1e0eb77e66a21 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 01:09:11 +0300
Subject: Add basic config for coverage tool
* .coveragerc: add it
---
.coveragerc | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 .coveragerc
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 00000000..8fbf85ce
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,28 @@
+[run]
+branch = True
+omit =
+ */site-packages/*
+ tests/*
+
+[report]
+# Regexes for lines to exclude from consideration
+exclude_lines =
+# Have to re-enable the standard pragma
+ pragma: no cover
+
+ # Don't complain about missing debug-only code:
+ def __repr__
+ if self\.debug
+
+ # Don't complain if tests don't hit defensive assertion code:
+ raise AssertionError
+ raise NotImplementedError
+
+ # Don't complain if non-runnable code isn't run:
+ if 0:
+ if __name__ == .__main__.:
+
+ignore_errors = False
+
+[html]
+directory = coverage_html_report
--
cgit v1.2.3
From ea8782da5c43e695ba11ff348aeb45b24db07010 Mon Sep 17 00:00:00 2001
From: BonfaceKilz
Date: Fri, 24 Jul 2020 01:40:31 +0300
Subject: Move .coveragerc to wqflask/
* .coveragerc: Move .coveragerc to wqflask so that the coverage test tool can
pick it up automatically without having to add an `--rc-file` flag
---
.coveragerc | 28 ----------------------------
1 file changed, 28 deletions(-)
delete mode 100644 .coveragerc
diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index 8fbf85ce..00000000
--- a/.coveragerc
+++ /dev/null
@@ -1,28 +0,0 @@
-[run]
-branch = True
-omit =
- */site-packages/*
- tests/*
-
-[report]
-# Regexes for lines to exclude from consideration
-exclude_lines =
-# Have to re-enable the standard pragma
- pragma: no cover
-
- # Don't complain about missing debug-only code:
- def __repr__
- if self\.debug
-
- # Don't complain if tests don't hit defensive assertion code:
- raise AssertionError
- raise NotImplementedError
-
- # Don't complain if non-runnable code isn't run:
- if 0:
- if __name__ == .__main__.:
-
-ignore_errors = False
-
-[html]
-directory = coverage_html_report
--
cgit v1.2.3
From e8ca99cc7a8e3fd9af0c477da423b60cc1eb654c Mon Sep 17 00:00:00 2001
From: zsloan
Date: Fri, 24 Jul 2020 15:18:44 -0500
Subject: Fixed queries that were wrongly returning Data IDs as Ns
---
wqflask/base/data_set.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index 2272b6ee..e9deb8a9 100644
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -939,7 +939,7 @@ class GenotypeDataSet(DataSet):
def retrieve_sample_data(self, trait):
query = """
SELECT
- Strain.Name, GenoData.value, GenoSE.error, GenoData.Id, Strain.Name2
+ Strain.Name, GenoData.value, GenoSE.error, "N/A", Strain.Name2
FROM
(GenoData, GenoFreeze, Strain, Geno, GenoXRef)
left join GenoSE on
@@ -1107,11 +1107,14 @@ class MrnaAssayDataSet(DataSet):
def retrieve_sample_data(self, trait):
query = """
SELECT
- Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id, Strain.Name2
+ Strain.Name, ProbeSetData.value, ProbeSetSE.error, NStrain.count, Strain.Name2
FROM
(ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef)
left join ProbeSetSE on
(ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId)
+ left join NStrain on
+ (NStrain.DataId = ProbeSetData.Id AND
+ NStrain.StrainId = ProbeSetData.StrainId)
WHERE
ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND
ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND
--
cgit v1.2.3
From 747eb82d0260c7bf9340e8402b78416373692b0a Mon Sep 17 00:00:00 2001
From: zsloan
Date: Fri, 24 Jul 2020 15:20:21 -0500
Subject: Added to menu option for user to change some basic user information,
like name/organization
---
wqflask/wqflask/templates/base.html | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html
index 262d9ee5..5b9700b5 100644
--- a/wqflask/wqflask/templates/base.html
+++ b/wqflask/wqflask/templates/base.html
@@ -96,7 +96,11 @@
{% if g.user_session.logged_in %}
- Manage Groups
+ User Account Settings
+
{% endif %}
{% endif %}
--
cgit v1.2.3
From a478d8171e075f68e5d9d970d67fa8e508b18628 Mon Sep 17 00:00:00 2001
From: zsloan
Date: Fri, 24 Jul 2020 15:22:06 -0500
Subject: Minor aesthetic indentation change in html
---
wqflask/wqflask/templates/show_trait.html | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html
index 7380d198..c37a41e2 100644
--- a/wqflask/wqflask/templates/show_trait.html
+++ b/wqflask/wqflask/templates/show_trait.html
@@ -21,8 +21,7 @@
{% endif %}
-