[ffigen] Fix coverage for ObjC tests (#370)

* Fix coverage for ObjC test

* Finish comment
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart
index f0f3ac9..188da1d 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'block_bindings.dart';
+import 'util.dart';
 
 void main() {
   late BlockTestObjCLibrary lib;
@@ -21,6 +22,7 @@
       final dylib = File('test/native_objc_test/block_test.dylib');
       verifySetupFile(dylib);
       lib = BlockTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('block');
     });
 
     test('BlockTester is working', () {
diff --git a/pkgs/ffigen/test/native_objc_test/cast_test.dart b/pkgs/ffigen/test/native_objc_test/cast_test.dart
index 2b17174..86ec063 100644
--- a/pkgs/ffigen/test/native_objc_test/cast_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/cast_test.dart
@@ -12,6 +12,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'cast_bindings.dart';
+import 'util.dart';
 
 void main() {
   late Castaway testInstance;
@@ -24,6 +25,7 @@
       verifySetupFile(dylib);
       lib = CastTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
       testInstance = Castaway.new1(lib);
+      generateBindingsForCoverage('cast');
     });
 
     test('castFrom', () {
diff --git a/pkgs/ffigen/test/native_objc_test/category_test.dart b/pkgs/ffigen/test/native_objc_test/category_test.dart
index 8d52f6f..2dda7cf 100644
--- a/pkgs/ffigen/test/native_objc_test/category_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/category_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'category_bindings.dart';
+import 'util.dart';
 
 void main() {
   late Thing testInstance;
@@ -23,6 +24,7 @@
       verifySetupFile(dylib);
       lib = CategoryTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
       testInstance = Thing.new1(lib);
+      generateBindingsForCoverage('category');
     });
 
     test('Category method', () {
diff --git a/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart b/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
index 197171e..4a06516 100644
--- a/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'forward_decl_bindings.dart';
+import 'util.dart';
 
 void main() {
   late ForwardDeclTestObjCLibrary lib;
@@ -22,6 +23,7 @@
       verifySetupFile(dylib);
       lib =
           ForwardDeclTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('forward_decl');
     });
 
     test('Forward declared class', () {
diff --git a/pkgs/ffigen/test/native_objc_test/method_test.dart b/pkgs/ffigen/test/native_objc_test/method_test.dart
index e08d36b..6ab2679 100644
--- a/pkgs/ffigen/test/native_objc_test/method_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/method_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'method_bindings.dart';
+import 'util.dart';
 
 void main() {
   late MethodInterface testInstance;
@@ -23,6 +24,7 @@
       verifySetupFile(dylib);
       lib = MethodTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
       testInstance = MethodInterface.new1(lib);
+      generateBindingsForCoverage('method');
     });
 
     group('Instance methods', () {
diff --git a/pkgs/ffigen/test/native_objc_test/native_objc_test.dart b/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
index 52b8b78..28c006a 100644
--- a/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'native_objc_test_bindings.dart';
+import 'util.dart';
 
 void main() {
   late NativeObjCLibrary lib;
@@ -20,6 +21,7 @@
       final dylib = File('test/native_objc_test/native_objc_test.dylib');
       verifySetupFile(dylib);
       lib = NativeObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('native_objc');
     });
 
     test('Basic types', () {
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_test.dart b/pkgs/ffigen/test/native_objc_test/nullable_test.dart
index de6cc77..f2fbf74 100644
--- a/pkgs/ffigen/test/native_objc_test/nullable_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/nullable_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'nullable_bindings.dart';
+import 'util.dart';
 
 void main() {
   late NullableTestObjCLibrary lib;
@@ -24,6 +25,7 @@
       lib = NullableTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
       nullableInterface = NullableInterface.new1(lib);
       obj = NSObject.new1(lib);
+      generateBindingsForCoverage('nullable');
     });
 
     group('Nullable property', () {
diff --git a/pkgs/ffigen/test/native_objc_test/property_test.dart b/pkgs/ffigen/test/native_objc_test/property_test.dart
index 1983256..f38b04c 100644
--- a/pkgs/ffigen/test/native_objc_test/property_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/property_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'property_bindings.dart';
+import 'util.dart';
 
 void main() {
   late PropertyInterface testInstance;
@@ -23,6 +24,7 @@
       verifySetupFile(dylib);
       lib = PropertyTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
       testInstance = PropertyInterface.new1(lib);
+      generateBindingsForCoverage('property');
     });
 
     group('instance properties', () {
diff --git a/pkgs/ffigen/test/native_objc_test/rename_test.dart b/pkgs/ffigen/test/native_objc_test/rename_test.dart
index b4f7403..aa8a23f 100644
--- a/pkgs/ffigen/test/native_objc_test/rename_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/rename_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'rename_test_bindings.dart';
+import 'util.dart';
 
 void main() {
   late RenameLibrary lib;
@@ -20,6 +21,7 @@
       final dylib = File('test/native_objc_test/rename_test.dylib');
       verifySetupFile(dylib);
       lib = RenameLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('rename');
     });
 
     test('Renamed class', () {
diff --git a/pkgs/ffigen/test/native_objc_test/string_test.dart b/pkgs/ffigen/test/native_objc_test/string_test.dart
index 117088b..458621e 100644
--- a/pkgs/ffigen/test/native_objc_test/string_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/string_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import '../test_utils.dart';
 import 'string_bindings.dart';
+import 'util.dart';
 
 void main() {
   late StringTestObjCLibrary lib;
@@ -21,6 +22,7 @@
       final dylib = File('test/native_objc_test/string_test.dylib');
       verifySetupFile(dylib);
       lib = StringTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('string');
     });
 
     // TODO(#329): Add 'Embedded\u0000Null'.
diff --git a/pkgs/ffigen/test/native_objc_test/util.dart b/pkgs/ffigen/test/native_objc_test/util.dart
new file mode 100644
index 0000000..1eb0746
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/util.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:ffigen/ffigen.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart';
+
+void generateBindingsForCoverage(String testName) {
+  // The ObjC test bindings are generated in setup.dart (see #362), which means
+  // that the ObjC related bits of ffigen are missed by test coverage. So this
+  // function just regenerates those bindings. It doesn't test anything except
+  // that the generation succeeded, by asserting the file exists.
+  final config = Config.fromYaml(loadYaml(
+      File(path.join('test', 'native_objc_test', '${testName}_config.yaml'))
+          .readAsStringSync()) as YamlMap);
+  final library = parse(config);
+  final file = File(
+    path.join('test', 'debug_generated', '${testName}_test.dart'),
+  );
+  library.generateFile(file);
+  assert(file.existsSync());
+  file.delete();
+}