diff --git a/.github/workflows/pr-review.yml b/.github/workflows/pr-review.yml new file mode 100644 index 0000000..b395129 --- /dev/null +++ b/.github/workflows/pr-review.yml @@ -0,0 +1,21 @@ +name: PR review/test + +on: + pull_request: + +jobs: + analyze: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v3 + - name: Setup Flutter + uses: subosito/flutter-action@v2 + - name: Install dependencies + run: | + flutter pub get + - uses: invertase/github-action-dart-analyzer@v1 + - name: Run tests + run: | + flutter test diff --git a/lib/view/board.dart b/lib/view/board.dart index 9de90ac..dfab25d 100644 --- a/lib/view/board.dart +++ b/lib/view/board.dart @@ -12,7 +12,9 @@ class Board extends ConsumerWidget { return Padding( padding: const EdgeInsets.all(16), - child: Column( + child: SingleChildScrollView(child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.all(16), @@ -64,7 +66,7 @@ class Board extends ConsumerWidget { ), ), ], - ), + )), ); } diff --git a/test/place_mark_test.dart b/test/place_mark_test.dart new file mode 100644 index 0000000..57d7499 --- /dev/null +++ b/test/place_mark_test.dart @@ -0,0 +1,139 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:tic_tac_toe_handson/provider/tic_tac_toe_provider.dart'; + +void main() { + late TicTacToeProvider target; + + setUp(() { + final container = ProviderContainer(); + target = container.read(ticTacToeProvider.notifier); + }); + + test("placeMark test - row: 0, col: 0", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(0, 0); + expect(target.state.board, [ + ['X', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("placeMark test - row: 0, col: 1", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(0, 1); + expect(target.state.board, [ + ['', 'X', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("placeMark test - row: 0, col: 2", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(0, 2); + expect(target.state.board, [ + ['', '', 'X'], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("placeMark test - row: 1, col: 0", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(1, 0); + expect(target.state.board, [ + ['', '', ''], + ['X', '', ''], + ['', '', ''], + ]); + }); + + test("placeMark test - row: 1, col: 1", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(1, 1); + expect(target.state.board, [ + ['', '', ''], + ['', 'X', ''], + ['', '', ''], + ]); + }); + + test("placeMark test - row: 1, col: 2", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(1, 2); + expect(target.state.board, [ + ['', '', ''], + ['', '', 'X'], + ['', '', ''], + ]); + }); + + test("placeMark test - row: 2, col: 0", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(2, 0); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['X', '', ''], + ]); + }); + + test("placeMark test - row: 2, col: 1", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(2, 1); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', 'X', ''], + ]); + }); + + test("placeMark test - row: 2, col: 2", () { + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.placeMark(2, 2); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', 'X'], + ]); + }); +} diff --git a/test/reset_board_test.dart b/test/reset_board_test.dart new file mode 100644 index 0000000..463152f --- /dev/null +++ b/test/reset_board_test.dart @@ -0,0 +1,148 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:tic_tac_toe_handson/provider/tic_tac_toe_provider.dart'; + +void main() { + late TicTacToeProvider target; + + setUp(() { + final container = ProviderContainer(); + target = container.read(ticTacToeProvider.notifier); + }); + + test("resetBoard test - row: 0, col: 0", () { + target.placeMark(0, 0); + expect(target.state.board, [ + ['X', '', ''], + ['', '', ''], + ['', '', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 0, col: 1", () { + target.placeMark(0, 1); + expect(target.state.board, [ + ['', 'X', ''], + ['', '', ''], + ['', '', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 0, col: 2", () { + target.placeMark(0, 2); + expect(target.state.board, [ + ['', '', 'X'], + ['', '', ''], + ['', '', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 1, col: 0", () { + target.placeMark(1, 0); + expect(target.state.board, [ + ['', '', ''], + ['X', '', ''], + ['', '', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 1, col: 1", () { + target.placeMark(1, 1); + expect(target.state.board, [ + ['', '', ''], + ['', 'X', ''], + ['', '', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 1, col: 2", () { + target.placeMark(1, 2); + expect(target.state.board, [ + ['', '', ''], + ['', '', 'X'], + ['', '', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 2, col: 0", () { + target.placeMark(2, 0); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['X', '', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 2, col: 1", () { + target.placeMark(2, 1); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', 'X', ''], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); + + test("resetBoard test - row: 2, col: 2", () { + target.placeMark(2, 2); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', 'X'], + ]); + target.resetBoard(); + expect(target.state.board, [ + ['', '', ''], + ['', '', ''], + ['', '', ''], + ]); + }); +} diff --git a/test/widget_test.dart b/test/widget_test.dart index f013804..6757d0e 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -5,26 +5,17 @@ // 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/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:tic_tac_toe_handson/main.dart'; void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + testWidgets('Title rendering test', (WidgetTester tester) async { + await tester.pumpWidget(const ProviderScope( + child: MyApp(), + )); - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); + expect(find.text('FlutterKaigi 2023 - TicTacToe'), findsOneWidget); }); }