package org.androiddaisyreader.model;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.androiddaisyreader.testutilities.CreateDaisy202Book;
import org.androiddaisyreader.testutilities.NotImplementedException;
public class NavigatorTest extends TestCase {
private static final String SECTIONS_FOR_COMPLEX_NCC = "123123211123454566";
private ByteArrayInputStream bookContents;
private Navigator navigator;
@Override
protected void setUp() {
bookContents = NccSpecificationTest.createNCC();
Book book = null;
try {
book = NccSpecification.readFromStream(bookContents);
} catch (IOException e) {
// We cannot throw an exception from setUp so this is all we're doing...
e.printStackTrace();
}
navigator = new Navigator(book);
}
public void testNavigationFromStartToEndOfBook() {
int elements = 0;
while (navigator.hasNext()) {
Navigable n = navigator.next();
assertTrue(n != null);
elements++;
}
assertSectionsFound(NccSpecificationTest.FIVE_SECTIONS, elements);
}
/**
* Assert Sections Found is a convenience method that counts sections.
*
* The convenience is in the more descriptive message when the count does
* not match.
*
* @param sections
* @param numberOfSections
*/
private void assertSectionsFound(String sections, int numberOfSections) {
int sectionsFound = sections.length();
String message = String.format(
"Expected %d elements for a book with sections [%s]",
sectionsFound, numberOfSections);
assertEquals(message, numberOfSections, sectionsFound);
}
public void testNavigationBackwardsThroughBook() {
List<Integer> sectionsFound = new ArrayList<Integer>();
// First we need to reach the end of the book
while (navigator.hasNext()) {
navigator.next();
}
// We should be at the end of the book now.
while (navigator.hasPrevious()) {
Navigable n = navigator.previous();
assertTrue(n != null);
Section s = (Section)n;
sectionsFound.add(s.level);
}
assertSectionsFound(NccSpecificationTest.FIVE_SECTIONS, sectionsFound.size());
String reversedSections = new StringBuilder(NccSpecificationTest.FIVE_SECTIONS).reverse().toString();
assertSectionsEquals(reversedSections, sectionsFound);
}
/**
* Assert the Sections Equals
* @param expectedSectionsInOrder list of section levels in the expected order
* @param sectionsFound the actual levels found
*/
private void assertSectionsEquals(String expectedSectionsInOrder, List<Integer> sectionsFound) {
int sectionToCompare = expectedSectionsInOrder.length();
while (sectionToCompare-- > 0) {
Integer level = Character.getNumericValue(expectedSectionsInOrder.charAt(sectionToCompare));
assertEquals(level, (Integer) sectionsFound.get(sectionToCompare));
}
}
public void testNavigationOfComplexDaisy202BookStructure() throws NotImplementedException, IOException {
DaisyBook book = createDaisy202Structure(SECTIONS_FOR_COMPLEX_NCC);
Navigator navigator = new Navigator(book);
navigator.gotoStartOfContent();
int elements = 0;
while (navigator.hasNext()) {
Navigable n = navigator.next();
assertSectionEquals(SECTIONS_FOR_COMPLEX_NCC, elements, n);
elements++;
}
assertEquals("Expected to process all elements",
SECTIONS_FOR_COMPLEX_NCC.length(), elements);
}
public void testForwardAndBackwardNavigationOfComplexDaisy202BookStructure() throws NotImplementedException, IOException {
DaisyBook book = createDaisy202Structure(SECTIONS_FOR_COMPLEX_NCC);
Navigator localNavigator = new Navigator(book);
localNavigator.gotoStartOfContent();
int position;
ArrayList<Integer> levelsTraversed = new ArrayList<Integer>();
for (int sectionsToTraverse = 0; sectionsToTraverse < SECTIONS_FOR_COMPLEX_NCC.length(); sectionsToTraverse++) {
position = 0;
while (localNavigator.hasNext() && position < sectionsToTraverse) {
Navigable n = localNavigator.next();
assertSectionEquals(SECTIONS_FOR_COMPLEX_NCC, position, n);
levelsTraversed.add(((Section)n).getLevel());
position++;
}
assertEquals(
String.format("Didn't traverse the expected number of sections in: %s",
SECTIONS_FOR_COMPLEX_NCC),
sectionsToTraverse, position);
Navigable n;
while (position > 0 && localNavigator.hasPrevious()) {
position--; // Useful to decrement now as we can use it as the array index.
n = localNavigator.previous();
int expectedValue = levelsTraversed.get(position);
int levelFound = ((Section)n).getLevel();
assertEquals("Expected the level returned to match that discovered from the forward navigation.", expectedValue, levelFound);
}
levelsTraversed.clear();
}
}
public void testSmilFilenamesAreCaptured() {
Navigable n = null;
String smilFilename = null;
while (navigator.hasNext()) {
n = navigator.next();
smilFilename = ((DaisySection)n).getSmilFilename();
assertSmilFilename(smilFilename);
}
}
/**
* assert the SMIL filename matches the pattern we use in these tests.
* @param smilFilename the smilfilename
*/
private void assertSmilFilename(String smilFilename) {
assertTrue(smilFilename.startsWith("test"));
assertTrue(smilFilename.endsWith(".smil"));
}
/**
* assertSectionEquals compare section contains the correct value.
*
* The value of the section at position is compared with the contents of
* the navigable item.
* @param structure The string that represents the sequence of sections.
* @param position The position within the structure to compare against.
* @param n the Navigable item.
*/
void assertSectionEquals(String structure, int position, Navigable n) {
assertEquals(
String.format(
"Section should be in correct sequence. Sequence [%s] element [%d]",
structure, position),
Character.getNumericValue((structure.charAt(position))),
((Section)n).getLevel());
}
/**
* Helper method to create a Daisy202 Ncc Structure.
* @param structure to create as a numeric string e.g. 11231
* @return a Daisy202Book structure
* @throws NotImplementedException
* @throws IOException
*/
DaisyBook createDaisy202Structure(String structure) throws NotImplementedException,
IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
CreateDaisy202Book eBookContents = new CreateDaisy202Book(out);
eBookContents.writeXmlHeader();
eBookContents.writeDoctype();
eBookContents.writeXmlns();
eBookContents.writeBasicMetadata();
eBookContents.addTheseLevels(structure);
eBookContents.writeEndOfDocument();
ByteArrayInputStream bookContents = new ByteArrayInputStream(out.toByteArray());
DaisyBook book = NccSpecification.readFromStream(bookContents);
return book;
}
}