Browse Source

deps: add WAT, a Gdscript library for unit testing

We also tried GUT in the past, so we wanted to try WAT this time.
We're not sure which would be easier to extend in order to add
a Gherkin parser and runner.
master
Dominique Merle 2 years ago
commit
e7270d2d68
  1. 21
      addons/WAT/LICENSE
  2. BIN
      addons/WAT/assets/crash_warning.png
  3. 34
      addons/WAT/assets/crash_warning.png.import
  4. BIN
      addons/WAT/assets/down.png
  5. 34
      addons/WAT/assets/down.png.import
  6. BIN
      addons/WAT/assets/failed.png
  7. 34
      addons/WAT/assets/failed.png.import
  8. BIN
      addons/WAT/assets/function.png
  9. 34
      addons/WAT/assets/function.png.import
  10. 3
      addons/WAT/assets/function.svg
  11. 34
      addons/WAT/assets/function.svg.import
  12. BIN
      addons/WAT/assets/icon_add.png
  13. 34
      addons/WAT/assets/icon_add.png.import
  14. BIN
      addons/WAT/assets/kofi.png
  15. 34
      addons/WAT/assets/kofi.png.import
  16. BIN
      addons/WAT/assets/more_button.png
  17. 34
      addons/WAT/assets/more_button.png.import
  18. 87
      addons/WAT/assets/more_button.svg
  19. 34
      addons/WAT/assets/more_button.svg.import
  20. 86
      addons/WAT/assets/play.svg
  21. 34
      addons/WAT/assets/play.svg.import
  22. BIN
      addons/WAT/assets/remove.png
  23. 34
      addons/WAT/assets/remove.png.import
  24. BIN
      addons/WAT/assets/replace.png
  25. 34
      addons/WAT/assets/replace.png.import
  26. BIN
      addons/WAT/assets/success.png
  27. 34
      addons/WAT/assets/success.png.import
  28. BIN
      addons/WAT/assets/summary.png
  29. 34
      addons/WAT/assets/summary.png.import
  30. 147
      addons/WAT/cli.tscn
  31. 315
      addons/WAT/core/assertions/assertions.gd
  32. 19
      addons/WAT/core/assertions/base.gd
  33. 10
      addons/WAT/core/assertions/boolean/is_false.gd
  34. 10
      addons/WAT/core/assertions/boolean/is_true.gd
  35. 132
      addons/WAT/core/assertions/class_list.gd
  36. 59
      addons/WAT/core/assertions/constants/type_library.gd
  37. 18
      addons/WAT/core/assertions/double/called_with_arguments.gd
  38. 9
      addons/WAT/core/assertions/double/script_was_called.gd
  39. 9
      addons/WAT/core/assertions/double/script_was_not_called.gd
  40. 12
      addons/WAT/core/assertions/equality/is_equal.gd
  41. 11
      addons/WAT/core/assertions/equality/is_equal_or_greater_than.gd
  42. 11
      addons/WAT/core/assertions/equality/is_equal_or_less_than.gd
  43. 11
      addons/WAT/core/assertions/equality/is_greater_than.gd
  44. 11
      addons/WAT/core/assertions/equality/is_less_than.gd
  45. 8
      addons/WAT/core/assertions/equality/is_not_equal.gd
  46. 9
      addons/WAT/core/assertions/file/file_does_not_exist.gd
  47. 10
      addons/WAT/core/assertions/file/file_exists.gd
  48. 9
      addons/WAT/core/assertions/is/is_AABB.gd
  49. 9
      addons/WAT/core/assertions/is/is_Array.gd
  50. 9
      addons/WAT/core/assertions/is/is_Basis.gd
  51. 9
      addons/WAT/core/assertions/is/is_Color.gd
  52. 9
      addons/WAT/core/assertions/is/is_Dictionary.gd
  53. 9
      addons/WAT/core/assertions/is/is_NodePath.gd
  54. 9
      addons/WAT/core/assertions/is/is_Object.gd
  55. 9
      addons/WAT/core/assertions/is/is_Plane.gd
  56. 9
      addons/WAT/core/assertions/is/is_PoolByteArray.gd
  57. 9
      addons/WAT/core/assertions/is/is_PoolColorArray.gd
  58. 9
      addons/WAT/core/assertions/is/is_PoolIntArray.gd
  59. 9
      addons/WAT/core/assertions/is/is_PoolRealArray.gd
  60. 9
      addons/WAT/core/assertions/is/is_PoolStringArray.gd
  61. 9
      addons/WAT/core/assertions/is/is_PoolVector2Array.gd
  62. 9
      addons/WAT/core/assertions/is/is_PoolVector3Array.gd
  63. 9
      addons/WAT/core/assertions/is/is_Quat.gd
  64. 9
      addons/WAT/core/assertions/is/is_RID.gd
  65. 9
      addons/WAT/core/assertions/is/is_Rect2.gd
  66. 9
      addons/WAT/core/assertions/is/is_String.gd
  67. 9
      addons/WAT/core/assertions/is/is_Transform.gd
  68. 9
      addons/WAT/core/assertions/is/is_Transform2D.gd
  69. 9
      addons/WAT/core/assertions/is/is_Vector2.gd
  70. 9
      addons/WAT/core/assertions/is/is_Vector3.gd
  71. 9
      addons/WAT/core/assertions/is/is_bool.gd
  72. 8
      addons/WAT/core/assertions/is/is_built_in_type.gd
  73. 9
      addons/WAT/core/assertions/is/is_class_instance.gd
  74. 9
      addons/WAT/core/assertions/is/is_float.gd
  75. 9
      addons/WAT/core/assertions/is/is_int.gd
  76. 9
      addons/WAT/core/assertions/is_not/is_not_AABB.gd
  77. 9
      addons/WAT/core/assertions/is_not/is_not_Array.gd
  78. 9
      addons/WAT/core/assertions/is_not/is_not_Basis.gd
  79. 9
      addons/WAT/core/assertions/is_not/is_not_Color.gd
  80. 9
      addons/WAT/core/assertions/is_not/is_not_Dictionary.gd
  81. 9
      addons/WAT/core/assertions/is_not/is_not_NodePath.gd
  82. 9
      addons/WAT/core/assertions/is_not/is_not_Object.gd
  83. 9
      addons/WAT/core/assertions/is_not/is_not_Plane.gd
  84. 9
      addons/WAT/core/assertions/is_not/is_not_PoolByteArray.gd
  85. 9
      addons/WAT/core/assertions/is_not/is_not_PoolColorArray.gd
  86. 9
      addons/WAT/core/assertions/is_not/is_not_PoolIntArray.gd
  87. 9
      addons/WAT/core/assertions/is_not/is_not_PoolRealArray.gd
  88. 9
      addons/WAT/core/assertions/is_not/is_not_PoolStringArray.gd
  89. 9
      addons/WAT/core/assertions/is_not/is_not_PoolVector2Array.gd
  90. 9
      addons/WAT/core/assertions/is_not/is_not_PoolVector3Array.gd
  91. 9
      addons/WAT/core/assertions/is_not/is_not_Quat.gd
  92. 9
      addons/WAT/core/assertions/is_not/is_not_RID.gd
  93. 9
      addons/WAT/core/assertions/is_not/is_not_Rect2.gd
  94. 9
      addons/WAT/core/assertions/is_not/is_not_String.gd
  95. 9
      addons/WAT/core/assertions/is_not/is_not_Transform.gd
  96. 9
      addons/WAT/core/assertions/is_not/is_not_Transform2D.gd
  97. 9
      addons/WAT/core/assertions/is_not/is_not_Vector2.gd
  98. 9
      addons/WAT/core/assertions/is_not/is_not_Vector3.gd
  99. 9
      addons/WAT/core/assertions/is_not/is_not_bool.gd
  100. 7
      addons/WAT/core/assertions/is_not/is_not_built_in_type.gd

