1//------------------------------------------------------------------------------
2//	ReadWriteTester.cpp
3//
4//------------------------------------------------------------------------------
5
6// Standard Includes -----------------------------------------------------------
7#include <string.h>
8
9// System Includes -------------------------------------------------------------
10#include <Application.h>
11#include <Clipboard.h>
12
13#define CHK	CPPUNIT_ASSERT
14
15#include <TestShell.h>
16
17// Project Includes ------------------------------------------------------------
18
19// Local Includes --------------------------------------------------------------
20#include "ReadWriteTester.h"
21
22// Local Defines ---------------------------------------------------------------
23
24// Globals ---------------------------------------------------------------------
25
26//------------------------------------------------------------------------------
27
28/*
29	status_t Clear()
30	@case 1
31	@results		Clear() returns B_ERROR
32 */
33void ReadWriteTester::Clear1()
34{
35  BApplication app("application/x-vnd.clipboardtest");
36  BClipboard clip("Clear1");
37
38#ifdef TEST_R5
39  CHK(false);
40#endif
41  CPPUNIT_ASSERT_DEBUGGER(clip.Clear());
42}
43
44/*
45	status_t Clear()
46	@case 2
47	@results		Clear() returns B_OK
48				data message is empty
49 */
50void ReadWriteTester::Clear2()
51{
52  BApplication app("application/x-vnd.clipboardtest");
53  BClipboard clip("Clear2");
54  BMessage *data;
55
56  if ( clip.Lock() )
57  {
58    CHK(clip.Clear() == B_OK);
59    if ( (data = clip.Data()) )
60      CHK(data->IsEmpty());
61  }
62}
63
64/*
65	status_t Revert()
66	@case 1
67	@results		Revert() returns B_ERROR
68 */
69void ReadWriteTester::Revert1()
70{
71  BApplication app("application/x-vnd.clipboardtest");
72  BClipboard clip("Revert1");
73
74#ifdef TEST_R5
75  CHK(false);
76#endif
77  CPPUNIT_ASSERT_DEBUGGER(clip.Revert());
78}
79
80/*
81	status_t Revert()
82	@case 2
83	@results		Revert() returns B_OK
84				data message is reset
85 */
86void ReadWriteTester::Revert2()
87{
88  BApplication app("application/x-vnd.clipboardtest");
89  BClipboard clip("Revert2");
90  BMessage *data;
91  char *str;
92  ssize_t size;
93
94  if ( clip.Lock() )
95  {
96    clip.Clear();
97    if ( (data = clip.Data()) )
98    {
99      data->AddData("text/plain",B_MIME_TYPE, "Revert2", 8);
100      clip.Commit();
101    }
102    clip.Unlock();
103  }
104
105  if ( clip.Lock() )
106  {
107    clip.Clear();
108    if ( (data = clip.Data()) )
109    {
110      data->AddData("text/plain",B_MIME_TYPE, "Foo", 4);
111    }
112    CHK(clip.Revert() == B_OK);
113    if ( (data = clip.Data()) )
114    {
115      data->FindData("text/plain",B_MIME_TYPE, (const void **)&str, &size);
116      CHK(strcmp(str,"Revert2") == 0);
117    }
118    clip.Unlock();
119  }
120}
121
122/*
123	status_t Commit()
124	@case 1
125	@results		Commit() returns B_ERROR
126 */
127void ReadWriteTester::Commit1()
128{
129  BApplication app("application/x-vnd.clipboardtest");
130  BClipboard clip("Commit1");
131
132#ifdef TEST_R5
133  CHK(false);
134#endif
135  CPPUNIT_ASSERT_DEBUGGER(clip.Commit());
136}
137
138/*
139	status_t Commit()
140	@case 2
141	@results		Commit() returns B_OK
142				data is uploaded from system
143 */
144void ReadWriteTester::Commit2()
145{
146  BApplication app("application/x-vnd.clipboardtest");
147  BClipboard clipA("Commit2");
148  BClipboard clipB("Commit2");
149  BMessage *data;
150  char *str;
151  ssize_t size;
152
153  if ( clipA.Lock() )
154  {
155    clipA.Clear();
156    if ( (data = clipA.Data()) )
157    {
158      data->AddData("text/plain",B_MIME_TYPE, "Commit2", 8);
159      CHK(clipA.Commit() == B_OK);
160    }
161    clipA.Unlock();
162  }
163  if ( clipB.Lock() )
164  {
165    if ( (data = clipB.Data()) )
166    {
167      data->FindData("text/plain",B_MIME_TYPE, (const void **)&str, &size);
168      CHK(strcmp(str,"Commit2") == 0);
169    }
170    clipB.Unlock();
171  }
172}
173
174/*
175	BMessage *Data()
176	@case 1
177	@results		Data() returns NULL
178 */
179void ReadWriteTester::Data1()
180{
181  BApplication app("application/x-vnd.clipboardtest");
182  BClipboard clip("Data1");
183
184#ifdef TEST_R5
185  CHK(false);
186#endif
187  CPPUNIT_ASSERT_DEBUGGER(clip.Data());
188}
189
190/*
191	BMessage *Data()
192	@case 2
193	@results		Data() returns a message with correct data
194 */
195void ReadWriteTester::Data2()
196{
197  BApplication app("application/x-vnd.clipboardtest");
198  BClipboard clip("Data2");
199  BMessage *data;
200  char *str;
201  ssize_t size;
202
203  if ( clip.Lock() )
204  {
205    clip.Clear();
206    data = clip.Data();
207    CHK(data);
208    data->AddData("text/plain",B_MIME_TYPE, "Data2", 6);
209    clip.Commit();
210    clip.Unlock();
211  }
212  if ( clip.Lock() )
213  {
214    data = clip.Data();
215    CHK(data);
216    data->FindData("text/plain",B_MIME_TYPE, (const void **)&str, &size);
217    CHK(strcmp(str,"Data2") == 0);
218    clip.Unlock();
219  }
220}
221
222/*
223	BMessenger DataSource()
224	@case 1
225	@results		DataSource returns and invalid BMessenger
226 */
227void ReadWriteTester::DataSource1()
228{
229  BApplication app("application/x-vnd.clipboardtest");
230  BClipboard clip("DataSource1");
231
232  CHK(!clip.DataSource().IsValid());
233}
234
235/*
236	BMessenger DataSource()
237	@case 2
238	@results		DataSource returns an invalid BMessenger
239 */
240void ReadWriteTester::DataSource2()
241{
242  BApplication app("application/x-vnd.clipboardtest");
243  BClipboard clipA("DataSource2");
244  BClipboard clipB("DataSource2");
245  BMessage *data;
246
247  if ( clipA.Lock() )
248  {
249    clipA.Clear();
250    if ( (data = clipA.Data()) )
251    {
252      data->AddData("text/plain",B_MIME_TYPE, "DataSource2", 12);
253      clipA.Commit();
254    }
255    clipA.Unlock();
256  }
257  CHK(!clipB.DataSource().IsValid());
258}
259
260/*
261	BMessenger DataSource()
262	@case 3
263	@results		DataSource returns a valid BMessenger
264 */
265void ReadWriteTester::DataSource3()
266{
267  BApplication app("application/x-vnd.clipboardtest");
268  BClipboard clipA("DataSource3");
269  BClipboard clipB("DataSource3");
270  BMessage *data;
271
272  if ( clipA.Lock() )
273  {
274    clipA.Clear();
275    if ( (data = clipA.Data()) )
276    {
277      data->AddData("text/plain",B_MIME_TYPE, "DataSource3", 12);
278      clipA.Commit();
279    }
280    clipA.Unlock();
281  }
282  if ( clipB.Lock() )
283  {
284    CHK(clipB.DataSource().IsValid());
285    CHK(clipB.DataSource() == be_app_messenger);
286  }
287}
288
289/*
290	status_t StartWatching(BMessenger target)
291	@case 1
292	@results		return B_OK, target is notified when clipboard is written
293 */
294void ReadWriteTester::StartWatching1()
295{
296  BApplication app("application/x-vnd.clipboardtest");
297  BClipboard clip("StartWatching1");
298  BMessage *data;
299
300  BLooper *looper = new BLooper();
301  RWHandler handler;
302  looper->AddHandler(&handler);
303  looper->Run();
304  BMessenger target(&handler);
305  CHK(clip.StartWatching(target) == B_OK);
306  if ( clip.Lock() )
307  {
308    clip.Clear();
309    data = clip.Data();
310    data->AddData("text/plain",B_MIME_TYPE, "StartWatching1", 15);
311    clip.Commit();
312    clip.Unlock();
313  }
314  snooze(100000);
315  looper->Lock();
316  looper->Quit();
317  CHK(handler.ClipboardModified());
318  clip.StopWatching(target);
319}
320
321/*
322	status_t StopWatching(BMessenger target)
323	@case 1
324	@results		return B_OK
325 */
326void ReadWriteTester::StopWatching1()
327{
328  BApplication app("application/x-vnd.clipboardtest");
329  BClipboard clip("StopWatching1");
330  if ( clip.StartWatching(be_app_messenger) == B_OK )
331  {
332    CHK(clip.StopWatching(be_app_messenger) == B_OK);
333  }
334}
335
336/*
337	status_t StopWatching(BMessenger target)
338	@case 2
339	@results		return B_BAD_VALUE
340 */
341void ReadWriteTester::StopWatching2()
342{
343  BApplication app("application/x-vnd.clipboardtest");
344  BClipboard clip("StopWatching2");
345  CHK(clip.StopWatching(be_app_messenger) == B_BAD_VALUE);
346}
347
348Test* ReadWriteTester::Suite()
349{
350	TestSuite* SuiteOfTests = new TestSuite;
351
352	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Clear1);
353	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Clear2);
354	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Revert1);
355	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Revert2);
356	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Commit1);
357	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Commit2);
358	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Data1);
359	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, Data2);
360	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, DataSource1);
361	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, DataSource2);
362	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, DataSource3);
363	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, StartWatching1);
364	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, StopWatching1);
365	ADD_TEST4(BClipboard, SuiteOfTests, ReadWriteTester, StopWatching2);
366
367	return SuiteOfTests;
368}
369
370// RWHandler
371
372// constructor
373RWHandler::RWHandler()
374		 : BHandler()
375{
376	fClipboardModified = false;
377}
378
379// MessageReceived
380void
381RWHandler::MessageReceived(BMessage *message)
382{
383	switch (message->what) {
384		case B_CLIPBOARD_CHANGED:
385		  	fClipboardModified = true;
386			break;
387		default:
388			BHandler::MessageReceived(message);
389			break;
390	}
391}
392
393// ClipboardModified
394bool
395RWHandler::ClipboardModified()
396{
397	return fClipboardModified;
398}
399
400