gdharness 1.3.41 → 1.3.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/build/cli.js +131 -47
  2. package/build/godot/addons/auto_reload/auto_reload.gd +18 -19
  3. package/build/godot/addons/gdharness_editor/animation_reads.gd +84 -35
  4. package/build/godot/addons/gdharness_editor/bridge_client.gd +53 -58
  5. package/build/godot/addons/gdharness_editor/declared_values.gd +68 -32
  6. package/build/godot/addons/gdharness_editor/file_reads.gd +114 -39
  7. package/build/godot/addons/gdharness_editor/file_walk.gd +12 -5
  8. package/build/godot/addons/gdharness_editor/headless_check.gd +94 -41
  9. package/build/godot/addons/gdharness_editor/plugin.gd +2 -3
  10. package/build/godot/addons/gdharness_editor/property_paths.gd +22 -12
  11. package/build/godot/addons/gdharness_editor/property_values.gd +143 -78
  12. package/build/godot/addons/gdharness_editor/reading.gd +37 -12
  13. package/build/godot/addons/gdharness_editor/same_values.gd +4 -4
  14. package/build/godot/addons/gdharness_editor/scene_file.gd +136 -79
  15. package/build/godot/addons/gdharness_editor/scene_uids.gd +12 -6
  16. package/build/godot/addons/gdharness_editor/serialisation.gd +75 -51
  17. package/build/godot/addons/gdharness_editor/setting_reads.gd +7 -6
  18. package/build/godot/addons/gdharness_editor/tool_executor.gd +3 -6
  19. package/build/godot/addons/gdharness_editor/tools/animation_states.gd +41 -28
  20. package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +84 -50
  21. package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +70 -40
  22. package/build/godot/addons/gdharness_editor/tools/class_tools.gd +34 -30
  23. package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +24 -22
  24. package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +49 -29
  25. package/build/godot/addons/gdharness_editor/tools/play_tools.gd +26 -21
  26. package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +40 -40
  27. package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +181 -107
  28. package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +16 -9
  29. package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +75 -43
  30. package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +35 -20
  31. package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +28 -13
  32. package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd +66 -0
  33. package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd.uid +1 -0
  34. package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +171 -62
  35. package/build/godot/addons/gdharness_editor/tools/script_paths.gd +20 -8
  36. package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +11 -8
  37. package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +47 -34
  38. package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +77 -50
  39. package/build/godot/addons/gdharness_editor/value_shapes.gd +5 -6
  40. package/build/godot/addons/gdharness_runtime/call_errors.gd +1 -2
  41. package/build/godot/addons/gdharness_runtime/declared_values.gd +68 -32
  42. package/build/godot/addons/gdharness_runtime/error_report.gd +1 -2
  43. package/build/godot/addons/gdharness_runtime/reading.gd +37 -12
  44. package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +84 -63
  45. package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +153 -148
  46. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +64 -42
  47. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +184 -122
  48. package/build/godot/addons/gdharness_runtime/runtime_frames.gd +2 -2
  49. package/build/godot/addons/gdharness_runtime/runtime_hover.gd +24 -20
  50. package/build/godot/addons/gdharness_runtime/runtime_input.gd +134 -92
  51. package/build/godot/addons/gdharness_runtime/runtime_items.gd +29 -13
  52. package/build/godot/addons/gdharness_runtime/runtime_menus.gd +0 -1
  53. package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +38 -20
  54. package/build/godot/addons/gdharness_runtime/runtime_pad.gd +17 -13
  55. package/build/godot/addons/gdharness_runtime/runtime_paths.gd +84 -46
  56. package/build/godot/addons/gdharness_runtime/runtime_queries.gd +117 -79
  57. package/build/godot/addons/gdharness_runtime/runtime_says.gd +14 -17
  58. package/build/godot/addons/gdharness_runtime/runtime_screen.gd +23 -16
  59. package/build/godot/addons/gdharness_runtime/runtime_targets.gd +117 -66
  60. package/build/godot/addons/gdharness_runtime/runtime_touch.gd +211 -0
  61. package/build/godot/addons/gdharness_runtime/runtime_touch.gd.uid +1 -0
  62. package/build/godot/addons/gdharness_runtime/runtime_typing.gd +44 -27
  63. package/build/godot/addons/gdharness_runtime/runtime_values.gd +108 -73
  64. package/build/godot/addons/gdharness_runtime/runtime_waits.gd +111 -84
  65. package/build/godot/addons/gdharness_runtime/runtime_words.gd +10 -7
  66. package/build/godot/addons/gdharness_runtime/serialisation.gd +75 -51
  67. package/build/godot/addons/gdharness_runtime/value_shapes.gd +5 -6
  68. package/build/godot/addons/gdharness_tests/bench.gd +4 -5
  69. package/build/godot/addons/gdharness_tests/event.gd +10 -5
  70. package/build/godot/addons/gdharness_tests/share.gd +38 -18
  71. package/build/godot/addons/gdharness_tests/suites.gd +3 -3
  72. package/build/godot/addons/gdharness_tests/wait.gd +3 -2
  73. package/build/godot/loader/loader.gd +9 -9
  74. package/build/godot/operations/animation_reads.gd +84 -35
  75. package/build/godot/operations/audio_buses.gd +48 -19
  76. package/build/godot/operations/class_cache.gd +16 -11
  77. package/build/godot/operations/classdb_queries.gd +89 -44
  78. package/build/godot/operations/declared_values.gd +68 -32
  79. package/build/godot/operations/dependencies.gd +139 -93
  80. package/build/godot/operations/editor_tools.gd +9 -10
  81. package/build/godot/operations/export_presets.gd +100 -54
  82. package/build/godot/operations/file_reads.gd +114 -39
  83. package/build/godot/operations/file_walk.gd +12 -5
  84. package/build/godot/operations/gdscript_analysis.gd +105 -66
  85. package/build/godot/operations/gdscript_authoring.gd +138 -39
  86. package/build/godot/operations/godot_operations.gd +17 -11
  87. package/build/godot/operations/import_pipeline.gd +110 -59
  88. package/build/godot/operations/input_actions.gd +63 -39
  89. package/build/godot/operations/patterns.gd +3 -1
  90. package/build/godot/operations/plugins.gd +36 -16
  91. package/build/godot/operations/project_config.gd +144 -27
  92. package/build/godot/operations/project_diagnostics.gd +24 -11
  93. package/build/godot/operations/project_file.gd +16 -16
  94. package/build/godot/operations/project_validation.gd +71 -44
  95. package/build/godot/operations/property_paths.gd +22 -12
  96. package/build/godot/operations/property_values.gd +143 -78
  97. package/build/godot/operations/reading.gd +37 -12
  98. package/build/godot/operations/rename_checks.gd +2 -2
  99. package/build/godot/operations/resource_files.gd +11 -9
  100. package/build/godot/operations/same_values.gd +4 -4
  101. package/build/godot/operations/scene_connections.gd +27 -13
  102. package/build/godot/operations/script_check.gd +52 -49
  103. package/build/godot/operations/serialisation.gd +75 -51
  104. package/build/godot/operations/setting_reads.gd +7 -6
  105. package/build/godot/operations/value_shapes.gd +5 -6
  106. package/build/godot/tests/listed.gd +321 -268
  107. package/package.json +1 -1
