Repository: avro Updated Branches: refs/heads/master ab25bf203 -> 1296ce923
AVRO-1849: C++: printJson fails on record with no fields. Contributed by Simon Woodford. Project: http://git-wip-us.apache.org/repos/asf/avro/repo Commit: http://git-wip-us.apache.org/repos/asf/avro/commit/1296ce92 Tree: http://git-wip-us.apache.org/repos/asf/avro/tree/1296ce92 Diff: http://git-wip-us.apache.org/repos/asf/avro/diff/1296ce92 Branch: refs/heads/master Commit: 1296ce9238a315b4323db351483dc66ec1a1afe3 Parents: ab25bf2 Author: Tom White <[email protected]> Authored: Tue Sep 27 15:50:56 2016 +0100 Committer: Tom White <[email protected]> Committed: Tue Sep 27 15:50:56 2016 +0100 ---------------------------------------------------------------------- CHANGES.txt | 3 ++ lang/c++/build.sh | 3 +- lang/c++/impl/NodeImpl.cc | 11 +++---- lang/c++/test/SchemaTests.cc | 68 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 76 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index eb5c3b2..d9b72ed 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -65,6 +65,9 @@ Trunk (not yet released) AVRO-1901: Record named "Exception" generated bad code. (Radai Rosenblatt via Niels Basjes) + AVRO-1849: C++: printJson fails on record with no fields. + (Simon Woodford vai tomwhite) + Avro 1.8.1 (14 May 2016) INCOMPATIBLE CHANGES http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/lang/c++/build.sh ---------------------------------------------------------------------- diff --git a/lang/c++/build.sh b/lang/c++/build.sh index 2c98885..c8281b4 100755 --- a/lang/c++/build.sh +++ b/lang/c++/build.sh @@ -83,7 +83,8 @@ case "$target" in && ./build/StreamTests \ && ./build/SpecificTests \ && ./build/AvrogencppTests \ - && ./build/DataFileTests) + && ./build/DataFileTests \ + && ./build/SchemaTests) ;; dist) http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/lang/c++/impl/NodeImpl.cc ---------------------------------------------------------------------- diff --git a/lang/c++/impl/NodeImpl.cc b/lang/c++/impl/NodeImpl.cc index aba2a73..606cd20 100644 --- a/lang/c++/impl/NodeImpl.cc +++ b/lang/c++/impl/NodeImpl.cc @@ -189,23 +189,22 @@ NodeRecord::printJson(std::ostream &os, int depth) const os << "{\n"; os << indent(++depth) << "\"type\": \"record\",\n"; printName(os, nameAttribute_.get(), depth); - os << indent(depth) << "\"fields\": [\n"; + os << indent(depth) << "\"fields\": ["; int fields = leafAttributes_.size(); ++depth; for(int i = 0; i < fields; ++i) { if(i > 0) { - os << indent(depth) << "},\n"; + os << ','; } - os << indent(depth) << "{\n"; + os << '\n' << indent(depth) << "{\n"; os << indent(++depth) << "\"name\": \"" << leafNameAttributes_.get(i) << "\",\n"; os << indent(depth) << "\"type\": "; leafAttributes_.get(i)->printJson(os, depth); os << '\n'; - --depth; + os << indent(--depth) << '}'; } - os << indent(depth) << "}\n"; - os << indent(--depth) << "]\n"; + os << '\n' << indent(--depth) << "]\n"; os << indent(--depth) << '}'; } http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/lang/c++/test/SchemaTests.cc ---------------------------------------------------------------------- diff --git a/lang/c++/test/SchemaTests.cc b/lang/c++/test/SchemaTests.cc index 7dce735..8ecde7a 100644 --- a/lang/c++/test/SchemaTests.cc +++ b/lang/c++/test/SchemaTests.cc @@ -23,7 +23,6 @@ #include <boost/test/unit_test.hpp> #include <boost/test/parameterized_test.hpp> - namespace avro { namespace schema { @@ -48,6 +47,7 @@ const char* basicSchemas[] = { "{ \"type\": \"string\" }", // Record + "{\"type\": \"record\",\"name\": \"Test\",\"fields\": []}", "{\"type\": \"record\",\"name\": \"Test\",\"fields\": " "[{\"name\": \"f\",\"type\": \"long\"}]}", "{\"type\": \"record\",\"name\": \"Test\",\"fields\": " @@ -136,6 +136,57 @@ const char* basicSchemaErrors[] = { "{\"type\": \"fixed\", \"size\": 314}", }; +const char* roundTripSchemas[] = { + "\"null\"", + "\"boolean\"", + "\"int\"", + "\"long\"", + "\"float\"", + "\"double\"", + "\"bytes\"", + "\"string\"", + // Record + "{\"type\":\"record\",\"name\":\"Test\",\"fields\":[]}", + "{\"type\":\"record\",\"name\":\"Test\",\"fields\":" + "[{\"name\":\"f\",\"type\":\"long\"}]}", + "{\"type\":\"record\",\"name\":\"Test\",\"fields\":" + "[{\"name\":\"f1\",\"type\":\"long\"}," + "{\"name\":\"f2\",\"type\":\"int\"}]}", +/* Avro-C++ cannot do a round-trip on error schemas. + * "{\"type\":\"error\",\"name\":\"Test\",\"fields\":" + * "[{\"name\":\"f1\",\"type\":\"long\"}," + * "{\"name\":\"f2\",\"type\":\"int\"}]}" + */ + // Recursive. + "{\"type\":\"record\",\"name\":\"LongList\"," + "\"fields\":[{\"name\":\"value\",\"type\":\"long\"}," + "{\"name\":\"next\",\"type\":[\"LongList\",\"null\"]}]}", + // Enum + "{\"type\":\"enum\",\"name\":\"Test\",\"symbols\":[\"A\",\"B\"]}", + + // Array + "{\"type\":\"array\",\"items\":\"long\"}", + "{\"type\":\"array\",\"items\":{\"type\":\"enum\"," + "\"name\":\"Test\",\"symbols\":[\"A\",\"B\"]}}", + + // Map + "{\"type\":\"map\",\"values\":\"long\"}", + "{\"type\":\"map\",\"values\":{\"type\":\"enum\"," + "\"name\":\"Test\",\"symbols\":[\"A\",\"B\"]}}", + + // Union + "[\"string\",\"null\",\"long\"]", + + // Fixed + "{\"type\":\"fixed\",\"name\":\"Test\",\"size\":1}", + "{\"type\":\"fixed\",\"namespace\":\"org.apache.hadoop.avro\"," + "\"name\":\"MyFixed\",\"size\":1}", + "{\"type\":\"fixed\",\"name\":\"Test\",\"size\":1}", + "{\"type\":\"fixed\",\"name\":\"Test\",\"size\":1}" +}; + + + static void testBasic(const char* schema) { BOOST_TEST_CHECKPOINT(schema); @@ -154,6 +205,19 @@ static void testCompile(const char* schema) compileJsonSchemaFromString(std::string(schema)); } +// Test that the JSON output from a valid schema matches the JSON that was +// used to construct it, apart from whitespace changes. +static void testRoundTrip(const char* schema) +{ + BOOST_TEST_CHECKPOINT(schema); + avro::ValidSchema compiledSchema = compileJsonSchemaFromString(std::string(schema)); + std::ostringstream os; + compiledSchema.toJson(os); + std::string result = os.str(); + result.erase(std::remove_if(result.begin(), result.end(), ::isspace), result.end()); // Remove whitespace + BOOST_CHECK(result == std::string(schema)); +} + } } @@ -173,6 +237,6 @@ init_unit_test_suite(int argc, char* argv[]) ADD_PARAM_TEST(ts, avro::schema::testBasic_fail, avro::schema::basicSchemaErrors); ADD_PARAM_TEST(ts, avro::schema::testCompile, avro::schema::basicSchemas); - + ADD_PARAM_TEST(ts, avro::schema::testRoundTrip, avro::schema::roundTripSchemas); return ts; }
