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

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'));
});
}