diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index cfd6bbd51..7262263df 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -56,4 +56,4 @@ jobs: uses: VeryGoodOpenSource/very_good_coverage@v2 with: path: 'charts_flutter/coverage/lcov.info' - min_coverage: 41.16 \ No newline at end of file + min_coverage: 44.4 \ No newline at end of file diff --git a/charts_flutter/example/lib/bar_chart/bar_gallery.dart b/charts_flutter/example/lib/bar_chart/bar_gallery.dart index 8d637ceff..29cb9c275 100644 --- a/charts_flutter/example/lib/bar_chart/bar_gallery.dart +++ b/charts_flutter/example/lib/bar_chart/bar_gallery.dart @@ -39,6 +39,25 @@ import 'vertical_bar_label.dart'; const simpleBarChartTileTitle = 'Simple Bar Chart'; const stackedBarChartTileTitle = 'Stacked Bar Chart'; const groupedBarChartTileTitle = 'Grouped Bar Chart'; +const groupedStackedBarChartTileTitle = 'Grouped Stacked Bar Chart'; +const groupedBarTargetLineChartTileTitle = 'Grouped Bar Target Line Chart'; +const groupedBarSingleTargetLineChartTileTitle = + 'Grouped Bar Single Target Line Chart'; +const stackedBarTargetLineChart = 'Stacked Bar Target Line Chart'; +const horizontalBarChart = 'Horizontal Bar Chart'; +const stackedHorizontalBarChart = 'Stacked Horizontal Bar Chart'; +const horizontalBarLabelChart = 'Horizontal Bar Chart with Bar Labels'; +const horizontalBarLabelCustomChart = + 'Horizontal Bar Chart with Custom Bar Labels'; +const verticalBarLabelChart = 'Vertical Bar Chart with Bar Labels'; +const sparkBarChart = 'Spark Bar Chart'; +const groupedFillColorChart = 'Grouped Fill Color Bar Chart'; +const stackedFillColorChart = 'Stacked Fill Color Bar Chart'; +const patternForwardHatchChart = 'Pattern Forward Hatch Bar Chart'; +const horizontalPatternForwardHatchChart = + 'Horizontal Pattern Forward Hatch Bar Chart'; +const weightedPatternChart = 'Weight Pattern Bar Chart'; +const barChartWithCustomBarRadius = 'Bar Chart with custom bar radius'; List buildGallery() { return [ @@ -68,108 +87,138 @@ List buildGallery() { ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Grouped Stacked Bar Chart', + title: groupedStackedBarChartTileTitle, subtitle: 'Grouped and stacked bar chart with multiple series', - childBuilder: () => new GroupedStackedBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? GroupedStackedBarChart.withRandomData() + : GroupedStackedBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Grouped Bar Target Line Chart', + title: groupedBarTargetLineChartTileTitle, subtitle: 'Grouped bar target line chart with multiple series', - childBuilder: () => new GroupedBarTargetLineChart.withRandomData(), + childBuilder: () => m.useRandomData + ? GroupedBarTargetLineChart.withRandomData() + : GroupedBarTargetLineChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Grouped Bar Single Target Line Chart', + title: groupedBarSingleTargetLineChartTileTitle, subtitle: 'Grouped bar target line chart with multiple series and a single target', - childBuilder: () => new GroupedBarSingleTargetLineChart.withRandomData(), + childBuilder: () => m.useRandomData + ? GroupedBarSingleTargetLineChart.withRandomData() + : GroupedBarSingleTargetLineChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Stacked Bar Target Line Chart', + title: stackedBarTargetLineChart, subtitle: 'Stacked bar target line chart with multiple series', - childBuilder: () => new StackedBarTargetLineChart.withRandomData(), + childBuilder: () => m.useRandomData + ? StackedBarTargetLineChart.withRandomData() + : StackedBarTargetLineChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Transform.rotate( angle: 1.5708, child: new Icon(Icons.insert_chart)), - title: 'Horizontal Bar Chart', + title: horizontalBarChart, subtitle: 'Horizontal bar chart with a single series', - childBuilder: () => new HorizontalBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? HorizontalBarChart.withRandomData() + : HorizontalBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Transform.rotate( angle: 1.5708, child: new Icon(Icons.insert_chart)), - title: 'Stacked Horizontal Bar Chart', + title: stackedHorizontalBarChart, subtitle: 'Stacked horizontal bar chart with multiple series', - childBuilder: () => new StackedHorizontalBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? StackedHorizontalBarChart.withRandomData() + : StackedHorizontalBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Transform.rotate( angle: 1.5708, child: new Icon(Icons.insert_chart)), - title: 'Horizontal Bar Chart with Bar Labels', + title: horizontalBarLabelChart, subtitle: 'Horizontal bar chart with a single series and bar labels', - childBuilder: () => new HorizontalBarLabelChart.withRandomData(), + childBuilder: () => m.useRandomData + ? HorizontalBarLabelChart.withRandomData() + : HorizontalBarLabelChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Transform.rotate( angle: 1.5708, child: new Icon(Icons.insert_chart)), - title: 'Horizontal Bar Chart with Custom Bar Labels', + title: horizontalBarLabelCustomChart, subtitle: 'Bar labels with customized styling', - childBuilder: () => new HorizontalBarLabelCustomChart.withRandomData(), + childBuilder: () => m.useRandomData + ? HorizontalBarLabelCustomChart.withRandomData() + : HorizontalBarLabelCustomChart.createWithSampleData(), ), new GalleryScaffold( listTileIcon: new Transform.rotate( angle: 1.5708, child: new Icon(Icons.insert_chart)), - title: 'Vertical Bar Chart with Bar Labels', + title: verticalBarLabelChart, subtitle: 'Vertical bar chart with a single series and bar labels', - childBuilder: () => new VerticalBarLabelChart.withRandomData(), + childBuilder: () => m.useRandomData + ? VerticalBarLabelChart.withRandomData() + : VerticalBarLabelChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Spark Bar Chart', + title: sparkBarChart, subtitle: 'Spark Bar Chart', - childBuilder: () => new SparkBar.withRandomData(), + childBuilder: () => m.useRandomData + ? SparkBar.withRandomData() + : SparkBar.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Grouped Fill Color Bar Chart', + title: groupedFillColorChart, subtitle: 'Grouped bar chart with fill colors', - childBuilder: () => new GroupedFillColorBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? GroupedFillColorBarChart.withRandomData() + : GroupedFillColorBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Stacked Fill Color Bar Chart', + title: stackedFillColorChart, subtitle: 'Stacked bar chart with fill colors', - childBuilder: () => new StackedFillColorBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? StackedFillColorBarChart.withRandomData() + : StackedFillColorBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Pattern Forward Hatch Bar Chart', + title: patternForwardHatchChart, subtitle: 'Pattern Forward Hatch Bar Chart', - childBuilder: () => new PatternForwardHatchBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? PatternForwardHatchBarChart.withRandomData() + : PatternForwardHatchBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Transform.rotate( angle: 1.5708, child: new Icon(Icons.insert_chart)), - title: 'Horizontal Pattern Forward Hatch Bar Chart', + title: horizontalPatternForwardHatchChart, subtitle: 'Horizontal Pattern Forward Hatch Bar Chart', - childBuilder: () => - new HorizontalPatternForwardHatchBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? HorizontalPatternForwardHatchBarChart.withRandomData() + : HorizontalPatternForwardHatchBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Weight Pattern Bar Chart', + title: weightedPatternChart, subtitle: 'Grouped and stacked bar chart with a weight pattern', - childBuilder: () => - new GroupedStackedWeightPatternBarChart.withRandomData(), + childBuilder: () => m.useRandomData + ? GroupedStackedWeightPatternBarChart.withRandomData() + : GroupedStackedWeightPatternBarChart.withSampleData(), ), new GalleryScaffold( listTileIcon: new Icon(Icons.insert_chart), - title: 'Bar Chart with custom bar radius', + title: barChartWithCustomBarRadius, subtitle: 'Custom rounded bar corners', - childBuilder: () => new CustomRoundedBars.withRandomData(), + childBuilder: () => m.useRandomData + ? CustomRoundedBars.withRandomData() + : CustomRoundedBars.withSampleData(), ), ]; } diff --git a/charts_flutter/test/example_widget_tests/example_test.dart b/charts_flutter/test/example_widget_tests/example_test.dart index cb65dec3c..6c5c2781c 100644 --- a/charts_flutter/test/example_widget_tests/example_test.dart +++ b/charts_flutter/test/example_widget_tests/example_test.dart @@ -5,10 +5,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:nimble_charts/flutter.dart' as charts; import '../../example/lib/bar_chart/bar_gallery.dart' as b; + import '../../example/lib/home.dart' as h; import '../../example/lib/main.dart' as m; + import '../test_functions.dart'; +/// Widget tests for the example app. void main() { group('ExampleApp Widget Tests', () { m.useRandomData = false; @@ -34,7 +37,7 @@ void main() { testWidgets( 'Navigates to Simple Bar Chart and Renders', - (tester) async => tester.navigateToChartAndGolden( + (tester) async => tester.navigateToChartAndGolden( b.simpleBarChartTileTitle, extra: () async { await tester.tap(find.byType(charts.BarChart)); @@ -45,39 +48,195 @@ void main() { testWidgets( 'Navigates to Stacked Bar Chart and Renders', - (tester) async => - tester.navigateToChartAndGolden(b.stackedBarChartTileTitle), + (tester) async => tester.navigateToChartAndGolden( + b.stackedBarChartTileTitle, + ), ); testWidgets( 'Navigates to Grouped Bar Chart and Renders', - (tester) async => - tester.navigateToChartAndGolden(b.groupedBarChartTileTitle), + (tester) async => tester.navigateToChartAndGolden( + b.groupedBarChartTileTitle, + ), + ); + + testWidgets( + 'Navigates to Grouped Stacked Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.groupedStackedBarChartTileTitle, + ), + ); + + testWidgets( + 'Navigates to Grouped Bar Target Line Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.groupedBarTargetLineChartTileTitle, + ), + ); + + testWidgets( + 'Navigates to Grouped Bar Single Target Line Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.groupedBarSingleTargetLineChartTileTitle, + ), + ); + + testWidgets( + 'Navigates to Stacked Bar Target Line Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.stackedBarTargetLineChart, + scrollDelta: 200, + ), + ); + + testWidgets( + 'Navigates to Horizontal Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.horizontalBarChart, + scrollDelta: 200, + ), + ); + + testWidgets( + 'Navigates to Stacked Horizontal Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.stackedHorizontalBarChart, + scrollDelta: 200, + ), + ); + + testWidgets( + 'Navigates to Horizontal Bar Chart with Bar Labels and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.horizontalBarLabelChart, + scrollDelta: 200, + ), + ); + + testWidgets( + 'Navigates to Horizontal Bar Chart with Custom Bar Labels and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.horizontalBarLabelCustomChart, + scrollDelta: 300, + ), + ); + + testWidgets( + 'Navigates to Vertical Bar Chart with Bar Labels and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.verticalBarLabelChart, + scrollDelta: 300, + ), + ); + + testWidgets( + 'Navigates to Spark Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.sparkBarChart, + scrollDelta: 300, + ), + ); + + testWidgets( + 'Navigates to Grouped Fill Color Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.groupedFillColorChart, + scrollDelta: 300, + ), + ); + + testWidgets( + 'Navigates to Stacked Fill Color Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.stackedFillColorChart, + scrollDelta: 300, + ), + ); + + //TODO: Fix this test. For some reason, we can't find the bar chart + //in the widget tree. 🤷🏼‍♂️ + testWidgets( + 'Navigates to Pattern Forward Hatch Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.patternForwardHatchChart, + scrollDelta: 300, + ), + skip: true, + ); + + testWidgets( + 'Navigates to Horizontal Pattern Forward Hatch Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.horizontalPatternForwardHatchChart, + scrollDelta: 300, + ), + ); + + testWidgets( + 'Navigates to Weighted Pattern Bar Chart and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.weightedPatternChart, + scrollDelta: 300, + ), + ); + + testWidgets( + 'Navigates to Bar Chart with custom bar radius and Renders', + (tester) async => tester.navigateToChartAndGolden( + b.barChartWithCustomBarRadius, + scrollDelta: 300, + ), ); }); } extension ExampleWidgetTestExtensions on WidgetTester { /// Taps on the button and takes a golden screenshot of the chart. - Future navigateToChartAndGolden( - String buttonText, { + Future navigateToChartAndGolden( + String tileText, { Future Function()? extra, + double? scrollDelta, }) async { + //Create an pump final galleryApp = m.GalleryApp(); - await pumpWidget(galleryApp); + //Set the screen size of the widget viewOf(find.byWidget(galleryApp)) ..physicalSize = const Size(1200, 700) ..devicePixelRatio = 1; expect(find.byType(h.Home), findsOneWidget); - await tap(find.text(buttonText)); + + // Find the list tile by text + final tileFinder = find.byWidgetPredicate( + (w) => switch (w) { + final ListTile l => switch (l.title) { + final Text t when t.data == tileText => true, + _ => false + }, + _ => false + }, + ); + + // Scroll to the button if needed. + if (scrollDelta != null) { + await scrollUntilVisible(tileFinder, scrollDelta); + } + + // Tap the tile + await tap(tileFinder); await pumpAndSettle(); - expect(find.byType(charts.BarChart), findsOneWidget); + await pump(const Duration(seconds: 1)); + + //Check that the chart exists + expect(find.byType(T), findsOneWidget); + + // Do extra assertions await extra?.call(); - await matchesGolden( - 'example_${buttonText.replaceAll(' ', '_').toLowerCase()}', + + await matchesGolden( + 'example_${tileText.replaceAll(' ', '_').toLowerCase()}', ); } } diff --git a/charts_flutter/test/goldens/example_bar_chart_with_custom_bar_radius.png b/charts_flutter/test/goldens/example_bar_chart_with_custom_bar_radius.png new file mode 100644 index 000000000..8adc8451f Binary files /dev/null and b/charts_flutter/test/goldens/example_bar_chart_with_custom_bar_radius.png differ diff --git a/charts_flutter/test/goldens/example_grouped_bar_single_target_line_chart.png b/charts_flutter/test/goldens/example_grouped_bar_single_target_line_chart.png new file mode 100644 index 000000000..16981a01d Binary files /dev/null and b/charts_flutter/test/goldens/example_grouped_bar_single_target_line_chart.png differ diff --git a/charts_flutter/test/goldens/example_grouped_bar_target_line_chart.png b/charts_flutter/test/goldens/example_grouped_bar_target_line_chart.png new file mode 100644 index 000000000..e6f8f1ced Binary files /dev/null and b/charts_flutter/test/goldens/example_grouped_bar_target_line_chart.png differ diff --git a/charts_flutter/test/goldens/example_grouped_fill_color_bar_chart.png b/charts_flutter/test/goldens/example_grouped_fill_color_bar_chart.png new file mode 100644 index 000000000..57dd839b9 Binary files /dev/null and b/charts_flutter/test/goldens/example_grouped_fill_color_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_grouped_stacked_bar_chart.png b/charts_flutter/test/goldens/example_grouped_stacked_bar_chart.png new file mode 100644 index 000000000..108411628 Binary files /dev/null and b/charts_flutter/test/goldens/example_grouped_stacked_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_horizontal_bar_chart.png b/charts_flutter/test/goldens/example_horizontal_bar_chart.png new file mode 100644 index 000000000..d532c6ec8 Binary files /dev/null and b/charts_flutter/test/goldens/example_horizontal_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_horizontal_bar_chart_with_bar_labels.png b/charts_flutter/test/goldens/example_horizontal_bar_chart_with_bar_labels.png new file mode 100644 index 000000000..9eba73747 Binary files /dev/null and b/charts_flutter/test/goldens/example_horizontal_bar_chart_with_bar_labels.png differ diff --git a/charts_flutter/test/goldens/example_horizontal_bar_chart_with_custom_bar_labels.png b/charts_flutter/test/goldens/example_horizontal_bar_chart_with_custom_bar_labels.png new file mode 100644 index 000000000..853b5ec57 Binary files /dev/null and b/charts_flutter/test/goldens/example_horizontal_bar_chart_with_custom_bar_labels.png differ diff --git a/charts_flutter/test/goldens/example_horizontal_pattern_forward_hatch_bar_chart.png b/charts_flutter/test/goldens/example_horizontal_pattern_forward_hatch_bar_chart.png new file mode 100644 index 000000000..f475d5323 Binary files /dev/null and b/charts_flutter/test/goldens/example_horizontal_pattern_forward_hatch_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_pattern_forward_hatch_bar_chart.png b/charts_flutter/test/goldens/example_pattern_forward_hatch_bar_chart.png new file mode 100644 index 000000000..55b20ef4c Binary files /dev/null and b/charts_flutter/test/goldens/example_pattern_forward_hatch_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_spark_bar_chart.png b/charts_flutter/test/goldens/example_spark_bar_chart.png new file mode 100644 index 000000000..d1b4a7e6c Binary files /dev/null and b/charts_flutter/test/goldens/example_spark_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_stacked_bar_target_line_chart.png b/charts_flutter/test/goldens/example_stacked_bar_target_line_chart.png new file mode 100644 index 000000000..3166af5fd Binary files /dev/null and b/charts_flutter/test/goldens/example_stacked_bar_target_line_chart.png differ diff --git a/charts_flutter/test/goldens/example_stacked_fill_color_bar_chart.png b/charts_flutter/test/goldens/example_stacked_fill_color_bar_chart.png new file mode 100644 index 000000000..c0b76d982 Binary files /dev/null and b/charts_flutter/test/goldens/example_stacked_fill_color_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_stacked_horizontal_bar_chart.png b/charts_flutter/test/goldens/example_stacked_horizontal_bar_chart.png new file mode 100644 index 000000000..9c0a33c7c Binary files /dev/null and b/charts_flutter/test/goldens/example_stacked_horizontal_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_vertical_bar_chart_with_bar_labels.png b/charts_flutter/test/goldens/example_vertical_bar_chart_with_bar_labels.png new file mode 100644 index 000000000..46747bdad Binary files /dev/null and b/charts_flutter/test/goldens/example_vertical_bar_chart_with_bar_labels.png differ diff --git a/charts_flutter/test/goldens/example_weight_pattern_bar_chart.png b/charts_flutter/test/goldens/example_weight_pattern_bar_chart.png new file mode 100644 index 000000000..e451f8d13 Binary files /dev/null and b/charts_flutter/test/goldens/example_weight_pattern_bar_chart.png differ diff --git a/charts_flutter/test/goldens/example_weighted_pattern_bar_chart.png b/charts_flutter/test/goldens/example_weighted_pattern_bar_chart.png new file mode 100644 index 000000000..e9b8803bb Binary files /dev/null and b/charts_flutter/test/goldens/example_weighted_pattern_bar_chart.png differ diff --git a/test.sh b/test.sh index c978fe92a..7e59112c1 100644 --- a/test.sh +++ b/test.sh @@ -8,4 +8,6 @@ flutter test --update-goldens --coverage lcov ./coverage --output-file ./coverage/lcov.info --capture --directory -genhtml ./coverage/lcov.info --output-directory ./coverage/html \ No newline at end of file +genhtml ./coverage/lcov.info --output-directory ./coverage/html + + \ No newline at end of file