diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d36da5d..74542c1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,12 +14,14 @@ jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on - runs-on: ubuntu-latest + runs-on: macos-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: - uses: actions/checkout@v2 - uses: subosito/flutter-action@v1.5.3 + - name: Run Flutter doctor. + run: flutter doctor -v - name: Install Dependencies run: flutter packages get - name: Format diff --git a/lib/src/chart.dart b/lib/src/chart.dart index 36dceec..caf17b2 100644 --- a/lib/src/chart.dart +++ b/lib/src/chart.dart @@ -127,10 +127,17 @@ class ChartState extends State _addScrollNotifier(); - final renderEndTime = widget.data.isNotEmpty - ? widget.data.first.end.dateWithoutTime() - : DateTime.now(); - processData(widget, renderEndTime); + processData(widget, _getFirstItemDate()); + } + + @override + void didUpdateWidget(covariant Chart oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.data != widget.data || + oldWidget.data.length != widget.data.length) { + processData(widget, _getFirstItemDate()); + } } @override @@ -146,6 +153,12 @@ class ChartState extends State super.dispose(); } + DateTime _getFirstItemDate({Duration addition = Duration.zero}) { + return widget.data.isEmpty + ? DateTime.now() + : widget.data.first.end.dateWithoutTime().add(addition); + } + void _addScrollNotifier() { WidgetsBinding.instance.addPostFrameCallback((_) { final minDifference = _blockWidth!; @@ -329,11 +342,8 @@ class ChartState extends State final scrollPositionDuration = Duration( days: -blockIndex + (needsToAdaptScrollPosition ? 1 : 0), ); - final renderEndTime = widget.data.isNotEmpty - ? widget.data.first.end.dateWithoutTime().add(scrollPositionDuration) - : DateTime.now(); - processData(widget, renderEndTime); + processData(widget, _getFirstItemDate(addition: scrollPositionDuration)); if (topHour == beforeTopHour && bottomHour == beforeBottomHour) return; diff --git a/lib/src/components/utils/time_data_processor.dart b/lib/src/components/utils/time_data_processor.dart index 03249f8..1f0ebee 100644 --- a/lib/src/components/utils/time_data_processor.dart +++ b/lib/src/components/utils/time_data_processor.dart @@ -34,7 +34,7 @@ mixin TimeDataProcessor { /// /// [bottomHour]와 24시 사이에 있는 데이터들을 다음날로 넘어가 있다. List get processedData => _processedData; - final List _processedData = []; + List _processedData = []; final List _inRangeDataList = []; @@ -59,8 +59,7 @@ mixin TimeDataProcessor { return; } - _processedData.clear(); - _processedData.addAll(List.from(chart.data)); + _processedData = [...chart.data]; _firstDataHasChanged = false; _countDays(chart.data); diff --git a/test/chart_test.dart b/test/chart_test.dart new file mode 100644 index 0000000..32fa03a --- /dev/null +++ b/test/chart_test.dart @@ -0,0 +1,92 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:time_chart/src/chart.dart'; +import 'package:time_chart/time_chart.dart'; + +import 'data_pool.dart'; + +void main() { + testWidgets('Chart updates when the data is replaced', (tester) async { + List data = data1; + + await tester.pumpWidget( + MaterialApp( + home: StatefulBuilder( + builder: (context, setState) { + return Column( + children: [ + TimeChart(data: data), + TextButton( + onPressed: () { + setState(() { + data = data2; + }); + }, + child: const Text('Update'), + ), + ], + ); + }, + ), + ), + ); + + await expectLater( + find.byType(Chart), + matchesGoldenFile('golden/data1_chart.png'), + skip: !Platform.isMacOS, + ); + + await tester.tap(find.text('Update')); + await tester.pump(const Duration(milliseconds: 300)); + + await expectLater( + find.byType(Chart), + matchesGoldenFile('golden/data2_chart.png'), + skip: !Platform.isMacOS, + ); + }); + + testWidgets('Chart updates when the data length is changed', (tester) async { + List data = data1; + + await tester.pumpWidget( + MaterialApp( + home: StatefulBuilder( + builder: (context, setState) { + return Column( + children: [ + TimeChart(data: data), + TextButton( + onPressed: () { + setState(() { + data = data3; + }); + }, + child: const Text('Update'), + ), + ], + ); + }, + ), + ), + ); + + await expectLater( + find.byType(Chart), + matchesGoldenFile('golden/data1_chart.png'), + skip: !Platform.isMacOS, + ); + + await tester.tap(find.text('Update')); + await tester.pump(const Duration(milliseconds: 300)); + + await expectLater( + find.byType(Chart), + matchesGoldenFile('golden/data3_chart.png'), + skip: !Platform.isMacOS, + ); + }); +} diff --git a/test/data_pool.dart b/test/data_pool.dart new file mode 100644 index 0000000..b888d79 --- /dev/null +++ b/test/data_pool.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; + +final List data1 = [ + DateTimeRange( + start: DateTime(2021, 10, 22, 23, 55), + end: DateTime(2021, 10, 23, 8, 0), + ), + DateTimeRange( + start: DateTime(2021, 10, 21, 21, 15), + end: DateTime(2021, 10, 22, 6, 10), + ), +]; + +final List data2 = [ + DateTimeRange( + start: DateTime(2021, 2, 2, 18, 4), + end: DateTime(2021, 2, 3, 8, 0), + ), + DateTimeRange( + start: DateTime(2021, 2, 1, 15, 3), + end: DateTime(2021, 2, 2, 5, 4), + ), +]; + +final List data3 = [ + DateTimeRange( + start: DateTime(2021, 2, 3, 20, 42), + end: DateTime(2021, 2, 4, 12, 10), + ), + DateTimeRange( + start: DateTime(2021, 2, 2, 18, 4), + end: DateTime(2021, 2, 3, 8, 0), + ), + DateTimeRange( + start: DateTime(2021, 2, 1, 15, 3), + end: DateTime(2021, 2, 2, 5, 4), + ), +]; diff --git a/test/golden/data1_chart.png b/test/golden/data1_chart.png new file mode 100644 index 0000000..f700b28 Binary files /dev/null and b/test/golden/data1_chart.png differ diff --git a/test/golden/data2_chart.png b/test/golden/data2_chart.png new file mode 100644 index 0000000..5b02240 Binary files /dev/null and b/test/golden/data2_chart.png differ diff --git a/test/golden/data3_chart.png b/test/golden/data3_chart.png new file mode 100644 index 0000000..75084fa Binary files /dev/null and b/test/golden/data3_chart.png differ