Skip to content

Commit

Permalink
Merge pull request #657 from lognaturel/alias_dataset
Browse files Browse the repository at this point in the history
Alias list_name to dataset and reject reserved entity properties regardless of case
  • Loading branch information
lindsay-stevens authored Sep 20, 2023
2 parents c3833b3 + 56f9906 commit bce4794
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ tests/test_output
build
dist
pyxform.egg-info
pip-wheel-metadata

# By having build ignored above, this ignores documents created by
# sphinx. Overall, I think this is a good thing.

# a virtual environment
env
venv

# ignore pypi manifest
MANIFEST
Expand Down
3 changes: 3 additions & 0 deletions pyxform/aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@
"parameters": "parameters",
constants.ENTITIES_SAVETO: "bind::entities:saveto",
}

entities_header = {"list_name": "dataset"}

# Key is the pyxform internal name, Value is the name used in error/warning messages.
TRANSLATABLE_SURVEY_COLUMNS = {
constants.LABEL: constants.LABEL,
Expand Down
14 changes: 7 additions & 7 deletions pyxform/entities/entities_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from pyxform.xlsparseutils import find_sheet_misspellings, is_valid_xml_tag


def get_entity_declaration(workbook_dict: Dict, warnings: List) -> Dict:
entities_sheet = workbook_dict.get(constants.ENTITIES, [])

def get_entity_declaration(
entities_sheet: Dict, workbook_dict: Dict, warnings: List
) -> Dict:
if len(entities_sheet) == 0:
similar = find_sheet_misspellings(
key=constants.ENTITIES, keys=workbook_dict.keys()
Expand All @@ -25,20 +25,20 @@ def get_entity_declaration(workbook_dict: Dict, warnings: List) -> Dict:

if dataset.startswith(constants.ENTITIES_RESERVED_PREFIX):
raise PyXFormError(
f"Invalid dataset name: '{dataset}' starts with reserved prefix {constants.ENTITIES_RESERVED_PREFIX}."
f"Invalid entity list name: '{dataset}' starts with reserved prefix {constants.ENTITIES_RESERVED_PREFIX}."
)

if "." in dataset:
raise PyXFormError(
f"Invalid dataset name: '{dataset}'. Dataset names may not include periods."
f"Invalid entity list name: '{dataset}'. Names may not include periods."
)

if not is_valid_xml_tag(dataset):
if isinstance(dataset, bytes):
dataset = dataset.encode("utf-8")

raise PyXFormError(
f"Invalid dataset name: '{dataset}'. Dataset names must begin with a letter, colon, or underscore. Other characters can include numbers or dashes."
f"Invalid entity list name: '{dataset}'. Names must begin with a letter, colon, or underscore. Other characters can include numbers or dashes."
)

if not ("label" in entity):
Expand Down Expand Up @@ -83,7 +83,7 @@ def validate_entity_saveto(

error_start = f"{constants.ROW_FORMAT_STRING % row_number} Invalid save_to name:"

if save_to == "name" or save_to == "label":
if save_to.lower() == "name" or save_to.lower() == "label":
raise PyXFormError(
f"{error_start} the entity property name '{save_to}' is reserved."
)
Expand Down
6 changes: 5 additions & 1 deletion pyxform/xls2json.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,11 @@ def workbook_to_json(
) # noqa

# ########## Entities sheet ###########
entity_declaration = get_entity_declaration(workbook_dict, warnings)
entities_sheet = workbook_dict.get(constants.ENTITIES, [])
entities_sheet = dealias_and_group_headers(
entities_sheet, aliases.entities_header, False
)
entity_declaration = get_entity_declaration(entities_sheet, workbook_dict, warnings)

# ########## Survey sheet ###########
survey_sheet = workbook_dict[constants.SURVEY]
Expand Down
57 changes: 54 additions & 3 deletions tests/test_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_dataset_with_reserved_prefix__errors(self):
""",
errored=True,
error__contains=[
"Invalid dataset name: '__sweet' starts with reserved prefix __."
"Invalid entity list name: '__sweet' starts with reserved prefix __."
],
)

Expand All @@ -77,7 +77,7 @@ def test_dataset_with_invalid_xml_name__errors(self):
""",
errored=True,
error__contains=[
"Invalid dataset name: '$sweet'. Dataset names must begin with a letter, colon, or underscore. Other characters can include numbers or dashes."
"Invalid entity list name: '$sweet'. Names must begin with a letter, colon, or underscore. Other characters can include numbers or dashes."
],
)

Expand All @@ -94,7 +94,7 @@ def test_dataset_with_period_in_name__errors(self):
""",
errored=True,
error__contains=[
"Invalid dataset name: 's.w.eet'. Dataset names may not include periods."
"Invalid entity list name: 's.w.eet'. Names may not include periods."
],
)

Expand Down Expand Up @@ -232,6 +232,23 @@ def test_name_in_saveto_column__errors(self):
],
)

def test_naMe_in_saveto_column__errors(self):
self.assertPyxformXform(
name="data",
md="""
| survey | | | | |
| | type | name | label | save_to |
| | text | a | A | naMe |
| entities | | | | |
| | dataset | label | | |
| | trees | a | | |
""",
errored=True,
error__contains=[
"[row : 2] Invalid save_to name: the entity property name 'naMe' is reserved."
],
)

def test_label_in_saveto_column__errors(self):
self.assertPyxformXform(
name="data",
Expand All @@ -249,6 +266,23 @@ def test_label_in_saveto_column__errors(self):
],
)

def test_lAbEl_in_saveto_column__errors(self):
self.assertPyxformXform(
name="data",
md="""
| survey | | | | |
| | type | name | label | save_to |
| | text | a | A | lAbEl |
| entities | | | | |
| | dataset | label | | |
| | trees | a | | |
""",
errored=True,
error__contains=[
"[row : 2] Invalid save_to name: the entity property name 'lAbEl' is reserved."
],
)

def test_system_prefix_in_saveto_column__errors(self):
self.assertPyxformXform(
name="data",
Expand Down Expand Up @@ -335,3 +369,20 @@ def test_saveto_in_group__works(self):
""",
errored=False,
)

def test_list_name_alias_to_dataset(self):
self.assertPyxformXform(
name="data",
md="""
| survey | | | |
| | type | name | label |
| | text | a | A |
| entities | | | |
| | list_name | label | |
| | trees | a | |
""",
xml__xpath_match=[
"/h:html/h:head/x:model/x:instance/x:data/x:meta/x:entity",
'/h:html/h:head/x:model/x:instance/x:data/x:meta/x:entity[@dataset = "trees"]',
],
)

0 comments on commit bce4794

Please sign in to comment.