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
29 changes: 29 additions & 0 deletions tests/integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,32 @@ def test_convert_preserves_explicit_empty_string_fields():
assert row[header.index("watermark")] == ""
assert row[header.index("fieldType")] == "text"
assert row[header.index("displayOrder")] == "1"


def test_convert_aligns_rows_to_header_order(tmp_path):
"""Ensure item key order does not shift values into wrong TSV columns."""
input_file = "tests/valid/mixed_key_order.yml"
output_file = tmp_path / "mixed_key_order.tsv"
runner = CliRunner()

result = runner.invoke(
yml2block.__main__.main,
["convert", input_file, "-o", str(output_file)],
)

assert result.exit_code == 0, result.output
lines = output_file.read_text().splitlines()
header_idx = next(
idx for idx, line in enumerate(lines) if line.startswith("#datasetField")
)
header = lines[header_idx].split("\t")
row = lines[header_idx + 2].split("\t")

assert row[header.index("name")] == "Second"
assert row[header.index("watermark")] == "Second watermark"
assert row[header.index("fieldType")] == "textbox"

expected_width = len(header)
assert expected_width > 0
for line in lines:
assert len(line.split("\t")) == expected_width
35 changes: 35 additions & 0 deletions tests/valid/mixed_key_order.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
metadataBlock:
- name: MixedOrder
displayName: Mixed Order
datasetField:
- name: First
title: First
description: First description
watermark: First watermark
fieldType: text
displayOrder: 1
advancedSearchField: true
allowControlledVocabulary: false
allowmultiples: false
facetable: false
displayoncreate: true
required: true
parent:
metadatablock_id: MixedOrder
termURI: https://example.org/first
- fieldType: textbox
watermark: Second watermark
name: Second
title: Second
description: Second description
displayOrder: 2
displayFormat:
advancedSearchField: false
allowControlledVocabulary: false
allowmultiples: false
facetable: false
displayoncreate: false
required: false
parent:
metadatablock_id: MixedOrder
14 changes: 11 additions & 3 deletions yml2block/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,20 @@ def write_metadata_block(yml_metadata, output_path, longest_line, verbose):
block_lines = []

for block_line in content:
new_line = [""]

for key, entry in block_line.items():
for key in block_line.keys():
if key not in block_headers:
block_headers.append(key)

for block_line in content:
new_line = [""]

for key in block_headers:
if key not in block_line:
new_line.append("")
continue

entry = block_line[key]

value = entry.value
# TODO: Consider screening for True, False, None
# before and replace them.
Expand Down
16 changes: 11 additions & 5 deletions yml2block/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,17 @@ def validate_entry(yaml_chunk, tsv_keyword, lint_conf, verbose):
lint = lint_conf.get(lint)
violations.extend(lint(item, tsv_keyword))

# Compute the highest number of columns in the block
row_length = (
len(item.keys()) if tsv_keyword == "metadataBlock" else len(item.keys()) + 1
)
longest_row = max(longest_row, row_length)
# Compute the highest number of columns in the block
block_headers = []
for item in yaml_chunk:
for key in item.keys():
if key not in block_headers:
block_headers.append(key)

row_length = (
len(block_headers) if tsv_keyword == "metadataBlock" else len(block_headers) + 1
)
longest_row = max(longest_row, row_length)

if verbose and len(violations) == 0:
print("SUCCESS!" if verbose == 1 else "SUCCESS!\n")
Expand Down
Loading