Skip to content

Commit

Permalink
feat: Rename and refactor DetailsPageChangeNotifier to CharacterDetai…
Browse files Browse the repository at this point in the history
…lsChangeNotifier (#14)

- Remove DetailsPageChangeNotifier and its references
- Implement CharacterDetailsChangeNotifier and corresponding tests
- Update CharacterDetailsPage to utilize new change notifier
- Create EpisodeItem widget from extracted code in CharacterDetailsPage
- Update README 'Provider' test column status to 'Yes'
  • Loading branch information
guilherme-v authored Apr 9, 2024
1 parent bace9c9 commit 64d201a
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ An overview of the current state management libraries explored is presented belo

| State Manager | Applied | Unit tests | Widget tests |
|---------------|---------|:----------:|--------------|
| Provider | Yes | Yes | In Progress |
| Provider | Yes | Yes | Yes |
| Riverpod | Yes | Yes | In Progress |
| Bloc | Yes | Yes | Yes |
| Cubit | Yes | Yes | Yes |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:rickmorty/layers/domain/entity/character.dart';

class DetailsPageChangeNotifier extends ChangeNotifier {
DetailsPageChangeNotifier({required this.character});
class CharacterDetailsChangeNotifier extends ChangeNotifier {
CharacterDetailsChangeNotifier({required this.character});

final Character character;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rickmorty/layers/domain/entity/character.dart';
import 'package:rickmorty/layers/presentation/using_provider/details_page/change_notifier/details_page_change_notifier.dart';
import 'package:rickmorty/layers/presentation/using_provider/details_page/change_notifier/character_details_change_notifier.dart';

// -----------------------------------------------------------------------------
// Page
Expand All @@ -14,7 +14,7 @@ class CharacterDetailsPage extends StatelessWidget {
return MaterialPageRoute(
builder: (context) {
return ChangeNotifierProvider(
create: (_) => DetailsPageChangeNotifier(character: character),
create: (_) => CharacterDetailsChangeNotifier(character: character),
child: const CharacterDetailsPage(),
);
},
Expand Down Expand Up @@ -56,7 +56,7 @@ class _Content extends StatelessWidget {
final colorScheme = theme.colorScheme;

final character = context.select(
(DetailsPageChangeNotifier cn) => cn.character,
(CharacterDetailsChangeNotifier cn) => cn.character,
);

return SingleChildScrollView(
Expand Down Expand Up @@ -89,9 +89,7 @@ class _Content extends StatelessWidget {
Text(
'Status: ${character.isAlive ? 'ALIVE!' : 'DEAD!!'}',
style: textTheme.titleMedium!.copyWith(
color: character.isAlive
? Colors.lightGreen
: Colors.redAccent,
color: character.isAlive ? Colors.lightGreen : Colors.redAccent,
),
),
const SizedBox(height: 8),
Expand Down Expand Up @@ -152,33 +150,48 @@ class _Content extends StatelessWidget {
itemCount: character.episode?.length ?? 0,
itemBuilder: (context, index) {
final ep = character.episode![index];
final name = ep.split('/').last;
return Padding(
padding: const EdgeInsets.only(left: 12.0, top: 8),
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(16),
),
color: colorScheme.surfaceVariant,
),
height: 80,
width: 80,
child: Center(
child: Text(
name,
style: textTheme.bodyLarge!.copyWith(
color: colorScheme.onSurfaceVariant,
),
),
),
),
);
return EpisodeItem(ep: ep);
},
),
)
),
],
),
);
}
}

// -----------------------------------------------------------------------------
// Episode
// -----------------------------------------------------------------------------
class EpisodeItem extends StatelessWidget {
const EpisodeItem({super.key, required this.ep});

final String ep;

@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final colorScheme = Theme.of(context).colorScheme;
final name = ep.split('/').last;

return Padding(
padding: const EdgeInsets.only(left: 12.0, top: 8),
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(16)),
color: colorScheme.surfaceVariant,
),
height: 80,
width: 80,
child: Center(
child: Text(
name,
style: textTheme.bodyLarge!.copyWith(
color: colorScheme.onSurfaceVariant,
),
),
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:rickmorty/layers/presentation/using_provider/details_page/change_notifier/character_details_change_notifier.dart';

import '../../../../../../fixtures/fixtures.dart';

void main() {
group('CharacterDetailsChangeNotifier', () {
test('initial state is correct', () {
final c = characterList1.first;

final notifier = CharacterDetailsChangeNotifier(character: c);

expect(notifier.character, c);
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:rickmorty/layers/presentation/using_provider/details_page/change_notifier/character_details_change_notifier.dart';
import 'package:rickmorty/layers/presentation/using_provider/details_page/view/character_details_page.dart';

import '../../../../../../fixtures/fixtures.dart';

void main() {
testWidgets('CharacterDetailsPage should render correctly', (WidgetTester tester) async {
final character = characterList1.first;

// Build our app and trigger a frame.
await tester.pumpWidget(
MaterialApp(
home: ChangeNotifierProvider(
create: (_) => CharacterDetailsChangeNotifier(character: character),
child: const CharacterDetailsPage(),
),
),
);

// Find items on the page
expect(find.text('Details'), findsOneWidget);
expect(find.text(character.name!), findsOneWidget);
expect(find.text('Origin: ${character.origin!.name}'), findsOneWidget);
expect(find.text('Species: ${character.species}'), findsOneWidget);
expect(find.text('Type: ${character.type}'), findsOneWidget);
expect(find.text('Gender: ${character.gender}'), findsOneWidget);
expect(find.text('Status: ${character.isAlive ? 'ALIVE!' : 'DEAD!'}'), findsOneWidget);
expect(find.text('Last location: ${character.location!.name}'), findsOneWidget);
expectLater(find.byType(EpisodeItem), findsNWidgets(character.episode!.length));
});
}

0 comments on commit 64d201a

Please sign in to comment.