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.text;
32  
33  import java.io.ByteArrayInputStream;
34  import java.io.ByteArrayOutputStream;
35  import java.io.IOException;
36  import org.easymock.MockControl;
37  import palmed.edit.util.Coordinate;
38  import palmed.util.EasyMockTestCase;
39  
40  /***
41   * Text test case.
42   *
43   * @author Mathieu Champlon
44   * @version $Revision$ $Date$
45   */
46  public class TextTest extends EasyMockTestCase
47  {
48      /***
49       * Tested object.
50       */
51      private Text text;
52      /***
53       * Mock objects.
54       */
55      private ITextView mockView;
56      /***
57       * Stub objects.
58       */
59      private ByteArrayOutputStream outputStreamStub;
60  
61      protected void setUp()
62      {
63          mockView = (ITextView)createMock( ITextView.class );
64          outputStreamStub = new ByteArrayOutputStream();
65          text = new Text();
66          text.register( mockView );
67      }
68  
69      private void assertArrayEquals( byte[] array1, byte[] array2 )
70      {
71          final MockControl controlArrayComparator = MockControl.createControl( IArrayComparator.class );
72          final IArrayComparator mockArrayComparator = (IArrayComparator)controlArrayComparator.getMock();
73          mockArrayComparator.compare( array1 );
74          controlArrayComparator.setMatcher( MockControl.ARRAY_MATCHER );
75          controlArrayComparator.replay();
76          mockArrayComparator.compare( array2 );
77          controlArrayComparator.verify();
78      }
79  
80      private ByteArrayInputStream createInputStreamStub( final String string )
81      {
82          return new ByteArrayInputStream( string.getBytes() );
83      }
84  
85      public void testViewUpdateWhenRegistered()
86      {
87          mockView.update( 0, 1 );
88          mockView.modified( false );
89          replay();
90          text.register( mockView );
91      }
92  
93      public void testSingleLineTextCreation() throws IOException
94      {
95          final String string = "string in a single line";
96          mockView.update( string.length(), 1 );
97          mockView.modified( false );
98          replay();
99          text.read( createInputStreamStub( string ) );
100         assertEquals( 1, text.getHeight() );
101         assertNull( text.getLine( -1 ) );
102         assertEquals( string, text.getLine( 0 ) );
103         assertNull( text.getLine( 1 ) );
104     }
105 
106     public void testThreeLinesTextCreation() throws IOException
107     {
108         final String string1 = "string on";
109         final String string2 = "three";
110         final String string3 = "lines";
111         mockView.update( string1.length(), 3 );
112         mockView.modified( false );
113         replay();
114         text.read( createInputStreamStub( string1 + '\n' + string2 + '\n' + string3 ) );
115         assertEquals( 3, text.getHeight() );
116         assertNull( text.getLine( -1 ) );
117         assertEquals( string1, text.getLine( 0 ) );
118         assertEquals( string2, text.getLine( 1 ) );
119         assertEquals( string3, text.getLine( 2 ) );
120     }
121 
122     public void testInsertCharacterInTheMiddleOfText() throws IOException
123     {
124         final String string = "this is my string";
125         text.read( createInputStreamStub( string ) );
126         reset();
127         mockView.update( string.length() + 1, 1 );
128         mockView.modified( true );
129         replay();
130         text.insert( new Coordinate( 7, 0 ), '*' );
131         assertEquals( "this is* my string", text.getLine( 0 ) );
132     }
133 
134     public void testInsertCharacterAfterLineLengthThrowsException() throws IOException
135     {
136         final String string = "this is my string";
137         text.read( createInputStreamStub( string ) );
138         reset();
139         try
140         {
141             text.insert( new Coordinate( 30, 0 ), '*' );
142         }
143         catch( Exception e )
144         {
145             assertEquals( string, text.getLine( 0 ) );
146             return;
147         }
148         fail();
149     }
150 
151     public void testInsertCharacterAtNegativeLineNumberThrowsException() throws IOException
152     {
153         final String string = "this is my string";
154         text.read( createInputStreamStub( string ) );
155         reset();
156         try
157         {
158             text.insert( new Coordinate( 0, -7 ), '*' );
159         }
160         catch( Exception e )
161         {
162             assertEquals( string, text.getLine( 0 ) );
163             return;
164         }
165         fail();
166     }
167 
168     public void testInsertCharacterAfterTextThrowsException() throws IOException
169     {
170         final String string = "this is my string";
171         text.read( createInputStreamStub( string ) );
172         reset();
173         try
174         {
175             text.insert( new Coordinate( 0, 30 ), '*' );
176         }
177         catch( Exception e )
178         {
179             assertEquals( string, text.getLine( 0 ) );
180             return;
181         }
182         fail();
183     }
184 
185     public void testInsertCharacterAtNegativeColumnNumberThrowsException() throws IOException
186     {
187         final String string = "this is my string";
188         text.read( createInputStreamStub( string ) );
189         reset();
190         try
191         {
192             text.insert( new Coordinate( 0, -7 ), '*' );
193         }
194         catch( Exception e )
195         {
196             assertEquals( string, text.getLine( 0 ) );
197             return;
198         }
199         fail();
200     }
201 
202     public void testInsertNewLineInTheMiddleOfText() throws IOException
203     {
204         final String string1 = "this is";
205         final String string2 = " my string";
206         text.read( createInputStreamStub( string1 + string2 ) );
207         reset();
208         mockView.update( string2.length(), 2 );
209         mockView.modified( true );
210         replay();
211         text.insertNewLine( new Coordinate( string1.length(), 0 ) );
212         assertEquals( 2, text.getHeight() );
213         assertEquals( string1, text.getLine( 0 ) );
214         assertEquals( string2, text.getLine( 1 ) );
215     }
216 
217     public void testRemoveBetweenSamePositionsIsNoOp() throws IOException
218     {
219         final String string = "this is my string";
220         text.read( createInputStreamStub( string ) );
221         reset();
222         text.remove( new Coordinate( 5, 0 ), new Coordinate( 5, 0 ) );
223         assertEquals( string, text.getLine( 0 ) );
224     }
225 
226     public void testRemoveBetweenPositionsOnSameLine() throws IOException
227     {
228         final String string1 = "abc";
229         final String string2 = "de";
230         final String string3 = "fg";
231         text.read( createInputStreamStub( string1 + string2 + string3 ) );
232         reset();
233         mockView.update( (string1 + string3).length(), 1 );
234         mockView.modified( true );
235         replay();
236         text.remove( new Coordinate( string1.length(), 0 ), new Coordinate( (string1 + string2).length(), 0 ) );
237         assertEquals( string1 + string3, text.getLine( 0 ) );
238     }
239 
240     public void testRemoveBetweenPositionsSeparatedBySeveralLines() throws IOException
241     {
242         final String string1 = "abcdef";
243         final String string2 = "ghijkl";
244         final String string3 = "mnopqr";
245         final String string4 = "stuvwx";
246         text.read( createInputStreamStub( string1 + '\n' + string2 + '\n' + string3 + '\n' + string4 ) );
247         reset();
248         final String result = "abwx";
249         mockView.update( result.length(), 1 );
250         mockView.modified( true );
251         replay();
252         text.remove( new Coordinate( 2, 0 ), new Coordinate( 4, 3 ) );
253         assertEquals( 1, text.getHeight() );
254         assertEquals( result, text.getLine( 0 ) );
255         assertNull( text.getLine( 1 ) );
256     }
257 
258     public void testGetOneLineTextReturnsSameAsSet() throws IOException
259     {
260         final String string = "this is a test";
261         text.read( createInputStreamStub( string ) );
262         reset();
263         mockView.modified( false );
264         replay();
265         text.write( outputStreamStub );
266         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
267     }
268 
269     public void testGetTwoLinesTextReturnsSameAsSet() throws IOException
270     {
271         final String string = "this is \na test";
272         text.read( createInputStreamStub( string ) );
273         reset();
274         mockView.modified( false );
275         replay();
276         text.write( outputStreamStub );
277         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
278     }
279 
280     public void testGetTextReturnsSameAsSetWithCR() throws IOException
281     {
282         final String string = "\r\rthis \r\ris a test\r\r";
283         text.read( createInputStreamStub( string ) );
284         reset();
285         mockView.modified( false );
286         replay();
287         text.write( outputStreamStub );
288         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
289     }
290 
291     public void testGetTextReturnsSameAsSetWithLF() throws IOException
292     {
293         final String string = "\n\nthis \n\nis a test\n\n";
294         text.read( createInputStreamStub( string ) );
295         reset();
296         mockView.modified( false );
297         replay();
298         text.write( outputStreamStub );
299         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
300     }
301 
302     public void testGetTextReturnsSameAsSetWithCRLF() throws IOException
303     {
304         final String string = "\r\n\r\nthis \r\n\r\nis a test\r\n\r\n";
305         text.read( createInputStreamStub( string ) );
306         reset();
307         mockView.modified( false );
308         replay();
309         text.write( outputStreamStub );
310         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
311     }
312 
313     public void testReadNullStreamThrowsAnException() throws IOException
314     {
315         try
316         {
317             text.read( null );
318         }
319         catch( IllegalArgumentException e )
320         {
321             return;
322         }
323         fail( "should throw an IllegalArgumentException" );
324     }
325 
326     public void testWritePartOnSingleLineOfText() throws IOException
327     {
328         text.read( createInputStreamStub( "this is my string" ) );
329         reset();
330         text.write( outputStreamStub, new Coordinate( 2, 0 ), new Coordinate( 12, 0 ) );
331         assertArrayEquals( "is is my s".getBytes(), outputStreamStub.toByteArray() );
332     }
333 
334     public void testWritePartOnMultipleLinesOfText() throws IOException
335     {
336         text.read( createInputStreamStub( "\n\nthis \n\nis a test\n\n" ) );
337         reset();
338         text.write( outputStreamStub, new Coordinate( 1, 2 ), new Coordinate( 2, 4 ) );
339         assertArrayEquals( "his \n\nis".getBytes(), outputStreamStub.toByteArray() );
340     }
341 
342     public void testReadPartOnSingleLineOfText() throws IOException
343     {
344         text.read( createInputStreamStub( "thtring" ) );
345         reset();
346         text.read( createInputStreamStub( "is is my s" ), new Coordinate( 2, 0 ) );
347         reset();
348         mockView.modified( false );
349         replay();
350         text.write( outputStreamStub );
351         assertArrayEquals( "this is my string".getBytes(), outputStreamStub.toByteArray() );
352     }
353 
354     public void testReadPartOnMultipleLinesOfText() throws IOException
355     {
356         text.read( createInputStreamStub( "\n\nt a test\n\n" ) );
357         reset();
358         text.read( createInputStreamStub( "his \n\nis" ), new Coordinate( 1, 2 ) );
359         reset();
360         mockView.modified( false );
361         replay();
362         text.write( outputStreamStub );
363         assertArrayEquals( "\n\nthis \n\nis a test\n\n".getBytes(), outputStreamStub.toByteArray() );
364     }
365 }