| // Copyright (c) 2026, 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 '../test_utils.dart'; |
| import 'util.dart'; |
| |
| void main() { |
| group('verify_bindings_test', () { |
| final testDir = Directory( |
| path.join(packagePathForTests, 'test', 'native_cpp_test'), |
| ); |
| |
| const excludedTests = {'verify_bindings_test.dart'}; |
| |
| final testFiles = |
| testDir |
| .listSync() |
| .whereType<File>() |
| .where((f) => f.path.endsWith('_test.dart')) |
| .map((f) => path.basename(f.path)) |
| .where((f) => !excludedTests.contains(f)) |
| .toList() |
| ..sort(); |
| |
| final defaultCppCompilerOptions = [ |
| '-x', |
| 'c++', |
| '-std=c++17', |
| if (Platform.isMacOS) ...['-isysroot', macSdkPath], |
| ]; |
| |
| final configs = <String, FfiGenerator>{ |
| 'cpp_class': FfiGenerator( |
| output: Output( |
| dartFile: Uri.file('cpp_class_test_bindings.dart'), |
| style: const NativeExternalBindings( |
| assetId: 'package:ffigen/cpp_test', |
| ), |
| ), |
| input: Input( |
| entryPoints: [ |
| Uri.file(path.join(testDir.path, 'cpp_class_test.h')), |
| Uri.file(path.join(testDir.path, 'finalizer_test_subject.h')), |
| ], |
| compilerOptions: defaultCppCompilerOptions, |
| ), |
| cpp: const Cpp(), |
| visitors: [ |
| Visitor( |
| cppClass: (node) => node.isIncluded = { |
| 'Animal', |
| 'FinalizerTestSubject', |
| }.contains(node.originalName), |
| ), |
| ], |
| ), |
| 'memory_edge_cases': FfiGenerator( |
| output: Output( |
| dartFile: Uri.file('memory_edge_cases_bindings.dart'), |
| style: const NativeExternalBindings( |
| assetId: 'package:ffigen/cpp_test', |
| ), |
| ), |
| input: Input( |
| entryPoints: [ |
| Uri.file(path.join(testDir.path, 'memory_edge_cases.h')), |
| ], |
| compilerOptions: defaultCppCompilerOptions, |
| ), |
| cpp: const Cpp(), |
| visitors: [ |
| Visitor( |
| cppClass: (node) => node.isIncluded = { |
| 'Node', |
| 'NodeManager', |
| 'NodeContainer', |
| }.contains(node.originalName), |
| ), |
| ], |
| ), |
| 'cpp_inheritance': FfiGenerator( |
| output: Output( |
| dartFile: Uri.file('cpp_inheritance_test_bindings.dart'), |
| style: const NativeExternalBindings( |
| assetId: 'package:ffigen/cpp_test', |
| ), |
| ), |
| input: Input( |
| entryPoints: [ |
| Uri.file(path.join(testDir.path, 'cpp_inheritance_test.h')), |
| ], |
| compilerOptions: defaultCppCompilerOptions, |
| ), |
| cpp: const Cpp(), |
| visitors: [ |
| Visitor( |
| cppClass: (node) => node.isIncluded = { |
| 'Shape', |
| 'Drawable', |
| 'Circle', |
| 'ColoredCircle', |
| 'Square', |
| 'AccessBase', |
| 'PublicDerived', |
| 'ProtectedDerived', |
| 'PrivateDerived', |
| 'OverloadBase', |
| 'OverloadDerived', |
| 'DiamondBase', |
| 'DiamondLeft', |
| 'DiamondRight', |
| 'DiamondDerived', |
| }.contains(node.originalName), |
| ), |
| ], |
| ), |
| }; |
| |
| for (final testFile in testFiles) { |
| final configName = testFile.replaceFirst('_test.dart', ''); |
| test('verifyBindings for $testFile', () { |
| final config = configs[configName]; |
| if (config == null) { |
| fail('No FfiGenerator config registered for $testFile in `configs`.'); |
| } |
| verifyBindings(config); |
| }); |
| } |
| }); |
| } |