@@ -1,12 +1,10 @@
1
1
  extends RefCounted
2
-
3
2
  ## A picture of the running game, as a PNG written where the server asked for it.
4
3
 
5
4
  const GdhRead = preload("reading.gd")
6
5
  const GdhValues = preload("runtime_values.gd")
7
6
  const GdhQueries = preload("runtime_queries.gd")
8
7
  const GdhScreen = preload("runtime_screen.gd")
9
-
10
8
  ## How far zoom enlarges at most. Sixteen makes a 3-pixel ring 48 pixels across, past any need to
11
9
  ## see it, and a 200-pixel region 3200, past the size anybody reads a picture at.
12
10
  const ZOOM_MOST: int = 16
@@ -37,7 +35,7 @@ func capture_viewport(params: Dictionary) -> Dictionary:
37
35
  return standing
38
36
  var node: Node = standing["node"]
39
37
  if not node is Viewport:
40
- return {"type": "error", "message": "Node is not a Viewport: " + viewport_path}
38
+ return { "type": "error", "message": "Node is not a Viewport: " + viewport_path }
41
39
  var viewport: Viewport = node
42
40
  # The root's own state is refused in _capture. Another window of the game's that is hidden or
43
41
  # minimised holds no frame, and asking it for its image makes the engine log the empty read into
@@ -50,8 +48,8 @@ func capture_viewport(params: Dictionary) -> Dictionary:
50
48
  "message":
51
49
  (
52
50
  (
53
- "The Window at %s is hidden, so nothing is drawn to it. Show it (its visible "
54
- + "property) and ask again."
51
+ "The Window at %s is hidden, so nothing is drawn to it. Show it (its "
52
+ + "visible property) and ask again."
55
53
  )
56
54
  % viewport_path
57
55
  ),
