@Test public void testFieldDocs() { String schemaStr = "{\"name\": \"Rec\",\"type\": \"record\",\"fields\" : [" + "{\"name\": \"f\", \"type\": \"int\", \"doc\": \"test\"}]}"; // check field doc is parsed correctly Schema schema = Schema.parse(schemaStr); assertEquals("test", schema.getField("f").doc()); // check print/read cycle preserves field doc schema = Schema.parse(schema.toString()); assertEquals("test", schema.getField("f").doc()); }
/** Returns an object of the same type as {@code o}, or null if it is not retained. */ private Object retainAll(Schema schema, MarkSet markSet, ProtoType type, Object o) { if (!markSet.contains(type)) { return null; // Prune this type. } else if (o instanceof Map) { ImmutableMap.Builder<ProtoMember, Object> builder = ImmutableMap.builder(); for (Map.Entry<?, ?> entry : ((Map<?, ?>) o).entrySet()) { ProtoMember protoMember = (ProtoMember) entry.getKey(); if (!markSet.contains(protoMember)) continue; // Prune this field. Field field = schema.getField(protoMember); Object retainedValue = retainAll(schema, markSet, field.type(), entry.getValue()); if (retainedValue != null) { builder.put(protoMember, retainedValue); // This retained field is non-empty. } } ImmutableMap<ProtoMember, Object> map = builder.build(); return !map.isEmpty() ? map : null; } else if (o instanceof List) { ImmutableList.Builder<Object> builder = ImmutableList.builder(); for (Object value : ((List) o)) { Object retainedValue = retainAll(schema, markSet, type, value); if (retainedValue != null) { builder.add(retainedValue); // This retained value is non-empty. } } ImmutableList<Object> list = builder.build(); return !list.isEmpty() ? list : null; } else { return o; } }
@Test public void testNamespaceScope() throws Exception { String z = "{\"type\":\"record\",\"name\":\"Z\",\"fields\":[]}"; String y = "{\"type\":\"record\",\"name\":\"q.Y\",\"fields\":[" + "{\"name\":\"f\",\"type\":" + z + "}]}"; String x = "{\"type\":\"record\",\"name\":\"p.X\",\"fields\":[" + "{\"name\":\"f\",\"type\":" + y + "}," + "{\"name\":\"g\",\"type\":" + z + "}" + "]}"; Schema xs = Schema.parse(x); Schema ys = xs.getField("f").schema(); assertEquals("p.Z", xs.getField("g").schema().getFullName()); assertEquals("q.Z", ys.getField("f").schema().getFullName()); }
@Test public void testAliases() throws Exception { String t1 = "{\"type\":\"record\",\"name\":\"a.b\",\"fields\":[" + "{\"name\":\"f\",\"type\":\"long\"}," + "{\"name\":\"h\",\"type\":\"int\"}]}"; String t2 = "{\"type\":\"record\",\"name\":\"x.y\",\"aliases\":[\"a.b\"]," + "\"fields\":[{\"name\":\"g\",\"type\":\"long\",\"aliases\":[\"f\"]}," + "{\"name\":\"h\",\"type\":\"int\"}]}"; Schema s1 = Schema.parse(t1); Schema s2 = Schema.parse(t2); assertEquals(s1.getAliases(), Collections.emptySet()); assertEquals(s1.getField("f").aliases(), Collections.emptySet()); assertEquals(s2.getAliases(), Collections.singleton("a.b")); assertEquals(s2.getField("g").aliases(), Collections.singleton("f")); Schema s3 = Schema.applyAliases(s1, s2); assertFalse(s2 == s3); assertEquals(s2, s3); t1 = "{\"type\":\"enum\",\"name\":\"a.b\"," + "\"symbols\":[\"x\"]}"; t2 = "{\"type\":\"enum\",\"name\":\"a.c\",\"aliases\":[\"b\"]," + "\"symbols\":[\"x\"]}"; s1 = Schema.parse(t1); s2 = Schema.parse(t2); s3 = Schema.applyAliases(s1, s2); assertFalse(s2 == s3); assertEquals(s2, s3); t1 = "{\"type\":\"fixed\",\"name\":\"a\"," + "\"size\": 5}"; t2 = "{\"type\":\"fixed\",\"name\":\"b\",\"aliases\":[\"a\"]," + "\"size\": 5}"; s1 = Schema.parse(t1); s2 = Schema.parse(t2); s3 = Schema.applyAliases(s1, s2); assertFalse(s2 == s3); assertEquals(s2, s3); }
@Test public void testRecord() throws Exception { String recordJson = "{\"type\":\"record\", \"name\":\"Test\", \"fields\":" + "[{\"name\":\"f\", \"type\":\"long\", \"foo\":\"bar\"}]}"; Schema schema = Schema.parse(recordJson); GenericData.Record record = new GenericData.Record(schema); record.put("f", 11L); check(recordJson, "{\"f\":11}", record, false); // test field props assertEquals("bar", schema.getField("f").getProp("foo")); assertEquals("bar", Schema.parse(schema.toString()).getField("f").getProp("foo")); schema.getField("f").addProp("baz", "boo"); assertEquals("boo", schema.getField("f").getProp("baz")); checkParseError("{\"type\":\"record\"}"); checkParseError("{\"type\":\"record\",\"name\":\"X\"}"); checkParseError("{\"type\":\"record\",\"name\":\"X\",\"fields\":\"Y\"}"); checkParseError( "{\"type\":\"record\",\"name\":\"X\",\"fields\":" + "[{\"name\":\"f\"}]}"); // no type checkParseError( "{\"type\":\"record\",\"name\":\"X\",\"fields\":" + "[{\"type\":\"long\"}]}"); // no name // check invalid record names checkParseError("{\"type\":\"record\",\"name\":\"1X\",\"fields\":[]}"); checkParseError("{\"type\":\"record\",\"name\":\"X$\",\"fields\":[]}"); // check invalid field names checkParseError( "{\"type\":\"record\",\"name\":\"X\",\"fields\":[" + "{\"name\":\"1f\",\"type\":\"int\"}]}"); checkParseError( "{\"type\":\"record\",\"name\":\"X\",\"fields\":[" + "{\"name\":\"f$\",\"type\":\"int\"}]}"); checkParseError( "{\"type\":\"record\",\"name\":\"X\",\"fields\":[" + "{\"name\":\"f.g\",\"type\":\"int\"}]}"); }
/** * Makes sure that "doc" tags are transcribed in the schemas. Note that there are docs both for * fields and for the records themselves. */ @Test public void testDocs() { Schema schema = Schema.parse(SCHEMA_WITH_DOC_TAGS); assertEquals("This is not a world record.", schema.getDoc()); assertEquals("Inner Fixed", schema.getField("inner_fixed").doc()); assertEquals("Very Inner Fixed", schema.getField("inner_fixed").schema().getDoc()); assertEquals("Inner String", schema.getField("inner_string").doc()); assertEquals("Inner Enum", schema.getField("inner_enum").doc()); assertEquals("Very Inner Enum", schema.getField("inner_enum").schema().getDoc()); assertEquals("Inner Union", schema.getField("inner_union").doc()); }