The Garage SDKs, in the open

garage_auth, garage_entitlements, garage_iap and garage_ui, moved out of
Garage-Services and Metro-Map-Maker into one public repo. MIT, one readme,
docs under docs/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013F4NWNvYcdeSgqbWMT1VQ7
This commit is contained in:
ImBenji
2026-09-23 18:49:21 +01:00
co-authored by Claude Opus 5.5
commit b269201919
117 changed files with 26944 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
import "package:flutter/foundation.dart";
import "package:flutter/services.dart";
import "package:flutter/widgets.dart";
import "package:flutter_test/flutter_test.dart";
import "package:garage_ui/garage_ui.dart";
import "package:garage_ui/platform/cursor_lock.dart";
import "support/test_scheme.dart";
// Drag-to-scrub used to be macOS only without anybody saying so. The moment
// the drag threshold was crossed the field handed everything over to
// CursorLock and ignored Flutters own pointer stream forever after - and
// CursorLock has no native handler off macOS, so on web (and windows/linux)
// the deltas it was waiting on never turned up. The field just froze on the
// value it started on.
Future<TextEditingController> pumpField(
WidgetTester tester, {
String text = "10.0",
}) async {
final controller = TextEditingController(text: text);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GarageTheme(
data: ThemeData(colorScheme: testScheme),
child: Center(
child: SizedBox(
width: 200,
child: TextField(
controller: controller,
features: const [InputFeature.scrub()],
),
),
),
),
),
);
await tester.pump();
return controller;
}
void main() {
testWidgets("no native cursor lock - the pointer stream drives the scrub", (
tester,
) async {
debugDefaultTargetPlatformOverride = TargetPlatform.linux;
expect(CursorLock.isSupported, isFalse);
final controller = await pumpField(tester);
// real pointer moves arrive a few px at a time, so drive it that way
// rather than as one giant jump. default sensitivity is 0.1/px, and the
// first move only arms the drag (it's the one the click threshold eats),
// so 100 counted px = +10.
final gesture = await tester.startGesture(
tester.getCenter(find.byType(TextField)),
);
for (var i = 0; i < 21; i++) {
await gesture.moveBy(const Offset(5, 0));
await tester.pump();
}
await gesture.up();
await tester.pump();
expect(double.parse(controller.text), closeTo(20.0, 0.5));
debugDefaultTargetPlatformOverride = null;
});
testWidgets("with a native cursor lock the pointer stream is ignored", (
tester,
) async {
debugDefaultTargetPlatformOverride = TargetPlatform.macOS;
const channel = MethodChannel("garage/cursor_lock");
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (_) async => null);
final controller = await pumpField(tester);
final gesture = await tester.startGesture(
tester.getCenter(find.byType(TextField)),
);
for (var i = 0; i < 21; i++) {
await gesture.moveBy(const Offset(5, 0));
await tester.pump();
}
await gesture.up();
await tester.pump();
// the native side would have sent deltas back over the channel; nothing
// did here, so the value must not have budged.
expect(double.parse(controller.text), closeTo(10.0, 1e-9));
debugDefaultTargetPlatformOverride = null;
});
}