/**************************************************************************/1/* signal_watcher.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/object/object.h"33#include "tests/test_macros.h"3435// Utility class / macros for testing signals36//37// Use SIGNAL_WATCH(*object, "signal_name") to start watching38// Makes sure to call SIGNAL_UNWATCH(*object, "signal_name") to stop watching in cleanup, this is not done automatically.39//40// The SignalWatcher will capture all signals and their args sent between checks.41//42// Use SIGNAL_CHECK("signal_name"), Vector<Vector<Variant>>), to check the arguments of all fired signals.43// The outer vector is each fired signal, the inner vector the list of arguments for that signal. Order does matter.44//45// Use SIGNAL_CHECK_FALSE("signal_name") to check if a signal was not fired.46//47// Use SIGNAL_DISCARD("signal_name") to discard records all of the given signal, use only in placed you don't need to check.48//49// All signals are automatically discarded between test/sub test cases.5051class SignalWatcher : public Object {52inline static SignalWatcher *singleton = nullptr;5354HashMap<String, Array> _signals;5556void _add_signal_entry(const Array &p_args, const String &p_name);57void _signal_callback_zero(const String &p_name);58void _signal_callback_one(Variant p_arg1, const String &p_name);59void _signal_callback_two(Variant p_arg1, Variant p_arg2, const String &p_name);60void _signal_callback_three(Variant p_arg1, Variant p_arg2, Variant p_arg3, const String &p_name);6162public:63static SignalWatcher *get_singleton() { return singleton; }6465void watch_signal(Object *p_object, const String &p_signal);66void unwatch_signal(Object *p_object, const String &p_signal);67bool check(const String &p_name, const Array &p_args);68bool check_false(const String &p_name);69void discard_signal(const String &p_name);7071void _clear_signals();7273SignalWatcher();74~SignalWatcher();75};7677#define SIGNAL_WATCH(m_object, m_signal) SignalWatcher::get_singleton()->watch_signal(m_object, m_signal);78#define SIGNAL_UNWATCH(m_object, m_signal) SignalWatcher::get_singleton()->unwatch_signal(m_object, m_signal);7980#define SIGNAL_CHECK(m_signal, m_args) CHECK(SignalWatcher::get_singleton()->check(m_signal, m_args));81#define SIGNAL_CHECK_FALSE(m_signal) CHECK(SignalWatcher::get_singleton()->check_false(m_signal));82#define SIGNAL_DISCARD(m_signal) SignalWatcher::get_singleton()->discard_signal(m_signal);838485