blob: 8d7321496ae5855cae433f75bee0d56618ac4fcb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id$ */
package org.apache.fop.pdf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.apache.commons.io.output.CountingOutputStream;
/**
* Test class for {@link PDFName}.
*/
public class PDFNameTestCase extends PDFObjectTestCase {
private PDFName pdfName;
/**
* Sets up the local variables
*/
@Before
public void setUp() {
pdfName = new PDFName("TestName");
pdfName.setParent(parent);
pdfName.setDocument(doc);
pdfObjectUnderTest = pdfName;
}
/**
* Tests escapeName() - tests that this method escapes the necessary characters.
*/
@Test
public void testEscapeName() {
try {
// Test for null, this is a programming error thus the NPE
PDFName.escapeName(null);
fail("NPE not thrown when null object given to escapeName()");
} catch (NullPointerException e) {
// PASS
}
// All names are prefixed by "/", check the PDF spec for further details.
assertEquals("/Test", PDFName.escapeName("Test"));
// Check that if the name is already prefixed with "/" it doens't do it twice
assertEquals("/Test", PDFName.escapeName("/Test"));
// Test with a space in the middle
assertEquals("/Test#20test", PDFName.escapeName("Test test"));
// Test that all chars apart from ASCII '!' --> '~' are escaped
nonEscapedCharactersTests();
escapedCharactersTests();
}
private void escapedCharactersTests() {
for (char i = 0; i < '!'; i++) {
String str = Integer.toHexString(i >>> 4 & 0x0f).toUpperCase();
str += Integer.toHexString(i & 0x0f).toUpperCase();
assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i)));
}
for (char i = '~' + 1; i < 256; i++) {
String str = Integer.toHexString(i >>> 4 & 0x0f).toUpperCase();
str += Integer.toHexString(i & 0x0f).toUpperCase();
assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i)));
}
checkCharacterIsEscaped('#');
checkCharacterIsEscaped('%');
checkCharacterIsEscaped('(');
checkCharacterIsEscaped(')');
checkCharacterIsEscaped('<');
checkCharacterIsEscaped('>');
checkCharacterIsEscaped('[');
checkCharacterIsEscaped(']');
checkCharacterIsEscaped('>');
}
private void checkCharacterIsEscaped(char c) {
String str = Integer.toHexString(c >>> 4 & 0x0f).toUpperCase();
str += Integer.toHexString(c & 0x0f).toUpperCase();
assertEquals("/#" + str, PDFName.escapeName(String.valueOf(c)));
}
private void nonEscapedCharactersTests() {
charactersNotEscapedBetween('!', '"');
charactersNotEscapedBetween('*', ';');
charactersNotEscapedBetween('?', 'Z');
charactersNotEscapedBetween('^', '~');
}
private void charactersNotEscapedBetween(char c1, char c2) {
for (char i = c1; i <= c2; i++) {
String str = String.valueOf(i);
String expected = !str.equals("/") ? "/" + str : str;
assertEquals(expected, PDFName.escapeName(str));
}
}
/**
* Tests toString() - this has been overridden to return the String that PDFName wraps.
*/
@Test
public void testToString() {
// The escape characters have already been tested in testEscapeName() so this doesn't need
// to be done twice.
PDFName test1 = new PDFName("test1");
assertEquals("/test1", test1.toString());
PDFName test2 = new PDFName("another test");
assertEquals("/another#20test", test2.toString());
try {
new PDFName(null);
fail("NPE not thrown when null passed to constructor");
} catch (NullPointerException e) {
// PASS
}
}
/**
* Tests output() - check that this object can stream itself in the correct format.
* @throws IOException error caused by I/O
*/
@Test
public void testOutput() throws IOException {
testOutputStreams("/TestName", pdfName);
testOutputStreams("/test#20test", new PDFName("test test"));
}
/**
* Test outputInline() - this writes the object reference if it is a direct object (has an
* object number), or writes the String representation if there is no object number.
*/
@Test
public void testOutputInline() {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
CountingOutputStream cout = new CountingOutputStream(outStream);
StringBuilder textBuffer = new StringBuilder();
try {
// test with no object number set.
pdfName.outputInline(outStream, textBuffer);
PDFDocument.flushTextBuffer(textBuffer, cout);
assertEquals("/TestName", outStream.toString());
outStream.reset();
// test with object number set
pdfName.setObjectNumber(1);
pdfName.outputInline(outStream, textBuffer);
PDFDocument.flushTextBuffer(textBuffer, cout);
assertEquals("1 0 R", outStream.toString());
} catch (IOException e) {
fail("IOException: " + e.getMessage());
}
}
}