157 lines
5.7 KiB
Dart
157 lines
5.7 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:yx_asr/yx_asr.dart';
|
||
|
||
void main() {
|
||
TestWidgetsFlutterBinding.ensureInitialized();
|
||
group('模型文件路径测试', () {
|
||
test('应该能够访问库内置的模型文件', () async {
|
||
// 测试库内置模型文件是否存在
|
||
final modelFiles = [
|
||
'packages/yx_asr/assets/models/encoder-epoch-99-avg-1.int8.onnx',
|
||
'packages/yx_asr/assets/models/decoder-epoch-99-avg-1.int8.onnx',
|
||
'packages/yx_asr/assets/models/joiner-epoch-99-avg-1.int8.onnx',
|
||
'packages/yx_asr/assets/models/tokens.txt',
|
||
];
|
||
|
||
for (final filePath in modelFiles) {
|
||
try {
|
||
final data = await rootBundle.load(filePath);
|
||
expect(data.lengthInBytes, greaterThan(0),
|
||
reason: '模型文件 $filePath 应该存在且不为空');
|
||
print('✅ 找到模型文件: $filePath (${data.lengthInBytes} bytes)');
|
||
} catch (e) {
|
||
fail('无法加载模型文件 $filePath: $e');
|
||
}
|
||
}
|
||
});
|
||
|
||
test('默认初始化应该使用正确的模型路径', () async {
|
||
final service = YxAsrService();
|
||
|
||
// 测试默认初始化方法
|
||
try {
|
||
// 注意:这个测试可能会失败,因为需要实际的sherpa_onnx环境
|
||
// 但我们可以验证路径是否正确传递
|
||
await service.initializeWithDefaultModel();
|
||
} catch (e) {
|
||
// 预期可能会失败,但错误信息应该包含正确的路径
|
||
final errorMessage = e.toString();
|
||
print('初始化错误(预期): $errorMessage');
|
||
|
||
// 验证错误信息不是因为找不到文件
|
||
expect(
|
||
errorMessage.contains('packages/yx_asr/assets/models') ||
|
||
errorMessage.contains('No such file'),
|
||
isFalse,
|
||
reason: '错误不应该是因为找不到模型文件路径');
|
||
}
|
||
});
|
||
|
||
test('自定义路径初始化应该正常工作', () async {
|
||
final service = YxAsrService();
|
||
|
||
// 测试使用自定义路径
|
||
try {
|
||
await service
|
||
.initialize({'modelPath': 'packages/yx_asr/assets/models'});
|
||
} catch (e) {
|
||
final errorMessage = e.toString();
|
||
print('自定义路径初始化错误(预期): $errorMessage');
|
||
|
||
// 验证路径传递正确
|
||
expect(
|
||
errorMessage.contains('packages/yx_asr/assets/models') ||
|
||
errorMessage.contains('No such file'),
|
||
isFalse,
|
||
reason: '错误不应该是因为路径问题');
|
||
}
|
||
});
|
||
|
||
test('验证模型文件的基本格式', () async {
|
||
// 检查 tokens.txt 文件内容
|
||
try {
|
||
final tokensData = await rootBundle
|
||
.loadString('packages/yx_asr/assets/models/tokens.txt');
|
||
|
||
expect(tokensData.isNotEmpty, true, reason: 'tokens.txt 不应该为空');
|
||
|
||
// tokens.txt 应该包含一些基本的token
|
||
final lines = tokensData
|
||
.split('\n')
|
||
.where((line) => line.trim().isNotEmpty)
|
||
.toList();
|
||
expect(lines.length, greaterThan(10),
|
||
reason: 'tokens.txt 应该包含足够的token');
|
||
|
||
print('✅ tokens.txt 验证通过: ${lines.length} 个token');
|
||
print(' 前几个token: ${lines.take(5).join(", ")}');
|
||
} catch (e) {
|
||
fail('无法读取或解析 tokens.txt: $e');
|
||
}
|
||
});
|
||
|
||
test('验证ONNX模型文件格式', () async {
|
||
// 检查ONNX文件的基本格式
|
||
final onnxFiles = [
|
||
'packages/yx_asr/assets/models/encoder-epoch-99-avg-1.int8.onnx',
|
||
'packages/yx_asr/assets/models/decoder-epoch-99-avg-1.int8.onnx',
|
||
'packages/yx_asr/assets/models/joiner-epoch-99-avg-1.int8.onnx',
|
||
];
|
||
|
||
for (final filePath in onnxFiles) {
|
||
try {
|
||
final data = await rootBundle.load(filePath);
|
||
final bytes = data.buffer.asUint8List();
|
||
|
||
// ONNX文件应该以特定的魔数开头
|
||
expect(bytes.length, greaterThan(100), reason: '$filePath 文件大小应该合理');
|
||
|
||
// 检查是否是有效的二进制文件
|
||
expect(bytes[0], isNot(equals(0)), reason: '$filePath 应该是有效的二进制文件');
|
||
|
||
print('✅ ONNX文件验证通过: $filePath (${bytes.length} bytes)');
|
||
} catch (e) {
|
||
fail('无法验证ONNX文件 $filePath: $e');
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
group('路径解析测试', () {
|
||
test('应该正确构建模型文件的完整路径', () {
|
||
final basePath = 'packages/yx_asr/assets/models';
|
||
final expectedPaths = {
|
||
'encoder': '$basePath/encoder-epoch-99-avg-1.int8.onnx',
|
||
'decoder': '$basePath/decoder-epoch-99-avg-1.int8.onnx',
|
||
'joiner': '$basePath/joiner-epoch-99-avg-1.int8.onnx',
|
||
'tokens': '$basePath/tokens.txt',
|
||
};
|
||
|
||
for (final entry in expectedPaths.entries) {
|
||
expect(entry.value.startsWith('packages/yx_asr/'), true,
|
||
reason: '${entry.key} 路径应该以包名开头');
|
||
expect(entry.value.contains('assets/models'), true,
|
||
reason: '${entry.key} 路径应该包含assets/models');
|
||
|
||
print('✅ ${entry.key} 路径: ${entry.value}');
|
||
}
|
||
});
|
||
|
||
test('验证路径格式的一致性', () {
|
||
final service = YxAsrService();
|
||
|
||
// 验证默认路径
|
||
expect(() => service.initializeWithDefaultModel(), returnsNormally,
|
||
reason: '默认初始化方法应该可以调用');
|
||
|
||
// 验证自定义路径
|
||
expect(
|
||
() => service
|
||
.initialize({'modelPath': 'packages/yx_asr/assets/models'}),
|
||
returnsNormally,
|
||
reason: '自定义路径初始化方法应该可以调用');
|
||
});
|
||
});
|
||
}
|