33import subprocess
44import sys
55from pathlib import Path , PureWindowsPath
6+ from typing import Any , Generator
67
78import pytest
89
@@ -21,6 +22,16 @@ def to_paths(*paths: str) -> list[Path]:
2122 return [Path (p ) for p in paths ]
2223
2324
25+ @pytest .fixture ()
26+ def plc_dir (plc_code ) -> Generator [Any , Any , None ]:
27+ yield plc_code / "TwinCAT Project1" / "MyPlc"
28+
29+
30+ @pytest .fixture ()
31+ def project (plc_dir ) -> Generator [Any , Any , None ]:
32+ yield plc_dir / "MyPlc.plcproj"
33+
34+
2435def test_help (capsys ):
2536 """Test the help text."""
2637 with pytest .raises (SystemExit ) as err :
@@ -32,27 +43,25 @@ def test_help(capsys):
3243 assert "usage:" in message
3344
3445
35- def test_cli (plc_code ):
46+ def test_cli (plc_dir , project ):
3647 """Test the CLI hook works."""
37- plc_dir = plc_code / "TwinCAT Project1" / "MyPlc"
38- project = plc_dir / "MyPlc.plcproj"
3948 source = plc_dir / "POUs" / "untracked_source"
4049
50+ assert "untracked_source" not in project .read_text ()
51+
4152 path = sys .executable # Re-use whatever executable we're using now
4253 result = subprocess .run (
4354 [path , "-m" , "tctools.patch_plc" , str (project ), "merge" , "-r" , str (source )],
4455 capture_output = True ,
4556 )
4657
4758 assert result .returncode == 0
48- # assert "Re-saved 1 path " in result.stdout.decode ()
49- # TODO: Add some kind of output assertion here
59+ assert "untracked_source " in project . read_text ()
60+ # More detailed assertions we will perform in the next tests
5061
5162
52- def test_merge_single_file (plc_code ):
63+ def test_merge_single_file (plc_dir , project ):
5364 """Test happy-flow adding."""
54- plc_dir = plc_code / "TwinCAT Project1" / "MyPlc"
55- project = plc_dir / "MyPlc.plcproj"
5665 source = plc_dir / "POUs" / "untracked_source" / "F_UntrackedFunc.TcPOU"
5766
5867 patcher = PatchPlc (str (project ), "merge" , str (source ))
@@ -70,11 +79,13 @@ def test_merge_single_file(plc_code):
7079 assert '<Folder Include="POUs\\ untracked_source"/>' in project_content
7180
7281
73- def test_merge_recursive (plc_code ):
74- """Test happy-flow adding for a complete folder."""
75- plc_dir = plc_code / "TwinCAT Project1" / "MyPlc"
76- project = plc_dir / "MyPlc.plcproj"
77- source = plc_dir / "POUs" / "untracked_source"
82+ @pytest .mark .parametrize ("target" , ["POUs/untracked_source/" , "./" ])
83+ def test_merge_recursive (plc_dir , project , target , caplog ):
84+ """Test happy-flow adding for a complete folder.
85+
86+ Try both on a completely new folder and the entire project root
87+ """
88+ source = plc_dir / Path (target )
7889
7990 untracked_files = to_paths (
8091 "POUs/untracked_source/F_UntrackedFunc.TcPOU" ,
@@ -92,8 +103,8 @@ def test_merge_recursive(plc_code):
92103 for path in untracked_files + untracked_folders :
93104 assert path_to_str (path ) not in project_content
94105
95- patcher = PatchPlc ( str ( project ), "merge" , str ( source ), "-r" )
96- patcher .run ()
106+ with caplog . at_level ( logging . WARNING ):
107+ PatchPlc ( str ( project ), "merge" , str ( source ), "-r" ) .run ()
97108
98109 project_content = project .read_text ()
99110
@@ -102,19 +113,18 @@ def test_merge_recursive(plc_code):
102113 for folder in untracked_folders :
103114 assert f'<Folder Include="{ path_to_str (folder )} "/>' in project_content
104115
116+ assert len (caplog .records ) == 0 # No warnings or errors
117+
105118 # Now compare with stored, sorted result:
106- expected_file = plc_code / source / "MyPlc_with_untracked.plcproj.xml"
119+ expected_file = plc_dir / "MyPlc_with_untracked.plcproj.xml"
107120
108121 XmlSorter (str (project )).run ()
109122
110123 assert project .read_text () == expected_file .read_text ()
111124
112125
113- def test_remove (plc_code ):
126+ def test_remove (plc_dir , project ):
114127 """Test remove happy-flow."""
115- plc_dir = plc_code / "TwinCAT Project1" / "MyPlc"
116- project = plc_dir / "MyPlc.plcproj"
117-
118128 tracked_files = to_paths (
119129 "POUs/FB_Example.TcPOU" ,
120130 "DUTs/ST_Example.TcDUT" ,
@@ -136,14 +146,11 @@ def test_remove(plc_code):
136146 assert path_to_str (file ) not in project_content
137147
138148 lines_after = project_content .count ("\n " )
139- assert lines_before - 6 == lines_after # Make sure not more got deleted
149+ assert lines_after == lines_before - 6 # Make sure not more got deleted
140150
141151
142152@pytest .mark .parametrize ("recursive" , [False , True ])
143- def test_remove_recursive (plc_code , recursive ):
144- plc_dir = plc_code / "TwinCAT Project1" / "MyPlc"
145- project = plc_dir / "MyPlc.plcproj"
146-
153+ def test_remove_recursive (plc_dir , project , recursive ):
147154 folder = Path ("POUs/Module" )
148155 tracked_folders = [
149156 'Include="POUs\\ Module"' ,
@@ -173,19 +180,16 @@ def test_remove_recursive(plc_code, recursive):
173180 lines_after = content_after .count ("\n " )
174181
175182 if not recursive :
176- assert content_before == content_after # No changes
183+ assert content_after == content_before # No changes
177184 return
178185
179186 for item in tracked_files + tracked_folders :
180187 assert item not in content_after
181188
182- assert lines_before - 2 * 1 - 3 * 3 == lines_after
183-
189+ assert lines_after == lines_before - 2 * 1 - 3 * 3
184190
185- def test_reset (plc_code ):
186- plc_dir = plc_code / "TwinCAT Project1" / "MyPlc"
187- project = plc_dir / "MyPlc.plcproj"
188191
192+ def test_reset (plc_dir , project ):
189193 # Remove the actual (tracked) folder first:
190194 shutil .rmtree (plc_dir / "POUs" / "Module" )
191195 # And there is already the "POUs/untracked_source" directory
@@ -225,14 +229,11 @@ def test_reset(plc_code):
225229 assert item in content_after
226230
227231 lines_after = content_after .count ("\n " )
228- assert lines_before - (2 * 1 ) - (3 * 3 ) + (2 * 1 ) + (4 * 3 ) == lines_after
232+ assert lines_after == lines_before - (2 * 1 ) - (3 * 3 ) + (2 * 1 ) + (4 * 3 )
229233 # Remove 2 folders and 3 files, add 2 folders and 4 files
230234
231235
232- def test_reset_duplicate (plc_code , caplog ):
233- plc_dir = plc_code / "TwinCAT Project1" / "MyPlc"
234- project = plc_dir / "MyPlc.plcproj"
235-
236+ def test_reset_duplicate (plc_dir , project , caplog ):
236237 # Create a new file, with a name that's already known:
237238 module_folder = plc_dir / "POUs" / "Module"
238239 new_file = module_folder / "DUTs" / "MAIN.TcPOU"
@@ -249,4 +250,4 @@ def test_reset_duplicate(plc_code, caplog):
249250 msg = caplog .records [0 ].message
250251 assert "Refusing to add" in msg and "MAIN.TcPOU" in msg
251252
252- assert content_before == project .read_text () # The project should not be changed
253+ assert project .read_text () == content_before # The project should not be changed
0 commit comments