123 lines
4.0 KiB
Dart
123 lines
4.0 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
// ignore_for_file: depend_on_referenced_packages
|
|
|
|
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
|
|
|
import 'package:pj_supermarket_cloud/common/index.dart';
|
|
import 'package:pj_supermarket_cloud/common/services/database/database_migration.dart';
|
|
|
|
/// 验证本地人脸质量迁移、阈值比较和查询统计协议。
|
|
void main() {
|
|
sqfliteFfiInit();
|
|
|
|
setUpAll(() {
|
|
databaseFactory = databaseFactoryFfi;
|
|
});
|
|
|
|
test('11到12迁移保留旧记录并补齐待检测默认值', () async {
|
|
final database =
|
|
await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);
|
|
addTearDown(database.close);
|
|
await database.execute('''
|
|
CREATE TABLE face (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
userId TEXT NOT NULL,
|
|
sampleId TEXT NOT NULL,
|
|
userName TEXT NOT NULL,
|
|
deptId TEXT,
|
|
deptName TEXT,
|
|
imagePath TEXT NOT NULL,
|
|
path TEXT,
|
|
faceModel TEXT,
|
|
createTime TEXT,
|
|
updateTime TEXT
|
|
)
|
|
''');
|
|
await database.insert('face', {
|
|
'userId': 'u1',
|
|
'sampleId': '1001',
|
|
'userName': '历史用户',
|
|
'imagePath': '/remote/face.jpg',
|
|
'faceModel': '[1,2,3]',
|
|
});
|
|
|
|
await DatabaseMigration.migration11To12.migrate(database);
|
|
|
|
final columns = await database.rawQuery('PRAGMA table_info(face)');
|
|
final columnNames = columns.map((column) => column['name']).toSet();
|
|
final rows = await database.query('face');
|
|
final indexes = await database.rawQuery('PRAGMA index_list(face)');
|
|
expect(
|
|
columnNames,
|
|
containsAll(const {
|
|
'qualityScore',
|
|
'qualityStatus',
|
|
'qualityCheckedAt',
|
|
'qualityErrorCode',
|
|
}));
|
|
expect(rows, hasLength(1));
|
|
expect(rows.single['sampleId'], '1001');
|
|
expect(rows.single['qualityStatus'], FaceQualityStatus.pending.code);
|
|
expect(rows.single['qualityCheckedAt'], '');
|
|
expect(
|
|
indexes.map((index) => index['name']),
|
|
contains('index_face_qualityStatus_qualityScore'),
|
|
);
|
|
});
|
|
|
|
test('低质量查询严格使用小于阈值且排除待检测和失败', () async {
|
|
final database =
|
|
await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);
|
|
addTearDown(database.close);
|
|
await database.execute('''
|
|
CREATE TABLE face (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
userName TEXT NOT NULL,
|
|
qualityScore REAL,
|
|
qualityStatus TEXT NOT NULL
|
|
)
|
|
''');
|
|
await database.rawInsert(
|
|
'INSERT INTO face(userName, qualityScore, qualityStatus) VALUES (?, ?, ?)',
|
|
['低于阈值', 0.59, FaceQualityStatus.detected.code],
|
|
);
|
|
await database.rawInsert(
|
|
'INSERT INTO face(userName, qualityScore, qualityStatus) VALUES (?, ?, ?)',
|
|
['等于阈值', 0.60, FaceQualityStatus.detected.code],
|
|
);
|
|
await database.rawInsert(
|
|
'INSERT INTO face(userName, qualityScore, qualityStatus) VALUES (?, ?, ?)',
|
|
['待检测', null, FaceQualityStatus.pending.code],
|
|
);
|
|
await database.rawInsert(
|
|
'INSERT INTO face(userName, qualityScore, qualityStatus) VALUES (?, ?, ?)',
|
|
['检测失败', null, FaceQualityStatus.failed.code],
|
|
);
|
|
|
|
final lowAtSixty = await database.rawQuery('''
|
|
SELECT userName FROM face
|
|
WHERE qualityStatus = 'detected'
|
|
AND qualityScore IS NOT NULL
|
|
AND qualityScore < ?
|
|
ORDER BY id ASC
|
|
''', [0.60]);
|
|
final lowAtFifty = await database.rawQuery('''
|
|
SELECT userName FROM face
|
|
WHERE qualityStatus = 'detected'
|
|
AND qualityScore IS NOT NULL
|
|
AND qualityScore < ?
|
|
''', [0.50]);
|
|
final summary = await database.rawQuery('''
|
|
SELECT
|
|
SUM(CASE WHEN qualityStatus = 'pending' THEN 1 ELSE 0 END) AS pendingCount,
|
|
SUM(CASE WHEN qualityStatus = 'failed' THEN 1 ELSE 0 END) AS failedCount
|
|
FROM face
|
|
''');
|
|
|
|
expect(lowAtSixty.map((row) => row['userName']), ['低于阈值']);
|
|
expect(lowAtFifty, isEmpty);
|
|
expect(summary.single['pendingCount'], 1);
|
|
expect(summary.single['failedCount'], 1);
|
|
});
|
|
}
|