mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-08-11 18:26:27 +10:00
Add ability to send images over lora
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:meshcore_open/main.dart';
|
||||
import 'package:meshcore_open/services/image_chunk_transport.dart';
|
||||
import 'package:meshcore_open/services/received_image_store.dart';
|
||||
import 'package:meshcore_open/models/app_settings.dart';
|
||||
import 'package:meshcore_open/models/image_codec_support.dart';
|
||||
import 'package:meshcore_open/widgets/image_send_codec_binding.dart';
|
||||
|
||||
void main() {
|
||||
test('ImageStreamReassembler.selfPrefix override suppresses our own echo', () {
|
||||
final store = ReceivedImageStore();
|
||||
final r = ImageStreamReassembler(store: store);
|
||||
final set = buildImageChunks(
|
||||
payload: Uint8List.fromList(List<int>.generate(120, (i) => i)),
|
||||
metadata: const ImageStreamMetadata(rate: ImageCodecRatePoint.standard),
|
||||
senderPrefix: 0xABCD,
|
||||
imgId: 7,
|
||||
);
|
||||
// Before SELF_INFO the prefix is unknown, so nothing is suppressed.
|
||||
expect(r.addChunk(set.blobs[0], channelIndex: 1).status,
|
||||
ImageChunkStatus.completed);
|
||||
r.clear();
|
||||
// After SELF_INFO the superclass must see the overridden getter.
|
||||
r.selfPrefix = 0xABCD;
|
||||
expect(r.addChunk(set.blobs[0], channelIndex: 1).status,
|
||||
ImageChunkStatus.fromSelf);
|
||||
});
|
||||
|
||||
test('addChunk forwards outcomes to the store with the channel index',
|
||||
() async {
|
||||
final store = ReceivedImageStore();
|
||||
final r = ImageStreamReassembler(store: store);
|
||||
final set = buildImageChunks(
|
||||
payload: Uint8List.fromList(List<int>.generate(400, (i) => i & 0xFF)),
|
||||
metadata: const ImageStreamMetadata(rate: ImageCodecRatePoint.standard),
|
||||
senderPrefix: 0x1234,
|
||||
imgId: 3,
|
||||
);
|
||||
r.addChunk(set.blobs[0], channelIndex: 5);
|
||||
await store.settle();
|
||||
final entry = store.entries.single;
|
||||
expect(entry.channelIndex, 5);
|
||||
expect(entry.senderPrefix, 0x1234);
|
||||
expect(entry.state, ReceivedImageState.receiving);
|
||||
});
|
||||
|
||||
group('AppSettings image codec block', () {
|
||||
test('round-trips through toJson/fromJson on the ImageCodecPreferences keys',
|
||||
() {
|
||||
final settings = AppSettings(
|
||||
imageCodecEnabled: true,
|
||||
imageCodecSelectedModelId: 'qdq_conv_pct_novae',
|
||||
imageCodecModelSourceUrl: 'https://example.invalid/model.onnx',
|
||||
imageCodecRatePoint: 4,
|
||||
imageCodecDownloadedModels: [
|
||||
ImageCodecModelRecord(
|
||||
id: 'qdq_conv_pct_novae',
|
||||
name: 'AEIC ft32 (int8)',
|
||||
sourceUrl: 'https://example.invalid/model.onnx',
|
||||
localPath: '/tmp/model.onnx',
|
||||
downloadedAt: DateTime.fromMillisecondsSinceEpoch(1000),
|
||||
fileSizeBytes: 872 * 1024 * 1024,
|
||||
),
|
||||
],
|
||||
);
|
||||
final json = settings.toJson();
|
||||
// The keys must be the ones ImageCodecPreferences already used, so a
|
||||
// build that wrote them through the old standalone store still reads.
|
||||
expect(json['image_codec_enabled'], isTrue);
|
||||
expect(json['image_codec_selected_model_id'], 'qdq_conv_pct_novae');
|
||||
expect(json['image_codec_rate_point'], 4);
|
||||
|
||||
final restored = AppSettings.fromJson(json);
|
||||
expect(restored.imageCodecEnabled, isTrue);
|
||||
expect(restored.imageCodecSelectedModelId, 'qdq_conv_pct_novae');
|
||||
expect(
|
||||
restored.imageCodecModelSourceUrl,
|
||||
'https://example.invalid/model.onnx',
|
||||
);
|
||||
expect(restored.imageCodecRatePoint, 4);
|
||||
expect(restored.imageCodecDownloadedModels.single.localPath,
|
||||
'/tmp/model.onnx');
|
||||
});
|
||||
|
||||
test('defaults are off, ft32, and empty', () {
|
||||
const prefs = ImageCodecPreferences();
|
||||
final settings = AppSettings();
|
||||
expect(settings.imageCodecEnabled, prefs.enabled);
|
||||
expect(settings.imageCodecRatePoint, prefs.ratePoint);
|
||||
expect(settings.imageCodecDownloadedModels, isEmpty);
|
||||
expect(settings.imageCodec.aeicRatePoint, AeicRatePoint.ft32);
|
||||
});
|
||||
|
||||
test('the assembled view matches the five fields', () {
|
||||
final settings = AppSettings(
|
||||
imageCodecEnabled: true,
|
||||
imageCodecSelectedModelId: 'x',
|
||||
imageCodecRatePoint: 4,
|
||||
);
|
||||
expect(settings.imageCodec.enabled, isTrue);
|
||||
expect(settings.imageCodec.selectedModelId, 'x');
|
||||
expect(settings.imageCodec.ratePoint, 4);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user