33
44#include < gtest/gtest.h>
55#include " MenuManager.h"
6+ #include < Notepad_plus_msgs.h>
67
78namespace NppPythonScript
89{
9-
10+
11+ static volatile HMENU g_hPluginMenu;
12+
13+ static LRESULT dummyWindowProc (HWND /* hWnd */ , UINT message, WPARAM /* wParam */ , LPARAM /* lParam */ )
14+ {
15+ switch (message)
16+ {
17+ case WM_CREATE:
18+ return FALSE ;
19+
20+ case NPPM_GETMENUHANDLE:
21+ return reinterpret_cast <LRESULT>(g_hPluginMenu);
22+
23+ default :
24+ return TRUE ;
25+ }
26+ }
27+
28+
29+ #define UNIT_TEST_WINDOW_CLASS L" UnitTestDummy"
30+
31+
32+ enum MenuIds {
33+ MENUID_FILE_OPEN = 1000 ,
34+ MENUID_FILE_CLOSE,
35+ MENUID_FILE_RECENT,
36+ MENUID_FILE_EXIT,
37+ MENUID_FILE_RECENT_1,
38+ MENUID_FILE_RECENT_2,
39+ MENUID_FILE_RECENT_3,
40+ MENUID_EDIT_COPY,
41+ MENUID_EDIT_PASTE,
42+ MENUID_XMLTOOLS_PRETTYPRINT,
43+ MENUID_XMLTOOLS_OPEN,
44+ MENUID_XMLTOOLS_RECENT_1,
45+ MENUID_XMLTOOLS_ABOUT,
46+ MENUID_SECONDPLUGIN_PRETTYPRINT,
47+ MENUID_SECONDPLUGIN_OPEN,
48+ MENUID_SECONDPLUGIN_ABOUT,
49+ MENUID_SECONDPLUGIN_RECENT_1,
50+ MENUID_SECONDPLUGIN_RECENT_2
51+ };
52+
1053class MenuManagerTest : public ::testing::Test {
1154 virtual void SetUp () {
55+ m_hModule = ::GetModuleHandle (NULL );
56+
57+ RegisterTestWindowClass ();
58+ CreateTestMenu ();
59+ CreateTestWindow ();
60+ ASSERT_NE (0 , (LONG)m_hWindow);
61+ MenuManager::create (m_hWindow, reinterpret_cast <HINSTANCE>(m_hModule), NULL );
62+ m_menuManager = MenuManager::getInstance ();
63+ }
64+
65+ virtual void TearDown () {
66+ DestroyWindow (m_hWindow);
67+ UnregisterClass (UNIT_TEST_WINDOW_CLASS, m_hModule);
68+ DestroyMenu (m_hMenu);
69+ MenuManager::destroyForTests ();
70+ }
71+
72+
73+
74+ protected:
75+ HMENU m_hMenu;
76+ HWND m_hWindow;
77+ HMODULE m_hModule;
78+ MenuManager* m_menuManager;
79+
80+
81+ void RegisterTestWindowClass () {
82+ WNDCLASS wndClass;
83+ memset (&wndClass, 0 , sizeof (WNDCLASS));
84+
85+ wndClass.lpfnWndProc = (WNDPROC)&dummyWindowProc;
86+ wndClass.hInstance = m_hModule;
87+ wndClass.lpszClassName = UNIT_TEST_WINDOW_CLASS;
88+ wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
89+
90+
91+ ::RegisterClassW (&wndClass);
92+ }
93+
94+
95+ /*
96+ Menu Structure:
97+
98+ File
99+ --> Open
100+ --> Close
101+ --> Recent
102+ --> Recent 1
103+ --> Recent 2
104+ --> Recent 3
105+ --> Exit
106+
107+ Edit
108+ --> Copy
109+ --> Paste
110+
111+ Plugins
112+ --> XML Tools
113+ --> Pretty Print
114+ --> Open
115+ --> Recent 1
116+ --> About
117+ --> Second Plugin
118+ --> Pretty Print
119+ --> Open
120+ --> Recent
121+ --> Recent 1
122+ --> Recent 2
123+ --> About
124+
12125
126+
127+
128+ */
129+
130+ void CreateTestMenu () {
131+ m_hMenu = ::CreateMenu ();
132+
133+ HMENU fileMenu = ::CreateMenu ();
134+ ::AppendMenu (m_hMenu, MF_POPUP, reinterpret_cast <UINT_PTR>(fileMenu), L"File");
135+ ::AppendMenu (fileMenu, MF_STRING, MENUID_FILE_OPEN, L" Open\t Ctrl-O" );
136+ ::AppendMenu (fileMenu, MF_STRING, MENUID_FILE_CLOSE, L" Close\t Ctrl-F4" );
137+
138+ HMENU recentMenu = ::CreateMenu ();
139+ ::AppendMenu (recentMenu, MF_STRING, MENUID_FILE_RECENT_1, L" Recent 1" );
140+ ::AppendMenu (recentMenu, MF_STRING, MENUID_FILE_RECENT_2, L" Recent 2" );
141+ ::AppendMenu (recentMenu, MF_STRING, MENUID_FILE_RECENT_3, L" Recent 3" );
142+ ::AppendMenu (fileMenu, MF_POPUP, reinterpret_cast <UINT_PTR>(recentMenu), L"Recent");
143+
144+ ::AppendMenu (fileMenu, MF_STRING, MENUID_FILE_CLOSE, L" Exit\t Alt-F4" );
145+
146+ HMENU editMenu = ::CreateMenu ();
147+ ::AppendMenu (m_hMenu, MF_POPUP, reinterpret_cast <UINT_PTR>(editMenu), L"Edit");
148+ ::AppendMenu (editMenu, MF_STRING, MENUID_EDIT_COPY, L" Copy" );
149+ ::AppendMenu (editMenu, MF_STRING, MENUID_EDIT_PASTE, L" Paste\t Ctrl-V" );
150+
151+ g_hPluginMenu = ::CreateMenu ();
152+ ::AppendMenu (m_hMenu, MF_POPUP, reinterpret_cast <UINT_PTR>(g_hPluginMenu), L"Plugins");
153+
154+ HMENU xmlToolsPluginMenu = ::CreateMenu ();
155+ ::AppendMenu (g_hPluginMenu, MF_POPUP, reinterpret_cast <UINT_PTR>(xmlToolsPluginMenu), L"XML Tools");
156+ ::AppendMenu (xmlToolsPluginMenu, MF_STRING, MENUID_XMLTOOLS_PRETTYPRINT, L" Pretty Print\t Ctrl-Alt-Shift-B" );
157+ ::AppendMenu (xmlToolsPluginMenu, MF_STRING, MENUID_XMLTOOLS_OPEN, L" Open\t Ctrl-O" );
158+ ::AppendMenu (xmlToolsPluginMenu, MF_STRING, MENUID_XMLTOOLS_RECENT_1, L" Recent 1" );
159+ ::AppendMenu (xmlToolsPluginMenu, MF_STRING, MENUID_XMLTOOLS_ABOUT, L" A&bout" );
160+
161+ HMENU secondPluginMenu = ::CreateMenu ();
162+
163+ ::AppendMenu (g_hPluginMenu, MF_POPUP, reinterpret_cast <UINT_PTR>(secondPluginMenu), L"Second Plugin");
164+ ::AppendMenu (secondPluginMenu, MF_STRING, MENUID_SECONDPLUGIN_PRETTYPRINT, L" Pretty Print\t Ctrl-Alt-Shift-B" );
165+ ::AppendMenu (secondPluginMenu, MF_STRING, MENUID_SECONDPLUGIN_OPEN, L" Open\t Ctrl-O" );
166+ HMENU secondPluginRecentMenu = ::CreateMenu ();
167+ ::AppendMenu (secondPluginMenu, MF_POPUP, reinterpret_cast <UINT_PTR>(secondPluginRecentMenu), L"Recent");
168+ ::AppendMenu (secondPluginRecentMenu, MF_STRING, MENUID_SECONDPLUGIN_RECENT_1, L" Recent 1" );
169+ ::AppendMenu (secondPluginRecentMenu, MF_STRING, MENUID_SECONDPLUGIN_RECENT_2, L" Recent 2" );
170+
171+ ::AppendMenu (secondPluginMenu, MF_STRING, MENUID_SECONDPLUGIN_ABOUT, L" A&bout" );
172+
173+ }
174+
175+ void CreateTestWindow () {
176+ m_hWindow = ::CreateWindow (
177+ UNIT_TEST_WINDOW_CLASS, /* Class name */
178+ L" Test window" ,
179+ WS_OVERLAPPEDWINDOW,
180+ 0 , 0 , 100 , 100 , /* x, y, width, heigth */
181+ NULL , /* hWndParent */
182+ m_hMenu,
183+ m_hModule,
184+ NULL /* lpParam */
185+ );
13186 }
187+
188+
189+ };
190+
191+ struct MenuTestCase {
192+ MenuTestCase () {}
193+ MenuTestCase (const TCHAR *pmenuName, const TCHAR *poptionName, int pexpectedID)
194+ : menuName(pmenuName),
195+ optionName (poptionName),
196+ expectedID(pexpectedID)
197+ {}
198+
199+ const TCHAR *menuName;
200+ const TCHAR *optionName;
201+ int expectedID;
202+ };
203+
204+
205+
206+ class MenuManagerFindMenuCommandTest : public MenuManagerTest ,
207+ public ::testing::WithParamInterface<MenuTestCase> {
208+
209+ };
210+
211+ TEST_P (MenuManagerFindMenuCommandTest, testFindOptionFindsCorrectOption) {
212+ MenuTestCase testCase = GetParam ();
213+ LONG_PTR windowWndProc = GetWindowLongPtr (m_hWindow, GWLP_WNDPROC);
214+ LONG_PTR dummyProc = reinterpret_cast <LONG_PTR>(&dummyWindowProc);
215+ ASSERT_EQ (windowWndProc, dummyProc);
216+ int foundMenuId = m_menuManager->findMenuCommand (m_hMenu, NULL , testCase.menuName , testCase.optionName );
217+ ASSERT_EQ (testCase.expectedID , foundMenuId);
218+ }
219+
220+
221+ INSTANTIATE_TEST_CASE_P (findMenuCommand, MenuManagerFindMenuCommandTest,
222+ ::testing::Values (MenuTestCase(L" File" , L" Open" , MENUID_FILE_OPEN), // First option
223+ MenuTestCase(L" File" , L" Close" , MENUID_FILE_CLOSE), // First menu, middle option
224+ MenuTestCase(L" Edit" , L" Copy" , MENUID_EDIT_COPY), // Mid menu, first option
225+ MenuTestCase(L" Edit" , L" Paste" , MENUID_EDIT_PASTE), // Mid menu, last option
226+ MenuTestCase(L" Recent" , L" Recent 1" , MENUID_FILE_RECENT_1), // Sub menu, first option
227+ MenuTestCase(L" Recent" , L" Recent 2" , MENUID_FILE_RECENT_2),
228+ MenuTestCase(L" Recent" , L" Recent 3" , MENUID_FILE_RECENT_3), // Sub menu, last option
229+ MenuTestCase(L" File" , L" Recent 2" , 0 ), // Shouldn't find Recent 2 directly under the File menu
230+ MenuTestCase(L" XML Tools" , L" Open" , MENUID_XMLTOOLS_OPEN), // Repeated option name, on third menu
231+ MenuTestCase(L" Second Plugin" , L" About" , MENUID_SECONDPLUGIN_ABOUT), // Repeated option name, with & in title
232+ MenuTestCase(L" Second Plugin" , L" Not found" , 0 ), // Non existent option
233+ MenuTestCase(L" Not exists" , L" Open" , 0 ) // Non existent menu
234+ ));
235+
236+ class MenuManagerFindPluginCommandTest : public MenuManagerTest ,
237+ public ::testing::WithParamInterface<MenuTestCase> {
238+
14239};
15240
16- TEST_F (MenuManagerTest, testDummy) {
17- ASSERT_EQ (0 , 0 );
241+ TEST_P (MenuManagerFindPluginCommandTest, testFindPluginCommand) {
242+ MenuTestCase testCase = GetParam ();
243+ int foundMenuId = m_menuManager->findPluginCommand (testCase.menuName , testCase.optionName , false );
244+ ASSERT_EQ (testCase.expectedID , foundMenuId);
18245}
246+
19247
248+ INSTANTIATE_TEST_CASE_P (findPluginMenuCommand, MenuManagerFindPluginCommandTest,
249+ ::testing::Values (MenuTestCase(L" XML Tools" , L" About" , MENUID_XMLTOOLS_ABOUT), // First plugin, last option
250+ MenuTestCase(L" Second Plugin" , L" About" , MENUID_SECONDPLUGIN_ABOUT), // Second plugin, repeated option name from other plugin
251+ MenuTestCase(L" XML Tools" , L" Recent 1" , MENUID_XMLTOOLS_RECENT_1), // First plugin, repeated option name from main menu
252+ MenuTestCase(L" Second Plugin" , L" Recent 1" , MENUID_SECONDPLUGIN_RECENT_1), // Second plugin, sub menu option
253+ MenuTestCase(L" Second Plugin" , L" Recent 2" , MENUID_SECONDPLUGIN_RECENT_2), // Second plugin, sub menu option
254+ MenuTestCase(L" Second Plugin" , L" Not exists" , 0 ), // Plugin option doesn't exist
255+ MenuTestCase(L" New Plugin" , L" Open" , 0 ) // Plugin doesn't exist
256+ ));
257+
20258}
0 commit comments