diff --git a/.drone.yml b/.drone.yml index 5de1843..56565bb 100644 --- a/.drone.yml +++ b/.drone.yml @@ -60,16 +60,35 @@ depends_on: workspace: path: "/app" + +environment: + PUB_CACHE: /app/.pub_cache + platform: os: linux arch: amd64 steps: + - name: load_packages + pull: always + image: jonasfranz/flutter:2.10.1 + commands: + - flutter packages get +####### BENCHMARKS + - name: run_benchmarks + pull: always + image: jonasfranz/flutter:2.10.1 + depends_on: + - load_packages + commands: + - flutter test --plain-name=Efficiency -r expanded > benchmarks.txt +####### METRICS - name: generate_metrics pull: always image: jonasfranz/flutter:2.10.1 + depends_on: + - load_packages commands: - - flutter pub get - flutter pub run dart_code_metrics:metrics analyze lib -r html - name: convert_to_latex pull: always @@ -78,25 +97,25 @@ steps: - generate_metrics commands: - pandoc -s metrics/index.html -o metrics.tex - - name: pull_thesis + +###### PUBLISHING + - name: pull_and_prepare_thesis_repo image: docker:git - commands: - - git clone https://git.jonasfranz.software/KoSI/thesis.git - - mkdir -p thesis/results/${DRONE_REPO_BRANCH} - - name: prepare_git depends_on: - convert_to_latex - - pull_thesis - image: docker:git + - run_benchmarks commands: + - git clone https://git.jonasfranz.software/KoSI/thesis.git + - mkdir -p thesis/results/${DRONE_REPO_BRANCH} - cp metrics.tex thesis/results/${DRONE_REPO_BRANCH}/ + - cp benchmarks.txt thesis/results/${DRONE_REPO_BRANCH}/ - cd thesis - git add results/ - git status - - pwd + - name: push_matrix depends_on: - - prepare_git + - pull_and_prepare_thesis_repo image: appleboy/drone-git-push settings: ssh_key: diff --git a/lib/app.dart b/lib/app.dart index 5235705..c755039 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -2,10 +2,13 @@ import 'package:flutter/material.dart'; import 'package:thesis_shop/route_key.dart'; import 'package:thesis_shop/screens/cart/cart_screen.dart'; import 'package:thesis_shop/screens/product_list/product_list_screen.dart'; +import 'package:thesis_shop/service/product_service.dart'; import 'package:thesis_shop/utils/map_keys_extension.dart'; class ThesisShopApp extends StatelessWidget { - const ThesisShopApp({Key? key}) : super(key: key); + final ProductService productService; + const ThesisShopApp({Key? key, required this.productService}) + : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/benchmark_counter.dart b/lib/benchmark_counter.dart new file mode 100644 index 0000000..4c76289 --- /dev/null +++ b/lib/benchmark_counter.dart @@ -0,0 +1,4 @@ +class BenchmarkCounters { + static var cartButton = 0; + static var userSwitch = 0; +} diff --git a/lib/main.dart b/lib/main.dart index b3ae2b3..dbeffa6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; import 'package:thesis_shop/app.dart'; +import 'package:thesis_shop/service/product_service.dart'; void main() { - runApp(const ThesisShopApp()); + runApp(ThesisShopApp( + productService: ProductService(), + )); } diff --git a/lib/screens/product_list/cart_button.dart b/lib/screens/product_list/cart_button.dart index 0958bcb..5256e5e 100644 --- a/lib/screens/product_list/cart_button.dart +++ b/lib/screens/product_list/cart_button.dart @@ -1,11 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:thesis_shop/benchmark_counter.dart'; import 'package:thesis_shop/route_key.dart'; class CartButton extends StatelessWidget { - const CartButton({Key? key}) : super(key: key); + const CartButton() : super(key: const Key('cart_button')); @override Widget build(BuildContext context) { + BenchmarkCounters.cartButton++; return ElevatedButton.icon( onPressed: () => Navigator.of(context).pushRouteKey(RouteKey.cart), icon: const Icon(Icons.shopping_basket), diff --git a/lib/widgets/user_switch.dart b/lib/widgets/user_switch.dart index 6f22562..63107e7 100644 --- a/lib/widgets/user_switch.dart +++ b/lib/widgets/user_switch.dart @@ -1,16 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:thesis_shop/benchmark_counter.dart'; class UserSwitch extends StatelessWidget { final bool isOn; final ValueChanged onChanged; const UserSwitch({ - Key? key, required this.isOn, required this.onChanged, - }) : super(key: key); + }) : super(key: const Key('user_switch')); @override Widget build(BuildContext context) { + BenchmarkCounters.userSwitch++; return Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/test/efficiency_bechmark_test.dart b/test/efficiency_bechmark_test.dart new file mode 100644 index 0000000..8c268aa --- /dev/null +++ b/test/efficiency_bechmark_test.dart @@ -0,0 +1,49 @@ +// ignore_for_file: avoid_print + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:thesis_shop/app.dart'; +import 'package:thesis_shop/benchmark_counter.dart'; + +import 'product_service_mock.dart'; + +void main() { + testWidgets('Efficiency Test', (WidgetTester tester) async { + await tester + .pumpWidget(ThesisShopApp(productService: MockedProductService())); + await tester.pumpAndSettle(const Duration(seconds: 2)); + final addIcons = find.byIcon(Icons.add); + expect(addIcons, findsWidgets); + // click at the first and last one 2 times + await tester.tap(addIcons.first); + await tester.pumpAndSettle(); + await tester.tap(addIcons.first); + await tester.pumpAndSettle(); + await tester.tap(addIcons.last); + await tester.pumpAndSettle(); + await tester.tap(addIcons.last); + await tester.pumpAndSettle(); + + // click on the first remove icon + final removeIcons = find.byIcon(Icons.remove); + await tester.tap(removeIcons.first); + await tester.pumpAndSettle(); + + // toggle sign in button two times + final switchButton = find.byKey(Key('user_switch')); + await tester.tap(switchButton); + await tester.pumpAndSettle(); + await tester.tap(switchButton); + await tester.pumpAndSettle(); + + // go to cart + final cartButton = find.byKey(Key('cart_button')); + await tester.tap(cartButton); + await tester.pumpAndSettle(); + final header = find.text('Warenkorb'); + expect(header, findsOneWidget); + + print("cartButton: ${BenchmarkCounters.cartButton}"); + print("userSwitch: ${BenchmarkCounters.userSwitch}"); + }); +} diff --git a/test/product_service_mock.dart b/test/product_service_mock.dart new file mode 100644 index 0000000..d3dbb63 --- /dev/null +++ b/test/product_service_mock.dart @@ -0,0 +1,17 @@ +import 'package:thesis_shop/models/product.dart'; +import 'package:thesis_shop/service/product_service.dart'; + +class MockedProductService implements ProductService { + @override + Future> fetchProducts() async { + return const [ + Product(title: 'Bananen', price: 3), + Product(title: 'Äpfel', price: 2), + Product(title: 'Birnen', price: 2.5), + Product(title: 'Kirschen', price: 1.2), + ]; + } + + @override + String get url => throw UnimplementedError(); +} diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index a11e8a6..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,16 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter_test/flutter_test.dart'; -import 'package:thesis_shop/app.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const ThesisShopApp()); - }); -}