@@ -62,8 +60,8 @@ func capture_viewport(params: Dictionary) -> Dictionary:
62
60
  "message":
63
61
  (
64
62
  (
65
- "Nothing is being drawn to the Window at %s, which is minimised. Restore it and "
66
- + "ask again."
63
+ "Nothing is being drawn to the Window at %s, which is minimised. Restore "
64
+ + "it and ask again."
67
65
  )
68
66
  % viewport_path
69
67
  ),
@@ -113,7 +111,9 @@ func _lay_native_windows(image: Image) -> void:
113
111
  if drawn == null or drawn.is_empty():
114
112
  continue
115
113
  drawn.convert(image.get_format())
116
- image.blend_rect(drawn, Rect2i(Vector2i.ZERO, drawn.get_size()), window.position - root.position)
114
+ image.blend_rect(
115
+ drawn, Rect2i(Vector2i.ZERO, drawn.get_size()), window.position - root.position
116
+ )
117
117
 
118
118
 
119
119
  ## The size a capture drawn at [param drawn] is scaled to, from the width and height asked for, 0
@@ -148,26 +148,29 @@ func _cut_asked(params: Dictionary, in_window: bool) -> Dictionary:
148
148
  if (region_given != null or not node_path.is_empty()) and not in_window:
149
149
  return _refused(
150
150
  (
151
- "region and nodePath are in the window's pixels, and this viewport's texture is in its "
152
- + "own: capture the screen with them, or this viewport whole"
151
+ "region and nodePath are in the window's pixels, and this viewport's texture is in "
152
+ + "its own: capture the screen with them, or this viewport whole"
153
153
  )
154
154
  )
155
155
  if zoom < 1 or zoom > ZOOM_MOST:
156
- return _refused("zoom is a whole factor from 1 to %d, and %d was asked for" % [ZOOM_MOST, zoom])
156
+ return _refused(
157
+ "zoom is a whole factor from 1 to %d, and %d was asked for" % [ZOOM_MOST, zoom]
158
+ )
157
159
  if zoom > 1 and sized:
158
160
  return _refused(
159
161
  (
160
- "zoom enlarges by a whole factor and keeps every pixel square, and width and height "
161
- + "scale to a size; give one or the other"
162
+ "zoom enlarges by a whole factor and keeps every pixel square, and width and "
163
+ + "height scale to a size; give one or the other"
162
164
  )
163
165
  )
164
- var asked: Dictionary = {"zoom": zoom}
166
+ var asked: Dictionary = { "zoom": zoom }
165
167
  if region_given != null:
166
168
  var region: Variant = region_of(_values, region_given)
167
169
  if region == null:
168
170
  var shape: String = (
169
- "region is a rectangle in window pixels with an area: x, y, width and height, or the "
170
- + "window rectangle runtime_inspect rect answers, passed back as it came. %s is neither"
171
+ "region is a rectangle in window pixels with an area: x, y, width and height, or "
172
+ + "the window rectangle runtime_inspect rect answers, passed back as it came. %s "
173
+ + "is neither"
171
174
  )
172
175
  return _refused(shape % JSON.stringify(region_given))
173
176
  asked["region"] = region
@@ -182,7 +185,7 @@ func _cut_asked(params: Dictionary, in_window: bool) -> Dictionary:
182
185
 
183
186
 
184
187
  static func _refused(message: String) -> Dictionary:
185
- return {"type": "error", "message": message}
188
+ return { "type": "error", "message": message }
186
189
 
187
190
 
188
191
  ## The rectangle [param given] names: the four numbers x, y, width and height, or a rectangle as the
@@ -210,8 +213,8 @@ static func region_of(values: GdhValues, given: Variant) -> Variant:
210
213
 
211
214
 
212
215
  ## Where [param node] is drawn, in window pixels, as runtime_inspect rect answers it: a Control's
213
- ## rectangle, what a 3D node's geometry covers, or what a 2D node that knows its own rectangle draws.
214
- ## A refusal's message when it has no extent on screen.
216
+ ## rectangle, what a 3D node's geometry covers, or what a 2D node that knows its own rectangle
217
+ ## draws. A refusal's message when it has no extent on screen.
215
218
  static func drawn_rect_of(node: Node) -> Variant:
216
219
  if node is Control:
217
220
  var control: Control = node
@@ -223,13 +226,18 @@ static func drawn_rect_of(node: Node) -> Variant:
223
226
  var spatial: Node3D = node
224
227
  var found: Dictionary = GdhQueries.in_frame(spatial)
