1/*
2 * Copyright 2018, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Augustin Cavalier <waddlesplash>
7 */
8#include "../common.h"
9
10
11#include <Application.h>
12#include <String.h>
13#include <Menu.h>
14#include <MenuItem.h>
15#include <PopUpMenu.h>
16
17
18class MenuTestcase : public TestCase {
19public:
20	void
21	SizeTest()
22	{
23		CPPUNIT_ASSERT_EQUAL(312, sizeof(BMenu));
24		CPPUNIT_ASSERT_EQUAL(128, sizeof(BMenuItem));
25	}
26
27	void
28	ConcurrencyAbuseTest()
29	{
30		BApplication app("application/x-vnd.Haiku-interfacekit-menutest");
31		BPopUpMenu* menu = new BPopUpMenu("Test");
32		menu->AddItem(new BMenuItem("One", NULL));
33		menu->AddItem(new BMenuItem("Two", NULL));
34		menu->AddSeparatorItem();
35
36		BMenuItem* items[10];
37		for (int i = 0; i < 10; i++) {
38			BString str;
39			str.SetToFormat("%d", i);
40			items[i] = new BMenuItem(str.String(), NULL);
41		}
42
43		// Now for the actual abuse.
44		menu->Go(BPoint(), false, true, true);
45		snooze(50 * 1000 /* 50 ms */);
46		for (int i = 0; i < 100; i++) {
47			for (int j = 0; j < (i % 5); j++) {
48				BMenuItem* item = items[(i + j) % 10];
49				if (item->Menu() != NULL)
50					continue;
51				menu->AddItem(item);
52			}
53			if ((i % 3) == 0) {
54				for (int j = 0; j < (i % 5); j++)
55					menu->RemoveItem((int32)0);
56			}
57		}
58
59		CPPUNIT_ASSERT_EQUAL(6, menu->CountItems());
60
61		// Cleanup.
62		for (int i = 0; i < 10; i++)
63			delete items[i];
64
65		// Close the menu.
66		char bytes[] = {B_ESCAPE};
67		menu->KeyDown(bytes, 1);
68		delete menu;
69	}
70};
71
72
73Test*
74MenuTestSuite()
75{
76	TestSuite* testSuite = new TestSuite();
77
78	testSuite->addTest(new CppUnit::TestCaller<MenuTestcase>(
79		"BMenu_Size", &MenuTestcase::SizeTest));
80	testSuite->addTest(new CppUnit::TestCaller<MenuTestcase>(
81		"BMenu_ConcurrencyAbuse", &MenuTestcase::ConcurrencyAbuseTest));
82
83	return testSuite;
84}
85