| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| class TestNotifier extends ChangeNotifier { |
| void notify() { |
| notifyListeners(); |
| } |
| } |
| |
| void main() { |
| testWidgets('ChangeNotifier', (WidgetTester tester) async { |
| final List<String> log = <String>[]; |
| final VoidCallback listener = () { log.add('listener'); }; |
| final VoidCallback listener1 = () { log.add('listener1'); }; |
| final VoidCallback listener2 = () { log.add('listener2'); }; |
| final VoidCallback badListener = () { log.add('badListener'); throw null; }; |
| |
| final TestNotifier test = new TestNotifier(); |
| |
| test.addListener(listener); |
| test.addListener(listener); |
| test.notify(); |
| expect(log, <String>['listener', 'listener']); |
| log.clear(); |
| |
| test.removeListener(listener); |
| test.notify(); |
| expect(log, <String>['listener']); |
| log.clear(); |
| |
| test.removeListener(listener); |
| test.notify(); |
| expect(log, <String>[]); |
| log.clear(); |
| |
| test.removeListener(listener); |
| test.notify(); |
| expect(log, <String>[]); |
| log.clear(); |
| |
| test.addListener(listener); |
| test.notify(); |
| expect(log, <String>['listener']); |
| log.clear(); |
| |
| test.addListener(listener1); |
| test.notify(); |
| expect(log, <String>['listener', 'listener1']); |
| log.clear(); |
| |
| test.addListener(listener2); |
| test.notify(); |
| expect(log, <String>['listener', 'listener1', 'listener2']); |
| log.clear(); |
| |
| test.removeListener(listener1); |
| test.notify(); |
| expect(log, <String>['listener', 'listener2']); |
| log.clear(); |
| |
| test.addListener(listener1); |
| test.notify(); |
| expect(log, <String>['listener', 'listener2', 'listener1']); |
| log.clear(); |
| |
| test.addListener(badListener); |
| test.notify(); |
| expect(log, <String>['listener', 'listener2', 'listener1', 'badListener']); |
| expect(tester.takeException(), isNullThrownError); |
| log.clear(); |
| |
| test.addListener(listener1); |
| test.removeListener(listener); |
| test.removeListener(listener1); |
| test.removeListener(listener2); |
| test.addListener(listener2); |
| test.notify(); |
| expect(log, <String>['badListener', 'listener1', 'listener2']); |
| expect(tester.takeException(), isNullThrownError); |
| log.clear(); |
| }); |
| |
| test('ChangeNotifier with mutating listener', () { |
| final TestNotifier test = new TestNotifier(); |
| final List<String> log = <String>[]; |
| |
| final VoidCallback listener1 = () { log.add('listener1'); }; |
| final VoidCallback listener3 = () { log.add('listener3'); }; |
| final VoidCallback listener4 = () { log.add('listener4'); }; |
| final VoidCallback listener2 = () { |
| log.add('listener2'); |
| test.removeListener(listener1); |
| test.removeListener(listener3); |
| test.addListener(listener4); |
| }; |
| |
| test.addListener(listener1); |
| test.addListener(listener2); |
| test.addListener(listener3); |
| test.notify(); |
| expect(log, <String>['listener1', 'listener2']); |
| log.clear(); |
| |
| test.notify(); |
| expect(log, <String>['listener2', 'listener4']); |
| log.clear(); |
| |
| test.notify(); |
| expect(log, <String>['listener2', 'listener4', 'listener4']); |
| log.clear(); |
| }); |
| |
| test('Merging change notifiers', () { |
| final TestNotifier source1 = new TestNotifier(); |
| final TestNotifier source2 = new TestNotifier(); |
| final TestNotifier source3 = new TestNotifier(); |
| final List<String> log = <String>[]; |
| |
| final Listenable merged = new Listenable.merge(<Listenable>[source1, source2]); |
| final VoidCallback listener1 = () { log.add('listener1'); }; |
| final VoidCallback listener2 = () { log.add('listener2'); }; |
| |
| merged.addListener(listener1); |
| source1.notify(); |
| source2.notify(); |
| source3.notify(); |
| expect(log, <String>['listener1', 'listener1']); |
| log.clear(); |
| |
| merged.removeListener(listener1); |
| source1.notify(); |
| source2.notify(); |
| source3.notify(); |
| expect(log, isEmpty); |
| log.clear(); |
| |
| merged.addListener(listener1); |
| merged.addListener(listener2); |
| source1.notify(); |
| source2.notify(); |
| source3.notify(); |
| expect(log, <String>['listener1', 'listener2', 'listener1', 'listener2']); |
| log.clear(); |
| }); |
| |
| test('Merging change notifiers ignores null', () { |
| final TestNotifier source1 = new TestNotifier(); |
| final TestNotifier source2 = new TestNotifier(); |
| final List<String> log = <String>[]; |
| |
| final Listenable merged = new Listenable.merge(<Listenable>[null, source1, null, source2, null]); |
| final VoidCallback listener = () { log.add('listener'); }; |
| |
| merged.addListener(listener); |
| source1.notify(); |
| source2.notify(); |
| expect(log, <String>['listener', 'listener']); |
| log.clear(); |
| }); |
| |
| test('Can dispose merged notifier', () { |
| final TestNotifier source1 = new TestNotifier(); |
| final TestNotifier source2 = new TestNotifier(); |
| final List<String> log = <String>[]; |
| |
| final ChangeNotifier merged = new Listenable.merge(<Listenable>[source1, source2]); |
| final VoidCallback listener = () { log.add('listener'); }; |
| |
| merged.addListener(listener); |
| source1.notify(); |
| source2.notify(); |
| expect(log, <String>['listener', 'listener']); |
| log.clear(); |
| merged.dispose(); |
| |
| source1.notify(); |
| source2.notify(); |
| expect(log, isEmpty); |
| }); |
| |
| test('Cannot use a disposed ChangeNotifier', () { |
| final TestNotifier source = new TestNotifier(); |
| source.dispose(); |
| expect(() { source.addListener(null); }, throwsFlutterError); |
| expect(() { source.removeListener(null); }, throwsFlutterError); |
| expect(() { source.dispose(); }, throwsFlutterError); |
| expect(() { source.notify(); }, throwsFlutterError); |
| }); |
| |
| test('Value notifier', () { |
| final ValueNotifier<double> notifier = new ValueNotifier<double>(2.0); |
| |
| final List<double> log = <double>[]; |
| final VoidCallback listener = () { log.add(notifier.value); }; |
| |
| notifier.addListener(listener); |
| notifier.value = 3.0; |
| |
| expect(log, equals(<double>[ 3.0 ])); |
| log.clear(); |
| |
| notifier.value = 3.0; |
| expect(log, isEmpty); |
| }); |
| |
| test('Listenable.merge toString', () { |
| final TestNotifier source1 = new TestNotifier(); |
| final TestNotifier source2 = new TestNotifier(); |
| |
| ChangeNotifier listenableUnderTest = new Listenable.merge(<Listenable>[]); |
| expect(listenableUnderTest.toString(), 'Listenable.merge([])'); |
| |
| listenableUnderTest = new Listenable.merge(<Listenable>[null]); |
| expect(listenableUnderTest.toString(), 'Listenable.merge([null])'); |
| |
| listenableUnderTest = new Listenable.merge(<Listenable>[source1]); |
| expect( |
| listenableUnderTest.toString(), |
| "Listenable.merge([Instance of 'TestNotifier'])", |
| ); |
| |
| listenableUnderTest = new Listenable.merge(<Listenable>[source1, source2]); |
| expect( |
| listenableUnderTest.toString(), |
| "Listenable.merge([Instance of 'TestNotifier', Instance of 'TestNotifier'])", |
| ); |
| |
| listenableUnderTest = new Listenable.merge(<Listenable>[null, source2]); |
| expect( |
| listenableUnderTest.toString(), |
| "Listenable.merge([null, Instance of 'TestNotifier'])", |
| ); |
| }); |
| } |