225
228
  if not found.has("rect"):
226
- return "%s is not drawn by any current camera, so it covers nothing on screen" % node.get_path()
229
+ return (
230
+ "%s is not drawn by any current camera, so it covers nothing on screen"
231
+ % node.get_path()
232
+ )
227
233
  var covered: Rect2 = found["rect"]
228
234
  return GdhScreen.rect_in_window(spatial.get_viewport(), covered)
229
235
  if node is Node2D and node.has_method("get_rect"):
230
236
  var item: Node2D = node
231
237
  var own: Rect2 = item.call("get_rect")
232
- return GdhScreen.rect_in_window(item.get_viewport(), item.get_global_transform_with_canvas() * own)
238
+ return GdhScreen.rect_in_window(
239
+ item.get_viewport(), item.get_global_transform_with_canvas() * own
240
+ )
233
241
  var no_extent: String = (
234
242
  "%s is a %s, which has a position on screen and no extent; give region around the point "
235
243
  + "runtime_inspect rect answers for it"
@@ -238,9 +246,10 @@ static func drawn_rect_of(node: Node) -> Variant:
238
246
 
239
247
 
240
248
  ## [param region], in window pixels, as pixels of a picture drawn at [param drawn] in a window
241
- ## [param window] pixels across: the same rectangle when the two match, scaled when the project draws
242
- ## at its own size and stretches that to the window. Widened to whole pixels, so an edge falling
243
- ## inside a pixel keeps that pixel, and cut to the picture. Without area when none of it is in it.
249
+ ## [param window] pixels across: the same rectangle when the two match, scaled when the project
250
+ ## draws at its own size and stretches that to the window. Widened to whole pixels, so an edge
251
+ ## falling inside a pixel keeps that pixel, and cut to the picture. Without area when none of it is
252
+ ## in it.
244
253
  static func in_picture(region: Rect2, window: Vector2i, drawn: Vector2i) -> Rect2i:
245
254
  return widened(region, window, drawn).intersection(Rect2i(Vector2i.ZERO, drawn))
246
255
 
@@ -257,14 +266,15 @@ static func widened(region: Rect2, window: Vector2i, drawn: Vector2i) -> Rect2i:
257
266
 
258
267
 
259
268
  ## [param picture], pixels of a picture drawn at [param drawn], as the window pixels it covers in a
260
- ## window [param window] pixels across: what an answer names, since the region was asked for in them.
269
+ ## window [param window] pixels across: what an answer names, since the region was asked for in
270
+ ## them.
261
271
  static func in_window_pixels(picture: Rect2i, window: Vector2i, drawn: Vector2i) -> Dictionary:
262
272
  var scale: Vector2 = Vector2.ONE
263
273
  if drawn.x > 0 and drawn.y > 0 and window.x > 0 and window.y > 0:
264
274
  scale = Vector2(window) / Vector2(drawn)
265
275
  var start: Vector2 = Vector2(picture.position) * scale
266
276
  var size: Vector2 = Vector2(picture.size) * scale
267
- return {"x": start.x, "y": start.y, "width": size.x, "height": size.y}
277
+ return { "x": start.x, "y": start.y, "width": size.x, "height": size.y }
268
278
 
269
279
 
270
280
  ## [param image] cut to [param picture] and enlarged [param zoom] times, each pixel made a square of
@@ -281,7 +291,7 @@ static func cut(image: Image, picture: Rect2i, zoom: int) -> Image:
281
291
  func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false) -> Dictionary:
282
292
  var requested_path: String = str(params.get("output_path", ""))
283
293
  if requested_path.is_empty():
284
- return {"type": "error", "message": "output_path required"}
294
+ return { "type": "error", "message": "output_path required" }
285
295
  var asked: Dictionary = _cut_asked(params, with_windows)
286
296
  if asked.has("message"):
287
297
  return asked
@@ -296,8 +306,8 @@ func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false
296
306
  "type": "error",
297
307
  "message":
298
308
  (
299
- "This game runs headless, so it has no window and draws nothing to capture. Start it "
300
- + "with a window (editor_run start with headless false) to capture it."
309
+ "This game runs headless, so it has no window and draws nothing to capture. Start "
310
+ + "it with a window (editor_run start with headless false) to capture it."
301
311
  ),
302
312
  }
303
313
  if not _host.get_tree().root.can_draw():
@@ -320,11 +330,11 @@ func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false
320
330
 
321
331
  var viewport_texture: ViewportTexture = viewport.get_texture()
322
332
  if viewport_texture == null:
