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
83 changes: 83 additions & 0 deletions ymmsl/tests/test_io.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ymmsl
from ymmsl import v0_2
import yatiml

import pytest
Expand All @@ -8,3 +9,85 @@ def test_invalid_version() -> None:
"""This is a regression test, the error was really confusing"""
with pytest.raises(yatiml.RecognitionError):
ymmsl.load('ymmsl_version: v0_1')


def test_component_description_trailing_whitespace() -> None:
"""Regression test

PyYAML refuses to use block mode if there is trailing whitespace.
"""
c = v0_2.Component('c1', v0_2.Ports(), 'Test \nmore test!')
dump = yatiml.dumps_function(v0_2.Component, v0_2.Ports, v0_2.Reference)
text = dump(c)
assert text == (
'name: c1\n'
'ports: {}\n'
'description: |\n'
' Test\n'
' more test!\n'
)


def test_configuration_description_trailing_whitespace() -> None:
"""Regression test, see above"""
c = v0_2.Configuration('Test\nmore test! ')
dump = yatiml.dumps_function(v0_2.Configuration, v0_2.Settings, v0_2.Checkpoints)
text = dump(c)
assert text == (
'description: |\n'
' Test\n'
' more test!\n'
)


def test_model_description_trailing_whitespace() -> None:
"""Regression test, see above"""
m = v0_2.Model('test_model', v0_2.Ports(), 'Test\nmore test \nand more')
dump = yatiml.dumps_function(
v0_2.Model, v0_2.Implementation, v0_2.Ports, v0_2.Reference)
text = dump(m)
assert text == (
'name: test_model\n'
'description: |\n'
' Test\n'
' more test\n'
' and more\n'
'components: {}\n'
)


def test_program_description_trailing_whitespace() -> None:
"""Regression test, see above"""
p = v0_2.Program('test_program', v0_2.Ports(), 'Test ', script='')
dump = yatiml.dumps_function(
v0_2.Program, v0_2.BaseEnv, v0_2.ExecutionModel, v0_2.Implementation,
v0_2.KeepsStateForNextUse, v0_2.Ports, v0_2.Reference)
text = dump(p)
assert text == (
'name: test_program\n'
'description: |\n'
' Test\n'
'script: \'\'\n'
)


def test_supported_settings_trailing_whitespace() -> None:
"""Regression test, see above"""
s = v0_2.SupportedSettings({
'alpha': 'float Collision angle ',
'beta': 'float Dampening coefficient',
'gamma': 'int Number\n of\nrays '})
dump = yatiml.dumps_function(
v0_2.SupportedSettings, v0_2.Identifier, v0_2.SettingType,
v0_2.SupportedSetting)
text = dump(s)
assert text == (
'alpha: float Collision angle\n'
'beta: float Dampening coefficient\n'
'gamma:\n'
' type: int\n'
' description: |\n'
' Number\n'
' of\n'
' rays\n'
)
7 changes: 7 additions & 0 deletions ymmsl/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def remove_trailing_whitespace(text: str) -> str:
"""Remove trailing whitespace from each line in text

This ensures that each line in text ends with only a newline, with no whitespace in
between the text and that newline.
"""
return '\n'.join([line.rstrip() for line in text.split('\n')]) + '\n'
5 changes: 3 additions & 2 deletions ymmsl/v0_2/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import yaml
import yatiml

from ymmsl.util import remove_trailing_whitespace
from ymmsl.v0_2.ports import Ports
from ymmsl.v0_2.identity import Reference

Expand Down Expand Up @@ -135,8 +136,8 @@ def _yatiml_sweeten(cls, node: yatiml.Node) -> None:
# output in block style
ynode = cast(yaml.ScalarNode, descr.yaml_node)
ynode.style = '|'
if not ynode.value.endswith('\n'):
ynode.value += '\n'
# ensure PyYAML actually uses block style
ynode.value = remove_trailing_whitespace(ynode.value)

multiplicity = node.get_attribute('multiplicity')
items = multiplicity.seq_items()
Expand Down
5 changes: 3 additions & 2 deletions ymmsl/v0_2/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import yatiml
import yaml

from ymmsl.util import remove_trailing_whitespace
from ymmsl.v0_2.checkpoint import Checkpoints
from ymmsl.v0_2.execution import ExecutionModel
from ymmsl.v0_2.resources import (
Expand Down Expand Up @@ -634,8 +635,8 @@ def _yatiml_sweeten(cls, node: yatiml.Node) -> None:
# output in block style
ynode = cast(yaml.ScalarNode, descr.yaml_node)
ynode.style = '|'
if not ynode.value.endswith('\n'):
ynode.value += '\n'
# ensure PyYAML actually uses block style
ynode.value = remove_trailing_whitespace(ynode.value)

imports = node.get_attribute('imports')
if imports.is_sequence() and imports.is_empty():
Expand Down
5 changes: 3 additions & 2 deletions ymmsl/v0_2/implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import yaml
import yatiml

from ymmsl.util import remove_trailing_whitespace
from ymmsl.v0_2.identity import Reference
from ymmsl.v0_2.ports import Ports
from ymmsl.v0_2.supported_settings import SupportedSettings
Expand Down Expand Up @@ -56,8 +57,8 @@ def _yatiml_sweeten(cls, node: yatiml.Node) -> None:
# output in block style
ynode = cast(yaml.ScalarNode, descr.yaml_node)
ynode.style = '|'
if not ynode.value.endswith('\n'):
ynode.value += '\n'
# ensure PyYAML actually uses block style
ynode.value = remove_trailing_whitespace(ynode.value)

if len(node.get_attribute('supported_settings').yaml_node.value) == 0:
node.remove_attribute('supported_settings')
Expand Down
13 changes: 11 additions & 2 deletions ymmsl/v0_2/supported_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import yaml
import yatiml

from ymmsl.util import remove_trailing_whitespace
from ymmsl.v0_2.identity import Identifier


Expand Down Expand Up @@ -256,8 +257,16 @@ def _yatiml_sweeten(cls, node: yatiml.Node) -> None:
"""If the description is multiple lines, format it block style"""
desc_node = node.get_attribute('description')
if desc_node.is_scalar(str):
ynode = cast(yaml.ScalarNode, desc_node.yaml_node)
if '\n' in cast(str, desc_node.get_value()):
cast(yaml.ScalarNode, desc_node.yaml_node).style = '|'
ynode.style = '|'

# ensure PyYAML actually uses block style
ynode.value = remove_trailing_whitespace(ynode.value)

else:
# we do it also for single-line descriptions for consistency
ynode.value = ynode.value.rstrip()


class SupportedSettings(MutableMapping):
Expand All @@ -279,7 +288,7 @@ class SupportedSettings(MutableMapping):

- low: Not very accurate, but fast. Good for testing.
- medium: Slower and more accurate. Good for most use.
- hight: Slowest, but very accurate. Good for reference runs.
- high: Slowest, but very accurate. Good for reference runs.
D: '[[float]] Diffusion kernel'
D2: [[float]]

Expand Down
2 changes: 1 addition & 1 deletion ymmsl/v0_2/tests/test_supported_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def test_dump_descriptions() -> None:
'd: str With single-line description\n'
'e:\n'
' type: [float]\n'
' description: |-\n'
' description: |\n'
' With multiline\n'
' description\n'
)
Expand Down
Loading