21
addons/WAT/LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

BIN
addons/WAT/assets/crash_warning.png

After

Width: 25  |  Height: 25  |  Size: 892 B

34
addons/WAT/assets/crash_warning.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/crash_warning.png-e91fc83896a759bc0e8033b98cc4897b.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/crash_warning.png"
dest_files=[ "res://.import/crash_warning.png-e91fc83896a759bc0e8033b98cc4897b.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/down.png

After

Width: 16  |  Height: 16  |  Size: 317 B

34
addons/WAT/assets/down.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/down.png-26c0271889a75bba3617a8a20841e34c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/down.png"
dest_files=[ "res://.import/down.png-26c0271889a75bba3617a8a20841e34c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/failed.png

After

Width: 25  |  Height: 25  |  Size: 2.0 KiB

34
addons/WAT/assets/failed.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/failed.png-18188bee7d18ad72bc7cbc6222c355b1.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/failed.png"
dest_files=[ "res://.import/failed.png-18188bee7d18ad72bc7cbc6222c355b1.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/function.png

After

Width: 16  |  Height: 16  |  Size: 317 B

34
addons/WAT/assets/function.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/function.png-b5f751bc93a3ee5a29c4d32864c250fc.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/function.png"
dest_files=[ "res://.import/function.png-b5f751bc93a3ee5a29c4d32864c250fc.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

3
addons/WAT/assets/function.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="m6.0215 3c-0.40133-0.0028518-0.79916 0.074854-1.1699 0.22852-1.1208 0.46444-1.8516 1.5582-1.8516 2.7715v7h2v-3h2v-2h-2v-2c0-0.55228 0.44772-1 1-1 0.2652 4.01e-5 0.51953 0.10542 0.70703 0.29297l1.4141-1.4141c-0.55724-0.5574-1.3115-0.87312-2.0996-0.87891zm2.9785 3c-1.3263 2.6586-1.3404 4.3252 0 7h2c-1.3404-2.6748-1.3263-4.3414 0-7h-2zm4 0c1.3263 2.6586 1.3404 4.3252 0 7h2c1.3404-2.6748 1.3263-4.3414 0-7h-2zm-12 5a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1z" fill="#e0e0e0" stroke-width="0"/>
</svg>

34
addons/WAT/assets/function.svg.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/function.svg-14e03c4a8904011639649cd74908f843.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/function.svg"
dest_files=[ "res://.import/function.svg-14e03c4a8904011639649cd74908f843.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/icon_add.png

After

Width: 16  |  Height: 16  |  Size: 351 B

34
addons/WAT/assets/icon_add.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_add.png-0e0742698753e4b62c9226c6a48eec36.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/icon_add.png"
dest_files=[ "res://.import/icon_add.png-0e0742698753e4b62c9226c6a48eec36.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/kofi.png

After

Width: 25  |  Height: 25  |  Size: 741 B

34
addons/WAT/assets/kofi.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/kofi.png-25130db51d1b80d6426df72322b3f642.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/kofi.png"
dest_files=[ "res://.import/kofi.png-25130db51d1b80d6426df72322b3f642.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/more_button.png

After

Width: 16  |  Height: 16  |  Size: 162 B

34
addons/WAT/assets/more_button.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/more_button.png-94fdfc4de255b283c1556198e1efe904.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/more_button.png"
dest_files=[ "res://.import/more_button.png-94fdfc4de255b283c1556198e1efe904.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

87
addons/WAT/assets/more_button.svg

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="16"
height="16"
viewBox="-27.5 -27.5 16 16"
id="svg9"
sodipodi:docname="more_button.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata15">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs13" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1608"
inkscape:window-height="1041"
id="namedview11"
showgrid="true"
inkscape:pagecheckerboard="true"
showborder="true"
borderlayer="false"
inkscape:showpageshadow="false"
inkscape:snap-object-midpoints="true"
inkscape:zoom="35.771086"
inkscape:cx="5.8871336"
inkscape:cy="8.1097558"
inkscape:window-x="305"
inkscape:window-y="116"
inkscape:window-maximized="0"
inkscape:current-layer="svg9">
<inkscape:grid
spacingx="1"
spacingy="1"
empspacing="4"
type="xygrid"
id="grid4525" />
</sodipodi:namedview>
<desc
id="en">
Codes 60-69 General Group: Rain.
Code: 64
Description: Rain, not freezing, intermittent (heavy at time of observation)
</desc>
<circle
id="circle3"
r="1.9642856"
cx="-19.5"
cy="-19.5"
style="fill:#e0e0e0;stroke-width:0.35714284" />
<circle
cy="-24.5"
id="circle5"
r="1.9642856"
cx="-19.5"
style="fill:#e0e0e0;stroke-width:0.35714284" />
<circle
cy="-14.5"
id="circle7"
r="1.9642856"
cx="-19.5"
style="fill:#e0e0e0;stroke-width:0.35714284" />
</svg>

34
addons/WAT/assets/more_button.svg.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/more_button.svg-f52f2977a26f7d8685b3e0a5dcb7978e.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/more_button.svg"
dest_files=[ "res://.import/more_button.svg-f52f2977a26f7d8685b3e0a5dcb7978e.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

86
addons/WAT/assets/play.svg

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
viewBox="0 0 16 16"
id="svg2"
version="1.1"
inkscape:version="0.92+devel unknown"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_packed_scene.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
sodipodi:docname="icon_play.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="9.4020048"
inkscape:cy="8.5528568"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:object-nodes="true"
inkscape:document-rotation="0">
<inkscape:grid
type="xygrid"
id="grid3336" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
<g
id="path4155"
style="opacity:1">
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 4.9882812,1039.3633 c -0.5469019,0.01 -0.9871709,0.4511 -0.9882812,0.998 v 8 c 1.163e-4,0.7986 0.8901078,1.275 1.5546875,0.8321 l 6.0000005,-4 c 0.593625,-0.3959 0.593625,-1.2682 0,-1.6641 l -6.0000005,-4 c -0.1678029,-0.1111 -0.3652036,-0.1689 -0.5664063,-0.166 z"
id="path4272"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</g>
</g>
</svg>

34
addons/WAT/assets/play.svg.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/play.svg-0b6b527de6d3691c6b38f55eee12b863.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/play.svg"
dest_files=[ "res://.import/play.svg-0b6b527de6d3691c6b38f55eee12b863.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/remove.png

After

Width: 16  |  Height: 16  |  Size: 519 B

34
addons/WAT/assets/remove.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/remove.png-8cb32c9aa5ac2bcacf7f560309eb94d7.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/remove.png"
dest_files=[ "res://.import/remove.png-8cb32c9aa5ac2bcacf7f560309eb94d7.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/replace.png

After

Width: 16  |  Height: 16  |  Size: 435 B

34
addons/WAT/assets/replace.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/replace.png-978f412fbc11b1790a1eb275c00218c4.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/replace.png"
dest_files=[ "res://.import/replace.png-978f412fbc11b1790a1eb275c00218c4.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/success.png

After

Width: 25  |  Height: 25  |  Size: 2.5 KiB

34
addons/WAT/assets/success.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/success.png-22ff6871ccf3e0018fe6815cfb7f3a42.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/success.png"
dest_files=[ "res://.import/success.png-22ff6871ccf3e0018fe6815cfb7f3a42.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
addons/WAT/assets/summary.png

After

Width: 76  |  Height: 13  |  Size: 1.3 KiB

34
addons/WAT/assets/summary.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/summary.png-7450d5c9f7423e218828f170e65d992e.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/WAT/assets/summary.png"
dest_files=[ "res://.import/summary.png-7450d5c9f7423e218828f170e65d992e.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

147
addons/WAT/cli.tscn

@ -0,0 +1,147 @@
[gd_scene load_steps=2 format=2]
[sub_resource type="GDScript" id=1]
script/source = "extends Node
const RUN_ALL: String = \"-run_all\"
const RUN_DIRECTORY: String = \"-run_dir\"
const RUN_SCRIPT: String = \"-run_script\"
const RUN_TAG: String = \"-run_tag\"
const RUN_METHOD: String = \"-run_method\"
const RUN_FAILURES: String = \"-rerun_failed\"
const LIST_ALL: String = \"-list_all\"
const LIST_DIR: String = \"-list_dir\"
const PASSED: int = 0
const FAILED: int = 1
const TestRunner: PackedScene = preload(\"res://addons/WAT/core/test_runner/TestRunner.tscn\")
const FileSystem: Reference = preload(\"res://addons/WAT/system/filesystem.gd\")
var _runner: Node
var _start_time: float
func _ready() -> void:
parse(arguments())
func arguments() -> Array:
return Array(OS.get_cmdline_args()).pop_back().split(\"=\") as Array
func repeat(args) -> int:
if not args.empty() and args.back().is_valid_integer():
return args.back() as int
else:
return 1
func parse(arguments: Array) -> void:
ProjectSettings.set(\"WAT/TestStrategy\", {})
ProjectSettings.save()
var command: String = arguments.pop_front()
match command:
RUN_ALL:
var strat = strategy()
strat[\"strategy\"] = \"RunAll\"
strat[\"repeat\"] = repeat(arguments)
ProjectSettings.set(\"WAT/TestStrategy\", strat)
_run()
RUN_DIRECTORY:
var strat = strategy()
strat[\"strategy\"] = \"RunDirectory\"
strat[\"directory\"] = arguments.front()
strat[\"repeat\"] = repeat(arguments)
ProjectSettings.set(\"WAT/TestStrategy\", strat)
_run()
RUN_SCRIPT:
var strat = strategy()
strat[\"strategy\"] = \"RunScript\"
strat[\"script\"] = arguments.front()
strat[\"repeat\"] = repeat(arguments)
ProjectSettings.set(\"WAT/TestStrategy\", strat)
_run()
RUN_TAG:
var strat = strategy()
strat[\"strategy\"] = \"RunTag\"
strat[\"tag\"] = arguments.front()
print(strat[\"tag\"])
strat[\"repeat\"] = repeat(arguments)
ProjectSettings.set(\"WAT/TestStrategy\", strat)
_run()
RUN_METHOD:
var strat = strategy()
strat[\"strategy\"] = \"RunMethod\"
strat[\"script\"] = arguments[0]
strat[\"method\"] = arguments[1]
strat[\"repeat\"] = repeat(arguments)
ProjectSettings.set(\"WAT/TestStrategy\", strat)
_run()
RUN_FAILURES:
var strat = strategy()
strat[\"strategy\"] = \"RerunFailures\"
strat[\"repeat\"] = repeat(arguments)
ProjectSettings.set(\"WAT/TestStrategy\", strat)
_run()
LIST_ALL:
_list()
get_tree().quit()
LIST_DIR:
_list(arguments.pop_front())
get_tree().quit()
_:
push_error(\"Invalid Argument\")
get_tree().quit()
func strategy() -> Dictionary:
return ProjectSettings.get_setting(\"WAT/TestStrategy\")
func test_directory() -> String:
return ProjectSettings.get_setting(\"WAT/Test_Directory\")
func _list(path: String = test_directory()):
print()
print(FileSystem.scripts(path))
func _run() -> void:
_runner = TestRunner.instance()
_runner.connect(\"ended\", self, \"_on_testrunner_ended\")
_start_time = OS.get_ticks_msec()
add_child(_runner)
static func set_run_path(path: String) -> void:
ProjectSettings.set(\"WAT/ActiveRunPath\", path)
func _on_testrunner_ended() -> void:
_runner.queue_free()
var caselist: Array = WAT.Results.withdraw()
var cases = {passed = 0, total = 0, crashed = 0}
for case in caselist:
cases.total += 1
if case.success:
cases.passed += 1
else:
display_failures(case)
display_summary(cases)
set_exit_code(cases)
func display_failures(case) -> void:
print(\"%s (%s)\" % [case.context, case.path])
for method in case.methods:
if not method.success:
print(\"\\n %s\" % method.context)
for assertion in method.assertions:
if not assertion.success:
print(\"\\t%s\" % assertion.context, \"\\n\\t (EXPECTED: %s) | (RESULTED: %s)\" % [assertion.expected, assertion.actual])
func display_summary(cases: Dictionary) -> void:
cases.seconds = (OS.get_ticks_msec() - _start_time) / 1000
print(\"\"\"
-------RESULTS-------
Took {seconds} seconds
{crashed} Tests Crashed
{passed} / {total} Tests Passed
-------RESULTS-------
\"\"\".format(cases).dedent())
func set_exit_code(cases: Dictionary) -> void:
OS.exit_code = PASSED if cases.total > 0 and cases.total == cases.passed and cases.crashed == 0 else FAILED
"
[node name="cli" type="Node"]
script = SubResource( 1 )

315
addons/WAT/core/assertions/assertions.gd

@ -0,0 +1,315 @@
extends "class_list.gd"
signal OUTPUT
signal asserted
func output(data) -> void:
emit_signal("asserted", data)
func loop(method: String, data: Array) -> void:
for set in data:
callv(method, set)
func is_true(condition: bool, context: String = "") -> void:
output(IsTrue.new(condition, context))
func is_false(condition: bool, context: String = "") -> void:
output(IsFalse.new(condition, context))
func is_equal(a, b, context: String = "") -> void:
output(IsEqual.new(a, b, context))
func is_not_equal(a, b, context: String = "") -> void:
output(IsNotEqual.new(a, b, context))
func is_greater_than(a, b, context: String = "") -> void:
output(IsGreaterThan.new(a, b, context))
func is_less_than(a, b, context: String = "") -> void:
output(IsLessThan.new(a, b, context))
func is_equal_or_greater_than(a, b, context: String = "") -> void:
output(IsEqualOrGreaterThan.new(a, b, context))
func is_equal_or_less_than(a, b, context: String = "") -> void:
output(IsEqualOrLessThan.new(a, b, context))
func is_in_range(value, low, high, context: String = "") -> void:
output(IsInRange.new(value, low, high, context))
func is_not_in_range(value, low, high, context: String = "") -> void:
output(IsNotInRange.new(value, low, high, context))
func has(value, container, context: String = "") -> void:
output(Has.new(value, container, context))
func does_not_have(value, container, context: String = "") -> void:
output(DoesNotHave.new(value, container, context))
func is_class_instance(instance, type, context: String = "") -> void:
output(IsClassInstance.new(instance, type, context))
func is_not_class_instance(instance, type, context: String = "") -> void:
output(IsNotClassInstance.new(instance, type, context))
func is_built_in_type(value, type, context: String = "") -> void:
print("WARNING: is_built_in_type is deprecated. Use is_x where x is builtin type")
output(IsBuiltInType.new(value, type, context))
func is_not_built_in_type(value, type: int, context: String = "") -> void:
output(IsNotBuiltInType.new(value, type, context))
func is_null(value, context: String = "") -> void:
output(IsNull.new(value, context))
func is_not_null(value, context: String = "") -> void:
output(IsNotNull.new(value, context))
func string_contains(value, string: String, context: String = "") -> void:
output(Contains.new(value, string, context))
func string_does_not_contain(value, string: String, context: String = "") -> void:
output(DoesNotContain.new(value, string, context))
func string_begins_with(value, string: String, context: String = "") -> void:
output(BeginsWith.new(value, string, context))
func string_does_not_begin_with(value, string: String, context: String = "") -> void:
output(DoesNotBeginWith.new(value, string, context))
func string_ends_with(value, string: String, context: String = "") -> void:
output(EndsWith.new(value, string, context))
func string_does_not_end_with(value, string: String, context: String = "") -> void:
output(DoesNotEndWith.new(value, string, context))
func was_called(double, method: String, context: String = "") -> void:
output(ScriptWasCalled.new(double, method, context))
func was_not_called(double, method: String, context: String = "") -> void:
output(ScriptWasNotCalled.new(double, method, context))
func was_called_with_arguments(double, method: String, arguments: Array, context: String = "") -> void:
output(CalledWithArguments.new(double, method, arguments, context))
func signal_was_emitted(emitter, _signal, context: String = "") -> void:
output(WasEmitted.new(emitter, _signal, context))
func signal_was_emitted_x_times(emitter, _signal, times: int, context: String = "") -> void:
output(WasEmittedXTimes.new(emitter, _signal, times, context))
func signal_was_not_emitted(emitter, _signal: String, context: String = "") -> void:
output(WasNotEmitted.new(emitter, _signal, context))
func signal_was_emitted_with_arguments(emitter, _signal, arguments: Array, context: String = "") -> void:
output(WasEmittedWithArguments.new(emitter, _signal, arguments, context))
func file_exists(path: String, context: String = "") -> void:
output(FileExists.new(path, context))
func file_does_not_exist(path: String, context: String = "") -> void:
output(FileDoesNotExist.new(path, context))
func that(obj: Object, method: String, arguments: Array = [], context: String = "", passed: String = "", failed: String = "") -> void:
output(That.new(obj, method, arguments, context, passed, failed))
func object_has_meta(obj: Object, meta: String, context: String) -> void:
output(ObjectHasMeta.new(obj, meta, context))
func object_does_not_have_meta(obj: Object, meta: String, context: String) -> void:
output(ObjectDoesNotHaveMeta.new(obj, meta, context))
func object_has_method(obj: Object, method: String, context: String) -> void:
output(ObjectHasMethod.new(obj, method, context))
func object_does_not_have_method(obj: Object, method: String, context: String) -> void:
output(ObjectDoesNotHaveMethod.new(obj, method, context))
func object_is_queued_for_deletion(obj: Object, context: String) -> void:
output(ObjectIsQueuedForDeletion.new(obj, context))
func object_is_not_queued_for_deletion(obj: Object, context: String) -> void:
output(ObjectIsNotQueuedForDeletion.new(obj, context))
func object_is_connected(sender: Object, _signal: String, receiver: Object, method: String, context: String) -> void:
output(ObjectIsConnected.new(sender, _signal, receiver, method, context))
func object_is_not_connected(sender: Object, _signal: String, receiver: Object, method: String, context: String) -> void:
output(ObjectIsNotConnected.new(sender, _signal, receiver, method, context))
func object_is_blocking_signals(obj: Object, context: String) -> void:
output(ObjectIsBlockingSignals.new(obj, context))
func object_is_not_blocking_signals(obj: Object, context: String) -> void:
output(ObjectIsNotBlockingSignals.new(obj, context))
func object_has_user_signal(obj: Object, _signal: String, context: String) -> void:
output(ObjectHasUserSignal.new(obj, _signal, context))
func object_does_not_have_user_signal(obj: Object, _signal: String, context: String) -> void:
output(ObjectDoesNotHaveUserSignal.new(obj, _signal, context))
func is_freed(obj: Object, context: String = "") -> void:
output(ObjectIsFreed.new(obj, context))
func is_not_freed(obj: Object, context: String = "") -> void:
output(ObjectIsNotFreed.new(obj, context))
func is_bool(value, context: String = "") -> void:
output(IsBool.new(value, context))
func is_not_bool(value, context: String = "") -> void:
output(IsNotBool.new(value, context))
func is_int(value, context: String = "") -> void:
output(IsInt.new(value, context))
func is_not_int(value, context: String = "") -> void:
output(IsNotInt.new(value, context))
func is_float(value, context: String = "") -> void:
output(IsFloat.new(value, context))
func is_not_float(value, context: String = "") -> void:
output(IsNotFloat.new(value, context))
func is_String(value, context: String = "") -> void:
output(IsString.new(value, context))
func is_not_String(value, context: String = "") -> void:
output(IsNotString.new(value, context))
func is_Vector2(value, context: String = "") -> void:
output(IsVector2.new(value, context))
func is_not_Vector2(value, context: String = "") -> void:
output(IsNotVector2.new(value, context))
func is_Rect2(value, context: String = "") -> void:
output(IsRect2.new(value, context))
func is_not_Rect2(value, context: String = "") -> void:
output(IsNotRect2.new(value, context))
func is_Vector3(value, context: String = "") -> void:
output(IsVector3.new(value, context))
func is_not_Vector3(value, context: String = "") -> void:
output(IsNotVector3.new(value, context))
func is_Transform2D(value, context: String = "") -> void:
output(IsTransform2D.new(value, context))
func is_not_Transform2D(value, context: String = "") -> void:
output(IsNotTransform2D.new(value, context))
func is_Plane(value, context: String = "") -> void:
output(IsPlane.new(value, context))
func is_not_Plane(value, context: String = "") -> void:
output(IsNotPlane.new(value, context))
func is_Quat(value, context: String = "") -> void:
output(IsQuat.new(value, context))
func is_not_Quat(value, context: String = "") -> void:
output(IsNotQuat.new(value, context))
func is_AABB(value, context: String = "") -> void:
output(IsAABB.new(value, context))
func is_not_AABB(value, context: String = "") -> void:
output(IsNotAABB.new(value, context))
func is_Basis(value, context: String = "") -> void:
output(IsBasis.new(value, context))
func is_not_Basis(value, context: String = "") -> void:
output(IsNotBasis.new(value, context))
func is_Transform(value, context: String = "") -> void:
output(IsTransform.new(value, context))
func is_not_Transform(value, context: String = "") -> void:
output(IsNotTransform.new(value, context))
func is_Color(value, context: String = "") -> void:
output(IsColor.new(value, context))
func is_not_Color(value, context: String = "") -> void:
output(IsNotColor.new(value, context))
func is_NodePath(value, context: String = "") -> void:
output(IsNodePath.new(value, context))
func is_not_NodePath(value, context: String = "") -> void:
output(IsNotNodePath.new(value, context))
func is_RID(value, context: String = "") -> void:
output(IsRID.new(value, context))
func is_not_RID(value, context: String = "") -> void:
output(IsNotRID.new(value, context))
func is_Object(value, context: String = "") -> void:
output(IsObject.new(value, context))
func is_not_Object(value, context: String = "") -> void:
output(IsNotObject.new(value, context))
func is_Dictionary(value, context: String = "") -> void:
output(IsDictionary.new(value, context))
func is_not_Dictionary(value, context: String = "") -> void:
output(IsNotDictionary.new(value, context))
func is_Array(value, context: String = "") -> void:
output(IsArray.new(value, context))
func is_not_Array(value, context: String = "") -> void:
output(IsNotArray.new(value, context))
func is_PoolByteArray(value, context: String = "") -> void:
output(IsPoolByteArray.new(value, context))
func is_not_PoolByteArray(value, context: String = "") -> void:
output(IsNotPoolByteArray.new(value, context))
func is_PoolIntArray(value, context: String = "") -> void:
output(IsPoolIntArray.new(value, context))
func is_not_PoolIntArray(value, context: String = "") -> void:
output(IsNotPoolIntArray.new(value, context))
func is_PoolRealArray(value, context: String = "") -> void:
output(IsPoolRealArray.new(value, context))
func is_not_PoolRealArray(value, context: String = "") -> void:
output(IsNotPoolRealArray.new(value, context))
func is_PoolStringArray(value, context: String = "") -> void:
output(IsPoolStringArray.new(value, context))
func is_not_PoolStringArray(value, context: String = "") -> void:
output(IsNotPoolStringArray.new(value, context))
func is_PoolVector2Array(value, context: String = "") -> void:
output(IsPoolVector2Array.new(value, context))
func is_not_PoolVector2Array(value, context: String = "") -> void:
output(IsNotPoolVector2Array.new(value, context))
func is_PoolVector3Array(value, context: String = "") -> void:
output(IsPoolVector3Array.new(value, context))
func is_not_PoolVector3Array(value, context: String = "") -> void:
output(IsNotPoolVector3Array.new(value, context))
func is_PoolColorArray(value, context: String = "") -> void:
output(IsPoolColorArray.new(value, context))
func is_not_PoolColorArray(value, context: String = "") -> void:
output(IsNotPoolColorArray.new(value, context))
func fail(context: String = "Unimplemented Test") -> void:
output(Fail.new(context))

19
addons/WAT/core/assertions/base.gd

@ -0,0 +1,19 @@
extends Reference
const TYPES = preload("constants/type_library.gd")
var success: bool
var expected: String = "NULL"
var result: String
var notes: String = "No Notes"
var context
func type2str(value):
return TYPES.get_type_string(typeof(value))
func to_dictionary() -> Dictionary:
return {
"success": success,
"expected": expected,
"actual": result,
"context": context
}

10
addons/WAT/core/assertions/boolean/is_false.gd

@ -0,0 +1,10 @@
extends "../base.gd"
func _init(value, context: String) -> void:
var type = type2str(value)
var passed: String = "|%s| %s == false" % [type, value]
var failed: String = "|%s| %s != false" % [type, value]
self.context = context
self.success = (value == false)
self.expected = passed
self.result = passed if self.success else failed

10
addons/WAT/core/assertions/boolean/is_true.gd

@ -0,0 +1,10 @@
extends "../base.gd"
func _init(value, context: String) -> void:
var type = type2str(value)
var passed: String = "|%s| %s == true" % [type, value]
var failed: String = "|%s| %s != true" % [type, value]
self.context = context
self.success = (value == true)
self.expected = passed
self.result = passed if self.success else failed

132
addons/WAT/core/assertions/class_list.gd

@ -0,0 +1,132 @@
extends Reference
# Boolean Assertions
const IsFalse: Script = preload("boolean/is_false.gd")
const IsTrue: Script = preload("boolean/is_true.gd")
# Test Double Assertions
const CalledWithArguments: Script = preload("double/called_with_arguments.gd")
const ScriptWasCalled: Script = preload("double/script_was_called.gd")
const ScriptWasNotCalled: Script = preload("double/script_was_not_called.gd")
# Equality Assertions
const IsEqual: Script = preload("equality/is_equal.gd")
const IsEqualOrGreaterThan: Script = preload("equality/is_equal_or_greater_than.gd")
const IsEqualOrLessThan: Script = preload("equality/is_equal_or_less_than.gd")
const IsGreaterThan: Script = preload("equality/is_greater_than.gd")
const IsLessThan: Script = preload("equality/is_less_than.gd")
const IsNotEqual: Script = preload("equality/is_not_equal.gd")
# File Assertions
const FileDoesNotExist: Script = preload("file/file_does_not_exist.gd")
const FileExists: Script = preload("file/file_exists.gd")
# Is <TYPE> Assertions
const IsAABB: Script = preload("is/is_AABB.gd")
const IsArray: Script = preload("is/is_Array.gd")
const IsBasis: Script = preload("is/is_Basis.gd")
const IsBool: Script = preload("is/is_bool.gd")
const IsBuiltInType: Script = preload("is/is_built_in_type.gd")
const IsClassInstance: Script = preload("is/is_class_instance.gd")
const IsColor: Script = preload("is/is_Color.gd")
const IsDictionary: Script = preload("is/is_Dictionary.gd")
const IsFloat: Script = preload("is/is_float.gd")
const IsInt: Script = preload("is/is_int.gd")
const IsNodePath: Script = preload("is/is_NodePath.gd")
const IsObject: Script = preload("is/is_Object.gd")
const IsPlane: Script = preload("is/is_Plane.gd")
const IsPoolByteArray: Script = preload("is/is_PoolByteArray.gd")
const IsPoolColorArray: Script = preload("is/is_PoolColorArray.gd")
const IsPoolIntArray: Script = preload("is/is_PoolIntArray.gd")
const IsPoolRealArray: Script = preload("is/is_PoolRealArray.gd")
const IsPoolStringArray: Script = preload("is/is_PoolStringArray.gd")
const IsPoolVector2Array: Script = preload("is/is_PoolVector2Array.gd")
const IsPoolVector3Array: Script = preload("is/is_PoolVector3Array.gd")
const IsQuat: Script = preload("is/is_Quat.gd")
const IsRect2: Script = preload("is/is_Rect2.gd")
const IsRID: Script = preload("is/is_RID.gd")
const IsString: Script = preload("is/is_String.gd")
const IsTransform: Script = preload("is/is_Transform.gd")
const IsTransform2D: Script = preload("is/is_Transform2D.gd")
const IsVector2: Script = preload("is/is_Vector2.gd")
const IsVector3: Script = preload("is/is_Vector3.gd")
# Is Not <TYPE> Assertions
const IsNotAABB: Script = preload("is_not/is_not_AABB.gd")
const IsNotArray: Script = preload("is_not/is_not_Array.gd")
const IsNotBasis: Script = preload("is_not/is_not_Basis.gd")
const IsNotBool: Script = preload("is_not/is_not_bool.gd")
const IsNotBuiltInType: Script = preload("is_not/is_not_built_in_type.gd")
const IsNotClassInstance: Script = preload("is_not/is_not_class_instance.gd")
const IsNotColor: Script = preload("is_not/is_not_Color.gd")
const IsNotDictionary: Script = preload("is_not/is_not_Dictionary.gd")
const IsNotFloat: Script = preload("is_not/is_not_float.gd")
const IsNotInt: Script = preload("is_not/is_not_int.gd")
const IsNotNodePath: Script = preload("is_not/is_not_NodePath.gd")
const IsNotObject: Script = preload("is_not/is_not_Object.gd")
const IsNotPlane: Script = preload("is_not/is_not_Plane.gd")
const IsNotPoolByteArray: Script = preload("is_not/is_not_PoolByteArray.gd")
const IsNotPoolColorArray: Script = preload("is_not/is_not_PoolColorArray.gd")
const IsNotPoolIntArray: Script = preload("is_not/is_not_PoolIntArray.gd")
const IsNotPoolRealArray: Script = preload("is_not/is_not_PoolRealArray.gd")
const IsNotPoolStringArray: Script = preload("is_not/is_not_PoolStringArray.gd")
const IsNotPoolVector2Array: Script = preload("is_not/is_not_PoolVector2Array.gd")
const IsNotPoolVector3Array: Script = preload("is_not/is_not_PoolVector3Array.gd")
const IsNotQuat: Script = preload("is_not/is_not_Quat.gd")
const IsNotRect2: Script = preload("is_not/is_not_Rect2.gd")
const IsNotRID: Script = preload("is_not/is_not_RID.gd")
const IsNotString: Script = preload("is_not/is_not_String.gd")
const IsNotTransform: Script = preload("is_not/is_not_Transform.gd")
const IsNotTransform2D: Script = preload("is_not/is_not_Transform2D.gd")
const IsNotVector2: Script = preload("is_not/is_not_Vector2.gd")
const IsNotVector3: Script = preload("is_not/is_not_Vector3.gd")
# Null Assertions
const IsNull: Script = preload("null/is_null.gd")
const IsNotNull: Script = preload("null/is_not_null.gd")
# Object Assertions
# Note: The elements this assertions act on exist throughout every object
# ..in godot so it was necessary. For other class-specific assertions..
# users should use assert.that
const ObjectIsFreed: Script = preload("object/is_freed.gd")
const ObjectIsNotFreed: Script = preload("object/is_not_freed.gd")
const ObjectHasMeta: Script = preload("object/has_meta.gd")
const ObjectDoesNotHaveMeta: Script = preload("object/does_not_have_meta.gd")
const ObjectHasMethod: Script = preload("object/has_method.gd")
const ObjectDoesNotHaveMethod: Script = preload("object/does_not_have_method.gd")
const ObjectHasUserSignal: Script = preload("object/has_user_signal.gd")
const ObjectDoesNotHaveUserSignal: Script = preload("object/does_not_have_user_signal.gd")
const ObjectIsQueuedForDeletion: Script = preload("object/is_queued_for_deletion.gd")
const ObjectIsNotQueuedForDeletion: Script = preload("object/is_not_queued_for_deletion.gd")
const ObjectIsBlockingSignals: Script = preload("object/is_blocking_signals.gd")
const ObjectIsNotBlockingSignals: Script = preload("object/is_not_blocking_signals.gd")
const ObjectIsConnected: Script = preload("object/is_connected.gd")
const ObjectIsNotConnected: Script = preload("object/is_not_connected.gd")
# Property Assertions
const Has: Script = preload("property/has.gd")
const DoesNotHave: Script = preload("property/does_not_have.gd")
# Range Assertions
const IsInRange: Script = preload("range/is_in_range.gd")
const IsNotInRange: Script = preload("range/is_not_in_range.gd")
# Signal Assertions
const WasEmitted: Script = preload("signal/signal_was_emitted.gd")
const WasEmittedXTimes: Script = preload("signal/signal_was_emitted_x_times.gd")
const WasEmittedWithArguments: Script = preload("signal/signal_was_emitted_with_arguments.gd")
const WasNotEmitted: Script = preload("signal/signal_was_not_emitted.gd")
# String Assertions
const BeginsWith: Script = preload("string/string_begins_with.gd")
const Contains: Script = preload("string/string_contains.gd")
const DoesNotBeginWith: Script = preload("string/string_does_not_begin_with.gd")
const DoesNotContain: Script = preload("string/string_does_not_contain.gd")
const DoesNotEndWith: Script = preload("string/string_does_not_end_with.gd")
const EndsWith: Script = preload("string/string_ends_with.gd")
# Misc Utility Assertions
const That: Script = preload("misc/that.gd")
const Fail: Script = preload("misc/fail.gd")

59
addons/WAT/core/assertions/constants/type_library.gd

@ -0,0 +1,59 @@
extends Reference
static func get_type_string(property_id: int) -> String:
match property_id:
TYPE_NIL:
return "null"
TYPE_BOOL:
return "bool"
TYPE_INT:
return "int"
TYPE_REAL:
return "float"
TYPE_STRING:
return "String"
TYPE_VECTOR2:
return "Vector2"
TYPE_RECT2:
return "Rect2"
TYPE_VECTOR3:
return "Vector3"
TYPE_TRANSFORM2D:
return "Transform2D"
TYPE_PLANE:
return "Plane"
TYPE_QUAT:
return "Quat"
TYPE_AABB:
return "AABB"
TYPE_BASIS:
return "Basis"
TYPE_TRANSFORM:
return "Transform"
TYPE_COLOR:
return "Color"
TYPE_NODE_PATH:
return "NodePath"
TYPE_RID:
return "RID"
TYPE_OBJECT:
return "Object"
TYPE_DICTIONARY:
return "Dictionary"
TYPE_ARRAY:
return "Array"
TYPE_RAW_ARRAY:
return "PoolByteArray"
TYPE_INT_ARRAY:
return "PoolIntArray"
TYPE_REAL_ARRAY:
return "PoolRealArray"
TYPE_STRING_ARRAY:
return "PoolStringArray"
TYPE_VECTOR2_ARRAY:
return "PoolVector2Array"
TYPE_VECTOR3_ARRAY:
return "PoolVector3Array"
TYPE_COLOR_ARRAY:
return "PoolColorArray"
return "OutOfBounds"

18
addons/WAT/core/assertions/double/called_with_arguments.gd

@ -0,0 +1,18 @@
extends "../base.gd"
func _init(double, method: String, args: Array, context: String) -> void:
var passed: String = "method: %s was called with arguments: %s" % [method, args]
var failed: String = "method: %s was not called with arguments: %s" % [method, args]
var alt_failed: String = "method: %s was not called at all" % method
self.context = context
self.expected = passed
if double.call_count(method) == 0:
self.success = false
self.result = alt_failed
elif double.found_matching_call(method, args):
self.success = true
self.result = passed
else:
self.success = false
self.result = failed

9
addons/WAT/core/assertions/double/script_was_called.gd

@ -0,0 +1,9 @@
extends "../base.gd"
func _init(double, method: String, context: String) -> void:
var passed: String = "%s was called" % method
var failed: String = "%s was not called" % method
self.context = context
self.success = double.call_count(method) > 0
self.expected = passed
self.result = passed if self.success else failed

9
addons/WAT/core/assertions/double/script_was_not_called.gd

@ -0,0 +1,9 @@
extends "../base.gd"
func _init(double, method: String, context: String) -> void:
var passed: String = "%s was not called" % method
var failed: String = "%s was called" % method
self.context = context
self.success = double.call_count(method) <= 0
self.expected = passed
self.result = passed if self.success else failed

12
addons/WAT/core/assertions/equality/is_equal.gd

@ -0,0 +1,12 @@
extends "../base.gd"
func _init(a, b, context: String) -> void:
var typeofa = type2str(a)
var typeofb = type2str(b)
var passed: String = "|%s| %s is equal to |%s| %s" % [typeofa, a, typeofb, b]
var failed: String = "|%s| %s is not equal to |%s| %s" % [typeofa, a, typeofb, b]
self.context = context
self.success = (a == b)
self.expected = passed
self.result = passed if self.success else failed

11
addons/WAT/core/assertions/equality/is_equal_or_greater_than.gd

@ -0,0 +1,11 @@
extends "../base.gd"
func _init(a, b, context: String) -> void:
var typeofa = type2str(a)
var typeofb = type2str(b)
var passed: String = "|%s| %s is equal or greater |%s| %s" % [typeofa, a, typeofb, b]
var failed: String = "|%s| %s is less than |%s| %s" % [typeofa, a, typeofb, b]
self.context = context
self.success = (a >= b)
self.expected = passed
self.result = passed if self.success else failed

11
addons/WAT/core/assertions/equality/is_equal_or_less_than.gd

@ -0,0 +1,11 @@
extends "../base.gd"
func _init(a, b, context: String) -> void:
var typeofa = type2str(a)
var typeofb = type2str(b)
var passed: String = "|%s| %s is equal or less than |%s| %s" % [typeofa, a, typeofb, b]
var failed: String = "|%s| %s is greater than |%s| %s" % [typeofa, a, typeofb, b]
self.context = context
self.success = (a <= b)
self.expected = passed
self.result = passed if self.success else failed

11
addons/WAT/core/assertions/equality/is_greater_than.gd

@ -0,0 +1,11 @@
extends "../base.gd"
func _init(a, b, context: String) -> void:
var typeofa = type2str(a)
var typeofb = type2str(b)
var passed: String = "|%s| %s is greater than |%s| %s" % [typeofa, a, typeofb, b]
var failed: String = "|%s| %s if equal or less than |%s| %s" % [typeofa, a, typeofb, b]
self.context = context
self.success = (a > b)
self.expected = passed
self.result = passed if self.success else failed

11
addons/WAT/core/assertions/equality/is_less_than.gd

@ -0,0 +1,11 @@
extends "../base.gd"
func _init(a, b, context: String) -> void:
var typeofa = type2str(a)
var typeofb = type2str(b)
var passed: String = "|%s| %s is less than |%s| %s" % [typeofa, a, typeofb, b]
var failed: String = "|%s| %s is equal or greater than |%s| %s" % [typeofa, a, typeofb, b]
self.context = context
self.success = (a < b)
self.expected = passed
self.result = passed if self.success else failed