import 'package:flutter_test/flutter_test.dart'; import 'package:tane/domain/species_autoclassify.dart'; /// A small catalog spanning the tricky cases: accents, multi-word names, a /// name shared across two species, and substrings that must NOT fire. const _names = [ SpeciesNameEntry(speciesId: 'zea', name: 'Maíz'), SpeciesNameEntry(speciesId: 'zea', name: 'Maize'), SpeciesNameEntry(speciesId: 'zea', name: 'Zea mays'), SpeciesNameEntry(speciesId: 'tomato', name: 'Tomate'), SpeciesNameEntry(speciesId: 'tomato', name: 'Tomato'), SpeciesNameEntry(speciesId: 'bean', name: 'Common bean'), SpeciesNameEntry(speciesId: 'faba', name: 'Broad bean'), SpeciesNameEntry(speciesId: 'faba', name: 'Haba'), SpeciesNameEntry(speciesId: 'pea', name: 'Pea'), // "Calabaza" is deliberately shared → ambiguous, must stay unclassified. SpeciesNameEntry(speciesId: 'pepo', name: 'Calabaza'), SpeciesNameEntry(speciesId: 'maxima', name: 'Calabaza'), ]; void main() { String? match(String label) => matchSpeciesInLabel(label, _names); test('matches a common name embedded in a free-text label', () { expect(match('Maíz de la abuela'), 'zea'); expect(match('Tomate cherry'), 'tomato'); }); test('is accent- and case-insensitive', () { expect(match('MAIZ dulce'), 'zea'); // no accent, upper-case expect(match('tomate rosa'), 'tomato'); }); test('matches the scientific name too', () { expect(match('Zea mays landrace'), 'zea'); }); test('matches multi-word names as a contiguous phrase', () { expect(match('Broad bean Aquadulce'), 'faba'); expect(match('Common bean from grandma'), 'bean'); }); test('prefers the longest (most specific) name', () { // "bean" alone is not in the catalog, but the two-word names should win // over any single-word coincidence. expect(match('Broad bean'), 'faba'); }); test('folds a plural label word to a singular catalog name', () { expect(match('Tomates de rama'), 'tomato'); expect(match('Habas de mi huerto'), 'faba'); }); test('does not fire on a substring that is not a whole word', () { expect(match('Habanero picante'), isNull); // contains "haba" as substring expect(match('Peach tree'), isNull); // contains "pea" as substring }); test('returns null when a name is shared across species (ambiguous)', () { expect(match('Calabaza de invierno'), isNull); }); test('returns null when nothing matches', () { expect(match('Girasol gigante'), isNull); expect(match(' '), isNull); expect(match(''), isNull); }); }