blob: e16d3d9dea3cfe66ca2365614b41fa51252bf9d1 [file] [log] [blame]
// Copyright (c) 2021, 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 'package:ffigen/src/code_generator.dart';
import 'package:test/test.dart';
import '../test_utils.dart';
void main() {
group('code_generator: ', () {
test('Function Binding (primitives, pointers)', () {
final library = Library(
name: 'Bindings',
bindings: [
Func(
name: 'noParam',
dartDoc: 'Just a test function\nheres another line',
returnType: NativeType(
SupportedNativeType.Int32,
),
),
Func(
name: 'withPrimitiveParam',
parameters: [
Parameter(
name: 'a',
type: NativeType(
SupportedNativeType.Int32,
),
),
Parameter(
name: 'b',
type: NativeType(
SupportedNativeType.Uint8,
),
),
],
returnType: NativeType(
SupportedNativeType.Char,
),
),
Func(
name: 'withPointerParam',
parameters: [
Parameter(
name: 'a',
type: PointerType(
NativeType(
SupportedNativeType.Int32,
),
),
),
Parameter(
name: 'b',
type: PointerType(
PointerType(
NativeType(
SupportedNativeType.Uint8,
),
),
),
),
],
returnType: PointerType(
NativeType(
SupportedNativeType.Double,
),
),
),
Func(
isLeaf: true,
name: 'leafFunc',
dartDoc: 'A function with isLeaf: true',
parameters: [
Parameter(
name: 'a',
type: NativeType(
SupportedNativeType.Int32,
),
),
],
returnType: NativeType(
SupportedNativeType.Int32,
),
),
],
);
_matchLib(library, 'function');
});
test('Struct Binding (primitives, pointers)', () {
final library = Library(
name: 'Bindings',
bindings: [
Struct(
name: 'NoMember',
dartDoc: 'Just a test struct\nheres another line',
),
Struct(
name: 'WithPrimitiveMember',
members: [
Member(
name: 'a',
type: NativeType(
SupportedNativeType.Int32,
),
),
Member(
name: 'b',
type: NativeType(
SupportedNativeType.Double,
),
),
Member(
name: 'c',
type: NativeType(
SupportedNativeType.Char,
),
),
],
),
Struct(
name: 'WithPointerMember',
members: [
Member(
name: 'a',
type: PointerType(
NativeType(
SupportedNativeType.Int32,
),
),
),
Member(
name: 'b',
type: PointerType(
PointerType(
NativeType(
SupportedNativeType.Double,
),
),
),
),
Member(
name: 'c',
type: NativeType(
SupportedNativeType.Char,
),
),
],
),
Struct(
name: 'WithIntPtrUintPtr',
members: [
Member(
name: 'a',
type: PointerType(
NativeType(
SupportedNativeType.UintPtr,
),
),
),
Member(
name: 'b',
type: PointerType(
PointerType(
NativeType(
SupportedNativeType.IntPtr,
),
),
),
),
],
),
],
);
_matchLib(library, 'struct');
});
test('Function and Struct Binding (pointer to Struct)', () {
final structSome = Struct(
name: 'SomeStruct',
members: [
Member(
name: 'a',
type: NativeType(
SupportedNativeType.Int32,
),
),
Member(
name: 'b',
type: NativeType(
SupportedNativeType.Double,
),
),
Member(
name: 'c',
type: NativeType(
SupportedNativeType.Char,
),
),
],
);
final library = Library(
name: 'Bindings',
bindings: [
structSome,
Func(
name: 'someFunc',
parameters: [
Parameter(
name: 'some',
type: PointerType(
PointerType(
structSome,
),
),
),
],
returnType: PointerType(
structSome,
),
),
],
);
_matchLib(library, 'function_n_struct');
});
test('global (primitives, pointers, pointer to struct)', () {
final structSome = Struct(
name: 'Some',
);
final emptyGlobalStruct = Struct(name: 'EmptyStruct');
final library = Library(
name: 'Bindings',
bindings: [
Global(
name: 'test1',
type: NativeType(
SupportedNativeType.Int32,
),
),
Global(
name: 'test2',
type: PointerType(
NativeType(
SupportedNativeType.Float,
),
),
),
structSome,
Global(
name: 'test5',
type: PointerType(
structSome,
),
),
emptyGlobalStruct,
Global(name: 'globalStruct', type: emptyGlobalStruct),
],
);
_matchLib(library, 'global');
});
test('constant', () {
final library = Library(
name: 'Bindings',
header: '// ignore_for_file: unused_import\n',
bindings: [
Constant(
name: 'test1',
rawType: 'int',
rawValue: '20',
),
Constant(
name: 'test2',
rawType: 'double',
rawValue: '20.0',
),
],
);
_matchLib(library, 'constant');
});
test('enum_class', () {
final library = Library(
name: 'Bindings',
header: '// ignore_for_file: unused_import\n',
bindings: [
EnumClass(
name: 'Constants',
dartDoc: 'test line 1\ntest line 2',
enumConstants: [
EnumConstant(
name: 'a',
value: 10,
),
EnumConstant(name: 'b', value: -1, dartDoc: 'negative'),
],
),
],
);
_matchLib(library, 'enumclass');
});
test('Internal conflict resolution', () {
final library = Library(
name: 'init_dylib',
header:
'// ignore_for_file: unused_element, camel_case_types, non_constant_identifier_names\n',
bindings: [
Func(
name: 'test',
returnType: NativeType(SupportedNativeType.Void),
),
Func(
name: '_test',
returnType: NativeType(SupportedNativeType.Void),
),
Func(
name: '_c_test',
returnType: NativeType(SupportedNativeType.Void),
),
Func(
name: '_dart_test',
returnType: NativeType(SupportedNativeType.Void),
),
Struct(
name: '_Test',
members: [
Member(
name: 'array',
type: ConstantArray(
2,
NativeType(
SupportedNativeType.Int8,
),
),
),
],
),
Struct(name: 'ArrayHelperPrefixCollisionTest'),
Func(
name: 'Test',
returnType: NativeType(SupportedNativeType.Void),
),
EnumClass(name: '_c_Test'),
EnumClass(name: 'init_dylib'),
],
);
_matchLib(library, 'internal_conflict_resolution');
});
});
test('boolean_dartBool', () {
final library = Library(
name: 'Bindings',
bindings: [
Func(
name: 'test1',
returnType: BooleanType(),
parameters: [
Parameter(name: 'a', type: BooleanType()),
Parameter(name: 'b', type: PointerType(BooleanType())),
],
),
Struct(
name: 'Test2',
members: [
Member(name: 'a', type: BooleanType()),
],
),
],
);
_matchLib(library, 'boolean_dartbool');
});
test('sort bindings', () {
final library = Library(
name: 'Bindings',
sort: true,
bindings: [
Func(name: 'b', returnType: NativeType(SupportedNativeType.Void)),
Func(name: 'a', returnType: NativeType(SupportedNativeType.Void)),
Struct(name: 'D'),
Struct(name: 'C'),
],
);
_matchLib(library, 'sort_bindings');
});
test('Pack Structs', () {
final library = Library(
name: 'Bindings',
bindings: [
Struct(name: 'NoPacking', pack: null, members: [
Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
]),
Struct(name: 'Pack1', pack: 1, members: [
Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
]),
Struct(name: 'Pack2', pack: 2, members: [
Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
]),
Struct(name: 'Pack2', pack: 4, members: [
Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
]),
Struct(name: 'Pack2', pack: 8, members: [
Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
]),
Struct(name: 'Pack16', pack: 16, members: [
Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
]),
],
);
_matchLib(library, 'packed_structs');
});
test('Union Bindings', () {
final struct1 =
Struct(name: 'Struct1', members: [Member(name: 'a', type: charType)]);
final union1 =
Union(name: 'Union1', members: [Member(name: 'a', type: charType)]);
final library = Library(
name: 'Bindings',
bindings: [
struct1,
union1,
Union(name: 'EmptyUnion'),
Union(name: 'Primitives', members: [
Member(name: 'a', type: charType),
Member(name: 'b', type: intType),
Member(name: 'c', type: floatType),
Member(name: 'd', type: doubleType),
]),
Union(name: 'PrimitivesWithPointers', members: [
Member(name: 'a', type: charType),
Member(name: 'b', type: floatType),
Member(name: 'c', type: PointerType(doubleType)),
Member(name: 'd', type: PointerType(union1)),
Member(name: 'd', type: PointerType(struct1)),
]),
Union(name: 'WithArray', members: [
Member(name: 'a', type: ConstantArray(10, charType)),
Member(name: 'b', type: ConstantArray(10, union1)),
Member(name: 'b', type: ConstantArray(10, struct1)),
Member(name: 'c', type: ConstantArray(10, PointerType(union1))),
]),
],
);
_matchLib(library, 'unions');
});
test('Typealias Bindings', () {
final library = Library(
name: 'Bindings',
header: '// ignore_for_file: non_constant_identifier_names\n',
bindings: [
Typealias(name: 'RawUnused', type: Struct(name: 'Struct1')),
Struct(name: 'WithTypealiasStruct', members: [
Member(
name: 't',
type: Typealias(
name: 'Struct2Typealias',
type: Struct(
name: 'Struct2',
members: [Member(name: 'a', type: doubleType)])))
]),
Func(
name: 'WithTypealiasStruct',
returnType: PointerType(NativeFunc(FunctionType(
returnType: NativeType(SupportedNativeType.Void),
parameters: []))),
parameters: [
Parameter(
name: 't',
type: Typealias(
name: 'Struct3Typealias', type: Struct(name: 'Struct3')))
]),
],
);
_matchLib(library, 'typealias');
});
}
/// Utility to match expected bindings to the generated bindings.
void _matchLib(Library lib, String testName) {
matchLibraryWithExpected(lib, 'code_generator_test_${testName}_output.dart', [
'test',
'code_generator_tests',
'expected_bindings',
'_expected_${testName}_bindings.dart'
]);
}