001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.flatfile; 018 019import static org.junit.Assert.assertArrayEquals; 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022import static org.junit.Assert.fail; 023 024import java.io.ByteArrayInputStream; 025import java.io.IOException; 026import java.util.Arrays; 027 028import org.apache.commons.flatfile.FieldSupport.Overflow; 029import org.apache.commons.flatfile.FieldSupport.Underflow; 030import org.junit.Test; 031 032/** 033 * Test dynamic fields. 034 */ 035public class DynamicFieldTest extends EntityParserTestBase { 036 private static final int BUFFER_SIZE = 20; 037 038 private static final byte[] SMALL_BYTES = new byte[0]; 039 private static final byte[] LARGE_BYTES = new byte[1024]; 040 041 static { 042 Arrays.fill(LARGE_BYTES, (byte) 'a'); 043 } 044 045 @Test 046 public void test1() throws Exception { 047 DynamicField df = get("df1"); 048 assertEquals(0, df.length()); 049 assertBounds(df, 0, 1); 050 assertLoad(df); 051 } 052 053 @Test 054 public void test2() throws Exception { 055 DynamicField df = get("df2"); 056 assertEquals(0, df.length()); 057 assertBounds(df, DynamicField.Bounds.DEFAULT.getMinimum(), 1); 058 assertLoad(df); 059 } 060 061 @Test 062 public void test3() throws Exception { 063 DynamicField df = get("df3"); 064 assertEquals(0, df.length()); 065 assertBounds(df, 0, DynamicField.Bounds.DEFAULT.getMaximum()); 066 assertLoad(df); 067 } 068 069 @Test 070 public void test4() throws Exception { 071 DynamicField df = get("df4"); 072 assertEquals(0, df.length()); 073 assertBounds(df, DynamicField.Bounds.DEFAULT); 074 assertLoad(df); 075 } 076 077 @Test 078 public void test5() throws Exception { 079 DynamicField df = get("df5"); 080 assertEquals(3, df.length()); 081 byte[] foo = "foo".getBytes(); 082 assertArrayEquals(foo, df.getValue()); 083 assertBounds(df, DynamicField.Bounds.DEFAULT); 084 assertLoad(df); 085 } 086 087 @Test 088 public void test6() throws Exception { 089 DynamicField df = get("df6"); 090 assertEquals(0, df.length()); 091 assertBounds(df, 0, 0); 092 assertLoad(df); 093 } 094 095 @Test 096 public void test7() throws Exception { 097 DynamicField df = get("df7"); 098 assertEquals(0, df.length()); 099 assertBounds(df, DynamicField.Bounds.DEFAULT.getMinimum(), 0); 100 assertLoad(df); 101 } 102 103 @Test 104 public void test8() throws Exception { 105 DynamicField df = get("df8"); 106 assertBounds(df, 1, 1); 107 assertArrayEquals(new byte[] { ' ' }, df.getValue()); 108 assertLoad(df); 109 } 110 111 @Test 112 public void test9() throws Exception { 113 DynamicField df = get("df9"); 114 assertBounds(df, 1, 3); 115 assertArrayEquals(" ".getBytes(), df.getValue()); 116 assertLoad(df); 117 } 118 119 @Test 120 public void testUnboundedArray() throws Exception { 121 EntityArray a = (EntityArray) entityFactory.getEntity("unboundedArray"); 122 assertEquals(0, a.length()); 123 a.getChild(1).setValue("foo".getBytes()); 124 assertArrayEquals("foo".getBytes(), a.getValue()); 125 } 126 127 @Test 128 public void testUnboundedDelimitedArray() throws Exception { 129 EntityArray a = (EntityArray) entityFactory 130 .getEntity("unboundedDelimitedArray"); 131 assertArrayEquals("---".getBytes(), a.getValue()); 132 a.getChild(1).setValue("foo".getBytes()); 133 assertArrayEquals("-foo--".getBytes(), a.getValue()); 134 } 135 136 @Test 137 public void testBoundedArray() throws Exception { 138 EntityArray a = (EntityArray) entityFactory.getEntity("boundedArray"); 139 assertArrayEquals(" ".getBytes(), a.getValue()); 140 a.getChild(1).setValue("foo".getBytes()); 141 assertArrayEquals(" foo ".getBytes(), a.getValue()); 142 } 143 144 @Test 145 public void testBoundedDelimitedArray() throws Exception { 146 EntityArray a = (EntityArray) entityFactory 147 .getEntity("boundedDelimitedArray"); 148 assertArrayEquals(" \n \n \n".getBytes(), a.getValue()); 149 a.getChild(1).setValue("foo".getBytes()); 150 assertArrayEquals(" \nfoo\n \n".getBytes(), a.getValue()); 151 152 } 153 154 @Test 155 public void testNestedUncertainty() throws Exception { 156 EntityArray a = (EntityArray) entityFactory 157 .getEntity("nestedUncertainty"); 158 assertTrue(a.isSizable()); 159 a.setSize(10); 160 assertArrayEquals(SMALL_BYTES, a.getValue()); 161 StringBuffer buf = new StringBuffer(); 162 for (int i = 0; i < 10; i++) { 163 byte[] b = new byte[i + 1]; 164 Arrays.fill(b, (byte) ((int) 'a' + i)); 165 buf.append(new String(b)); 166 a.getChild(i).setValue(b); 167 } 168 assertArrayEquals(buf.toString().getBytes(), a.getValue()); 169 } 170 171 private void assertBounds(DynamicField df, int min, int max) { 172 assertBounds(df, new DynamicField.Bounds(min, max)); 173 } 174 175 private void assertBounds(DynamicField df, DynamicField.Bounds bounds) { 176 assertEquals(bounds, df.getBounds()); 177 testValue(df, SMALL_BYTES); 178 testValue(df, LARGE_BYTES); 179 } 180 181 private void assertLoad(DynamicField df) throws IOException { 182 df.readFrom(new ByteArrayInputStream(LARGE_BYTES)); 183 int max = df.getBounds().getMaximum(); 184 int expectedLength = Math.min(max, LARGE_BYTES.length); 185 assertEquals(expectedLength, df.length()); 186 byte[] expec; 187 if (LARGE_BYTES.length < max) { 188 expec = LARGE_BYTES; 189 } else { 190 expec = new byte[max]; 191 System.arraycopy(LARGE_BYTES, 0, expec, 0, expec.length); 192 } 193 assertArrayEquals(expec, df.getValue()); 194 } 195 196 private void testValue(DynamicField df, byte[] value) { 197 int len = value.length; 198 int min = df.getBounds().getMinimum(); 199 int max = df.getBounds().getMaximum(); 200 if (df.getUnderflow() == Underflow.ERROR && len < min 201 || df.getOverflow() == Overflow.ERROR && len > max) { 202 byte[] old = df.getValue(); 203 try { 204 df.setValue(value); 205 fail(new String(value)); 206 } catch (IllegalArgumentException e) { 207 assertArrayEquals(old, df.getValue()); 208 } 209 } else { 210 df.setValue(value); 211 assertTrue(len < min || len > max 212 || Arrays.equals(value, df.getValue())); 213 } 214 } 215 216 private DynamicField get(String name) { 217 return (DynamicField) entityFactory.getEntity(name); 218 } 219 220 protected String getSource() { 221 return "dynamicField.test"; 222 } 223 224}