116 lines
4.1 KiB
Dart
116 lines
4.1 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:words999/services/houses_service.dart';
|
|
import 'package:words999/services/words_repository.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
group('HousesService 33x30 Field & 10 Archons Tests', () {
|
|
late HousesService service;
|
|
|
|
setUp(() async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
final repo = WordsRepository();
|
|
await repo.init(remoteDailyShuffle: false);
|
|
service = HousesService();
|
|
});
|
|
|
|
test('Session generation creates exactly 10 Archons and 990 Houses without overlap', () {
|
|
final session = service.createNewSession(question: 'Тестовый вопрос');
|
|
|
|
expect(session.sectors.length, equals(10));
|
|
expect(session.grid.length, equals(990));
|
|
|
|
final allWords = <String>{};
|
|
|
|
// Check Archons
|
|
for (int i = 0; i < 10; i++) {
|
|
final s = session.sectors[i];
|
|
expect(s.index, equals(i));
|
|
expect(s.startCol, equals(i * 3));
|
|
expect(s.endCol, equals(i * 3 + 2));
|
|
expect(s.archonWord.word.isNotEmpty, isTrue);
|
|
allWords.add(s.archonWord.word.toLowerCase());
|
|
}
|
|
|
|
expect(allWords.length, equals(10), reason: '10 Archons must be unique');
|
|
|
|
// Check Houses (33 rows x 30 cols)
|
|
for (int r = 0; r < 33; r++) {
|
|
for (int c = 0; c < 30; c++) {
|
|
final idx = r * 30 + c;
|
|
final cell = session.grid[idx];
|
|
expect(cell.row, equals(r));
|
|
expect(cell.col, equals(c));
|
|
expect(cell.houseIndex, equals(idx));
|
|
expect(cell.sectorIndex, equals(c ~/ 3));
|
|
expect(cell.houseWord.word.isNotEmpty, isTrue);
|
|
allWords.add(cell.houseWord.word.toLowerCase());
|
|
}
|
|
}
|
|
|
|
// Exactly 1000 unique words partitioned
|
|
expect(allWords.length, equals(1000));
|
|
});
|
|
|
|
test('Divination with 5 chosen houses populates guests and computes chains', () {
|
|
final session = service.createNewSession();
|
|
final chosen = [
|
|
session.grid[0].copyWith(selectionOrder: 1),
|
|
session.grid[15].copyWith(selectionOrder: 2),
|
|
session.grid[42].copyWith(selectionOrder: 3),
|
|
session.grid[100].copyWith(selectionOrder: 4),
|
|
session.grid[500].copyWith(selectionOrder: 5),
|
|
];
|
|
|
|
final result = service.completeDivination(session, chosen);
|
|
|
|
expect(result.selectedHouses.length, equals(5));
|
|
for (int i = 0; i < 5; i++) {
|
|
final h = result.selectedHouses[i];
|
|
expect(h.guestWord, isNotNull);
|
|
expect(h.selectionOrder, equals(i + 1));
|
|
}
|
|
|
|
expect(result.chains.isNotEmpty, isTrue);
|
|
for (final chain in result.chains) {
|
|
expect(chain.steps.isNotEmpty, isTrue);
|
|
expect(chain.steps.first.house, isNotNull);
|
|
expect(chain.steps.first.guest, isNotNull);
|
|
}
|
|
});
|
|
|
|
test('Chain length is capped at maximum 9 links', () {
|
|
final session = service.createNewSession();
|
|
final chosen = [
|
|
session.grid[0].copyWith(selectionOrder: 1),
|
|
];
|
|
|
|
final result = service.completeDivination(session, chosen);
|
|
for (final chain in result.chains) {
|
|
expect(chain.steps.length, lessThanOrEqualTo(9));
|
|
}
|
|
});
|
|
|
|
test('Querent word is guaranteed to be in houses and its index matches dynamically', () {
|
|
final repo = WordsRepository();
|
|
final manWord = repo.allWords.firstWhere((w) => w.word.toLowerCase() == 'мужчина');
|
|
|
|
final session1 = service.createNewSession(querentWord: manWord);
|
|
expect(session1.querentHouseIndex, isNotNull);
|
|
final qIndex1 = session1.querentHouseIndex!;
|
|
expect(session1.grid[qIndex1].houseWord.word.toLowerCase(), equals('мужчина'));
|
|
|
|
// Reshuffle matrix multiple times: the querent must always match the house word at its index
|
|
for (int i = 0; i < 5; i++) {
|
|
final sessionRe = service.createNewSession(querentWord: manWord);
|
|
expect(sessionRe.querentHouseIndex, isNotNull);
|
|
final qIdx = sessionRe.querentHouseIndex!;
|
|
expect(sessionRe.grid[qIdx].houseWord.word.toLowerCase(), equals('мужчина'));
|
|
}
|
|
});
|
|
|
|
});
|
|
}
|