Sondé avant de câbler (`+etm56`) : `periodStartedAt` = 1788562800 = 00:00 Londres = 01:00 Paris, `measuredSince` = 07:04 Londres, `timeZone` = Europe/London. Sept heures d'écart entre les deux bornes. - `EnergyRatiosSnapshot` — les deux instants et le fuseau. `baselineRepriseEnJournee` dit quand les ratios de la box ne parlent que depuis un redémarrage : c'est le silence que `measuredSince` existe pour fermer, et quand les deux coïncident — le cas normal — il n'y a rien à dire de plus ; - `fetchEnergyRatios()`, et `fetchDailyBalance()` qui prend désormais la frontière publiée. Repli sur minuit local pour une box antérieure, écrit comme tel. Et un effet de bord attrapé avant qu'il ne parte : `startsLate` comparait à minuit du TÉLÉPHONE. Avec la frontière de la box, il aurait crié « partiel » tous les jours sur un bilan complet — un avertissement permanent cesse d'être lu. Il se compare maintenant à `periodStart`, porté par le bilan, et un test fige le piège. Les taux journaliers de `DailyBalance` sont donc corrigés du même geste : ils se calculent déjà par différence de compteurs sur la fenêtre, c'était la fenêtre qui était fausse. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKM8FDNHZWogAsjjfB8pSw
66 lines
2.9 KiB
Dart
66 lines
2.9 KiB
Dart
/// **Les deux bornes des ratios de la box** — et la phrase que leur écart autorise.
|
|
///
|
|
/// Relevé sur `.75` le 2026-09-05 en `+etm56` : `periodStartedAt` à 00:00 Londres
|
|
/// (01:00 Paris), `measuredSince` à 07:04 Londres. **Sept heures d'écart.** Un ratio
|
|
/// étiqueté « aujourd'hui » aurait donc parlé d'une fenêtre commencée à 08:04 sans que rien
|
|
/// ne le signale — c'est ce silence que la paire ferme.
|
|
library;
|
|
|
|
import 'package:etm_powersync_app/models/energy_ratios_snapshot.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
/// La charge utile réelle, telle que la sonde l'a lue.
|
|
Map<String, dynamic> _releve({int? measuredSince}) => {
|
|
'autonomyRate': 41.0,
|
|
'selfConsumptionRate': 63.0,
|
|
'periodStartedAt': 1788562800,
|
|
'measuredSince': measuredSince ?? 1788588269,
|
|
'timeZone': 'Europe/London',
|
|
};
|
|
|
|
void main() {
|
|
group('les deux instants se lisent, et leur écart parle', () {
|
|
test('la frontière de journée est PUBLIÉE, pas dérivée', () {
|
|
final r = EnergyRatiosSnapshot.fromJson(_releve());
|
|
// 1788562800 = 2026-09-04T23:00:00Z = minuit à Londres. L'app ne recalcule rien :
|
|
// un nom de fuseau IANA ne donne pas de décalage, et une base de fuseaux ne donnerait
|
|
// pas les jours à 23 ou 25 heures.
|
|
expect(r.periodStartedAt!.toUtc(),
|
|
DateTime.utc(2026, 9, 4, 23, 0, 0));
|
|
expect(r.timeZone, 'Europe/London');
|
|
expect(r.datePeriode, isTrue);
|
|
});
|
|
|
|
test('baseline reprise en journée : l\'écran doit le dire', () {
|
|
expect(EnergyRatiosSnapshot.fromJson(_releve()).baselineRepriseEnJournee,
|
|
isTrue,
|
|
reason: 'sept heures après le début de journée — un redémarrage de nymead');
|
|
});
|
|
|
|
test('les deux coïncident : rien à dire de plus', () {
|
|
// Le cas normal. Une phrase supplémentaire y serait du bruit.
|
|
final r = EnergyRatiosSnapshot.fromJson(_releve(measuredSince: 1788562800));
|
|
expect(r.baselineRepriseEnJournee, isFalse);
|
|
});
|
|
|
|
test('une minute d\'écart n\'est pas une reprise', () {
|
|
// Les deux instants viennent de la même box, mais rien ne garantit qu'ils tombent
|
|
// sur la même seconde au premier cycle après minuit.
|
|
final r = EnergyRatiosSnapshot.fromJson(_releve(measuredSince: 1788562840));
|
|
expect(r.baselineRepriseEnJournee, isFalse);
|
|
});
|
|
});
|
|
|
|
group('box antérieure : on ne conclut pas d\'une absence', () {
|
|
test('sans les champs, aucune date et aucune alerte', () {
|
|
const vide = <String, dynamic>{'autonomyRate': 41.0};
|
|
final r = EnergyRatiosSnapshot.fromJson(vide);
|
|
expect(r.periodStartedAt, isNull);
|
|
expect(r.datePeriode, isFalse,
|
|
reason: 'le bilan retombera sur minuit local, et c\'est écrit');
|
|
expect(r.baselineRepriseEnJournee, isFalse,
|
|
reason: 'ne pas savoir n\'est pas « la baseline a bougé »');
|
|
});
|
|
});
|
|
}
|