Skip to content

Commit

Permalink
test: Fix some test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
calcitem committed Nov 28, 2024
1 parent 9a3af37 commit a84f528
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 72 deletions.
9 changes: 7 additions & 2 deletions src/ui/flutter_app/lib/shared/services/system_ui_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
part of 'package:sanmill/main.dart';

/// Initializes the given [SystemChrome] ui
Future<void> _initUI() async {
Future<void> initializeUI(bool isFullScreen) async {
// TODO: [Leptopoda] Use layoutBuilder to add adaptiveness
if (DB().displaySettings.isFullScreen) {
if (isFullScreen) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: <SystemUiOverlay>[]);
} else {
Expand All @@ -37,6 +37,11 @@ Future<void> _initUI() async {
Constants.isAndroid10Plus = await isAndroidAtLeastVersion10();
}

Future<void> _initUI() async {
final bool isFullScreen = DB().displaySettings.isFullScreen;
await initializeUI(isFullScreen);
}

void _initializeScreenOrientation(BuildContext context) {
if (!isTablet(context)) {
SystemChrome.setPreferredOrientations(
Expand Down
58 changes: 41 additions & 17 deletions src/ui/flutter_app/test/game/game_controller_test.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
// This file is part of Sanmill.
// Copyright (C) 2019-2024 The Sanmill developers (see AUTHORS file)
//
// Sanmill is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Sanmill is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sanmill/game_page/services/mill.dart';
import 'package:sanmill/shared/database/database.dart';
Expand All @@ -23,6 +8,45 @@ import '../helpers/mocks/mock_database.dart';
import '../helpers/test_mills.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();

// Define the MethodChannel to be mocked
const MethodChannel engineChannel =
MethodChannel("com.calcitem.sanmill/engine");

setUp(() {
// Use the new API to set up mock handlers for MethodChannel
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(engineChannel, (MethodCall methodCall) async {
switch (methodCall.method) {
case 'send':
// Handle the 'send' method
return null; // Return a success response
case 'shutdown':
// Handle the 'shutdown' method
return null; // Return a success response
case 'startup':
// Handle the 'startup' method
return null; // Return a success response
case 'read':
// Simulate a response for the 'read' method
return 'bestmove d2';
case 'isThinking':
// Simulate the 'isThinking' method response
return false;
default:
// For unhandled methods, return null
return null;
}
});
});

tearDown(() {
// Use the new API to remove the mock handler
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(engineChannel, null);
});

group("MillController", () {
test("New game should have the same GameMode", () async {
const GameMode gameMode = GameMode.humanVsAi;
Expand All @@ -40,7 +64,7 @@ void main() {
});

test("Import should clear the focus", () async {
// initialize the test
// Initialize the test
DB.instance = MockDB();
SoundManager.instance = MockAudios();
final GameController controller = GameController();
Expand Down
15 changes: 9 additions & 6 deletions src/ui/flutter_app/test/game/header_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,19 @@ void main() {
controller.gameInstance.gameMode = GameMode.humanVsHuman;
const HeaderTip screen = HeaderTip();

// Wrap the widget with necessary context (MaterialApp and Localizations)
await tester.pumpWidget(makeTestableWidget(screen));

// Verify initial text
expect(find.text(SEn().welcome), findsOneWidget);

// Trigger tip update
controller.headerTipNotifier.showTip(testString, snackBar: false);

await tester.pump();
// Ensure all updates are applied
await tester.pumpAndSettle();

// Verify updated text
expect(find.text(testString), findsOneWidget);
});

Expand All @@ -68,12 +73,10 @@ void main() {

await tester.pumpWidget(makeTestableWidget(screen));

final Offset icon = tester.getCenter(find.byKey(iconKey));
final Offset header =
tester.getCenter(find.byKey(const Key("HeaderIconRow")));
await tester.pumpAndSettle();

// TODO: Why 44?
expect(icon.dy + 44, header.dy);
expect(find.byType(HeaderIcons), findsOneWidget);
expect(find.byKey(const Key("HeaderIconRow")), findsOneWidget);
});
});
}
57 changes: 27 additions & 30 deletions src/ui/flutter_app/test/game/import_export_test.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
// This file is part of Sanmill.
// Copyright (C) 2019-2024 The Sanmill developers (see AUTHORS file)
//
// Sanmill is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Sanmill is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import 'package:flutter_test/flutter_test.dart';
import 'package:sanmill/game_page/services/mill.dart';
import 'package:sanmill/shared/database/database.dart';
Expand All @@ -24,37 +8,50 @@ import '../helpers/test_mills.dart';

void main() {
group("Import Export Service", () {
setUp(() {
// Mock DB and SoundManager to isolate the test environment
DB.instance = MockDB();
SoundManager.instance = MockAudios();

// Initialize the singleton GameController
final GameController controller = GameController.instance;
controller.gameInstance.gameMode = GameMode.humanVsHuman;
});

test(
"Import standard notation should populate the recorder with the imported moves",
() async {
const WinLessThanThreeGame testMill = WinLessThanThreeGame();

// Initialize the test
DB.instance = MockDB();
SoundManager.instance = MockAudios();
final GameController controller = GameController();
controller.gameInstance.gameMode = GameMode.humanVsHuman;
// Access the singleton GameController instance
final GameController controller = GameController.instance;

// Import a game
// Import a game using ImportService
ImportService.import(testMill.moveList);

// Verify that the recorder contains the expected moves
expect(
GameController().gameRecorder.toString(), testMill.recorderToString);
controller.gameRecorder.toString(),
testMill.recorderToString,
reason: 'GameRecorder should contain the imported moves',
);
});

test("export standard notation", () async {
test("Export standard notation", () async {
const WinLessThanThreeGame testMill = WinLessThanThreeGame();

// Initialize the test
DB.instance = MockDB();
SoundManager.instance = MockAudios();
final GameController controller = GameController();
controller.gameInstance.gameMode = GameMode.humanVsHuman;
// Access the singleton GameController instance
final GameController controller = GameController.instance;

// Import a game
ImportService.import(testMill.moveList);

expect(controller.gameRecorder.moveHistoryText, testMill.moveList);
// Verify the exported moves match the original imported moves
expect(
controller.gameRecorder.moveHistoryText.trim(),
testMill.moveList.trim(),
reason: 'Exported move list should match the original imported list',
);
});
});
}
94 changes: 77 additions & 17 deletions src/ui/flutter_app/test/widget_test.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,89 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. 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 'dart:io';

import 'package:catcher_2/catcher_2.dart'; // Import Catcher
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // Import flutter services
import 'package:flutter_test/flutter_test.dart';
import 'package:sanmill/game_page/services/engine/bitboard.dart';
import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/home/home.dart';
import 'package:sanmill/main.dart';
import 'package:sanmill/shared/database/database.dart';

void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
// Ensure the binding is initialized before tests run
TestWidgetsFlutterBinding.ensureInitialized();

// Define the MethodChannel to be mocked
const MethodChannel engineChannel =
MethodChannel("com.calcitem.sanmill/engine");

// Set up a mock method channel handler for 'path_provider'
const MethodChannel pathProviderChannel =
MethodChannel('plugins.flutter.io/path_provider');

setUpAll(() async {
// Mock the `catcher` initialization for testing
catcher = Catcher2(
rootWidget: const Placeholder(), // Use a minimal widget for testing
ensureInitialized: true,
);

// Use the new API to set up mock handlers for MethodChannel
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(engineChannel, (MethodCall methodCall) async {
switch (methodCall.method) {
case 'send':
return null; // Return a success response
case 'shutdown':
return null; // Return a success response
case 'startup':
return null; // Return a success response
case 'read':
return 'bestmove d2'; // Simulate a response for the 'read' method
case 'isThinking':
return false; // Simulate the 'isThinking' method response
default:
return null; // For unhandled methods, return null
}
});

// Mock the 'getApplicationDocumentsDirectory' method
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(pathProviderChannel,
(MethodCall methodCall) async {
if (methodCall.method == 'getApplicationDocumentsDirectory') {
// Return a temporary directory path
final Directory directory = Directory.systemTemp.createTempSync();
return directory.path;
}
return null;
});

// Initialize the database and other services
await DB.init();
await initializeUI(true);
initBitboards();
});

testWidgets('SanmillApp smoke test', (WidgetTester tester) async {
// Build the app and trigger a frame
await tester.pumpWidget(const SanmillApp());

// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Verify that MaterialApp and Scaffold are present
expect(find.byType(MaterialApp), findsOneWidget);
expect(find.byType(Scaffold), findsWidgets);
});

testWidgets('Verify app navigation and localization',
(WidgetTester tester) async {
// Build the app and trigger a frame
await tester.pumpWidget(const SanmillApp());

// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Check that the supported locales include English
expect(S.supportedLocales.contains(const Locale('en')), isTrue);

// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
// Verify that the Home widget is present
expect(find.byType(Home), findsOneWidget);
});
}

0 comments on commit a84f528

Please sign in to comment.