3737
3838
3939def test_runner_declares_install_status_enum () -> None :
40- source = RUNNER_PATH .read_text ()
40+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
4141 assert "enum InstallStatus { OK, FAILED_CLEAN, FAILED_MIXED }" in source , (
4242 "Three-state install outcome is the contract callers depend on. "
4343 "FAILED_CLEAN means rollback restored the prior state; FAILED_MIXED "
@@ -48,7 +48,7 @@ def test_runner_declares_install_status_enum() -> None:
4848
4949
5050def test_runner_tracks_paths_written_for_cross_batch_rollback () -> None :
51- source = RUNNER_PATH .read_text ()
51+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
5252 assert "var _paths_written = []" in source , (
5353 "Per-file install records must accumulate across both `_new_file_paths` "
5454 "and `_existing_file_paths` batches so a failure in the second batch "
@@ -60,7 +60,7 @@ def test_runner_tracks_paths_written_for_cross_batch_rollback() -> None:
6060
6161
6262def test_install_zip_paths_returns_install_status_and_drives_rollback () -> None :
63- source = RUNNER_PATH .read_text ()
63+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
6464 paths_block = get_func_block (source , "func _install_zip_paths(" )
6565 assert "-> int:" in source [: source .index (paths_block ) + len (paths_block )]
6666 assert "InstallStatus.OK" in paths_block , (
@@ -78,7 +78,7 @@ def test_install_zip_paths_returns_install_status_and_drives_rollback() -> None:
7878
7979
8080def test_install_zip_file_returns_dictionary_record_with_backup_metadata () -> None :
81- source = RUNNER_PATH .read_text ()
81+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
8282 install_block = get_func_block (source , "func _install_zip_file(" )
8383 assert "-> Dictionary:" in source [: source .index (install_block ) + len (install_block )]
8484 # Backup is taken via COPY (not rename) so the original stays in place
@@ -94,7 +94,7 @@ def test_install_zip_file_returns_dictionary_record_with_backup_metadata() -> No
9494
9595
9696def test_install_zip_file_does_not_remove_target_before_rename_attempt () -> None :
97- source = RUNNER_PATH .read_text ()
97+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
9898 install_block = get_func_block (source , "func _install_zip_file(" )
9999 # The first rename attempt must precede any DirAccess.remove_absolute(target_path).
100100 # The remove-then-rename pattern only appears INSIDE the
@@ -112,7 +112,7 @@ def test_install_zip_file_does_not_remove_target_before_rename_attempt() -> None
112112
113113
114114def test_rollback_returns_failed_mixed_when_any_restore_fails () -> None :
115- source = RUNNER_PATH .read_text ()
115+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
116116 rollback_block = get_func_block (source , "func _rollback_paths_written(" )
117117 assert "-> int:" in source [: source .index (rollback_block ) + len (rollback_block )]
118118 assert "InstallStatus.FAILED_MIXED" in rollback_block , (
@@ -138,17 +138,15 @@ def test_inner_install_restore_failure_surfaces_failed_mixed() -> None:
138138 its conditional set in `_install_zip_file`, and its consumption in
139139 `_rollback_paths_written`."""
140140
141- source = RUNNER_PATH .read_text ()
141+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
142142 # Member declaration with the protective comment.
143143 assert "var _restore_failed := false" in source
144144
145145 # `_install_zip_file` must only delete the backup when the restore
146146 # copy actually succeeded. The pattern is: a guarded copy_absolute
147147 # call whose return is checked, and an `else: _restore_failed = true`.
148148 install_block = get_func_block (source , "func _install_zip_file(" )
149- assert (
150- "DirAccess.copy_absolute(backup_path, target_path) == OK" in install_block
151- ), (
149+ assert "DirAccess.copy_absolute(backup_path, target_path) == OK" in install_block , (
152150 "Inner restore must check the copy result before treating the "
153151 "restore as complete. Without this check, a failed copy followed "
154152 "by an unconditional backup delete strands the file and produces "
@@ -170,7 +168,7 @@ def test_inner_install_restore_failure_surfaces_failed_mixed() -> None:
170168
171169
172170def test_handle_install_failure_refuses_to_reenable_on_mixed_state () -> None :
173- source = RUNNER_PATH .read_text ()
171+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
174172 handler_block = get_func_block (source , "func _handle_install_failure(" )
175173 assert "InstallStatus.FAILED_MIXED" in handler_block
176174 # The MIXED branch must NOT call set_plugin_enabled(true). The caller
@@ -189,7 +187,7 @@ def test_handle_install_failure_refuses_to_reenable_on_mixed_state() -> None:
189187
190188
191189def test_extract_and_scan_routes_failure_through_handle_install_failure () -> None :
192- source = RUNNER_PATH .read_text ()
190+ source = RUNNER_PATH .read_text (encoding = "utf-8" )
193191 extract_block = get_func_block (source , "func _extract_and_scan() -> void:" )
194192 assert "_install_zip_paths(_new_file_paths)" in extract_block
195193 assert "_handle_install_failure(status)" in extract_block , (
@@ -213,7 +211,7 @@ def test_extract_and_scan_routes_failure_through_handle_install_failure() -> Non
213211def test_atomic_write_does_not_remove_target_before_swap () -> None :
214212 """The bug pattern: remove(path) then retry rename. Must not return."""
215213
216- source = ATOMIC_WRITE_PATH .read_text ()
214+ source = ATOMIC_WRITE_PATH .read_text (encoding = "utf-8" )
217215 write_block = get_func_block (source , "static func write(" )
218216 # The dangerous sequence was: rename failed -> remove(path) -> rename retry.
219217 # In the new code, remove(path) only happens AFTER a successful copy
@@ -237,7 +235,7 @@ def test_atomic_write_does_not_remove_target_before_swap() -> None:
237235
238236
239237def test_atomic_write_uses_copy_then_verify_as_rename_fallback () -> None :
240- source = ATOMIC_WRITE_PATH .read_text ()
238+ source = ATOMIC_WRITE_PATH .read_text (encoding = "utf-8" )
241239 write_block = get_func_block (source , "static func write(" )
242240 assert "DirAccess.copy_absolute(tmp_path, path)" in write_block , (
243241 "Overwrite-copy is the safe fallback when rename-over-existing is "
@@ -252,7 +250,7 @@ def test_atomic_write_uses_copy_then_verify_as_rename_fallback() -> None:
252250
253251
254252def test_atomic_write_restores_from_backup_when_swap_fails () -> None :
255- source = ATOMIC_WRITE_PATH .read_text ()
253+ source = ATOMIC_WRITE_PATH .read_text (encoding = "utf-8" )
256254 write_block = get_func_block (source , "static func write(" )
257255 assert "DirAccess.copy_absolute(path, backup_path)" in write_block , (
258256 "Snapshot the prior file via copy_absolute BEFORE attempting the "
@@ -272,7 +270,7 @@ def test_atomic_write_restore_does_not_remove_path_before_copy() -> None:
272270 only. `copy_absolute` overwrites by default, so the pre-remove was
273271 unnecessary AND introduced a window where `path` could disappear."""
274272
275- source = ATOMIC_WRITE_PATH .read_text ()
273+ source = ATOMIC_WRITE_PATH .read_text (encoding = "utf-8" )
276274 write_block = get_func_block (source , "static func write(" )
277275
278276 # Locate the `if backup_made:` branch and assert it does NOT contain
@@ -296,7 +294,7 @@ def test_atomic_write_restore_does_not_remove_path_before_copy() -> None:
296294
297295def test_atomic_write_size_verification_uses_utf8_byte_count () -> None :
298296 """`store_string` writes UTF-8 bytes — verify against to_utf8_buffer().size()."""
299- source = ATOMIC_WRITE_PATH .read_text ()
297+ source = ATOMIC_WRITE_PATH .read_text (encoding = "utf-8" )
300298 verify_block = get_func_block (source , "static func _written_size_matches(" )
301299 assert "content.to_utf8_buffer().size()" in verify_block , (
302300 "String.length() returns char count which diverges from the byte "
@@ -314,7 +312,7 @@ def test_atomic_write_clears_partial_new_file_when_no_original_existed() -> None
314312 "destination is in its pre-call state on failure" — for a brand-new path
315313 that means nothing should be on disk after the function returns false."""
316314
317- source = ATOMIC_WRITE_PATH .read_text ()
315+ source = ATOMIC_WRITE_PATH .read_text (encoding = "utf-8" )
318316 write_block = get_func_block (source , "static func write(" )
319317 assert "elif not had_original and FileAccess.file_exists(path):" in write_block , (
320318 "Failure path must clear partial bytes when no original existed. "
0 commit comments