diff --git a/tests/ffi/coordinate_nnbd_workaround.dart b/tests/ffi/coordinate_nnbd_workaround.dart new file mode 100644 index 000000000000..515badd22d8a --- /dev/null +++ b/tests/ffi/coordinate_nnbd_workaround.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2020, 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. + +library FfiTest; + +import 'dart:ffi'; +import "package:ffi/ffi.dart"; + +/// Sample struct for dart:ffi library. +class Coordinate extends Struct { + @Double() + external double get x; + external set x(double v); + + @Double() + external double get y; + external set y(double v); + + external Pointer get next; + external set next(Pointer v); + + factory Coordinate.allocate(double x, double y, Pointer next) { + return allocate().ref + ..x = x + ..y = y + ..next = next; + } +} diff --git a/tests/ffi/structs_nnbd_workaround_test.dart b/tests/ffi/structs_nnbd_workaround_test.dart new file mode 100644 index 000000000000..6501faf251b7 --- /dev/null +++ b/tests/ffi/structs_nnbd_workaround_test.dart @@ -0,0 +1,100 @@ +// Copyright (c) 2020, 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. +// +// Dart test program for testing dart:ffi struct pointers. +// +// VMOptions=--deterministic --optimization-counter-threshold=50 + +import 'dart:ffi'; + +import "package:expect/expect.dart"; +import "package:ffi/ffi.dart"; + +import 'coordinate_nnbd_workaround.dart'; + +void main() { + for (int i = 0; i < 100; i++) { + testStructAllocate(); + testStructFromAddress(); + testStructWithNulls(); + testTypeTest(); + testUtf8(); + } +} + +/// allocates each coordinate separately in c memory +void testStructAllocate() { + Pointer c1 = Coordinate.allocate(10.0, 10.0, nullptr).addressOf; + Pointer c2 = Coordinate.allocate(20.0, 20.0, c1).addressOf; + Pointer c3 = Coordinate.allocate(30.0, 30.0, c2).addressOf; + c1.ref.next = c3; + + Coordinate currentCoordinate = c1.ref; + Expect.equals(10.0, currentCoordinate.x); + currentCoordinate = currentCoordinate.next.ref; + Expect.equals(30.0, currentCoordinate.x); + currentCoordinate = currentCoordinate.next.ref; + Expect.equals(20.0, currentCoordinate.x); + currentCoordinate = currentCoordinate.next.ref; + Expect.equals(10.0, currentCoordinate.x); + + free(c1); + free(c2); + free(c3); +} + +/// allocates coordinates consecutively in c memory +void testStructFromAddress() { + Pointer c1 = allocate(count: 3); + Pointer c2 = c1.elementAt(1); + Pointer c3 = c1.elementAt(2); + c1.ref + ..x = 10.0 + ..y = 10.0 + ..next = c3; + c2.ref + ..x = 20.0 + ..y = 20.0 + ..next = c1; + c3.ref + ..x = 30.0 + ..y = 30.0 + ..next = c2; + + Coordinate currentCoordinate = c1.ref; + Expect.equals(10.0, currentCoordinate.x); + currentCoordinate = currentCoordinate.next.ref; + Expect.equals(30.0, currentCoordinate.x); + currentCoordinate = currentCoordinate.next.ref; + Expect.equals(20.0, currentCoordinate.x); + currentCoordinate = currentCoordinate.next.ref; + Expect.equals(10.0, currentCoordinate.x); + + free(c1); +} + +void testStructWithNulls() { + Pointer coordinate = + Coordinate.allocate(10.0, 10.0, nullptr).addressOf; + Expect.equals(coordinate.ref.next, nullptr); + coordinate.ref.next = coordinate; + Expect.notEquals(coordinate.ref.next, nullptr); + coordinate.ref.next = nullptr; + Expect.equals(coordinate.ref.next, nullptr); + free(coordinate); +} + +void testTypeTest() { + Coordinate c = Coordinate.allocate(10, 10, nullptr); + Expect.isTrue(c is Struct); + Expect.isTrue(c.addressOf is Pointer); + free(c.addressOf); +} + +void testUtf8() { + final String test = 'Hasta MaƱana'; + final Pointer medium = Utf8.toUtf8(test); + Expect.equals(test, Utf8.fromUtf8(medium)); + free(medium); +}