blob: 71f129b001312c6dd45f266c997afcfa892e9d9a [file] [edit]
// 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:jnigen/jnigen.dart';
import 'package:jnigen/src/util/dart_executable.dart';
import 'package:path/path.dart' hide equals;
import 'package:test/test.dart';
import 'test_util/test_util.dart';
JniGenerator _getConfig(Uri output, bool generateStubs) {
final testRoot = join('test', 'stub_test');
final javaPath = join(testRoot, 'java');
return JniGenerator(
input: Input(
sourcePath: [Uri.directory(javaPath)],
classPath: [Uri.directory(javaPath)],
classes: ['com.example.A', 'com.example.C'],
),
output: Output(
dart: DartOutput(
path: output,
structure: OutputStructure.singleFile,
),
generateStubs: generateStubs,
),
);
}
void main() async {
if (!Platform.isAndroid && !Platform.isLinux && !Platform.isMacOS) {
return;
}
await checkLocallyBuiltDependencies();
group('Stub generation', () {
final tempDir = getTempDir('stub_test_');
tearDownAll(() {
tempDir.deleteSync(recursive: true);
});
test('Generate bindings with stubs disabled', () async {
final output = tempDir.uri.resolve('bindings_no_stubs.dart');
await _getConfig(output, false).generate();
final analyzeResult =
Process.runSync(dartExecutable, ['analyze', output.toFilePath()]);
expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout as String);
final content = File.fromUri(output).readAsStringSync();
// When stubs are disabled, we should see JObject for excluded types.
expect(content, contains(r'jni$_.JObject? get b'));
expect(content, contains(r'void takeB('));
expect(content, contains(r'jni$_.JObject? b,'));
expect(content, contains(r'void takeD('));
expect(content, contains(r'jni$_.JObject? d,'));
// Stub classes should NOT exist.
expect(content, isNot(contains('extension type B')));
expect(content, isNot(contains('extension type D')));
});
test('Generate bindings with stubs enabled', () async {
final output = tempDir.uri.resolve('bindings_stubs.dart');
await _getConfig(output, true).generate();
final analyzeResult =
Process.runSync(dartExecutable, ['analyze', output.toFilePath()]);
expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout as String);
final content = File.fromUri(output).readAsStringSync();
// When stubs are enabled, we should see specific stub types.
expect(content, contains('B? get b'));
expect(content, contains('void takeB('));
expect(content, contains('B? b,'));
expect(content, contains('void takeD('));
expect(content, contains('D? d,'));
// Stub classes should exist with warnings.
expect(content, contains('extension type B'));
expect(content, contains('WARNING: B is a stub'));
expect(content, contains('extension type D'));
expect(content, contains('WARNING: D is a stub'));
// Transitive dependencies (E) shouldn't be generated if not referenced.
expect(content, isNot(contains('extension type E')));
});
});
}