Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2 failing tests left #7

Merged
merged 2 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 1 addition & 32 deletions steps/connect_view_view_model/test/date_service_test.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:demo/date_service.dart';

void main() {
group(DateService, () {
late DateService dateService;

setUp(() {
dateService = DateService();
});

test('should initialize with the current date', () {
final now = DateTime.now();
final date = dateService.dateNotifier.value;

// Compare up to seconds precision
expect(
date.difference(now).inSeconds.abs() <= 1,
isTrue,
);
});

test('should be able to reset the date', () {
final oldDate = dateService.dateNotifier.value;

dateService.resetDate();
final newDate = dateService.dateNotifier.value;

expect(newDate.isAfter(oldDate), isTrue);
});
});
}
void main() {}
41 changes: 41 additions & 0 deletions steps/hide_todos/test/todo/todo_page_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import 'package:demo/date_service.dart';
import 'package:demo/todo/todo.dart';
import 'package:demo/todo/todo_page.dart';
import 'package:demo/utils/locator.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
setUp(() {
// Register the DateService can be a fake if needed
locator.registerSingleton(DateService());
});

tearDown(() {
// Reset the GetIt instance before each test
locator.reset();
});

testWidgets('should add a todo when using the add button',
(WidgetTester tester) async {
await tester.pumpWidget(
Expand Down Expand Up @@ -81,4 +93,33 @@ void main() {
reason: 'ValueListenableBuilder should contain ListView to display todos',
);
});

testWidgets('TodoPage uses ValueListenableBuilder with dateNotifier',
(WidgetTester tester) async {
// Arrange
await tester.pumpWidget(const MaterialApp(home: TodoPage()));

// Assert
expect(
find.byWidgetPredicate(
(widget) => widget is ValueListenableBuilder &&
widget.valueListenable is ValueNotifier<DateTime>,
),
findsOneWidget,
reason: 'TodoPage should use ValueListenableBuilder to listen to date changes from the notifier',
);

// Verify the date display is in AppBar
expect(
find.ancestor(
of: find.byWidgetPredicate(
(widget) => widget is ValueListenableBuilder &&
widget.valueListenable is ValueNotifier<DateTime>,
),
matching: find.byType(AppBar),
),
findsOneWidget,
reason: 'Date ValueListenableBuilder should be within AppBar',
);
});
}
26 changes: 24 additions & 2 deletions steps/hide_todos/test/todo/todo_page_view_model_test.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import 'package:demo/todo/todo_page_view_model.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:demo/date_service.dart';
import 'package:demo/todo/todo_page_view_model.dart';

class FakeDateService extends Fake implements DateService {
@override
ValueNotifier<DateTime> dateNotifier = ValueNotifier(DateTime(2024, 12, 1));

@override
void resetDate() {
dateNotifier.value = DateTime(2022, 3, 17);
}
}

void main() {
group(TodoPageViewModel, () {
late TodoPageViewModel viewModel;
late DateService dateService;
const todoTitle = 'Test Todo';

setUp(() {
viewModel = TodoPageViewModel();
dateService = FakeDateService();
viewModel = TodoPageViewModel(dateService: dateService);
});

test('should persist a newly added todo', () {
Expand Down Expand Up @@ -40,5 +54,13 @@ void main() {
viewModel.toggleDone(todo);
expect(viewModel.todosNotifier.value.first.completed, false);
});

test('should update the date when the date service updates', () {
expect(viewModel.dateNotifier.value, DateTime(2024, 12, 1));

viewModel.resetDate();

expect(viewModel.dateNotifier.value, DateTime(2022, 3, 17));
});
});
}
5 changes: 3 additions & 2 deletions steps/locator/lib/todo/todo_page_view_model.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:demo/date_service.dart';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';

import 'todo.dart';
Expand Down Expand Up @@ -33,5 +33,6 @@ class TodoPageViewModel {
}

void resetDate() {
_dateService.resetDate();
}
}
}
37 changes: 5 additions & 32 deletions steps/locator/test/todo/todo_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,13 @@ void main() {
// Assert
expect(
find.byWidgetPredicate(
(widget) => widget is ValueListenableBuilder &&
widget.valueListenable is ValueNotifier<List<Todo>>,
(widget) =>
widget is ValueListenableBuilder &&
widget.valueListenable is ValueNotifier<List<Todo>>,
),
findsOneWidget,
reason: 'TodoPage should use ValueListenableBuilder to listen to ViewModel changes from the notifier',
reason:
'TodoPage should use ValueListenableBuilder to listen to ViewModel changes from the notifier',
);

// Verify ListView.builder exists
Expand All @@ -93,33 +95,4 @@ void main() {
reason: 'ValueListenableBuilder should contain ListView to display todos',
);
});