323
- return {"type": "error", "message": "No viewport texture available"}
333
+ return { "type": "error", "message": "No viewport texture available" }
324
334
 
325
335
  var image: Image = viewport_texture.get_image()
326
336
  if image == null:
327
- return {"type": "error", "message": "Failed to capture viewport image"}
337
+ return { "type": "error", "message": "Failed to capture viewport image" }
328
338
  if with_windows:
329
339
  _lay_native_windows(image)
330
340
 
@@ -341,10 +351,12 @@ func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false
341
351
  var why: String = placed
342
352
  return _refused(why)
343
353
  region = placed
344
- # A hidden node's rectangle is still a place, and what is drawn there is whatever is behind it.
354
+ # A hidden node's rectangle is still a place, and what is drawn there is whatever is behind
355
+ # it.
345
356
  if not GdhQueries.shown(node):
346
357
  described["note"] = (
347
- "%s is hidden, so this is what is drawn where it would be rather than the node" % node_path
358
+ "%s is hidden, so this is what is drawn where it would be rather than the node"
359
+ % node_path
348
360
  )
349
361
  if region != null:
350
362
  var asked_region: Rect2 = region
@@ -355,7 +367,10 @@ func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false
355
367
  if not picture.has_area():
356
368
  return _refused(
357
369
  (
358
- "The region at %s, %s pixels across, is outside the window, which is %dx%d pixels"
370
+ (
371
+ "The region at %s, %s pixels across, is outside the window, which is %dx%d "
372
+ + "pixels"
373
+ )
359
374
  % [asked_region.position, asked_region.size, window.x, window.y]
360
375
  )
361
376
  )
@@ -363,10 +378,11 @@ func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false
363
378
  described["region"] = in_window_pixels(picture, window, picture_size)
364
379
  if picture != whole:
365
380
  described["clipped"] = true
366
- # The project draws at its own size and stretches that to the window, so the picture's pixels
367
- # are not the window's: said, because a caller sizing a region by window pixels gets fewer.
381
+ # The project draws at its own size and stretches that to the window, so the picture's
382
+ # pixels are not the window's: said, because a caller sizing a region by window pixels gets
383
+ # fewer.
368
384
  if picture_size != window:
369
- described["drawnAt"] = {"width": picture_size.x, "height": picture_size.y}
385
+ described["drawnAt"] = { "width": picture_size.x, "height": picture_size.y }
370
386
 
371
387
  var zoom: int = asked["zoom"]
372
388
  if zoom > 1:
@@ -384,12 +400,15 @@ func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false
384
400
  if screenshot_path.begins_with("user://") or screenshot_path.begins_with("res://"):
385
401
  screenshot_path = ProjectSettings.globalize_path(screenshot_path)
386
402
  # The server makes the folder for each capture and takes it away when it stops waiting for one,
387
- # and a server replaced since the capture was asked for took it with it. Saving into a folder that
388
- # is gone raises an engine error, which counts against a game that did nothing wrong.
403
+ # and a server replaced since the capture was asked for took it with it. Saving into a folder
404
+ # that is gone raises an engine error, which counts against a game that did nothing wrong.
389
405
  if not DirAccess.dir_exists_absolute(screenshot_path.get_base_dir()):
390
406
  return _refused(
391
407
  (
392
- "The folder to save the capture in, %s, is gone: the server that asked for it stopped waiting"
408
+ (
409
+ "The folder to save the capture in, %s, is gone: the server that asked for it "
410
+ + "stopped waiting"
411
+ )
393
412
  % screenshot_path.get_base_dir()
394
413
  )
395
414
  )
@@ -405,13 +424,16 @@ func _capture(viewport: Viewport, params: Dictionary, with_windows: bool = false
405
424
  static func saved(image: Image, png_path: String) -> Dictionary:
406
425
  var save_error: Error = image.save_png(png_path)
407
426
  if save_error != OK:
408
- return {"type": "error", "message": "Failed to save screenshot as PNG: " + str(save_error)}
427
+ return {
428
+ "type": "error",
429
+ "message": "Failed to save screenshot as PNG: " + str(save_error),
430
+ }
409
431
  var answer: Dictionary = {
410
432
  "type": "screenshot_file",
411
433
  "format": "png",
412
434
  "width": image.get_width(),
413
435
  "height": image.get_height(),
414
- "path": png_path
436
+ "path": png_path,
415
437
  }
416
438
  if image.detect_alpha() == Image.ALPHA_NONE:
417
439
  var jpeg_path: String = png_path.get_basename() + ".jpg"