001/*
002 *   Copyright (C) 2005 Christian Schulte <cs@schulte.it>
003 *   All rights reserved.
004 *
005 *   Redistribution and use in source and binary forms, with or without
006 *   modification, are permitted provided that the following conditions
007 *   are met:
008 *
009 *     o Redistributions of source code must retain the above copyright
010 *       notice, this list of conditions and the following disclaimer.
011 *
012 *     o Redistributions in binary form must reproduce the above copyright
013 *       notice, this list of conditions and the following disclaimer in
014 *       the documentation and/or other materials provided with the
015 *       distribution.
016 *
017 *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
018 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
019 *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
020 *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
021 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
022 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
023 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
024 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
026 *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027 *
028 *   $JOMC: SectionEditorTest.java 5291 2016-08-29 17:31:15Z schulte $
029 *
030 */
031package org.jomc.util.test;
032
033import java.io.BufferedReader;
034import java.io.IOException;
035import java.io.InputStream;
036import java.io.StringReader;
037import java.util.concurrent.ExecutorService;
038import org.apache.commons.io.IOUtils;
039import org.jomc.util.LineEditor;
040import org.jomc.util.Section;
041import org.jomc.util.SectionEditor;
042import org.junit.After;
043import org.junit.Test;
044import static org.junit.Assert.assertEquals;
045import static org.junit.Assert.assertFalse;
046import static org.junit.Assert.assertNotNull;
047import static org.junit.Assert.assertTrue;
048import static org.junit.Assert.fail;
049
050/**
051 * Test cases for class {@code org.jomc.util.SectionEditor}.
052 *
053 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
054 * @version $JOMC: SectionEditorTest.java 5291 2016-08-29 17:31:15Z schulte $
055 */
056public class SectionEditorTest extends LineEditorTest
057{
058
059    /**
060     * Constant to prefix relative resource names with.
061     */
062    private static final String ABSOLUTE_RESOURCE_NAME_PREFIX = "/org/jomc/util/test/";
063
064    /**
065     * The {@code ExecutorService} backing the tests.
066     */
067    private ExecutorService executorService;
068
069    /**
070     * Creates a new {@code SectionEditorTest} instance.
071     */
072    public SectionEditorTest()
073    {
074        super();
075    }
076
077    /**
078     * {@inheritDoc}
079     */
080    @Override
081    public SectionEditor getLineEditor()
082    {
083        return (SectionEditor) super.getLineEditor();
084    }
085
086    /**
087     * {@inheritDoc}
088     */
089    @Override
090    protected SectionEditor newLineEditor()
091    {
092        final SectionEditor sectionEditor = new SectionEditor()
093        {
094
095            @Override
096            protected void editSection( final Section section ) throws IOException
097            {
098                super.editSection( section );
099
100                if ( section.getName() != null )
101                {
102                    section.getHeadContent().append( section.getName() ).append( " Head" ).
103                        append( this.getLineSeparator() );
104
105                    section.getTailContent().append( section.getName() ).append( " Tail" ).
106                        append( this.getLineSeparator() );
107
108                }
109            }
110
111        };
112
113        sectionEditor.setExecutorService( this.getExecutorService() );
114        return sectionEditor;
115    }
116
117    /**
118     * {@inheritDoc}
119     */
120    @Override
121    protected SectionEditor newLineEditor( final LineEditor editor )
122    {
123        final SectionEditor sectionEditor = new SectionEditor( editor );
124        sectionEditor.setExecutorService( this.getExecutorService() );
125        return sectionEditor;
126    }
127
128    /**
129     * Gets the {@code ExecutorService} backing the tests.
130     *
131     * @return The {@code ExecutorService} backing the tests.
132     *
133     * @see #newExecutorService()
134     * @since 1.10
135     */
136    public final ExecutorService getExecutorService()
137    {
138        if ( this.executorService == null )
139        {
140            this.executorService = this.newExecutorService();
141        }
142
143        return this.executorService;
144    }
145
146    /**
147     * Creates a new {@code ExecutorService} backing the tests.
148     *
149     * @return A new {@code ExecutorService} backing the tests, or {@code null}.
150     *
151     * @see #getExecutorService()
152     * @since 1.10
153     */
154    protected ExecutorService newExecutorService()
155    {
156        return null;
157    }
158
159    /**
160     * Shuts down the {@code ExecutorService} backing the tests, if not {@code null}.
161     */
162    @After
163    public final void shutdown()
164    {
165        if ( this.executorService != null )
166        {
167            this.executorService.shutdown();
168            this.executorService = null;
169        }
170    }
171
172    @Test
173    public final void testSectionEditor() throws Exception
174    {
175        String test = this.getResource( ABSOLUTE_RESOURCE_NAME_PREFIX + "TestSections.txt" );
176        String expected =
177            convertLineSeparator( this.getResource( ABSOLUTE_RESOURCE_NAME_PREFIX + "TestSectionsEdited.txt" ) );
178
179        String edited = this.getLineEditor().edit( test );
180
181        System.out.println( "TEST:" );
182        System.out.println( test );
183        System.out.println( "EXPECTED:" );
184        System.out.println( expected );
185        System.out.println( "EDITED:" );
186        System.out.println( edited );
187
188        assertEquals( expected, edited );
189        assertTrue( this.getLineEditor().isSectionPresent( "1" ) );
190        assertTrue( this.getLineEditor().isSectionPresent( "1.1" ) );
191        assertTrue( this.getLineEditor().isSectionPresent( "1.1.1" ) );
192        assertTrue( this.getLineEditor().isSectionPresent( "1.1.1.1" ) );
193        assertTrue( this.getLineEditor().isSectionPresent( "1.2" ) );
194        assertTrue( this.getLineEditor().isSectionPresent( "1.3" ) );
195        assertTrue( this.getLineEditor().isSectionPresent( "1.4" ) );
196        assertTrue( this.getLineEditor().isSectionPresent( "2" ) );
197        assertTrue( this.getLineEditor().isSectionPresent( "3" ) );
198        assertTrue( this.getLineEditor().isSectionPresent( "4" ) );
199        assertTrue( this.getLineEditor().isSectionPresent( "5" ) );
200        assertTrue( this.getLineEditor().isSectionPresent( "6" ) );
201        assertTrue( this.getLineEditor().isSectionPresent( "7" ) );
202        assertTrue( this.getLineEditor().isSectionPresent( "8" ) );
203        assertTrue( this.getLineEditor().isSectionPresent( "9" ) );
204        assertTrue( this.getLineEditor().isSectionPresent( "10" ) );
205
206        test = this.getResource( ABSOLUTE_RESOURCE_NAME_PREFIX + "TestSectionsCont.txt" );
207        expected =
208            convertLineSeparator( this.getResource( ABSOLUTE_RESOURCE_NAME_PREFIX + "TestSectionsContEdited.txt" ) );
209
210        edited = this.getLineEditor().edit( test );
211
212        System.out.println( "TEST:" );
213        System.out.println( test );
214        System.out.println( "EXPECTED:" );
215        System.out.println( expected );
216        System.out.println( "EDITED:" );
217        System.out.println( edited );
218
219        assertEquals( expected, edited );
220        assertTrue( this.getLineEditor().isSectionPresent( "1" ) );
221        assertTrue( this.getLineEditor().isSectionPresent( "1.1" ) );
222        assertTrue( this.getLineEditor().isSectionPresent( "1.1.1" ) );
223        assertTrue( this.getLineEditor().isSectionPresent( "2" ) );
224        assertFalse( this.getLineEditor().isSectionPresent( "10" ) );
225
226        this.assertUnmatchedSections( ABSOLUTE_RESOURCE_NAME_PREFIX + "UnmatchedSectionTest.txt" );
227        this.assertUnmatchedSections( ABSOLUTE_RESOURCE_NAME_PREFIX + "UnmatchedSectionsTest.txt" );
228        this.assertUnmatchedSections( ABSOLUTE_RESOURCE_NAME_PREFIX + "UnmatchedSubsectionTest.txt" );
229        this.assertUnmatchedSections( ABSOLUTE_RESOURCE_NAME_PREFIX + "UnmatchedSubsectionsTest.txt" );
230        this.assertUnmatchedSections( ABSOLUTE_RESOURCE_NAME_PREFIX + "MissingSectionStartTest.txt" );
231        this.assertUnmatchedSections( ABSOLUTE_RESOURCE_NAME_PREFIX + "MissingSectionsStartTest.txt" );
232
233        final StringBuilder testNoSections = new StringBuilder();
234        final StringBuilder expectedNoSections = new StringBuilder();
235
236        for ( int i = 1000; i >= 0; i-- )
237        {
238            testNoSections.append( "Hello editor.\n" );
239            expectedNoSections.append( "Hello editor." ).append( this.getLineEditor().getLineSeparator() );
240        }
241
242        assertEquals( expectedNoSections.toString(), this.getLineEditor().edit( testNoSections.toString() ) );
243
244        try
245        {
246            this.getLineEditor().edit( "SECTION-START[Test\nSECTION-END\n" );
247        }
248        catch ( final IOException e )
249        {
250            assertNotNull( e.getMessage() );
251            System.out.println( e.toString() );
252        }
253    }
254
255    private void assertUnmatchedSections( final String resourceName ) throws Exception
256    {
257        try
258        {
259            this.getLineEditor().edit( this.getResource( resourceName ) );
260            fail( "Expected IOException not thrown for resource '" + resourceName + "'." );
261        }
262        catch ( final IOException e )
263        {
264            assertNotNull( e.getMessage() );
265            System.out.println( e.toString() );
266        }
267    }
268
269    private static String convertLineSeparator( final String s ) throws IOException
270    {
271        BufferedReader reader = null;
272        boolean suppressExceptionOnClose = true;
273
274        try
275        {
276            final StringBuilder b = new StringBuilder();
277            reader = new BufferedReader( new StringReader( s ) );
278
279            String line;
280            while ( ( line = reader.readLine() ) != null )
281            {
282                b.append( line ).append( System.getProperty( "line.separator", "\n" ) );
283            }
284
285            suppressExceptionOnClose = false;
286            return b.toString();
287        }
288        finally
289        {
290            try
291            {
292                if ( reader != null )
293                {
294                    reader.close();
295                }
296            }
297            catch ( final IOException e )
298            {
299                if ( !suppressExceptionOnClose )
300                {
301                    throw e;
302                }
303            }
304        }
305    }
306
307    private String getResource( final String resourceName ) throws IOException
308    {
309
310        InputStream in = null;
311        boolean suppressExceptionOnClose = true;
312        assertTrue( resourceName.startsWith( "/" ) );
313
314        try
315        {
316            in = this.getClass().getResourceAsStream( resourceName );
317            assertNotNull( "Resource '" + resourceName + "' not found.", in );
318            final String content = IOUtils.toString( in, this.getResourceEncoding() );
319            suppressExceptionOnClose = false;
320            return content;
321        }
322        finally
323        {
324            try
325            {
326                if ( in != null )
327                {
328                    in.close();
329                }
330            }
331            catch ( final IOException e )
332            {
333                if ( !suppressExceptionOnClose )
334                {
335                    throw e;
336                }
337            }
338        }
339    }
340
341}