mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-08 00:18:12 +08:00
Fixed categorical filter not being converted to type, added tests
This commit is contained in:
@@ -7,14 +7,16 @@ def _convert_variable(datatype, variable):
|
|||||||
Convert variable to number (float/int)
|
Convert variable to number (float/int)
|
||||||
Used for dataset metadata and for query string
|
Used for dataset metadata and for query string
|
||||||
:param datatype: type to convert to
|
:param datatype: type to convert to
|
||||||
:param variable: value of variable
|
:param variable (string or None): value of variable
|
||||||
:return: converted variable
|
:return: converted variable
|
||||||
:raises: ValueError
|
:raises: ValueError
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if variable and datatype == "int":
|
if variable is None:
|
||||||
|
return variable
|
||||||
|
if datatype == "int":
|
||||||
variable = int(variable)
|
variable = int(variable)
|
||||||
elif variable and datatype == "float":
|
elif datatype == "float":
|
||||||
variable = float(variable)
|
variable = float(variable)
|
||||||
return variable
|
return variable
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -23,12 +25,9 @@ def _convert_variable(datatype, variable):
|
|||||||
|
|
||||||
def parse_filter(filter, schema):
|
def parse_filter(filter, schema):
|
||||||
"""
|
"""
|
||||||
{key: variable_type
|
|
||||||
value_type
|
|
||||||
query
|
|
||||||
|
|
||||||
:param filter:
|
:param filter: flask's request.args
|
||||||
:param schema:
|
:param schema: dictionary schema
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
query = {}
|
query = {}
|
||||||
@@ -41,7 +40,7 @@ def parse_filter(filter, schema):
|
|||||||
"value_type": schema[key]["type"]
|
"value_type": schema[key]["type"]
|
||||||
}
|
}
|
||||||
if query[key]["variable_type"] == "categorical":
|
if query[key]["variable_type"] == "categorical":
|
||||||
query[key]["query"] = _convert_variable(query[key]["value_type"], value)
|
query[key]["query"] = [_convert_variable(query[key]["value_type"], v) for v in value]
|
||||||
elif query[key]["variable_type"] == "continuous":
|
elif query[key]["variable_type"] == "continuous":
|
||||||
value = value[0]
|
value = value[0]
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "../app")
|
||||||
|
from util.filter import _convert_variable, parse_filter
|
||||||
|
|
||||||
|
|
||||||
|
class UtilTest(unittest.TestCase):
|
||||||
|
"""Test Case for endpoints"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.schema = {
|
||||||
|
"cluster": {
|
||||||
|
"displayname": "Cluster",
|
||||||
|
"include": True,
|
||||||
|
"type": "int",
|
||||||
|
"variabletype": "categorical"
|
||||||
|
},
|
||||||
|
"louvain": {
|
||||||
|
"displayname": "Louvain Cluster",
|
||||||
|
"include": True,
|
||||||
|
"type": "string",
|
||||||
|
"variabletype": "categorical"
|
||||||
|
},
|
||||||
|
"n_genes": {
|
||||||
|
"displayname": "Num Genes",
|
||||||
|
"include": True,
|
||||||
|
"type": "int",
|
||||||
|
"variabletype": "continuous"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_convert(self):
|
||||||
|
five = _convert_variable("int", "5")
|
||||||
|
assert five == 5
|
||||||
|
|
||||||
|
def test_convert_zero(self):
|
||||||
|
zero = _convert_variable("int", "0")
|
||||||
|
assert zero == 0
|
||||||
|
|
||||||
|
def test_empty_convert(self):
|
||||||
|
empty = _convert_variable("int", None)
|
||||||
|
assert empty is None
|
||||||
|
|
||||||
|
def test_bad_convert(self):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
_convert_variable("int", "5.5")
|
||||||
|
|
||||||
|
def test_filter_categorical(self):
|
||||||
|
filterMock = MagicMock()
|
||||||
|
filterMock.__iter__.return_value = iter(["louvain"])
|
||||||
|
filterMock.getlist.return_value = ["B cells", "T cells"]
|
||||||
|
query = parse_filter(filterMock, self.schema)
|
||||||
|
assert query == {"louvain": {"variable_type": "categorical", "value_type": "string", "query": ["B cells", "T cells"]}}
|
||||||
|
filterMock.__iter__.return_value = iter(["cluster"])
|
||||||
|
filterMock.getlist.return_value = ["1", "2"]
|
||||||
|
query = parse_filter(filterMock, self.schema)
|
||||||
|
assert query == {"cluster": {"variable_type": "categorical", "value_type": "int", "query": [1, 2]}}
|
||||||
|
|
||||||
|
def test_filter_contiunous(self):
|
||||||
|
filterMock = MagicMock()
|
||||||
|
filterMock.__iter__.return_value = iter(["n_genes"])
|
||||||
|
filterMock.getlist.return_value = ["0,100"]
|
||||||
|
query = parse_filter(filterMock, self.schema)
|
||||||
|
assert query == {"n_genes": {"variable_type": "continuous", "value_type": "int", "query": {"min": 0, "max": 100}}}
|
||||||
|
filterMock.__iter__.return_value = iter(["n_genes"])
|
||||||
|
filterMock.getlist.return_value = ["*,100"]
|
||||||
|
query = parse_filter(filterMock, self.schema)
|
||||||
|
assert query == {"n_genes": {"variable_type": "continuous", "value_type": "int", "query": {"min": None, "max": 100}}}
|
||||||
|
filterMock.__iter__.return_value = iter(["n_genes"])
|
||||||
|
filterMock.getlist.return_value = ["0,*"]
|
||||||
|
query = parse_filter(filterMock, self.schema)
|
||||||
|
assert query == {"n_genes": {"variable_type": "continuous", "value_type": "int", "query": {"min": 0, "max": None}}}
|
||||||
Reference in New Issue
Block a user