testWidgets('TodoPage uses ValueListenableBuilder with dateNotifier',
(WidgetTester tester) async {
// Arrange
await tester.pumpWidget(const MaterialApp(home: TodoPage()));

// Assert
expect(
find.byWidgetPredicate(
(widget) => widget is ValueListenableBuilder &&
widget.valueListenable is ValueNotifier<DateTime>,
),
findsOneWidget,
reason: 'TodoPage should use ValueListenableBuilder to listen to date changes from the notifier',
);

// Verify the date display is in AppBar
expect(
find.ancestor(
of: find.byWidgetPredicate(
(widget) => widget is ValueListenableBuilder &&
widget.valueListenable is ValueNotifier<DateTime>,
),
matching: find.byType(AppBar),
),
findsOneWidget,
reason: 'Date ValueListenableBuilder should be within AppBar',
);
});
}
2 changes: 1 addition & 1 deletion steps/service/lib/todo/todo_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class TodoPage extends StatefulWidget {
}

class _TodoPageState extends State<TodoPage> {
final TodoPageViewModel _todoPageViewModel = TodoPageViewModel(dateService: locator<DateService>());
final TodoPageViewModel _todoPageViewModel = TodoPageViewModel();

final TextEditingController _todoController = TextEditingController();

Expand Down
18 changes: 1 addition & 17 deletions steps/service/test/utils/locator_test.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:demo/utils/locator.dart';
import 'package:demo/date_service.dart';

void main() {
group('Locator Setup Tests', () {
tearDown(() {
locator.reset();
});

test('setupLocator registers DateService correctly', () {
setupLocator();

expect(locator.isRegistered<DateService>(), true, reason: 'DateService should be registered');
});
});
}
void main() {}
41 changes: 2 additions & 39 deletions steps/start/test/todo/todo_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:demo/todo/todo.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
group('Todo', () {
Expand All @@ -14,42 +14,5 @@ void main() {
expect(todo.title, 'Test Todo');
expect(todo.completed, false);
});

test('copyWith should create a new instance with updated values', () {
final todo = Todo(
id: '1',
title: 'Test Todo',
completed: false,
);

final updatedTodo = todo.copyWith(
completed: true,
title: 'Updated Todo',
);

// Original todo should remain unchanged
expect(todo.id, '1');
expect(todo.title, 'Test Todo');
expect(todo.completed, false);

// New todo should have updated values
expect(updatedTodo.id, '1'); // id wasn't changed
expect(updatedTodo.title, 'Updated Todo');
expect(updatedTodo.completed, true);
});

test('copyWith should keep original values when parameters are null', () {
final todo = Todo(
id: '1',
title: 'Test Todo',
completed: false,
);

final updatedTodo = todo.copyWith();

expect(updatedTodo.id, todo.id);
expect(updatedTodo.title, todo.title);
expect(updatedTodo.completed, todo.completed);
});
});
}
}
45 changes: 1 addition & 44 deletions steps/todo_class/test/todo/todo_page_view_model_test.dart
Original file line number Diff line number Diff line change
@@ -1,44 +1 @@
import 'package:demo/todo/todo_page_view_model.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
group(TodoPageViewModel, () {
late TodoPageViewModel viewModel;
const todoTitle = 'Test Todo';

setUp(() {
viewModel = TodoPageViewModel();
});

test('should persist a newly added todo', () {
viewModel.add(todoTitle);

expect(viewModel.todosNotifier.value.length, 1);
expect(viewModel.todosNotifier.value.first.title, todoTitle);
expect(viewModel.todosNotifier.value.first.completed, false);
});

test('should be able to remove a specified todo', () {
viewModel.add(todoTitle);

final todo = viewModel.todosNotifier.value.first;

viewModel.remove(todo);

expect(viewModel.todosNotifier.value.isEmpty, true);
});

test('should be able to toggle the completed status of a specified Todo',
() {
viewModel.add(todoTitle);

final todo = viewModel.todosNotifier.value.first;

viewModel.toggleDone(todo);
expect(viewModel.todosNotifier.value.first.completed, true);

viewModel.toggleDone(todo);
expect(viewModel.todosNotifier.value.first.completed, false);
});
});
}
void main() {}
23 changes: 0 additions & 23 deletions steps/view/test/todo/todo_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,4 @@ void main() {
// Verify the checkbox is no longer rendered after completion
expect(checkbox, findsNothing);
});

testWidgets('TodoPage uses ValueListenableBuilder with ViewModel',
(WidgetTester tester) async {
// Arrange
await tester.pumpWidget(const MaterialApp(home: TodoPage()));

// Assert
expect(
find.byWidgetPredicate(
(widget) => widget is ValueListenableBuilder &&
widget.valueListenable is ValueNotifier<List<Todo>>,
),
findsOneWidget,
reason: 'TodoPage should use ValueListenableBuilder to listen to ViewModel changes from the notifier',
);

// Verify ListView.builder exists
expect(
find.byType(ListView),
findsOneWidget,
reason: 'ValueListenableBuilder should contain ListView to display todos',
);
});
}
Loading