chore: add GUT test framework
3
addons/gut/documentation/docs/Asserts-and-Methods.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Asserts and Methods
|
||||
|
||||
This documentation has been moved to Class Reference page for [GutTest](class_GutTest). The [GutTest](class_GutTest) page is generated from code comments, making it available in the in-editor help as well.
|
||||
131
addons/gut/documentation/docs/Awaiting.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Awaiting
|
||||
If you aren't sure about coroutines and using `await`, [Godot explains it pretty well](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#awaiting-signals-or-coroutines). GUT supports coroutines, so you can `await` at anytime in your tests. GUT also provides some handy methods to make awaiting in your tests a little easier.
|
||||
|
||||
You can use `await` with any of the following methods to pause execution for a duration or until something occurs. You can find more information about each method below, and in the `GutTest` documentation.
|
||||
* `wait_seconds`: Waits x seconds.
|
||||
* `wait_idle_frames`: Waits x process frames(_process(delta)).
|
||||
* `wait_physics_frames`: Waits x physics frames(_physics_process(delta)).
|
||||
* `wait_for_signal`: Waits until a signal is emitted, or a maximum amount of time.
|
||||
* `wait_until`: Waits until a `Callable` returns `true` or a maximum amount of time.
|
||||
* `wait_while`: Waits while a `Callable` returns `true` or a maximum amount of time.
|
||||
* `pause_before_teardown`: can be called in a test to pause execution at the end of a test, before moving on to the next test or ending the run.
|
||||
|
||||
Calling `await` without using one of GUT's "wait" methods is discouraged. When you use these methods, GUT provides output to indicate that execution is paused. If you don't use them it can look like your tests have stopped running.
|
||||
|
||||
|
||||
## wait_seconds
|
||||
<a href="class_ref/class_guttest.html#class-guttest-method-wait-seconds">GutTest.wait_seconds</a>
|
||||
``` gdscript
|
||||
wait_seconds(time, msg=''):
|
||||
```
|
||||
Sometimes you just want to pause for some amount of time. Use `wait_seconds` instead of making timers.
|
||||
|
||||
The optional `msg` parameter is logged so you know why test execution is paused.
|
||||
``` gdscript
|
||||
# wait 2.8 seconds then continue running the test
|
||||
await wait_seconds(2.8)
|
||||
|
||||
# wait .25 seconds, text included in log message
|
||||
await wait_seconds(.25, "waiting for a short period")
|
||||
```
|
||||
|
||||
## wait_physics_frames
|
||||
<a href="class_ref/class_guttest.html#class-guttest-method-wait-physics-frames">GutTest.wait_physics_frames</a>
|
||||
``` gdscript
|
||||
wait_physics_frames(frames, msg=''):
|
||||
```
|
||||
This returns a signal that is emitted after `x` physics frames have
|
||||
elpased. You can await this method directly to pause execution for `x`
|
||||
physics frames. The frames are counted prior to _physics_process being called
|
||||
on any node (when `SceneTree.physics_frame` is emitted). This means the
|
||||
signal is emitted after `x` frames and just before the x + 1 frame starts.
|
||||
```
|
||||
await wait_physics_frames(10)
|
||||
```
|
||||
|
||||
The optional `msg` parameter is logged so you know why test execution is paused.
|
||||
``` gdscript
|
||||
# wait 2 frames before continue test execution
|
||||
await wait_physics_frames(2)
|
||||
|
||||
# waits some frames and includes optional message
|
||||
await wait_physics_frames(20, 'waiting some frames.')
|
||||
```
|
||||
|
||||
## wait_idle_frames
|
||||
<a href="class_ref/class_guttest.html#class-guttest-method-wait-idle-frames">GutTest.wait_idle_frames</a>
|
||||
```gdscript
|
||||
await wait_idle_frames(10)
|
||||
# wait_process_frames is an alias of wait_idle_frames
|
||||
await wait_process_frames(10)
|
||||
```
|
||||
This returns a signal that is emitted after `x` process/idle frames have
|
||||
elpased. You can await this method directly to pause execution for `x`
|
||||
process/idle frames. The frames are counted prior to _process being called
|
||||
on any node (when `SceneTree.process_frame` is emitted). This means the
|
||||
signal is emitted after `x` frames and just before the x + 1 frame starts.
|
||||
|
||||
|
||||
## wait_for_signal
|
||||
<a href="class_ref/class_guttest.html#class-guttest-method-wait-for-signal">GutTest.wait_for_signal</a>
|
||||
``` gdscript
|
||||
wait_for_signal(sig, max_wait, msg=''):
|
||||
```
|
||||
This method will pause execution until a signal is emitted or until `max_wait` seconds have passed, whichever comes first. Using `wait_for_signal` is better than just using `await my_obj.my_signal` since tests will continue to run if the signal is never emitted.
|
||||
|
||||
This method returns `true` if the signal was emitted before timing out, `false` if not.
|
||||
|
||||
The optional `msg` parameter is logged so you know why test execution is paused.
|
||||
``` gdscript
|
||||
...
|
||||
# wait for my_object to emit the signal 'my_signal'
|
||||
# or 5 seconds, whichever comes first.
|
||||
await wait_for_signal(my_object.my_signal, 5)
|
||||
assert_signal_emitted(my_object, 'my_signal', \
|
||||
'Maybe it did, maybe it didnt, but we still got here.')
|
||||
|
||||
# You can also use the return value directly in an assert
|
||||
assert_true(await wait_for_signal(my_object.my_signal, 2),
|
||||
"The signal should have been emitted before timeout")
|
||||
```
|
||||
|
||||
As a bonus, `wait_for_signal` internally calls <a href="class_ref/class_guttest.html#class-guttest-method-watch-signals">watch_signals</a> for the object, so you can skip that step when asserting signals have been emitted.
|
||||
|
||||
|
||||
## wait_until
|
||||
<a href="class_ref/class_guttest.html#class-guttest-method-wait-until">GutTest.wait_until</a>
|
||||
``` gdscript
|
||||
wait_until(callable, max_wait, p3='', p4=''):
|
||||
```
|
||||
This method takes a `Callable` predicate method that will be called every frame. The wait will end when the `Callable` returns `true` or when `max_wait` seconds has expired. This requires the method to explicity return `true` and not a truthy value.
|
||||
|
||||
This will return `true` if the method returned `true` before the timeout, `false` if otherwise. You can optionally specify an amount of time to wait between calling the `Callable`.
|
||||
|
||||
* `p3` can be the optional message or an amount of time to wait between tests.
|
||||
* `p4` is the optional message if you have specified an amount of time to wait between tests.
|
||||
|
||||
``` gdscript
|
||||
var everything_is_ok = func():
|
||||
return true
|
||||
|
||||
# Call everything_is_ok every frame until it returns true or 5 seconds elapses
|
||||
await wait_until(everything_is_ok, 5)
|
||||
|
||||
# Same as above but we get the result to use later and provide a message to
|
||||
# display when the await starts.
|
||||
var result = await wait_until(everything_is_ok, 5, 'Show this message')
|
||||
|
||||
# Calls everything_is_ok every second until it returns true and asserts
|
||||
# on the returned value
|
||||
assert_true(await wait_until(everything_is_ok, 10, 1),
|
||||
"Everything should be ok in 10 seconds").
|
||||
```
|
||||
|
||||
## wait_while
|
||||
<a href="class_ref/class_guttest.html#class-guttest-method-wait-while">GutTest.wait_while</a>
|
||||
This is the inverse of `wait_until`. Use the link above for more information.
|
||||
|
||||
## pause_before_teardown
|
||||
<a href="class_ref/class_guttest.html#class-guttest-method-pause-before-teardown">GutTest.pause_before_teardown</a>
|
||||
|
||||
Sometimes, as you are developing your tests you may want to verify something before the any of the teardown methods are called or just look at things a bit. If you call `pause_before_teardown()` anywhere in your test then GUT will pause execution until you press the "Continue" button in the GUT GUI. You can also specify an option to ignore all calls to `pause_before_teardown` through the GUT Panel, command line, or `.gutconfig` in case you get lazy and don't want to remove them. You should always remove them, but I know you won't because I didn't, so I made that an option.
|
||||
13
addons/gut/documentation/docs/Class-Ref.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# About Class Reference
|
||||
|
||||
These pages are generated from code comments, making the same information available both in the wiki and through the Editor's help. The code to generate these pages has been adapted from the Godot Engine's code used to generate its wiki.
|
||||
|
||||
This is a work in progress and will become more complete over time.
|
||||
|
||||
|
||||
## Internal Use
|
||||
Anything marked as "internal use" is for internal use. You probably shouldn't use these things. They may change or be removed without warning. If you find yourself using one of these, open an issue on Github and let me know and maybe I can make it available for public consumption.
|
||||
|
||||
Why included them if they shouldn't be used? Probably because I wasn't sure if they would be useful. Also, I added an "@internal" annotation to the parser that generates the documentation and I wanted to try it out.
|
||||
|
||||
Feedback is always welcome.
|
||||
157
addons/gut/documentation/docs/Command-Line.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# Command Line
|
||||
Also supplied in this repo is the `gut_cmdln.gd` script that can be run from the command line. This is also used by the VSCode Plugin [gut-extension](https://marketplace.visualstudio.com/items?itemName=bitwes.gut-extension).
|
||||
|
||||
__Note:__ All the examples here come from my Mac/Bash.
|
||||
|
||||
In the examples below I will be using `godot` as a command. This is an alias I have created as:
|
||||
```bash
|
||||
alias godot='/Applications/Godot.app/Contents/MacOS/Godot'
|
||||
```
|
||||
|
||||
From the command line, at the root of your project, use the following command to run the script. Use the options below to run tests.
|
||||
|
||||
```bash
|
||||
godot -d -s --path "$PWD" addons/gut/gut_cmdln.gd
|
||||
```
|
||||
|
||||
The `-d` option tells Godot to run in debug mode which is helpful. The `-s` option tells Godot to run a script. `--path "$PWD"` tells Godot to treat the current directory as the root of a project.
|
||||
|
||||
When running from command line, `0` will be returned if all tests pass and `1` will be returned if any fail (`pending` doesn't affect the return value).
|
||||
|
||||
## Options
|
||||
_Output from the command line help via `-gh` option_
|
||||
```text
|
||||
The GUT CLI
|
||||
-----------
|
||||
The default behavior for GUT is to load options from a res://.gutconfig.json if
|
||||
it exists. Any options specified on the command line will take precedence over
|
||||
options specified in the gutconfig file. You can specify a different gutconfig
|
||||
file with the -gconfig option.
|
||||
|
||||
To generate a .gutconfig.json file you can use -gprint_gutconfig_sample
|
||||
To see the effective values of a CLI command and a gutconfig use -gpo
|
||||
|
||||
Values for options can be supplied using:
|
||||
option=value # no space around "="
|
||||
option value # a space between option and value w/o =
|
||||
|
||||
Options whose values are lists/arrays can be specified multiple times:
|
||||
-gdir=a,b
|
||||
-gdir c,d
|
||||
-gdir e
|
||||
# results in -gdir equaling [a, b, c, d, e]
|
||||
|
||||
To not use an empty value instead of a default value, specifiy the option with
|
||||
an immediate "=":
|
||||
-gconfig=
|
||||
|
||||
|
||||
Usage
|
||||
-----------
|
||||
<path to godot> -s addons/gut/gut_cmdln.gd [opts]
|
||||
|
||||
|
||||
Options
|
||||
-----------
|
||||
|
||||
Test Config:
|
||||
-gdir List of directories to search for test scripts in.
|
||||
-ginclude_subdirs Flag to include all subdirectories specified with -gdir.
|
||||
-gtest List of full paths to test scripts to run.
|
||||
-gprefix Prefix used to find tests when specifying -gdir. Default "test_".
|
||||
-gsuffix Test script suffix, including .gd extension. Default ".gd".
|
||||
-gconfig The config file to load options from. The default is res://.gutconfig.json.
|
||||
Use "-gconfig=" to not use a config file.
|
||||
-gpre_run_script pre-run hook script path
|
||||
-gpost_run_script post-run hook script path
|
||||
-gerrors_do_not_cause_failure When an internal GUT error occurs tests will fail. With this option
|
||||
set, that does not happen.
|
||||
-gdouble_strategy Default strategy to use when doubling. Valid values are [INCLUDE_NATIVE,
|
||||
SCRIPT_ONLY]. Default "SCRIPT_ONLY"
|
||||
|
||||
Run Options:
|
||||
-gselect All scripts that contain the specified string in their filename will be ran
|
||||
-ginner_class Only run inner classes that contain the specified string in their name.
|
||||
-gunit_test_name Any test that contains the specified text will be run, all others will be skipped.
|
||||
-gexit Exit after running tests. If not specified you have to manually close the window.
|
||||
-gexit_on_success Only exit if zero tests fail.
|
||||
-gignore_pause Ignores any calls to pause_before_teardown.
|
||||
-gno_error_tracking Disable error tracking.
|
||||
-gfailure_error_types Error types that will cause tests to fail if the are encountered during
|
||||
the execution of a test. Default "["engine", "gut", "push_error"]"
|
||||
|
||||
Display Settings:
|
||||
-glog Log level [0-3]. Default 1
|
||||
-ghide_orphans Display orphan counts for tests and scripts. Default false.
|
||||
-gmaximize Maximizes test runner window to fit the viewport.
|
||||
-gcompact_mode The runner will be in compact mode. This overrides -gmaximize.
|
||||
-gopacity Set opacity of test runner window. Use range 0 - 100. 0 = transparent,
|
||||
100 = opaque.
|
||||
-gdisable_colors Disable command line colors.
|
||||
-gfont_name Valid values are: ["AnonymousPro", "CourierPrime", "LobsterTwo", "Default"].
|
||||
Default "CourierPrime"
|
||||
-gfont_size Font size, default "16"
|
||||
-gbackground_color Background color as an html color, default "262626ff"
|
||||
-gfont_color Font color as an html color, default "ccccccff"
|
||||
-gpaint_after Delay before GUT will add a 1 frame pause to paint the screen/GUI. default 0.1
|
||||
-gwait_log_delay Delay before GUT will print a message to indicate a test is awaiting
|
||||
one of the wait_* methods. Default 0.5
|
||||
|
||||
Result Export:
|
||||
-gjunit_xml_file Export results of run to this file in the Junit XML format.
|
||||
-gjunit_xml_timestamp Include a timestamp in the -gjunit_xml_file, default false
|
||||
|
||||
Help:
|
||||
-gh Print this help. You did this to see this, so you probably understand.
|
||||
-gpo Print option values from all sources and the value used.
|
||||
-gprint_gutconfig_sample Print out json that can be used to make a gutconfig file.
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
Run godot in debug mode (-d), run a test script (-gtest), set log level to lowest (-glog), exit when done (-gexit)
|
||||
|
||||
```bash
|
||||
godot -s addons/gut/gut_cmdln.gd -d --path "$PWD" -gtest=res://test/unit/sample_tests.gd -glog=1 -gexit
|
||||
```
|
||||
|
||||
Load all test scripts that begin with 'me_' and end in '.res' and run me_only_only_me.res (given that the directory contains the following scripts: me_and_only_me.res, me_only.res, me_one.res, me_two.res). I don't specify the -gexit on this one since I might want to run all the scripts using the GUI after I run this one script.
|
||||
|
||||
```bash
|
||||
godot -s addons/gut/gut_cmdln.gd -d --path "$PWD" -gdir=res://test/unit -gprefix=me_ -gsuffix=.res -gselect=only_me
|
||||
```
|
||||
|
||||
## Config file
|
||||
To cut down on the amount of arguments you have to pass to gut and to make it easier to change them, you can optionally use a json file to specify some of the values. By default `gut_cmdln` looks for a config file at `res://.gutconfig.json`. You can specify a different file using the `-gconfig` option.
|
||||
|
||||
Here is a sample file. You can print out the text for a gutconfig file using the `-gprint_gutconfig_sample` option.
|
||||
### Example
|
||||
``` json
|
||||
{
|
||||
"dirs":["res://test/unit/","res://test/integration/"],
|
||||
"double_strategy":"partial",
|
||||
"ignore_pause":false,
|
||||
"include_subdirs":true,
|
||||
"inner_class":"",
|
||||
"log_level":3,
|
||||
"opacity":100,
|
||||
"prefix":"test_",
|
||||
"selected":"",
|
||||
"should_exit":true,
|
||||
"should_maximize":true,
|
||||
"suffix":".gd",
|
||||
"tests":[],
|
||||
"unit_test_name":"",
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Common Errors
|
||||
I really only know of one so far, but if you get a space in your command somewhere, you might see something like this:
|
||||
```
|
||||
ERROR: No loader found for resource: res://samples3
|
||||
At: core\io\resource_loader.cpp:209
|
||||
ERROR: Failed loading scene: res://samples3
|
||||
At: main\main.cpp:1260
|
||||
```
|
||||
I got this one when I accidentally put a space instead of an "=" after `-gselect`.
|
||||
145
addons/gut/documentation/docs/Comparing-Things.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# Comparing Things
|
||||
Comparing things isn't always as obvious as you would think. It can get a little tricky when comparing the contents of dictionaries and arrays. GUT has some utilities to help out.
|
||||
|
||||
In Godot 3.x dictionaries were compared by reference and arrays were compared by value. In 4.0 both are compared by value. Godot 4.0 introduces the `is_same` method which (amongst other things) will compare dictionaries and arrays by reference. GUT now has `assert_same` and `assert_not_same`.
|
||||
|
||||
For more information about the changes to Dictionaries and Arrays and how they affect GUT see [Godot 4 Changes](New-For-Godot-4).
|
||||
|
||||
The `assert_eq` and `assert_ne` methods use Godot's default comparision logic, meaning arrays and dictionaries are compared by value. Godot uses a hashing function to compare the values. This is fast, but does not give you any insight into what is actually different when your tests fail. GUT has some "deep" comparison methods that will show the differences in the two values.
|
||||
|
||||
* `compare_deep`
|
||||
* `assert_eq_deep`
|
||||
* `assert_ne_deep`
|
||||
|
||||
A deep compare will recursively compare all values in the dictionary/array and all sub-dictionaries and sub-arrays. Floats and Integers are never equal. See `assert_eq_deep` in [GutTest](class_GutTest) for examples.
|
||||
|
||||
|
||||
## CompareResult
|
||||
A `CompareResult` object is returned from `compare_deep`. You can use this object to further inspect the differences or adjust the output.
|
||||
|
||||
### Properties
|
||||
* __are_equal__<br> `true`/`false` if all keys/values in the two objects are equal.
|
||||
* __summary__<br> returns a string of all the differences found. This will display `max_differences` differences per each entry and per each sub-array/sub-dictionary. This is returned if you use `str` on a `CompareResult`.
|
||||
* __max_differences__<br> The number of differences to display. This only affects output, all differences are accessible from the `differences` property. Set this to -1 to show the maximum number of differences (10,000)
|
||||
* __differences__<br> This is a dictionary of all the keys/indexes that are different between the compared items. The key is the key/index that is different. Keys/indexes that are missing from one of the compared objects are included. The value of each index is a `CompareResult`.
|
||||
<br><br>
|
||||
`CompareResult`s for sub-arrays/sub-dictionaries `differences` will contain all their differences. You can use the `differences` property for that key to dig deeper into the differences. `differences` will be an empty dictionary for any element that is not an array or dictionary.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
### Deep array compare:
|
||||
```gdscript
|
||||
var a1 = [
|
||||
[1, 2, 3, 4],
|
||||
[[4, 5, 6], ['same'], [7, 8, 9]]
|
||||
]
|
||||
var a2 = [
|
||||
["1", 2.0, 13],
|
||||
[[14, 15, 16], ['same'], [17, 18, 19]]
|
||||
]
|
||||
var result = compare_deep(a1, a2)
|
||||
print(result.summary)
|
||||
|
||||
print('Traversing differences:')
|
||||
print(result.differences[1].differences[2].differences[0])
|
||||
```
|
||||
Output
|
||||
```
|
||||
[[1, 2, 3, 4], [[4, 5, 6], [same], [7, 8...7, 8, 9]]] != [[1, 2, 13], [[14, 15, 16], [same], [17,... 18, 19]]] 2 of 2 indexes do not match.
|
||||
[
|
||||
0: [
|
||||
0: 1 != "1". Cannot compare Int with String.
|
||||
1: 2 != 2.0. Cannot compare Int with Float/Real.
|
||||
2: 3 != 13
|
||||
3: 4 != <missing index>
|
||||
]
|
||||
1: [
|
||||
0: [
|
||||
0: 4 != 14
|
||||
1: 5 != 15
|
||||
2: 6 != 16
|
||||
]
|
||||
2: [
|
||||
0: 7 != 17
|
||||
1: 8 != 18
|
||||
2: 9 != 19
|
||||
]
|
||||
]
|
||||
]
|
||||
Traversing differences:
|
||||
7 != 17
|
||||
```
|
||||
|
||||
### Deep Dictionary Compare
|
||||
``` gdscript
|
||||
var v1 = {'a':{'b':{'c':{'d':1}}}}
|
||||
var v2 = {'a':{'b':{'c':{'d':2}}}}
|
||||
var result = compare_deep(v1, v2)
|
||||
print(result.summary)
|
||||
|
||||
print('Traversing differences:')
|
||||
print(result.differences['a'].differences['b'].differences['c'])
|
||||
```
|
||||
Output
|
||||
```
|
||||
{a:{b:{c:{d:1}}}} != {a:{b:{c:{d:2}}}} 1 of 1 keys do not match.
|
||||
{
|
||||
a: {
|
||||
b: {
|
||||
c: {
|
||||
d: 1 != 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Traversing differences:
|
||||
{d:1} != {d:2} 1 of 1 keys do not match.
|
||||
{
|
||||
d: 1 != 2
|
||||
}
|
||||
```
|
||||
### Mix Bag of Differences
|
||||
```gdscript
|
||||
var a1 = [
|
||||
'a', 'b', 'c',
|
||||
[1, 2, 3, 4],
|
||||
{'a':1, 'b':2, 'c':3},
|
||||
[{'a':1}, {'b':2}]
|
||||
]
|
||||
var a2 = [
|
||||
'a', 2, 'c',
|
||||
['a', 2, 3, 'd'],
|
||||
{'a':11, 'b':12, 'c':13},
|
||||
[{'a':'diff'}, {'b':2}]
|
||||
]
|
||||
var result = compare_deep(a1, a2)
|
||||
print(result.summary)
|
||||
|
||||
print('Traversing differences:')
|
||||
print(result.differences[5].differences[0].differences['a'])
|
||||
|
||||
```
|
||||
Output
|
||||
```
|
||||
[a, b, c, [1, 2, 3, 4], {a:1, b:2, c:3},...}, {b:2}]] != [a, 2, c, [a, 2, 3, d], {a:11, b:12, c:1...}, {b:2}]] 4 of 6 indexes do not match.
|
||||
[
|
||||
1: "b" != 2. Cannot compare String with Int.
|
||||
3: [
|
||||
0: 1 != "a". Cannot compare Int with String.
|
||||
3: 4 != "d". Cannot compare Int with String.
|
||||
]
|
||||
4: {
|
||||
a: 1 != 11
|
||||
b: 2 != 12
|
||||
c: 3 != 13
|
||||
}
|
||||
5: [
|
||||
0: {
|
||||
a: 1 != "diff". Cannot compare Int with String.
|
||||
}
|
||||
]
|
||||
]
|
||||
Traversing differences:
|
||||
1 != "diff". Cannot compare Int with String.
|
||||
```
|
||||
44
addons/gut/documentation/docs/Contributing.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Contributing
|
||||
|
||||
## Contributing Documentation
|
||||
The wiki is hosted at https://gut.readthedocs.io. The source for documentation is in the `documentation` directory. There's info about the wiki structure and local documentation generation in `documentation/README.md` in the repo.
|
||||
|
||||
|
||||
## Contributing Code
|
||||
|
||||
### Checklist for PRs
|
||||
* Open PRs against `main` for Godot 4 issues, or the `godot_3x` branc for Godot 3 issues.
|
||||
* PRs __must have unit tests__. See sections below.
|
||||
* Include any wiki text in the PR.
|
||||
* Info about documentation changes can be found in `documentation/README.md`.
|
||||
* CHANGES.md
|
||||
* I will take care of making any changes to CHANGES.md.
|
||||
* I will credit you in the CHANGES.md. If you have a handle you would like me to use (other than your GitHub username) then let me know in the PR
|
||||
|
||||
### Creating Tests for GUT
|
||||
|
||||
#### All GUT tests are found in
|
||||
* `res://test/unit`
|
||||
* `res://test/integration`
|
||||
|
||||
Edit existing scripts or add new ones there.
|
||||
|
||||
#### Any resources needed by tests should be placed in:
|
||||
* `res://test/resources`
|
||||
|
||||
If you don't see an existing directory that matches your needs then you can create a new directory or place them directly in `res://test/resources`.
|
||||
|
||||
|
||||
### Running GUT Tests
|
||||
Due to the nature of using GUT to test GUT, some tests may not work as intended. These are being cleaned up, but there may still be some left in the codebase. You should run all the tests once before developing to see which tests are currently in use.
|
||||
|
||||
Here's some common errors:
|
||||
|
||||
#### The GUT Panel doesn't do anything.
|
||||
Sometimes when you edit GUT files, the plugin doesn't like it. Reload the plugin.
|
||||
|
||||
#### If you see this in the IDE Output
|
||||
```
|
||||
res://addons/gut/gui/GutBottomPanel.gd:### - Invalid get index '<whatever>' (on base: 'Nil').
|
||||
```
|
||||
Then reload the plugin.
|
||||
88
addons/gut/documentation/docs/Creating-Tests.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Creating Tests
|
||||
|
||||
## Quick Sample
|
||||
Here's a sample test script. Copy the contents into the file `res://test/unit/test_example.gd` then run the script. If everything is setup correctly then you'll see some passing and failing tests.
|
||||
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
func before_each():
|
||||
gut.p("ran setup", 2)
|
||||
|
||||
func after_each():
|
||||
gut.p("ran teardown", 2)
|
||||
|
||||
func before_all():
|
||||
gut.p("ran run setup", 2)
|
||||
|
||||
func after_all():
|
||||
gut.p("ran run teardown", 2)
|
||||
|
||||
func test_assert_eq_number_not_equal():
|
||||
assert_eq(1, 2, "Should fail. 1 != 2")
|
||||
|
||||
func test_assert_eq_number_equal():
|
||||
assert_eq('asdf', 'asdf', "Should pass")
|
||||
|
||||
func test_assert_true_with_true():
|
||||
assert_true(true, "Should pass, true is true")
|
||||
|
||||
func test_assert_true_with_false():
|
||||
assert_true(false, "Should fail")
|
||||
|
||||
func test_something_else():
|
||||
assert_true(false, "didn't work")
|
||||
```
|
||||
|
||||
## Details
|
||||
All test scripts must extend the test class.
|
||||
* `extends GutTest`
|
||||
|
||||
Each test script has optional setup and teardown methods that you can provide an implementation for. These are called by Gut at various stages of execution. They take no parameters. For hooks that are run before/after _every_ test, not just a single test script, see [Global Lifecycle Hooks](Global-Lifecycle-Hooks.md).
|
||||
* `before_each()`: Runs before each test.
|
||||
* `after_each()`: Runs after each test.
|
||||
* `before_all()`: Runs once before any test starts running.
|
||||
* `after_all()`: Runs once after all tests finish running.
|
||||
|
||||
All tests in the test script must start with the prefix `test_` in order for them to be run. The methods must not have any parameters (except [Parameterized-Tests](Parameterized-Tests)).
|
||||
* `func test_this_is_only_a_test():`
|
||||
|
||||
Each test should perform at least one assert or call `pending`, `pass_test` or `fail_test` or it will be marked risky.
|
||||
|
||||
A list of all `asserts` and other helper functions available in your test script can be found in [GutTest](class_GutTest).
|
||||
|
||||
|
||||
## Inner Test Classes
|
||||
You can group tests together using Inner Classes. These classes must start with the prefix `'Test'` (this is configurable) and they must also extend `GutTest`. You cannot create Inner Test Classes inside Inner Test Classes. More info can be found at [Inner Test Classes](Inner-Test-Classes).
|
||||
|
||||
### Simple Example
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
|
||||
class TestFeatureA:
|
||||
extends GutTest
|
||||
|
||||
var Obj = load('res://scripts/object.gd')
|
||||
var _obj = null
|
||||
|
||||
func before_each():
|
||||
_obj = Obj.new()
|
||||
|
||||
func test_something():
|
||||
assert_true(_obj.is_something_cool(), 'Should be cool.')
|
||||
|
||||
class TestFeatureB:
|
||||
extends GutTest
|
||||
|
||||
var Obj = load('res://scripts/object.gd')
|
||||
var _obj = null
|
||||
|
||||
func before_each():
|
||||
_obj = Obj.new()
|
||||
|
||||
func test_foobar():
|
||||
assert_eq(_obj.foo(), 'bar', 'Foo should return bar')
|
||||
```
|
||||
## Where to next?
|
||||
* [GutTest](class_GutTest)
|
||||
* [Inner Test Classes](Inner-Test-Classes)
|
||||
* [Command Line](Command-Line)
|
||||
45
addons/gut/documentation/docs/Double-Strategy.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Doubling Strategy
|
||||
By default Godot 4 does not allow you to override native methods defined in Godot Objects (you can change this in the project settings: Debug->GDScript->Native Method Override). For example, overriding `set_position` on a Node2D will cause an error. This is because the engine may or may not use overrides in some cases for performance reasons. It has something to do with pointers and functions and efficiency and stuff. I don't fully understand it, but it's true ([Here's a Github Issue with some info](https://github.com/godotengine/godot/issues/55024)). The important thing for us, is that this means you cannot spy-on or stub these functions...or can you?
|
||||
|
||||
<hr>
|
||||
|
||||
__Warning:__ `INCLUDE_NATIVE` is not compatible with static typing. When you statically type a variable, Godot will call all of its native methods directly, bypassing the overrides in the double. See [this issue](https://github.com/bitwes/Gut/issues/633#issuecomment-2198440346) for more information and some examples.
|
||||
|
||||
<hr>
|
||||
|
||||
In most cases Doubles are not used in a manner that would cause the engine to directly interact with them. You may want to verify that some object you created calls `set_position` on a double. This is where changing the Double Strategy can help. When using `DOUBLE_STRATEGY.INCLUDE_NATIVE` GUT will override all native functions which means you can spy-on and stub them for your tests. It will also disable the error and then restore the original setting after the Double or Partial Double is created so that GUT does not blow up. Only direct calls that you make in your objects are guaranteed use the overrides. A tween probably won't call your `set_position` override.
|
||||
|
||||
The default Double Strategy is `SCRIPT_ONLY`, meaning no overrides will be included. You can change the strategy globally, at the script level, or for an individual Double or Partial Double.
|
||||
|
||||
|
||||
## Set the Default Strategy
|
||||
You can change the default through the GutPanel in the editor, the `.gutconfig.json` file for the command line, or as a command line option. Note that the editor and the command line configuration are separate, so you must set it in both places if you are using both.
|
||||
|
||||
### .gutconfig
|
||||
Valid values are `SCRIPT_ONLY`(default) or `INCLUDE_NATIVE`
|
||||
```json
|
||||
"double_strategy":"INCLUDE_NATIVE"
|
||||
```
|
||||
|
||||
### Command Line
|
||||
Use the `-gdouble_strategy` option with the values `INCLUDE_NATIVE` or `SCRIPT_ONLY`
|
||||
```bash
|
||||
-gdouble_strategy='SCRIPT_ONLY'
|
||||
```
|
||||
|
||||
## Overriding the Default
|
||||
|
||||
### Script Level
|
||||
From within a `GutTest` script you can call `set_double_strategy` to change the strategy for that script/inner-class ONLY. This value will be reset to the default after the script has finished. You should call this in `before_all`.
|
||||
```gdscript
|
||||
set_double_strategy(DOUBLE_STRATEGY.INCLUDE_NATIVE)
|
||||
set_double_strategy(DOUBLE_STRATEGY.SCRIPT_ONLY)
|
||||
```
|
||||
|
||||
### Individual Double/Partial Double
|
||||
When calling `double` or `partial_double` you can pass an optional parameter to set the double strategy for just that double.
|
||||
```gdscript
|
||||
double(Foo, DOUBLE_STRATEGY.SCRIPT_ONLY)
|
||||
partial_double(Bar, DOUBLE_STRATEGY.INCLUDE_NATIVE)
|
||||
double(MyScene, DOUBLE_STRATEGY.SCRIPT_ONLY)
|
||||
```
|
||||
147
addons/gut/documentation/docs/Doubles.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Doubles
|
||||
If you aren't sure what a Double is, check out [Test Double on Wikipedia](https://en.wikipedia.org/wiki/Test_double).
|
||||
|
||||
You create a Double by calling the `double` method which in your `GutTest` script. The `double` method accepts a loaded script or scene and returns a class based on the loaded script or scene passed to it. The returned class/scene wraps the source and the methods defined will not execute the code defined in them. These doubles can then be [stubbed](Stubbing) and [spied on](Spies) in tests. You can also create [Partial Doubles](Partial-Doubles) which retain their functionality by default.
|
||||
|
||||
Using your double, you can:
|
||||
* Stub methods to return different values.
|
||||
* Stub them to call the super method.
|
||||
* Assert how many times a method was called.
|
||||
* Assert a method was called with specific parameters.
|
||||
* And much much more. See [Stubbing](Stubbing) and [Spies](Spies) for more information.
|
||||
|
||||
<hr>
|
||||
|
||||
__Warning:__ Native Godot methods are not included in doubles by default. Native methods are all the non-overridable methods in objects such as `Node`. This means `_ready` will exist in the double, but `set_position` will not. A good rule of thumb is that if you didn't write the function, it probably will not be included in your double. You can include them by changing the [Double-Strategy](Double-Strategy), but there are some complications and gotchas.
|
||||
|
||||
<hr>
|
||||
|
||||
## Characteristics of a Double
|
||||
* The double inherits (`extends`) the source.
|
||||
* Contains all class level variables defined in the source.
|
||||
* Contains all signals defined in the source.
|
||||
* Methods defined in the source (and any user defined super class):
|
||||
* Do nothing (unless stubbed).
|
||||
* Will return `null` (unless stubbed).
|
||||
* __All__ parameters are defaulted to `null`, even if they did not have a default value originally. You can stub parameter defaults (see [Stubbing](Stubbing)).
|
||||
* Inner Classes of the source are not doubled and will retain their functionality.
|
||||
* You can double Inner Classes, but it requires an extra step. See the Inner Class section below.
|
||||
* If your `_init` method has required parameters you must [stub](Stubbing) default values before trying to `double` the object.
|
||||
* Any static methods you add to your scripts must be ignored before doubling using `ignore_method_when_doubling`. More information about this below.
|
||||
* You can double Scripts, Inner Classes, and Packed Scenes. Once you have a double, you can then call `new` or `instantiate` on it to create instances of a doubled object.
|
||||
* All instances of Doubles and Partial Doubles are freed when a test finishes. This means you do not have to free them manually and you should not be created in `before_all` or referenced in `after_all`.
|
||||
|
||||
|
||||
## Doubling a Script
|
||||
To double a script just give it a path or an already loaded script.
|
||||
``` gdscript
|
||||
var MyScript = load('res://my_script.gd')
|
||||
|
||||
# Load the doubled object.
|
||||
var DoubledMyScript = double(MyScript)
|
||||
|
||||
# Create an instance of a doubled object
|
||||
var doubled_script = DoubledMyScript.new()
|
||||
# or
|
||||
var doubled_script = double(MyScript).new()
|
||||
```
|
||||
|
||||
|
||||
## Doubling Inner Classes
|
||||
Inner Classes cannot be automatically detected and therefore must be registered with GUT before they can be doubled. You do this by calling `register_inner_classes(Foo)`. You only have to do this once per script/scene that contains Inner Classes, so it is best to call it in `before_all` or a pre-hook script. Registering multiple times does nothing. Failing to call `register_inner_classes` will result in a GUT error and a runtime error.
|
||||
|
||||
```gdscript
|
||||
# Given that SomeScript contains the class InnerClass that
|
||||
# you wish to double:
|
||||
var SomeScript = load('res://some_script.gd')
|
||||
|
||||
func before_all():
|
||||
register_inner_classes(SomeScript)
|
||||
|
||||
func test_foo():
|
||||
var dbl = double(SomeScript.InnerClass).new()
|
||||
```
|
||||
|
||||
If you reuse doubles of the same inner classes across several tests, it may be easier to register them once in a [Pre-Run Hook](Hooks.md#pre-run-hook) so that you don't have to register them in every test you write. This can be achieved by calling `register_inner_classes` during your pre-run hook like so:
|
||||
|
||||
```gdscript
|
||||
extends GutHookScript
|
||||
|
||||
# Given that SomeScript contains the class InnerClass that
|
||||
# you wish to double:
|
||||
var SomeScript = load('res://some_script.gd')
|
||||
|
||||
func run():
|
||||
register_inner_classes(SomeScript)
|
||||
```
|
||||
|
||||
This approach was used to make tests cleaner and less susceptible to typos. If Godot adds meta data to inner classes that point back to the source script, then `register_inner_classes` can be removed later and no other changes will need to be made.
|
||||
|
||||
|
||||
## Doubling a Scene
|
||||
A doubled version of your scene is created along with a double of its script. The doubled scene is altered to load the doubled script instead of the original. A reference to the newly doubled scene is returned. You can call `instantiate` on the returned reference.
|
||||
|
||||
``` gdscript
|
||||
var MyScene = load('res://my_scene.tscn')
|
||||
|
||||
var DoubledScene = double(MyScene)
|
||||
|
||||
# Create an instance
|
||||
var doubled_scene = DoubledScene.instantiate()
|
||||
# or
|
||||
var doubled_scene = double(MyScene).instantiate()
|
||||
```
|
||||
|
||||
|
||||
## Doubling Scripts with Static Methods
|
||||
Currently you cannot double static methods. In fact if you try to double a class with a static method then you will get an error that looks similar to:
|
||||
```
|
||||
Parser Error: Function signature doesn't match the parent. Parent signature is: 'Variant foo()'.
|
||||
```
|
||||
As of now, GUT does not have the ability to detect static methods in the code. As a workaround there is the `ignore_method_when_doubling` method. This method takes in a variant as the first parameter and a method name as the second. The first parameter can be a path to a script, a path to a scene, a loaded script, or a loaded scene.
|
||||
|
||||
Calling this method will prevent GUT from trying to make a stubbed out version of the method in the generated double allowing you to successfully double your classes that contain static methods.
|
||||
|
||||
These ignored methods are cleared after each test is ran to avoid any unexpected results in your tests, so you may want to add this call to your `before_each`.
|
||||
|
||||
There's more info and examples on this method on the [[Methods|Asserts-and-Methods]] page.
|
||||
|
||||
|
||||
## Doubled method default parameters
|
||||
GUT stubs all parameters in doubled user methods to be `null`. This is because Godot only provides defaults for built-in methods. When using Partial Doubles or stubbing a method `to_call_super`, `null` can get passed around when you wouldn't expect it causing errors such as `Invalid operands 'int' and 'Nil'`. See the "Stubbing Method Parameter Defaults" in [Stubbing](Stubbing) for a way to stub method default values.
|
||||
|
||||
|
||||
## Methods with varargs and NativeScript parameter mismatches
|
||||
Some methods provided by Godot can contain and endless list of parameters (varargs). Trying to call one of these methods on a double can result in runtime errors due to a parameter mismatch. See the sections in [Stubbing](Stubbing) that address parameters.
|
||||
|
||||
GUT can detect these vararg parameters and will stub the doubled method to accept 10 values which are all defaulted to `null`.
|
||||
|
||||
For example, the signature for Node's `rpc_id` function is:
|
||||
``` gdscript
|
||||
Error rpc_id ( int peer_id, StringName method, ... ) vararg
|
||||
```
|
||||
Here the `...` is the placeholder for the vararg parameter. When GUT encounters this kind of signature it will generate the following:
|
||||
```gdscript
|
||||
func rpc_id (peer_id, method, arg1=null, arg2=null, arg3=null, arg4=null, arg5=null, arg6=null, arg7=null, arg8=null, arg9=null, arg10=null)
|
||||
```
|
||||
|
||||
You can change the number of arguments passed and their default by [stubbing](Stubbing) parameters.
|
||||
|
||||
|
||||
## Doubling Built-In/Base Objects
|
||||
You can `double` built-in objects that are not inherited by a script such as a `Node2D` or a `Raycast2D`. These doubles are always created using the Doubling Strategy of `INCLUDE_NATIVE` (see [Double-Strategy](Double-Strategy)). Be sure to read the [Double-Strategy](Double-Strategy), there are some gotchas and issues with this.
|
||||
|
||||
For example you can `double` or `partial_double` like this:
|
||||
``` gdscript
|
||||
var doubled_node2d = double(Node2D).new()
|
||||
stub(doubled_node2d, 'get_position').to_return(-1)
|
||||
|
||||
var partial_doubled_raycast = partial_double(Raycast2D).new()
|
||||
```
|
||||
|
||||
|
||||
## Where to next?
|
||||
* [Stubbing](Stubbing)
|
||||
* [Spies](Spies)
|
||||
* [Partial-Doubles](Partial-Doubles)
|
||||
* [Double-Strategy](Double-Strategy)
|
||||
142
addons/gut/documentation/docs/Doubling-Singletons.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Doubling-Singletons
|
||||
You can create pseudo-doubles of Engine Singletons (not to be confused with Autoloads) using `double_singleton` or `partial_double_singleton`. Godot Engine Singletons are single instance classes that are created by Godot. `Input`, `OS`, and `Time` are Engine Singletons that are commonly used. A full list of supported Engine Singletons can be found below.
|
||||
|
||||
All Engine Singletons extend `Object` but their doubles extend `RefCounted`. This was done so that they would be freed automatically.
|
||||
|
||||
__These doubles do not replace the existing Engine Singleton__, so they must be injected into a variable in your script. You must then use this local singleton reference in your script instead of directly referencing the Singleton. If you use `:=` you still get all autocomplete features in the editor.
|
||||
|
||||
```gdscript
|
||||
class_name Player
|
||||
|
||||
var my_local_input_singleton_ref := Input
|
||||
|
||||
func _physics_process(delta):
|
||||
if(my_local_input_singleton_ref.is_action_just_pressed("jump")):
|
||||
....
|
||||
```
|
||||
|
||||
```gdscript
|
||||
extends GutTest
|
||||
|
||||
func test_player_does_something_with_input():
|
||||
var dbl_input = partial_double_singleton(Input).new()
|
||||
var p = Player.new()
|
||||
p.my_local_input_singleton_ref = dbl_input
|
||||
|
||||
stub(dbl_input.is_action_just_pressed)\
|
||||
.to_return(true)\
|
||||
.when_passed("jump")
|
||||
...
|
||||
```
|
||||
## Differences to a normal Double
|
||||
Engine Singleton doubles are different from normal doubles in the following way:
|
||||
* Singleton doubles wrap around a an Engine Singleton, they do not extend it.
|
||||
* Properties are copied from the source Singleton when an instance of the double is created. This means the intial values will change (on calls to `.new()`) if the Singleton's properties change.
|
||||
* `double_singleton` and `partial_double_singleton` parameters are checked against a list of known-valid Engine Singletons.
|
||||
* Inherit from `RefCounted`, not the source Engine Singleton or `Object`.
|
||||
* Parial doubles of singletons, or stubbing `to_call_super`, calls methods on the source Engine Singleton.
|
||||
* The properties/methods of `Object` are never included in the double, regardless of the Double Strategy.
|
||||
* Ignoring a method on an Engine Singleton means it will not exist in the double, whereas normal doubles just don't get overrides for the ignored method.
|
||||
```gdscript
|
||||
ignore_method_when_doubling(Time, 'get_ticks_msec')
|
||||
var inst = double_singleton(Time).new()
|
||||
assert_false(inst.has_method('get_ticks_msec'))
|
||||
```
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
This example has a class that uses the `Time` singleton. We make a double of `Time` in the tests and "inject" it into the instance of `UsesTime` we are testing. We then stub the double to return values that allow us to verify `UsesTime` is correctly using `Time`.
|
||||
``` gdscript
|
||||
class_name UsesTime
|
||||
|
||||
# Must have a reference to Engine Singleton that we can
|
||||
# inject our double into.
|
||||
var t := Time
|
||||
|
||||
var _start_time = -1
|
||||
func start():
|
||||
_start_time = t.get_ticks_msec()
|
||||
|
||||
func end():
|
||||
var monday_extra = 0
|
||||
if(t.get_date_dict_from_system().weekday == t.WEEKDAY_MONDAY):
|
||||
monday_extra = 10
|
||||
return t.get_ticks_msec() - _start_time + monday_extra
|
||||
```
|
||||
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
|
||||
# Fun fact, this test will fail if ran on any Monday. I wrote this on a
|
||||
# Wednesday, so it passes. This is a doozy of a flakey test. Don't make
|
||||
# tests
|
||||
func test_calling_end_returns_elapsed_time_using_msecs():
|
||||
var dbl_time = partial_double_singleton(Time).new()
|
||||
var inst = UsesTime.new()
|
||||
inst.t = dbl_time
|
||||
|
||||
stub(dbl_time.get_ticks_msec).to_return(0)
|
||||
inst.start()
|
||||
stub(dbl_time.get_ticks_msec).to_return(10)
|
||||
assert_eq(inst.end(), 10)
|
||||
|
||||
|
||||
# Illustrate that enums are included in singleton doubles.
|
||||
func test_on_mondays_elapsed_time_is_longer_because_time_moves_slower_on_mondays():
|
||||
var dbl_time = double_singleton(Time).new()
|
||||
var inst = UsesTime.new()
|
||||
|
||||
inst.t = dbl_time
|
||||
stub(dbl_time.get_date_dict_from_system)\
|
||||
.to_return({
|
||||
"year": 2025,
|
||||
"month": 1,
|
||||
"day": 1,
|
||||
"weekday": Time.WEEKDAY_MONDAY})
|
||||
|
||||
stub(dbl_time.get_ticks_msec).to_return(0)
|
||||
inst.start()
|
||||
stub(dbl_time.get_ticks_msec).to_return(10)
|
||||
assert_eq(inst.end(), 20)
|
||||
```
|
||||
|
||||
## Eligible Singletons
|
||||
I have verified that a double of these can be created and instantiated. All the ways they could be used has not been explored. Your mileage may vary. Please open an issue if you encounter a problem when doubling any of these Engine Singletons.
|
||||
|
||||
* [AudioServer](https://docs.godotengine.org/en/stable/classes/class_audioserver.html)
|
||||
* [CameraServer](https://docs.godotengine.org/en/stable/classes/class_cameraserver.html)
|
||||
* [ClassDB](https://docs.godotengine.org/en/stable/classes/class_classdb.html)
|
||||
* [DisplayServer](https://docs.godotengine.org/en/stable/classes/class_displayserver.html)
|
||||
* [Engine](https://docs.godotengine.org/en/stable/classes/class_engine.html)
|
||||
* [EngineDebugger](https://docs.godotengine.org/en/stable/classes/class_enginedebugger.html)
|
||||
* [GDExtensionManager](https://docs.godotengine.org/en/stable/classes/class_gdextensionmanager.html)
|
||||
* [Geometry2D](https://docs.godotengine.org/en/stable/classes/class_geometry2d.html)
|
||||
* [Geometry3D](https://docs.godotengine.org/en/stable/classes/class_geometry3d.html)
|
||||
* [GodotNavigationServer2D](https://docs.godotengine.org/en/stable/classes/class_godotnavigationserver2d.html)
|
||||
* [IP](https://docs.godotengine.org/en/stable/classes/class_ip.html)
|
||||
* [Input](https://docs.godotengine.org/en/stable/classes/class_input.html)
|
||||
* [InputMap](https://docs.godotengine.org/en/stable/classes/class_inputmap.html)
|
||||
* [JavaClassWrapper](https://docs.godotengine.org/en/stable/classes/class_javaclasswrapper.html)
|
||||
* [JavaScriptBridge](https://docs.godotengine.org/en/stable/classes/class_javascriptbridge.html)
|
||||
* [Marshalls](https://docs.godotengine.org/en/stable/classes/class_marshalls.html)
|
||||
* [NativeMenuMacOS](https://docs.godotengine.org/en/stable/classes/class_nativemenumacos.html)
|
||||
* [NavigationMeshGenerator](https://docs.godotengine.org/en/stable/classes/class_navigationmeshgenerator.html)
|
||||
* [NavigationServer3D](https://docs.godotengine.org/en/stable/classes/class_navigationserver3d.html)
|
||||
* [OS](https://docs.godotengine.org/en/stable/classes/class_os.html)
|
||||
* [Performance](https://docs.godotengine.org/en/stable/classes/class_performance.html)
|
||||
* [PhysicsServer2D](https://docs.godotengine.org/en/stable/classes/class_physicsserver2d.html)
|
||||
* [PhysicsServer2DManager](https://docs.godotengine.org/en/stable/classes/class_physicsserver2dmanager.html)
|
||||
* [PhysicsServer3D](https://docs.godotengine.org/en/stable/classes/class_physicsserver3d.html)
|
||||
* [PhysicsServer3DManager](https://docs.godotengine.org/en/stable/classes/class_physicsserver3dmanager.html)
|
||||
* [ProjectSettings](https://docs.godotengine.org/en/stable/classes/class_projectsettings.html)
|
||||
* [RenderingServer](https://docs.godotengine.org/en/stable/classes/class_renderingserver.html)
|
||||
* [ResourceLoader](https://docs.godotengine.org/en/stable/classes/class_resourceloader.html)
|
||||
* [ResourceSaver](https://docs.godotengine.org/en/stable/classes/class_resourcesaver.html)
|
||||
* [ResourceUID](https://docs.godotengine.org/en/stable/classes/class_resourceuid.html)
|
||||
* [TextServerManager](https://docs.godotengine.org/en/stable/classes/class_textservermanager.html)
|
||||
* [ThemeDB](https://docs.godotengine.org/en/stable/classes/class_themedb.html)
|
||||
* [Time](https://docs.godotengine.org/en/stable/classes/class_time.html)
|
||||
* [TranslationServer](https://docs.godotengine.org/en/stable/classes/class_translationserver.html)
|
||||
* [WorkerThreadPool](https://docs.godotengine.org/en/stable/classes/class_workerthreadpool.html)
|
||||
* [XRServer](https://docs.godotengine.org/en/stable/classes/class_xrserver.html)
|
||||
156
addons/gut/documentation/docs/Error-Tracking.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# Error Tracking
|
||||
|
||||
Godot introduced the ability to detect errors in version 4.5. GUT records all the errors that occur during the execution of tests. At the end of each test GUT will check for any errors that were generated and not "handled". If any exist then the test will fail.
|
||||
|
||||
Gut can detect the following
|
||||
* Internal GUT errors
|
||||
* Calls to `push_error`
|
||||
* Engine errors (Script/Shader/Godot errors)
|
||||
* Calls to `push_warning` (warnings do not cause failures)
|
||||
|
||||
__Note about logging:__ All errors and warnings will always appear in the output. I don't know of a way to suppress them. If GUT's log level is 0 or 1 then GUT will print a message to the log for expected errors to make it more obvious when an error has been "handled". On log level 0, errors will appear before the test name (this can't be helped...or maybe it could but it would be ugly).
|
||||
|
||||
## "Handling" Expected Errors and Warnings
|
||||
Any error that is generated over the course of a test must be marked as "handled" to prevent GUT from failing the test. This can be done with any of the asserts below or manually via `get_errors()`. If you want to see all the errors that have been generated you can get detailed output by using <a href="class_ref/class_guttest.html#class-guttest-method-print-tracked-errors">print_tracked_errors</a>.
|
||||
|
||||
If you disable error tracking the asserts listed here will __always fail__. If you disable failing for specific error types, the asserts will still work but tests will not fail for any unhandled error type that is disabled. See below on how to disable things.
|
||||
|
||||
Errors can only be asserted against once. If one error is generated and you assert that it has occurred multiple times or in different ways, it will not be found on subsequent asserts, causing those asserts to fail.
|
||||
Example:
|
||||
```gdscript
|
||||
func test_fails_because_error_already_handled():
|
||||
push_error("This is a push error")
|
||||
# This marks the error as handled.
|
||||
assert_push_error_count(1)
|
||||
# This will fail because GUT cannot find a matching unhandled error
|
||||
assert_push_error("is a push")
|
||||
```
|
||||
|
||||
If you want to assert that no errors have been generated for a test, you can assert the count is zero. You could also assert on the size of the array returned by `get_errors`. Using `get_errors` means you wouldn't have to assert for each error/warning type. Asserting that no errors exist should only be used when you do not have another meaningful assert other than the fact that errors did not occur.
|
||||
```gdscript
|
||||
func test_no_errors:
|
||||
# Ideally you would use just one of these.
|
||||
assert_engine_error_count(0, 'no engine errors')
|
||||
assert_push_error_count(0, 'no push errors')
|
||||
assert_push_warning_count(0, 'no push warnings')
|
||||
|
||||
# Or you could assert no errors of any type happened, but that has
|
||||
# a funny smell to it...but you could do it.
|
||||
assert_eq(get_errors().size(), 0, 'no nuthin')
|
||||
```
|
||||
|
||||
|
||||
## Engine Errors
|
||||
Engine errors are errors generated by Godot. These include Script errors, shader errors, engine warnings, and others. Your code should probably prevent these errors and generate an application specific `push_error` or some internal error mechanism. This might not always be possible, or you might not want to do that, so GUT has some asserts for these.
|
||||
|
||||
Example engine error generation:
|
||||
```gdscript
|
||||
func divide_recklessly(top, bottom):
|
||||
return top / bottom
|
||||
|
||||
func assign_a_to_string_and_b_to_int(a, b):
|
||||
var string_a : String = a
|
||||
var int_b : int = b
|
||||
|
||||
func test_demo_engine_type_error():
|
||||
assign_a_to_string_and_b_to_int(Object.new(), 'asdf')
|
||||
divide_recklessly('some words', Node)
|
||||
```
|
||||
GUT error output
|
||||
```
|
||||
[Failed]: Unexpected Errors:
|
||||
[1] <engine-2>Trying to assign value of type 'Object' to a variable of type 'String'.
|
||||
[2] <engine-2>Invalid operands 'String' and 'Object' in operator '/'.
|
||||
at line -1
|
||||
```
|
||||
|
||||
You can use <a href="class_ref/class_guttest.html#class-guttest-method-assert-engine-error-count">assert_engine_error_count</a> to assert a specific number of engine errors have been genrated or you can use <a href="class_ref/class_guttest.html#class-guttest-method-assert-engine-error">assert_engine_error</a> to assert that an engine error with the passsed in text was generated.
|
||||
|
||||
```gdscript
|
||||
func test_demo_engine_type_error():
|
||||
assign_a_to_string_and_b_to_int(Object.new(), 'asdf')
|
||||
divide_recklessly('some words', Node)
|
||||
assert_engine_error_count(2)
|
||||
|
||||
func test_demo_engine_type_error_other_way():
|
||||
assign_a_to_string_and_b_to_int(Object.new(), 'asdf')
|
||||
divide_recklessly('some words', Node)
|
||||
assert_engine_error("Invalid operands")
|
||||
assert_engine_error("to assign value")
|
||||
```
|
||||
|
||||
|
||||
## push_error Errors
|
||||
A push_error error is any error generated from `push_error`. `push_error` errors are the closest thing we have to an application error. You can use `push_error` in your game and then assert that the error happened during at test.
|
||||
|
||||
Example push error
|
||||
```gdscript
|
||||
func test_demo_push_error():
|
||||
push_error("This is a push error")
|
||||
```
|
||||
GUT error output
|
||||
```
|
||||
[Failed]: Unexpected Errors:
|
||||
[1] <push_error>This is a push error
|
||||
at line -1
|
||||
```
|
||||
You can use <a href="class_ref/class_guttest.html#class-guttest-method-assert-push-error-count">assert_push_error_count</a> to assert a specific number of push errors have been genrated or you can use <a href="class_ref/class_guttest.html#class-guttest-method-assert-push-error">assert_push_error</a> to assert that a push error with the passsed in text was generated.
|
||||
|
||||
```gdscript
|
||||
func test_demo_assert_push_error_count():
|
||||
push_error("This is a push error")
|
||||
assert_push_error_count(1)
|
||||
|
||||
func test_demo_assert_push_error():
|
||||
push_error("This is a push error")
|
||||
assert_push_error("this is")
|
||||
```
|
||||
|
||||
## push_warning Warnings
|
||||
A push_warning warning is generated by calling `push_warning`. Warnings do not cause failures, but you can still assert that they were generated using <a href="class_ref/class_guttest.html#class-guttest-method-assert-push-warning-count">assert_push_warning_count</a> and <a href="class_ref/class_guttest.html#class-guttest-method-assert-push-warning">assert_push_warning</a>. The asserts work the same as the engine and push error asserts.
|
||||
|
||||
## Manually handle errors via get_errors</a>
|
||||
You can also use <a href="class_ref/class_guttest.html#class-guttest-method-get-errors">get_errors</a> to get all the errors and inspect them more closely and mark them as "handled".
|
||||
|
||||
It is not recommended that mix how you "handle" errors in a single test. Setting the `handled` property of an error returned by `get_errors` and then asserting an error has occurred will give unexpected results.
|
||||
|
||||
`get_errors` returns an array of <a href="class_ref/class_guttrackederror.html">GutTrackedError</a>. To mark an error as handled, set the `handled` property to `true`.
|
||||
|
||||
See <a href="class_ref/class_guttest.html#class-guttest-method-get-errors">get_errors</a> and <a href="class_ref/class_guttrackederror.html">GutTrackedError</a> for more information.
|
||||
|
||||
|
||||
## Disabling Failing/Error Detection
|
||||
You can prevent GUT from failing when it encounters an error or prevent the detection all together. When failures are disabled, you can still assert that errors have occured. If you disable the error detection then error assertions will always fail.
|
||||
|
||||
|
||||
### Via the Editor
|
||||
These options can be found in the GutPanel options. Track Errors disables the error tracking systm (same as `no_error_tracking` below). "Engine", "Push", and "GUT" enable/disable whether that error type causes a test to fail.
|
||||
|
||||

|
||||
|
||||
|
||||
### Via .gutconfig.json File
|
||||
`failure_error_types` holds a list of the error types that will cause failures. An empty list means no error types will cause failures. Invalid values are ignored. Values are case sensitive. This is the default entry which contains all errors. This should only be specified in your file if you want to disable an error type.
|
||||
```json
|
||||
failure_error_types = ["engine", "gut", "push_error"]
|
||||
```
|
||||
|
||||
`no_error_tracking` can be used to disable the error detection system. GUT errors will still be detected (they are handled differently).
|
||||
```json
|
||||
no_error_tracking = true,
|
||||
```
|
||||
|
||||
|
||||
### Via the CLI
|
||||
There are also command line options for these, see the command line help for more information.
|
||||
|
||||
|
||||
|
||||
## Where is assert_gut_error_count and assert_gut_error?
|
||||
I didn't make those because your game shouldn't generate GUT errors. Your tests might, but it seems unlikely that you would test a test to ensure your test was doing something tests weren't meant to do. You could use `get_errors` if you really wanted...or just disable GUT errors causing errors.
|
||||
|
||||
|
||||
## See Also
|
||||
This is my first pass at adding error detection/assertions to GUT. Please open an issue if you have additional ideas.
|
||||
|
||||
* <a href><a href="class_ref/class_guttrackederror.html">GutTrackedError</a>
|
||||
96
addons/gut/documentation/docs/Export-Test-Results.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Export Test Results
|
||||
|
||||
You can export test results in the JUnit XML format specified [here](https://llg.cubic.org/docs/junit/). You can specify a file name to export to, or kick off an export in a [post-run hook](Hooks).
|
||||
|
||||
## Setting the export file
|
||||
There are two settings, the file name and a flag to include an epoch timestamp in the filename. The epoch timestamp will prevent runs from overwriting the last run's file.
|
||||
|
||||
* Gut Panel
|
||||
* Set `Output Path` in the XML Output section in the Gut Panel
|
||||
* Check `Include Timestamp` if you want the timestamp to be included.
|
||||
* Command Line
|
||||
* Set `-gjunit_xml_file` to the path.
|
||||
* Add option `-gjunit_xml_timestamp` to include the timestamp.
|
||||
* `.gutconfig.json` File
|
||||
* `"junit_xml_file":"user://results.xml"`
|
||||
* `"junit_xml_timestamp":false`
|
||||
* Inspector
|
||||
* Set `Junit Xml File` to the path.
|
||||
* Check `Junit Xml Timestamp` if you want the timestamp to be included.
|
||||
|
||||
|
||||
## Example Output
|
||||
``` xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="GutTests" failures="7" tests="17">
|
||||
<testsuite name="res://test/resources/exporter_test_files/test_simple_2.gd" tests="3" failures="1" skipped="1">
|
||||
<testcase name="test_pass" assertions="1" status="pass" classname="res://test/resources/exporter_test_files/test_simple_2.gd"></testcase>
|
||||
<testcase name="test_fail" assertions="1" status="fail" classname="res://test/resources/exporter_test_files/test_simple_2.gd">
|
||||
<failure message="failed">Cannot compare Int[1] to String["two"].
|
||||
at line 7</failure>
|
||||
</testcase>
|
||||
<testcase name="test_pending" assertions="0" status="pending" classname="res://test/resources/exporter_test_files/test_simple_2.gd">
|
||||
<skipped message="pending">this has text</skipped>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
<testsuite name="res://test/resources/exporter_test_files/test_simple.gd" tests="8" failures="4" skipped="2">
|
||||
<testcase name="test_pending_with_text" assertions="0" status="pending" classname="res://test/resources/exporter_test_files/test_simple.gd">
|
||||
<skipped message="pending">this has text</skipped>
|
||||
</testcase>
|
||||
<testcase name="test_parameterized_passing" assertions="4" status="pass" classname="res://test/resources/exporter_test_files/test_simple.gd"></testcase>
|
||||
<testcase name="test_parameterized_failing" assertions="2" status="fail" classname="res://test/resources/exporter_test_files/test_simple.gd">
|
||||
<failure message="failed">(call #1) [1] expected to equal [2]:
|
||||
at line 25</failure>
|
||||
</testcase>
|
||||
<testcase name="test_fail_2" assertions="1" status="fail" classname="res://test/resources/exporter_test_files/test_simple.gd">
|
||||
<failure message="failed">Cannot compare String["two"] to Int[2].
|
||||
at line 13</failure>
|
||||
</testcase>
|
||||
<testcase name="test_pending_no_text" assertions="0" status="pending" classname="res://test/resources/exporter_test_files/test_simple.gd">
|
||||
<skipped message="pending"></skipped>
|
||||
</testcase>
|
||||
<testcase name="test_pass_1" assertions="1" status="pass" classname="res://test/resources/exporter_test_files/test_simple.gd"></testcase>
|
||||
<testcase name="test_pass_2" assertions="1" status="pass" classname="res://test/resources/exporter_test_files/test_simple.gd"></testcase>
|
||||
<testcase name="test_fail_1" assertions="1" status="fail" classname="res://test/resources/exporter_test_files/test_simple.gd">
|
||||
<failure message="failed">Cannot compare Int[1] to String["two"].
|
||||
at line 10</failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
<testsuite name="res://test/resources/exporter_test_files/test_with_inner_classes.gd" tests="0" failures="0" skipped="0"></testsuite>
|
||||
<testsuite name="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassOne" tests="3" failures="1" skipped="1">
|
||||
<testcase name="test_pending_with_text" assertions="0" status="pending" classname="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassOne">
|
||||
<skipped message="pending">this has text</skipped>
|
||||
</testcase>
|
||||
<testcase name="test_fail_1" assertions="1" status="fail" classname="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassOne">
|
||||
<failure message="failed">Cannot compare Int[1] to String["two"].
|
||||
at line 11</failure>
|
||||
</testcase>
|
||||
<testcase name="test_pass_1" assertions="1" status="pass" classname="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassOne"></testcase>
|
||||
</testsuite>
|
||||
<testsuite name="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassTwo" tests="3" failures="1" skipped="1">
|
||||
<testcase name="test_pending_with_text" assertions="0" status="pending" classname="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassTwo">
|
||||
<skipped message="pending">this has text</skipped>
|
||||
</testcase>
|
||||
<testcase name="test_fail_1" assertions="1" status="fail" classname="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassTwo">
|
||||
<failure message="failed">Cannot compare Int[1] to String["two"].
|
||||
at line 26</failure>
|
||||
</testcase>
|
||||
<testcase name="test_pass_1" assertions="1" status="pass" classname="res://test/resources/exporter_test_files/test_with_inner_classes.gd.TestClassTwo"></testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
```
|
||||
|
||||
## Exporting results in post-run Hook
|
||||
If you would like more control over exporting the results you can do so manually in a post-run hook. See [Hooks](Hooks) for more information about setting up a post-run script.
|
||||
|
||||
Note that `JunitXmlExport` and `gut` are defined by the parent script `res://addons/gut/hook_script.gd`
|
||||
``` gdscript
|
||||
extends GutHookScript
|
||||
|
||||
func run() # called automatically by Gut
|
||||
var exporter = JunitXmlExport.new()
|
||||
var filename = 'user://my_post_hook_results.xml'
|
||||
var f_result = exporter.write_file(gut, filename)
|
||||
if(f_result == OK):
|
||||
gut.p(str("Results saved to ", filename))
|
||||
```
|
||||
120
addons/gut/documentation/docs/GDScript-Warnings.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# GDScript Warnings
|
||||
|
||||
GUT has a bit of legacy code in it. I'm pretty proud that GUT has existed long enough to have legacy code, but that means GUT development hasn't benefited from all the warnings that Godot has introduced over the years. GUT also has to do some things that you shouldn't normally do.
|
||||
|
||||
Godot introduced a `directory_rules` setting in Project Settings->Debug->GDScript (requires "Advance Settings" to be enabled to edit). This allows you to define which directories should be included/excluded when applying your warning settings. By default `res://addons` is excluded. Godot recommends you leave this setting and then add any directories in the addons directory that you want included.
|
||||
|
||||

|
||||
|
||||
GUT does some warning management when executing tests. This alleviates clashes between your project's warnings and the warnings that GUT triggers.
|
||||
* When a run starts, prior to loading most of the scripts in GUT, `res://addons/gut` is added to `directory_rules` as "Exclude". This only affects the Project Settings while running tests, and is not saved.
|
||||
* Before each test script is loaded, all warnings are disabled. They are re-enabled after the script is loaded.
|
||||
* All warnings are disabled when creating doubles of objects.
|
||||
|
||||
If you are concerned that these GUT is hiding warnings in your own scripts during a test run, you can create a standalone script to generate all warnings for your code using something like this:
|
||||
|
||||
```gdscript
|
||||
# ------------------------------------------------------------------------------
|
||||
# This script loads scripts so you can see a list of all the warnings that
|
||||
# are generated by your scripts.
|
||||
# * Sets all ERROR warnings to WARN
|
||||
# * Loads all scripts in "res" and all subdirectories (by default)
|
||||
# * If you specify a path after the script it will load that path instead
|
||||
#
|
||||
# You must run this script with the -d option or errors/warnings are not
|
||||
# printed by Godot.
|
||||
#
|
||||
# Example:
|
||||
# godot -d -s path/to/this/script.gd
|
||||
# godot -d -s path/to/this/script.gd res://addons/my_addon
|
||||
# ------------------------------------------------------------------------------
|
||||
extends SceneTree
|
||||
|
||||
var include_subdirectories := true
|
||||
const GDSCRIPT_WARNING = 'debug/gdscript/warnings/'
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Gets all the files in a directory and all subdirectories if include_subdirectories
|
||||
# is true. The files returned are all sorted by name.
|
||||
# ------------------------------------------------------------------------------
|
||||
func get_files(path: String, prefix: String, suffix: String) -> Array[String]:
|
||||
var files: Array[String] = []
|
||||
var directories: Array[String] = []
|
||||
|
||||
var d := DirAccess.open(path)
|
||||
d.list_dir_begin()
|
||||
|
||||
# Traversing a directory is kinda odd. You have to start the process of listing
|
||||
# the contents of a directory with list_dir_begin then use get_next until it
|
||||
# returns an empty string. Then I guess you should end it.
|
||||
var fs_item := d.get_next()
|
||||
var full_path := ''
|
||||
while fs_item != '':
|
||||
full_path = path.path_join(fs_item)
|
||||
|
||||
#file_exists returns fasle for directories
|
||||
if d.file_exists(full_path):
|
||||
if fs_item.begins_with(prefix) and fs_item.ends_with(suffix):
|
||||
files.append(full_path)
|
||||
elif include_subdirectories and d.dir_exists(full_path):
|
||||
directories.append(full_path)
|
||||
|
||||
fs_item = d.get_next()
|
||||
d.list_dir_end()
|
||||
|
||||
for dir in range(directories.size()):
|
||||
var dir_files := get_files(directories[dir], prefix, suffix)
|
||||
for i in range(dir_files.size()):
|
||||
files.append(dir_files[i])
|
||||
|
||||
files.sort()
|
||||
return files
|
||||
|
||||
|
||||
func set_all_errors_to_warnings() -> void:
|
||||
var props := ProjectSettings.get_property_list()
|
||||
for prop in props:
|
||||
var prop_name: String = prop.name
|
||||
var prop_hint_string: String = prop.hint_string
|
||||
if prop_name.begins_with(GDSCRIPT_WARNING) and\
|
||||
prop_hint_string == 'Ignore,Warn,Error' and \
|
||||
ProjectSettings.get_setting(prop_name) == 2:
|
||||
print('Changed [', prop_name.replace(GDSCRIPT_WARNING, ''), '] to WARN')
|
||||
ProjectSettings.set_setting(prop_name, 1)
|
||||
|
||||
|
||||
func load_all_scripts(path:String) -> void:
|
||||
var files := get_files(path, '', '.gd')
|
||||
for f in files:
|
||||
print("---- ", f, " ----")
|
||||
var _thing := load(f)
|
||||
|
||||
|
||||
# get_cmdline_args always has -s as first and the script path as the second
|
||||
# argument. All other arguments used by the engine do not appear in
|
||||
# get_cmdline_args.
|
||||
#
|
||||
# This treats the 3rd argument as the directory. All other arguments are
|
||||
# ignored.
|
||||
func get_directory_to_load(default) -> String:
|
||||
var args = OS.get_cmdline_args()
|
||||
var to_return = default
|
||||
|
||||
if(args.size() > 2):
|
||||
to_return = args[2]
|
||||
|
||||
return to_return
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
if(EngineDebugger.is_active()):
|
||||
var dir = get_directory_to_load('res://')
|
||||
print('Loading scripts from ', dir)
|
||||
set_all_errors_to_warnings()
|
||||
load_all_scripts(dir)
|
||||
else:
|
||||
print("This script must be run with -d flag or warnings/errors will not be displayed.")
|
||||
|
||||
quit()
|
||||
```
|
||||
157
addons/gut/documentation/docs/Global-Lifecycle-Hooks.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# Global Lifecycle Hooks
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This page describes how to use existing signals to perform logic at various stages of test execution.
|
||||
Eventually, a more formal mechanism will be implemented.
|
||||
See [Issue 762](https://github.com/bitwes/Gut/issues/762) for more details.
|
||||
|
||||
## Overview
|
||||
|
||||
GUT does not expose "global" function hooks that can be run before each test script or method
|
||||
-- while GutTest exposes [hooks](Creating-Tests.md#details)
|
||||
to run code before/after each test method/class,
|
||||
these must be set on every GutTest instance you want the behavior for.
|
||||
|
||||
However, the gut instance accessible in a [Pre-Run Hook](Hooks.md#pre-run-hook)
|
||||
has the following signals that can be connected to.
|
||||
These signals were not intended to be used for this purpose,
|
||||
but it's what we have until a more formal solution exists.
|
||||
|
||||
```
|
||||
signal start_run
|
||||
signal end_run
|
||||
## Emitted before every test script instance is created.
|
||||
## Emitted before [method GutTest.before_all] hook on test is run.
|
||||
## test_script_obj is an instance of addons/gut/collected_script.gd.
|
||||
signal start_script(test_script_obj)
|
||||
## Emitted after every test script is run. Emitted after [method GutTest.after_all] hook on test is run.
|
||||
signal end_script
|
||||
## Emitted before every test method is run. Emitted after [method GutTest.before_each] hook on test is run.
|
||||
## test_name is the string name of the current test about to be started.
|
||||
signal start_test(test_name)
|
||||
## Emitted after every test method is run. Emitted after [method GutTest.after_each] hook on test is run.
|
||||
signal end_test
|
||||
```
|
||||
|
||||
By connecting custom functions to these signals during the Pre-Run Hook,
|
||||
you can call custom code in hooks across every GutTest instance while defining it only once.
|
||||
Following is an example of how you would write a pre-run hook script to set up a global setup function.
|
||||
|
||||
```gdscript
|
||||
extends GutHookScript
|
||||
|
||||
func run():
|
||||
gut.start_test.connect(_on_test_started)
|
||||
|
||||
func _on_test_started(test_name):
|
||||
# setup logic run before every test in every test script goes here
|
||||
```
|
||||
|
||||
## Signal Order
|
||||
|
||||
It may be important to note the order in which the normal GutTest hooks are run
|
||||
and the GutMain signals are emitted.
|
||||
The order of the signals and hooks is as follows:
|
||||
|
||||
1. signal `start_script` (once per test script)
|
||||
1. hook `before_all` (once per test script)
|
||||
1. hook `before_each` (once per test method)
|
||||
1. signal `start_test` (once per test method)
|
||||
1. hook `after_each` (once per test method)
|
||||
1. signal `end_test` (once per test method)
|
||||
1. hook `after_all` (once per test script)
|
||||
1. signal `end_script` (once per test script)
|
||||
|
||||
## Example
|
||||
|
||||
In this example pre-hook script,
|
||||
functions are connected to each of the lifecycle hooks
|
||||
to use the names of test methods and files as a test is run.
|
||||
|
||||
```gdscript
|
||||
extends GutHookScript
|
||||
|
||||
const NO_TEST := "__NO_TEST__"
|
||||
var _current_test_script_object = null
|
||||
var _current_collected_script = null
|
||||
var _current_test_name := NO_TEST
|
||||
|
||||
func run():
|
||||
gut.start_run.connect(_on_run_started)
|
||||
gut.start_script.connect(_on_script_started)
|
||||
gut.start_test.connect(_on_test_started)
|
||||
gut.end_test.connect(_on_test_ended)
|
||||
gut.end_script.connect(_on_script_ended)
|
||||
gut.end_run.connect(_on_run_ended)
|
||||
|
||||
# Do pre-run stuff here
|
||||
|
||||
# This might be redundant, and it might have already been emitted by the time
|
||||
# this hook is called. I wanted it in here for illustration purposes.
|
||||
func _on_run_started():
|
||||
pass
|
||||
|
||||
# This is passed an instance of res://addons/gut/collected_script.gd. It is not
|
||||
# the instance of the script that will be run. You can get to the script object
|
||||
# using `load_script`, but you can't get to the actual instance that will be
|
||||
# run.
|
||||
func _on_script_started(collected_script):
|
||||
_current_collected_script = collected_script
|
||||
# The GutTest script, not the instance.
|
||||
_current_test_script_object = collected_script.load_script()
|
||||
# _current_collected_script.get_full_name() returns the path of the file
|
||||
# that contains the test
|
||||
|
||||
|
||||
# This is just the name of the test method being ran.
|
||||
func _on_test_started(test_name):
|
||||
_current_test_name = test_name
|
||||
|
||||
|
||||
func _on_test_ended():
|
||||
# example of inspecing the test that ended if you wanted to.
|
||||
var failed = _current_collected_script.get_test_named(_current_test_name).is_failing()
|
||||
if (failed):
|
||||
print(_current_test_name + " failed")
|
||||
else:
|
||||
print(_current_test_name + " passed")
|
||||
|
||||
_current_test_name = NO_TEST
|
||||
|
||||
|
||||
func _on_script_ended():
|
||||
#example of inspecing the script that ended if you wanted to
|
||||
if(!_current_collected_script.was_skipped):
|
||||
if(_current_collected_script.get_fail_count() > 0):
|
||||
print("The script ", _current_collected_script.get_full_name(), " failed")
|
||||
else:
|
||||
print("The script ", _current_collected_script.get_full_name(), " passed")
|
||||
|
||||
_current_collected_script = null
|
||||
_current_test_script_object = null
|
||||
|
||||
|
||||
# I'm not sure if this is called before or after the post-run hook. This can't
|
||||
# do everything a post-run hook can do, but it might be enough for this.
|
||||
func _on_run_ended():
|
||||
pass
|
||||
# Do "after_every" things here.
|
||||
```
|
||||
|
||||
## Related Material
|
||||
|
||||
The `start_script` signal contains an object `test_script_obj` which is an instance of
|
||||
the [collected_script.gd](https://github.com/bitwes/Gut/blob/main/addons/gut/collected_script.gd) class,
|
||||
which may be found at `addons/gut/collected_script.gd`.
|
||||
This is NOT the instance of the test script that is actually being run.
|
||||
This class is not intended for public consumption, so use this value at your own risk.
|
||||
|
||||
## Improvements
|
||||
|
||||
The GutMain signals were not originally intended to be used for this purpose
|
||||
(the astute may observe that the ordering of signals and hooks is not particularly orderly).
|
||||
Plans for a new system of hooks created for this purpose
|
||||
were considered [here](https://github.com/bitwes/Gut/pull/804#issuecomment-3929695342),
|
||||
but further input and consideration of the matter would be appreciated
|
||||
-- if you've got an idea, open an issue about it!
|
||||
99
addons/gut/documentation/docs/Hooks.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Hooks
|
||||
|
||||
GUT has a pre-run and post-run hook that allows you to take any initialization steps or verify the results of the run.
|
||||
|
||||
Hook scripts can be set through the editor, through a command line option or in the `.gutconfig.json` file.
|
||||
|
||||
All Hook scripts must inherit from [GutHookScript](class_GutHookScript). If the pre-run or post-run scripts specified do not exist or do not extend [GutHookScript](class_GutHookScript) then the run will be aborted before any tests are run.
|
||||
|
||||
All Hook scripts have access to the GUT instance that is running the tests via the `gut` property defined in `hook_script.gd`. This is set after initializing the script.
|
||||
|
||||
GUT executes the virtual method `run()` when the hook should be executed. Place your custom code in there.
|
||||
|
||||
**Note:** All Hook scripts are instantiated at the start of the run and later `run()` is called on each instance at the appropriate time. The `_init()` method of your Hook Script will not have access to the GUT instance since it is set later.
|
||||
|
||||
|
||||
|
||||
|
||||
## Setup
|
||||
Create scripts that inherit from [GutHookScript](class_GutHookScript), implement the `run()` method. Set the path to your scripts through the panel or `.gutconfig.json`, depending on how you are running your tests.
|
||||
|
||||
|
||||
You can specify `pre_run_script` and `post_run_script` in the `.gutconfig.json` file. You can also specify these options directly at the command line using the `-gpre_run_script` and `-gpost_run_script` options.
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
The following features are available to scripts that inherit from [GutHookScript](class_GutHookScript). Not all features are usable by all hooks. Details below.
|
||||
* `gut` - the GUT instance running tests.
|
||||
* `abort()` - abort the test run.
|
||||
* `set_exit_code(code)` - Set the code to be returned when the command line finishes.
|
||||
* The `JunitXmlExport` class can be used to create an export object to export results. See [Export-Test-Results](Export-Test-Results)
|
||||
* `register_inner_classes` - Register inner classes for doubling. See [Doubling Inner Classes](Doubles.md#doubling-inner-classes).
|
||||
|
||||
### Access GUT instance
|
||||
Each Hook script can access the GUT instance via the `gut` variable. Useful for getting to summary info or manipulating the GUT instance for reasons I can't think of (which is probably a bad idea but who am I to judge).
|
||||
|
||||
### Abort (pre-run only)
|
||||
The built in `abort()` method will cause the run to end immediately after the `run()` method of the pre-run script finishes. The post-run script will NOT be executed. Calling this in the post-run script will have no effect.
|
||||
|
||||
### Exit Code (post-run only)
|
||||
The `set_exit_code(code)` method will set an exit code that will be used when running from the command line. The default behavior is to return `0` when all tests pass and `1` if any tests fail (pending tests do not affect the exit code). If you call `set_exit_code` then the value passed will be used.
|
||||
|
||||
**Note** Calling `set_exit_code` in the pre-run script will not affect the actual exit code. You could use `gut.get_pre_run_script_instance().get_exit_code()` in your post-run script to get you any value you've set via `set_exit_code` in your pre-run script.
|
||||
|
||||
|
||||
|
||||
|
||||
## Pre-Run Hook
|
||||
The pre-run hook is run just before any tests are executed. This can be useful in setting global variables or performing any setup required for all your tests.
|
||||
|
||||
The post-run hook can access the pre-run hook instance via `gut.get_pre_run_script_instance()`.
|
||||
|
||||
**Things to do in your pre-run script**:
|
||||
* mute all sounds `AudioServer.set_bus_volume_db(0, -INF)`
|
||||
* set flags you've implemented to prevent actions from occurring during tests
|
||||
* flags to prevent files from being saved like user stats (my personal catalyst for all these features)
|
||||
* logging levels for your application
|
||||
* register inner classes for doubling to avoid doing it in each individual test
|
||||
* other things I haven't thought of.
|
||||
|
||||
|
||||
|
||||
|
||||
## Post-Run Hook
|
||||
The post-run hook is run after all tests are run and all output has been generated. The post-run hook can access the pre-run script instance (if one was specified) via `gut.get_pre_run_script_instance()`.
|
||||
|
||||
The post-run hook could be useful in writing files used by CICD pipelines to verify the status of the run.
|
||||
|
||||
|
||||
|
||||
|
||||
## Summary Info
|
||||
GUT tracks the results of all the scripts and tests that are run. There is a Summary object that you can access via the `gut` variable. Using this information you can take actions in the post-run hook.
|
||||
|
||||
Reading the documentation/code in [summary.gd](https://github.com/bitwes/Gut/blob/master/addons/gut/summary.gd) will get you the full details, but here are a few examples of how to get the summary data.
|
||||
|
||||
### Full Summary
|
||||
```
|
||||
# Returns GUT's summary.gd instance holding all the data about the run.
|
||||
gut.get_summary()
|
||||
```
|
||||
|
||||
### Counts
|
||||
```
|
||||
# This will return a dictionary containing the following counts:
|
||||
# passing = 0,
|
||||
# pending = 0,
|
||||
# failing = 0,
|
||||
# tests = 0,
|
||||
# scripts = 0
|
||||
gut.get_summary().get_totals()
|
||||
```
|
||||
|
||||
### All Scripts
|
||||
```
|
||||
# Returns and array of Summary.gd.TestScript objects that have detailed information
|
||||
# about each script/inner class that was ran. See summary.gd for more details.
|
||||
gut.get_summary().get_scripts()
|
||||
```
|
||||
78
addons/gut/documentation/docs/Inner-Test-Classes.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Inner Test Classes
|
||||
|
||||
You can define test classes inside a test script that will be treated as test scripts themselves. This allows you to create different contexts for your tests in a single script. These Inner Classes have their own `before_all`, `before_each`, `after_each`, and `after_all` methods that will be called. Only the methods defined in the class are used, the methods defined in the containing script will not be called.
|
||||
|
||||
The Inner Classes must also extend `GutTest` and their constructor cannot take any parameters. The Classes will be loaded and ran in the order they are defined _after_ all the tests in the containing script are run. If the script does not contain any tests then only the Inner Classes will be listed in the output.
|
||||
|
||||
The order the tests are run are not guaranteed to be in the same order they are defined (I don't know why yet).
|
||||
|
||||
Inner Classes are parsed out of the script by looking for a classes that start with `'Test'` and also extend `test.gd`. You can change the name that Gut looks for using the `inner_class_prefix` property.
|
||||
|
||||
## Example
|
||||
Given the following test script defined at `res://test/unit/some_example.gd`
|
||||
```
|
||||
extends GutTest
|
||||
|
||||
func before_all():
|
||||
gut.p('script: pre-run')
|
||||
|
||||
func before_each():
|
||||
gut.p('script: setup')
|
||||
|
||||
func after_each():
|
||||
gut.p('script: teardown')
|
||||
|
||||
func after_all():
|
||||
gut.p('script: post-run')
|
||||
|
||||
func test_something():
|
||||
assert_true(true)
|
||||
|
||||
class TestClass1:
|
||||
extends GutTest
|
||||
|
||||
func before_all():
|
||||
gut.p('TestClass1: pre-run')
|
||||
|
||||
func before_each():
|
||||
gut.p('TestClass1: setup')
|
||||
|
||||
func after_each():
|
||||
gut.p('TestClass1: teardown')
|
||||
|
||||
func after_all():
|
||||
gut.p('TestClass1: post-run')
|
||||
|
||||
func test_context1_one():
|
||||
assert_true(true)
|
||||
|
||||
func test_context1_two():
|
||||
pending()
|
||||
```
|
||||
|
||||
Gut will generate this following when running the test script.
|
||||
|
||||
```
|
||||
/-----------------------------------------
|
||||
Running Script res://test/unit/some_sample.gd
|
||||
-----------------------------------------/
|
||||
script: pre-run
|
||||
* test_something
|
||||
script: setup
|
||||
PASSED:
|
||||
script: teardown
|
||||
|
||||
/-----------------------------------------
|
||||
Running Class [TestClass1] in res://test/unit/some_sample.gd
|
||||
-----------------------------------------/
|
||||
TestClass1: pre-run
|
||||
* test_context1_two
|
||||
TestClass1: setup
|
||||
Pending
|
||||
TestClass1: teardown
|
||||
* test_context1_one
|
||||
TestClass1: setup
|
||||
PASSED:
|
||||
TestClass1: teardown
|
||||
TestClass1: post-run
|
||||
```
|
||||
3
addons/gut/documentation/docs/Input-Factory.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# InputFactory
|
||||
|
||||
The information on this page has moved to [GutInputFactory](class_GutInputFactory)
|
||||
6
addons/gut/documentation/docs/Input-Sender.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Input Sender
|
||||
|
||||
The information on this page has been split between the following pages:
|
||||
* [Mocking Input](Mocking-Input)
|
||||
* [GutInputSender Class Reference](class_GutInputSender)
|
||||
|
||||
65
addons/gut/documentation/docs/Install.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Install
|
||||
GUT is a Godot Plugin. You can download it directly or install it from the Asset Lib in the Godot Editor.
|
||||
|
||||
## Installing from in-editor Godot Asset Lib
|
||||
1. Click the AssetLib button at the top of the editor
|
||||
1. Search for "Gut"
|
||||
1. Click it.
|
||||
1. Click "Install". This will kick off the download.
|
||||
1. Click the 2nd "Install" button that appears when the download finishes. It will be in a little dialog at the bottom of the AssetLib window.
|
||||
1. Click the 3rd "Install" button.
|
||||
1. You did it!
|
||||
|
||||
Finish the install by following the instructions in [Setup](#setup) below.
|
||||
|
||||
|
||||
## Download and install
|
||||
Download the zip from the [releases](https://github.com/bitwes/gut/releases) or from the [Godot Asset Library](https://godotengine.org/asset-library/asset/54).
|
||||
|
||||
Extract the zip and place the `gut` directory into your `addons` directory in your project. If you don't have an `addons` folder at the root of your project, then make one and THEN put the `gut` directory in there.
|
||||
|
||||
Finish the install by following the instructions in Setup below.
|
||||
|
||||
## Installing from this repository
|
||||
GUT's file structure is not organized to be used as a Git submodule. If you would like to have GUT as a submodule of your project you could:
|
||||
1. Add GUT as a submodule at `<path to gut>/gut`
|
||||
1. Symlink `<path to gut>/gut/addons/gut` to `addons/gut`
|
||||
|
||||
This will clone the entire GUT repository, including all of its documentation and tests (which are unnecessary). It may be better to clone GUT outside your project and symlink to it from there instead (contributors must all have a copy of GUT at the same location for the symlink to work).
|
||||
|
||||
## Setup
|
||||
### Activate
|
||||
1. From the menu choose Project->Project Settings, click the Plugins tab and activate Gut. Once activated, the GUT Panel will appear at the bottom of your editor:
|
||||
|
||||

|
||||
|
||||
### Setup directories for tests
|
||||
The next few steps cover the suggested configuration. Feel free to deviate where you see fit.
|
||||
|
||||
1. Create directories to store your tests and test related code (suggested config)
|
||||
* `res://test`
|
||||
* `res://test/unit`
|
||||
* `res://test/integration`
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Run tests from the GUT Panel
|
||||
Set the test directories in the settings subpanel (below) and click "Run All". That's all there is to it.
|
||||
|
||||

|
||||
|
||||
|
||||
### Run tests from the command line
|
||||
GUT comes with a command line interface, more info can be found on the [Command Line](Command-Line) page.
|
||||
|
||||
|
||||
### Run tests through VSCode
|
||||
There is also a VSCode plugin that you can use to run tests directly from VSCode. You can find the plugin and related documentation [here](https://github.com/bitwes/gut-extension).
|
||||
|
||||
|
||||
## Where to next?
|
||||
* [Quick Start](Quick-Start)
|
||||
* [Creating Tests](Creating-Tests)
|
||||
* [Command Line](Command-Line)
|
||||
|
||||
|
||||
139
addons/gut/documentation/docs/Memory-Management.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Memory Management
|
||||
|
||||
|
||||
You may have noticed errors similar to this at the end of your run:
|
||||
```sh
|
||||
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
|
||||
at: cleanup (core/object/object.cpp:2490)
|
||||
ERROR: 24 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:789)
|
||||
```
|
||||
|
||||
These indicate that there were existing objects that had not been freed when your game/tests finished running. These objects are called orphans. GUT will display when orphans are created in a test and a list of orphans (except the children of orphans) at the end of a run.
|
||||
|
||||
Example of orphans in a test:
|
||||
``` gdscript
|
||||
* test_this_makes_two_orphans
|
||||
2 Orphans
|
||||
* test_two_one:<Node#59944994582>
|
||||
* test_two_two:<Node#59961771799>
|
||||
* test_with_a_scene_orphan
|
||||
104 Orphans
|
||||
* main:<Node2D#60045657884>(main.gd) + 27
|
||||
* GutRunner:<Node2D#60565751588>(GutRunner.gd) + 75
|
||||
```
|
||||
GUT displays the name of the node, the node converted to string, and the script of the node if it has one. If the node has children then the number of all decendents will be listed as `+ x`.
|
||||
|
||||
All of GUT's orphan features are wrappers around `Node.get_orphan_node_ids()`. This static method on `Node` returns the `instance_id` of each orphaned node.
|
||||
|
||||
## Orphans
|
||||
Any Node (or a subclass of Node) that is not currently in the tree is considered an orphan. Children of orphaned Nodes are also considered orphans. Orphans aren't necesasrily bad, but they usually indicate a memory leak.
|
||||
|
||||
The [Godot docs](https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/gdscript_basics.html#memory-management) has some useful reading on memory management. Godot provides the following two mechanisms to get information about orphans.
|
||||
|
||||
|
||||
## Leaked References
|
||||
You may also see the following error if you have a refernce counted object that could not be freed.
|
||||
```sh
|
||||
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
|
||||
at: cleanup (core/object/object.cpp:2490)
|
||||
```
|
||||
Many times, reference counted objects cannot be freed due to a cyclical reference. In the simplest case, a cyclical reference happens when two objects have a reference to each other. When this happens, the references cannot be cleared and therefore referenced object cannot be freed. The best way to solve this is by using [Weakref](https://docs.godotengine.org/en/latest/classes/class_weakref.html).
|
||||
|
||||
Godot does not yet supply any information about these leaked objects, so GUT cannot display any information about them. Using the `--verbose` flag is the best way to debug these.
|
||||
|
||||
|
||||
## GUT Memory Management Features
|
||||
Since GUT cannot know if an orphan was created on purpose or not, it will tell you about all the orphans it finds, as soon as it finds them. GUT provides some methods to make it easier to free objects you create in your tests so GUT is more likely to report an actual orphan and not some test object.
|
||||
|
||||
|
||||
### Autofree Methods
|
||||
GUT detects when an orphan is created and will log the orphans it finds in each test and at the end of the run. `GutTest` provides the following methods to ease freeing Nodes you create in your tests. Each of these methods return what is passed in, so you can save a line or two of code.
|
||||
|
||||
Henceforth these will be referred to as an "Autofree" method.
|
||||
* `autofree` - calls `free` after `after_each`.
|
||||
* `autoqfree` - calls `queue_free` after `after_each`.
|
||||
* `add_child_autofree` - calls `add_child` right away, and `free` after `after_each`.
|
||||
* `add_child_autoqfree` - calls `add_child` right away, and `queue_free` after `after_each`.
|
||||
|
||||
|
||||
__Notes__:
|
||||
* It is ok to use any of the Autofree methods `before_each`.
|
||||
|
||||
|
||||
__Warnings:__
|
||||
* Objects passed to `autofree` and `autoqfree` are not in the tree and therefore will still cause `assert_no_new_orphans` to fail.
|
||||
* Do not use any of the `autofree` methods in `before_all`. This will cause the objects to be freed after the first test is run.
|
||||
|
||||
### Freeing Globals
|
||||
You can use a [post-run hook](Hooks) to clean up any global objects you have created.
|
||||
|
||||
|
||||
### Automatically Freed Objects
|
||||
GUT automatically frees any [Doubles](Doubles) or [Partial Doubles](Partial-Doubles) you create.
|
||||
|
||||
Calling `autofree` with one of these objects, or manually freeing them yourself will not have any adverse effects.
|
||||
|
||||
All children of tests are also freed after the test runs, though a warning is printed out if a test has any children.
|
||||
|
||||
|
||||
### Quick Example:
|
||||
This test generates an orphan
|
||||
```gdscript
|
||||
func test_something():
|
||||
var my_node = Node.new()
|
||||
assert_not_null(my_node)
|
||||
```
|
||||
Here, we use one of the `autofree` methods to automatically free our new node after the test without adding any additional lines of code.
|
||||
``` gdscript
|
||||
func test_something():
|
||||
# add_child_autofree will add the result of Node.new() to the tree,
|
||||
# mark it to be freed after the test, and return the instance created by
|
||||
# Node.new().
|
||||
var my_node = add_child_autofree(Node.new())
|
||||
assert_not_null(my_node)
|
||||
```
|
||||
|
||||
### Using `add_child` in Tests
|
||||
When you call `add_child` from within a test the object is added as a child of the test script. The test script is a child of the GUT. GUT will output a warning if a test script has children when it finishes running (after `after_all`). If you need an object to exist for the duration of a script, be sure to free it in `after_all`. All scripts and children of scripts are freed after they are done.
|
||||
|
||||
|
||||
|
||||
### Testing for Leaks
|
||||
GUT provides the `assert_no_new_orphans` method that will assert that the test has not created any new orphans. Using this can be a little tricky in complicated test scripts.
|
||||
|
||||
`assert_no_new_orphans` will verify that, at the time of calling, the test has not created an new orphans.
|
||||
|
||||
`assert_no_new_orphans` cannot take into account anything you have called `autofree` on. For one, it's impossible, and it wouldn't tell you much since freeing that object could cause leaks.
|
||||
|
||||
A standard memory leak test will create an object, free it, and then verify that you have not created any new orphans. Based on some bad practices I've done myself I would advise creating tests with and without using `add_child`.
|
||||
|
||||
```gdscript
|
||||
# res://test/unit/test_foo.gd
|
||||
extends GutTest
|
||||
...
|
||||
|
||||
class TestLeaks:
|
||||
extends GutTest
|
||||
var Foo = load('res://foo.gd')
|
||||
|
||||
func test_no_leaks():
|
||||
var to_free = Foo.new()
|
||||
to_free.free()
|
||||
assert_not_new_orphans()
|
||||
|
||||
func test_no_leaks_with_add_child():
|
||||
var to_free = Foo.new()
|
||||
add_child(to_free)
|
||||
to_free.free()
|
||||
assert_no_new_orphans()
|
||||
```
|
||||
If you must use `queue_free` instead of `free` in your test then you will have to pause before asserting that no orphans have been created. You can do this with `await`
|
||||
``` gdscript
|
||||
func test_no_orphans_queue_free();
|
||||
var node = Node.new()
|
||||
node.queue_free()
|
||||
assert_no_new_orphans('this will fail')
|
||||
await wait_seconds(.2)
|
||||
assert_no_new_orphans('this one passes')
|
||||
```
|
||||
231
addons/gut/documentation/docs/Mocking-Input.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# Mocking Input
|
||||
|
||||
The [GutInputSender](class_GutInputSender) class operates on one or more receivers. It will create and send `InputEvent` instances to all of its receivers.
|
||||
|
||||
There are two ways you could be processing your input. You could be using the `_input` events to receive input events and process them. The other way is to interact with the `Input` global and detect input in the `_process` and `_physics_process` methods. [GutInputSender](class_GutInputSender) works with both approaches, but using [GutInputSender](class_GutInputSender) differs for each approach. Read the sections below to learn the best way to use [GutInputSender](class_GutInputSender) with your game.
|
||||
|
||||
|
||||
### Using an Object as a Receiver
|
||||
When you use an instance of an object as a receiver, [GutInputSender](class_GutInputSender) will send `InputEvent` instances to the various `input` methods. They will be called in this order:
|
||||
1. `_input`
|
||||
1. `_gui_input`
|
||||
1. `_unhandled_input`
|
||||
|
||||
When there are multiple receivers, each receiver will be called in the order they were added. All three `_input` methods will be called on each receiver then the [GutInputSender](class_GutInputSender) will move to the next receiver.
|
||||
|
||||
When using objects as receivers it is recommended that each test create its own instance of [GutInputSender](class_GutInputSender). [GutInputSender](class_GutInputSender) retains information about what actions/buttons/etc have been pressed. By creating a new instance in each test, you don't have to worry about clearing this state between tests.
|
||||
|
||||
If you are processing input by directly interacting with the `Input` global, then you should follow the instructions in the next section.
|
||||
``` gdscript
|
||||
func test_shoot():
|
||||
var player = Player.new()
|
||||
var sender = InputSender.new(player)
|
||||
|
||||
sender.action_down("shoot")
|
||||
assert_true(player.is_shooting())
|
||||
```
|
||||
|
||||
|
||||
### Using `Input` as a Receiver
|
||||
|
||||
When `Input` is used as a receiver `Input` will send all inputs it receives from the [GutInputSender](class_GutInputSender) to every object that has been added to the tree. `Input` will treat all the events it gets exactly the same as if the events were triggered from hardware. This means all the `is_action_just_pressed` and similar functions will work the same. The `InputEvent` instances will also be sent to the various `_input` methods on objects in the tree in whatever order `Input` desires.
|
||||
|
||||
Using `Input` makes testing objects that handle input via `_process` or `_process_delta` much easier but you have to be a little careful when using it though. Since the `Input` instance is global and retains its state for the duration of the test run.
|
||||
|
||||
1. You should declare your [GutInputSender](class_GutInputSender) instance at the class level. You will need access to it in the `after_each` method.
|
||||
1. Call `release_all` on the [GutInputSender](class_GutInputSender) in `after_each`. This makes sure that `Input` doesn't think that a button is pressed when you don't expect it to be. If `Input` thinks a button is pressed, it will not send any "down" events until it gets an "up" event.
|
||||
1. Call `clear` on the [GutInputSender](class_GutInputSender) in `after_each`. This clears out any state the [GutInputSender](class_GutInputSender) has. It tracks inputs so that functions like `hold_for` can create dynamic "up" events, as well as various other things. Calling `clear` makes sure that [GutInputSender](class_GutInputSender) state does not leak from one test to another.
|
||||
1. You must ALWAYS await before making an assert or your objects will not get a chance to process the frame the `Input` was sent on (`_process` and `_physics_process` will not be called without a await).
|
||||
|
||||
``` gdscript
|
||||
var _sender = InputSender.new(Input)
|
||||
|
||||
func after_each():
|
||||
_sender.release_all()
|
||||
_sender.clear()
|
||||
|
||||
func test_shoot():
|
||||
var player = Player.new()
|
||||
|
||||
_sender.action_down("shoot").wait_frames(1)
|
||||
await(_sender.idle)
|
||||
|
||||
assert_true(player.is_shooting())
|
||||
```
|
||||
|
||||
|
||||
### Chaining Input Events
|
||||
The [GutInputSender](class_GutInputSender) methods return the instance so you can chain multiple calls together to script out a sequence of inputs. The sequence is immediately started. When the sequence finishes the `'idle'` signal is emitted.
|
||||
|
||||
```
|
||||
var player = Player.new()
|
||||
var sender = InputSender.new(player)
|
||||
|
||||
# press a, then b, then release a, then release b
|
||||
sender.key_down("a").wait(.1)\
|
||||
.key_down(KEY_B).wait(.1)\
|
||||
.key_up("a").wait(.1)\
|
||||
.key_up(KEY_B)
|
||||
await(sender.idle)
|
||||
```
|
||||
The [GutInputSender](class_GutInputSender) will emit the `idle` signal when all inputs in a sequence have been sent and all `waits` have expired.
|
||||
|
||||
Any events that do not have a `wait` or `hold_for` call in between them will be fired on the same frame.
|
||||
```
|
||||
# checking for is_action_just_pressed for "jump" and "fire" will be true in the same frame.
|
||||
sender.action-down("jump").action_down("fire")
|
||||
```
|
||||
|
||||
You can use a trailing `wait` to give the result of the input time to play out
|
||||
```
|
||||
# wait an extra .2 seconds at the end so that asserts will be run after the
|
||||
# shooting animation finishes.
|
||||
sender.action_down("shoot").hold_for(1).wait(.2)
|
||||
await(sender.idle)
|
||||
```
|
||||
|
||||
|
||||
## Examples
|
||||
These are examples of scripting out inputs and sending them to `Input`. The `Player` class in these examples would be handling input in `_process` or `_process_physics`.
|
||||
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
|
||||
# When sending events to Input the InputSender instance should be defined at
|
||||
# the class level so that you can easily clear it between tests in after_each.
|
||||
var _sender = InputSender.new(Input)
|
||||
|
||||
# IMPORTANT: When using Input as the receiver of events you should always
|
||||
# release_all and clear the InputSender so that any
|
||||
# actions/keys/buttons that are not released in a test are released
|
||||
# before the next test runs. "down" events will not be sent by
|
||||
# Input if the action/button/etc is currently "down".
|
||||
func after_each():
|
||||
_sender.release_all()
|
||||
_sender.clear()
|
||||
|
||||
|
||||
# In this test we press and hold the jump button for .1 seconds then wait
|
||||
# another .3 seconds for the jump to take take place. We then assert that
|
||||
# the character has moved up between 4 and 5 pixels.
|
||||
func test_tapping_jump_jumps_certain_height():
|
||||
var player = add_child_autofree(Player.new())
|
||||
|
||||
_sender.action_down("jump").hold_for(.1).wait(.3)
|
||||
await(_sender.idle)
|
||||
|
||||
assert_between(player.position.y, 4, 5)
|
||||
|
||||
|
||||
# This is similar to the other test but we hold jump for longer and then
|
||||
# verify the player jumped higher.
|
||||
func test_holding_jump_jumps_higher():
|
||||
var player = add_child_autofree(Player.new())
|
||||
|
||||
_sender.action_down("jump").hold_for(.75)
|
||||
await(_sender.idle)
|
||||
|
||||
assert_between(player.position.y, 7, 8)
|
||||
|
||||
|
||||
# This tests throwing a fireball, like with Ryu or Ken from Street Fighter.
|
||||
# Note that there is not a hold_for after "forward" and the key_down for
|
||||
# fierce punch (FP) immediately after. This means the "forward" motion AND
|
||||
# FP are pressed in the same frame.
|
||||
func test_fireball_input():
|
||||
var player = add_child_autofree(Player.new())
|
||||
|
||||
_sender.action_down("down").hold_for("2f")\
|
||||
.action_down("down_forward").hold_for("2f")\
|
||||
.action_down("forward").key_down("FP")
|
||||
await(_sender.idle)
|
||||
|
||||
assert_true(player.is_throwing_fireball())
|
||||
|
||||
|
||||
# In this example we are testing that two actions in combination cause the
|
||||
# player to slide. Note that there is no release of the actions in this
|
||||
# test. This is a good example of why using release_all in after_each makes
|
||||
# the tests simpler to write and prevents leaking of inputs from one test to
|
||||
# another.
|
||||
func test_holding_down_and_jump_does_slide():
|
||||
var player = add_child_autofree(Player.new())
|
||||
|
||||
_sender.action_down("down").wait("1f")\
|
||||
.action_down("jump").wait("2f")
|
||||
await(_sender.idle)
|
||||
|
||||
assert_gt(player.velocity.x, 0)
|
||||
```
|
||||
|
||||
|
||||
## Gotchas
|
||||
* When using `Input` as a receiver, everything in the tree gets the signals AND any actual inputs from hardware will be sent as well. It's best not to touch anything when running these tests.
|
||||
* If you use a class level [GutInputSender](class_GutInputSender) and forget to call `release_all` and `clear` between tests then things will eventually start behaving weird and your tests will pass/fail in unpredictable ways.
|
||||
|
||||
|
||||
## Understanding Input.use_accumulated_input
|
||||
When `use_accumualted_input` is enabled, `Input` waits to process input until the end of a frame. This means that if you do not flush the buffer or there are no "waits" or calls to `await` before you test how input was processed then your tests will fail.
|
||||
|
||||
### Testing with use_accumulated_input
|
||||
#### Recommended approaches
|
||||
1. If you game does not want to have `use_accumulated_input` enabled, then disable it in a an Autoload. GUT loads autoloads before running so this will disable it for all tests.
|
||||
1. Always have a trailing `wait` when sending input `_sender.key_down('a').wait('10f')`. In testing, 6 frames wasn't enough but 7 was _(for reasons I don't understand but probably should so I made I used 10 frames for good measure)_.
|
||||
1. After sending all your input, call `Input.flush_buffered_events`. Only use this in the specific cases where you know you want to send inputs immediately since this is NOT how your game will actually receive inputs.
|
||||
|
||||
#### Other ways that aren't so good.
|
||||
If you use these approaches you should quarantine these tests in their own Inner Class or script so that they do not influence other tests that do not expect the buffer to be constantly flushed or `use_accumulated_input` to be disabled.
|
||||
1. In GUT 7.4.0 [GutInputSender](class_GutInputSender) has an `auto_flush_input` property which is disabled by default. When enabled this will call `Input.flush_buffered_events` after each input sent through an [GutInputSender](class_GutInputSender). This is a bit dangerous since this can cause some of your tests to not test the way your game will receive input when playing the game.
|
||||
1. You can disable `use_accumulated_input` in `before_all` and re-enable in `after_all`. Just like with `auto_flush_input`, this has the potential to not test all inputs the same way as your game will get them when playing the game.
|
||||
|
||||
### Examples
|
||||
The following assume `use_accumulated_input` is enabled and uses Godot 3.5 syntax. In 3.4 you have to call `set_use_accumulated_input`. There is no way to check the value of this flag in 3.4.
|
||||
```gdscript
|
||||
extends GutTest
|
||||
|
||||
var _sender = InputSender.new(Input)
|
||||
|
||||
func before_all():
|
||||
InputMap.add_action("jump")
|
||||
|
||||
func after_each():
|
||||
_sender.release_all()
|
||||
_sender.clear()
|
||||
|
||||
func test_when_uai_enabled_input_not_processed_immediately():
|
||||
_sender.key_down('a')
|
||||
assert_false(Input.is_key_pressed(KEY_A))
|
||||
|
||||
func test_when_uai_enabled_just_pressed_is_not_processed_immediately():
|
||||
_sender.action_down('jump')
|
||||
assert_false(Input.is_action_just_pressed('jump'))
|
||||
|
||||
func test_when_uai_enabled_waiting_makes_button_pressed():
|
||||
# wait 10 frames. In testing, 6 frames failed, but 7 passed. Added 3 for
|
||||
# good measure.
|
||||
_sender.key_down(KEY_Y).wait('10f')
|
||||
await(_sender.idle)
|
||||
assert_true(_sender.is_key_pressed(KEY_Y))
|
||||
assert_true(Input.is_key_pressed(KEY_Y))
|
||||
|
||||
func test_when_uai_enabled_flushig_buffer_sends_input_immediatly():
|
||||
_sender.key_down('a')
|
||||
Input.flush_buffered_events()
|
||||
assert_true(Input.is_key_pressed(KEY_A))
|
||||
|
||||
func test_disabling_uai_sends_input_immediately():
|
||||
Input.use_accumulated_input = false
|
||||
_sender.key_down('a')
|
||||
assert_true(Input.is_key_pressed(KEY_A))
|
||||
# re-enable so we don't ruin other tests
|
||||
Input.use_accumulated_input = true
|
||||
|
||||
func test_when_uai_enabled_flushing_buffer_just_pressed_is_processed_immediately():
|
||||
_sender.action_down('jump')
|
||||
Input.flush_buffered_events()
|
||||
assert_true(Input.is_action_just_pressed('jump'))
|
||||
```
|
||||
|
||||
|
||||
* [GutInputSender Class Reference](class_GutInputSender)
|
||||
* [GutInputFactory Class Reference](class_GutInputFactory)
|
||||
110
addons/gut/documentation/docs/New-For-Godot-4.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Godot 4 Changes
|
||||
These are changes to Godot that affect how GUT is used/implemented. There is more information about these changes and how GUT has been altered below.
|
||||
|
||||
* `setget` has been replaced with a completely new syntax. More info at [#380](https://github.com/bitwes/Gut/issues/380). Examples of the new way and the new `assert_property` method below.
|
||||
* `connect` has been significantly altered. The signal related asserts will likely change to use `Callable` parameters instead of strings. It is possible to use strings, so this may remain in some form. More info in [#383](https://github.com/bitwes/Gut/issues/383).
|
||||
* `yield` has been replaced with `await`. `yield_to`, `yield_for`, and `yield_frames` have been deprecated, the new methods are below.
|
||||
* Arrays are pass by reference now.
|
||||
* Dictionaries are compared by value now.
|
||||
* `File` and `Directory` have been replaced with `FileAccess` and `DirAccess`.
|
||||
* `is` no longer accepts a variable for a class. You must use `is_instance_of` instead.
|
||||
|
||||
|
||||
## What's new/changed in GUT 9.0.0 for Godot 4.0
|
||||
* Any methods that were deprecated in GUT 7.x have been removed.
|
||||
* `assert_setget` no longer works (it now just fails with a message). `assert_property` has been altered to work with the new setter/getter syntax. `assert_set_property`, `assert_readonly_property`, and `assert_property_with_backing_variable` have been added.
|
||||
* To aid refactoring, `assert_property` and `assert_property_with_backing_variable` will warn if any "public accessors" are found for the property ('get_' and 'set_' methods).
|
||||
* `assert_property` now requires an instance instead of also working with a loaded objects.
|
||||
* Doubling strategy flags have been renamed to `INCLUDE_NATIVE` (was `FULL`) and `SCRIPT_ONLY` (was `PARTIAL`). The default is `SCRIPT_ONLY`. I wanted something more descriptive and less likely to be confused with partial doubles.
|
||||
* The various `yield_` methods have been deprecated but are still supported to make conversions easier. The new syntax for `yield_to`, `yield_for`, or `yield_frames` is:
|
||||
```gdscript
|
||||
await yield_to(signaler, 'the_signal_name', 5, 'optional message')
|
||||
await yield_for(1.5, 'optional message')
|
||||
await yield_frames(30, 'optional message')
|
||||
```
|
||||
* The replacement methods for the various `yield_` methods are `wait_seconds`, `wait_idle_frames`, `wait_physics_frames`, and `wait_for_signal`.
|
||||
```gdscript
|
||||
await wait_for_signal(signaler.the_signal, 5, 'optional message') # wait for signal or 5 seconds
|
||||
await wait_seconds(1.5, 'optional message')
|
||||
await wait_physics_frames(30, 'optional message')
|
||||
```
|
||||
* Doubling no longer supports paths to a script or scene. Load the script or scene first and pass that to `double`. See the "Doubling Changes" section for more details.
|
||||
* Doubling Inner Classes now requires you to call `register_inner_classes` first. See the "Doubling Changes" section for more details.
|
||||
* Comparing Dictionary/Arrays with `assert_eq`, `assert_eq_deep`, and the new `assert_same` and `assert_not_same` for comparing references. See Godot's new `is_same` function for details on how `assert_same` works (it's just an assertion wrapper around `is_same`). See the section "Comparing Dictionaries and Arrays" below for more details.
|
||||
|
||||
|
||||
## Comparing Dictionaries and Arrays
|
||||
In Godot 3.x dictionaries were compared by reference and arrays were compared by value. In 4.0 both are compared by value. Godot 4.0 introduces the `is_same` method which (amongst other things) will compare dictionaries and arrays by reference.
|
||||
|
||||
GUT's `assert_eq` and `assert_ne` changed to match Godot's behavior. To compare by reference you can use the new `assert_same` or `assert_not_same`. This works with arrays and dictionaries. Review Godot's documentation for `is_same`. When comparing dictionaries and arrays it is recommended that you use `assert_eq_deep` since it provides more detailed output than `assert_eq`.
|
||||
|
||||
The shallow compare functionality has been removed since it no longer applies. Shallow compares would compare the elements of an array or dictionary by value. In Godot 3.x this meant that dictionaries inside of arrays or dictionaries would be compared by reference and everything else would be compared by value. Since arrays and dictionaries are both compared by value now, shallow compares are no different (functionally) than deep compares. The following methods have been removed. Calling these methods will generate a failure and an error.
|
||||
* `compare_shallow` (causes failure and returns `null` which will likely result in a runtime error)
|
||||
* `assert_eq_shallow`
|
||||
* `assert_ne_shallow`
|
||||
|
||||
Final note: `assert_eq` does not use `assert_eq_deep` since `assert_eq_deep` compares each element of both arrays/dictionaries and provides detailed info about what is different. This can be slow for large arrays/dictionaries. Godot's `==` operator uses a hashing function which is much faster but does not provide information about what is different in each array/dictionary. With `assert_eq`, `assert_eq_deep`, and `assert_same` (and their inverses) you have fine grained control over the type of comparison that is performed.
|
||||
|
||||
|
||||
## Doubling Changes
|
||||
### Doubling scripts and scenes
|
||||
The `double` method no longer supports paths to scripts or scenes. You should `load` the script or scene first, and then pass that to `double` instead.
|
||||
```
|
||||
var MyScript = load('res://my_script.gd')
|
||||
var dbl = double(MyScript).new()
|
||||
```
|
||||
If you pass a string then an error message will be printed and `double` will return `null`. This will most likely result in a runtime error when you attempt to instantiate your double.
|
||||
```
|
||||
'Invalid call. Nonexistent function 'new' in base 'Nil'.'
|
||||
```
|
||||
|
||||
### Doubling Inner Classes
|
||||
The `double` method no longer supports strings for the path of the base script or a string of the name of the Inner Class. You must call `register_inner_classes` then pass the Inner Class to `double`. You only have to do this once, so it is best to call it in `before_all` or a pre-hook script. Registering multiple times does nothing. Failing to call `register_inner_classes` will result in a GUT error and a runtime error.
|
||||
```gdscript
|
||||
# Given that SomeScript contains the class InnerClass that you wish to double:
|
||||
var SomeScript = load('res://some_script.gd')
|
||||
|
||||
func before_all():
|
||||
register_inner_classes(SomeScript)
|
||||
|
||||
func test_foo():
|
||||
var dbl = double(SomeScript.InnerClass).new()
|
||||
```
|
||||
This approach was used to make tests cleaner and less susceptible to typos. If Godot adds meta data to inner classes that point back to the source script, then `register_inner_classes` can be removed later and no other changes will need to be made.
|
||||
|
||||
|
||||
## setget vs set: and get:
|
||||
In godot 4.0 `setget` has been replaced with `set(val):` and `get():` pseudo methods which make properties more concrete. This is a welcome change, but comes with a few caveats.
|
||||
|
||||
Here's an example of usage:
|
||||
```
|
||||
var foo = 10:
|
||||
get():
|
||||
return foo
|
||||
set(val):
|
||||
foo = val
|
||||
```
|
||||
This means you no longer need to define methods for your accessors. Though you may still want to for organizational purposes.
|
||||
|
||||
One downside to this approach is that there is no way to set the `foo` without going through the accessor. Many times, internally, you will want to set a value for a property without going through the setter. This is still possible, but you have to make a backing variable.
|
||||
```
|
||||
var _foo = 10
|
||||
var foo = 10:
|
||||
get():
|
||||
return _foo
|
||||
set(val):
|
||||
_foo = val
|
||||
foo_changed.emit()
|
||||
```
|
||||
With this approach you can set `_foo` internally in your class without triggering the `foo_changed` signal. When you see `foo =` anywhere in your code, it will be going through the accessor. When you see `_foo =` you are only setting the backing variable.
|
||||
|
||||
To test this new paradigm `assert_setget` has been removed. `assert_property` has changed to work with the new syntax. `assert_property_with_backing_variable` was added to validate the backing variable wiring. If you use `assert_property_with_backing_variable` it will verify that the property has accessors and will also look for a `_<varname>` variable with the same name and verify it is being set.
|
||||
|
||||
`assert_property` will generate a warning when it finds "public" accessors for these properties (`get_foo`, `set_foo`).
|
||||
|
||||
|
||||
## Implementation Changes
|
||||
* The `Gut` control has been removed. Adding a `Gut` node to a scene to run tests will no longer work. This control dates back to Godot 2.x days. With GUT 7.4.1 I believe the in-editor Gut Panel has enough features to discontinue using a Scene/`Gut` control to run tests.
|
||||
* The GUI for GUT has been simplified to reflect that it is no longer used to run tests, just display progress and output. It has also been decoupled from `gut.gd`. `gut.gd` is now a `Node` instead of a `Control` and all GUI logic has been removed. New signals have been added so that a GUI can be made without `gut.gd` having to know anything about it. As a result, GUT can now be run without a GUI if that ever becomes something we want to do.
|
||||
* Replaced the old `yield_between_tests` flag with `paint_after`. This property (initially set to .1s) tells GUT how long to wait before it pauses for 1 frame to allow for painting the screen. This value is checked after each test, so longer tests can still cause a delay in the painting of the screen. This has made the painting a little choppier but has cut down the time it takes to run tests (200 simple tests in 20 scripts dropped from 2+ seconds to .5 seconds to run). This feature is settable from the command line, .gutconfig.json, and GutPanel.
|
||||
* Doubling has changed significantly.
|
||||
87
addons/gut/documentation/docs/Parameterized-Tests.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Parameterized Tests
|
||||
There are some scenarios where it is desirable to run a test numerous times with different parameters. You can do this in GUT by creating a test that has a single parameter that is defaulted to the GUT method `use_parameters`.
|
||||
|
||||
`use_parameters` expects an array. The test will be called once for each element in the array, passing the value of each element to the parameter of the function.
|
||||
|
||||
## Requirements:
|
||||
* The test must have one and only one parameter.
|
||||
* The parameter must be defaulted to call `use_parameters`.
|
||||
* You must pass an array to `use_parameters`. The test will be called once for each element in the array.
|
||||
* If the parameter is not defaulted then it will cause a runtime error.
|
||||
* If `use_parameters` is not called then GUT will only run the test once and will generate an error.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
|
||||
class Foo:
|
||||
func add(p1, p2):
|
||||
return p1 + p2
|
||||
|
||||
# Define one array, with two arrays as the elements in the array.
|
||||
# This will cause the test to be called twice. The first
|
||||
# call will get [1, 2, 3] as the value of the parameter.
|
||||
# The second call will get ['a', 'b', 'c']
|
||||
var foo_params = [[1, 2, 3], ['a', 'b', 'c']]
|
||||
|
||||
# This test will add the first two elements in params together,
|
||||
# using Foo, and assert that they equal the third element in params.
|
||||
func test_foo(params=use_parameters(foo_params)):
|
||||
var foo = Foo.new()
|
||||
var result = foo.add(params[0], params[1])
|
||||
assert_eq(result, params[2])
|
||||
```
|
||||
Running this test will result in:
|
||||
* One passing test (`1 + 2 = 3`)
|
||||
* One failing test (`'a' + 'b' != 'c'`, it actually equals `'ab'`)
|
||||
|
||||
## ParameterFactory
|
||||
`GutTest` scripts have access to the `ParameterFactory` static class which has helper methods for defining parameters for parameterized tests.
|
||||
|
||||
### Methods
|
||||
There's only one right now. If you have any suggestions, open up an [issue on Github](https://github.com/bitwes/Gut/issues).
|
||||
|
||||
#### named_parameters
|
||||
`named_parameters(names, values)`<br>
|
||||
Creates an array of dictionaries. It pairs up the names array with each set of values in values. If more names than values are specified then the missing values will be filled with nulls. If more values than names are specified those values will be ignored.
|
||||
|
||||
Example:
|
||||
``` gdscript
|
||||
# With this setup, you can use `params.p1`, `params.p2`, and
|
||||
# `params.result` in the test below.
|
||||
var foo_params = ParameterFactory.named_parameters(
|
||||
['p1', 'p2', 'result'], # names
|
||||
[ # values
|
||||
[1, 2, 3],
|
||||
['a', 'b', 'c']
|
||||
])
|
||||
|
||||
func test_foo(params = use_parameters(foo_params)):
|
||||
var foo = Foo.new()
|
||||
var result = foo.add(params.p1, params.p2)
|
||||
assert_eq(result, params.result)
|
||||
```
|
||||
|
||||
Here are some invalid setups and what results.
|
||||
``` gdscript
|
||||
# Example of extra values. This returns:
|
||||
# [{a:1}, {a:3}]
|
||||
ParameterFactory.named_parameters(
|
||||
['a'],
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
])
|
||||
|
||||
# Example of not enough values. This returns:
|
||||
# [{a:1, b:null}, {a:'oops', b:null}, {a:'one', b:'two'}]
|
||||
ParameterFactory.named_parameters(
|
||||
['a', 'b'],
|
||||
[
|
||||
[1],
|
||||
'oops',
|
||||
['one', 'two']
|
||||
])
|
||||
```
|
||||
47
addons/gut/documentation/docs/Partial-Doubles.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Partial Doubles
|
||||
|
||||
A Partial Double is the same thing as a normal Double except all methods retain their functionality by default.
|
||||
|
||||
You can create Partial Doubles for scripts, packed scenes, and inner classes. It works the same way as `double` works, so read up on that and then apply all that new knowledge to `partial_double`.
|
||||
|
||||
Under the covers, whether you call `double` or `partial_double`, GUT makes the same thing. If you call `partial_double` though, it will setup the object's methods to be stubbed `to_call_super` instead of not being stubbed at all.
|
||||
|
||||
After you have your partial double, you can stub methods to return values instead of doing what they normally do. You can also spy on any of the methods.
|
||||
|
||||
__NOTE__ All Doubles and Partial Doubles are freed when a test finishes. This means you do not have to free them manually and you should not be created in `before_all` or referenced in `after_all`.
|
||||
|
||||
## Script Example
|
||||
|
||||
Given
|
||||
``` gdscript
|
||||
# res://foo.gd
|
||||
extends Node2D
|
||||
|
||||
var _value = 10
|
||||
|
||||
func set_value(val):
|
||||
_value = val
|
||||
|
||||
func get_value():
|
||||
return _value
|
||||
```
|
||||
|
||||
Then
|
||||
|
||||
```gdscript
|
||||
var Foo = load('res://script.gd')
|
||||
|
||||
func test_things():
|
||||
var partial = partial_double(Foo).new()
|
||||
stub(partial, 'set_value').to_do_nothing()
|
||||
partial.set_value(20) # stubbed so implementation bypassed.
|
||||
|
||||
# since set_value was stubbed, and get_value was not, and since
|
||||
# this is a partial stub, then the original functionality of
|
||||
# get_value will be executed and _value is returned.
|
||||
assert_eq(partial.get_value(), 10)
|
||||
# unstubbed partial methods can be spied on.
|
||||
assert_called(partial, 'get_value')
|
||||
# stubbed methods can be spied on as well
|
||||
assert_called(partial, 'set_value', [20])
|
||||
```
|
||||
250
addons/gut/documentation/docs/Quick-Start.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# Quick Start
|
||||
This page contains brief descriptions of many of GUT's features. Most sections have a "More information" link where more in depth documentation can be found.
|
||||
|
||||
|
||||
## Install
|
||||
Add GUT to your project by downloading the `GUT - Godot Unit Testing` package in the Godot Asset Library (top center of Godot screen). For more details and alternate install methods, check the [install page](Install).
|
||||
|
||||
|
||||
## Creating Two Example Tests
|
||||
For purposes of this Quick Start guide, create a script file `res://test/unit/test_example.gd` with the following content:
|
||||
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
|
||||
func test_passes():
|
||||
# this test will pass because 1 does equal 1
|
||||
assert_eq(1, 1)
|
||||
|
||||
func test_fails():
|
||||
# this test will fail because those strings are not equal
|
||||
assert_eq('hello', 'goodbye')
|
||||
```
|
||||
|
||||
|
||||
## Run Tests
|
||||
|
||||
* Open the GUT panel
|
||||
|
||||

|
||||
|
||||
* Configure the directories where your tests are in the GUT Panel settings (you may need to scroll down to see this section). If you created the example test above, this would be in `res://test/unit`. A good strategy with GUT is to separate unit and integration tests into separate directory structures (such as `res://test/unit` and `res://test/integration`). Once you get a lot of tests, this will make it easier to run the fast unit tests frequently, and the slower integration tests only as often as is useful.
|
||||
|
||||

|
||||
|
||||
* Click "Run All" to run all your tests.
|
||||
* Open a test script and click the button with your test script's name (`test_test.gd` in image below) to run only that test script.
|
||||
* Open a test script, put the cursor inside a test function, click the button with your test function's name (`test_fails_when_number_not_equal` in the image below) to run just that one test.
|
||||
|
||||

|
||||
|
||||
Mouse-over labels and buttons in the GUT panel for more information. You can even set keyboard shortcuts for all of the GUT panel actions.
|
||||
|
||||
You can also run tests via the [command line](Command-Line) and through [VSCode](https://marketplace.visualstudio.com/items?itemName=bitwes.gut-extension)
|
||||
|
||||
|
||||
## Creating Tests
|
||||
|
||||
Much more information is available in the [Creating Tests](Creating-Tests) document, but here are some basics:
|
||||
|
||||
* All test scripts must extend `GutTest` (`res://addons/gut/test.gd`) script supplied by GUT.
|
||||
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
```
|
||||
|
||||
* By default, all test files must begin with `test_` to be found by GUT. You can change the prefix and suffix of test files in the GUT settings.
|
||||
|
||||
|
||||
There is a plethora of asserts and helpers that are listed [here](Asserts-and-Methods)
|
||||
|
||||
Setup and teardown methods:
|
||||
* `before_all`
|
||||
* `before_each`
|
||||
* `after_each`
|
||||
* `after_all`
|
||||
|
||||
Any method that starts with "test" will be run as a test.
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
|
||||
func before_all():
|
||||
gut.p("Runs once before all tests")
|
||||
|
||||
func before_each():
|
||||
gut.p("Runs before each test.")
|
||||
|
||||
func after_each():
|
||||
gut.p("Runs after each test.")
|
||||
|
||||
func after_all():
|
||||
gut.p("Runs once after all tests")
|
||||
|
||||
func test_assert_eq_number_not_equal():
|
||||
assert_eq(1, 2, "Should fail. 1 != 2")
|
||||
|
||||
func test_assert_eq_number_equal():
|
||||
assert_eq('asdf', 'asdf', "Should pass")
|
||||
```
|
||||
|
||||
You can use inner classes to group tests together. The class name must start with "Test" and extend `test.gd`.
|
||||
``` gdscript
|
||||
extends GutTest
|
||||
|
||||
class TestSomeAspects:
|
||||
extends GutTest
|
||||
|
||||
func test_assert_eq_number_not_equal():
|
||||
assert_eq(1, 2, "Should fail. 1 != 2")
|
||||
|
||||
func test_assert_eq_number_equal():
|
||||
assert_eq('asdf', 'asdf', "Should pass")
|
||||
|
||||
class TestOtherAspects:
|
||||
extends GutTest
|
||||
|
||||
func test_assert_true_with_true():
|
||||
assert_true(true, "Should pass, true is true")
|
||||
```
|
||||
|
||||
## Doubles/Spies/Stubs
|
||||
More Information: [Doubles](Doubles), [Spies](Spies), [Stubs](Stubbing)
|
||||
|
||||
You can make a double of just about anything. `double` returns a loaded class/scene, not an instance. Doubles extend the object to be doubled and have empty implementations for all methods defined in the script or parent scripts, but not parent Godot methods that are not overridden.
|
||||
|
||||
```gdscript
|
||||
var Foo = load('res://foo.gd')
|
||||
var MyScene = load('res://my_scene.tscn')
|
||||
|
||||
var double_foo = double(Foo).new()
|
||||
var double_scene = double(MyScene).instantiate()
|
||||
```
|
||||
|
||||
You can stub your double to do different things. Unstubbed methods that are called generate log messages.
|
||||
```gdscript
|
||||
var double_foo = double(Foo).new()
|
||||
stub(double_foo.bar).to_return(42)
|
||||
stub(double_foo, "something").to_call_super() # do what method would normally do
|
||||
stub(double_foo.other_thing).to_return(77).when_passed(1, 2, 'c')
|
||||
stub(double_foo.other_thing.bind(4, 5, 'z')).to_do_nothing()
|
||||
```
|
||||
|
||||
You can spy on your doubles with various asserts and helpers.
|
||||
```gdscript
|
||||
var double_foo = double(Foo).new()
|
||||
|
||||
...
|
||||
|
||||
assert_called(double_foo, 'bar')
|
||||
assert_not_called(double_foo, 'something')
|
||||
assert_call_count(double_foo, 'call_me', 10)
|
||||
|
||||
# assert other_thing called with parameters in array.
|
||||
assert_called(double_foo, 'other_thing', [1, 2, 'c'])
|
||||
|
||||
# Get an array of the parameters sent to the last
|
||||
# call to call_me
|
||||
var called_with_last = get_call_parameters(double_foo, 'call_me')
|
||||
|
||||
# get the parameters passed to the 4th call of `call_me`
|
||||
var called_with_4 = get_call_parameters(double_foo, 'call_me', 4))
|
||||
```
|
||||
|
||||
## Partial Doubles
|
||||
[More Information](Partial-Doubles)
|
||||
|
||||
Partial doubles have all the same properties of a double except they retain the source functionality by default. You can stub and spy on them just like a double, but anything not stubbed will behave as if it wasn't a double.
|
||||
```gdscript
|
||||
var double_bar = partial_double(Bar).instance()
|
||||
|
||||
# the foo method will do nothing always now
|
||||
stub(double_ba.foo).to_do_nothing()
|
||||
|
||||
# the something method will return 27 when passed 32,
|
||||
# but act normally when passed anything else.
|
||||
stub(double_bar.something).to_return(27).when_passed(32)
|
||||
|
||||
# example of spying
|
||||
assert_called(double_bar, 'other_thing')
|
||||
```
|
||||
|
||||
## Parameterized Tests
|
||||
[More Information](Parameterized-Tests)
|
||||
|
||||
You can create tests that will be run multiple times and be passed multiple values.
|
||||
* The test must have one and only one parameter.
|
||||
* That parameter must be defaulted to call `use_parameters`.
|
||||
* The value passed to use_parameters must be an array.
|
||||
* Each element in the array will result in one execution of the test with that element passed in.
|
||||
|
||||
```gdscript
|
||||
var test_params = [[1, 2, 3], [4, 5, 6]]
|
||||
func test_with_parameters(p=use_parameters(test_params)):
|
||||
assert_eq(p[0], p[2] - p[1])
|
||||
|
||||
# The first array contains the name of the parameters, the 2nd array contains the values.
|
||||
var named_params = ParameterFactory.named_parameters(['a', 'b'], [[1, 2], ['one', 'two']])
|
||||
func test_with_named_params(p=use_parameters(better_params)):
|
||||
assert_ne(p.a, p.b)
|
||||
```
|
||||
There are helpers to make your parameters more readable.
|
||||
|
||||
|
||||
## Await
|
||||
[More Information](Awaiting)
|
||||
|
||||
You can use `await` in your tests to allow time to pass before making assertions. This can be useful if you need to wait for some interaction to play out, a signal to be emitted, or wait for things to happen in the next frames, such as physics process or draw.
|
||||
|
||||
If you want to wait for a certain amount of time you can use `wait_seconds`.
|
||||
```gdscript
|
||||
await wait_seconds(10)
|
||||
```
|
||||
You can `await` to a signal or an amount of time, whichever comes first with `wait_for_signal`. This ensures that your tests do not hang when a signal is not emitted.
|
||||
```gdscript
|
||||
var my_obj = load('res://my_obj.gd').new()
|
||||
await wait_for_signal(my_obj.some_signal, 3)
|
||||
```
|
||||
You can also `await` for a number of physics frames using `wait_physics_frames`. It's best to wait at least 2 frames as waiting one frame can be flaky.
|
||||
```gdscript
|
||||
await wait_physics_frames(5)
|
||||
```
|
||||
Or a number of idle/process frames using `wait_process_frames`.
|
||||
```gdscript
|
||||
await wait_process_frames(10)
|
||||
```
|
||||
|
||||
## Leak Testing and Memory Management
|
||||
[More Information](Memory-Management)
|
||||
|
||||
Call `autofree` or `autoqfree` on anything you want to be automatically freed up after your test. These return whatever you pass it so you can save a line of code!
|
||||
```gdscript
|
||||
var my_node = autofree(Node.new())
|
||||
```
|
||||
`autofree` calls `free` on the object and `autoqfree` calls `queue_free`.
|
||||
|
||||
If you plan to add your object to the tree you can use the `add_child_autofree` and `add_child_autoqfree` methods to add them as a child of the test script and free them at the end of the test.
|
||||
``` gdscript
|
||||
var my_node = add_child_autofree(Node2D.new())
|
||||
```
|
||||
|
||||
Orphan counts are displayed after each test/script that generates orphans and at the end of the run. If you don't see output, then you don't have any orphans! You can disable this feature if you want.
|
||||
|
||||
All objects created with `double` or `partial_double` are freed automatically after a test finishes.
|
||||
|
||||
You can assert you didn't make any new orphans with `assert_no_new_orphans`. `assert_no_new_orphans` doesn't know about objects passed to `autofree` so they will be counted if they are not in the tree.
|
||||
```gdscript
|
||||
func test_freeing():
|
||||
var node = Node.new()
|
||||
assert_no_new_orphans('this one fails')
|
||||
node.free()
|
||||
assert_no_new_orphans('this one passes')
|
||||
|
||||
# If you queue_free then you have to wait for it to be freed.
|
||||
func test_queue_freeing():
|
||||
var node = Node.new()
|
||||
node.queue_free()
|
||||
assert_no_new_orphans('this one fails')
|
||||
await(wait_seconds(.1))
|
||||
assert_no_new_orphans('this one passes')
|
||||
|
||||
```
|
||||
153
addons/gut/documentation/docs/Running-On-Devices.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Running on Devices
|
||||
|
||||
You may want to deploy your tests with your game so you can run tests on different devices and platforms. GUT provides the handy `GutControl` to help you run your tests.
|
||||

|
||||
|
||||
|
||||
In order to run tests in a deployed game you must create a scene to kick off the tests from within the game. Here's the steps:
|
||||
* Create a scene
|
||||
* Add a `GutControl` to the scene.
|
||||

|
||||
* Add a script to your scene and paste in the code below.
|
||||
* You're off to the races.
|
||||
|
||||
Remember to add `*.json` in your export settings (resources tab), or your config file will not be exported with your game.
|
||||
|
||||
```
|
||||
# ------------------------------------------------------------------------------
|
||||
# This is an example of using the GutControl (res://addons/gut/gui/GutContro.tscn)
|
||||
# to execute tests in a deployed game.
|
||||
#
|
||||
# Setup:
|
||||
# Create a scene.
|
||||
# Add a GutControl to your scene, name it GutControl.
|
||||
# Add this script to your scene.
|
||||
# Run it.
|
||||
# ------------------------------------------------------------------------------
|
||||
extends Node2D
|
||||
@onready var _gut_control = $GutControl
|
||||
|
||||
# Holds a reference to the current test script object being run. Set in
|
||||
# signal callbacks.
|
||||
var _current_script_object = null
|
||||
# Holds the name of the current test being run. Set in signal callbacks.
|
||||
var _current_test_name = null
|
||||
|
||||
|
||||
func _ready():
|
||||
simple_setup()
|
||||
# complex_setup()
|
||||
|
||||
|
||||
func simple_setup():
|
||||
# You must load a gut config file to use this control. Here we are loading
|
||||
# the default config file used by the command line. You can use any config
|
||||
# file you have created. Use the "save as" button in the Settings subpanel
|
||||
# to create a config file, or write your own.
|
||||
#
|
||||
# Some settings may not work. For example, the exit flags do not have any
|
||||
# effect.
|
||||
#
|
||||
# Settings are not saved, so any changes will be lost. The idea is that you
|
||||
# want to deploy the settings and users should not be able to save them. If
|
||||
# you want to save changes, you can call:
|
||||
# _gut_control.get_config().write_options(path).
|
||||
# Note that you cannot to write to res:// on mobile platforms, so you will
|
||||
# have to juggle the initial loading from res:// or user:// and save to
|
||||
# user://.
|
||||
_gut_control.load_config_file('res://.gutconfig.json')
|
||||
|
||||
# That's it. Just get a reference to the control you added to the scene and
|
||||
# give it a config. The rest of the stuff in this script optional.
|
||||
|
||||
|
||||
|
||||
func complex_setup():
|
||||
# See simple setup
|
||||
_gut_control.load_config_file('res://.gutconfig.json')
|
||||
|
||||
# Returns a gut_config.gd instance.
|
||||
var config = _gut_control.get_config()
|
||||
|
||||
# Override specific values for the purposes of this scene. You can see all
|
||||
# the options available in the default_options dictionary in gut_config.gd.
|
||||
# Changing settings AFTER _ready will not have any effect.
|
||||
config.options.should_exit = false
|
||||
config.options.should_exit_on_success = false
|
||||
config.options.compact_mode = false
|
||||
# Note that if you are exporting xml results you may want to set the path to
|
||||
# a file in user:// instead of an absolute path. Your game may not have
|
||||
# permissions to save files elsewhere when running on a mobile device.
|
||||
config.options.junit_xml_file = 'user://deployed_results.xml'
|
||||
|
||||
# Some actions cannot be done until after _ready has finished in all objects
|
||||
_post_ready_setup.call_deferred()
|
||||
|
||||
|
||||
|
||||
|
||||
# If you would like to connect to signals provided by gut.gd then you must do
|
||||
# so after _ready. This is an example of getting a reference to gut and all
|
||||
# of the signals it provides.
|
||||
func _post_ready_setup():
|
||||
var gut = _gut_control.get_gut()
|
||||
gut.start_run.connect(_on_gut_run_start)
|
||||
|
||||
gut.start_script.connect(_on_gut_start_script)
|
||||
gut.end_script.connect(_on_gut_end_script)
|
||||
|
||||
gut.start_test.connect(_on_gut_start_test)
|
||||
gut.end_test.connect(_on_gut_end_test)
|
||||
|
||||
gut.end_run.connect(_on_gut_run_end)
|
||||
|
||||
|
||||
# -----------------------
|
||||
# Events
|
||||
# -----------------------
|
||||
func _on_gut_run_start():
|
||||
print('Starting tests')
|
||||
|
||||
|
||||
# This signal passes a TestCollector.gd/TestScript instance
|
||||
func _on_gut_start_script(script_obj):
|
||||
print(script_obj.get_full_name(), ' has ', script_obj.tests.size(), ' tests')
|
||||
_current_script_object = script_obj
|
||||
|
||||
|
||||
func _on_gut_end_script():
|
||||
var pass_count = 0
|
||||
for test in _current_script_object.tests:
|
||||
if(test.did_pass()):
|
||||
pass_count += 1
|
||||
print(pass_count, '/', _current_script_object.tests.size(), " passed\n")
|
||||
_current_script_object = null
|
||||
|
||||
|
||||
func _on_gut_start_test(test_name):
|
||||
_current_test_name = test_name
|
||||
print(' ', test_name)
|
||||
|
||||
|
||||
func _on_gut_end_test():
|
||||
# get_test_named returns a TestCollector.gd/Test instance for the name
|
||||
# passed in.
|
||||
var test_object = _current_script_object.get_test_named(_current_test_name)
|
||||
var status = "failed"
|
||||
if(test_object.did_pass()):
|
||||
status = "passed"
|
||||
elif(test_object.pending):
|
||||
status = "pending"
|
||||
|
||||
print(' ', status)
|
||||
_current_test_name = null
|
||||
|
||||
|
||||
func _on_gut_run_end():
|
||||
print('Tests Done')
|
||||
|
||||
|
||||
# You can kick of the tests via code if you want.
|
||||
func _on_run_gut_tests_button_pressed():
|
||||
_gut_control.run_tests()
|
||||
```
|
||||
75
addons/gut/documentation/docs/Simulate.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Simulate
|
||||
`simulate(obj, times, delta, check_is_processing: bool = false)`
|
||||
|
||||
The simulate method will call the `_process` and `_physics_process` on a tree of objects. It will check each object to see if they have either method and run it if it exists. In cases where the object has both it will call `_process` and then `_physics_process` and then move on to the next node in the tree.
|
||||
|
||||
`simulate` takes in the base object, the number of times to call the methods and the delta value to be passed to `_process` or `_physics_process` (if the object has one). It starts calling it on the passed in object and then moves through the tree recursively calling `_process` and `_physics_process`. The order that the children are processed is determined by the order that `get_children` returns
|
||||
|
||||
By default `simulate` will ignore if the object is "processing" or not. When the optional `check_is_processing` is `true`, GUT will check `is_processing` and `is_physics_processing` on each object and will not call their respective methods if the object is not "processing". Remeber, that nodes not in the tree will not be "processing" by default, so you have to add them (use `add_child_autofree` or `add_child_autoqfree`) or call `set_process` or `set_physics_process` before calling `simulate`.
|
||||
|
||||
`simulate` will only cause code directly related to the `_process` and `_physics_process` methods to run. Signals will be sent, methods will be called but timers, for example, will not fire since the main loop of the game is not actually running. Creating a test that uses `await` is a better solution for testing such things.
|
||||
|
||||
Example
|
||||
``` gdscript
|
||||
|
||||
# --------------------------------
|
||||
# res://scripts/my_object.gd
|
||||
# --------------------------------
|
||||
extends Node2D
|
||||
var a_number = 1
|
||||
|
||||
func _process(delta):
|
||||
a_number += 1
|
||||
|
||||
# --------------------------------
|
||||
# res://scripts/another_object.gd
|
||||
# --------------------------------
|
||||
extends Node2D
|
||||
var another_number = 1
|
||||
|
||||
func _physics_process(delta):
|
||||
another_number += 1
|
||||
|
||||
# --------------------------------
|
||||
# res://test/unit/test_my_object.gd
|
||||
# --------------------------------
|
||||
|
||||
# ...
|
||||
|
||||
var MyObject = load('res://scripts/my_object.gd')
|
||||
var AnotherObject = load('res://scripts/another_object')
|
||||
|
||||
# ...
|
||||
|
||||
# Given that SomeCoolObj has a _process method that increments a_number by 1
|
||||
# each time _process is called, and that the number starts at 0, this test
|
||||
# should pass
|
||||
func test_does_something_each_loop():
|
||||
var my_obj = MyObject.new()
|
||||
add_child_autofree(my_obj)
|
||||
gut.simulate(my_obj, 20, .1)
|
||||
assert_eq(my_obj.a_number, 20, 'Since a_number is incremented in _process, it should be 20 now')
|
||||
|
||||
# Let us also assume that AnotherObj acts exactly the same way as
|
||||
# but has SomeCoolObj but has a _physics_process method instead of
|
||||
# _process. In that case, this test will pass too since all child objects
|
||||
# have the _process or _physics_process method called.
|
||||
func test_does_something_each_loop():
|
||||
var my_obj = MyObject.new()
|
||||
var other_obj = AnotherObj.new()
|
||||
|
||||
add_child_autofree(my_obj)
|
||||
my_obj.add_child(other_obj)
|
||||
|
||||
gut.simulate(my_obj, 20, .1)
|
||||
|
||||
assert_eq(my_obj.a_number, 20, 'Since a_number is incremented in _process, \
|
||||
it should be 20 now')
|
||||
assert_eq(other_obj.another_number, 20, 'Since other_obj is a child of my_obj \
|
||||
and another_number is incremented in \
|
||||
_physics_process then it should be 20 now')
|
||||
|
||||
```
|
||||
|
||||
## Where to next?
|
||||
* [Awaiting](Awaiting)<br/>
|
||||
19
addons/gut/documentation/docs/Spies.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Spies
|
||||
When a `double` is instanced, Gut will record calls to methods that are defined in the script or scripts it inherits from. You can then make assertions to check if a method was called, not called, passed certain values, or how many times it was called.
|
||||
|
||||
You should read the page on doubling before using this, as there are some gotchas with doubling.
|
||||
|
||||
__You can only spy on methods that have been included in the Double. Built-in functions (such as `set_position`) are not doubled by default, so you cannot spy on them unless you have set the [Double Strategy](Double-Strategy).__
|
||||
|
||||
## Spy Related Methods
|
||||
The following methods can be used to "spy" on doubled objects. They are available in any script that extends [GutTest](class_GutTest).
|
||||
<!--
|
||||
I could not find any other way to link
|
||||
TO an anchor in a page generated from a class ref rst file,
|
||||
FROM a page generated by markdown
|
||||
-->
|
||||
* <a href="class_ref/class_guttest.html#class-guttest-method-assert-called">assert_called</a>
|
||||
* <a href="class_ref/class_guttest.html#class-guttest-method-assert-not-called">assert_not_called</a>
|
||||
* <a href="class_ref/class_guttest.html#class-guttest-method-assert-called-count">assert_called_count</a>
|
||||
* <a href="class_ref/class_guttest.html#class-guttest-method-get-call-parameters">get_call_parameters</a>
|
||||
* <a href="class_ref/class_guttest.html#class-guttest-method-get-call-count">get_call_count</a>
|
||||
335
addons/gut/documentation/docs/Stubbing.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# Stubbing
|
||||
|
||||
The `stub` function allows you to define behavior for methods of a Doubled instance. Stubs can be layered to address general and specific circumstances. You can use `stub` to
|
||||
* Force a method to do nothing and return a specific value.
|
||||
* Call `super`'s version of the method, allowing the double to retain original functionality.
|
||||
* Call a `Callable` of your choosing (aka Monkey Patching).
|
||||
* Force the method to take no action (useful when using Partial Doubles).
|
||||
|
||||
All Stubs are cleared between tests. If you want to stub a method for all your tests do this in `before_each` using `stub(MyScript, "method_name")...`. You should not stub anything in `before_all`, `after_each`, or `after_all`.
|
||||
|
||||
|
||||
|
||||
|
||||
## Syntax
|
||||
`stub` creates a stub for a method on a specific instance of a Double or any instance of a Doubled script. After calling `stub` you chain calls to the various actioins available to tell GUT what the stub should do. `stub` can be called numerous ways:
|
||||
|
||||
### stub(callable)
|
||||
This will create a stub for the Double instance and method of the callable. If the Callable has bound parameters the stub will only be used when the parameters used when calling the method match the bound parameters. Using bound parameters is the same as using `when_passed`.
|
||||
``` gdscript
|
||||
var inst = double(MyScript).new()
|
||||
stub(inst.some_method).to_return(111)
|
||||
stub(inst.some_method.bind("a")).to_return(999)
|
||||
|
||||
assert_eq(inst.some_method("not a"), 111)
|
||||
assert_eq(inst.some_method("a"), 999)
|
||||
```
|
||||
|
||||
### stub(double_instance, method_name)
|
||||
This creates a stub for the object and method. This is the same as `stub(callable)`. If you wish to stub for specific parameter values, use `when_passed`.
|
||||
``` gdscript
|
||||
var inst = double(MyScript).new()
|
||||
stub(inst, "some_method").to_return(111)
|
||||
stub(inst, "some_method").when_passed("a").to_return(999)
|
||||
|
||||
assert_eq(inst.some_method("not a"), 111)
|
||||
assert_eq(inst.some_method("a"), 999)
|
||||
```
|
||||
|
||||
### stub(script, method_name) / stub(path_to_script, method_name):
|
||||
Creates a stub for `method_name` on all Doubles of a `script`. This stub will be used if a stub is not added for an instance. It is best to do this in `before_each`.
|
||||
``` gdscript
|
||||
func before_each():
|
||||
stub(MyScript, "some_method").to_return(111)
|
||||
|
||||
func test_script_level_stubs():
|
||||
var uses_script_stub = double(MyScript).new()
|
||||
var has_instance_stub = double(MyScript).new()
|
||||
stub(has_instance_stub.some_method).to_return(555)
|
||||
stub(has_instance_stub.some_method.bind("a")).to_return(999)
|
||||
|
||||
assert_eq(uses_script_stub.some_method("anything"), 111)
|
||||
assert_eq(uses_script_stub.some_method("a"), 111)
|
||||
|
||||
assert_eq(has_instance_stub.some_method("anything"), 555)
|
||||
assert_eq(has_instance_stub.some_method("a"), 999)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Stub Actions
|
||||
You can stub a method to take the following actions when called. These actions will be taken based on the best matched stub found for the method.
|
||||
|
||||
__Only one action should be specified as only one will be used.__
|
||||
|
||||
Chain an action to the end of a call to `stub`
|
||||
``` gdscript
|
||||
stub(MyScript, "some_method").to_return(9)
|
||||
```
|
||||
|
||||
### to_return(value)
|
||||
This stubs the method to do nothing and return a specific value when called.
|
||||
|
||||
|
||||
### to_do_nothing()
|
||||
This is the same as `to_return(null)` but has a nice explicit name that is easy to read. This is mostly used with Partial Doubles to make them not "call super".
|
||||
```gdscript
|
||||
var inst = partial_double(MyScript).new()
|
||||
stub(inst._set).to_do_nothing()
|
||||
|
||||
inst.some_property = 9
|
||||
assert_ne(inst.some_property, 9)
|
||||
```
|
||||
|
||||
### to_call_super()
|
||||
This will cause a method to punch through to `super`'s implementation of the method retaining the original functionality of the method.
|
||||
```gdscript
|
||||
var dbl_inst = double(MyScript).new()
|
||||
var inst = double(MyScript).new()
|
||||
|
||||
stub(dbl_inst.some_method).to_call_super()
|
||||
|
||||
assert_eq(dbl_inst.some_method(), inst.some_method())
|
||||
```
|
||||
|
||||
### to_call(callable)
|
||||
This will cause the double to call the method specified. Any value returned from the `Callable` will be returned by the original method.
|
||||
|
||||
The parameters passed to the original method will be sent to the `Callable.` Be sure the parameters of the `Callable` are compatable with the parameters of the original method or a runtime error will occur.
|
||||
|
||||
Any parameters bound to the `Callable` will be passed __after__ the parameters sent to the original method. Bound parameters will not be included when spying.
|
||||
|
||||
```gdscript
|
||||
func return_passed(p1=null, p2=null, p3=null, p4=null, p5=null, p6=null):
|
||||
return [p1, p2, p3, p4, p5, p6]
|
||||
|
||||
func test_illustrate_stub_action_to_call():
|
||||
var dbl_inst = double(MyScript).new()
|
||||
|
||||
stub(MyScript, "foo")\
|
||||
.to_call(func(value): print("We did not get a seven."))
|
||||
|
||||
stub(MyScript, "foo")\
|
||||
.when_passed(7)\
|
||||
.to_call(func(value): print("We got a 7"))
|
||||
|
||||
|
||||
# This illustrates the ordering of bound parameters, return values, and
|
||||
# argument spying.
|
||||
stub(dbl_inst.bar).to_call(return_passed.bind("three", "four"))
|
||||
var result = dbl_inst.bar("one", "two")
|
||||
assert_eq(result, ["one", "two", "three", "four", null, null])
|
||||
assert_called(dbl_inst, "bar", ["one", "two"],
|
||||
"This passes because bound arguments are not spied on.")
|
||||
```
|
||||
|
||||
All the greatness and super weirdness of using lambdas applies.
|
||||
```gdscript
|
||||
func test_using_local_variable_in_callable():
|
||||
var this_var = "some value"
|
||||
var d = double(DoubleMe).new()
|
||||
stub(d.has_one_param).to_call(
|
||||
func(value):
|
||||
this_var = "another value"
|
||||
return this_var)
|
||||
|
||||
var result = d.has_one_param("asdf")
|
||||
|
||||
# These all pass
|
||||
assert_eq(result, "another value", "Seems reasonable")
|
||||
assert_ne(result, this_var, "Why would this pass?")
|
||||
assert_eq(this_var, "some value", "Ohhh, well ok.")
|
||||
```
|
||||
|
||||
|
||||
## Stub Qualifiers
|
||||
There is only one qualifier, `when_passed`. Only the last `when_passed` qualifier will be used. If you wish to stub the same action for multiple argument patterns you must make multiple stubs. See the various examples above.
|
||||
|
||||
|
||||
|
||||
|
||||
## Method Signature Modifiers
|
||||
You alter a method's signature with:
|
||||
* `param_defaults([default1, default2, ...])`
|
||||
* `param_count(x)`
|
||||
|
||||
There are very few cases where you would want to do this. They are discussed further near the end of this page.
|
||||
|
||||
|
||||
|
||||
|
||||
## Stubbing at the Script level vs Instance level
|
||||
The `stub` method is pretty smart about what you pass it. You can pass it a path, an Object or an instance. If you pass an instance, it __must__ be an instance of a double.
|
||||
|
||||
When passed an Object or a path, it will stub the value for __all__ instances that do not have explicitly defined stubs. When you pass it an instance of a doubled class, then the stubbed return will only be set for that instance.
|
||||
|
||||
```gdscript
|
||||
var DoubleThis = load('res://scripts/double_this.gd')
|
||||
var Doubled = double(DoubleThis)
|
||||
var inst = Doubled.new()
|
||||
|
||||
# These two are equivalent, and stub returns_seven for any doubles of
|
||||
# DoubleThis to return 500.
|
||||
stub('res://scripts/double_this.gd', 'returns_seven').to_return(500)
|
||||
# or
|
||||
stub(DoubleThis, 'returns_seven').to_return(500)
|
||||
assert_eq(inst.returns_seven(), 500)
|
||||
|
||||
# This will stub returns_seven on the passed in instance ONLY.
|
||||
# Any other instances will return 500 from the lines above.
|
||||
var stub_again = Doubled.new()
|
||||
stub(stub_again, 'returns_seven').to_return('words')
|
||||
assert_eq(stub_again.returns_seven(), 'words')
|
||||
assert_eq(inst.returns_seven, 500)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Stubbing based off of parameter values
|
||||
You can stub a method to return a specific value based on what was passed to it.
|
||||
```gdscript
|
||||
var DoubleThis = load('res://scripts/double_this.gd')
|
||||
var Doubled = double(DoubleThis)
|
||||
var inst = Doubled.new()
|
||||
|
||||
# Script level using when_passed
|
||||
stub(DoubleThis, "return_hello").to_return("world").when_passed("hello")
|
||||
# Instance level using bound callable
|
||||
stub(inst.return_hello.bind("foo")).to_return("bar")
|
||||
|
||||
assert_eq(inst.return_hello(), "hello")
|
||||
assert_eq(inst.return_hello("hello"), "world")
|
||||
assert_eq(inst.return_hello("foo"), "bar")
|
||||
```
|
||||
The ordering of `when_passed` and `to_return` does not matter.
|
||||
|
||||
|
||||
|
||||
|
||||
## Stubbing Packed Scenes
|
||||
When stubbing doubled scenes, use the path to the scene, __not__ the path to the scene's script. If you double and stub the script used by the scene, the `instance` you make from `double` will not return values stubbed for the script. It will only return values stubbed for the scene.
|
||||
|
||||
In order for a scene to be doubled, the scene's script must be able to be instantiated with `new` with zero parameters passed.
|
||||
|
||||
### Example
|
||||
Given the script `res://the_script.gd`:
|
||||
``` gdscript
|
||||
func return_hello():
|
||||
return 'hello'
|
||||
```
|
||||
And given a scene with the path `res://double_this_scene.tscn` which has its script set to `res://the_script.gd`.
|
||||
|
||||
``` gdscript
|
||||
var DoubleThisScene = load('res://double_this_scene.tscn')
|
||||
|
||||
func test_illustrate_stubbing_scenes():
|
||||
var doubled_scene = double(DoubleThisScene).instantiate()
|
||||
stub(doubled_scene, 'return_hello').to_return('world')
|
||||
|
||||
assert_eq(doubled_scene.return_hello(), 'world')
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Stubbing Method Parameter Defaults
|
||||
Godot only provides information about default values for built in methods so Gut doesn't know what any default values are for methods you have created. Since it can't know, Gut defaults all parameters to `null`. This can cause issues in specific cases (probably all involving calling super). You can use `.param_defaults` to specify default values to be used.
|
||||
|
||||
Here's an example where things go wrong
|
||||
```
|
||||
# res://foo.gd
|
||||
var _sum = 0
|
||||
func increment(inc_by=1):
|
||||
_sum += inc_by
|
||||
|
||||
func go_up_one():
|
||||
increment()
|
||||
|
||||
func get_sum():
|
||||
return _sum
|
||||
```
|
||||
|
||||
The following test will cause a `Invalid operands 'int' and 'Nil'` error. This is because increment's `inc_by` parameter is defaulted to `null` in the double.
|
||||
```
|
||||
var Foo = load('res://foo.gd')
|
||||
test_go_up_one_increments_sum_by_1():
|
||||
var dbl_foo = double(Foo).new()
|
||||
stub(dbl_foo, 'go_up_one').to_call_super()
|
||||
|
||||
dbl_foo.go_up_one()
|
||||
assert_called(dbl_foo, 'increment', [1])
|
||||
```
|
||||
|
||||
The fix is to add a `param_defaults` stub
|
||||
```
|
||||
stub(dbl_foo, 'increment').param_defaults([1])
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Stubbing Method Parameter Count
|
||||
<u>__Changing the number of parameters must be done before `double` is called__</u>
|
||||
|
||||
Some built-in methods have `vararg` parameters. This makes the parameter list dynamic. Godot does not provide this information. This can cause errors due to a signature mismatch. Your code might be calling a method using 10 parameter values but Gut only sees two.
|
||||
|
||||
Let's take `Node.rpc_id` for example. It has two normal parameters and then a vararg of strings as the last parameter.
|
||||
```
|
||||
Variant rpc_id(peer_id: int, method: String, ...) vararg
|
||||
```
|
||||
If this method gets called in a partial double with more than 2 parameters Godot will will throw _Invalid call to function 'rpc_id' in base 'Control ()'. Expected 2 arguments._
|
||||
|
||||
You can use `.param_count(x)` to tell Gut to give the method any number of extra parameters. You cannot make the method have less parameters. You must do this before you call `double`.
|
||||
``` gdscript
|
||||
func test_issue_246_rpc_id_varargs():
|
||||
# must happen before double is called
|
||||
stub(Node, 'rpc_id').to_do_nothing().param_count(5)
|
||||
|
||||
var inst = double(Node).new()
|
||||
inst.rpc_id(1, 'foo', '3', '4', '5')
|
||||
assert_called(inst, 'rpc_id', [1, 'foo', '3', '4', '5'])
|
||||
```
|
||||
|
||||
You can also use `.param_defaults` to specify extra parameters if you supply more defaults than the method has parameters.
|
||||
|
||||
``` gdscript
|
||||
func test_issue_246_rpc_id_varargs_with_defaults():
|
||||
# must happen before double is called
|
||||
stub(Node, 'rpc_id').to_do_nothing().param_defaults([null, null, 'a', 'b', 'c'])
|
||||
|
||||
var inst = double(Node).new()
|
||||
inst.rpc_id(1, 'foo', 'z')
|
||||
assert_called(inst, 'rpc_id', [1, 'foo', 'z', 'b', 'c'])
|
||||
```
|
||||
You cannot make a method have less parameters, only more.
|
||||
|
||||
|
||||
|
||||
|
||||
## Stubbing Accessors
|
||||
It is not possible to stub the accessors for properties if you do not use a secondary method for the accessors. This means that doubles retain the functionality of the accessors, and it cannot be changed.
|
||||
``` gdscript
|
||||
# The get and set for my_property cannot be stubbed. Doubles retain the
|
||||
# functionality of the get and set methods.
|
||||
var my_property = 'foo' :
|
||||
get: return my_property
|
||||
set(val): my_property = val
|
||||
```
|
||||
|
||||
If you use secondary methods, you can stub the behavior, but all doubles will not have any functionality for the accessors by default.
|
||||
```gdscript
|
||||
# You can stub _get_my_property and _set_my_property. Doubles of this do not
|
||||
# retain the functionality of the accessors. _get_my_property and
|
||||
# _set_my_property must be stubbed to_call_super to actually return or set
|
||||
# the value of my_property.
|
||||
var my_property = 'foo' :
|
||||
get: _get_my_property, set: _set_my_property
|
||||
|
||||
func _get_my_property():
|
||||
return my_property
|
||||
|
||||
func _set_my_property(val):
|
||||
my_property = val
|
||||
```
|
||||
4
addons/gut/documentation/docs/Tutorials.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Tutorials
|
||||
Here's a list of known tutorials.
|
||||
|
||||
* [Mocking Input](https://www.youtube.com/watch?v=cRKppa9R7ZQ) Implements double jump in the Godot 2D Platformer by using the `InputSender` class in some integration tests.
|
||||
45
addons/gut/documentation/docs/_static/css/gut_custom.css
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/* ----------------------------------------------------------------------------*
|
||||
Gut Wiki Specific items
|
||||
----------------------------------------------------------------------------- */
|
||||
.gutwarning{
|
||||
background-color: rgb(60, 0, 0);
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
border-style: dashed;
|
||||
border-width: 5px;
|
||||
border-color: black;
|
||||
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------*
|
||||
sphinx-rtd-dark-mode
|
||||
----------------------------------------------------------------------------- */
|
||||
html[data-theme="dark"] li.current > a,
|
||||
html[data-theme="dark"] li.current > ul > li
|
||||
{
|
||||
background-color: rgb(42, 33, 42) !important;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] li.toctree-l3 > a {
|
||||
background-color: rgb(36, 22, 36) !important;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] a.reference.internal.current{
|
||||
background-color: rgb(155, 152, 152) !important;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------*
|
||||
Customizing the wiki
|
||||
----------------------------------------------------------------------------- */
|
||||
.wy-menu-vertical p.caption {
|
||||
text-transform: capitalize !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search {
|
||||
background-color: rgb(66, 10, 130) !important;
|
||||
}
|
||||
BIN
addons/gut/documentation/docs/_static/images/AddGutControl.png
vendored
Normal file
|
After Width: | Height: | Size: 99 KiB |
34
addons/gut/documentation/docs/_static/images/AddGutControl.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cigysgwwb5dp5"
|
||||
path="res://.godot/imported/AddGutControl.png-5d6e19c9b4cd7b49c399c48d700ce69b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/AddGutControl.png"
|
||||
dest_files=["res://.godot/imported/AddGutControl.png-5d6e19c9b4cd7b49c399c48d700ce69b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/GuiCompact.png
vendored
Normal file
|
After Width: | Height: | Size: 26 KiB |
34
addons/gut/documentation/docs/_static/images/GuiCompact.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://goc2vwbfgndr"
|
||||
path="res://.godot/imported/GuiCompact.png-d61824da3e858e1e70fc3527fdada064.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/GuiCompact.png"
|
||||
dest_files=["res://.godot/imported/GuiCompact.png-d61824da3e858e1e70fc3527fdada064.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/GutControl.png
vendored
Normal file
|
After Width: | Height: | Size: 54 KiB |
34
addons/gut/documentation/docs/_static/images/GutControl.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://shuhyrvian16"
|
||||
path="res://.godot/imported/GutControl.png-37843914ac106d73f17facea877d62ce.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/GutControl.png"
|
||||
dest_files=["res://.godot/imported/GutControl.png-37843914ac106d73f17facea877d62ce.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/GutDocsLogo.png
vendored
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
34
addons/gut/documentation/docs/_static/images/GutDocsLogo.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://sleldhoqj8je"
|
||||
path="res://.godot/imported/GutDocsLogo.png-a5f48d2fab70aab34e33336f94ac690a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/GutDocsLogo.png"
|
||||
dest_files=["res://.godot/imported/GutDocsLogo.png-a5f48d2fab70aab34e33336f94ac690a.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/GutErrorOptions.png
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
addons/gut/documentation/docs/_static/images/GutGui.png
vendored
Normal file
|
After Width: | Height: | Size: 189 KiB |
34
addons/gut/documentation/docs/_static/images/GutGui.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bo6nfm1l5j6qk"
|
||||
path="res://.godot/imported/GutGui.png-0605fa140f90e6b2908f382fa141f20b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/GutGui.png"
|
||||
dest_files=["res://.godot/imported/GutGui.png-0605fa140f90e6b2908f382fa141f20b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/WarningsSettings.png
vendored
Normal file
|
After Width: | Height: | Size: 331 KiB |
BIN
addons/gut/documentation/docs/_static/images/exclude_addons.png
vendored
Normal file
|
After Width: | Height: | Size: 177 KiB |
34
addons/gut/documentation/docs/_static/images/exclude_addons.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d0a78guxlm2mn"
|
||||
path="res://.godot/imported/exclude_addons.png-2d2c817abc528e131640983575b6c388.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/exclude_addons.png"
|
||||
dest_files=["res://.godot/imported/exclude_addons.png-2d2c817abc528e131640983575b6c388.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/export_as_text.png
vendored
Normal file
|
After Width: | Height: | Size: 35 KiB |
34
addons/gut/documentation/docs/_static/images/export_as_text.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dvvfhdnh0wuin"
|
||||
path="res://.godot/imported/export_as_text.png-d37529967c7f7994ebb66d4d42eda96a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/export_as_text.png"
|
||||
dest_files=["res://.godot/imported/export_as_text.png-d37529967c7f7994ebb66d4d42eda96a.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/gut_panel.png
vendored
Normal file
|
After Width: | Height: | Size: 503 KiB |
34
addons/gut/documentation/docs/_static/images/gut_panel.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://qtfbylicg3tx"
|
||||
path="res://.godot/imported/gut_panel.png-cb9e402270550ba26158d0fe087b7127.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/gut_panel.png"
|
||||
dest_files=["res://.godot/imported/gut_panel.png-cb9e402270550ba26158d0fe087b7127.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/gut_panel_test_directories.png
vendored
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
addons/gut/documentation/docs/_static/images/gut_panel_where.png
vendored
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
addons/gut/documentation/docs/_static/images/gut_settings.png
vendored
Normal file
|
After Width: | Height: | Size: 160 KiB |
34
addons/gut/documentation/docs/_static/images/gut_settings.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c3cfi45411hi"
|
||||
path="res://.godot/imported/gut_settings.png-ecf0de2d9d98448f73791eaceedf7607.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/gut_settings.png"
|
||||
dest_files=["res://.godot/imported/gut_settings.png-ecf0de2d9d98448f73791eaceedf7607.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
addons/gut/documentation/docs/_static/images/view_user_files.png
vendored
Normal file
|
After Width: | Height: | Size: 10 KiB |
34
addons/gut/documentation/docs/_static/images/view_user_files.png.import
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://lig0073w8cjy"
|
||||
path="res://.godot/imported/view_user_files.png-35546bf00953427de4c80db5784e48e8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://documentation/docs/_static/images/view_user_files.png"
|
||||
dest_files=["res://.godot/imported/view_user_files.png-35546bf00953427de4c80db5784e48e8.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -0,0 +1,385 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_addons/gut/cli/optparse.gd:
|
||||
|
||||
addons/gut/cli/optparse.gd
|
||||
==========================
|
||||
|
||||
**Inherits:** `RefCounted <https://docs.godotengine.org/en/stable/classes/class_refcounted.html>`_
|
||||
|
||||
Parses command line arguments, as one might expect.
|
||||
|
||||
.. rst-class:: classref-introduction-group
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Parses command line arguments with a bunch of options including generating text that displays all the arguments your script accepts. This is included in the GUT ClassRef since it might be usable by others and is portable (everything it needs is in this one file).
|
||||
|
||||
This does alot, if you want to see it in action have a look at `scratch/optparse_example.gd <https://github.com/bitwes/Gut/blob/main/scratch/optparse_example.gd>`__\
|
||||
|
||||
.. code:: text
|
||||
|
||||
|
||||
Godot Argument Lists
|
||||
-------------------------
|
||||
There are two sets of command line arguments that Godot populates:
|
||||
OS.get_cmdline_args
|
||||
OS.get_cmdline_user_args.
|
||||
|
||||
OS.get_cmdline_args contains any arguments that are not used by the engine
|
||||
itself. This means options like --help and -d will never appear in this list
|
||||
since these are used by the engine. The one exception is the -s option which
|
||||
is always included as the first entry and the script path as the second.
|
||||
Optparse ignores these values for argument processing but can be accessed
|
||||
with my_optparse.options.script_option. This list does not contain any
|
||||
arguments that appear in OS.get_cmdline_user_args.
|
||||
|
||||
OS.get_cmdline_user_args contains any arguments that appear on the command
|
||||
line AFTER " -- " or " ++ ". This list CAN contain options that the engine
|
||||
would otherwise use, and are ignored completely by the engine.
|
||||
|
||||
The parse method, by default, includes arguments from OS.get_cmdline_args and
|
||||
OS.get_cmdline_user_args. You can optionally pass one of these to the parse
|
||||
method to limit which arguments are parsed. You can also conjure up your own
|
||||
array of arguments and pass that to parse.
|
||||
|
||||
See Godot's documentation for get_cmdline_args and get_cmdline_user_args for
|
||||
more information.
|
||||
|
||||
|
||||
Adding Options
|
||||
--------------
|
||||
Use the following to add options to be parsed. These methods return the
|
||||
created Option instance. See that class above for more info. You can use
|
||||
the returned instance to get values, or use get_value/get_value_or_null.
|
||||
add("--name", "default", "Description goes here")
|
||||
add(["--name", "--aliases"], "default", "Description goes here")
|
||||
add_required(["--name", "--aliases"], "default", "Description goes here")
|
||||
add_positional("--name", "default", "Description goes here")
|
||||
add_positional_required("--name", "default", "Description goes here")
|
||||
|
||||
get_value will return the value of the option or the default if it was not
|
||||
set. get_value_or_null will return the value of the option or null if it was
|
||||
not set.
|
||||
|
||||
The Datatype for an option is determined from the default value supplied to
|
||||
the various add methods. Supported types are
|
||||
String
|
||||
Int
|
||||
Float
|
||||
Array of strings
|
||||
Boolean
|
||||
|
||||
|
||||
Value Parsing
|
||||
-------------
|
||||
optparse uses option_name_prefix to differentiate between option names and
|
||||
values. Any argument that starts with this value will be treated as an
|
||||
argument name. The default is "-". Set this before calling parse if you want
|
||||
to change it.
|
||||
|
||||
Values for options can be supplied on the command line with or without an "=":
|
||||
option=value # no space around "="
|
||||
option value # a space between option and value w/o =
|
||||
There is no way to escape "=" at this time.
|
||||
|
||||
Array options can be specified multiple times and/or set from a comma delimited
|
||||
list.
|
||||
-gdir=a,b
|
||||
-gdir c,d
|
||||
-gdir e
|
||||
Results in -gdir equaling [a, b, c, d, e]. There is no way to escape commas
|
||||
at this time.
|
||||
|
||||
To specify an empty list via the command line follow the option with an equal
|
||||
sign
|
||||
-gdir=
|
||||
|
||||
Boolean options will have thier value set to !default when they are supplied
|
||||
on the command line. Boolean options cannot have a value on the command line.
|
||||
They are either supplied or not.
|
||||
|
||||
If a value is not an array and is specified multiple times on the command line
|
||||
then the last entry will be used as the value.
|
||||
|
||||
Positional argument values are parsed after all named arguments are parsed.
|
||||
This means that other options can appear before, between, and after positional
|
||||
arguments.
|
||||
--foo=bar positional_0_value --disabled --bar foo positional_1_value --a_flag
|
||||
|
||||
Anything that is not used by named or positional arguments will appear in the
|
||||
unused property. You can use this to detect unrecognized arguments or treat
|
||||
everything else provided as a list of things, or whatever you want. You can
|
||||
use is_option on the elements of unused (or whatever you want really) to see
|
||||
if optparse would treat it as an option name.
|
||||
|
||||
Use get_missing_required_options to get an array of Option with all required
|
||||
options that were not found when parsing.
|
||||
|
||||
The parsed_args property holds the list of arguments that were parsed.
|
||||
|
||||
|
||||
Help Generation
|
||||
---------------
|
||||
You can call get_help to generate help text, or you can just call print_help
|
||||
and this will print it for you.
|
||||
|
||||
Set the banner property to any text you want to appear before the usage and
|
||||
options sections.
|
||||
|
||||
Options are printed in the order they are added. You can add a heading for
|
||||
different options sections with add_heading.
|
||||
add("--asdf", 1, "This will have no heading")
|
||||
add_heading("foo")
|
||||
add("--foo", false, "This will have the foo heading")
|
||||
add("--another_foo", 1.5, "This too.")
|
||||
add_heading("This is after foo")
|
||||
add("--bar", true, "You probably get it by now.")
|
||||
|
||||
If you include "[default]" in the description of a option, then the help will
|
||||
substitue it with the default value.
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+---------+
|
||||
| `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ | :ref:`banner<class_addons/gut/cli/optparse.gd_property_banner>` | ``""`` |
|
||||
+------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+---------+
|
||||
| `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ | :ref:`option_name_prefix<class_addons/gut/cli/optparse.gd_property_option_name_prefix>` | ``"-"`` |
|
||||
+------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+---------+
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ | :ref:`add<class_addons/gut/cli/optparse.gd_method_add>`\ (\ op_names, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`add_heading<class_addons/gut/cli/optparse.gd_method_add_heading>`\ (\ display_text\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ | :ref:`add_positional<class_addons/gut/cli/optparse.gd_method_add_positional>`\ (\ op_name, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ | :ref:`add_positional_required<class_addons/gut/cli/optparse.gd_method_add_positional_required>`\ (\ op_name, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ | :ref:`add_required<class_addons/gut/cli/optparse.gd_method_add_required>`\ (\ op_names, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ | :ref:`get_help<class_addons/gut/cli/optparse.gd_method_get_help>`\ (\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Array <https://docs.godotengine.org/en/stable/classes/class_array.html>`_ | :ref:`get_missing_required_options<class_addons/gut/cli/optparse.gd_method_get_missing_required_options>`\ (\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_value<class_addons/gut/cli/optparse.gd_method_get_value>`\ (\ name\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_value_or_null<class_addons/gut/cli/optparse.gd_method_get_value_or_null>`\ (\ name\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `bool <https://docs.godotengine.org/en/stable/classes/class_bool.html>`_ | :ref:`is_option<class_addons/gut/cli/optparse.gd_method_is_option>`\ (\ arg\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`parse<class_addons/gut/cli/optparse.gd_method_parse>`\ (\ cli_args = null\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`print_help<class_addons/gut/cli/optparse.gd_method_print_help>`\ (\ ) |
|
||||
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Property Descriptions
|
||||
---------------------
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_property_banner:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ **banner** = ``""`` :ref:`🔗<class_addons/gut/cli/optparse.gd_property_banner>`
|
||||
|
||||
Set the banner property to any text you want to appear before the usage and options sections when printing the options help.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_property_option_name_prefix:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ **option_name_prefix** = ``"-"`` :ref:`🔗<class_addons/gut/cli/optparse.gd_property_option_name_prefix>`
|
||||
|
||||
optparse uses option_name_prefix to differentiate between option names and values. Any argument that starts with this value will be treated as an argument name. The default is "-". Set this before calling parse if you want to change it.
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_is_option:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`bool <https://docs.godotengine.org/en/stable/classes/class_bool.html>`_ **is_option**\ (\ arg\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_is_option>`
|
||||
|
||||
Test if something is an existing argument. If ``str(arg)`` begins with the :ref:`option_name_prefix<class_addons/gut/cli/optparse.gd_property_option_name_prefix>`, it will considered true, otherwise it will be considered false.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_add:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ **add**\ (\ op_names, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_add>`
|
||||
|
||||
Adds a command line option. If ``op_names`` is a String, this is set as the argument's name. If ``op_names`` is an Array of Strings, all elements of the array will be aliases for the same argument and will be treated as such during parsing. ``default`` is the default value the option will be set to if it is not explicitly set during parsing. ``desc`` is a human readable text description of the option. If the option is successfully added, the Option object will be returned. If the option is not successfully added (e.g. a name collision with another option occurs), an error message will be printed and ``null`` will be returned.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_add_required:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ **add_required**\ (\ op_names, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_add_required>`
|
||||
|
||||
Adds a required command line option. Required options that have not been set may be collected after parsing by calling :ref:`get_missing_required_options<class_addons/gut/cli/optparse.gd_method_get_missing_required_options>`. If ``op_names`` is a String, this is set as the argument's name. If ``op_names`` is an Array of Strings, all elements of the array will be aliases for the same argument and will be treated as such during parsing. ``default`` is the default value the option will be set to if it is not explicitly set during parsing. ``desc`` is a human readable text description of the option. If the option is successfully added, the Option object will be returned. If the option is not successfully added (e.g. a name collision with another option occurs), an error message will be printed and ``null`` will be returned.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_add_positional:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ **add_positional**\ (\ op_name, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_add_positional>`
|
||||
|
||||
Adds a positional command line option. Positional options are parsed by their position in the list of arguments are are not assigned by name by the user. If ``op_name`` is a String, this is set as the argument's name. If ``op_name`` is an Array of Strings, all elements of the array will be aliases for the same argument and will be treated as such during parsing. ``default`` is the default value the option will be set to if it is not explicitly set during parsing. ``desc`` is a human readable text description of the option. If the option is successfully added, the Option object will be returned. If the option is not successfully added (e.g. a name collision with another option occurs), an error message will be printed and ``null`` will be returned.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_add_positional_required:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`"addons/gut/cli/optparse.gd".Option <https://docs.godotengine.org/en/stable/classes/class_"addons/gut/cli/optparse.gd".option.html>`_ **add_positional_required**\ (\ op_name, default, desc\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_add_positional_required>`
|
||||
|
||||
Adds a required positional command line option. If ``op_name`` is a String, this is set as the argument's name. Required options that have not been set may be collected after parsing by calling :ref:`get_missing_required_options<class_addons/gut/cli/optparse.gd_method_get_missing_required_options>`. Positional options are parsed by their position in the list of arguments are are not assigned by name by the user. If ``op_name`` is an Array of Strings, all elements of the array will be aliases for the same argument and will be treated as such during parsing. ``default`` is the default value the option will be set to if it is not explicitly set during parsing. ``desc`` is a human readable text description of the option. If the option is successfully added, the Option object will be returned. If the option is not successfully added (e.g. a name collision with another option occurs), an error message will be printed and ``null`` will be returned.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_add_heading:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **add_heading**\ (\ display_text\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_add_heading>`
|
||||
|
||||
Headings are used to separate logical groups of command line options when printing out options from the help menu. Headings are printed out between option descriptions in the order that :ref:`add_heading<class_addons/gut/cli/optparse.gd_method_add_heading>` was called.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_get_value:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_value**\ (\ name\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_get_value>`
|
||||
|
||||
Gets the value assigned to an option after parsing. ``name`` can be the name of the option or an alias of it. ``name`` specifies the option whose value you wish to query. If the option exists, the value assigned to it during parsing is returned. Otherwise, an error message is printed and ``null`` is returned.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_get_value_or_null:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_value_or_null**\ (\ name\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_get_value_or_null>`
|
||||
|
||||
Gets the value assigned to an option after parsing, returning null if the option was not assigned instead of its default value. ``name`` specifies the option whose value you wish to query. This can be useful when providing an order of precedence to your values. For example if
|
||||
|
||||
::
|
||||
|
||||
default value < config file < command line
|
||||
|
||||
then you do not want to get the default value for a command line option or it will overwrite the value in a config file.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_get_help:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ **get_help**\ (\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_get_help>`
|
||||
|
||||
Returns the help text for all defined options.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_print_help:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **print_help**\ (\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_print_help>`
|
||||
|
||||
Prints out the help text for all defined options.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_parse:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **parse**\ (\ cli_args = null\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_parse>`
|
||||
|
||||
Parses a string for all options that have been set in this optparse. if ``cli_args`` is passed as a String, then it is parsed. Otherwise if ``cli_args`` is null, aruments passed to the Godot engine at startup are parsed. See the explanation at the top of addons/gut/cli/optparse.gd to understand which arguments this will have access to.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/cli/optparse.gd_method_get_missing_required_options:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Array <https://docs.godotengine.org/en/stable/classes/class_array.html>`_ **get_missing_required_options**\ (\ ) :ref:`🔗<class_addons/gut/cli/optparse.gd_method_get_missing_required_options>`
|
||||
|
||||
Get all options that were required and were not set during parsing. The return value is an Array of Options.
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
@@ -0,0 +1,72 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_addons/gut/junit_xml_export.gd:
|
||||
|
||||
addons/gut/junit_xml_export.gd
|
||||
==============================
|
||||
|
||||
**Inherits:** `RefCounted <https://docs.godotengine.org/en/stable/classes/class_refcounted.html>`_
|
||||
|
||||
Exposes functionality to export results of a test run in JUnit XML format.
|
||||
|
||||
.. rst-class:: classref-introduction-group
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This class exposes two methods for exporting GUT test results to XML. One returns a string representing the XML, and the other writes it to a file.
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ | :ref:`get_results_xml<class_addons/gut/junit_xml_export.gd_method_get_results_xml>`\ (\ gut\: :ref:`GutMain<class_GutMain>`\ ) |
|
||||
+------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `int <https://docs.godotengine.org/en/stable/classes/class_int.html>`_ | :ref:`write_file<class_addons/gut/junit_xml_export.gd_method_write_file>`\ (\ gut\: :ref:`GutMain<class_GutMain>`, path\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) |
|
||||
+------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_addons/gut/junit_xml_export.gd_method_get_results_xml:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ **get_results_xml**\ (\ gut\: :ref:`GutMain<class_GutMain>`\ ) :ref:`🔗<class_addons/gut/junit_xml_export.gd_method_get_results_xml>`
|
||||
|
||||
Takes in an instance of :ref:`GutMain<class_GutMain>` and returns a string of XML representing the results of the run.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_addons/gut/junit_xml_export.gd_method_write_file:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`int <https://docs.godotengine.org/en/stable/classes/class_int.html>`_ **write_file**\ (\ gut\: :ref:`GutMain<class_GutMain>`, path\: `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_\ ) :ref:`🔗<class_addons/gut/junit_xml_export.gd_method_write_file>`
|
||||
|
||||
Takes in an instance of GutMain and writes test results to an XML file specified by ``path``. Return value is an error code forwarded from the call to FileAccess.open to write to ``path``.
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
@@ -0,0 +1,90 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_addons/gut/parameter_factory.gd:
|
||||
|
||||
addons/gut/parameter_factory.gd
|
||||
===============================
|
||||
|
||||
**Inherits:** `RefCounted <https://docs.godotengine.org/en/stable/classes/class_refcounted.html>`_
|
||||
|
||||
Creates parameter structures for parameterized tests.
|
||||
|
||||
.. rst-class:: classref-introduction-group
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This is a static class accessible in a :ref:`GutTest<class_GutTest>` script through :ref:`GutTest.ParameterFactory<class_GutTest_property_ParameterFactory>`. It contains methods for constructing parameters to be used in parameterized tests. It currently only has one, if you have anyu ideas for more, make an issue. More of them would be great since I prematurely decided to make this static class and it has such a long name. I'd feel a lot better about it if there was more in here.
|
||||
|
||||
Additional Helper Ideas?
|
||||
|
||||
* File. IDK what it would look like. csv maybe.
|
||||
* Random values within a range?
|
||||
* All int values in a range or add an optioanal step.
|
||||
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`named_parameters<class_addons/gut/parameter_factory.gd_method_named_parameters>`\ (\ names, values\ ) |static| |
|
||||
+--------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_addons/gut/parameter_factory.gd_method_named_parameters:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **named_parameters**\ (\ names, values\ ) |static| :ref:`🔗<class_addons/gut/parameter_factory.gd_method_named_parameters>`
|
||||
|
||||
Creates an array of dictionaries. It pairs up the names array with each set of values in values. If more names than values are specified then the missing values will be filled with nulls. If more values than names are specified those values will be ignored. Example:
|
||||
|
||||
::
|
||||
|
||||
create_named_parameters(['a', 'b'], [[1, 2], ['one', 'two']]) returns
|
||||
[{a:1, b:2}, {a:'one', b:'two'}]
|
||||
|
||||
|
||||
|
||||
This allows you to increase readability of your parameterized tests:
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
var params = create_named_parameters(['a', 'b'], [[1, 2], ['one', 'two']])
|
||||
func test_foo(p = use_parameters(params)):
|
||||
assert_eq(p.a, p.b)
|
||||
|
||||
|
||||
|
||||
Parameters:
|
||||
|
||||
* names: an array of names to be used as keys in the dictionaries
|
||||
* values: an array of arrays of values.
|
||||
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
183
addons/gut/documentation/docs/class_ref/class_guthookscript.rst
Normal file
@@ -0,0 +1,183 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_GutHookScript:
|
||||
|
||||
GutHookScript
|
||||
=============
|
||||
|
||||
**Inherits:** `RefCounted <https://docs.godotengine.org/en/stable/classes/class_refcounted.html>`_
|
||||
|
||||
This script is the base for custom scripts to be used in pre and post run hooks.
|
||||
|
||||
.. rst-class:: classref-introduction-group
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
GUT Wiki: `https://gut.readthedocs.io <https://gut.readthedocs.io>`__
|
||||
|
||||
|
||||
|
||||
Creating a hook script requires that you:
|
||||
|
||||
- Inherit ``GutHookScript``\
|
||||
|
||||
- Implement a ``run()`` method
|
||||
|
||||
- Configure the path in GUT (gutconfig and/or editor) as the approparite hook (pre or post).
|
||||
|
||||
See `Hooks <../Hooks.html>`__
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+---------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`JunitXmlExport<class_GutHookScript_property_JunitXmlExport>` | ``load(...)`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+---------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`gut<class_GutHookScript_property_gut>` | ``null`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+---------------+
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`abort<class_GutHookScript_method_abort>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_exit_code<class_GutHookScript_method_get_exit_code>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`register_inner_classes<class_GutHookScript_method_register_inner_classes>`\ (\ script\: `Script <https://docs.godotengine.org/en/stable/classes/class_script.html>`_\ ) |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`run<class_GutHookScript_method_run>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`set_exit_code<class_GutHookScript_method_set_exit_code>`\ (\ code\: `int <https://docs.godotengine.org/en/stable/classes/class_int.html>`_\ ) |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`should_abort<class_GutHookScript_method_should_abort>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Property Descriptions
|
||||
---------------------
|
||||
|
||||
.. _class_GutHookScript_property_JunitXmlExport:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **JunitXmlExport** = ``load(...)`` :ref:`🔗<class_GutHookScript_property_JunitXmlExport>`
|
||||
|
||||
Class responsible for generating xml. You could use this to generate XML yourself instead of using the built in GUT xml generation options. See :ref:`addons/gut/junit_xml_export.gd<class_addons/gut/junit_xml_export.gd>`
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutHookScript_property_gut:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **gut** = ``null`` :ref:`🔗<class_GutHookScript_property_gut>`
|
||||
|
||||
This is the instance of :ref:`GutMain<class_GutMain>` that is running the tests. You can get information about the run from this object. This is set by GUT when the script is instantiated.
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_GutHookScript_method_run:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **run**\ (\ ) :ref:`🔗<class_GutHookScript_method_run>`
|
||||
|
||||
Virtual method that will be called by GUT after instantiating this script. This is where you put all of your logic.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutHookScript_method_register_inner_classes:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **register_inner_classes**\ (\ script\: `Script <https://docs.godotengine.org/en/stable/classes/class_script.html>`_\ ) :ref:`🔗<class_GutHookScript_method_register_inner_classes>`
|
||||
|
||||
Register inner classes from one or more scripts for doubling. Only worth calling from pre-run hook, not post-run.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutHookScript_method_set_exit_code:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **set_exit_code**\ (\ code\: `int <https://docs.godotengine.org/en/stable/classes/class_int.html>`_\ ) :ref:`🔗<class_GutHookScript_method_set_exit_code>`
|
||||
|
||||
Set the exit code when running from the command line. If not set then the default exit code will be returned (0 when no tests fail, 1 when any tests fail).
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutHookScript_method_get_exit_code:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_exit_code**\ (\ ) :ref:`🔗<class_GutHookScript_method_get_exit_code>`
|
||||
|
||||
Returns the exit code set with ``set_exit_code``
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutHookScript_method_abort:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **abort**\ (\ ) :ref:`🔗<class_GutHookScript_method_abort>`
|
||||
|
||||
Usable by pre-run script to cause the run to end AFTER the run() method finishes. GUT will quit and post-run script will not be ran.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutHookScript_method_should_abort:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **should_abort**\ (\ ) :ref:`🔗<class_GutHookScript_method_should_abort>`
|
||||
|
||||
Returns if ``abort`` was called.
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
@@ -0,0 +1,212 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_GutInputFactory:
|
||||
|
||||
GutInputFactory
|
||||
===============
|
||||
|
||||
**Inherits:** `RefCounted <https://docs.godotengine.org/en/stable/classes/class_refcounted.html>`_
|
||||
|
||||
Static class full of helper methods to make InputEvent instances.
|
||||
|
||||
.. rst-class:: classref-introduction-group
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This thing makes InputEvents. Enjoy.
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ | :ref:`action_down<class_GutInputFactory_method_action_down>`\ (\ which, strength = 1.0\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ | :ref:`action_up<class_GutInputFactory_method_action_up>`\ (\ which, strength = 1.0\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ | :ref:`key_down<class_GutInputFactory_method_key_down>`\ (\ which\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ | :ref:`key_up<class_GutInputFactory_method_key_up>`\ (\ which\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ | :ref:`mouse_double_click<class_GutInputFactory_method_mouse_double_click>`\ (\ position, global_position = null\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ | :ref:`mouse_left_button_down<class_GutInputFactory_method_mouse_left_button_down>`\ (\ position, global_position = null\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ | :ref:`mouse_left_button_up<class_GutInputFactory_method_mouse_left_button_up>`\ (\ position, global_position = null\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ | :ref:`mouse_motion<class_GutInputFactory_method_mouse_motion>`\ (\ position, global_position = null\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ | :ref:`mouse_relative_motion<class_GutInputFactory_method_mouse_relative_motion>`\ (\ offset, last_motion_event = null, speed = Vector2(0, 0)\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ | :ref:`mouse_right_button_down<class_GutInputFactory_method_mouse_right_button_down>`\ (\ position, global_position = null\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ | :ref:`mouse_right_button_up<class_GutInputFactory_method_mouse_right_button_up>`\ (\ position, global_position = null\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ | :ref:`new_mouse_button_event<class_GutInputFactory_method_new_mouse_button_event>`\ (\ position, global_position, pressed, button_index\ ) |static| |
|
||||
+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_GutInputFactory_method_new_mouse_button_event:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ **new_mouse_button_event**\ (\ position, global_position, pressed, button_index\ ) |static| :ref:`🔗<class_GutInputFactory_method_new_mouse_button_event>`
|
||||
|
||||
Creates a new button with the given propoerties.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_key_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ **key_up**\ (\ which\ ) |static| :ref:`🔗<class_GutInputFactory_method_key_up>`
|
||||
|
||||
Returns an `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ event with ``pressed = false``. ``which`` can be a character or a ``KEY_*`` constant.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_key_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ **key_down**\ (\ which\ ) |static| :ref:`🔗<class_GutInputFactory_method_key_down>`
|
||||
|
||||
Returns an `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ event with ``pressed = true``. ``which`` can be a character or a ``KEY_*`` constant.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_action_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ **action_up**\ (\ which, strength = 1.0\ ) |static| :ref:`🔗<class_GutInputFactory_method_action_up>`
|
||||
|
||||
Returns an "action up" `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ instance. ``which`` is the name of the action defined in the Key Map.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_action_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ **action_down**\ (\ which, strength = 1.0\ ) |static| :ref:`🔗<class_GutInputFactory_method_action_down>`
|
||||
|
||||
Returns an "action down" `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ instance. ``which`` is the name of the action defined in the Key Map.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_mouse_left_button_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ **mouse_left_button_down**\ (\ position, global_position = null\ ) |static| :ref:`🔗<class_GutInputFactory_method_mouse_left_button_down>`
|
||||
|
||||
Returns a "button down" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the left mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_mouse_left_button_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ **mouse_left_button_up**\ (\ position, global_position = null\ ) |static| :ref:`🔗<class_GutInputFactory_method_mouse_left_button_up>`
|
||||
|
||||
Returns a "button up" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the left mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_mouse_double_click:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ **mouse_double_click**\ (\ position, global_position = null\ ) |static| :ref:`🔗<class_GutInputFactory_method_mouse_double_click>`
|
||||
|
||||
Returns a "double click" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the left mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_mouse_right_button_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ **mouse_right_button_down**\ (\ position, global_position = null\ ) |static| :ref:`🔗<class_GutInputFactory_method_mouse_right_button_down>`
|
||||
|
||||
Returns a "button down" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the right mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_mouse_right_button_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ **mouse_right_button_up**\ (\ position, global_position = null\ ) |static| :ref:`🔗<class_GutInputFactory_method_mouse_right_button_up>`
|
||||
|
||||
Returns a "button up" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the right mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_mouse_motion:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ **mouse_motion**\ (\ position, global_position = null\ ) |static| :ref:`🔗<class_GutInputFactory_method_mouse_motion>`
|
||||
|
||||
Returns a `InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ to move the mouse the specified positions.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputFactory_method_mouse_relative_motion:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ **mouse_relative_motion**\ (\ offset, last_motion_event = null, speed = Vector2(0, 0)\ ) |static| :ref:`🔗<class_GutInputFactory_method_mouse_relative_motion>`
|
||||
|
||||
Returns an `InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ that moves the mouse ``offset`` from the last :ref:`mouse_motion<class_GutInputFactory_method_mouse_motion>` or :ref:`mouse_motion<class_GutInputFactory_method_mouse_motion>` call.
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
619
addons/gut/documentation/docs/class_ref/class_gutinputsender.rst
Normal file
@@ -0,0 +1,619 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_GutInputSender:
|
||||
|
||||
GutInputSender
|
||||
==============
|
||||
|
||||
**Inherits:** `RefCounted <https://docs.godotengine.org/en/stable/classes/class_refcounted.html>`_
|
||||
|
||||
The GutInputSender class. It sends input to places.
|
||||
|
||||
.. rst-class:: classref-introduction-group
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GUT Wiki: `https://gut.readthedocs.io <https://gut.readthedocs.io>`__\
|
||||
|
||||
See `Mocking-Input <../Mocking-Input.html>`__ for examples.
|
||||
|
||||
|
||||
|
||||
This class can be used to send ``InputEvent*`` events to various objects. It also allows you to script out a series of inputs and play them back in real time. You could use it to:
|
||||
|
||||
- Verify that jump height depends on how long the jump button is pressed.
|
||||
|
||||
- Double tap a direction performs a dash.
|
||||
|
||||
- Down, Down-Forward, Forward + punch throws a fireball.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
And much much more.
|
||||
|
||||
|
||||
|
||||
As of 9.3.1 you can use ``GutInputSender`` instead of ``InputSender``. It's the same thing, but ``GutInputSender`` is a ``class_name`` so you may have less warnings and auto-complete will work.
|
||||
|
||||
|
||||
|
||||
\ **Warning**\
|
||||
|
||||
If you move the Godot window to a different monitor while tests are running it can cause input tests to fail. `This issue <https://github.com/bitwes/Gut/issues/643>`__ has more details.
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------+-----------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_warp<class_GutInputSender_property_mouse_warp>` | ``false`` |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------+-----------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`draw_mouse<class_GutInputSender_property_draw_mouse>` | ``true`` |
|
||||
+--------------------------------------------------------------------------------+-------------------------------------------------------------+-----------+
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`_init<class_GutInputSender_private_method__init>`\ (\ r = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`action_down<class_GutInputSender_method_action_down>`\ (\ which, strength = 1.0\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`action_up<class_GutInputSender_method_action_up>`\ (\ which, strength = 1.0\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`add_receiver<class_GutInputSender_method_add_receiver>`\ (\ obj\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`clear<class_GutInputSender_method_clear>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_auto_flush_input<class_GutInputSender_method_get_auto_flush_input>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_receivers<class_GutInputSender_method_get_receivers>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`hold_for<class_GutInputSender_method_hold_for>`\ (\ duration\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`hold_frames<class_GutInputSender_method_hold_frames>`\ (\ duration\: `int <https://docs.godotengine.org/en/stable/classes/class_int.html>`_\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`hold_seconds<class_GutInputSender_method_hold_seconds>`\ (\ duration\: `float <https://docs.godotengine.org/en/stable/classes/class_float.html>`_\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_action_pressed<class_GutInputSender_method_is_action_pressed>`\ (\ which\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_idle<class_GutInputSender_method_is_idle>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_key_pressed<class_GutInputSender_method_is_key_pressed>`\ (\ which\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_mouse_button_pressed<class_GutInputSender_method_is_mouse_button_pressed>`\ (\ which\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`key_down<class_GutInputSender_method_key_down>`\ (\ which\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`key_echo<class_GutInputSender_method_key_echo>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`key_up<class_GutInputSender_method_key_up>`\ (\ which\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_double_click<class_GutInputSender_method_mouse_double_click>`\ (\ position = null, global_position = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_left_button_down<class_GutInputSender_method_mouse_left_button_down>`\ (\ position = null, global_position = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_left_button_up<class_GutInputSender_method_mouse_left_button_up>`\ (\ position = null, global_position = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_left_click_at<class_GutInputSender_method_mouse_left_click_at>`\ (\ where, duration = "5f"\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_motion<class_GutInputSender_method_mouse_motion>`\ (\ position, global_position = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_relative_motion<class_GutInputSender_method_mouse_relative_motion>`\ (\ offset, speed = Vector2(0, 0)\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_right_button_down<class_GutInputSender_method_mouse_right_button_down>`\ (\ position = null, global_position = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_right_button_up<class_GutInputSender_method_mouse_right_button_up>`\ (\ position = null, global_position = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`mouse_set_position<class_GutInputSender_method_mouse_set_position>`\ (\ position, global_position = null\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`release_all<class_GutInputSender_method_release_all>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`send_event<class_GutInputSender_method_send_event>`\ (\ event\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |void| | :ref:`set_auto_flush_input<class_GutInputSender_method_set_auto_flush_input>`\ (\ val\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`wait<class_GutInputSender_method_wait>`\ (\ t\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`wait_frames<class_GutInputSender_method_wait_frames>`\ (\ num_frames\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`wait_secs<class_GutInputSender_method_wait_secs>`\ (\ num_secs\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Signals
|
||||
-------
|
||||
|
||||
.. _class_GutInputSender_signal_idle:
|
||||
|
||||
.. rst-class:: classref-signal
|
||||
|
||||
**idle**\ (\ ) :ref:`🔗<class_GutInputSender_signal_idle>`
|
||||
|
||||
Emitted when all events in the input queue have been sent.
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. _class_GutInputSender_constant_INPUT_WARN:
|
||||
|
||||
.. rst-class:: classref-constant
|
||||
|
||||
**INPUT_WARN** = ``"If using Input as a reciever it will not respond to *_down events until a *_up event is recieved. Call the appropriate *_up event or use hold_for(...) to automatically release after some duration."`` :ref:`🔗<class_GutInputSender_constant_INPUT_WARN>`
|
||||
|
||||
Local reference to the GutInputFactory static class
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Property Descriptions
|
||||
---------------------
|
||||
|
||||
.. _class_GutInputSender_property_mouse_warp:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_warp** = ``false`` :ref:`🔗<class_GutInputSender_property_mouse_warp>`
|
||||
|
||||
Warp mouse when sending InputEventMouse\* events
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_property_draw_mouse:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **draw_mouse** = ``true`` :ref:`🔗<class_GutInputSender_property_draw_mouse>`
|
||||
|
||||
Draw mouse position cross hairs. Useful to see where the mouse is at when not using :ref:`mouse_warp<class_GutInputSender_property_mouse_warp>`
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_GutInputSender_private_method__init:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **_init**\ (\ r = null\ ) :ref:`🔗<class_GutInputSender_private_method__init>`
|
||||
|
||||
Accepts a single optional receiver.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_add_receiver:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **add_receiver**\ (\ obj\ ) :ref:`🔗<class_GutInputSender_method_add_receiver>`
|
||||
|
||||
Add an object to receive input events.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_get_receivers:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_receivers**\ (\ ) :ref:`🔗<class_GutInputSender_method_get_receivers>`
|
||||
|
||||
Returns the receivers that have been added.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_is_idle:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_idle**\ (\ ) :ref:`🔗<class_GutInputSender_method_is_idle>`
|
||||
|
||||
Returns true if the input queue has items to be processed, false if not.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_is_key_pressed:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_key_pressed**\ (\ which\ ) :ref:`🔗<class_GutInputSender_method_is_key_pressed>`
|
||||
|
||||
.. container:: contribute
|
||||
|
||||
No description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_is_action_pressed:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_action_pressed**\ (\ which\ ) :ref:`🔗<class_GutInputSender_method_is_action_pressed>`
|
||||
|
||||
.. container:: contribute
|
||||
|
||||
No description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_is_mouse_button_pressed:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_mouse_button_pressed**\ (\ which\ ) :ref:`🔗<class_GutInputSender_method_is_mouse_button_pressed>`
|
||||
|
||||
.. container:: contribute
|
||||
|
||||
No description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_get_auto_flush_input:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_auto_flush_input**\ (\ ) :ref:`🔗<class_GutInputSender_method_get_auto_flush_input>`
|
||||
|
||||
Get the value of :ref:`set_auto_flush_input<class_GutInputSender_method_set_auto_flush_input>`.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_set_auto_flush_input:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **set_auto_flush_input**\ (\ val\ ) :ref:`🔗<class_GutInputSender_method_set_auto_flush_input>`
|
||||
|
||||
Enable/Disable auto flushing of input. When enabled the **GutInputSender** will call ``Input.flush_buffered_events`` after each event is sent. See the "use_accumulated_input" section in `Mocking-Input <../Mocking-Input.html>`__ for more information.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_wait:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **wait**\ (\ t\ ) :ref:`🔗<class_GutInputSender_method_wait>`
|
||||
|
||||
Adds a delay between the last input queue item added and any queue item added next. By default this will wait ``t`` seconds. You can specify a number of frames to wait by passing a string composed of a number and "f". For example ``wait("5f")`` will wait 5 frames.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_clear:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
|void| **clear**\ (\ ) :ref:`🔗<class_GutInputSender_method_clear>`
|
||||
|
||||
Clears the input queue and any state such as the last event sent and any pressed actions/buttons. Does not clear the list of receivers.
|
||||
|
||||
|
||||
|
||||
This should be done between each test when the **GutInputSender** is a class level variable so that state does not leak between tests.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_key_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **key_up**\ (\ which\ ) :ref:`🔗<class_GutInputSender_method_key_up>`
|
||||
|
||||
Sends a `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ event with ``pressed = false``. ``which`` can be a character or a ``KEY_*`` constant.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_key_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **key_down**\ (\ which\ ) :ref:`🔗<class_GutInputSender_method_key_down>`
|
||||
|
||||
Sends a `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ event with ``pressed = true``. ``which`` can be a character or a ``KEY_*`` constant.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_key_echo:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **key_echo**\ (\ ) :ref:`🔗<class_GutInputSender_method_key_echo>`
|
||||
|
||||
Sends an echo `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_ event of the last key event.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_action_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **action_up**\ (\ which, strength = 1.0\ ) :ref:`🔗<class_GutInputSender_method_action_up>`
|
||||
|
||||
Sends a "action up" `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ instance. ``which`` is the name of the action defined in the Key Map.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_action_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **action_down**\ (\ which, strength = 1.0\ ) :ref:`🔗<class_GutInputSender_method_action_down>`
|
||||
|
||||
Sends a "action down" `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ instance. ``which`` is the name of the action defined in the Key Map.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_left_button_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_left_button_down**\ (\ position = null, global_position = null\ ) :ref:`🔗<class_GutInputSender_method_mouse_left_button_down>`
|
||||
|
||||
Sends a "button down" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the left mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_left_button_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_left_button_up**\ (\ position = null, global_position = null\ ) :ref:`🔗<class_GutInputSender_method_mouse_left_button_up>`
|
||||
|
||||
Sends a "button up" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the left mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_double_click:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_double_click**\ (\ position = null, global_position = null\ ) :ref:`🔗<class_GutInputSender_method_mouse_double_click>`
|
||||
|
||||
Sends a "double click" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the left mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_right_button_down:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_right_button_down**\ (\ position = null, global_position = null\ ) :ref:`🔗<class_GutInputSender_method_mouse_right_button_down>`
|
||||
|
||||
Sends a "button down" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the right mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_right_button_up:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_right_button_up**\ (\ position = null, global_position = null\ ) :ref:`🔗<class_GutInputSender_method_mouse_right_button_up>`
|
||||
|
||||
Sends a "button up" `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ for the right mouse button.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_motion:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_motion**\ (\ position, global_position = null\ ) :ref:`🔗<class_GutInputSender_method_mouse_motion>`
|
||||
|
||||
Sends a `InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ to move the mouse the specified positions.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_relative_motion:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_relative_motion**\ (\ offset, speed = Vector2(0, 0)\ ) :ref:`🔗<class_GutInputSender_method_mouse_relative_motion>`
|
||||
|
||||
Sends a `InputEventMouseMotion <https://docs.godotengine.org/en/stable/classes/class_inputeventmousemotion.html>`_ that moves the mouse ``offset`` from the last :ref:`mouse_motion<class_GutInputSender_method_mouse_motion>` or :ref:`mouse_set_position<class_GutInputSender_method_mouse_set_position>` call.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_set_position:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_set_position**\ (\ position, global_position = null\ ) :ref:`🔗<class_GutInputSender_method_mouse_set_position>`
|
||||
|
||||
Sets the mouse's position. This does not send an event. This position will be used for the next call to :ref:`mouse_relative_motion<class_GutInputSender_method_mouse_relative_motion>`.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_mouse_left_click_at:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **mouse_left_click_at**\ (\ where, duration = "5f"\ ) :ref:`🔗<class_GutInputSender_method_mouse_left_click_at>`
|
||||
|
||||
Performs a left click at the given position.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_send_event:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **send_event**\ (\ event\ ) :ref:`🔗<class_GutInputSender_method_send_event>`
|
||||
|
||||
Create your own event and use this to send it to all receivers.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_release_all:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **release_all**\ (\ ) :ref:`🔗<class_GutInputSender_method_release_all>`
|
||||
|
||||
Releases all `InputEventKey <https://docs.godotengine.org/en/stable/classes/class_inputeventkey.html>`_, `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_, and `InputEventMouseButton <https://docs.godotengine.org/en/stable/classes/class_inputeventmousebutton.html>`_ events that have passed through this instance. These events could have been generated via the various ``_down`` methods or passed to :ref:`send_event<class_GutInputSender_method_send_event>`.
|
||||
|
||||
|
||||
|
||||
This will send the "release" event (``pressed = false``) to all receivers. This should be done between each test when using `Input` as a receiver.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_wait_frames:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **wait_frames**\ (\ num_frames\ ) :ref:`🔗<class_GutInputSender_method_wait_frames>`
|
||||
|
||||
Same as :ref:`wait<class_GutInputSender_method_wait>` but only accepts a number of frames to wait.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_wait_secs:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **wait_secs**\ (\ num_secs\ ) :ref:`🔗<class_GutInputSender_method_wait_secs>`
|
||||
|
||||
Same as :ref:`wait<class_GutInputSender_method_wait>` but only accepts a number of seconds to wait.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_hold_for:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **hold_for**\ (\ duration\ ) :ref:`🔗<class_GutInputSender_method_hold_for>`
|
||||
|
||||
This is a special :ref:`wait<class_GutInputSender_method_wait>` that will emit the previous input queue item with ``pressed = false`` after a delay. If you pass a number then it will wait that many seconds. You can also use the `"4f"` format to wait a specific number of frames.
|
||||
|
||||
|
||||
|
||||
For example ``sender.action_down('jump').hold_for("10f")`` will cause two `InputEventAction <https://docs.godotengine.org/en/stable/classes/class_inputeventaction.html>`_ instances to be sent. The "jump-down" event from :ref:`action_down<class_GutInputSender_method_action_down>` and then a "jump-up" event after 10 frames.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_hold_frames:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **hold_frames**\ (\ duration\: `int <https://docs.godotengine.org/en/stable/classes/class_int.html>`_\ ) :ref:`🔗<class_GutInputSender_method_hold_frames>`
|
||||
|
||||
Same as :ref:`hold_for<class_GutInputSender_method_hold_for>` but specifically holds for a number of physics frames.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutInputSender_method_hold_seconds:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **hold_seconds**\ (\ duration\: `float <https://docs.godotengine.org/en/stable/classes/class_float.html>`_\ ) :ref:`🔗<class_GutInputSender_method_hold_seconds>`
|
||||
|
||||
Same as :ref:`hold_for<class_GutInputSender_method_hold_for>` but specifically holds for a number of seconds.
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
223
addons/gut/documentation/docs/class_ref/class_gutmain.rst
Normal file
@@ -0,0 +1,223 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_GutMain:
|
||||
|
||||
GutMain
|
||||
=======
|
||||
|
||||
**Inherits:** addons/gut/gut_to_move.gd
|
||||
|
||||
The GUT brains.
|
||||
|
||||
.. rst-class:: classref-introduction-group
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Most of this class is for internal use only. Features that can be used have descriptions and can be accessed through the :ref:`GutTest.gut<class_GutTest_property_gut>` variable in your test scripts (extends :ref:`GutTest<class_GutTest>`). The wiki page for this class contains only the usable features.
|
||||
|
||||
|
||||
|
||||
GUT Wiki: `https://gut.readthedocs.io <https://gut.readthedocs.io>`__
|
||||
|
||||
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------+----------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`log_level<class_GutMain_property_log_level>` | ``_log_level`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------+----------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`wait_log_delay<class_GutMain_property_wait_log_delay>` | ``0.5`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------+----------------+
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_assert_count<class_GutMain_method_get_assert_count>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_fail_count<class_GutMain_method_get_fail_count>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_pass_count<class_GutMain_method_get_pass_count>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_pending_count<class_GutMain_method_get_pending_count>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_summary<class_GutMain_method_get_summary>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_test_script_count<class_GutMain_method_get_test_script_count>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Signals
|
||||
-------
|
||||
|
||||
.. _class_GutMain_signal_start_script:
|
||||
|
||||
.. rst-class:: classref-signal
|
||||
|
||||
**start_script**\ (\ test_script_obj\ ) :ref:`🔗<class_GutMain_signal_start_script>`
|
||||
|
||||
Emitted before every test script instance is created. Emitted before :ref:`GutTest.before_all<class_GutTest_method_before_all>` hook on test is run. test_script_obj is an instance of addons/gut/collected_script.gd.
|
||||
|
||||
.. _class_GutMain_signal_end_script:
|
||||
|
||||
.. rst-class:: classref-signal
|
||||
|
||||
**end_script**\ (\ ) :ref:`🔗<class_GutMain_signal_end_script>`
|
||||
|
||||
Emitted after every test script is run. Emitted after :ref:`GutTest.after_all<class_GutTest_method_after_all>` hook on test is run.
|
||||
|
||||
.. _class_GutMain_signal_start_test:
|
||||
|
||||
.. rst-class:: classref-signal
|
||||
|
||||
**start_test**\ (\ test_name\ ) :ref:`🔗<class_GutMain_signal_start_test>`
|
||||
|
||||
Emitted before every test method is run. Emitted after :ref:`GutTest.before_each<class_GutTest_method_before_each>` hook on test is run. test_name is the string name of the current test about to be started.
|
||||
|
||||
.. _class_GutMain_signal_end_test:
|
||||
|
||||
.. rst-class:: classref-signal
|
||||
|
||||
**end_test**\ (\ ) :ref:`🔗<class_GutMain_signal_end_test>`
|
||||
|
||||
Emitted after every test method is run. Emitted after :ref:`GutTest.after_each<class_GutTest_method_after_each>` hook on test is run.
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Property Descriptions
|
||||
---------------------
|
||||
|
||||
.. _class_GutMain_property_log_level:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **log_level** = ``_log_level`` :ref:`🔗<class_GutMain_property_log_level>`
|
||||
|
||||
.. rst-class:: classref-property-setget
|
||||
|
||||
- |void| **@log_level_setter**\ (\ value\ )
|
||||
- `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **@log_level_getter**\ (\ )
|
||||
|
||||
The log detail level. Valid values are 0 - 2. Larger values do not matter.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutMain_property_wait_log_delay:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **wait_log_delay** = ``0.5`` :ref:`🔗<class_GutMain_property_wait_log_delay>`
|
||||
|
||||
The amount of time that must elapse before an "Awaiting" message is printed.
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_GutMain_method_get_assert_count:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_assert_count**\ (\ ) :ref:`🔗<class_GutMain_method_get_assert_count>`
|
||||
|
||||
Get the number of assertions that were made
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutMain_method_get_pass_count:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_pass_count**\ (\ ) :ref:`🔗<class_GutMain_method_get_pass_count>`
|
||||
|
||||
Get the number of assertions that passed
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutMain_method_get_fail_count:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_fail_count**\ (\ ) :ref:`🔗<class_GutMain_method_get_fail_count>`
|
||||
|
||||
Get the number of assertions that failed
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutMain_method_get_pending_count:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_pending_count**\ (\ ) :ref:`🔗<class_GutMain_method_get_pending_count>`
|
||||
|
||||
Get the number of tests flagged as pending
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutMain_method_get_summary:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_summary**\ (\ ) :ref:`🔗<class_GutMain_method_get_summary>`
|
||||
|
||||
Returns a summary.gd object that contains all the information about the run results.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutMain_method_get_test_script_count:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_test_script_count**\ (\ ) :ref:`🔗<class_GutMain_method_get_test_script_count>`
|
||||
|
||||
Returns the number of test scripts. Inner Test classes each count as a script.
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
2896
addons/gut/documentation/docs/class_ref/class_guttest.rst
Normal file
@@ -0,0 +1,284 @@
|
||||
:github_url: hide
|
||||
|
||||
.. DO NOT EDIT THIS FILE!!!
|
||||
.. Generated automatically from GUT Plugin sources.
|
||||
.. Generator: documentation/godot_make_rst.py.
|
||||
.. _class_GutTrackedError:
|
||||
|
||||
GutTrackedError
|
||||
===============
|
||||
|
||||
**Inherits:** `RefCounted <https://docs.godotengine.org/en/stable/classes/class_refcounted.html>`_
|
||||
|
||||
This contains all the information provided by Godot about an error. This is also used to represent a GUT error. See `Logger <https://docs.godotengine.org/en/stable/classes/class_logger.html>`_ for additional information about properties. Some properties are not populated for GUT errors.
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`backtrace<class_GutTrackedError_property_backtrace>` | ``[]`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`code<class_GutTrackedError_property_code>` | ``"NONE"`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`rationale<class_GutTrackedError_property_rationale>` | ``"NONE"`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`error_type<class_GutTrackedError_property_error_type>` | ``-1`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`editor_notify<class_GutTrackedError_property_editor_notify>` | ``false`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`file<class_GutTrackedError_property_file>` | ``"NONE"`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`function<class_GutTrackedError_property_function>` | ``"NONE"`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`line<class_GutTrackedError_property_line>` | ``-1`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`handled<class_GutTrackedError_property_handled>` | ``false`` |
|
||||
+--------------------------------------------------------------------------------+--------------------------------------------------------------------+------------+
|
||||
|
||||
.. rst-class:: classref-reftable-group
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. table::
|
||||
:widths: auto
|
||||
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`contains_text<class_GutTrackedError_method_contains_text>`\ (\ text\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`get_error_type_name<class_GutTrackedError_method_get_error_type_name>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_engine_error<class_GutTrackedError_method_is_engine_error>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_gut_error<class_GutTrackedError_method_is_gut_error>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_push_error<class_GutTrackedError_method_is_push_error>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
| `Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ | :ref:`is_push_warning<class_GutTrackedError_method_is_push_warning>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
| `String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ | :ref:`to_s<class_GutTrackedError_method_to_s>`\ (\ ) |
|
||||
+--------------------------------------------------------------------------------+------------------------------------------------------------------------------------+
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Property Descriptions
|
||||
---------------------
|
||||
|
||||
.. _class_GutTrackedError_property_backtrace:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **backtrace** = ``[]`` :ref:`🔗<class_GutTrackedError_property_backtrace>`
|
||||
|
||||
This will be an ``Array[ScriptBacktrace]`` for engine/push errors. This will the result of ``get_stack`` for GUT errors.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_code:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **code** = ``"NONE"`` :ref:`🔗<class_GutTrackedError_property_code>`
|
||||
|
||||
Usually the description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_rationale:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **rationale** = ``"NONE"`` :ref:`🔗<class_GutTrackedError_property_rationale>`
|
||||
|
||||
.. container:: contribute
|
||||
|
||||
No description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_error_type:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **error_type** = ``-1`` :ref:`🔗<class_GutTrackedError_property_error_type>`
|
||||
|
||||
`Logger.ErrorType <https://docs.godotengine.org/en/stable/classes/class_logger.html>`_ value or, for GUT errors, this will be ``GutUtils.GUT_ERROR_TYPE``.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_editor_notify:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **editor_notify** = ``false`` :ref:`🔗<class_GutTrackedError_property_editor_notify>`
|
||||
|
||||
.. container:: contribute
|
||||
|
||||
No description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_file:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **file** = ``"NONE"`` :ref:`🔗<class_GutTrackedError_property_file>`
|
||||
|
||||
The full path to the file where the error occurred.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_function:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **function** = ``"NONE"`` :ref:`🔗<class_GutTrackedError_property_function>`
|
||||
|
||||
The function name in :ref:`file<class_GutTrackedError_property_file>` where the error occurred.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_line:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **line** = ``-1`` :ref:`🔗<class_GutTrackedError_property_line>`
|
||||
|
||||
The line number in :ref:`file<class_GutTrackedError_property_file>`
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_property_handled:
|
||||
|
||||
.. rst-class:: classref-property
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **handled** = ``false`` :ref:`🔗<class_GutTrackedError_property_handled>`
|
||||
|
||||
Used by GUT to flag errors as being handled. This is set by various asserts or can be set in a test. When set to ``true`` GUT will ignore it when determining if an unexpected error occurred during the execution of the test. Setting this value prior to performing any of the error related asserts may have unexpected results. It is recommended you either set this manually or use the error asserts.
|
||||
|
||||
.. rst-class:: classref-section-separator
|
||||
|
||||
----
|
||||
|
||||
.. rst-class:: classref-descriptions-group
|
||||
|
||||
Method Descriptions
|
||||
-------------------
|
||||
|
||||
.. _class_GutTrackedError_method_to_s:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`String <https://docs.godotengine.org/en/stable/classes/class_string.html>`_ **to_s**\ (\ ) :ref:`🔗<class_GutTrackedError_method_to_s>`
|
||||
|
||||
_to_string that is not _to_string.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_method_is_push_error:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_push_error**\ (\ ) :ref:`🔗<class_GutTrackedError_method_is_push_error>`
|
||||
|
||||
Returns ``true`` if the error is a push_error.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_method_is_engine_error:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_engine_error**\ (\ ) :ref:`🔗<class_GutTrackedError_method_is_engine_error>`
|
||||
|
||||
Returns ``true`` if the error is an engine error. This includes all errors that pass through the `Logger <https://docs.godotengine.org/en/stable/classes/class_logger.html>`_ that do not originate from the ``push_error`` function.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_method_is_push_warning:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_push_warning**\ (\ ) :ref:`🔗<class_GutTrackedError_method_is_push_warning>`
|
||||
|
||||
.. container:: contribute
|
||||
|
||||
No description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_method_is_gut_error:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **is_gut_error**\ (\ ) :ref:`🔗<class_GutTrackedError_method_is_gut_error>`
|
||||
|
||||
Returns ``true`` if the error is a GUT error. Some fields may not be populated for GUT errors.
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_method_contains_text:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **contains_text**\ (\ text\ ) :ref:`🔗<class_GutTrackedError_method_contains_text>`
|
||||
|
||||
.. container:: contribute
|
||||
|
||||
No description
|
||||
|
||||
.. rst-class:: classref-item-separator
|
||||
|
||||
----
|
||||
|
||||
.. _class_GutTrackedError_method_get_error_type_name:
|
||||
|
||||
.. rst-class:: classref-method
|
||||
|
||||
`Variant <https://docs.godotengine.org/en/stable/classes/class_variant.html>`_ **get_error_type_name**\ (\ ) :ref:`🔗<class_GutTrackedError_method_get_error_type_name>`
|
||||
|
||||
For display purposes only, the actual value returned may change over time. This returns a name for the error_type as far as this class is concerned. Use the various ``is_`` methods to check if an error is a certain type.
|
||||
|
||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
||||
.. |void| replace:: :abbr:`void (No return value.)`
|
||||
57
addons/gut/documentation/docs/conf.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
|
||||
# -- Project information
|
||||
|
||||
project = 'GUT'
|
||||
copyright = '2024, Butch Wesley'
|
||||
author = 'bitwes'
|
||||
|
||||
release = '9.6.0'
|
||||
version = '9.6.0 for Godot-4'
|
||||
|
||||
# -- General configuration
|
||||
|
||||
|
||||
extensions = [
|
||||
'sphinx.ext.duration',
|
||||
'sphinx.ext.doctest',
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.autosummary',
|
||||
'sphinx.ext.intersphinx',
|
||||
'myst_parser',
|
||||
'sphinx_rtd_dark_mode',
|
||||
]
|
||||
|
||||
intersphinx_mapping = {
|
||||
'python': ('https://docs.python.org/3/', None),
|
||||
'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
|
||||
}
|
||||
intersphinx_disabled_domains = ['std']
|
||||
|
||||
templates_path = ['_templates']
|
||||
|
||||
# -- Options for HTML output
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# -- Options for EPUB output
|
||||
epub_show_urls = 'footnote'
|
||||
|
||||
source_suffix = [
|
||||
".md",
|
||||
".rst",
|
||||
]
|
||||
|
||||
html_static_path = ['_static']
|
||||
|
||||
# custom.css copied from Godot's CSS:
|
||||
# https://github.com/godotengine/godot-docs/blob/4.2/_static/css/custom.css
|
||||
html_css_files = [
|
||||
'css/gut_custom.css'
|
||||
]
|
||||
|
||||
html_js_files = [
|
||||
]
|
||||
|
||||
html_favicon = 'favicon.ico'
|
||||
html_logo = '_static/images/GutDocsLogo.png'
|
||||
BIN
addons/gut/documentation/docs/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
148
addons/gut/documentation/docs/index.rst
Normal file
@@ -0,0 +1,148 @@
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 3
|
||||
:caption: Getting Started
|
||||
:name: sec-started
|
||||
|
||||
Install
|
||||
Quick-Start
|
||||
Command-Line
|
||||
New-For-Godot-4
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 3
|
||||
:caption: Test Scripts
|
||||
:name: sec-guttest
|
||||
|
||||
Creating-Tests
|
||||
Awaiting
|
||||
Inner-Test-Classes
|
||||
Error-Tracking
|
||||
Parameterized-Tests
|
||||
Simulate
|
||||
Comparing-Things
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Doubling
|
||||
:name: sec-doubles
|
||||
|
||||
Doubles
|
||||
Partial-Doubles
|
||||
Double-Strategy
|
||||
Stubbing
|
||||
Spies
|
||||
Doubling-Singletons
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Other
|
||||
:name: sec-other
|
||||
|
||||
Export-Test-Results
|
||||
Hooks
|
||||
Global-Lifecycle-Hooks
|
||||
Memory-Management
|
||||
Mocking-Input
|
||||
Running-On-Devices
|
||||
GDScript-Warnings
|
||||
Contributing
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Class Reference
|
||||
:name: class-ref
|
||||
:glob:
|
||||
|
||||
Class-Ref
|
||||
class_ref/*
|
||||
|
||||
|
||||
|
||||
|
||||
Gut 9.6.0 (Godot 4.6)
|
||||
=========
|
||||
|
||||
|
||||
GUT/Godot Versions
|
||||
------------------
|
||||
There are only two versions of GUT in the Asset Library. GUT 9 requires Godot 4. GUT 7 requires Godot 3.4. GUT will not appear in the Asset Library if your current version of Godot is less than GUT's required version.
|
||||
|
||||
The Godot/GUT version list and download links can be found in the repo README https://github.com/bitwes/Gut/blob/main/README.md
|
||||
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
|
||||
* :doc:`Quick-Start <Quick-Start>`
|
||||
* :doc:`Install <Install>`
|
||||
* :doc:`GutTest Class <class_ref/class_guttest>`
|
||||
* :doc:`Creating Tests <Creating-Tests>`
|
||||
* :doc:`Using Gut at the command line <Command-Line>`
|
||||
|
||||
|
||||
Advanced Testing
|
||||
----------------
|
||||
|
||||
* :doc:`Inner Test Classes <Inner-Test-Classes>`
|
||||
* :doc:`Doubling <Doubles>`
|
||||
* :doc:`Spies <Spies>`
|
||||
* :doc:`Stubbing <Stubbing>`
|
||||
* :doc:`Parameterized Tests <Parameterized-Tests>`
|
||||
* :doc:`Simulate <Simulate>`
|
||||
* :doc:`Coroutines and await in tests <Awaiting>`
|
||||
* :doc:`Pre/Post Run Hooks <Hooks>`
|
||||
* :doc:`Exporting Results <Export-Test-Results>`
|
||||
* :doc:`Error Tracking <Error-Tracking>`
|
||||
|
||||
|
||||
Editor GUI
|
||||
----------
|
||||
|
||||
.. image:: _static/images/gut_panel.png
|
||||
|
||||
GUT GUI
|
||||
-------
|
||||
|
||||
Normal
|
||||
|
||||
.. image:: _static/images/GutGui.png
|
||||
|
||||
Compact
|
||||
|
||||
.. image:: _static/images/GuiCompact.png
|
||||
|
||||
Engine Warnings
|
||||
---------------
|
||||
|
||||
There are a fair number of warnings that Godot will show related to GUT. Some of the warnings are valid and are being cleaned up overtime. Most of the warnings are not valid and sometimes relate to generated code. As of 3.2 you can disable warnings for addons, and it recommended you do so.
|
||||
|
||||
.. image:: _static/images/exclude_addons.png
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Gut is provided under the MIT license. [The license is distributed with Gut so it is in the `addons/gut` folder](https://github.com/bitwes/Gut/blob/master/addons/gut/LICENSE.md).
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
:doc:`Contributing <Contributing>`
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
||||