aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/org/yaml/snakeyaml/array/PrimitiveArrayTest.java
blob: e54d4d0646415c75525e8485997b5a691e2e65fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/**
 * Copyright (c) 2008, SnakeYAML
 *
 * 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 = 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, 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;
    }
  }
}