Browse Source

add tests for generating form option groups from filters

Daniel Sheffield 1 year ago
parent
commit
f3e894496f
2 changed files with 132 additions and 2 deletions
  1. 6 2
      app/rest/form.py
  2. 126 0
      test/rest/test_form.py

+ 6 - 2
app/rest/form.py

@@ -4,12 +4,16 @@
 # All rights reserved
 # All rights reserved
 #
 #
 # THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
 # THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
+from typing import Dict, Tuple
 from bottle import template
 from bottle import template
 from pandas import DataFrame
 from pandas import DataFrame
 from itertools import chain
 from itertools import chain
 from ..rest import ALL_UNITS
 from ..rest import ALL_UNITS
 
 
-def get_option_groups(data: DataFrame, filter_data, k, g, _type):
+def get_option_groups(
+    data: DataFrame, filter_data: Dict[str, Tuple[set, set]],
+    k: str, g: str, _type: str
+):
     in_chart = data['$/unit'].apply(lambda x: (x or False) and True)
     in_chart = data['$/unit'].apply(lambda x: (x or False) and True)
     groups = sorted(set(data[g] if g is not None else []))
     groups = sorted(set(data[g] if g is not None else []))
     groups.append(None)
     groups.append(None)
@@ -60,7 +64,7 @@ def get_option_groups(data: DataFrame, filter_data, k, g, _type):
                 map(lambda x: (True, x), set(selected)),
                 map(lambda x: (True, x), set(selected)),
                 map(lambda x: (False, x), set(unselected)),
                 map(lambda x: (False, x), set(unselected)),
             )), key=lambda x: x["display"] if "display" in x else x["value"])
             )), key=lambda x: x["display"] if "display" in x else x["value"])
-        } 
+        }
 
 
 
 
 def get_form(action: str, method: str, filter_data, data: DataFrame):
 def get_form(action: str, method: str, filter_data, data: DataFrame):

+ 126 - 0
test/rest/test_form.py

@@ -0,0 +1,126 @@
+#
+# Copyright (c) Daniel Sheffield 2023
+#
+# All rights reserved
+#
+# THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
+from typing import Dict, Iterable, Tuple
+from pandas import DataFrame
+from pytest import fixture, mark
+from app.rest.form import get_option_groups
+
+@fixture
+def data():
+    return DataFrame({
+        'type': ['dog', 'cat', 'horse', 'sheep', 'cow'],
+        'category': ['pet', 'pet', 'utility', 'farm', 'farm'],
+        'group': ['small', 'small', 'large', 'medium', 'large',],
+        'tags': [['a'], ['a','b'], [], [], []],
+        '$/unit': ['1', '2', '3', '4', '5'],
+    })
+
+@mark.parametrize('filter_data, _type, key, parent_grouping, expected', [
+    ({
+        'type': [{'dog'}, {'cat'}]
+    }, 'include', 'type', 'category', [
+        {
+            "optgroup": 'pet', "options": [{
+                "selected": True,
+                "value": "dog",
+                "display": "dog",
+            }]
+        }, {
+            "optgroup": None, "options":[{
+                "selected": False,
+                "value": "cat",
+                "display": "cat",
+            }]
+        }
+    ]), ({
+        'type': [{'dog'}, {'cat'}]
+    }, 'exclude', 'type', 'category', [
+        {
+            "optgroup": 'pet', "options": [{
+                "selected": False,
+                "value": "!dog",
+                "display": "dog",
+            }],
+        }, {
+            "optgroup": None, "options":[{
+                "selected": True,
+                "value": "!cat",
+                "display": "cat",
+            }],
+        }
+    ]), ({
+        'group': [{'small'}, {'large'}]
+    }, 'include', 'group', None, [
+        {
+            "optgroup": None, "options": [ {
+                "selected": False,
+                "value": "large",
+                "display": "large",
+            },{
+                "selected": True,
+                "value": "small",
+                "display": "small",
+            }],
+        }
+    ]), ({
+        'group': [{'small'}, {'large'}]
+    }, 'exclude', 'group', None, [
+        {
+            "optgroup": None, "options": [{
+                "selected": True,
+                "value": "!large",
+                "display": "large",
+            },{
+                "selected": False,
+                "value": "!small",
+                "display": "small",
+            }],
+        }
+    ]),  ({
+        'tag': [{'a'}, {'b'}]
+    }, 'include', 'tag', None, [
+        {
+            "optgroup": None, "options": [ {
+                "selected": True,
+                "value": "a",
+                "display": "a",
+            },{
+                "selected": False,
+                "value": "b",
+                "display": "b",
+            }],
+        }
+    ]), ({
+        'tag': [{'a'}, {'b'}]
+    }, 'exclude', 'tag', None, [
+        {
+            "optgroup": None, "options": [{
+                "selected": False,
+                "value": "!a",
+                "display": "a",
+            },{
+                "selected": True,
+                "value": "!b",
+                "display": "b",
+            }],
+        }
+    ]),
+])
+def test_get_option_groups(
+    data: DataFrame,  _type: str,
+    filter_data: Dict[str, Tuple[set, set]],
+    key: str, parent_grouping: str,
+    expected: Iterable
+):
+
+    _filter = data['type'].apply(lambda _: False)
+    for k, (inc, exc) in filter_data.items():
+        for i in inc:
+            _filter |= (data['tags'].apply(lambda x: i in x) if k == 'tag' else data[k] == i)
+        for i in exc:
+            _filter &= ~(data['tags'].apply(lambda x: i in x) if k == 'tag' else data[k] == i)
+    assert list(get_option_groups(data[_filter], filter_data, key, parent_grouping, _type)) == expected