Refactor Dart SDK tests for onde_inference 0.2.0 API
- Update widget test to verify root widget construction
keypair34 committed
Apr 5, 2026 at 18:14 UTC
05439fb861bf4b645ce31aec85daac47e189d128
2 files changed
+74
-83
sdk/dart/example/test/widget_test.dart
+9
-22
@@ -1,30 +1,17 @@
1
-// This is a basic Flutter widget test.
1
+// Copyright 2026 Onde Inference (Splitfire AB). All rights reserved.
2
+// Use of this source code is governed by the MIT license.
3
//
3
-// To perform an interaction with a widget in your test, use the WidgetTester
4
-// utility in the flutter_test package. For example, you can send tap and scroll
5
-// gestures. You can also use WidgetTester to find child widgets in the widget
6
-// tree, read text, and verify that the values of widget properties are correct.
7
-
8
-import 'package:flutter/material.dart';
4
import 'package:flutter_test/flutter_test.dart';
5
6
import 'package:onde_inference_example/main.dart';
7
8
void main() {
14
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15
- // Build our app and trigger a frame.
16
- await tester.pumpWidget(const MyApp());
17
-
18
- // Verify that our counter starts at 0.
19
- expect(find.text('0'), findsOneWidget);
20
- expect(find.text('1'), findsNothing);
21
-
22
- // Tap the '+' icon and trigger a frame.
23
- await tester.tap(find.byIcon(Icons.add));
24
- await tester.pump();
25
-
26
- // Verify that our counter has incremented.
27
- expect(find.text('0'), findsNothing);
28
- expect(find.text('1'), findsOneWidget);
9
+ testWidgets('OndeInferenceApp builds without crashing',
10
+ (WidgetTester tester) async {
11
+ // Verify the root widget can be constructed.
12
+ // Full integration tests require the native inference library to be
13
+ // compiled first — run `flutter build` or `cargo build` in sdk/dart/rust/
14
+ // before running widget tests that exercise the engine.
15
+ expect(const OndeInferenceApp(), isA<OndeInferenceApp>());
16
});
17
}
sdk/dart/test/dart_test.dart
+65
-61
@@ -6,39 +6,39 @@ import 'package:onde_inference/onde_inference.dart';
6
7
void main() {
8
group('OndeException', () {
9
- test('toString includes message', () {
10
- const e = OndeException('No model loaded');
11
- expect(e.toString(), contains('No model loaded'));
9
+ test('toString includes error info', () {
10
+ const e = OndeException(OndeError_NoModelLoaded());
11
+ expect(e.toString(), contains('OndeException'));
12
});
13
14
test('equality', () {
15
- const a = OndeException('foo');
16
- const b = OndeException('foo');
17
- const c = OndeException('bar');
15
+ const a = OndeException(OndeError_NoModelLoaded());
16
+ const b = OndeException(OndeError_NoModelLoaded());
17
+ const c = OndeException(OndeError_Cancelled());
18
expect(a, equals(b));
19
expect(a, isNot(equals(c)));
20
});
21
});
22
23
group('ChatRole', () {
24
- test('toString values', () {
25
- expect(ChatRole.system.toString(), 'system');
26
- expect(ChatRole.user.toString(), 'user');
27
- expect(ChatRole.assistant.toString(), 'assistant');
24
+ test('name values', () {
25
+ expect(ChatRole.system.name, 'system');
26
+ expect(ChatRole.user.name, 'user');
27
+ expect(ChatRole.assistant.name, 'assistant');
28
});
29
});
30
31
group('ChatMessage', () {
32
test('factory constructors set correct roles', () {
33
- expect(ChatMessage.system('Hi').role, ChatRole.system);
34
- expect(ChatMessage.user('Hi').role, ChatRole.user);
35
- expect(ChatMessage.assistant('Hi').role, ChatRole.assistant);
33
+ expect(ChatMessageX.system('Hi').role, ChatRole.system);
34
+ expect(ChatMessageX.user('Hi').role, ChatRole.user);
35
+ expect(ChatMessageX.assistant('Hi').role, ChatRole.assistant);
36
});
37
38
test('equality', () {
39
- final a = ChatMessage.user('Hello');
40
- final b = ChatMessage.user('Hello');
41
- final c = ChatMessage.user('World');
39
+ final a = ChatMessageX.user('Hello');
40
+ final b = ChatMessageX.user('Hello');
41
+ final c = ChatMessageX.user('World');
42
expect(a, equals(b));
43
expect(a, isNot(equals(c)));
44
});
@@ -46,28 +46,28 @@ void main() {
46
47
group('SamplingConfig', () {
48
test('defaultConfig preset', () {
49
- final s = SamplingConfig.defaultConfig();
49
+ final s = SamplingConfigX.defaultConfig();
50
expect(s.temperature, 0.7);
51
expect(s.topP, 0.95);
52
- expect(s.maxTokens, 512);
52
+ expect(s.maxTokens, BigInt.from(512));
53
});
54
55
test('deterministic preset', () {
56
- final s = SamplingConfig.deterministic();
56
+ final s = SamplingConfigX.deterministic();
57
expect(s.temperature, 0.0);
58
- expect(s.maxTokens, 512);
58
+ expect(s.maxTokens, BigInt.from(512));
59
expect(s.topP, isNull);
60
});
61
62
test('mobile preset', () {
63
- final s = SamplingConfig.mobile();
63
+ final s = SamplingConfigX.mobile();
64
expect(s.temperature, 0.7);
65
expect(s.topP, 0.95);
66
- expect(s.maxTokens, 128);
66
+ expect(s.maxTokens, BigInt.from(128));
67
});
68
69
test('copyWith overrides single field', () {
70
- final base = SamplingConfig.defaultConfig();
70
+ final base = SamplingConfigX.defaultConfig();
71
final copy = base.copyWith(temperature: 0.3);
72
expect(copy.temperature, 0.3);
73
expect(copy.topP, base.topP);
@@ -76,19 +76,19 @@ void main() {
76
77
test('equality', () {
78
expect(
79
- SamplingConfig.deterministic(),
80
- equals(SamplingConfig.deterministic()),
79
+ SamplingConfigX.deterministic(),
80
+ equals(SamplingConfigX.deterministic()),
81
);
82
expect(
83
- SamplingConfig.deterministic(),
84
- isNot(equals(SamplingConfig.mobile())),
83
+ SamplingConfigX.deterministic(),
84
+ isNot(equals(SamplingConfigX.mobile())),
85
);
86
});
87
});
88
89
group('GgufModelConfig', () {
90
- test('stub factory functions return non-empty configs', () {
91
- final config1_5b = OndeInference.qwen251_5bConfig();
90
+ test('factory functions return non-empty configs', () {
91
+ final config1_5b = OndeInference.qwen2515bConfig();
92
expect(config1_5b.modelId, contains('1.5B'));
93
expect(config1_5b.files, isNotEmpty);
94
expect(config1_5b.displayName, isNotEmpty);
@@ -98,7 +98,7 @@ void main() {
98
expect(config3b.modelId, contains('3B'));
99
expect(config3b.files, isNotEmpty);
100
101
- final configCoder1_5b = OndeInference.qwen25Coder1_5bConfig();
101
+ final configCoder1_5b = OndeInference.qwen25Coder15bConfig();
102
expect(configCoder1_5b.modelId, contains('Coder'));
103
104
final configCoder3b = OndeInference.qwen25Coder3bConfig();
@@ -110,11 +110,11 @@ void main() {
110
111
test('equality', () {
112
expect(
113
- OndeInference.qwen251_5bConfig(),
114
- equals(OndeInference.qwen251_5bConfig()),
113
+ OndeInference.qwen2515bConfig(),
114
+ equals(OndeInference.qwen2515bConfig()),
115
);
116
expect(
117
- OndeInference.qwen251_5bConfig(),
117
+ OndeInference.qwen2515bConfig(),
118
isNot(equals(OndeInference.qwen253bConfig())),
119
);
120
});
@@ -129,24 +129,30 @@ void main() {
129
expect(EngineStatus.error.isReady, isFalse);
130
});
131
132
- test('toString values', () {
133
- expect(EngineStatus.unloaded.toString(), 'unloaded');
134
- expect(EngineStatus.loading.toString(), 'loading');
135
- expect(EngineStatus.ready.toString(), 'ready');
136
- expect(EngineStatus.generating.toString(), 'generating');
137
- expect(EngineStatus.error.toString(), 'error');
132
+ test('name values', () {
133
+ expect(EngineStatus.unloaded.name, 'unloaded');
134
+ expect(EngineStatus.loading.name, 'loading');
135
+ expect(EngineStatus.ready.name, 'ready');
136
+ expect(EngineStatus.generating.name, 'generating');
137
+ expect(EngineStatus.error.name, 'error');
138
});
139
});
140
141
group('EngineInfo', () {
142
test('equality', () {
143
- const a = EngineInfo(status: EngineStatus.unloaded, historyLength: 0);
144
- const b = EngineInfo(status: EngineStatus.unloaded, historyLength: 0);
145
- const c = EngineInfo(
143
+ final a = EngineInfo(
144
+ status: EngineStatus.unloaded,
145
+ historyLength: BigInt.zero,
146
+ );
147
+ final b = EngineInfo(
148
+ status: EngineStatus.unloaded,
149
+ historyLength: BigInt.zero,
150
+ );
151
+ final c = EngineInfo(
152
status: EngineStatus.ready,
153
modelName: 'Qwen 2.5 3B',
154
approxMemory: '~1.93 GB',
149
- historyLength: 3,
155
+ historyLength: BigInt.from(3),
156
);
157
expect(a, equals(b));
158
expect(a, isNot(equals(c)));
@@ -169,24 +175,23 @@ void main() {
175
text: 'Hi there!',
176
durationSecs: 1.5,
177
durationDisplay: '1.5s',
178
+ finishReason: 'stop',
179
);
180
const b = InferenceResult(
181
text: 'Hi there!',
182
durationSecs: 1.5,
183
durationDisplay: '1.5s',
184
+ finishReason: 'stop',
185
);
186
expect(a, equals(b));
187
});
188
});
189
182
- group('RustLib stub', () {
183
- test('init() is a safe no-op', () async {
184
- expect(RustLib.isInitialized, isFalse);
185
- await RustLib.init();
186
- expect(RustLib.isInitialized, isTrue);
187
- // Second call is also safe.
188
- await RustLib.init();
189
- expect(RustLib.isInitialized, isTrue);
190
+ group('RustLib', () {
191
+ test('instance is accessible before init', () {
192
+ // instance is always non-null; initialization requires the native
193
+ // library to be compiled first.
194
+ expect(RustLib.instance, isNotNull);
195
});
196
});
197
@@ -197,26 +202,25 @@ void main() {
202
203
test('config factories return valid configs', () {
204
expect(OndeInference.defaultModelConfig().modelId, isNotEmpty);
200
- expect(OndeInference.qwen251_5bConfig().modelId, contains('1.5B'));
205
+ expect(OndeInference.qwen2515bConfig().modelId, contains('1.5B'));
206
expect(OndeInference.qwen253bConfig().modelId, contains('3B'));
202
- expect(OndeInference.qwen25Coder1_5bConfig().modelId, contains('Coder'));
207
+ expect(OndeInference.qwen25Coder15bConfig().modelId, contains('Coder'));
208
expect(OndeInference.qwen25Coder3bConfig().modelId, contains('Coder'));
209
});
210
211
test('sampling factories return correct presets', () {
212
expect(OndeInference.defaultSamplingConfig().temperature, 0.7);
213
expect(OndeInference.deterministicSamplingConfig().temperature, 0.0);
209
- expect(OndeInference.mobileSamplingConfig().maxTokens, 128);
214
+ expect(
215
+ OndeInference.mobileSamplingConfig().maxTokens,
216
+ BigInt.from(128),
217
+ );
218
});
219
});
220
213
- group('OndeChatEngine stub', () {
214
- test('create() throws UnimplementedError before codegen', () async {
215
- // RustLib.init() is already called above; init guard is met.
216
- await expectLater(
217
- OndeChatEngine.create(),
218
- throwsA(isA<UnimplementedError>()),
219
- );
221
+ group('OndeChatEngine', () {
222
+ test('constructor throws when library not initialized', () {
223
+ expect(() => OndeChatEngine(), throwsA(anything));
224
});
225
});
226
}