import 'package:flutter_test/flutter_test.dart'; import 'package:receipity/services/receipt_parser.dart'; void main() { test('parses name and price at the end of a line', () { final items = ReceiptParser.parse(''' MILK 1.50 BREAD 2.00 TOTAL 3.50 CASH 5.00 CHANGE 1.50 '''); expect(items.map((item) => item.name), ['MILK', 'BREAD']); expect(items.map((item) => item.price), [1.50, 2.00]); }); test('uses the next line when quantity and total are split', () { final items = ReceiptParser.parse(''' EGGS 2 X 1.50 3.00 BUTTER 2.25 SUBTOTAL 5.25 '''); expect(items, hasLength(2)); expect(items[0].name, 'EGGS'); expect(items[0].price, 3.00); expect(items[0].quantity, 2); expect(items[0].unitPrice, 1.50); expect(items[1].name, 'BUTTER'); expect(items[1].price, 2.25); }); test('computes a total when the quantity line has no line total', () { final items = ReceiptParser.parse(''' BROODSTICKS OLIJF 4 X 1,25 '''); expect(items, hasLength(1)); expect(items.single.name, 'BROODSTICKS OLIJF'); expect(items.single.price, 5.00); expect(items.single.quantity, 4); }); test('folds a discount into the previous item', () { final result = ReceiptParser.parseReceipt(''' AARDBEIEN 7,98 ACTIE AARDBEIEN -2,00 Totaal 5,98 VISA 5,98 Totaal korting: -2,00 '''); expect(result.items.map((item) => item.name), ['AARDBEIEN']); expect(result.items.single.price, 5.98); expect(result.items.single.discount, -2.00); expect(result.validationPassed, isTrue); }); test('parses Kruidvat-style inline quantity', () { final items = ReceiptParser.parse(''' ZEEPTABLET NEUTRAL 2 X 3,99 PER STUK 7,98 KORTING NEUTRAL ZE.HP -1,00 Totaal 6,98 '''); expect(items, hasLength(1)); expect(items.single.name, 'ZEEPTABLET NEUTRAL'); expect(items.single.quantity, 2); expect(items.single.unitPrice, 3.99); expect(items.single.price, 6.98); }); test('parses Lidl-style price-reduction lines', () { final items = ReceiptParser.parse(''' MELK 1,09 B In prijs verlaagd -0,50 Totaal 0,59 '''); expect(items, hasLength(1)); expect(items.single.name, 'MELK'); expect(items.single.price, 0.59); }); test('ignores BTW breakdown rows', () { final items = ReceiptParser.parse(''' MELK 2,09 Totaal 2,09 BTW B 9% 0,17 C 21% 0,00 Bedr.Excl 1,92 Bedr.Incl 2,09 '''); expect(items.map((item) => item.name), ['MELK']); }); test('pairs a name column with a price column from OCR', () { final items = ReceiptParser.parse(_jumboColumnOcr); expect(items.map((item) => item.name), isNot(contains('OMSCHRIJVING'))); expect(items.map((item) => item.name), isNot(contains('Totaal'))); expect(items.map((item) => item.name), isNot(contains('ACTIE AARDBEIEN'))); expect(items.first.name, 'JUMBO BIO VOLLE MELK'); expect(items.first.price, 2.09); final eggs = items.firstWhere( (item) => item.name.startsWith('BIOLOGISCH EI'), ); expect(eggs.quantity, 2); expect(eggs.price, 5.58); final berries = items.firstWhere((item) => item.name == 'AARDBEIEN'); expect(berries.quantity, 2); expect(berries.price, 5.98); expect(items.last.name, 'JUMBO PREM LUIER M4'); expect(items.last.price, 6.20); expect(items, hasLength(26)); }); } const _jumboColumnOcr = ''' OMSCHRIJVING JUMBO BIO VOLLE MELK JUMBO BIO BLOEMKOOLS JUMBO BIO ROM TOMAAT JUMBO BIO SIZ LINZEN JUMBO BIO SIZ CHAMP. JUMBO FRITO BIOLOGISCH EI 6 ST 2 X 2,79 KABELJAUW GROENE KR JUMBO BIO KIPDI JFILE JUMBO RASP MOZZAREL JUMBO KAASBL BELEGEN GALBAN MOZZAREL MAXI TORTELL DROGE HAM PATURATIN NATURAL PAPRIKA ROOD BIO COTTAGE CHEESE FP BIO JB PLAK BIO VASTKOKEND AARD 2 X 1,99 AARDBEIEN 2 X 3,99 ACTIE AARDBEIEN BROCCOLI PREI CITROENEN KOMKOMMER 2 X 0,95 ACTIE KOMKOMMER BOL KNOFLOOK BROODSTICKS OLIJF 4 X 1,25 Krui dernhof 26 1112 PS Diemen 0206904928 www.jumbo. com JUMBO PREM LUIER M4 Totaal Betaal d: VISA Totaal korting: BEDRAG IN € 2,09 2,39 2,89 2,89 2,39 0,87 5,58 9,54 4.74 2,49 3,89 2,77 2,49 2,59 1,09 0,99 4,12 3,98 7,98 -2,00 1,24 0,69 2,11 1,90 -0,21 1,79 5,00 6,20 82,99 82,99 -2,21 ''';