|
5 | 5 | import uuid |
6 | 6 | from dataclasses import dataclass |
7 | 7 | from pathlib import Path |
8 | | -from unittest.mock import MagicMock |
| 8 | +from unittest.mock import MagicMock, patch |
9 | 9 | from openjd.sessions._os_checker import is_posix, is_windows |
10 | 10 | import pytest |
11 | 11 |
|
|
19 | 19 | from openjd.model.v2023_09 import ( |
20 | 20 | EmbeddedFileTypes as EmbeddedFileTypes_2023_09, |
21 | 21 | ) |
| 22 | +from openjd.model.v2023_09 import ( |
| 23 | + EndOfLine as EndOfLine_2023_09, |
| 24 | +) |
22 | 25 | from openjd.sessions._embedded_files import EmbeddedFiles, EmbeddedFilesScope |
23 | 26 | from openjd.sessions._session_user import PosixSessionUser, WindowsSessionUser |
24 | 27 |
|
@@ -365,6 +368,119 @@ def test_changes_owner(self, tmp_path: Path, windows_user: WindowsSessionUser) - |
365 | 368 | result_contents = file.read() |
366 | 369 | assert result_contents == testdata, "File contents are as expected" |
367 | 370 |
|
| 371 | + class TestEndOfLine: |
| 372 | + """Tests for endOfLine handling in embedded files.""" |
| 373 | + |
| 374 | + @pytest.mark.parametrize( |
| 375 | + "end_of_line,input_data,expected_bytes", |
| 376 | + [ |
| 377 | + pytest.param( |
| 378 | + EndOfLine_2023_09.LF, |
| 379 | + "line1\nline2\nline3", |
| 380 | + b"line1\nline2\nline3", |
| 381 | + id="LF-only", |
| 382 | + ), |
| 383 | + pytest.param( |
| 384 | + EndOfLine_2023_09.LF, |
| 385 | + "line1\r\nline2\r\nline3", |
| 386 | + b"line1\nline2\nline3", |
| 387 | + id="LF-converts-CRLF", |
| 388 | + ), |
| 389 | + pytest.param( |
| 390 | + EndOfLine_2023_09.CRLF, |
| 391 | + "line1\nline2\nline3", |
| 392 | + b"line1\r\nline2\r\nline3", |
| 393 | + id="CRLF-converts-LF", |
| 394 | + ), |
| 395 | + pytest.param( |
| 396 | + EndOfLine_2023_09.CRLF, |
| 397 | + "line1\r\nline2\r\nline3", |
| 398 | + b"line1\r\nline2\r\nline3", |
| 399 | + id="CRLF-preserves-CRLF", |
| 400 | + ), |
| 401 | + ], |
| 402 | + ) |
| 403 | + def test_end_of_line_conversion( |
| 404 | + self, |
| 405 | + tmp_path: Path, |
| 406 | + end_of_line: EndOfLine_2023_09, |
| 407 | + input_data: str, |
| 408 | + expected_bytes: bytes, |
| 409 | + ) -> None: |
| 410 | + # Test that endOfLine correctly converts line endings |
| 411 | + |
| 412 | + # GIVEN |
| 413 | + test_obj = EmbeddedFiles( |
| 414 | + logger=MagicMock(), scope=EmbeddedFilesScope.STEP, session_files_directory=tmp_path |
| 415 | + ) |
| 416 | + test_file = EmbeddedFileText_2023_09( |
| 417 | + name="Foo", |
| 418 | + type=EmbeddedFileTypes_2023_09.TEXT, |
| 419 | + data=DataString_2023_09(input_data), |
| 420 | + endOfLine=end_of_line, |
| 421 | + ) |
| 422 | + filename = tmp_path / uuid.uuid4().hex |
| 423 | + symtab = SymbolTable() |
| 424 | + |
| 425 | + # WHEN |
| 426 | + test_obj._materialize_file(filename, test_file, symtab) |
| 427 | + |
| 428 | + # THEN |
| 429 | + with open(filename, "rb") as file: |
| 430 | + result_bytes = file.read() |
| 431 | + assert result_bytes == expected_bytes |
| 432 | + |
| 433 | + @pytest.mark.skipif(is_windows(), reason="Cannot simulate POSIX file I/O on Windows") |
| 434 | + def test_auto_uses_lf_on_posix(self, tmp_path: Path) -> None: |
| 435 | + # Test that AUTO mode uses LF on POSIX systems |
| 436 | + |
| 437 | + # GIVEN |
| 438 | + test_obj = EmbeddedFiles( |
| 439 | + logger=MagicMock(), scope=EmbeddedFilesScope.STEP, session_files_directory=tmp_path |
| 440 | + ) |
| 441 | + test_file = EmbeddedFileText_2023_09( |
| 442 | + name="Foo", |
| 443 | + type=EmbeddedFileTypes_2023_09.TEXT, |
| 444 | + data=DataString_2023_09("line1\r\nline2"), |
| 445 | + endOfLine=EndOfLine_2023_09.AUTO, |
| 446 | + ) |
| 447 | + filename = tmp_path / uuid.uuid4().hex |
| 448 | + symtab = SymbolTable() |
| 449 | + |
| 450 | + # WHEN |
| 451 | + test_obj._materialize_file(filename, test_file, symtab) |
| 452 | + |
| 453 | + # THEN |
| 454 | + with open(filename, "rb") as file: |
| 455 | + result_bytes = file.read() |
| 456 | + assert result_bytes == b"line1\nline2" |
| 457 | + |
| 458 | + @pytest.mark.skipif(not is_windows(), reason="Windows-specific test") |
| 459 | + def test_auto_uses_crlf_on_windows(self, tmp_path: Path) -> None: |
| 460 | + # Test that AUTO mode uses CRLF on Windows systems |
| 461 | + |
| 462 | + # GIVEN |
| 463 | + test_obj = EmbeddedFiles( |
| 464 | + logger=MagicMock(), scope=EmbeddedFilesScope.STEP, session_files_directory=tmp_path |
| 465 | + ) |
| 466 | + test_file = EmbeddedFileText_2023_09( |
| 467 | + name="Foo", |
| 468 | + type=EmbeddedFileTypes_2023_09.TEXT, |
| 469 | + data=DataString_2023_09("line1\nline2"), |
| 470 | + endOfLine=EndOfLine_2023_09.AUTO, |
| 471 | + ) |
| 472 | + filename = tmp_path / uuid.uuid4().hex |
| 473 | + symtab = SymbolTable() |
| 474 | + |
| 475 | + # WHEN |
| 476 | + with patch("os.name", "nt"): |
| 477 | + test_obj._materialize_file(filename, test_file, symtab) |
| 478 | + |
| 479 | + # THEN |
| 480 | + with open(filename, "rb") as file: |
| 481 | + result_bytes = file.read() |
| 482 | + assert result_bytes == b"line1\r\nline2" |
| 483 | + |
368 | 484 | class TestMaterialize: |
369 | 485 | """Tests for EmbeddedFiles.materialize()""" |
370 | 486 |
|
|
0 commit comments