blob: 0a74ab98c03359f39cea836ae69c70b18f02c236 [file] [log] [blame]
// Copyright (c) 2024, 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.
// Objective C support is only available on mac.
@TestOn('mac-os')
import 'dart:ffi';
import 'dart:io';
import 'package:objective_c/objective_c.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import '../test_utils.dart';
import 'global_native_bindings.dart';
import 'util.dart';
void main() {
group('global using @Native', () {
setUpAll(() {
final dylib = File(
path.join(
packagePathForTests,
'test',
'native_objc_test',
'objc_test.dylib',
),
);
verifySetupFile(dylib);
DynamicLibrary.open(dylib.absolute.path);
generateBindingsForCoverage('global');
});
test('Global string', () {
expect(globalString.toDartString(), 'Hello World');
globalString = 'Something else'.toNSString();
expect(globalString.toDartString(), 'Something else');
globalString = 'Hello World'.toNSString();
});
Pointer<ObjCObjectImpl> globalObjectRefCountingInner() {
globalObject = NSObject();
final obj1raw = globalObject!.ref.pointer;
expect(objectRetainCount(obj1raw), greaterThan(0));
return obj1raw;
}
test('Global object ref counting', () {
final obj1raw = globalObjectRefCountingInner();
globalObject = null;
doGC();
expect(objectRetainCount(obj1raw), 0);
}, skip: !canDoGC);
test('Global block', () {
globalBlock = ObjCBlock_Int32_Int32.fromFunction((int x) => x * 10);
expect(globalBlock!(123), 1230);
globalBlock = ObjCBlock_Int32_Int32.fromFunction((int x) => x + 1000);
expect(globalBlock!(456), 1456);
});
(Pointer<ObjCBlockImpl>, Pointer<ObjCBlockImpl>)
globalBlockRefCountingInner() {
final blk1 = ObjCBlock_Int32_Int32.fromFunction((int x) => x * 10);
globalBlock = blk1;
final blk1raw = blk1.ref.pointer;
expect(blockRetainCount(blk1raw), 2); // blk1, and the global variable.
final blk2 = ObjCBlock_Int32_Int32.fromFunction((int x) => x + 1000);
globalBlock = blk2;
final blk2raw = blk2.ref.pointer;
expect(blockRetainCount(blk2raw), 2); // blk2, and the global variable.
expect(blockRetainCount(blk1raw), 1); // Just blk1.
expect(blk1, isNotNull); // Force blk1 to stay in scope.
expect(blk2, isNotNull); // Force blk2 to stay in scope.
return (blk1raw, blk2raw);
}
test('Global block ref counting', () {
final (blk1raw, blk2raw) = globalBlockRefCountingInner();
doGC();
expect(blockRetainCount(blk2raw), 1); // Just the global variable.
expect(blockRetainCount(blk1raw), 0);
globalBlock = null;
expect(blockRetainCount(blk2raw), 0);
expect(blockRetainCount(blk1raw), 0);
}, skip: !canDoGC);
});
}