KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_clipboard.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <boost/test/unit_test.hpp>
21#include <clipboard.h>
22#include <wx/clipbrd.h>
23#include <wx/image.h>
24#include <wx/string.h>
25#include <wx/filename.h>
26#include <wx/mstream.h>
27#include <vector>
28
29BOOST_AUTO_TEST_SUITE( ClipboardTests )
30
31BOOST_AUTO_TEST_CASE( SaveClipboard_BasicText )
32{
33 std::string testText = "Basic clipboard test";
34 bool result = SaveClipboard( testText );
35
36 if( result )
37 {
38 std::string retrieved = GetClipboardUTF8();
39 BOOST_CHECK_EQUAL( retrieved, testText );
40 }
41 // Note: Test may fail on headless systems where clipboard isn't available
42}
43
44BOOST_AUTO_TEST_CASE( SaveClipboard_EmptyString )
45{
46 std::string emptyText = "";
47 bool result = SaveClipboard( emptyText );
48
49 if( result )
50 {
51 std::string retrieved = GetClipboardUTF8();
52 BOOST_CHECK_EQUAL( retrieved, emptyText );
53 }
54}
55
56BOOST_AUTO_TEST_CASE( SaveClipboard_UTF8Characters )
57{
58 std::string utf8Text = "Héllo Wörld! 你好 🚀";
59 bool result = SaveClipboard( utf8Text );
60
61 if( result )
62 {
63 std::string retrieved = GetClipboardUTF8();
64 BOOST_CHECK_EQUAL( retrieved, utf8Text );
65 }
66}
67
68BOOST_AUTO_TEST_CASE( SaveClipboard_LargeText )
69{
70 std::string largeText( 10000, 'A' );
71 largeText += "END";
72 bool result = SaveClipboard( largeText );
73
74 if( result )
75 {
76 std::string retrieved = GetClipboardUTF8();
77 BOOST_CHECK_EQUAL( retrieved, largeText );
78 }
79}
80
81BOOST_AUTO_TEST_CASE( SaveClipboard_SpecialCharacters )
82{
83 std::string specialText = "Line1\nLine2\tTabbed\r\nWindows newline";
84 bool result = SaveClipboard( specialText );
85
86 if( result )
87 {
88 std::string retrieved = GetClipboardUTF8();
89 BOOST_CHECK_EQUAL( retrieved, specialText );
90 }
91}
92
93BOOST_AUTO_TEST_CASE( GetClipboardUTF8_EmptyClipboard )
94{
95 // Clear clipboard first
96 if( wxTheClipboard->Open() )
97 {
98 wxTheClipboard->Clear();
99 wxTheClipboard->Close();
100 }
101
102 std::string result = GetClipboardUTF8();
103 BOOST_CHECK( result.empty() );
104}
105
106BOOST_AUTO_TEST_CASE( GetClipboardUTF8_NonTextData )
107{
108 // This test verifies behavior when clipboard contains non-text data
109 // Implementation depends on system behavior - may return empty string
110 std::string result = GetClipboardUTF8();
111 // No specific assertion - just ensure it doesn't crash
112 BOOST_CHECK( true );
113}
114
115BOOST_AUTO_TEST_CASE( SaveTabularData_SimpleGrid )
116{
117 std::vector<std::vector<wxString>> testData = {
118 { wxS("A1"), wxS("B1"), wxS("C1") },
119 { wxS("A2"), wxS("B2"), wxS("C2") },
120 { wxS("A3"), wxS("B3"), wxS("C3") }
121 };
122
123 bool result = SaveTabularDataToClipboard( testData );
124
125 if( result )
126 {
127 std::vector<std::vector<wxString>> retrieved;
128 bool parseResult = GetTabularDataFromClipboard( retrieved );
129
130 if( parseResult )
131 {
132 BOOST_CHECK_EQUAL( retrieved.size(), testData.size() );
133 for( size_t i = 0; i < testData.size() && i < retrieved.size(); ++i )
134 {
135 BOOST_CHECK_EQUAL( retrieved[i].size(), testData[i].size() );
136 for( size_t j = 0; j < testData[i].size() && j < retrieved[i].size(); ++j )
137 {
138 BOOST_CHECK_EQUAL( retrieved[i][j], testData[i][j] );
139 }
140 }
141 }
142 }
143}
144
145BOOST_AUTO_TEST_CASE( SaveTabularData_EmptyGrid )
146{
147 std::vector<std::vector<wxString>> emptyData;
148 bool result = SaveTabularDataToClipboard( emptyData );
149
150 if( result )
151 {
152 std::vector<std::vector<wxString>> retrieved;
153 bool parseResult = GetTabularDataFromClipboard( retrieved );
154
155 if( parseResult )
156 {
157 BOOST_CHECK( retrieved.empty() );
158 }
159 }
160}
161
162BOOST_AUTO_TEST_CASE( SaveTabularData_SingleCell )
163{
164 std::vector<std::vector<wxString>> singleCell = {
165 { wxS("OnlyCell") }
166 };
167
168 bool result = SaveTabularDataToClipboard( singleCell );
169
170 if( result )
171 {
172 std::vector<std::vector<wxString>> retrieved;
173 bool parseResult = GetTabularDataFromClipboard( retrieved );
174
175 if( parseResult )
176 {
177 BOOST_CHECK_EQUAL( retrieved.size(), 1 );
178 BOOST_CHECK_EQUAL( retrieved[0].size(), 1 );
179 BOOST_CHECK_EQUAL( retrieved[0][0], wxS("OnlyCell") );
180 }
181 }
182}
183
184BOOST_AUTO_TEST_CASE( SaveTabularData_WithCommas )
185{
186 std::vector<std::vector<wxString>> dataWithCommas = {
187 { wxS("Value, with comma"), wxS("Normal") },
188 { wxS("Another, comma"), wxS("Also normal") }
189 };
190
191 bool result = SaveTabularDataToClipboard( dataWithCommas );
192
193 if( result )
194 {
195 std::vector<std::vector<wxString>> retrieved;
196 bool parseResult = GetTabularDataFromClipboard( retrieved );
197
198 if( parseResult )
199 {
200 BOOST_CHECK_EQUAL( retrieved.size(), dataWithCommas.size() );
201 for( size_t i = 0; i < dataWithCommas.size() && i < retrieved.size(); ++i )
202 {
203 BOOST_CHECK_EQUAL( retrieved[i].size(), dataWithCommas[i].size() );
204 for( size_t j = 0; j < dataWithCommas[i].size() && j < retrieved[i].size(); ++j )
205 {
206 BOOST_CHECK_EQUAL( retrieved[i][j], dataWithCommas[i][j] );
207 }
208 }
209 }
210 }
211}
212
213BOOST_AUTO_TEST_CASE( SaveTabularData_WithQuotes )
214{
215 std::vector<std::vector<wxString>> dataWithQuotes = {
216 { wxS("\"Quoted value\""), wxS("Normal") },
217 { wxS("Value with \"inner\" quotes"), wxS("Plain") }
218 };
219
220 bool result = SaveTabularDataToClipboard( dataWithQuotes );
221
222 if( result )
223 {
224 std::vector<std::vector<wxString>> retrieved;
225 bool parseResult = GetTabularDataFromClipboard( retrieved );
226
227 if( parseResult )
228 {
229 BOOST_CHECK_EQUAL( retrieved.size(), dataWithQuotes.size() );
230 // Note: Exact quote handling depends on CSV parser implementation
231 }
232 }
233}
234
235BOOST_AUTO_TEST_CASE( SaveTabularData_WithNewlines )
236{
237 std::vector<std::vector<wxString>> dataWithNewlines = {
238 { wxS("Line1\nLine2"), wxS("Normal") },
239 { wxS("Single line"), wxS("Another\nmultiline") }
240 };
241
242 bool result = SaveTabularDataToClipboard( dataWithNewlines );
243
244 if( result )
245 {
246 std::vector<std::vector<wxString>> retrieved;
247 bool parseResult = GetTabularDataFromClipboard( retrieved );
248
249 if( parseResult )
250 {
251 BOOST_CHECK_EQUAL( retrieved.size(), dataWithNewlines.size() );
252 // Note: Newline handling depends on CSV parser implementation
253 }
254 }
255}
256
257BOOST_AUTO_TEST_CASE( SaveTabularData_IrregularGrid )
258{
259 std::vector<std::vector<wxString>> irregularData = {
260 { wxS("A1"), wxS("B1"), wxS("C1"), wxS("D1") },
261 { wxS("A2"), wxS("B2") },
262 { wxS("A3"), wxS("B3"), wxS("C3") }
263 };
264
265 bool result = SaveTabularDataToClipboard( irregularData );
266
267 if( result )
268 {
269 std::vector<std::vector<wxString>> retrieved;
270 bool parseResult = GetTabularDataFromClipboard( retrieved );
271
272 if( parseResult )
273 {
274 BOOST_CHECK_EQUAL( retrieved.size(), irregularData.size() );
275 // Each row should maintain its individual size
276 for( size_t i = 0; i < irregularData.size() && i < retrieved.size(); ++i )
277 {
278 for( size_t j = 0; j < irregularData[i].size() && j < retrieved[i].size(); ++j )
279 {
280 BOOST_CHECK_EQUAL( retrieved[i][j], irregularData[i][j] );
281 }
282 }
283 }
284 }
285}
286
287BOOST_AUTO_TEST_CASE( GetTabularDataFromClipboard_InvalidData )
288{
289 // Save non-tabular text to clipboard
290 std::string invalidText = "This is not tabular data\nJust some text";
291 SaveClipboard( invalidText );
292
293 std::vector<std::vector<wxString>> retrieved;
294 bool result = GetTabularDataFromClipboard( retrieved );
295
296 // Should either parse as single-column data or return appropriate result
297 // Exact behavior depends on AutoDecodeCSV implementation
298 BOOST_CHECK( true ); // Test that it doesn't crash
299}
300
301BOOST_AUTO_TEST_CASE( GetImageFromClipboard_NoImage )
302{
303 // Clear clipboard
304 if( wxTheClipboard->Open() )
305 {
306 wxTheClipboard->Clear();
307 wxTheClipboard->Close();
308 }
309
310 std::unique_ptr<wxImage> image = GetImageFromClipboard();
311 BOOST_CHECK( !image || !image->IsOk() );
312}
313
314BOOST_AUTO_TEST_CASE( GetImageFromClipboard_TextInClipboard )
315{
316 // Put text in clipboard
317 SaveClipboard( "This is text, not an image" );
318
319 std::unique_ptr<wxImage> image = GetImageFromClipboard();
320 BOOST_CHECK( !image || !image->IsOk() );
321}
322
323BOOST_AUTO_TEST_CASE( Clipboard_MultipleSaveOperations )
324{
325 // Test multiple sequential save operations
326 std::vector<std::string> testStrings = {
327 "First string",
328 "Second string with 特殊字符",
329 "Third string\nwith\nnewlines",
330 ""
331 };
332
333 for( const auto& testString : testStrings )
334 {
335 bool saved = SaveClipboard( testString );
336 if( saved )
337 {
338 std::string retrieved = GetClipboardUTF8();
339 BOOST_CHECK_EQUAL( retrieved, testString );
340 }
341 }
342}
343
344BOOST_AUTO_TEST_CASE( Clipboard_ConcurrentAccess )
345{
346 // Test that clipboard operations are properly synchronized
347 std::string testText1 = "Concurrent test 1";
348 std::string testText2 = "Concurrent test 2";
349
350 bool result1 = SaveClipboard( testText1 );
351 bool result2 = SaveClipboard( testText2 );
352
353 if( result2 )
354 {
355 std::string retrieved = GetClipboardUTF8();
356 BOOST_CHECK_EQUAL( retrieved, testText2 ); // Should have the last saved value
357 }
358}
359
360BOOST_AUTO_TEST_CASE( Clipboard_FlushBehavior )
361{
362 // Test that Flush() allows data to persist after the application
363 std::string persistentText = "This should persist after flush";
364 bool result = SaveClipboard( persistentText );
365
366 if( result )
367 {
368 // Data should still be available
369 std::string retrieved = GetClipboardUTF8();
370 BOOST_CHECK_EQUAL( retrieved, persistentText );
371 }
372}
373
bool SaveTabularDataToClipboard(const std::vector< std::vector< wxString > > &aData)
Store tabular data to the system clipboard.
Definition: clipboard.cpp:118
bool SaveClipboard(const std::string &aTextUTF8)
Store information to the system clipboard.
Definition: clipboard.cpp:37
std::string GetClipboardUTF8()
Return the information currently stored in the system clipboard.
Definition: clipboard.cpp:57
std::unique_ptr< wxImage > GetImageFromClipboard()
Get image data from the clipboard, if there is any.
Definition: clipboard.cpp:83
bool GetTabularDataFromClipboard(std::vector< std::vector< wxString > > &aData)
Attempt to get tabular data from the clipboard.
Definition: clipboard.cpp:152
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_CHECK_EQUAL(ret, c.m_exp_result)
BOOST_AUTO_TEST_CASE(SaveClipboard_BasicText)
BOOST_AUTO_TEST_SUITE_END()