/* * 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.afp.modca; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.apache.fop.afp.Streamable; /** * Tests the {@link AbstractAFPObject} class. */ public abstract class AbstractAFPObjectTest<S extends AbstractAFPObject> { private S sut; protected final S getSut() { return sut; } protected final void setSut(S sut) { if (this.sut == null) { this.sut = sut; } } private byte[] header = new byte[] { 0x5A, // Structured field identifier 0x00, // Length byte 1 0x10, // Length byte 2 0x00, // Structured field id byte 1 0x00, // Structured field id byte 2 0x00, // Structured field id byte 3 0x00, // Flags 0x00, // Reserved 0x00 // Reserved }; @Test public void testCopySFStatic() { byte[] actual = new byte[9]; Arrays.fill(actual, (byte)-1); S.copySF(actual, (byte)0, (byte)0, (byte)0); assertTrue(Arrays.equals(actual, header)); byte[] expected2 = new byte[9]; System.arraycopy(header, 0, expected2, 0, header.length); final byte clazz = (byte) 0x01; final byte type = (byte) 0x02; final byte catagory = (byte) 0x03; expected2[3] = clazz; expected2[4] = type; expected2[5] = catagory; AbstractAFPObject.copySF(actual, clazz, type, catagory); assertTrue(Arrays.equals(actual, expected2)); } @Test public void testCopySF() { byte[] expected = new byte[9]; S.copySF(expected, (byte) 0xD3, (byte)0, (byte)0); byte[] actual = new byte[9]; Arrays.fill(actual, (byte)-1); getSut().copySF(actual, (byte)0, (byte)0); assertTrue(Arrays.equals(actual, expected)); byte[] expected2 = new byte[9]; System.arraycopy(expected, 0, expected2, 0, expected.length); final byte type = (byte)1; final byte catagory = (byte)2; expected2[4] = type; expected2[5] = catagory; getSut().copySF(actual, type, catagory); assertTrue(Arrays.equals(actual, expected2)); } /** * */ @Test public void testwriteObjects() { final byte[][] expected = {{(byte)0, (byte)1}, {(byte)2, (byte)3}, {(byte)4, (byte)5}}; List<Streamable> objects = new ArrayList<Streamable>() { { add(StreamableObject.instance(expected[0])); add(StreamableObject.instance(expected[1])); add(StreamableObject.instance(expected[2])); } }; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { getSut().writeObjects(objects, baos); } catch (IOException e) { fail(); } byte[] actual = baos.toByteArray(); int index = 0; for (byte[] anExpected : expected) { for (int j = 0; j < anExpected.length; j++) { assertTrue("" + index, actual[index] == anExpected[j]); index++; } } } /** * */ @Test public void testTruncate() { String expected = "abc"; assertTrue(AbstractAFPObject.truncate(expected, 4) == expected); assertTrue(AbstractAFPObject.truncate(expected, 3) == expected); assertEquals(AbstractAFPObject.truncate(expected + "d", 3), expected); assertEquals(AbstractAFPObject.truncate(expected, 0), ""); try { assertTrue(AbstractAFPObject.truncate(null, 4) == null); fail(); } catch (NullPointerException e) { // PASS } } /** * */ @Test public void testWriteChunksToStream() throws IOException { final byte[] data = new byte[256]; int counter = 0; for (int i = 0; i < data.length; i++) { data[i] = (byte) counter++; } byte[] header = new byte[9]; // Test when chunk size % data.length == 0 testWithGivenChunkSize(data, header, 16); // test when chunk size % data.length != 0 testWithGivenChunkSize(data, header, 10); // test with an odd number... testWithGivenChunkSize(data, header, 13); } private void testWithGivenChunkSize(byte[] data, byte[] header, int chunkSize) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); S.writeChunksToStream(data, header, 0, chunkSize, baos); byte[] testData = baos.toByteArray(); int numberOfFullDataChunks = data.length / chunkSize; int lastChunkSize = data.length % chunkSize; int lengthOfTestData = numberOfFullDataChunks * (chunkSize + header.length); lengthOfTestData += lastChunkSize == 0 ? 0 : header.length + lastChunkSize; putLengthInHeader(header, chunkSize); assertEquals(lengthOfTestData, testData.length); int testIndex = 0; int expectedIndex = 0; for (int i = 0; i < numberOfFullDataChunks; i++) { checkHeaderAndData(header, data, testData, expectedIndex, testIndex, chunkSize); expectedIndex += chunkSize + header.length; testIndex += chunkSize; } putLengthInHeader(header, lastChunkSize); // check last chunk if (lastChunkSize != 0) { checkHeaderAndData(header, data, testData, expectedIndex, testIndex, lastChunkSize); } } private void putLengthInHeader(byte[] header, int chunkSize) { header[0] = 0; header[1] = (byte) (chunkSize + header.length); } private void checkHeaderAndData(byte[] header, byte[] data, byte[] testData, int expectedIndex, int testIndex, int chunkSize) { for (byte aHeader : header) { assertEquals(testData[expectedIndex++], aHeader); } for (int i = 0; i < chunkSize; i++) { assertEquals(testData[expectedIndex++], data[i + testIndex]); } } /** * */ private static class StreamableObject implements Streamable { private byte[] bytes; StreamableObject(byte[] bytes) { this.bytes = new byte[bytes.length]; System.arraycopy(bytes, 0, this.bytes, 0, bytes.length); } private static Streamable instance(byte[] bytes) { return new StreamableObject(bytes); } public void writeToStream(OutputStream os) throws IOException { os.write(bytes); } } }