mirror of https://github.com/chriskiehl/Gooey.git
5 changed files with 163 additions and 47 deletions
Split View
Diff Options
-
2gooey/gui/components/config.py
-
49gooey/python_bindings/constraints.py
-
20gooey/python_bindings/gooey_parser.py
-
98gooey/tests/test_constraints.py
-
41gooey/tests/test_language_parity.py
@ -0,0 +1,49 @@ |
|||
""" |
|||
Basic constraints to ensure GooeyParser is fed all the info it needs |
|||
for various widget classes. |
|||
|
|||
TODO: this should all live in the build_config stage here where it is used |
|||
within the GooeyParser directly. As is, logic is fragmented across files. Some |
|||
assertions happen in argparse_to_json, while others happen in GooeyParser. |
|||
|
|||
Whenever refactoring happens, these should be removed from GooeyParser. |
|||
""" |
|||
from textwrap import dedent |
|||
|
|||
def is_required(action): |
|||
return action.required |
|||
|
|||
def is_hidden(options): |
|||
return not options.get('visible', True) |
|||
|
|||
def has_validator(options): |
|||
return bool(options.get('validator')) |
|||
|
|||
def has_default(action): |
|||
return bool(action.default) |
|||
|
|||
def assert_visibility_requirements(action, options): |
|||
if action.required and is_hidden(options) \ |
|||
and not (has_validator(options) or has_default(action)): |
|||
raise ValueError(dedent( |
|||
''' |
|||
When using Gooey's hidden field functionality, you must either ' |
|||
|
|||
(a) provide a default value, or ' |
|||
(b) provide a custom validator' |
|||
|
|||
Without one of those, your users will be unable to advance past |
|||
the configuration screen as they cannot interact with your |
|||
hidden field, and the default validator requires something to |
|||
be present for fields marked as `required`. |
|||
''' |
|||
)) |
|||
|
|||
def assert_listbox_constraints(widget, **kwargs): |
|||
if widget and widget == 'Listbox': |
|||
if not 'nargs' in kwargs or kwargs['nargs'] not in ['*', '+']: |
|||
raise ValueError( |
|||
'Gooey\'s Listbox widget requires that nargs be specified.\n' |
|||
'Nargs must be set to either `*` or `+` (e.g. nargs="*")' |
|||
) |
|||
|
@ -0,0 +1,98 @@ |
|||
import unittest |
|||
|
|||
from gooey import GooeyParser |
|||
|
|||
|
|||
class TestConstraints(unittest.TestCase): |
|||
|
|||
def test_listbox_constraints(self): |
|||
""" |
|||
Listbox widgets must be provided a nargs option |
|||
""" |
|||
|
|||
# Trying to create a listbox widget without specifying nargs |
|||
# throws an error |
|||
with self.assertRaises(ValueError): |
|||
parser = GooeyParser() |
|||
parser.add_argument('one', choices=['one', 'two'], widget='Listbox') |
|||
|
|||
# Listbox with an invalid nargs value throws an error |
|||
with self.assertRaises(ValueError): |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', choices=['one', 'two'], widget='Listbox', nargs='?') |
|||
|
|||
# Listbox with an invalid nargs value throws an error |
|||
with self.assertRaises(ValueError): |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', choices=['one', 'two'], widget='Listbox', nargs=3) |
|||
|
|||
# valid nargs throw no errors |
|||
for narg in ['*', '+']: |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', choices=['one', 'two'], widget='Listbox', nargs=narg) |
|||
|
|||
|
|||
|
|||
def test_visibility_constraint(self): |
|||
""" |
|||
When visible=False in Gooey config, the user MUST supply either |
|||
a custom validator or a default value. |
|||
""" |
|||
# added without issue |
|||
parser = GooeyParser() |
|||
parser.add_argument('one') |
|||
|
|||
# still fine |
|||
parser = GooeyParser() |
|||
parser.add_argument('one', gooey_options={'visible': True}) |
|||
|
|||
# trying to hide an input without a default or custom validator |
|||
# results in an error |
|||
with self.assertRaises(ValueError): |
|||
parser = GooeyParser() |
|||
parser.add_argument('one', gooey_options={'visible': False}) |
|||
|
|||
# explicit default=None; still error |
|||
with self.assertRaises(ValueError): |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', |
|||
default=None, |
|||
gooey_options={'visible': False}) |
|||
|
|||
# default = empty string. Still error |
|||
with self.assertRaises(ValueError): |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', |
|||
default='', |
|||
gooey_options={'visible': False}) |
|||
|
|||
# default = valid string. No Error |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', |
|||
default='Hello', |
|||
gooey_options={'visible': False}) |
|||
|
|||
# No default, but custom validator: Success |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', |
|||
gooey_options={ |
|||
'visible': False, |
|||
'validator': {'test': 'true'} |
|||
}) |
|||
|
|||
# default AND validator, still fine |
|||
parser = GooeyParser() |
|||
parser.add_argument( |
|||
'one', |
|||
default='Hai', |
|||
gooey_options={ |
|||
'visible': False, |
|||
'validator': {'test': 'true'} |
|||
}) |
@ -1,41 +0,0 @@ |
|||
import os |
|||
import unittest |
|||
import json |
|||
from collections import OrderedDict |
|||
from gooey import languages |
|||
|
|||
from gooey.gui.processor import ProcessController |
|||
|
|||
|
|||
class TestLanguageParity(unittest.TestCase): |
|||
""" |
|||
Checks that all language files have the same set of keys so that non-english |
|||
languages don't silently break as features are added to Gooey. |
|||
""" |
|||
|
|||
def test_languageParity(self): |
|||
langDir = os.path.dirname(languages.__file__) |
|||
englishFile = os.path.join(langDir, 'english.json') |
|||
|
|||
english = self.readFile(englishFile) |
|||
jsonFiles = [(path, self.readFile(os.path.join(langDir, path))) |
|||
for path in os.listdir(langDir) |
|||
if path.endswith('json') and 'poooo' not in path and '2' not in path] |
|||
|
|||
allKeys = set(english.keys()) |
|||
for name, contents in jsonFiles: |
|||
missing = allKeys.difference(set(contents.keys())) |
|||
self.assertEqual( |
|||
set(), |
|||
missing, |
|||
"{} language file is missing keys: [{}]".format(name, missing) |
|||
) |
|||
|
|||
|
|||
def readFile(self, path): |
|||
with open(path, 'r', encoding='utf-8') as f: |
|||
return json.loads(f.read()) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
Write
Preview
Loading…
Cancel
Save