/* * Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. * * 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.jboss.errai.marshalling.tests; 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 static org.junit.Assert.fail; import org.jboss.errai.marshalling.client.api.json.EJArray; import org.jboss.errai.marshalling.client.api.json.EJValue; import org.jboss.errai.marshalling.server.JSONDecoder; import org.junit.Ignore; import org.junit.Test; /** * Direct tests for the (server-side) JSON decoder. * * @author Jonathan Fuerth <jfuerth@gmail.com> */ public class JSONDecoderTest { @Test public void testDecodeArrayOfMixedType() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": [ \"string\", 123.456, {}, [], true, false, null ] }"); assertTrue(ejv.isObject().containsKey("myValue")); EJArray array = ejv.isObject().get("myValue").isArray(); assertEquals(7, array.size()); assertEquals("string", array.get(0).isString().stringValue()); assertEquals(123.456, array.get(1).isNumber().doubleValue(), .00001); assertNotNull(array.get(2).isObject()); assertNotNull(array.get(3).isArray()); assertTrue(array.get(4).isBoolean().booleanValue()); assertFalse(array.get(5).isBoolean().booleanValue()); assertTrue(array.get(6).isNull()); } @Test public void testDecodeEmptyArray() throws Exception { EJValue ejv = JSONDecoder.decode("[]"); assertNotNull(ejv.isArray()); assertEquals(0, ejv.isArray().size()); // ensure it's not also identifying as any of the other JSON types assertNull(ejv.isString()); assertNull(ejv.isNumber()); assertNull(ejv.isObject()); assertNull(ejv.isBoolean()); assertFalse(ejv.isNull()); } @Test public void testDecodeEmptyObject() throws Exception { EJValue ejv = JSONDecoder.decode("{}"); assertNotNull(ejv.isObject()); assertEquals(0, ejv.isObject().keySet().size()); // ensure it's not also identifying as any of the other JSON types assertNull(ejv.isString()); assertNull(ejv.isNumber()); assertNull(ejv.isArray()); assertNull(ejv.isBoolean()); assertFalse(ejv.isNull()); } @Test public void testDecodeObjectWithTrue() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": true }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertTrue(myValue.isBoolean().booleanValue()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isString()); assertNull(myValue.isNumber()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertFalse(myValue.isNull()); } @Test public void testDecodeObjectWithFalse() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": false }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertFalse(myValue.isBoolean().booleanValue()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isString()); assertNull(myValue.isNumber()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertFalse(myValue.isNull()); } @Test public void testDecodeObjectWithNull() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": null }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertTrue(myValue.isNull()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isString()); assertNull(myValue.isNumber()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertNull(myValue.isBoolean()); } @Test public void testDecodeObjectWithNumber() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": 123456 }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertEquals(123456, myValue.isNumber().intValue()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isString()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertNull(myValue.isBoolean()); assertFalse(myValue.isNull()); } @Test public void testDecodeObjectWithNegativeNumber() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": -123456 }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertEquals(-123456, myValue.isNumber().intValue()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isString()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertNull(myValue.isBoolean()); assertFalse(myValue.isNull()); } @Test public void testDecodeObjectWithScientificNumbers() throws Exception { EJValue ejv = JSONDecoder.decode("{" + " \"myValue0\": 1.234e56" + ", \"myValue1\": 1.234e+56" + ", \"myValue2\": 1.234e-56" + ", \"myValue3\": 1.234E56" + ", \"myValue4\": 1.234E+56" + ", \"myValue5\": 1.234E-56" + ", \"myValue6\": 1234E-59" + "}"); for (int i = 0; i < 6; i++) { assertTrue(ejv.isObject().containsKey("myValue" + i)); EJValue myValue = ejv.isObject().get("myValue" + i); switch (i) { case 2: case 5: assertEquals("Failed on myValue" + i, 1.234e-56, myValue.isNumber().doubleValue(), 0.0); break; default: assertEquals("Failed on myValue" + i, 1.234e56, myValue.isNumber().doubleValue(), 0.0); break; } } } /** * JSON numbers can't have a leading 0. This test is presently ignored because * the logic for detecting a leading 0 is nontrivial (that is, it may impact * performance). We can re-enable this test if leading 0 detection becomes * important. */ @Test @Ignore public void testDecodeObjectWithInvalidNumberLeading0() throws Exception { try { JSONDecoder.decode("{ \"myValue\": 0123456 }"); fail("Expected NumberFormatException"); } catch (Exception e) { assertEquals(NumberFormatException.class, findRootCause(e).getClass()); } } /** * JSON numbers can't have a leading dot. */ @Test public void testDecodeObjectWithInvalidNumberLeadingDot() throws Exception { try { JSONDecoder.decode("{ \"myValue\": .123456 }"); fail("Expected NumberFormatException"); } catch (Exception e) { assertEquals(NumberFormatException.class, findRootCause(e).getClass()); } } /** * JSON numbers can't have a trailing e. */ @Test public void testDecodeObjectWithInvalidNumberTrailingE() throws Exception { try { JSONDecoder.decode("{ \"myValue\": 123456e }"); fail("Expected NumberFormatException"); } catch (Exception e) { assertEquals(NumberFormatException.class, findRootCause(e).getClass()); } } @Test public void testDecodeObjectWithString() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": \"myString\" }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertEquals("myString", myValue.isString().stringValue()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isNumber()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertNull(myValue.isBoolean()); assertFalse(myValue.isNull()); } @Test public void testDecodeObjectWithEmptyString() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": \"\" }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertEquals("", myValue.isString().stringValue()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isNumber()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertNull(myValue.isBoolean()); assertFalse(myValue.isNull()); } @Test public void testDecodeObjectWithNonAsciiString() throws Exception { EJValue ejv = JSONDecoder.decode("{ \"myValue\": \"myStr\u00efng\" }"); assertTrue(ejv.isObject().containsKey("myValue")); EJValue myValue = ejv.isObject().get("myValue"); assertEquals("myStr\u00efng", myValue.isString().stringValue()); // ensure it's not also identifying as any of the other JSON types assertNull(myValue.isNumber()); assertNull(myValue.isObject()); assertNull(myValue.isArray()); assertNull(myValue.isBoolean()); assertFalse(myValue.isNull()); } private static Throwable findRootCause(Throwable e) { while (e.getCause() != null && e.getCause() != e) { e = e.getCause(); } return e; } }