2026-10-15 22:24:36 +09:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
|
|
import 'package:display/theme/light.dart';
|
2026-10-15 22:14:29 +09:00
|
|
|
import 'package:display/theme/palette.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
|
final dispatcher = TestWidgetsFlutterBinding.instance.platformDispatcher;
|
|
|
|
|
tearDown(dispatcher.clearPlatformBrightnessTestValue);
|
|
|
|
|
|
|
|
|
|
test(
|
|
|
|
|
'auto follows Android, the quick switch holds one, and it is kept',
|
|
|
|
|
() async {
|
|
|
|
|
SharedPreferences.setMockInitialValues({});
|
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
Themes make() =>
|
|
|
|
|
Themes('t', Palette.fallbackDark, Palette.fallbackBright, prefs);
|
|
|
|
|
final t = make();
|
|
|
|
|
var notified = 0;
|
|
|
|
|
t.addListener(() => notified++);
|
|
|
|
|
|
|
|
|
|
expect(t.mode, VariantMode.auto);
|
|
|
|
|
dispatcher.platformBrightnessTestValue = Brightness.light;
|
|
|
|
|
expect(t.isDark, isFalse);
|
|
|
|
|
expect(notified, 1); // the binding tells its observers
|
|
|
|
|
|
|
|
|
|
t.toggle(); // bright showing: hold dark
|
|
|
|
|
expect((t.mode, t.isDark), (VariantMode.dark, true));
|
|
|
|
|
dispatcher.platformBrightnessTestValue = Brightness.dark;
|
|
|
|
|
dispatcher.platformBrightnessTestValue = Brightness.light;
|
|
|
|
|
expect(notified, 2); // fixed: Android's changes are ignored
|
|
|
|
|
|
|
|
|
|
expect(make().mode, VariantMode.dark); // kept for the next start
|
|
|
|
|
},
|
|
|
|
|
);
|
2026-10-15 22:24:36 +09:00
|
|
|
|
|
|
|
|
test('the light switch has a gap and a hold', () {
|
|
|
|
|
final s = LightSwitch();
|
|
|
|
|
final t0 = DateTime(2026);
|
|
|
|
|
DateTime at(int sec) => t0.add(Duration(seconds: sec));
|
|
|
|
|
expect(s.feed(30, at(0)), isNull); // in the gap: no verdict yet
|
|
|
|
|
expect(s.feed(500, at(1)), isFalse); // the first clear reading decides
|
|
|
|
|
expect(s.feed(30, at(2)), isFalse); // the gap keeps it
|
|
|
|
|
expect(s.feed(5, at(3)), isFalse); // dark, but not for long enough
|
|
|
|
|
expect(s.pending, isTrue);
|
|
|
|
|
expect(s.feed(200, at(4)), isFalse); // back: the hold restarts
|
|
|
|
|
expect(s.pending, isFalse);
|
|
|
|
|
s.feed(5, at(10));
|
|
|
|
|
expect(s.feed(5, at(14)), isFalse);
|
|
|
|
|
expect(s.feed(5, at(15)), isTrue);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
testWidgets('auto takes the light sensor over Android', (tester) async {
|
|
|
|
|
SharedPreferences.setMockInitialValues({});
|
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
|
|
|
|
|
final t = Themes('t', Palette.fallbackDark, Palette.fallbackBright, prefs);
|
|
|
|
|
final levels = StreamController<double>();
|
|
|
|
|
t.followLight(levels.stream);
|
|
|
|
|
expect(t.isDark, isTrue); // no reading yet: Android's
|
|
|
|
|
levels.add(800);
|
|
|
|
|
await tester.pump();
|
|
|
|
|
expect((t.isDark, t.lux.value), (false, 800));
|
|
|
|
|
levels.add(2);
|
|
|
|
|
await tester.pump(
|
|
|
|
|
const Duration(seconds: 6),
|
|
|
|
|
); // no new reading: the timer ends the hold
|
|
|
|
|
expect(t.isDark, isTrue);
|
|
|
|
|
});
|
2026-10-15 22:14:29 +09:00
|
|
|
}
|