@@ -155,4 +155,222 @@ TEST_CASE("[ProjectSettings] localize_path") {
155155	TestProjectSettingsInternalsAccessor::resource_path () = old_resource_path;
156156}
157157
158+ TEST_CASE (" [SceneTree][ProjectSettings] settings_changed signal"  ) {
159+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
160+ 
161+ 	ProjectSettings::get_singleton ()->set_setting (" test_signal_setting"  , " test_value"  );
162+ 	MessageQueue::get_singleton ()->flush ();
163+ 
164+ 	SIGNAL_CHECK (" settings_changed"  , { {} });
165+ 
166+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
167+ }
168+ 
169+ TEST_CASE (" [SceneTree][ProjectSettings] setting_changed signal for new setting"  ) {
170+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
171+ 
172+ 	String setting_name = " test_new_setting"  ;
173+ 	String new_value = " new_value"  ;
174+ 
175+ 	CHECK_FALSE (ProjectSettings::get_singleton ()->has_setting (setting_name));
176+ 
177+ 	SIGNAL_DISCARD (" setting_changed"  );
178+ 
179+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, new_value);
180+ 	MessageQueue::get_singleton ()->flush ();
181+ 
182+ 	Array expected_args;
183+ 	expected_args.push_back (StringName (setting_name));
184+ 	expected_args.push_back (Variant ());
185+ 	expected_args.push_back (new_value);
186+ 	Array signal_args;
187+ 	signal_args.push_back (expected_args);
188+ 	SIGNAL_CHECK (" setting_changed"  , signal_args);
189+ 
190+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
191+ }
192+ 
193+ TEST_CASE (" [SceneTree][ProjectSettings] setting_changed signal with parameters"  ) {
194+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
195+ 
196+ 	String setting_name = " test_old_value_signal"  ;
197+ 	String old_value = " old_value"  ;
198+ 	String new_value = " new_value"  ;
199+ 
200+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, old_value);
201+ 	MessageQueue::get_singleton ()->flush ();
202+ 
203+ 	SIGNAL_DISCARD (" setting_changed"  );
204+ 
205+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, new_value);
206+ 	MessageQueue::get_singleton ()->flush ();
207+ 
208+ 	Array expected_args;
209+ 	expected_args.push_back (StringName (setting_name));
210+ 	expected_args.push_back (old_value);
211+ 	expected_args.push_back (new_value);
212+ 	Array signal_args;
213+ 	signal_args.push_back (expected_args);
214+ 	SIGNAL_CHECK (" setting_changed"  , signal_args);
215+ 
216+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
217+ }
218+ 
219+ TEST_CASE (" [SceneTree][ProjectSettings] setting_changed signal for setting removal"  ) {
220+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
221+ 
222+ 	String setting_name = " test_removal_setting"  ;
223+ 	String initial_value = " initial_value"  ;
224+ 
225+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, initial_value);
226+ 	MessageQueue::get_singleton ()->flush ();
227+ 	SIGNAL_DISCARD (" setting_changed"  );
228+ 
229+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, Variant ());
230+ 	MessageQueue::get_singleton ()->flush ();
231+ 
232+ 	Array expected_args;
233+ 	expected_args.push_back (StringName (setting_name));
234+ 	expected_args.push_back (initial_value);
235+ 	expected_args.push_back (Variant ());
236+ 	Array signal_args;
237+ 	signal_args.push_back (expected_args);
238+ 	SIGNAL_CHECK (" setting_changed"  , signal_args);
239+ 
240+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
241+ }
242+ 
243+ TEST_CASE (" [SceneTree][ProjectSettings] Both signals emitted together"  ) {
244+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
245+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
246+ 
247+ 	String setting_name = " test_both_signals"  ;
248+ 	String old_value = " old_both"  ;
249+ 	String new_value = " new_both"  ;
250+ 
251+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, old_value);
252+ 	MessageQueue::get_singleton ()->flush ();
253+ 	SIGNAL_DISCARD (" settings_changed"  );
254+ 	SIGNAL_DISCARD (" setting_changed"  );
255+ 
256+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, new_value);
257+ 	MessageQueue::get_singleton ()->flush ();
258+ 
259+ 	SIGNAL_CHECK (" settings_changed"  , { {} });
260+ 
261+ 	Array expected_args;
262+ 	expected_args.push_back (StringName (setting_name));
263+ 	expected_args.push_back (old_value);
264+ 	expected_args.push_back (new_value);
265+ 	Array signal_args;
266+ 	signal_args.push_back (expected_args);
267+ 	SIGNAL_CHECK (" setting_changed"  , signal_args);
268+ 
269+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
270+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
271+ }
272+ 
273+ TEST_CASE (" [SceneTree][ProjectSettings] No signals when setting same value"  ) {
274+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
275+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
276+ 
277+ 	String setting_name = " test_same_value"  ;
278+ 	String test_value = " same_value"  ;
279+ 
280+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, test_value);
281+ 	MessageQueue::get_singleton ()->flush ();
282+ 	SIGNAL_DISCARD (" settings_changed"  );
283+ 	SIGNAL_DISCARD (" setting_changed"  );
284+ 
285+ 	//  Set the same value again. This should not trigger any signals.
286+ 	ProjectSettings::get_singleton ()->set_setting (setting_name, test_value);
287+ 	MessageQueue::get_singleton ()->flush ();
288+ 
289+ 	SIGNAL_CHECK_FALSE (" settings_changed"  );
290+ 	SIGNAL_CHECK_FALSE (" setting_changed"  );
291+ 
292+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
293+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
294+ }
295+ 
296+ TEST_CASE (" [SceneTree][ProjectSettings] Multiple setting changes in same frame"  ) {
297+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
298+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
299+ 
300+ 	SIGNAL_DISCARD (" settings_changed"  );
301+ 	SIGNAL_DISCARD (" setting_changed"  );
302+ 
303+ 	//  Change multiple settings in the same frame,
304+ 	ProjectSettings::get_singleton ()->set_setting (" setting_1"  , " value_1"  );
305+ 	ProjectSettings::get_singleton ()->set_setting (" setting_2"  , " value_2"  );
306+ 
307+ 	MessageQueue::get_singleton ()->flush ();
308+ 
309+ 	Array expected_args1;
310+ 	expected_args1.push_back (StringName (" setting_1"  ));
311+ 	expected_args1.push_back (Variant ());
312+ 	expected_args1.push_back (" value_1"  );
313+ 
314+ 	Array expected_args2;
315+ 	expected_args2.push_back (StringName (" setting_2"  ));
316+ 	expected_args2.push_back (Variant ());
317+ 	expected_args2.push_back (" value_2"  );
318+ 
319+ 	Array all_signal_args;
320+ 	all_signal_args.push_back (expected_args1);
321+ 	all_signal_args.push_back (expected_args2);
322+ 
323+ 	//  Should have 2 setting_changed signals.
324+ 	SIGNAL_CHECK (" setting_changed"  , all_signal_args);
325+ 	//  Should have 1 settings_changed signal.
326+ 	SIGNAL_CHECK (" settings_changed"  , { {} });
327+ 
328+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
329+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
330+ }
331+ 
332+ TEST_CASE (" [SceneTree][ProjectSettings] Multiple changes to the same setting only fire for actual changes"  ) {
333+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
334+ 	SIGNAL_WATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
335+ 
336+ 	SIGNAL_DISCARD (" settings_changed"  );
337+ 	SIGNAL_DISCARD (" setting_changed"  );
338+ 
339+ 	//  Change setting multiple times in the same frame.
340+ 	ProjectSettings::get_singleton ()->set_setting (" reused_setting"  , " value_1"  );
341+ 	ProjectSettings::get_singleton ()->set_setting (" reused_setting"  , " value_2"  );
342+ 	ProjectSettings::get_singleton ()->set_setting (" reused_setting"  , " value_2"  );
343+ 	ProjectSettings::get_singleton ()->set_setting (" reused_setting"  , " value_3"  );
344+ 
345+ 	MessageQueue::get_singleton ()->flush ();
346+ 
347+ 	Array expected_args1;
348+ 	expected_args1.push_back (StringName (" reused_setting"  ));
349+ 	expected_args1.push_back (Variant ());
350+ 	expected_args1.push_back (" value_1"  );
351+ 
352+ 	Array expected_args2;
353+ 	expected_args2.push_back (StringName (" reused_setting"  ));
354+ 	expected_args2.push_back (" value_1"  );
355+ 	expected_args2.push_back (" value_2"  );
356+ 
357+ 	Array expected_args3;
358+ 	expected_args3.push_back (StringName (" reused_setting"  ));
359+ 	expected_args3.push_back (" value_2"  );
360+ 	expected_args3.push_back (" value_3"  );
361+ 
362+ 	Array all_signal_args;
363+ 	all_signal_args.push_back (expected_args1);
364+ 	all_signal_args.push_back (expected_args2);
365+ 	all_signal_args.push_back (expected_args3);
366+ 
367+ 	//  Should have 3 setting_changed signals as the duplicate value_2 should be ignored.
368+ 	SIGNAL_CHECK (" setting_changed"  , all_signal_args);
369+ 	//  Should have 1 settings_changed signal.
370+ 	SIGNAL_CHECK (" settings_changed"  , { {} });
371+ 
372+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" settings_changed"  ));
373+ 	SIGNAL_UNWATCH (ProjectSettings::get_singleton (), SNAME (" setting_changed"  ));
374+ }
375+ 
158376} //  namespace TestProjectSettings
0 commit comments