/* * Copyright (C) 2011 Laurent Caillette * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.opus; import java.io.File; import java.io.IOException; import java.util.Iterator; import org.apache.commons.lang.SystemUtils; import org.junit.Rule; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.novelang.ResourcesForTests.initialize; import static org.novelang.parser.NodeKind.*; import static org.novelang.parser.antlr.TreeFixture.tree; import org.novelang.ResourcesForTests; import org.novelang.common.Problem; import org.novelang.common.SyntacticTree; import org.novelang.common.filefixture.Resource; import org.novelang.common.filefixture.ResourceInstaller; import org.novelang.logger.Logger; import org.novelang.logger.LoggerFactory; import org.novelang.parser.antlr.TreeFixture; import org.novelang.testing.junit.MethodSupport; /** * Test for {@link Opus} and also built-in functions. * * @author Laurent Caillette */ @SuppressWarnings( { "HardcodedFileSeparator" } ) public class OpusTest { /** * Test that some parsing error produces a Problem. */ @Test public void badCommandGeneratesProblem() { final File oneWordFile = resourceInstaller.copy( ResourcesForTests.Parts.NOVELLA_ONE_WORD ) ; final Opus opus = OpusTestTools.createBook( SystemUtils.getUserDir(), "insert file:" + oneWordFile.getAbsolutePath() + " $recurse" // old syntax ) ; assertTrue( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void justInsert() { final File oneWordFile = resourceInstaller.copy( ResourcesForTests.Parts.NOVELLA_ONE_WORD ) ; final String absoluteFilePath = oneWordFile.getAbsolutePath().replace( '\\', '/' ) ; final Opus opus = OpusTestTools.createBook( SystemUtils.getUserDir(), "insert file:" + absoluteFilePath ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "oneword" ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithRecursiveFileScan() throws IOException { resourceInstaller.copy( ResourcesForTests.Scanned.dir ) ; final File scannedBookNoStyle = resourceInstaller.createFileObject( ResourcesForTests.Scanned.BOOK ) ; final Opus opus = OpusTestTools.createBook( scannedBookNoStyle ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "6" ) ), tree( _LEVEL, tree( LEVEL_TITLE, tree( WORD_, "file1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file1" ) ) ), tree( _LEVEL, tree( LEVEL_TITLE, tree( WORD_, "file2" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file2" ) ) ), tree( _LEVEL, tree( LEVEL_TITLE, tree( WORD_, "file3" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file3" ) ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithFlatFileScan() throws IOException { resourceInstaller.copy( ResourcesForTests.Scanned.dir ) ; final File scannedBookNoStyleNoRecurse = resourceInstaller.createFileObject( ResourcesForTests.Scanned.BOOK_NORECURSE ) ; final Opus opus = OpusTestTools.createBook( scannedBookNoStyleNoRecurse ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "2" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file2" ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithFileScanAndStyle() throws IOException { resourceInstaller.copy( ResourcesForTests.Scanned.dir ) ; final File scannedBookWithStyle = resourceInstaller.createFileObject( ResourcesForTests.Scanned.BOOK_WITHSTYLE ) ; final Opus opus = OpusTestTools.createBook( scannedBookWithStyle ); LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "6" ) ), tree( _LEVEL, tree( _STYLE, tree( CUSTOM_STYLE ) ), tree( LEVEL_TITLE, tree( WORD_, "file1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file1" ) ) ), tree( _LEVEL, tree( _STYLE, tree( CUSTOM_STYLE ) ), tree( LEVEL_TITLE, tree( WORD_, "file2" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file2" ) ) ), tree( _LEVEL, tree( _STYLE, tree( CUSTOM_STYLE ) ), tree( LEVEL_TITLE, tree( WORD_, "file3" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "content-of-file3" ) ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithBadPart() throws IOException { resourceInstaller.copy( ResourcesForTests.Served.BROKEN_NOVELLA ) ; final File scannedBookWithBadPart = resourceInstaller.copy( ResourcesForTests.Served.BROKEN_BOOK_BAD_SCANNED_NOVELLA ) ; final Opus opus = OpusTestTools.createBook( scannedBookWithBadPart ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; assertTrue( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand} and empty Novella detection * in {@link org.novelang.common.AbstractSourceReader}. */ @Test public void insertEmptyPart() throws IOException { final Resource emptyPartResource = ResourcesForTests.BookWithEmptyPart.EMPTY_NOVELLA; resourceInstaller.copy( emptyPartResource ) ; final File bookFile = resourceInstaller.copy( ResourcesForTests.BookWithEmptyPart.BOOK ) ; final Opus opus = OpusTestTools.createBook( bookFile ) ; final Iterator< Problem > problems = opus.getProblems().iterator() ; assertTrue( problems.hasNext() ) ; final Problem problem = problems.next() ; assertTrue( problem.getMessage().contains( "Novella is empty" ) ) ; assertTrue( problem.getLocation().getFileName().contains( emptyPartResource.getBaseName() ) ) ; assertFalse( problems.hasNext() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void detectMissingImage() throws IOException { resourceInstaller.copy( ResourcesForTests.MissingImages.MISSING_IMAGE_PART ) ; final File scannedBookWithBadImage = resourceInstaller.copy( ResourcesForTests.MissingImages.MISSING_IMAGE_BOOK ) ; final Opus opus = OpusTestTools.createBook( scannedBookWithBadImage ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; assertTrue( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithExplicitIdentifiers() throws IOException { resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.BOOK_1 ) ; resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.NOVELLA_1 ) ; final File bookWithIdentifier = resourceInstaller.createFileObject( ResourcesForTests.Identifiers.BOOK_1 ) ; final Opus opus = OpusTestTools.createBook( bookWithIdentifier ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "2" ) ), tree( _LEVEL, tree( _EXPLICIT_IDENTIFIER, tree( "IdentifierTwo" ) ), tree( _IMPLICIT_TAG, "LevelTwo" ), tree( LEVEL_TITLE, tree( WORD_, "LevelTwo" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "Paragraph" ) ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithPromotedTags() throws IOException { final File bookWithTags = resourceInstaller.copyWithPath( ResourcesForTests.TaggedPart.PROMOTED_TAGS_BOOK ) ; resourceInstaller.copyWithPath( ResourcesForTests.TaggedPart.PROMOTED_TAGS_PART_1 ) ; final Opus opus = OpusTestTools.createBook( bookWithTags ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; assertFalse( opus.hasProblem() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "7" ), tree( _TAGS, tree( _EXPLICIT_TAG, "Bar" ), tree( _EXPLICIT_TAG, "Foo" ) ) ), tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, tree( "FooAndBar" ) ), tree( _EXPLICIT_TAG, "Bar" ), tree( _EXPLICIT_TAG, "Foo" ), tree( LEVEL_TITLE, tree( WORD_, "Foo" ), tree( WORD_, "and" ), tree( WORD_, "Bar" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "y" ), tree( APOSTROPHE_WORDMATE, "'" ), tree( _PRESERVED_WHITESPACE ), tree( WORD_, "z" ), tree( PUNCTUATION_SIGN, tree( SIGN_FULLSTOP, "." ) ) ) ), tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, tree( "Foo_Bar" ) ), tree( _PROMOTED_TAG, "Bar" ), tree( _PROMOTED_TAG, "Foo" ), tree( LEVEL_TITLE, tree( WORD_, "Foo" ), tree( PUNCTUATION_SIGN, tree( SIGN_COMMA, "," ) ), tree( WORD_, "Bar" ) ) ) ), bookTree ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithImplicitIdentifiers() throws IOException { final File bookWithIdentifier = resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.BOOK_2 ) ; resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.NOVELLA_2 ) ; final Opus opus = OpusTestTools.createBook( bookWithIdentifier ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "6" ) ), tree( _LEVEL, tree( _IMPLICIT_TAG, "L0-1" ), tree( LEVEL_TITLE, tree( WORD_, "L0-1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p0-1" ) ) ), tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, tree( "L1" ) ), tree( _IMPLICIT_TAG, "L1" ), tree( LEVEL_TITLE, tree( WORD_, "L1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p1" ) ) ), tree( _LEVEL, tree( _IMPLICIT_TAG, "L0-1" ), tree( LEVEL_TITLE, tree( WORD_, "L0-1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p0-1" ) ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithCollidingIdentifiers() throws IOException { final File bookWithIdentifier = resourceInstaller.copy( ResourcesForTests.Identifiers.BOOK_4 ) ; resourceInstaller.copy( ResourcesForTests.Identifiers.Subdirectory4.dir ) ; final Opus opus = OpusTestTools.createBook( bookWithIdentifier ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "4" ) ), tree( _LEVEL, tree( _COLLIDING_EXPLICIT_IDENTIFIER, "Collider" ), tree( _IMPLICIT_TAG, "L0" ), tree( LEVEL_TITLE, tree( WORD_, "L0" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p0" ) ) ), tree( _LEVEL, tree( _COLLIDING_EXPLICIT_IDENTIFIER, "Collider" ), tree( _IMPLICIT_TAG, "L1" ), tree( LEVEL_TITLE, tree( WORD_, "L1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p1" ) ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertWithRecurseShouldKeepImplicitIdentifiers() throws IOException { final File bookWithIdentifier = resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.BOOK_3_RECURSE ) ; resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.Subdirectory3.PART_3 ) ; verifyBook3( bookWithIdentifier ); } /** * Test {@link org.novelang.opus.function.builtin.InsertCommand}. */ @Test public void insertShouldKeepImplicitIdentifiers() throws IOException { final File bookWithIdentifier = resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.BOOK_3_STRAIGHT ) ; resourceInstaller.copyWithPath( ResourcesForTests.Identifiers.Subdirectory3.PART_3 ) ; verifyBook3( bookWithIdentifier ); } // ======= // Fixture // ======= static { initialize() ; } private static final Logger LOGGER = LoggerFactory.getLogger( OpusTest.class ); @Rule public final MethodSupport methodSupport = new MethodSupport() ; private final ResourceInstaller resourceInstaller = new ResourceInstaller( methodSupport ) ; public static final String CUSTOM_STYLE = "mystyle" ; private static void verifyBook3( final File bookWithIdentifier ) throws IOException { final Opus opus = OpusTestTools.createBook( bookWithIdentifier ) ; LOGGER.debug( "Opus's document tree: ", opus.getDocumentTree().toStringTree() ) ; final SyntacticTree bookTree = opus.getDocumentTree() ; TreeFixture.assertEqualsNoSeparators( tree( OPUS, tree( _META, tree( _WORD_COUNT, "8" ) ), tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, tree( "L0" ) ), tree( _IMPLICIT_TAG, "L0" ), tree( LEVEL_TITLE, tree( WORD_, "L0" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p0" ) ), tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, tree( "L0-0" ) ), tree( _IMPLICIT_TAG, "L0-0" ), tree( LEVEL_TITLE, tree( WORD_, "L0-0" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p0-0" ) ) ), tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, tree( "L0-1" ) ), tree( _IMPLICIT_TAG, "L0-1" ), tree( LEVEL_TITLE, tree( WORD_, "L0-1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p0-1" ) ) ) ), tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, tree( "L1" ) ), tree( _IMPLICIT_TAG, "L1" ), tree( LEVEL_TITLE, tree( WORD_, "L1" ) ), tree( PARAGRAPH_REGULAR, tree( WORD_, "p1" ) ) ) ), bookTree ) ; assertFalse( opus.hasProblem() ) ; } }