Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions src/dayamlchecker/yaml_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,34 @@ class PythonBool:

def __init__(self, x):
self.errors = []
pass
if isinstance(x, bool):
return
# number like 10 or 0 - not valid, even though Python treats them as truthy/falsy
if isinstance(x, (int, float)):
self.errors = [
(f"expected True, False, or a Python expression, got number: {x}", 1)
]
return
# must be a string at this point
if not isinstance(x, str):
self.errors = [
(
f"expected True, False, or a Python expression, got: {type(x).__name__}",
1,
)
]
return
# try parsing it as a Python expression - covers things like "user_age > 18"
try:
ast.parse(x)
except SyntaxError as ex:
msg = ex.msg or str(ex)
self.errors = [
(
f"expected True, False, or a valid Python expression, got: {x!r} (Python syntax error: {msg})",
1,
)
]


class JavascriptText:
Expand Down Expand Up @@ -754,7 +781,7 @@ def _variable_candidates(self, var_expr):
"scan for variables": {},
"if": {},
"sets": {},
"initial": {},
"initial": {"type": PythonBool},
"event": {},
"comment": {},
"generic object": {"type": DAPythonVar},
Expand Down
97 changes: 97 additions & 0 deletions tests/test_yaml_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,103 @@ def test_show_hide_nesting_depth_two_no_warning(self):
f"Did not expect nesting warning, got: {errs}",
)

def test_mandatory_number_errors(self):
"""Error: mandatory with a number should be flagged"""
invalid = """
mandatory: 10
question: |
Hello
field: user_name
"""
errs = find_errors_from_string(invalid, input_file="<string_invalid>")
self.assertTrue(
any("got number: 10" in e.err_str for e in errs),
f"Expected mandatory number error, got: {errs}",
)

def test_mandatory_bool_true_valid(self):
"""Valid: mandatory: True should pass"""
valid = """
mandatory: True
question: |
Hello
field: user_name
"""
errs = find_errors_from_string(valid, input_file="<string_valid>")
self.assertFalse(
any("expected True, False" in e.err_str for e in errs),
f"Did not expect mandatory error for True, got: {errs}",
)

def test_mandatory_bool_false_valid(self):
"""Valid: mandatory: False should pass"""
valid = """
mandatory: False
question: |
Hello
field: user_name
"""
errs = find_errors_from_string(valid, input_file="<string_valid>")
self.assertFalse(
any("expected True, False" in e.err_str for e in errs),
f"Did not expect mandatory error for False, got: {errs}",
)

def test_mandatory_python_expression_valid(self):
"""Valid: mandatory with a Python expression should pass"""
valid = """
mandatory: user_age > 18
question: |
Hello
field: user_name
"""
errs = find_errors_from_string(valid, input_file="<string_valid>")
self.assertFalse(
any("expected True, False" in e.err_str for e in errs),
f"Did not expect mandatory error for Python expression, got: {errs}",
)

def test_mandatory_invalid_string_errors(self):
"""Error: mandatory with a non-Python string should be flagged"""
invalid = """
mandatory: yes please
question: |
Hello
field: user_name
"""
errs = find_errors_from_string(invalid, input_file="<string_invalid>")
self.assertTrue(
any("expected True, False" in e.err_str for e in errs),
f"Expected mandatory invalid string error, got: {errs}",
)

def test_initial_number_errors(self):
"""Error: initial with a number should be flagged"""
invalid = """
initial: 10
code: |
x = 1
"""
errs = find_errors_from_string(invalid, input_file="<string_invalid>")
self.assertTrue(
any("got number: 10" in e.err_str for e in errs),
f"Expected initial number error, got: {errs}",
)

def test_mandatory_null_errors(self):
"""Error: mandatory: null should be flagged"""
invalid = """
mandatory: null
question: |
Hello
field: user_name
"""
errs = find_errors_from_string(invalid, input_file="<string_invalid>")
self.assertTrue(
any("expected True, False" in e.err_str for e in errs),
f"Expected mandatory null error, got: {errs}",
)


if __name__ == "__main__":
unittest.main()
Loading