001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.schematic.internal.document; 017 018import static org.hamcrest.core.Is.is; 019import static org.hamcrest.core.IsNull.notNullValue; 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNotNull; 022import static org.junit.Assert.assertNull; 023import static org.junit.Assert.assertThat; 024import static org.junit.Assert.fail; 025import java.io.InputStream; 026import org.junit.After; 027import org.junit.Before; 028import org.junit.Test; 029import org.modeshape.schematic.document.Document; 030import org.modeshape.schematic.document.DocumentSequence; 031import org.modeshape.schematic.document.ParsingException; 032import org.modeshape.schematic.internal.annotation.FixFor; 033 034public class JsonReaderTest { 035 036 protected JsonReader reader; 037 protected boolean print; 038 protected Document doc; 039 040 @Before 041 public void beforeTest() { 042 reader = new JsonReader(); 043 print = false; 044 } 045 046 @After 047 public void afterTest() { 048 reader = null; 049 } 050 051 @Test 052 public void shouldParseEmptyDocument() throws Exception { 053 doc = reader.read("{ }"); 054 } 055 056 @Test 057 public void shouldParseEmptyDocumentWithLeadingWhitespace() throws Exception { 058 doc = reader.read(" { }"); 059 } 060 061 @Test 062 public void shouldParseEmptyDocumentWithEmbeddedWhitespace() throws Exception { 063 doc = reader.read("{ \n \t \r\n } "); 064 } 065 066 @Test 067 public void shouldParseDocumentWithSingleFieldWithStringValue() throws Exception { 068 doc = reader.read("{ \"foo\" : \"bar\" }"); 069 assertField("foo", "bar"); 070 } 071 072 @Test 073 public void shouldParseDocumentWithSingleFieldWithBooleanFalseValue() throws Exception { 074 doc = reader.read("{ \"foo\" : false }"); 075 assertField("foo", false); 076 } 077 078 @Test 079 public void shouldParseDocumentWithSingleFieldWithBooleanTrueValue() throws Exception { 080 doc = reader.read("{ \"foo\" : true }"); 081 assertField("foo", true); 082 } 083 084 @Test 085 public void shouldParseDocumentWithSingleFieldWithIntegerValue() throws Exception { 086 doc = reader.read("{ \"foo\" : 0 }"); 087 assertField("foo", 0); 088 } 089 090 @Test 091 public void shouldParseDocumentWithSingleFieldWithLongValue() throws Exception { 092 long val = Integer.MAX_VALUE + 10L; 093 doc = reader.read("{ \"foo\" : " + val + " }"); 094 assertField("foo", val); 095 } 096 097 @Test 098 public void shouldParseDocumentWithSingleFieldWithDoubleValue() throws Exception { 099 doc = reader.read("{ \"foo\" : 2.3543 }"); 100 assertField("foo", 2.3543d); 101 } 102 103 @Test 104 public void shouldParseDocumentWithMultipleFieldsAndExtraDelimiters() throws Exception { 105 doc = reader.read("{ \"foo\" : 32 ,, \"nested\" : { \"bar\" : \"baz\", \"bom\" : true } ,}"); 106 assertField("foo", 32); 107 doc = doc.getDocument("nested"); 108 assertField("bar", "baz"); 109 assertField("bom", true); 110 } 111 112 @Test 113 public void shouldParseMultipleDocuments() throws Exception { 114 InputStream stream = getClass().getClassLoader().getResourceAsStream("json/multiple-json-files.txt"); 115 DocumentSequence seq = reader.readMultiple(stream); 116 int count = 0; 117 while (true) { 118 Document doc = seq.nextDocument(); 119 if (doc == null) break; 120 ++count; 121 } 122 assertThat(count, is(265)); 123 } 124 125 @Test 126 @FixFor( "MODE-2309" ) 127 public void shouldParseJsonWithControlCharactersInFieldValues() throws Exception { 128 InputStream stream = getClass().getClassLoader().getResourceAsStream("json/example-with-control-characters.json"); 129 doc = reader.read(stream); 130 assertNotNull(doc); 131 assertEquals(6, countFields(doc)); 132 assertField("firstName", "Jane"); 133 assertField("lastName", "Doe"); 134 assertField("fieldWithLF", "This is a value\nwith a line feed"); 135 assertField("fieldWithCRLF", "This is a value\r\nwith a line feed\r\ncarriage return"); 136 137 doc = doc.getDocument("address"); 138 assertEquals(3, countFields(doc)); 139 assertField("street", "Main Street"); 140 assertField("city", "Memphis"); 141 assertField("zip", 12345); 142 } 143 144 @Test 145 @FixFor( "MODE-2082" ) 146 public void shouldParseJsonWithComments() throws Exception { 147 InputStream stream = getClass().getClassLoader().getResourceAsStream("json/example-with-comments.json"); 148 doc = reader.read(stream); 149 assertNotNull(doc); 150 assertEquals(4, countFields(doc)); 151 assertField("firstName", "Jane"); 152 assertField("lastName", "Doe"); 153 154 doc = doc.getDocument("address"); 155 assertEquals(3, countFields(doc)); 156 assertField("street", "Main // Street"); 157 assertField("city", "Mem/ phis"); 158 assertField("zip", 12345); 159 } 160 161 @Test 162 @FixFor( "MODE-2082" ) 163 public void shouldNotParseJsonWithInvalidComments() throws Exception { 164 InputStream stream = getClass().getClassLoader().getResourceAsStream("json/invalid-example-with-comments.json"); 165 try { 166 doc = reader.read(stream); 167 fail("Expected parsing exception"); 168 } catch (ParsingException e) { 169 // expected 170 } 171 172 stream = getClass().getClassLoader().getResourceAsStream("json/invalid-example-with-comments2.json"); 173 try { 174 doc = reader.read(stream); 175 fail("Expected parsing exception"); 176 } catch (ParsingException e) { 177 // expected 178 } 179 } 180 181 @Test 182 @FixFor( "MODE-2214" ) 183 public void shouldNotParseJsonWithInvalidArray() throws Exception { 184 InputStream stream = getClass().getClassLoader().getResourceAsStream("json/invalid-array-repo-config-1.json"); 185 try { 186 doc = reader.read(stream); 187 fail("Expected parsing exception"); 188 } catch (ParsingException e) { 189 // expected 190 } 191 192 stream = getClass().getClassLoader().getResourceAsStream("json/invalid-array-repo-config-2.json"); 193 try { 194 doc = reader.read(stream); 195 fail("Expected parsing exception"); 196 } catch (ParsingException e) { 197 // expected 198 } 199 } 200 201 @Test 202 @FixFor( "MODE-2317" ) 203 public void shouldParseNonUnicodeEscapeSequence() throws Exception { 204 String url = "jdbc:h2:file:path\\upstream.jboss-integration.modeshape\\modeshape-jcr;DB_CLOSE_DELAY=-1"; 205 doc = reader.read("{ \"url\" : \"" + url + "\"}"); 206 assertField("url", url); 207 208 InputStream stream = getClass().getClassLoader().getResourceAsStream("json/non-unicode-escape.json"); 209 reader.read(stream); 210 } 211 212 private int countFields( Document doc ) { 213 int fieldCount = 0; 214 for (Document.Field field : doc.fields()) { 215 assertThat(field, is(notNullValue())); 216 fieldCount++; 217 } 218 return fieldCount; 219 } 220 221 protected void assertField( String name, 222 Object value ) { 223 Object actual = doc.get(name); 224 if (value == null) { 225 assertNull(actual); 226 } else { 227 assertEquals(value, actual); 228 } 229 } 230 231}