blob: 09b1d532ef4433a91dcd86720738ac96b452c271 [file] [log] [blame]
/**
* Copyright (c) 2008, http://www.snakeyaml.org
*
* Licensed 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.
*/
package org.yaml.snakeyaml.array;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
import org.junit.Assert;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.ConstructorException;
import org.yaml.snakeyaml.error.YAMLException;
public class PrimitiveArrayTest extends TestCase {
private final String pkg = "!!org.yaml.snakeyaml.array";
private final byte[] bytes = new byte[] { 1, 2, 3 };
private final short[] shorts = new short[] { 300, 301, 302 };
private final int[] ints = new int[] { 40000, 40001, 40002 };
private final long[] longs = new long[] { 5000000000L, 5000000001L };
private final float[] floats = new float[] { 0.1f, 3.1415f };
private final double[] doubles = new double[] { 50.0001, 2150.0002 };
private final char[] chars = new char[] { 'a', 'b', 'c', 'd', 'e' };
private final boolean[] bools = new boolean[] { true, false };
public void testValidConstructor() {
String testInput = "- " + pkg + ".ByteArr [ " + Arrays.toString(bytes) + " ]\n" + "- "
+ pkg + ".ShortArr [ " + Arrays.toString(shorts) + " ]\n" + "- " + pkg
+ ".IntArr [ " + Arrays.toString(ints) + " ]\n" + "- " + pkg + ".LongArr [ "
+ Arrays.toString(longs) + " ]\n" + "- " + pkg + ".FloatArr [ "
+ Arrays.toString(floats) + " ]\n" + "- " + pkg + ".DoubleArr [ "
+ Arrays.toString(doubles) + " ]\n" + "- " + pkg + ".CharArr [ "
+ Arrays.toString(chars) + " ]\n" + "- " + pkg + ".BooleanArr [ "
+ Arrays.toString(bools) + " ]\n";
Yaml yaml = new Yaml();
List<Object> wrappers = (List<Object>) yaml.load(testInput);
Assert.assertArrayEquals(bytes, ((ByteArr) wrappers.get(0)).getBytes());
Assert.assertArrayEquals(shorts, ((ShortArr) wrappers.get(1)).getShorts());
Assert.assertArrayEquals(ints, ((IntArr) wrappers.get(2)).getInts());
Assert.assertArrayEquals(longs, ((LongArr) wrappers.get(3)).getLongs());
Assert.assertArrayEquals(floats, ((FloatArr) wrappers.get(4)).getFloats(), 0.001f);
Assert.assertArrayEquals(doubles, ((DoubleArr) wrappers.get(5)).getDoubles(), 0.001);
Assert.assertArrayEquals(chars, ((CharArr) wrappers.get(6)).getChars());
assertArrayEquals(bools, ((BooleanArr) wrappers.get(7)).getBools());
}
/*
* For some reason, every other assertArrayEquals specialization is provided
* by org.junit.Assert, but not this one.
*/
private void assertArrayEquals(boolean[] expected, boolean[] actuals) {
assertEquals("Arrays differ in length", expected.length, actuals.length);
for (int i = 0; i < expected.length; ++i) {
if (expected[i] != actuals[i]) {
fail("Arrays first differ at " + i + "; expected " + expected[i] + " but got "
+ actuals[i]);
}
}
}
private void tryInvalid(String t, Class<?> expectedException) {
Yaml yaml = new Yaml();
try {
Object loaded = yaml.load(t);
fail("Expected " + expectedException.getCanonicalName() + " but loaded = \"" + loaded
+ "\"");
} catch (YAMLException e) {
assertEquals(expectedException, e.getCause().getClass());
}
}
public void testInvalidConstructors() {
// Loading a character as any primitive other than 'char' is a
// NumberFormatException
tryInvalid(pkg + ".ByteArr [ [ 'a' ] ]", NumberFormatException.class);
tryInvalid(pkg + ".ShortArr [ [ 'a' ] ]", NumberFormatException.class);
tryInvalid(pkg + ".IntArr [ [ 'a' ] ]", NumberFormatException.class);
tryInvalid(pkg + ".LongArr [ [ 'a' ] ]", NumberFormatException.class);
tryInvalid(pkg + ".FloatArr [ [ 'a' ] ]", NumberFormatException.class);
tryInvalid(pkg + ".DoubleArr [ [ 'a' ] ]", NumberFormatException.class);
// Exception: because of how boolean construction works, constructing a
// boolean from 'a'
// results in null.
tryInvalid(pkg + ".BooleanArr [ [ 'a' ] ]", NullPointerException.class);
// Loading a floating-point number as a character is a YAMLException
tryInvalid(pkg + ".CharArr [ [ 1.2 ] ]", YAMLException.class);
// Loading a String as a Character is a YAMLException
tryInvalid(pkg + ".CharArr [ [ 'abcd' ] ]", YAMLException.class);
}
public void testTruncation() {
// Loading floating-point numbers as integer types is disallowed,
// because that's a number-format problem.
tryInvalid(pkg + ".ByteArr [ [ 3.14 ] ]", NumberFormatException.class);
tryInvalid(pkg + ".ShortArr [ [ 3.14 ] ]", NumberFormatException.class);
tryInvalid(pkg + ".IntArr [ [ 3.14 ] ]", NumberFormatException.class);
tryInvalid(pkg + ".LongArr [ [ 3.14 ] ]", NumberFormatException.class);
}
public void testPromotion() {
Yaml yaml = new Yaml();
// Loading integer numbers as floating-point types is allowed...
Assert.assertArrayEquals(new float[] { 3, 5 },
((FloatArr) yaml.load(pkg + ".FloatArr [ [ 3, 5 ] ] ")).getFloats(), 0.001f);
Assert.assertArrayEquals(new double[] { 3, 5 },
((DoubleArr) yaml.load(pkg + ".DoubleArr [ [ 3, 5 ] ] ")).getDoubles(), 0.001f);
}
public void testStringCharArray() {
Yaml yaml = new Yaml();
try {
yaml.load(pkg + ".CharArr [ [ abcd ] ]");
fail("Expected exception.");
} catch (Exception e) {
assertEquals(ConstructorException.class, e.getClass());
assertEquals("Invalid node Character: 'abcd'; length: 4", e.getCause().getMessage());
}
}
private static Object cycle(Object in) {
Yaml yaml = new Yaml();
String dumped = yaml.dump(in);
// System.out.println ( dumped );
return yaml.load(dumped);
}
/**
* All kinds of primitive arrays should be able to cycle from (Java array)
* to (YAML string) to (Java array) again, and they should be exactly the
* same before and after.
*/
public void testCycle() {
ByteArr byteArr = new ByteArr(bytes);
Assert.assertArrayEquals(byteArr.getBytes(), ((ByteArr) cycle(byteArr)).getBytes());
ShortArr shortArr = new ShortArr(shorts);
Assert.assertArrayEquals(shortArr.getShorts(), ((ShortArr) cycle(shortArr)).getShorts());
IntArr intArr = new IntArr(ints);
Assert.assertArrayEquals(intArr.getInts(), ((IntArr) cycle(intArr)).getInts());
LongArr longArr = new LongArr(longs);
Assert.assertArrayEquals(longArr.getLongs(), ((LongArr) cycle(longArr)).getLongs());
FloatArr floatArr = new FloatArr(floats);
Assert.assertArrayEquals(floatArr.getFloats(), ((FloatArr) cycle(floatArr)).getFloats(),
0.001f);
DoubleArr doubleArr = new DoubleArr(doubles);
Assert.assertArrayEquals(doubleArr.getDoubles(),
((DoubleArr) cycle(doubleArr)).getDoubles(), 0.001);
CharArr charArr = new CharArr(chars);
Assert.assertArrayEquals(charArr.getChars(), ((CharArr) cycle(charArr)).getChars());
BooleanArr boolArr = new BooleanArr(bools);
assertArrayEquals(boolArr.getBools(), ((BooleanArr) cycle(boolArr)).getBools());
}
public void testMultiDimensional() {
Array2D two = new Array2D();
two.setLongs(new long[][] { { 1, 2, 3 }, { 4, 5, 6 } });
assertTrue(Arrays.deepEquals(two.getLongs(), ((Array2D) cycle(two)).getLongs()));
Array3D three = new Array3D();
three.setLongs(new long[][][] { { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } },
{ { 9, 10, 11, 12 }, { 13, 14, 15, 16 } } });
assertTrue(Arrays.deepEquals(three.getLongs(), ((Array3D) cycle(three)).getLongs()));
// Object with an array of Objects which each have an array of
// primitives.
ArrayLongArr four = new ArrayLongArr();
four.setContents(new LongArr[] { new LongArr(new long[] { 1, 2, 3, 4 }),
new LongArr(new long[] { 5, 6, 7, 8 }) });
Object result = cycle(four);
assertEquals(four, (ArrayLongArr) result);
}
public static class Array2D {
private long[][] longs;
public long[][] getLongs() {
return longs;
}
public void setLongs(long[][] longs) {
this.longs = longs;
}
}
public static class Array3D {
private long[][][] longs;
public long[][][] getLongs() {
return longs;
}
public void setLongs(long[][][] longs) {
this.longs = longs;
}
}
public static class ArrayLongArr {
private LongArr[] contents;
public LongArr[] getContents() {
return contents;
}
public void setContents(LongArr[] contents) {
this.contents = contents;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ArrayLongArr))
return false;
ArrayLongArr other = ((ArrayLongArr) obj);
if (contents.length != other.getContents().length)
return false;
for (int i = 0; i < contents.length; ++i) {
if (!Arrays.equals(contents[i].getLongs(), other.getContents()[i].getLongs())) {
return false;
}
}
return true;
}
}
}