[fidl] Add JSON generation tests
Test: make -j 12 HOST_USE_ASAN=true tools && ./build-x64/host_tests/fidl-compiler-test
Change-Id: I1a8f6cb83ed479acc1202b7265846d658fdc6ddf
diff --git a/system/utest/fidl-compiler/json_generator_tests.cpp b/system/utest/fidl-compiler/json_generator_tests.cpp
new file mode 100644
index 0000000..fb5af64
--- /dev/null
+++ b/system/utest/fidl-compiler/json_generator_tests.cpp
@@ -0,0 +1,247 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <unittest/unittest.h>
+
+#include <fidl/flat_ast.h>
+#include <fidl/lexer.h>
+#include <fidl/parser.h>
+#include <fidl/source_file.h>
+
+#include <fstream>
+
+#include "examples.h"
+#include "test_library.h"
+
+namespace {
+
+static inline void trim(std::string &s) {
+ s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
+ return !std::isspace(ch) && ch != '\n';
+ }));
+ s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
+ return !std::isspace(ch) && ch != '\n';
+ }).base(), s.end());
+}
+
+bool checkJSONGenerator(std::string raw_source_code, std::string expected_json) {
+ TestLibrary library("json.fidl", raw_source_code);
+ EXPECT_TRUE(library.Compile());
+
+ // actual
+ auto actual = library.GenerateJSON();
+ trim(actual);
+
+ // expected
+ trim(expected_json);
+
+ if (actual.compare(expected_json) == 0) {
+ return true;
+ }
+
+ // On error, we output both the actual and expected to allow simple
+ // diffing to debug the test.
+
+ std::ofstream output_actual("json_generator_tests_actual.txt");
+ output_actual << actual;
+ output_actual.close();
+
+ std::ofstream output_expected("json_generator_tests_expected.txt");
+ output_expected << expected_json;
+ output_expected.close();
+
+ return false;
+}
+
+bool json_generator_test_simple() {
+ BEGIN_TEST;
+
+ EXPECT_TRUE(checkJSONGenerator(R"FIDL(
+library fidl.test.json;
+
+struct Simple {
+ uint8 f1;
+ bool f2;
+};
+
+)FIDL", R"JSON(
+{
+ "version": "0.0.1",
+ "name": "fidl.test.json",
+ "library_dependencies": [],
+ "const_declarations": [],
+ "enum_declarations": [],
+ "interface_declarations": [],
+ "struct_declarations": [
+ {
+ "name": "fidl.test.json/Simple",
+ "members": [
+ {
+ "type": {
+ "kind": "primitive",
+ "subtype": "uint8"
+ },
+ "name": "f1",
+ "size": 1,
+ "alignment": 1,
+ "offset": 0,
+ "max_handles": 0
+ },
+ {
+ "type": {
+ "kind": "primitive",
+ "subtype": "bool"
+ },
+ "name": "f2",
+ "size": 1,
+ "alignment": 1,
+ "offset": 1,
+ "max_handles": 0
+ }
+ ],
+ "size": 2,
+ "alignment": 1,
+ "max_handles": 0
+ }
+ ],
+ "union_declarations": [],
+ "declaration_order": [
+ "fidl.test.json/Simple"
+ ],
+ "declarations": {
+ "fidl.test.json/Simple": "struct"
+ }
+}
+)JSON"));
+
+ END_TEST;
+}
+
+bool json_generator_test_union() {
+ BEGIN_TEST;
+
+ EXPECT_TRUE(checkJSONGenerator(R"FIDL(
+library fidl.test.json;
+
+struct Pizza {
+ vector<string:16> toppings;
+};
+
+struct Pasta {
+ string:16 sauce;
+};
+
+union PizzaOrPasta {
+ Pizza pizza;
+ Pasta pasta;
+};
+
+)FIDL", R"JSON(
+{
+ "version": "0.0.1",
+ "name": "fidl.test.json",
+ "library_dependencies": [],
+ "const_declarations": [],
+ "enum_declarations": [],
+ "interface_declarations": [],
+ "struct_declarations": [
+ {
+ "name": "fidl.test.json/Pizza",
+ "members": [
+ {
+ "type": {
+ "kind": "vector",
+ "element_type": {
+ "kind": "string",
+ "maybe_element_count": 16,
+ "nullable": false
+ },
+ "nullable": false
+ },
+ "name": "toppings",
+ "size": 16,
+ "alignment": 8,
+ "offset": 0,
+ "max_handles": 0
+ }
+ ],
+ "size": 16,
+ "alignment": 8,
+ "max_handles": 0
+ },
+ {
+ "name": "fidl.test.json/Pasta",
+ "members": [
+ {
+ "type": {
+ "kind": "string",
+ "maybe_element_count": 16,
+ "nullable": false
+ },
+ "name": "sauce",
+ "size": 16,
+ "alignment": 8,
+ "offset": 0,
+ "max_handles": 0
+ }
+ ],
+ "size": 16,
+ "alignment": 8,
+ "max_handles": 0
+ }
+ ],
+ "union_declarations": [
+ {
+ "name": "fidl.test.json/PizzaOrPasta",
+ "members": [
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.json/Pizza",
+ "nullable": false
+ },
+ "name": "pizza",
+ "size": 16,
+ "alignment": 8,
+ "offset": 8
+ },
+ {
+ "type": {
+ "kind": "identifier",
+ "identifier": "fidl.test.json/Pasta",
+ "nullable": false
+ },
+ "name": "pasta",
+ "size": 16,
+ "alignment": 8,
+ "offset": 8
+ }
+ ],
+ "size": 24,
+ "alignment": 8,
+ "max_handles": 0
+ }
+ ],
+ "declaration_order": [
+ "fidl.test.json/Pasta",
+ "fidl.test.json/Pizza",
+ "fidl.test.json/PizzaOrPasta"
+ ],
+ "declarations": {
+ "fidl.test.json/Pizza": "struct",
+ "fidl.test.json/Pasta": "struct",
+ "fidl.test.json/PizzaOrPasta": "union"
+ }
+}
+)JSON"));
+
+ END_TEST;
+}
+
+} // namespace
+
+BEGIN_TEST_CASE(json_generator_tests);
+RUN_TEST(json_generator_test_simple);
+RUN_TEST(json_generator_test_union);
+END_TEST_CASE(json_generator_tests);
diff --git a/system/utest/fidl-compiler/rules.mk b/system/utest/fidl-compiler/rules.mk
index 74b8f45..e6370b9 100644
--- a/system/utest/fidl-compiler/rules.mk
+++ b/system/utest/fidl-compiler/rules.mk
@@ -65,6 +65,7 @@
$(LOCAL_DIR)/bad_compound_identifier_tests.cpp \
$(LOCAL_DIR)/dup_attributes_tests.cpp \
$(LOCAL_DIR)/formatter_unittests.cpp \
+ $(LOCAL_DIR)/json_generator_tests.cpp \
$(LOCAL_DIR)/max_bytes_tests.cpp \
$(LOCAL_DIR)/max_handle_tests.cpp \
$(LOCAL_DIR)/superinterface_tests.cpp \
diff --git a/system/utest/fidl-compiler/test_library.h b/system/utest/fidl-compiler/test_library.h
index 0a59953..ddfaf6e 100644
--- a/system/utest/fidl-compiler/test_library.h
+++ b/system/utest/fidl-compiler/test_library.h
@@ -6,6 +6,7 @@
#define ZIRCON_SYSTEM_UTEST_FIDL_COMPILER_TEST_LIBRARY_H_
#include <fidl/flat_ast.h>
+#include <fidl/json_generator.h>
#include <fidl/lexer.h>
#include <fidl/parser.h>
#include <fidl/source_file.h>
@@ -51,6 +52,12 @@
library_->Compile();
}
+ std::string GenerateJSON() {
+ auto json_generator = fidl::JSONGenerator(library_.get());
+ auto out = json_generator.Produce();
+ return out.str();
+ }
+
bool AddSourceFile(const std::string& filename, const std::string& raw_source_code) {
auto source_file = MakeSourceFile(filename, raw_source_code);
fidl::IdentifierTable identifier_table;