You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.3 KiB
62 lines
2.3 KiB
import 'dart:io';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
/// 分层边界:业务层不认厂商。
|
|
///
|
|
/// `lib/modules`、`lib/core`、`lib/data` 只能 import `lib/devices/*.dart`(中枢)
|
|
/// 与 `device_plugin_interface`,**不能** import `lib/devices/<vendor>/…`,
|
|
/// 也不能出现厂商类名。新接一种芯片只动 `lib/devices/<vendor>/` 与 bootstrap。
|
|
void main() {
|
|
final vendorImport = RegExp(r"devices/(bes|holder|eaicar)/");
|
|
final vendorTypes = RegExp(
|
|
r'\b(BesBluetoothService|BesDevicePlugin|BesDeviceSession|BesDeviceAuth|'
|
|
r'HolderDeviceService|HolderDevicePlugin|HolderDeviceSession|'
|
|
r'EchoMeetDeviceSdk|BluetoothManager\(\))');
|
|
final vendorPackages = RegExp(
|
|
r"package:(bluetooth_manager|echomeet_device_sdk|bes_ota_manager)/");
|
|
|
|
List<File> dartFiles(String dir) => Directory(dir)
|
|
.listSync(recursive: true)
|
|
.whereType<File>()
|
|
.where((f) => f.path.endsWith('.dart'))
|
|
.toList();
|
|
|
|
/// 只看代码,注释里提到厂商名不算
|
|
String codeOnly(File f) => f
|
|
.readAsLinesSync()
|
|
.where((l) => !l.trimLeft().startsWith('//'))
|
|
.map((l) => l.replaceFirst(RegExp(r'\s//.*$'), ''))
|
|
.join('\n');
|
|
|
|
test('lib/modules、lib/core、lib/data 不引用任何厂商实现', () {
|
|
final offenders = <String>[];
|
|
for (final dir in ['lib/modules', 'lib/core', 'lib/data']) {
|
|
for (final f in dartFiles(dir)) {
|
|
final src = codeOnly(f);
|
|
if (vendorImport.hasMatch(src) ||
|
|
vendorTypes.hasMatch(src) ||
|
|
vendorPackages.hasMatch(src)) {
|
|
offenders.add(f.path);
|
|
}
|
|
}
|
|
}
|
|
expect(offenders, isEmpty,
|
|
reason: '这些文件绕过了 DeviceHub 直接碰厂商实现:\n${offenders.join('\n')}');
|
|
});
|
|
|
|
test('厂商目录之间互不引用', () {
|
|
final offenders = <String>[];
|
|
for (final f in dartFiles('lib/devices')) {
|
|
final parts = f.path.split('/');
|
|
final idx = parts.indexOf('devices');
|
|
if (idx < 0 || idx + 2 >= parts.length) continue; // 顶层文件不限制
|
|
final myVendor = parts[idx + 1];
|
|
final src = codeOnly(f);
|
|
for (final m in vendorImport.allMatches(src)) {
|
|
if (m.group(1) != myVendor) offenders.add('${f.path} -> ${m.group(0)}');
|
|
}
|
|
}
|
|
expect(offenders, isEmpty, reason: offenders.join('\n'));
|
|
});
|
|
}
|
|
|