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.junit.Assert.assertEquals; 019import static org.junit.Assert.assertTrue; 020import java.io.StringReader; 021import java.util.Calendar; 022import java.util.Date; 023import java.util.TimeZone; 024import java.util.UUID; 025import org.junit.After; 026import org.junit.Before; 027import org.junit.Test; 028import org.modeshape.schematic.document.Binary; 029import org.modeshape.schematic.document.Bson; 030import org.modeshape.schematic.document.Code; 031import org.modeshape.schematic.document.CodeWithScope; 032import org.modeshape.schematic.document.Document; 033import org.modeshape.schematic.document.Null; 034import org.modeshape.schematic.document.ObjectId; 035 036public class JsonReaderParserTest { 037 038 protected boolean print; 039 protected Object value; 040 protected Document bson; 041 protected JsonWriter writer; 042 043 @Before 044 public void beforeTest() { 045 print = false; 046 writer = new CompactJsonWriter(); 047 } 048 049 @After 050 public void afterTest() { 051 value = null; 052 bson = null; 053 } 054 055 protected JsonReader.Parser parser( String string ) { 056 return new JsonReader.Parser(new JsonReader.Tokenizer(new StringReader(string)), JsonReader.VALUE_FACTORY, 057 JsonReader.DATE_VALUE_MATCHER); 058 } 059 060 @Test 061 public void shouldParseValueAsNullGivenNoContent() throws Exception { 062 value = parser("").parseValue(); 063 assertTrue(Null.matches(value)); 064 } 065 066 @Test 067 public void shouldParseValueAsNullGivenNullLiteral() throws Exception { 068 value = parser("null").parseValue(); 069 assertTrue(Null.matches(value)); 070 } 071 072 @Test 073 public void shouldParseValueAsNullGivenNullLiteralWithIncorrectCase() throws Exception { 074 value = parser("nULl").parseValue(); 075 assertTrue(Null.matches(value)); 076 } 077 078 @Test 079 public void shouldParseValueGivenTrueBooleanLiteral() throws Exception { 080 value = parser("true").parseValue(); 081 assertTrue(Boolean.TRUE.equals(value)); 082 } 083 084 @Test 085 public void shouldParseValueGivenFalseBooleanLiteral() throws Exception { 086 value = parser("false").parseValue(); 087 assertTrue(Boolean.FALSE.equals(value)); 088 } 089 090 @Test 091 public void shouldParseValueGivenTrueBooleanLiteralWithIncorrectCase() throws Exception { 092 value = parser("TrUe").parseValue(); 093 assertTrue(Boolean.TRUE.equals(value)); 094 } 095 096 @Test 097 public void shouldParseValueGivenFalseBooleanLiteralWithIncorrectCase() throws Exception { 098 value = parser("fAlSE").parseValue(); 099 assertTrue(Boolean.FALSE.equals(value)); 100 } 101 102 @Test 103 public void shouldParseValueGivenIntegerValues() throws Exception { 104 assertEquals(0, parser("0").parseValue()); 105 assertEquals(-1, parser("-1").parseValue()); 106 assertEquals(1, parser("1").parseValue()); 107 assertEquals(123456, parser("123456").parseValue()); 108 assertEquals(Integer.MAX_VALUE, parser("" + Integer.MAX_VALUE).parseValue()); 109 assertEquals(Integer.MIN_VALUE, parser("" + Integer.MIN_VALUE).parseValue()); 110 } 111 112 @Test 113 public void shouldParseValueGivenLongValues() throws Exception { 114 assertEquals(Integer.MAX_VALUE + 1L, parser("" + (Integer.MAX_VALUE + 1L)).parseValue()); 115 assertEquals(Integer.MIN_VALUE - 1L, parser("" + (Integer.MIN_VALUE - 1L)).parseValue()); 116 assertEquals(Long.MAX_VALUE, parser("" + Long.MAX_VALUE).parseValue()); 117 assertEquals(Long.MIN_VALUE, parser("" + Long.MIN_VALUE).parseValue()); 118 } 119 120 @Test 121 public void shouldParseValueGivenDoubleValues() throws Exception { 122 assertEquals(0.1d, parser("0.1").parseValue()); 123 assertEquals(1.0d, parser("1.0").parseValue()); 124 assertEquals(-1.0d, parser("-1.0").parseValue()); 125 assertEquals(-1000.0d, parser("-1.0e3").parseValue()); 126 assertEquals((double) Float.MAX_VALUE + 1f, parser("" + ((double) Float.MAX_VALUE + 1f)).parseValue()); 127 assertEquals((double) Float.MIN_VALUE - 1f, parser("" + ((double) Float.MIN_VALUE - 1f)).parseValue()); 128 assertEquals(Double.MAX_VALUE, parser("" + Double.MAX_VALUE).parseValue()); 129 assertEquals(Double.MIN_VALUE, parser("" + Double.MIN_VALUE).parseValue()); 130 } 131 132 @Test 133 public void shouldParseDocumentWithOneField() throws Exception { 134 bson = (Document)parser("{ \"foo\" : 32 }").parseValue(); 135 assertField("foo", 32); 136 } 137 138 @Test 139 public void shouldParseDocumentWithTwoFields() throws Exception { 140 bson = (Document)parser("{ \"foo\" : 32 , \"bar\" : \"baz\" }").parseValue(); 141 assertField("foo", 32); 142 assertField("bar", "baz"); 143 } 144 145 @Test 146 public void shouldParseDocumentWithThreeFields() throws Exception { 147 bson = (Document)parser("{ \"foo\" : 32 , \"bar\" : \"baz\", \"bom\" : true }").parseValue(); 148 assertField("foo", 32); 149 assertField("bar", "baz"); 150 assertField("bom", true); 151 } 152 153 @Test 154 public void shouldParseDocumentWithNestedDocument() throws Exception { 155 bson = (Document)parser("{ \"foo\" : 32 , \"nested\" : { \"bar\" : \"baz\", \"bom\" : true }}").parseValue(); 156 assertField("foo", 32); 157 bson = bson.getDocument("nested"); 158 assertField("bar", "baz"); 159 assertField("bom", true); 160 } 161 162 @Test 163 public void shouldParseDocumentWithExtraTrailingFieldDelimiter() throws Exception { 164 bson = (Document)parser("{ \"foo\" : 32 , \"bar\" : \"baz\", }").parseValue(); 165 assertField("foo", 32); 166 assertField("bar", "baz"); 167 } 168 169 @Test 170 public void shouldParseDocumentWithExtraFieldDelimiters() throws Exception { 171 bson = (Document)parser("{ \"foo\" : 32 , , \"bar\" : \"baz\",, }").parseValue(); 172 assertField("foo", 32); 173 assertField("bar", "baz"); 174 } 175 176 @Test 177 public void shouldParseDocumentWithUuid() throws Exception { 178 UUID obj = UUID.randomUUID(); 179 value = parser(writer.write(obj)).parseValue(); 180 assertEquals(obj, value); 181 } 182 183 @Test 184 public void shouldParseDocumentWithObjectId() throws Exception { 185 ObjectId obj = new ObjectId(300, 200, 9, 15); 186 value = parser(writer.write(obj)).parseValue(); 187 assertEquals(obj, value); 188 } 189 190 @Test 191 public void shouldParseDocumentWithDate() throws Exception { 192 Date obj = now(); 193 String dateDoc = writer.write(obj); 194 value = parser(dateDoc).parseValue(); 195 assertTrue(value instanceof Date); 196 } 197 198 @Test 199 public void shouldParseDocumentWithCode() throws Exception { 200 Code obj = new Code("foo"); 201 value = parser(writer.write(obj)).parseValue(); 202 assertEquals(obj, value); 203 } 204 205 @Test 206 public void shouldParseDocumentWithCodeAndSscope() throws Exception { 207 Document scope = (Document)parser("{ \"foo\" : 32 }").parseValue(); 208 CodeWithScope obj = new CodeWithScope("foo", scope); 209 // String str = writer.write(obj); 210 // print = true; 211 // print(str); 212 value = parser(writer.write(obj)).parseValue(); 213 assertEquals(obj, value); 214 } 215 216 @Test 217 public void shouldParseDocumentWithBinary() throws Exception { 218 byte[] bytes = new byte[] {0x13, 0x22, 0x53, 0x00}; 219 Binary obj = new Binary(Bson.BinaryType.MD5, bytes); 220 value = parser(writer.write(obj)).parseValue(); 221 assertEquals(obj, value); 222 } 223 224 @Test 225 public void shouldParseIsoFormat() throws Exception { 226 value = Bson.getDateParsingFormatter().parse("2011-06-14T16:05:11GMT+00:00"); 227 Date date = (Date)value; 228 assertTrue(date.after(date(2011, 06, 13))); 229 assertTrue(date.before(date(2011, 06, 16))); 230 } 231 232 @Test 233 public void shouldParseMsDateFormat() throws Exception { 234 value = JsonReader.DATE_VALUE_MATCHER.parseValue("\\/Date(2011-06-14T16:05:11GMT+00:00)\\/"); 235 assertTrue(value instanceof Date); 236 Date date = (Date)value; 237 assertTrue(date.after(date(2011, 06, 13))); 238 assertTrue(date.before(date(2011, 06, 16))); 239 } 240 241 @Test 242 public void shouldParseMsDateFormatWithSpaces() throws Exception { 243 value = JsonReader.DATE_VALUE_MATCHER.parseValue("\\/Date( 2011-06-14T16:05:11GMT+00:00 )\\/"); 244 assertTrue(value instanceof Date); 245 Date date = (Date)value; 246 assertTrue(date.after(date(2011, 06, 13))); 247 assertTrue(date.before(date(2011, 06, 16))); 248 } 249 250 @Test 251 public void shouldParseEscapedDateFormat() throws Exception { 252 value = JsonReader.DATE_VALUE_MATCHER.parseValue("/Date(2011-06-14T16:05:11GMT+00:00)/"); 253 assertTrue(value instanceof Date); 254 Date date = (Date)value; 255 assertTrue(date.after(date(2011, 06, 13))); 256 assertTrue(date.before(date(2011, 06, 16))); 257 } 258 259 protected Date date( int year, 260 int month, 261 int day ) { 262 Calendar cal = Calendar.getInstance(); 263 cal.clear(); 264 cal.setTimeZone(TimeZone.getTimeZone("GMT")); 265 cal.set(year, month - 1, day); 266 return cal.getTime(); 267 } 268 269 @Test 270 public void shouldParseEscapedDateFormatWithSpaces() throws Exception { 271 value = JsonReader.DATE_VALUE_MATCHER.parseValue("/Date( 2011-06-14T16:05:11GMT+00:00 )/"); 272 assertTrue(value instanceof Date); 273 Date date = (Date)value; 274 assertTrue(date.after(date(2011, 06, 13))); 275 assertTrue(date.before(date(2011, 06, 16))); 276 } 277 278 @Test 279 public void shouldEvaluateIsoDateWithGmtTimeZone() throws Exception { 280 value = JsonReader.DATE_VALUE_MATCHER.parseValue("2011-06-14T16:05:11GMT+00:00"); 281 assertTrue(value instanceof Date); 282 Date date = (Date)value; 283 assertTrue(date.after(date(2011, 06, 13))); 284 assertTrue(date.before(date(2011, 06, 16))); 285 } 286 287 @Test 288 public void shouldEvaluateIsoDateWithZuluTimeZone() throws Exception { 289 value = JsonReader.DATE_VALUE_MATCHER.parseValue("2011-06-14T16:05:11Z"); 290 assertTrue(value instanceof Date); 291 Date date = (Date)value; 292 assertTrue(date.after(date(2011, 06, 13))); 293 assertTrue(date.before(date(2011, 06, 16))); 294 } 295 296 @Test 297 public void shouldParseIsoDateWithZuluTimeZone() throws Exception { 298 Date date = now(); 299 value = JsonReader.DATE_VALUE_MATCHER.parseValue(Bson.getDateFormatter().format(date)); 300 assertTrue(value instanceof Date); 301 } 302 303 @Test 304 public void dateMatcherShouldPreserveBackslashEscapeChars() throws Exception { 305 String value1 = "one\\backslash"; 306 assertEquals(value1, JsonReader.DATE_VALUE_MATCHER.parseValue(value1)); 307 String value2 = "two\\\\backslashes"; 308 assertEquals(value2, JsonReader.DATE_VALUE_MATCHER.parseValue(value2)); 309 String value3 = "three\\\\\\backslashes"; 310 assertEquals(value3, JsonReader.DATE_VALUE_MATCHER.parseValue(value3)); 311 } 312 313 protected void print( Object object ) { 314 if (print) { 315 System.out.println(object); 316 System.out.flush(); 317 } 318 } 319 320 protected Date now() { 321 return new Date(); 322 } 323 324 protected void assertField( String name, 325 Object value ) { 326 Object actual = bson.get(name); 327 if (value == null) { 328 assertTrue(Null.matches(actual)); 329 } else { 330 assertEquals(value, actual); 331 } 332 } 333}