package com.googlecode.totallylazy.json;
import com.googlecode.totallylazy.Maps;
import com.googlecode.totallylazy.Pair;
import com.googlecode.totallylazy.Unchecked;
import com.googlecode.totallylazy.functions.TimeReport;
import com.googlecode.totallylazy.matchers.NumberMatcher;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.junit.Ignore;
import org.junit.Test;
import java.util.List;
import java.util.Map;
import static com.googlecode.totallylazy.Lists.list;
import static com.googlecode.totallylazy.Maps.map;
import static com.googlecode.totallylazy.Sequences.sequence;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
public class GrammarTest {
@Test
public void canParseNull() throws Exception {
assertThat(Grammar.NULL.parse("null").value(), is(nullValue()));
assertThat(Grammar.NULL.parse("falure").failure(), is(true));
}
@Test
public void canParseABoolean() throws Exception {
assertThat(Grammar.BOOLEAN.parse("true").value(), is(true));
assertThat(Grammar.BOOLEAN.parse("false").value(), is(false));
assertThat(Grammar.BOOLEAN.parse("falure").failure(), is(true));
}
@Test
public void canHandleEscapedCharacters() throws Exception {
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\\"").value(), is("\""));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\\\").value(), is("\\"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\/").value(), is("/"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\b").value(), is("\b"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\f").value(), is("\f"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\n").value(), is("\n"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\r").value(), is("\r"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\t").value(), is("\t"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("falure").failure(), is(true));
}
@Test
public void handlesUnicodeCharacters() throws Exception {
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\u03BB").value(), is("λ"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\u5c71").value(), is("山"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\u7530").value(), is("田"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\u3000").value(), is(" "));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\u7ae0").value(), is("章"));
assertThat(Grammar.ESCAPED_CHARACTER.parse("\\u96c4").value(), is("雄"));
}
@Test
public void canParseString() throws Exception {
assertThat(Grammar.STRING.parse("\"\"").value(), is(""));
assertThat(Grammar.STRING.parse("\"Word\"").value(), is("Word"));
assertThat(Grammar.STRING.parse("\"This is some \\\" random string\"").value(), is("This is some \" random string"));
assertThat(Grammar.STRING.parse("\"Text with unicode \\u03BB\"").value(), is("Text with unicode λ"));
assertThat(Grammar.STRING.parse("falure").failure(), is(true));
}
@Test
public void canParseNumber() throws Exception {
assertThat(Grammar.NUMBER.parse("12").value(), NumberMatcher.is(12));
assertThat(Grammar.NUMBER.parse("12.1").value(), NumberMatcher.is(12.1));
assertThat(Grammar.NUMBER.parse("-12").value(), NumberMatcher.is(-12));
}
@Test
public void canParsePair() throws Exception {
Pair<String, Object> pair = Grammar.PAIR.parse("\"foo\":\"value\"").value();
assertThat(pair.first(), is("foo"));
assertThat((String) pair.second(), is("value"));
Pair<String, Object> parse = Grammar.PAIR.parse("\"foo\":123").value();
assertThat(parse.first(), is("foo"));
assertThat((Number) parse.second(), NumberMatcher.is(123));
}
@Test
public void canParseArray() throws Exception {
List<Object> listOfOne = Grammar.ARRAY.parse("[\"foo\"]").value();
assertThat((String) listOfOne.get(0), is("foo"));
List<Object> listOfTwo = Grammar.ARRAY.parse("[\"foo\", 123 ]").value();
assertThat((String) listOfTwo.get(0), is("foo"));
assertThat((Number) listOfTwo.get(1), NumberMatcher.is(123));
List<Object> empty = Grammar.ARRAY.parse("[]").value();
assertThat(empty.isEmpty(), is(true));
List<Object> nested = Grammar.ARRAY.parse("[[\"cats\", \"dogs\"],[true, false],{\"foo\": true, \"bar\": false }]").value();
assertThat(Unchecked.<List<String>>cast(nested.get(0)), is(list("cats", "dogs")));
assertThat(Unchecked.<List<Boolean>>cast(nested.get(1)), is(list(true, false)));
assertThat(Unchecked.<Map<String, Boolean>>cast(nested.get(2)), is(map("foo", true, "bar", false)));
}
@Test
public void canParseObjectLiteral() throws Exception {
Map<String, Object> mapOfOne = Grammar.OBJECT.parse("{ \"foo\" : 123 } ").value();
assertThat((Number) mapOfOne.get("foo"), NumberMatcher.is(123));
Map<String, Object> mapOfTwo = Grammar.OBJECT.parse("{\"foo\":123,\"bar\":\"baz\"}").value();
assertThat((Number) mapOfTwo.get("foo"), NumberMatcher.is(123));
assertThat((String) mapOfTwo.get("bar"), is("baz"));
Map<String, Object> empty = Grammar.OBJECT.parse("{}").value();
assertThat(empty.isEmpty(), is(true));
}
@Test
public void canParseAValue() throws Exception {
Number number = (Number) Grammar.VALUE.parse("1").value();
assertThat(number, NumberMatcher.is(1));
String string = (String) Grammar.VALUE.parse("\"foo\"").value();
assertThat(string, is("foo"));
Map map = (Map) Grammar.VALUE.parse("{\"foo\":123}").value();
assertThat((Number) map.get("foo"), NumberMatcher.is(123));
List array = (List) Grammar.VALUE.parse("[\"foo\",123]").value();
assertThat(array.get(0), is((Object) "foo"));
assertThat((Number) array.get(1), NumberMatcher.is(123));
}
@Test
public void canParseNestedJson() throws Exception {
Map map = (Map) Grammar.VALUE.parse(" { \"root\" : { \"foo\" : [ \"bar\", { \"baz\" : [1, null, true, false, 12.3 ] } ] } } ").value();
Map root = (Map) map.get("root");
List foo = (List) root.get("foo");
assertThat(foo.get(0), is((Object) "bar"));
Map child = (Map) foo.get(1);
List baz = (List) child.get("baz");
assertThat((Number)baz.get(0), NumberMatcher.is(1));
assertThat(baz.get(1), is((nullValue())));
assertThat(baz.get(2), is(((Object) true)));
assertThat(baz.get(3), is(((Object) false)));
assertThat((Number) baz.get(4), NumberMatcher.is(12.3));
}
@Test
@Ignore("Manual test")
public void performanceTest() throws Exception {
final String json = "{\n" +
" \"graph\": {\n" +
" \"mode\":\"NORMAL\",\n" +
" \"vertices\": [\n" +
" {\n" +
" \"name\": \"lop\",\n" +
" \"lang\": \"java\",\n" +
" \"_id\": \"3\",\n" +
" \"_type\": \"vertex\"\n" +
" },\n" +
" {\n" +
" \"name\": \"vadas\",\n" +
" \"age\": 27,\n" +
" \"_id\": \"2\",\n" +
" \"_type\": \"vertex\"\n" +
" },\n" +
" {\n" +
" \"name\": \"marko\",\n" +
" \"age\": 29,\n" +
" \"_id\": \"1\",\n" +
" \"_type\": \"vertex\"\n" +
" },\n" +
" {\n" +
" \"name\": \"peter\",\n" +
" \"age\": 35,\n" +
" \"_id\": \"6\",\n" +
" \"_type\": \"vertex\"\n" +
" },\n" +
" {\n" +
" \"name\": \"ripple\",\n" +
" \"lang\": \"java\",\n" +
" \"_id\": \"5\",\n" +
" \"_type\": \"vertex\"\n" +
" },\n" +
" {\n" +
" \"name\": \"josh\",\n" +
" \"age\": 32,\n" +
" \"_id\": \"4\",\n" +
" \"_type\": \"vertex\"\n" +
" }\n" +
" ],\n" +
" \"edges\": [\n" +
" {\n" +
" \"weight\": 1,\n" +
" \"_id\": \"10\",\n" +
" \"_type\": \"edge\",\n" +
" \"_outV\": \"4\",\n" +
" \"_inV\": \"5\",\n" +
" \"_label\": \"created\"\n" +
" },\n" +
" {\n" +
" \"weight\": 0.5,\n" +
" \"_id\": \"7\",\n" +
" \"_type\": \"edge\",\n" +
" \"_outV\": \"1\",\n" +
" \"_inV\": \"2\",\n" +
" \"_label\": \"knows\"\n" +
" },\n" +
" {\n" +
" \"weight\": 0.4000000059604645,\n" +
" \"_id\": \"9\",\n" +
" \"_type\": \"edge\",\n" +
" \"_outV\": \"1\",\n" +
" \"_inV\": \"3\",\n" +
" \"_label\": \"created\"\n" +
" },\n" +
" {\n" +
" \"weight\": 1,\n" +
" \"_id\": \"8\",\n" +
" \"_type\": \"edge\",\n" +
" \"_outV\": \"1\",\n" +
" \"_inV\": \"4\",\n" +
" \"_label\": \"knows\"\n" +
" },\n" +
" {\n" +
" \"weight\": 0.4000000059604645,\n" +
" \"_id\": \"11\",\n" +
" \"_type\": \"edge\",\n" +
" \"_outV\": \"4\",\n" +
" \"_inV\": \"3\",\n" +
" \"_label\": \"created\"\n" +
" },\n" +
" {\n" +
" \"weight\": 0.20000000298023224,\n" +
" \"_id\": \"12\",\n" +
" \"_type\": \"edge\",\n" +
" \"_outV\": \"6\",\n" +
" \"_inV\": \"3\",\n" +
" \"_label\": \"created\"\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
System.out.println(TimeReport.time(10000, () -> Grammar.OBJECT.parse(json).value()));
}
}