1   /***
2    * Redistribution  and use  in source  and binary  forms, with  or without
3    * modification, are permitted provided  that the following conditions are
4    * met :
5    *
6    * . Redistributions  of  source  code  must  retain  the  above copyright
7    *   notice, this list of conditions and the following disclaimer.
8    *
9    * . Redistributions in  binary form  must reproduce  the above  copyright
10   *   notice, this list of conditions  and the following disclaimer in  the
11   *   documentation and/or other materials provided with the distribution.
12   *
13   * . The name of the author may not be used to endorse or promote products
14   *   derived from this software without specific prior written permission.
15   *
16   * THIS SOFTWARE IS  PROVIDED BY THE  AUTHOR ``AS IS''  AND ANY EXPRESS  OR
17   * IMPLIED  WARRANTIES,  INCLUDING,  BUT   NOT  LIMITED  TO,  THE   IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE ARE
19   * DISCLAIMED.  IN NO  EVENT SHALL  THE AUTHOR  BE LIABLE  FOR ANY  DIRECT,
20   * INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES
21   * (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS OR
22   * SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION)
23   * HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN  CONTRACT,
24   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25   * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE, EVEN  IF  ADVISED OF  THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   *
28   * $Id$
29   */
30  
31  package palmed.edit;
32  
33  import java.io.OutputStream;
34  import palmed.edit.selection.ILineVisitor;
35  import palmed.edit.text.Text;
36  import palmed.util.EasyMockTestCase;
37  
38  /***
39   * Content test case.
40   *
41   * @author Mathieu Champlon
42   * @version $Revision$ $Date$
43   */
44  public class ContentTest extends EasyMockTestCase
45  {
46      /***
47       * Tested object.
48       */
49      private Content content;
50      /***
51       * Mock objects.
52       */
53      private ILineVisitor mockVisitor;
54      private OutputStream mockOutput;
55  
56      protected void setUp()
57      {
58          content = new Content( new Text() ); // FIXME cannot really use a mock text...
59          mockVisitor = (ILineVisitor)createMock( ILineVisitor.class );
60          mockOutput = (OutputStream)createMock( OutputStream.class );
61      }
62  
63      public void testTypeOneCharacterAddsIt()
64      {
65          content.type( 'a' );
66          mockVisitor.visit( "a", 1, 1, false );
67          replay();
68          content.accept( mockVisitor, 0 );
69      }
70  
71      public void testUndoTypedCharacterRemovesIt()
72      {
73          content.type( 'a' );
74          content.click( 0, 0 );
75          content.undo();
76          mockVisitor.visit( "", 0, 0, false );
77          replay();
78          content.accept( mockVisitor, 0 );
79      }
80  
81      public void testRedoTypedCharacterAddsAndSelectsIt()
82      {
83          content.type( 'a' );
84          content.undo();
85          content.click( 0, 0 );
86          content.redo();
87          mockVisitor.visit( "a", 0, 1, false );
88          replay();
89          content.accept( mockVisitor, 0 );
90      }
91  
92      public void testTypeSeveralCharactersAddsThem()
93      {
94          content.type( 'a' );
95          content.type( 'b' );
96          content.type( 'c' );
97          mockVisitor.visit( "abc", 3, 3, false );
98          replay();
99          content.accept( mockVisitor, 0 );
100     }
101 
102     public void testUndoTypeSeveralCharactersRemovesThem()
103     {
104         content.type( 'a' );
105         content.type( 'b' );
106         content.type( 'c' );
107         content.click( 0, 0 );
108         content.undo();
109         mockVisitor.visit( "", 0, 0, false );
110         replay();
111         content.accept( mockVisitor, 0 );
112     }
113 
114     public void testRedoTypeSeveralCharactersRestoresAndSelectsThem()
115     {
116         content.type( 'a' );
117         content.type( 'b' );
118         content.type( 'c' );
119         content.undo();
120         content.click( 0, 0 );
121         content.redo();
122         mockVisitor.visit( "abc", 0, 3, false );
123         replay();
124         content.accept( mockVisitor, 0 );
125     }
126 
127     public void testTypeCharacterReplacesSelection()
128     {
129         content.type( 'a' );
130         content.type( 'b' );
131         content.type( 'c' );
132         content.drag( 1, 0 );
133         content.type( 'd' );
134         mockVisitor.visit( "ad", 2, 2, false );
135         replay();
136         content.accept( mockVisitor, 0 );
137     }
138 
139     public void testUndoTypeCharacterReplacingSelectionRestoresAndSelectsIt()
140     {
141         content.type( 'a' );
142         content.type( 'b' );
143         content.type( 'c' );
144         content.drag( 1, 0 );
145         content.type( 'd' );
146         content.click( 0, 0 );
147         content.undo();
148         mockVisitor.visit( "abc", 1, 3, false );
149         replay();
150         content.accept( mockVisitor, 0 );
151     }
152 
153     public void testRedoTypeCharacterReplacingSelectionRestoresAndSelectsIt()
154     {
155         content.type( 'a' );
156         content.type( 'b' );
157         content.type( 'c' );
158         content.drag( 1, 0 );
159         content.type( 'd' );
160         content.undo();
161         content.click( 0, 0 );
162         content.redo();
163         mockVisitor.visit( "ad", 1, 2, false );
164         replay();
165         content.accept( mockVisitor, 0 );
166     }
167 
168     public void testBackspaceRemovesLastTypedCharacter()
169     {
170         content.type( 'a' );
171         content.type( 'b' );
172         content.backspace();
173         mockVisitor.visit( "a", 1, 1, false );
174         replay();
175         content.accept( mockVisitor, 0 );
176     }
177 
178     public void testUndoBackspaceRemovingCharacterRestoresAndSelectsIt()
179     {
180         content.type( 'a' );
181         content.type( 'b' );
182         content.backspace();
183         content.click( 0, 0 );
184         content.undo();
185         mockVisitor.visit( "ab", 1, 2, false );
186         replay();
187         content.accept( mockVisitor, 0 );
188     }
189 
190     public void testRedoBackspaceRemovingCharacterRemovesIt()
191     {
192         content.type( 'a' );
193         content.type( 'b' );
194         content.backspace();
195         content.undo();
196         content.click( 0, 0 );
197         content.redo();
198         mockVisitor.visit( "a", 1, 1, false );
199         replay();
200         content.accept( mockVisitor, 0 );
201     }
202 
203     public void testSeveralBackspacesRemoveSeveralCharacters()
204     {
205         content.type( 'a' );
206         content.type( 'b' );
207         content.type( 'c' );
208         content.backspace();
209         content.backspace();
210         mockVisitor.visit( "a", 1, 1, false );
211         replay();
212         content.accept( mockVisitor, 0 );
213     }
214 
215     public void testUndoBackspaceRemovingSeveralCharactersRestoresAndSelectsThem()
216     {
217         content.type( 'a' );
218         content.type( 'b' );
219         content.type( 'c' );
220         content.backspace();
221         content.backspace();
222         content.click( 0, 0 );
223         content.undo();
224         mockVisitor.visit( "abc", 1, 3, false );
225         replay();
226         content.accept( mockVisitor, 0 );
227     }
228 
229     public void testRedoBackspaceRemovingSeveralCharactersRemovesThem()
230     {
231         content.type( 'a' );
232         content.type( 'b' );
233         content.type( 'c' );
234         content.backspace();
235         content.backspace();
236         content.undo();
237         content.click( 0, 0 );
238         content.redo();
239         mockVisitor.visit( "a", 1, 1, false );
240         replay();
241         content.accept( mockVisitor, 0 );
242     }
243 
244     public void testBackspaceRemovesSelection()
245     {
246         content.type( 'a' );
247         content.type( 'b' );
248         content.type( 'c' );
249         content.drag( 1, 0 );
250         content.backspace();
251         mockVisitor.visit( "a", 1, 1, false );
252         replay();
253         content.accept( mockVisitor, 0 );
254     }
255 
256     public void testUndoBackspaceRemovingSelectionRestoresAndSelectsIt()
257     {
258         content.type( 'a' );
259         content.type( 'b' );
260         content.type( 'c' );
261         content.drag( 1, 0 );
262         content.backspace();
263         content.click( 0, 0 );
264         content.undo();
265         mockVisitor.visit( "abc", 1, 3, false );
266         replay();
267         content.accept( mockVisitor, 0 );
268     }
269 
270     public void testRedoBackspaceRemovingSelectionRemovesIt()
271     {
272         content.type( 'a' );
273         content.type( 'b' );
274         content.type( 'c' );
275         content.drag( 1, 0 );
276         content.backspace();
277         content.undo();
278         content.click( 0, 0 );
279         content.redo();
280         mockVisitor.visit( "a", 1, 1, false );
281         replay();
282         content.accept( mockVisitor, 0 );
283     }
284 
285     public void testEnterAddsNewLine()
286     {
287         content.type( 'a' );
288         content.enter();
289         mockVisitor.visit( "a", 0, 0, false );
290         mockVisitor.visit( "", 0, 0, false );
291         replay();
292         content.accept( mockVisitor, 0 );
293         content.accept( mockVisitor, 1 );
294     }
295 
296     public void testUndoEnterRemovesTheNewLine()
297     {
298         content.type( 'a' );
299         content.enter();
300         content.click( 0, 0 );
301         content.undo();
302         mockVisitor.visit( "a", 1, 1, false );
303         replay();
304         content.accept( mockVisitor, 0 );
305         content.accept( mockVisitor, 1 );
306     }
307 
308     public void testRedoEnterRestoresTheNewLineAndSelectsIt()
309     {
310         content.type( 'a' );
311         content.enter();
312         content.undo();
313         content.click( 0, 0 );
314         content.redo();
315         mockVisitor.visit( "a", 1, 1, true );
316         mockVisitor.visit( "", 0, 0, false );
317         replay();
318         content.accept( mockVisitor, 0 );
319         content.accept( mockVisitor, 1 );
320     }
321 
322     public void testEnterReplacesSelection()
323     {
324         content.type( 'a' );
325         content.type( 'b' );
326         content.type( 'c' );
327         content.click( 2, 0 );
328         content.drag( 1, 0 );
329         content.enter();
330         mockVisitor.visit( "a", 0, 0, false );
331         mockVisitor.visit( "c", 0, 0, false );
332         replay();
333         content.accept( mockVisitor, 0 );
334         content.accept( mockVisitor, 1 );
335     }
336 
337     public void testUndoEnterReplacingSelectionRestoresAndSelectsIt()
338     {
339         content.type( 'a' );
340         content.type( 'b' );
341         content.type( 'c' );
342         content.click( 2, 0 );
343         content.drag( 1, 0 );
344         content.enter();
345         content.click( 0, 0 );
346         content.undo();
347         mockVisitor.visit( "abc", 1, 2, false );
348         replay();
349         content.accept( mockVisitor, 0 );
350         content.accept( mockVisitor, 1 );
351     }
352 
353     public void testRedoEnterReplacingSelectionRestoresTheNewLineAndSelectsIt()
354     {
355         content.type( 'a' );
356         content.type( 'b' );
357         content.type( 'c' );
358         content.click( 2, 0 );
359         content.drag( 1, 0 );
360         content.enter();
361         content.undo();
362         content.click( 0, 0 );
363         content.redo();
364         mockVisitor.visit( "a", 1, 1, true );
365         mockVisitor.visit( "c", 0, 0, false );
366         replay();
367         content.accept( mockVisitor, 0 );
368         content.accept( mockVisitor, 1 );
369     }
370 
371     public void testUndoSeveralEnterReplacingSelectionRestoresAndSelectsIt()
372     {
373         content.type( 'a' );
374         content.type( 'b' );
375         content.type( 'c' );
376         content.click( 2, 0 );
377         content.drag( 1, 0 );
378         content.enter();
379         content.enter();
380         content.enter();
381         content.click( 0, 0 );
382         content.undo();
383         mockVisitor.visit( "abc", 1, 2, false );
384         replay();
385         content.accept( mockVisitor, 0 );
386         content.accept( mockVisitor, 1 );
387     }
388 
389     public void testRedoSeveralEnterReplacingSelectionRestoresNewLinesAndSelectsThem()
390     {
391         content.type( 'a' );
392         content.type( 'b' );
393         content.type( 'c' );
394         content.click( 2, 0 );
395         content.drag( 1, 0 );
396         content.enter();
397         content.enter();
398         content.enter();
399         content.undo();
400         content.click( 0, 0 );
401         content.redo();
402         mockVisitor.visit( "a", 1, 1, true );
403         mockVisitor.visit( "", 0, 0, true );
404         mockVisitor.visit( "", 0, 0, true );
405         mockVisitor.visit( "c", 0, 0, false );
406         replay();
407         content.accept( mockVisitor, 0 );
408         content.accept( mockVisitor, 1 );
409         content.accept( mockVisitor, 2 );
410         content.accept( mockVisitor, 3 );
411     }
412 
413     public void testCutWithoutSelectionIsNoOpAndCannotBeUndone()
414     {
415         content.type( 'a' );
416         content.type( 'b' );
417         content.type( 'c' );
418         content.backspace();
419         replay();
420         content.cut( mockOutput );
421         content.undo();
422         reset();
423         mockVisitor.visit( "abc", 2, 3, false );
424         replay();
425         content.accept( mockVisitor, 0 );
426     }
427 
428     public void testCutRemovesSelectedText()
429     {
430         content.type( 'a' );
431         content.type( 'b' );
432         content.type( 'c' );
433         content.click( 2, 0 );
434         content.drag( 1, 0 );
435         content.cut( mockOutput );
436         reset();
437         mockVisitor.visit( "ac", 1, 1, false );
438         replay();
439         content.accept( mockVisitor, 0 );
440     }
441 
442     public void testUndoCutRestoresTextAndSelectsIt()
443     {
444         content.type( 'a' );
445         content.type( 'b' );
446         content.type( 'c' );
447         content.click( 2, 0 );
448         content.drag( 1, 0 );
449         content.cut( mockOutput );
450         content.click( 0, 0 );
451         content.undo();
452         reset();
453         mockVisitor.visit( "abc", 1, 2, false );
454         replay();
455         content.accept( mockVisitor, 0 );
456     }
457 
458     public void testRedoCutRemovesText()
459     {
460         content.type( 'a' );
461         content.type( 'b' );
462         content.type( 'c' );
463         content.click( 2, 0 );
464         content.drag( 1, 0 );
465         content.cut( mockOutput );
466         content.undo();
467         content.click( 0, 0 );
468         content.redo();
469         reset();
470         mockVisitor.visit( "ac", 1, 1, false );
471         replay();
472         content.accept( mockVisitor, 0 );
473     }
474 
475     public void testClickPreventsUndoMerge()
476     {
477         content.type( 'a' );
478         content.click( 1, 0 );
479         content.type( 'b' );
480         content.undo();
481         reset();
482         mockVisitor.visit( "a", 1, 1, false );
483         replay();
484         content.accept( mockVisitor, 0 );
485     }
486 }