import 'dart:convert'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:kouyu_english/core/courses/courses.dart'; import 'package:kouyu_english/core/courses/course_pack.dart'; import '../tool/courses/course_validator.dart'; void main() { test('tokenize expands contractions and skips digits', () { expect(tokenize("I'm Tom. Can't pay 15 dollars at 7 a.m.; let's go"), [ 'i', 'am', 'tom', 'can', 'not', 'pay', 'dollars', 'at', 'am', 'let', 'us', 'go', ]); }); test('match groups use AND across groups and OR inside a group', () { expect( matchesRule("Sorry, I don't understand.", [ ['do not understand'], ]), isTrue, ); expect( matchesRule('twelvee', [ ['twelve'], ]), isFalse, ); expect( matchesRule('What is this word?', [ ['what does', 'what is'], ['mean'], ]), isFalse, ); }); test('course packs pass validation', () { final report = CourseValidator( projectRoot: Directory.current, a0Texts: [ for (final item in a0CoreItems.values) item.replaceAll(RegExp(r'\[[^\]]*\]'), ''), for (final sentence in coreDictationSentences.values) sentence.sentence, ], ).validate(); expect(report.errors.map((issue) => '$issue'), isEmpty); }); test('the course parser keeps item links and extra model sentences', () { final unit = jsonDecode(File('assets/courses/A1/A1-U01.json').readAsStringSync()) as Map; final segment = PackSegment.fromJson( (unit['segments'] as List).first as Map, ); expect(segment.speakingItemIds, ['A1-U01-P01', 'A1-U01-P04']); expect(segment.speakingExamples, isNotEmpty); expect(segment.speakingChunks.join(' '), segment.speakingText); }); }