Files
999/test/words_repository_test.dart
T
Alexyz 7f91366201 feat: Random.org dice and daily word matrix, interpreter voices, curated lexicon
Wire cleromancy rolls and the once-per-UTC-day 000-999 word shuffle to RANDOM.ORG JSON-RPC, with a local CSPRNG fallback. Add settings for interpreter personas and a cleaner default oracle prompt. Replace proper names and bureaucratic filler in the 1000-word lexicon with sacred symbols.
2026-09-08 13:46:11 +05:00

126 lines
4.9 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:words999/models/history_entry_model.dart';
import 'package:words999/services/words_repository.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('WordsRepository Oracle & Divination Tests', () {
late WordsRepository repo;
setUp(() async {
SharedPreferences.setMockInitialValues({});
repo = WordsRepository();
await repo.init(remoteDailyShuffle: false);
});
test('Dataset contains exactly 1000 words with unique randomized session numbers 000 to 999', () {
expect(repo.totalWords, equals(1000));
expect(repo.allWords.length, equals(1000));
final seenSessionNumbers = <int>{};
for (int i = 0; i <= 999; i++) {
final item = repo.getWordBySessionNumber(i);
expect(item, isNotNull, reason: 'Word with session number $i must exist');
expect(item!.sessionNumber, equals(i));
expect(item.formattedSessionNumber.length, equals(3));
expect(item.word.isNotEmpty, isTrue, reason: 'Word cannot be empty');
expect(item.description.isNotEmpty, isTrue, reason: 'Symbolic meaning must be present');
expect(item.partOfSpeech.isNotEmpty, isTrue);
seenSessionNumbers.add(item.sessionNumber);
}
expect(seenSessionNumbers.length, equals(1000));
});
test('Reshuffling changes the order / mapping of words to session numbers', () async {
await repo.reshuffleSessionNumbers();
expect(repo.totalWords, equals(1000));
for (int i = 0; i < 1000; i++) {
expect(repo.getWordBySessionNumber(i)?.sessionNumber, equals(i));
}
});
test('Same UTC day reuses the persisted word matrix', () async {
final first = [
for (int i = 0; i < 8; i++) repo.getWordBySessionNumber(i)!.word,
];
await repo.init(remoteDailyShuffle: false);
expect([
for (int i = 0; i < 8; i++) repo.getWordBySessionNumber(i)!.word,
], first);
expect(repo.dailyMappingDate, WordsRepository.utcDateStamp());
});
test('Search by number string returns correct session word', () {
final results0 = repo.search('0');
expect(results0.isNotEmpty, isTrue);
expect(results0.first.sessionNumber, equals(0));
final results42 = repo.search('42');
expect(results42.isNotEmpty, isTrue);
expect(results42.first.sessionNumber, equals(42));
final results999 = repo.search('999');
expect(results999.isNotEmpty, isTrue);
expect(results999.first.sessionNumber, equals(999));
});
test('Next and previous word navigation wraps around 000..999', () {
expect(repo.getNextWord(0).sessionNumber, equals(1));
expect(repo.getNextWord(999).sessionNumber, equals(0));
expect(repo.getPreviousWord(1).sessionNumber, equals(0));
expect(repo.getPreviousWord(0).sessionNumber, equals(999));
});
test('Multi-word session history can be saved, updated with AI interpretation, and cleared', () async {
await repo.clearHistory();
expect(repo.sessions.isEmpty, isTrue);
final session = OracleSession(
id: 'session_1',
timestamp: DateTime(2026, 8, 31, 12, 0),
question: 'В чем скрытый конфликт?',
wordsCount: 3,
words: [
const SessionWord(
word: 'огонь',
sessionNumber: 777,
partOfSpeech: 'существительное',
category: 'Образ',
symbolicMeaning: 'Очищающее пламя',
),
const SessionWord(
word: 'вода',
sessionNumber: 15,
partOfSpeech: 'существительное',
category: 'Образ',
symbolicMeaning: 'Поток интуиции',
),
const SessionWord(
word: 'мир',
sessionNumber: 999,
partOfSpeech: 'существительное',
category: 'Образ',
symbolicMeaning: 'Гармония согласия',
),
],
);
await repo.saveSession(session);
expect(repo.sessions.length, equals(1));
expect(repo.sessions.first.words.length, equals(3));
expect(repo.sessions.first.words[0].word, equals('огонь'));
expect(repo.sessions.first.words[1].word, equals('вода'));
expect(repo.sessions.first.question, equals('В чем скрытый конфликт?'));
// Update with AI interpretation
await repo.updateSession('session_1', aiInterpretation: 'Связка огня и воды рождает баланс мира.');
expect(repo.sessions.first.aiInterpretation, equals('Связка огня и воды рождает баланс мира.'));
await repo.clearHistory();
expect(repo.sessions.isEmpty, isTrue);
});
});
}