import 'dart:math'; import 'package:test/test.dart'; import 'package:platform_support/platform_support.dart'; class TestRandom implements Random { final List values; int index = 0; TestRandom(this.values); @override bool nextBool() => throw UnimplementedError(); @override double nextDouble() => throw UnimplementedError(); @override int nextInt(int max) => values[index++ % values.length]; } void main() { group('Lottery', () { test('creates instance with valid parameters', () { expect(() => Lottery(10, 5), returnsNormally); expect(() => Lottery(10, 0), returnsNormally); expect(() => Lottery(10, 10), returnsNormally); }); test('throws assertion error for invalid parameters', () { expect(() => Lottery(0, 0), throwsA(isA())); expect(() => Lottery(-1, 0), throwsA(isA())); expect(() => Lottery(5, 6), throwsA(isA())); expect(() => Lottery(5, -1), throwsA(isA())); }); test('creates instance with odds', () { final lottery = Lottery.odds(1, 2); expect(lottery.tickets, equals(2)); expect(lottery.winners, equals(1)); }); test('creates instance with percentage', () { final lottery = Lottery.percentage(50); expect(lottery.tickets, equals(100)); expect(lottery.winners, equals(50)); }); test('throws assertion error for invalid percentage', () { expect(() => Lottery.percentage(-1), throwsA(isA())); expect(() => Lottery.percentage(101), throwsA(isA())); }); test('always wins with full winners', () { final lottery = Lottery(5, 5); for (var i = 0; i < 100; i++) { expect(lottery.choose(), isTrue); } }); test('never wins with zero winners', () { final lottery = Lottery(5, 0); for (var i = 0; i < 100; i++) { expect(lottery.choose(), isFalse); } }); test('wins based on random value', () { final random = TestRandom([0, 1, 2, 3, 4]); final lottery = Lottery(5, 3, random); // Should win for values 0, 1, 2 (less than winners) // Should lose for values 3, 4 (greater than or equal to winners) expect(lottery.choose(), isTrue); // 0 expect(lottery.choose(), isTrue); // 1 expect(lottery.choose(), isTrue); // 2 expect(lottery.choose(), isFalse); // 3 expect(lottery.choose(), isFalse); // 4 }); test('runs async callback when winning', () async { final random = TestRandom([0]); // Will win final lottery = Lottery(2, 1, random); final result = await lottery.run(() async => 'winner'); expect(result, equals('winner')); }); test('skips async callback when losing', () async { final random = TestRandom([1]); // Will lose final lottery = Lottery(2, 1, random); final result = await lottery.run(() async => 'winner'); expect(result, isNull); }); test('runs sync callback when winning', () { final random = TestRandom([0]); // Will win final lottery = Lottery(2, 1, random); final result = lottery.sync(() => 'winner'); expect(result, equals('winner')); }); test('skips sync callback when losing', () { final random = TestRandom([1]); // Will lose final lottery = Lottery(2, 1, random); final result = lottery.sync(() => 'winner'); expect(result, isNull); }); test('calculates probability correctly', () { expect(Lottery(100, 50).probability, equals(50.0)); expect(Lottery(100, 25).probability, equals(25.0)); expect(Lottery(100, 75).probability, equals(75.0)); }); test('formats odds correctly', () { expect(Lottery(100, 50).odds, equals('50:100')); expect(Lottery(100, 25).odds, equals('25:100')); expect(Lottery(100, 75).odds, equals('75:100')); }); }); }