blob: 97ccfc8d8383ac8073e6287132b4638a242be688 [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.
*/
package org.apache.drill.exec.store.json.parser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.apache.drill.exec.store.easy.json.parser.JsonType;
import org.junit.Test;
/**
* Tests array (including multi-dimensional and object) support
* for the JSON structure parser.
*/
public class TestJsonParserArrays extends BaseTestJsonParser {
@Test
public void test1DArray() {
final String json =
"{a: [1, 100]} {a: [null]} \n" +
"{a: []} {a: null} {}";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
// {a: [1, 100]}
assertTrue(fixture.next());
// Value of object.a
ValueListenerFixture a = fixture.field("a");
assertEquals(JsonType.INTEGER, a.type);
assertEquals(1, a.dimCount);
// Array aspect of a
assertNotNull(a.arrayValue);
ArrayListenerFixture aArray = a.arrayValue;
assertEquals(1, aArray.startCount);
assertEquals(aArray.startCount, aArray.endCount);
assertEquals(1, aArray.dimCount);
// Value of each element of array aspect of a
assertNotNull(aArray.element);
ValueListenerFixture aElement = aArray.element;
assertEquals(JsonType.INTEGER, aElement.type);
assertEquals(0, aElement.dimCount);
assertNull(aElement.arrayValue);
assertEquals(2, aElement.valueCount);
assertEquals(100L, aElement.value);
assertEquals(0, aElement.nullCount);
// {a: [null]}
assertTrue(fixture.next());
assertEquals(2, aArray.startCount);
assertEquals(aArray.startCount, aArray.endCount);
assertEquals(2, aElement.valueCount);
assertEquals(1, aElement.nullCount);
// {a: []}
assertTrue(fixture.next());
assertEquals(3, aArray.startCount);
assertEquals(aArray.startCount, aArray.endCount);
assertEquals(2, aElement.valueCount);
assertEquals(1, aElement.nullCount);
assertEquals(0, a.nullCount);
// {a: null}
assertTrue(fixture.next());
assertEquals(3, aArray.startCount);
assertEquals(1, a.nullCount);
// {}
assertTrue(fixture.next());
assertEquals(3, aArray.startCount);
assertEquals(1, a.nullCount);
assertFalse(fixture.next());
fixture.close();
}
@Test
public void testNullToArray() {
final String json =
"{a: null} {a: [1, 100]}";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
// Can't predict the future, all we know is a is null.
// {a: null}
assertTrue(fixture.next());
ValueListenerFixture a = fixture.field("a");
assertEquals(JsonType.NULL, a.type);
assertEquals(0, a.dimCount);
assertNull(a.arrayValue);
// See an array, can revise estimate of field type
// {a: [1, 100]}
assertTrue(fixture.next());
assertNotNull(a.arrayValue);
ArrayListenerFixture aArray = a.arrayValue;
assertEquals(1, aArray.dimCount);
ValueListenerFixture aElement = aArray.element;
assertEquals(2, aElement.valueCount);
assertEquals(100L, aElement.value);
assertFalse(fixture.next());
fixture.close();
}
@Test
public void testEmptyArray() {
final String json =
"{a: []} {a: [1, 100]}";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
// Can't predict the future, all we know is a is an array.
// "{a: []}
assertTrue(fixture.next());
ValueListenerFixture a = fixture.field("a");
assertEquals(JsonType.EMPTY, a.type);
assertEquals(1, a.dimCount);
assertNotNull(a.arrayValue);
ArrayListenerFixture aArray = a.arrayValue;
assertEquals(1, aArray.dimCount);
ValueListenerFixture aElement = aArray.element;
assertEquals(JsonType.EMPTY, aElement.type);
// See elements, can revise estimate of element type
// {a: [1, 100]}
assertTrue(fixture.next());
assertEquals(2, aElement.valueCount);
assertEquals(100L, aElement.value);
assertFalse(fixture.next());
fixture.close();
}
@Test
public void test2DArray() {
final String json =
"{a: [ [10, 1], [20, 2]]}\n" +
"{a: [[null]]} {a: [[]]} {a: [null]} {a: null}";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
// {a: [ [10, 1], [20, 2]]}
assertTrue(fixture.next());
// Value of a
ValueListenerFixture a = fixture.field("a");
assertEquals(JsonType.INTEGER, a.type);
assertEquals(2, a.dimCount);
// Array for a[]
assertNotNull(a.arrayValue);
ArrayListenerFixture outerArr = a.arrayValue;
assertEquals(2, outerArr.dimCount);
assertEquals(1, outerArr.startCount);
assertEquals(outerArr.startCount, outerArr.endCount);
// Value of a[] elements
ValueListenerFixture outerElement = outerArr.element;
assertEquals(JsonType.INTEGER, outerElement.type);
assertEquals(1, outerElement.dimCount);
assertNotNull(outerElement.arrayValue);
// Array for a[][]
assertNotNull(outerElement.arrayValue);
ArrayListenerFixture innerArr = outerElement.arrayValue;
assertEquals(1, innerArr.dimCount);
assertEquals(2, innerArr.startCount);
assertEquals(innerArr.startCount, innerArr.endCount);
// Value of a[][] elements
ValueListenerFixture innerElement = innerArr.element;
assertEquals(JsonType.INTEGER, innerElement.type);
assertEquals(0, innerElement.dimCount);
assertEquals(4, innerElement.valueCount);
assertEquals(0, innerElement.nullCount);
assertEquals(2L, innerElement.value);
// {a: [[null]]}
assertTrue(fixture.next());
assertEquals(2, outerArr.startCount);
assertEquals(outerArr.startCount, outerArr.endCount);
assertEquals(0, outerElement.nullCount);
assertEquals(3, innerArr.startCount);
assertEquals(innerArr.startCount, innerArr.endCount);
assertEquals(4, innerElement.valueCount);
assertEquals(1, innerElement.nullCount);
// {a: [[]]}
assertTrue(fixture.next());
assertEquals(3, outerArr.startCount);
assertEquals(outerArr.startCount, outerArr.endCount);
assertEquals(0, outerElement.nullCount);
assertEquals(4, innerArr.startCount);
assertEquals(innerArr.startCount, innerArr.endCount);
assertEquals(4, innerElement.valueCount);
assertEquals(1, innerElement.nullCount);
// {a: [null]}
assertTrue(fixture.next());
assertEquals(0, a.nullCount);
assertEquals(4, outerArr.startCount);
assertEquals(outerArr.startCount, outerArr.endCount);
assertEquals(1, outerElement.nullCount);
assertEquals(4, innerArr.startCount);
assertEquals(4, innerElement.valueCount);
assertEquals(1, innerElement.nullCount);
// {a: null}
assertTrue(fixture.next());
assertEquals(1, a.nullCount);
assertEquals(4, outerArr.startCount);
assertEquals(outerArr.startCount, outerArr.endCount);
assertEquals(1, outerElement.nullCount);
assertEquals(4, innerArr.startCount);
assertEquals(4, innerElement.valueCount);
assertEquals(1, innerElement.nullCount);
assertFalse(fixture.next());
fixture.close();
}
@Test
public void test1DEmptyTo2DArray() {
final String json =
"{a: []}\n" +
"{a: [ [10, 1], [20, 2]]}\n";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
// Check of details done in other tests. Just cut to
// the chase to verify proper structure.
assertEquals(2, fixture.read());
ValueListenerFixture element =
fixture.field("a").arrayValue.element.arrayValue.element;
assertEquals(4, element.valueCount);
assertEquals(2L, element.value);
assertFalse(fixture.next());
fixture.close();
}
@Test
public void testObjArray() {
final String json =
"{a: [ {b: \"fred\"}, {b: \"barney\"} ] }";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
assertTrue(fixture.next());
// Value of object.a
ValueListenerFixture a = fixture.field("a");
assertEquals(JsonType.OBJECT, a.type);
assertEquals(1, a.dimCount);
// a[]
assertNotNull(a.arrayValue);
ArrayListenerFixture aArray = a.arrayValue;
assertEquals(1, aArray.startCount);
assertEquals(aArray.startCount, aArray.endCount);
assertEquals(1, aArray.dimCount);
// Value of each element of a[]
assertNotNull(aArray.element);
ValueListenerFixture aElement = aArray.element;
assertEquals(JsonType.OBJECT, aElement.type);
assertEquals(0, aElement.dimCount);
assertNull(aElement.arrayValue);
assertEquals(0, aElement.valueCount);
assertEquals(0, aElement.nullCount);
// Object for a[] elements
assertNotNull(aElement.objectValue);
ObjectListenerFixture elementObj = aElement.objectValue;
assertEquals(2, elementObj.startCount);
assertEquals(elementObj.startCount, elementObj.endCount);
// b field within a[]{}
ValueListenerFixture b = elementObj.field("b");
assertEquals(2, b.valueCount);
assertEquals("barney", b.value);
assertFalse(fixture.next());
fixture.close();
}
@Test
public void test2DObjArray() {
final String json =
"{a: [ [ {b: \"fred\"}, {b: \"wilma\"} ],\n" +
" [ {b: \"barney\"}, {b: \"betty\"} ] ] }";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
assertTrue(fixture.next());
// Value of object.a
ValueListenerFixture a = fixture.field("a");
assertEquals(JsonType.OBJECT, a.type);
assertEquals(2, a.dimCount);
// a[]
assertNotNull(a.arrayValue);
ArrayListenerFixture outerArray = a.arrayValue;
assertEquals(1, outerArray.startCount);
assertEquals(outerArray.startCount, outerArray.endCount);
assertEquals(2, outerArray.dimCount);
// Value of each element of a[]
assertNotNull(outerArray.element);
ValueListenerFixture outerElement = outerArray.element;
assertEquals(JsonType.OBJECT, outerElement.type);
assertEquals(1, outerElement.dimCount);
assertEquals(0, outerElement.valueCount);
assertEquals(0, outerElement.nullCount);
// a[][]
assertNotNull(outerElement.arrayValue);
ArrayListenerFixture innerArray = outerElement.arrayValue;
assertEquals(2, innerArray.startCount);
assertEquals(innerArray.startCount, innerArray.endCount);
assertEquals(1, innerArray.dimCount);
// Value of each element of a[][]
assertNotNull(innerArray.element);
ValueListenerFixture innerElement = innerArray.element;
assertEquals(JsonType.OBJECT, innerElement.type);
assertEquals(0, innerElement.dimCount);
assertEquals(0, innerElement.valueCount);
assertEquals(0, innerElement.nullCount);
// Object for a[][] elements
assertNotNull(innerElement.objectValue);
ObjectListenerFixture elementObj = innerElement.objectValue;
assertEquals(4, elementObj.startCount);
assertEquals(elementObj.startCount, elementObj.endCount);
// b field within a[][]{}
ValueListenerFixture b = elementObj.field("b");
assertEquals(4, b.valueCount);
assertEquals("betty", b.value);
assertFalse(fixture.next());
}
/**
* JSON allows any combination of value types.
*/
@Test
public void testMixArray() {
final String json =
"{a: [10, 11] }\n" +
"{a: {b: \"fred\"}}\n" +
"{a: 20.5}\n" +
"{a: null}\n";
JsonParserFixture fixture = new JsonParserFixture();
fixture.open(json);
assertEquals(4, fixture.read());
ValueListenerFixture a = fixture.field("a");
// Type first seen
assertEquals(JsonType.INTEGER, a.type);
assertEquals(1, a.dimCount);
// Everything populated
assertEquals(2, a.arrayValue.element.valueCount);
assertEquals(11L, a.arrayValue.element.value);
assertEquals(1, a.objectValue.startCount);
assertEquals("fred", a.objectValue.field("b").value);
assertEquals(20.5D, a.value);
assertEquals(1, a.nullCount);
fixture.close();
}
}