[fostr] Start of hermetic tests for fostr

And test-driving fix to bits formatting.

FIDL-623 #comment

Test: added
Change-Id: I540686e0a525b2a3a13876458080c45fc2d3807e
diff --git a/garnet/public/build/fostr/fostr.fidlmerge b/garnet/public/build/fostr/fostr.fidlmerge
index 623b526..d017651 100644
--- a/garnet/public/build/fostr/fostr.fidlmerge
+++ b/garnet/public/build/fostr/fostr.fidlmerge
@@ -176,12 +176,18 @@
         {{- $type_name := .Name.Parts.Name }}
 std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
   using fidl::operator<<;
-  switch (value) {
+  bool is_first = true;
         {{- range .Members }}
-    case {{ $type_name }}::{{ .Name }}:
-      return os << "{{ toFriendlyCase .Name }}";
-        {{- end }}
+  // TODO(FIDL-620): Simplify when bool conversion is supported.
+  if ((value & {{ $type_name }}::{{ .Name }}) != {{ $type_name }}(0)) {
+    if (is_first) {
+      is_first = false;
+    } else {
+      os << "|";
+    }
+    os << "{{ toFriendlyCase .Name }}";
   }
+        {{- end }}
 
   return os;
 }
diff --git a/garnet/public/lib/fostr/BUILD.gn b/garnet/public/lib/fostr/BUILD.gn
index 4fa36de..a328835 100644
--- a/garnet/public/lib/fostr/BUILD.gn
+++ b/garnet/public/lib/fostr/BUILD.gn
@@ -64,6 +64,10 @@
   deps = [
     ":fostr",
     "//garnet/public/lib/fsl",
+    "//garnet/public/lib/fostr/fidl/fuchsia.example.fostr",
+    # TODO(FIDL-623): Remove dependency on fuchsia.sys. We should instead be
+    # using the fuchsia.example.fostr library to avoid changes in unrelated code
+    # to break tests here.
     "//sdk/fidl/fuchsia.sys",
     "//sdk/lib/fidl/cpp",
     "//src/lib/fxl/test:gtest_main",
diff --git a/garnet/public/lib/fostr/fidl/fuchsia.example.fostr/BUILD.gn b/garnet/public/lib/fostr/fidl/fuchsia.example.fostr/BUILD.gn
new file mode 100644
index 0000000..020050c
--- /dev/null
+++ b/garnet/public/lib/fostr/fidl/fuchsia.example.fostr/BUILD.gn
@@ -0,0 +1,9 @@
+# Copyright 2019 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.
+
+import("//garnet/public/build/fostr/fostr_fidl.gni")
+
+fostr_fidl("fuchsia.example.fostr") {
+  fidl_target = "//garnet/public/lib/fostr/test/fuchsia.example.fostr"
+}
diff --git a/garnet/public/lib/fostr/test/fidl_types_unittests.cc b/garnet/public/lib/fostr/test/fidl_types_unittests.cc
index 339b669..986a9cc 100644
--- a/garnet/public/lib/fostr/test/fidl_types_unittests.cc
+++ b/garnet/public/lib/fostr/test/fidl_types_unittests.cc
@@ -7,6 +7,8 @@
 #include <sstream>
 
 #include <fuchsia/sys/cpp/fidl.h>
+#include <fuchsia/example/fostr/cpp/fidl.h>
+#include <lib/fostr/fidl/fuchsia/example/fostr/formatting.h>
 #include <lib/async-loop/cpp/loop.h>
 
 #include "lib/fsl/handles/object_info.h"
@@ -474,5 +476,22 @@
   EXPECT_EQ(fsl::GetKoid(interface_ptr.channel().get()), related_koid);
 }
 
+#define EXPECT_FIDL_TO_FORMAT_AS(Value, Expected) \
+   do {                                           \
+       std::ostringstream os;                     \
+       os << (Value);                             \
+       EXPECT_EQ(Expected, os.str());             \
+   } while (0)
+
+TEST(FidlTypes, BitsFormatting) {
+  using namespace fuchsia::example::fostr;
+
+  EXPECT_FIDL_TO_FORMAT_AS(ExampleBits::A, "a");
+  EXPECT_FIDL_TO_FORMAT_AS(ExampleBits::B, "b");
+  EXPECT_FIDL_TO_FORMAT_AS(ExampleBits::C, "c");
+  EXPECT_FIDL_TO_FORMAT_AS(ExampleBits::A | ExampleBits::C, "a|c");
+  EXPECT_FIDL_TO_FORMAT_AS(~ExampleBits::C, "a|b");
+}
+
 }  // namespace
 }  // namespace fostr
diff --git a/garnet/public/lib/fostr/test/fuchsia.example.fostr/BUILD.gn b/garnet/public/lib/fostr/test/fuchsia.example.fostr/BUILD.gn
new file mode 100644
index 0000000..4ccf792
--- /dev/null
+++ b/garnet/public/lib/fostr/test/fuchsia.example.fostr/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2019 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.
+
+import("//build/fidl/fidl.gni")
+
+fidl("fuchsia.example.fostr") {
+  sources = [
+    "fostr.test.fidl",
+  ]
+}
diff --git a/garnet/public/lib/fostr/test/fuchsia.example.fostr/fostr.test.fidl b/garnet/public/lib/fostr/test/fuchsia.example.fostr/fostr.test.fidl
new file mode 100644
index 0000000..66f7797
--- /dev/null
+++ b/garnet/public/lib/fostr/test/fuchsia.example.fostr/fostr.test.fidl
@@ -0,0 +1,7 @@
+library fuchsia.example.fostr;
+
+bits ExampleBits {
+    A = 1;
+    B = 2;
+    C = 4;
+};