Skip to content

Commit 94bc365

Browse files
authored
acknowledge --lineseparator option (#165)
1 parent 7b4accb commit 94bc365

File tree

10 files changed

+86
-21
lines changed

10 files changed

+86
-21
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
### Fixes
99
- Do not count documentation length when aligning all columns in settings section [#156](https://github.com/MarketSquare/robotframework-tidy/issues/156)
10+
- Acknowledge ``--lineseparator`` option [#163](https://github.com/MarketSquare/robotframework-tidy/issues/163)
1011

1112
## 1.4.0
1213

robotidy/app.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
from robotidy.utils import (
1212
StatementLinesCollector,
1313
decorate_diff_with_color,
14-
GlobalFormattingConfig
14+
GlobalFormattingConfig,
15+
ModelWriter
1516
)
1617

1718
INCLUDE_EXT = ('.robot', '.resource')
@@ -74,7 +75,8 @@ def transform(self, model):
7475

7576
def save_model(self, model):
7677
if self.overwrite:
77-
model.save(output=self.output)
78+
output = self.output or model.source
79+
ModelWriter(output=output, newline=self.formatting_config.line_sep).write(model)
7880

7981
def output_diff(self, path: str, old_model: StatementLinesCollector, new_model: StatementLinesCollector):
8082
if not self.show_diff:

robotidy/utils.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Token
88
)
99
from robot.parsing.model import Statement
10+
from robot.utils.robotio import file_writer
1011
from click import style
1112

1213

@@ -201,3 +202,20 @@ def get_normalized_candidates(candidates):
201202
norm_cand['alignvariables'] = ['AlignVariablesSection']
202203
norm_cand['assignmentnormalizer'] = ['NormalizeAssignments']
203204
return norm_cand
205+
206+
207+
class ModelWriter(ModelVisitor):
208+
def __init__(self, output, newline):
209+
self.writer = file_writer(output, newline=newline)
210+
self.close_writer = True
211+
212+
def write(self, model):
213+
try:
214+
self.visit(model)
215+
finally:
216+
if self.close_writer:
217+
self.writer.close()
218+
219+
def visit_Statement(self, statement): # noqa
220+
for token in statement.tokens:
221+
self.writer.write(token.value)

tests/utest/test_cli.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
from unittest.mock import patch
1+
import os
22
from pathlib import Path
3-
43
from unittest.mock import MagicMock, Mock
4+
55
import pytest
66
from click import FileError, NoSuchOption
77

8-
from .utils import run_tidy, save_tmp_model
98
from robotidy.cli import (
109
find_project_root,
1110
read_pyproject_config,
1211
read_config
1312
)
14-
from robotidy.utils import node_within_lines
1513
from robotidy.transformers import load_transformers
1614
from robotidy.transformers.AlignSettingsSection import AlignSettingsSection
1715
from robotidy.transformers.ReplaceRunKeywordIf import ReplaceRunKeywordIf
1816
from robotidy.transformers.SmartSortKeywords import SmartSortKeywords
17+
from robotidy.utils import node_within_lines
1918
from robotidy.version import __version__
19+
from .utils import run_tidy
2020

2121

22-
@patch('robotidy.app.Robotidy.save_model', new=save_tmp_model)
2322
class TestCli:
2423
@pytest.mark.parametrize('src', [
2524
None,
@@ -88,7 +87,7 @@ def test_too_many_arguments_for_transform(self):
8887
def test_find_project_root_from_src(self):
8988
src = Path(Path(__file__).parent, 'testdata', 'nested', 'test.robot')
9089
path = find_project_root([src])
91-
assert path == Path(Path(__file__).parent, 'testdata')
90+
assert path == Path(Path(__file__).parent, 'testdata', 'nested')
9291

9392
def test_read_robotidy_config(self):
9493
""" robotidy.toml follows the same format as pyproject starting from 1.2.0 """
@@ -101,7 +100,7 @@ def test_read_robotidy_config(self):
101100
'ReplaceRunKeywordIf'
102101
]
103102
}
104-
config_path = str(Path(Path(__file__).parent, 'testdata', 'robotidy.toml'))
103+
config_path = str(Path(Path(__file__).parent, 'testdata', 'config', 'robotidy.toml'))
105104
config = read_pyproject_config(config_path)
106105
assert config == expected_config
107106

@@ -176,7 +175,7 @@ def test_read_config_from_param(self):
176175
'ReplaceRunKeywordIf'
177176
]
178177
}
179-
config_path = str(Path(Path(__file__).parent, 'testdata', 'robotidy.toml'))
178+
config_path = str(Path(Path(__file__).parent, 'testdata', 'config', 'robotidy.toml'))
180179
ctx_mock = MagicMock()
181180
ctx_mock.command.params = None
182181
param_mock = Mock()
@@ -193,7 +192,7 @@ def test_read_config_without_param(self):
193192
'ReplaceRunKeywordIf'
194193
]
195194
}
196-
config_path = str(Path(Path(__file__).parent, 'testdata', 'robotidy.toml'))
195+
config_path = str(Path(Path(__file__).parent, 'testdata', 'config', 'robotidy.toml'))
197196
ctx_mock = MagicMock()
198197
ctx_mock.params = {'src': [config_path]}
199198
ctx_mock.command.params = None
@@ -300,3 +299,25 @@ def test_configure_transformer_overwrite(self):
300299
{'AlignVariablesSection': ['up_to_column=4']}
301300
)
302301
assert transformers[0].up_to_column + 1 == 4
302+
303+
@pytest.mark.parametrize('line_sep', ['unix', 'windows', 'native', None])
304+
def test_line_sep(self, line_sep):
305+
source = Path(Path(__file__).parent, 'testdata', 'line_sep', 'test.robot')
306+
expected = Path(Path(__file__).parent, 'testdata', 'line_sep', 'expected.robot')
307+
actual = Path(Path(__file__).parent, 'actual', 'test.robot')
308+
if line_sep is not None:
309+
run_tidy(['--lineseparator', line_sep, str(source)], output='test.robot')
310+
else:
311+
run_tidy([str(source)], output='test.robot')
312+
line_end = {
313+
'unix': '\n',
314+
'windows': '\r\n',
315+
'native': os.linesep,
316+
None: os.linesep
317+
}[line_sep]
318+
with open(str(expected)) as f:
319+
expected_str = f.read()
320+
expected_str = expected_str.replace('\n', line_end)
321+
with open(str(actual), newline='') as f:
322+
actual_str = f.read()
323+
assert actual_str == expected_str, 'Line endings does not match'
File renamed without changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*** Settings ***
2+
Library library.py
3+
4+
Force Tags tag
5+
6+
*** Keywords ***
7+
Keyword
8+
Log information
9+
No Operation
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*** Settings ***
2+
Library library.py
3+
4+
Force Tags tag
5+
6+
*** Keywords ***
7+
Keyword
8+
Log information
9+
No Operation
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[tool.robotidy]
2+
overwrite = false
3+
diff = false
4+
spacecount = 4
5+
transform = [
6+
"DiscardEmptySections:allow_only_comments=True",
7+
"ReplaceRunKeywordIf"
8+
]

tests/utest/utils.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
from pathlib import Path
2-
from typing import List
2+
from typing import List, Optional
33

44
from click.testing import CliRunner
55

66
from robotidy.cli import cli
77

88

9-
def save_tmp_model(self, model):
10-
""" Decorator that disables default robotidy save to file mechanism and replace with mocked one.
11-
That way we can save output to 'actual' directory for easy comparison with expected files. """
12-
path = Path(Path(__file__).parent, 'actual', Path(model.source).name)
13-
print(path)
14-
model.save(output=path)
15-
16-
17-
def run_tidy(args: List[str] = None, exit_code: int = 0):
9+
def run_tidy(args: List[str] = None, exit_code: int = 0, output: Optional[str] = None):
1810
runner = CliRunner()
1911
arguments = args if args is not None else []
12+
if output:
13+
output_path = str(Path(Path(__file__).parent, 'actual', output))
14+
else:
15+
output_path = str(Path(Path(__file__).parent, 'actual', 'tmp'))
16+
arguments = ['--output', output_path] + arguments
2017
result = runner.invoke(cli, arguments)
2118
if result.exit_code != exit_code:
2219
print(result.output)

0 commit comments

Comments
 (0)