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 java.io.InputStream;
37  import java.io.OutputStream;
38  import java.util.Enumeration;
39  import java.util.Vector;
40  import org.easymock.MockControl;
41  import palmed.edit.util.Coordinate;
42  import palmed.util.EasyMockTestCase;
43  
44  /***
45   * LargeText test case.
46   *
47   * @author Mathieu Champlon
48   * @version $Revision$ $Date$
49   */
50  public class LargeTextTest extends EasyMockTestCase
51  {
52      private static final int THRESHOLD = 20;
53      /***
54       * Tested object.
55       */
56      private LargeText text;
57      /***
58       * Mock objects.
59       */
60      private ITextView mockView;
61      /***
62       * Stub objects.
63       */
64      private ByteArrayOutputStream outputStreamStub;
65  
66      private class NullCache implements ICache
67      {
68          private Vector elements_ = new Vector();
69  
70          public void wake( ICachable cachable )
71          {
72          }
73  
74          public void sleep( ICachable cachable )
75          {
76          }
77  
78          public void clear()
79          {
80              elements_.removeAllElements();
81          }
82  
83          public Enumeration elements()
84          {
85              return elements_.elements();
86          }
87  
88          public void add( ICachable chunk )
89          {
90              elements_.addElement( chunk );
91          }
92  
93          public void unmarshall( InputStream stream )
94          {
95          }
96  
97          public void marshall( OutputStream stream )
98          {
99          }
100 
101         public void delete()
102         {
103             clear();
104         }
105     }
106 
107     protected final void setUp()
108     {
109         mockView = (ITextView)createMock( ITextView.class );
110         text = new LargeText( new NullCache(), THRESHOLD );
111         outputStreamStub = new ByteArrayOutputStream();
112         text.register( mockView );
113     }
114 
115     private void assertArrayEquals( byte[] array1, byte[] array2 )
116     {
117         final MockControl controlArrayComparator = MockControl.createControl( IArrayComparator.class );
118         final IArrayComparator mockArrayComparator = (IArrayComparator)controlArrayComparator.getMock();
119         mockArrayComparator.compare( array1 );
120         controlArrayComparator.setMatcher( MockControl.ARRAY_MATCHER );
121         controlArrayComparator.replay();
122         mockArrayComparator.compare( array2 );
123         controlArrayComparator.verify();
124     }
125 
126     private ByteArrayInputStream createInputStreamStub( final String string )
127     {
128         return new ByteArrayInputStream( string.getBytes() );
129     }
130 
131     public void testNewTextIsEmpty()
132     {
133         assertEquals( 1, text.getHeight() );
134         assertEquals( "", text.getLine( 0 ) );
135         assertNull( text.getLine( 1 ) );
136     }
137 
138     public void testInsertCharacterInNewText()
139     {
140         mockView.update( 1, 1 );
141         mockView.modified( true );
142         replay();
143         text.insert( new Coordinate( 0, 0 ), '*' );
144         assertEquals( "*", text.getLine( 0 ) );
145     }
146 
147     public void testReadAndWriteOneLineTextSmallerThanThreshold() throws IOException
148     {
149         final String string = "this is my string";
150         assertTrue( THRESHOLD > string.length() );
151         mockView.update( string.length(), 1 );
152         mockView.modified( false );
153         replay();
154         text.read( createInputStreamStub( string ) );
155         verify();
156         reset();
157         mockView.modified( false );
158         replay();
159         text.write( outputStreamStub );
160         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
161         assertEquals( 1, text.getHeight() );
162         assertNull( text.getLine( -1 ) );
163         assertEquals( string, text.getLine( 0 ) );
164         assertNull( text.getLine( 1 ) );
165     }
166 
167     public void testReadAndWriteOneLongLineTextLargerThanThreshold() throws IOException
168     {
169         final String string = "this is my very long string larger than three times the threshold";
170         assertTrue( 3 * THRESHOLD < string.length() );
171         mockView.update( string.length(), 1 );
172         mockView.modified( false );
173         replay();
174         text.read( createInputStreamStub( string ) );
175         verify();
176         reset();
177         mockView.modified( false );
178         replay();
179         text.write( outputStreamStub );
180         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
181         assertEquals( 1, text.getHeight() );
182         assertNull( text.getLine( -1 ) );
183         assertEquals( string, text.getLine( 0 ) );
184         assertNull( text.getLine( 1 ) );
185     }
186 
187     public void testReadAndWriteTextLargerThanThreshold() throws IOException
188     {
189         final String string = "\nthis\n is\n\n my\n string larger than threshold\n";
190         assertTrue( THRESHOLD < string.length() );
191         mockView.update( 29, 7 );
192         mockView.modified( false );
193         replay();
194         text.read( createInputStreamStub( string ) );
195         verify();
196         reset();
197         mockView.modified( false );
198         replay();
199         text.write( outputStreamStub );
200         assertArrayEquals( string.getBytes(), outputStreamStub.toByteArray() );
201         assertEquals( 7, text.getHeight() );
202         assertNull( text.getLine( -1 ) );
203         assertEquals( "", text.getLine( 0 ) );
204         assertEquals( "this", text.getLine( 1 ) );
205         assertEquals( " is", text.getLine( 2 ) );
206         assertEquals( "", text.getLine( 3 ) );
207         assertEquals( " my", text.getLine( 4 ) );
208         assertEquals( " string larger than threshold", text.getLine( 5 ) );
209         assertEquals( "", text.getLine( 6 ) );
210         assertNull( text.getLine( 7 ) );
211     }
212 
213     public void testInsertCharacterInTextSmallerThanThreshold() throws IOException
214     {
215         final String string = "this is my string";
216         assertTrue( THRESHOLD > string.length() );
217         text.read( createInputStreamStub( string ) );
218         mockView.modified( false );
219         reset();
220         mockView.update( string.length() + 1, 1 );
221         mockView.modified( true );
222         replay();
223         text.insert( new Coordinate( 7, 0 ), '*' );
224         assertEquals( "this is* my string", text.getLine( 0 ) );
225     }
226 
227     public void testInsertCharacterAfterLineLengthThrowsException() throws IOException
228     {
229         final String string = "\nthis\n is\n\n my\n string larger than threshold\n";
230         assertTrue( THRESHOLD < string.length() );
231         text.read( createInputStreamStub( string ) );
232         reset();
233         try
234         {
235             text.insert( new Coordinate( 1, 0 ), '*' );
236         }
237         catch( Exception e )
238         {
239             return;
240         }
241         fail();
242     }
243 
244     public void testInsertCharacterAtNegativeLineNumberThrowsException() throws IOException
245     {
246         final String string = "\nthis\n is\n\n my\n string larger than threshold\n";
247         assertTrue( THRESHOLD < string.length() );
248         text.read( createInputStreamStub( string ) );
249         reset();
250         try
251         {
252             text.insert( new Coordinate( 0, -1 ), '*' );
253         }
254         catch( Exception e )
255         {
256             return;
257         }
258         fail();
259     }
260 
261     public void testInsertCharacterAfterTextThrowsException() throws IOException
262     {
263         final String string = "\nthis\n is\n\n my\n string larger than threshold\n";
264         assertTrue( THRESHOLD < string.length() );
265         text.read( createInputStreamStub( string ) );
266         reset();
267         try
268         {
269             text.insert( new Coordinate( 0, 7 ), '*' );
270         }
271         catch( Exception e )
272         {
273             return;
274         }
275         fail();
276     }
277 
278     public void testInsertCharacterAtNegativeColumnNumberThrowsException() throws IOException
279     {
280         final String string = "\nthis\n is\n\n my\n string larger than threshold\n";
281         assertTrue( THRESHOLD < string.length() );
282         text.read( createInputStreamStub( string ) );
283         reset();
284         try
285         {
286             text.insert( new Coordinate( 0, -1 ), '*' );
287         }
288         catch( Exception e )
289         {
290             return;
291         }
292         fail();
293     }
294 
295     public void testInsertCharacterInOneLineTextLargerThanThreshold() throws IOException
296     {
297         final String string = "this is my very long string larger than three times the threshold";
298         assertTrue( 3 * THRESHOLD < string.length() );
299         text.read( createInputStreamStub( string ) );
300         reset();
301         mockView.update( string.length() + 1, 1 );
302         mockView.modified( true );
303         replay();
304         text.insert( new Coordinate( THRESHOLD + 1, 0 ), '*' );
305         assertEquals( "this is my very long *string larger than three times the threshold", text.getLine( 0 ) );
306         verify();
307         reset();
308         mockView.update( string.length() + 2, 1 );
309         mockView.modified( true );
310         replay();
311         text.insert( new Coordinate( THRESHOLD, 0 ), '*' );
312         assertEquals( "this is my very long* *string larger than three times the threshold", text.getLine( 0 ) );
313         verify();
314         reset();
315         mockView.update( string.length() + 3, 1 );
316         mockView.modified( true );
317         replay();
318         text.insert( new Coordinate( THRESHOLD - 1, 0 ), '*' );
319         assertEquals( "this is my very lon*g* *string larger than three times the threshold", text.getLine( 0 ) );
320     }
321 
322     public void testInsertCharacterInTextLargerThanThreshold() throws IOException
323     {
324         final String string = "\nthis\n is\n\n my\n string larger than threshold\n";
325         assertTrue( THRESHOLD < string.length() );
326         text.read( createInputStreamStub( string ) );
327         reset();
328         mockView.update( 30, 7 );
329         mockView.modified( true );
330         replay();
331         text.insert( new Coordinate( 29, 5 ), '*' );
332         assertEquals( " string larger than threshold*", text.getLine( 5 ) );
333     }
334 
335     public void testRemoveFromTextSmallerThanThreshold() throws IOException
336     {
337         final String string = "this is my string";
338         assertTrue( THRESHOLD > string.length() );
339         text.read( createInputStreamStub( string ) );
340         reset();
341         mockView.update( string.length() - 3, 1 );
342         mockView.modified( true );
343         replay();
344         text.remove( new Coordinate( 7, 0 ), new Coordinate( 10, 0 ) );
345         assertEquals( "this is string", text.getLine( 0 ) );
346     }
347 
348     public void testRemoveFromOneLongLineTextLargerThanThreshold() throws IOException
349     {
350         final String string = "this is my very long string larger than three times the threshold";
351         assertTrue( 3 * THRESHOLD < string.length() );
352         text.read( createInputStreamStub( string ) );
353         reset();
354         mockView.update( string.length() - 1, 1 );
355         mockView.modified( true );
356         replay();
357         text.remove( new Coordinate( THRESHOLD - 2, 0 ), new Coordinate( THRESHOLD - 1, 0 ) );
358         assertEquals( "this is my very log string larger than three times the threshold", text.getLine( 0 ) );
359         verify();
360         reset();
361         mockView.update( string.length() - 2, 1 );
362         mockView.modified( true );
363         replay();
364         text.remove( new Coordinate( THRESHOLD + 3, 0 ), new Coordinate( THRESHOLD + 4, 0 ) );
365         assertEquals( "this is my very log strng larger than three times the threshold", text.getLine( 0 ) );
366         verify();
367         reset();
368         mockView.update( string.length() - 8, 1 );
369         mockView.modified( true );
370         replay();
371         text.remove( new Coordinate( THRESHOLD - 3, 0 ), new Coordinate( THRESHOLD + 3, 0 ) );
372         assertEquals( "this is my very lng larger than three times the threshold", text.getLine( 0 ) );
373     }
374 
375     public void testRemoveFromMultipleLinesTextLargerThanThreshold() throws IOException
376     {
377         final String string = "\nthis\n is\n\n my\n string larger than threshold\n";
378         assertTrue( THRESHOLD < string.length() );
379         text.read( createInputStreamStub( string ) );
380         reset();
381         mockView.update( 16, 3 );
382         mockView.modified( true );
383         replay();
384         text.remove( new Coordinate( 2, 1 ), new Coordinate( 15, 5 ) );
385         assertEquals( "", text.getLine( 0 ) );
386         assertEquals( "ththan threshold", text.getLine( 1 ) );
387         assertEquals( "", text.getLine( 2 ) );
388         assertNull( text.getLine( 3 ) );
389     }
390 }