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(); }); 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 = {}; 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', () { repo.reshuffleSessionNumbers(); expect(repo.totalWords, equals(1000)); for (int i = 0; i < 1000; i++) { expect(repo.getWordBySessionNumber(i)?.sessionNumber, equals(i)); } }); 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); }); }); }