From e5e9f6175df0fe9330d48df8e673dfa8470ba82c Mon Sep 17 00:00:00 2001 From: Iiro Krankka Date: Tue, 3 Jul 2018 21:40:29 +0300 Subject: [PATCH] Fix the hashCode and equality implementations of viewmodels. --- lib/data/models/event.dart | 50 ++++++++++++++++ lib/data/models/show.dart | 27 +++++++++ lib/data/models/theater.dart | 13 ++++ lib/ui/events/events_page_view_model.dart | 7 +-- .../showtimes/showtime_page_view_model.dart | 13 ++-- .../theater_list/theater_list_view_model.dart | 7 +-- .../events/events_page_view_model_test.dart | 48 +++++++++++++++ .../showtimes_page_view_model_test.dart | 60 +++++++++++++++++++ .../theater_list_view_model_test.dart | 51 ++++++++++++++++ 9 files changed, 260 insertions(+), 16 deletions(-) create mode 100644 test/ui/events/events_page_view_model_test.dart create mode 100644 test/ui/showtimes/showtimes_page_view_model_test.dart create mode 100644 test/ui/theater_list/theater_list_view_model_test.dart diff --git a/lib/data/models/event.dart b/lib/data/models/event.dart index 5a818312..f6b4e670 100644 --- a/lib/data/models/event.dart +++ b/lib/data/models/event.dart @@ -88,6 +88,37 @@ class Event { return 'https://youtube.com/watch?v=' + tagContents(node, 'Location'); }).toList(); } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is Event && + runtimeType == other.runtimeType && + id == other.id && + title == other.title && + originalTitle == other.originalTitle && + genres == other.genres && + directors == other.directors && + lengthInMinutes == other.lengthInMinutes && + shortSynopsis == other.shortSynopsis && + synopsis == other.synopsis && + images == other.images && + youtubeTrailers == other.youtubeTrailers && + actors == other.actors; + + @override + int get hashCode => + id.hashCode ^ + title.hashCode ^ + originalTitle.hashCode ^ + genres.hashCode ^ + directors.hashCode ^ + lengthInMinutes.hashCode ^ + shortSynopsis.hashCode ^ + synopsis.hashCode ^ + images.hashCode ^ + youtubeTrailers.hashCode ^ + actors.hashCode; } class EventImageData { @@ -134,4 +165,23 @@ class EventImageData { landscapeBig: tagContentsOrNull(root, 'EventLargeImageLandscape'), ); } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is EventImageData && + runtimeType == other.runtimeType && + portraitSmall == other.portraitSmall && + portraitMedium == other.portraitMedium && + portraitLarge == other.portraitLarge && + landscapeSmall == other.landscapeSmall && + landscapeBig == other.landscapeBig; + + @override + int get hashCode => + portraitSmall.hashCode ^ + portraitMedium.hashCode ^ + portraitLarge.hashCode ^ + landscapeSmall.hashCode ^ + landscapeBig.hashCode; } diff --git a/lib/data/models/show.dart b/lib/data/models/show.dart index eca17d95..16cf418b 100644 --- a/lib/data/models/show.dart +++ b/lib/data/models/show.dart @@ -46,4 +46,31 @@ class Show { ); }).toList(); } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is Show && + runtimeType == other.runtimeType && + id == other.id && + eventId == other.eventId && + title == other.title && + originalTitle == other.originalTitle && + url == other.url && + presentationMethod == other.presentationMethod && + theaterAndAuditorium == other.theaterAndAuditorium && + start == other.start && + end == other.end; + + @override + int get hashCode => + id.hashCode ^ + eventId.hashCode ^ + title.hashCode ^ + originalTitle.hashCode ^ + url.hashCode ^ + presentationMethod.hashCode ^ + theaterAndAuditorium.hashCode ^ + start.hashCode ^ + end.hashCode; } diff --git a/lib/data/models/theater.dart b/lib/data/models/theater.dart index 3274dcd1..7fe809a4 100644 --- a/lib/data/models/theater.dart +++ b/lib/data/models/theater.dart @@ -42,4 +42,17 @@ class Theater { return '${match.group(1)}${match.group(2).toLowerCase()}'; }); } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is Theater && + runtimeType == other.runtimeType && + id == other.id && + name == other.name; + + @override + int get hashCode => + id.hashCode ^ + name.hashCode; } diff --git a/lib/ui/events/events_page_view_model.dart b/lib/ui/events/events_page_view_model.dart index 8966bc41..bd6f3207 100644 --- a/lib/ui/events/events_page_view_model.dart +++ b/lib/ui/events/events_page_view_model.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:inkino/data/loading_status.dart'; import 'package:inkino/data/models/event.dart'; import 'package:inkino/redux/app/app_state.dart'; @@ -34,10 +35,8 @@ class EventsPageViewModel { other is EventsPageViewModel && runtimeType == other.runtimeType && status == other.status && - events == other.events && - refreshEvents == other.refreshEvents; + const IterableEquality().equals(events, other.events); @override - int get hashCode => - status.hashCode ^ events.hashCode ^ refreshEvents.hashCode; + int get hashCode => status.hashCode ^ const IterableEquality().hash(events); } diff --git a/lib/ui/showtimes/showtime_page_view_model.dart b/lib/ui/showtimes/showtime_page_view_model.dart index ffc2aecf..aa4d6bd0 100644 --- a/lib/ui/showtimes/showtime_page_view_model.dart +++ b/lib/ui/showtimes/showtime_page_view_model.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:inkino/data/loading_status.dart'; import 'package:inkino/data/models/show.dart'; import 'package:inkino/redux/app/app_state.dart'; @@ -42,18 +43,14 @@ class ShowtimesPageViewModel { other is ShowtimesPageViewModel && runtimeType == other.runtimeType && status == other.status && - dates == other.dates && + const IterableEquality().equals(dates, other.dates) && selectedDate == other.selectedDate && - shows == other.shows && - changeCurrentDate == other.changeCurrentDate && - refreshShowtimes == other.refreshShowtimes; + const IterableEquality().equals(shows, other.shows); @override int get hashCode => status.hashCode ^ - dates.hashCode ^ + const IterableEquality().hash(dates) ^ selectedDate.hashCode ^ - shows.hashCode ^ - changeCurrentDate.hashCode ^ - refreshShowtimes.hashCode; + const IterableEquality().hash(shows); } diff --git a/lib/ui/theater_list/theater_list_view_model.dart b/lib/ui/theater_list/theater_list_view_model.dart index 30a83098..aaf785bb 100644 --- a/lib/ui/theater_list/theater_list_view_model.dart +++ b/lib/ui/theater_list/theater_list_view_model.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:inkino/data/models/theater.dart'; import 'package:inkino/redux/app/app_state.dart'; import 'package:inkino/redux/common_actions.dart'; @@ -32,12 +33,10 @@ class TheaterListViewModel { other is TheaterListViewModel && runtimeType == other.runtimeType && currentTheater == other.currentTheater && - theaters == other.theaters && - changeCurrentTheater == other.changeCurrentTheater; + const IterableEquality().equals(theaters, other.theaters); @override int get hashCode => currentTheater.hashCode ^ - theaters.hashCode ^ - changeCurrentTheater.hashCode; + const IterableEquality().hash(theaters); } diff --git a/test/ui/events/events_page_view_model_test.dart b/test/ui/events/events_page_view_model_test.dart new file mode 100644 index 00000000..13696f06 --- /dev/null +++ b/test/ui/events/events_page_view_model_test.dart @@ -0,0 +1,48 @@ +import 'package:inkino/data/loading_status.dart'; +import 'package:inkino/data/models/event.dart'; +import 'package:inkino/ui/events/events_page_view_model.dart'; +import 'package:test/test.dart'; + +void main() { + group('EventsPageViewModel', () { + test('equal', () { + var first = EventsPageViewModel( + status: LoadingStatus.success, + events: [ + Event(id: 'abc123'), + ], + refreshEvents: () {}, + ); + + var second = EventsPageViewModel( + status: LoadingStatus.success, + events: [ + Event(id: 'abc123'), + ], + refreshEvents: () {}, + ); + + expect(first, second); + }); + + test('not equal', () { + var first = EventsPageViewModel( + status: LoadingStatus.success, + events: [ + Event(id: 'abc123'), + ], + refreshEvents: () {}, + ); + + var second = EventsPageViewModel( + status: LoadingStatus.success, + events: [ + Event(id: 'xyz456'), + ], + refreshEvents: () {}, + ); + + expect(first, isNot(second)); + }); + }); +} diff --git a/test/ui/showtimes/showtimes_page_view_model_test.dart b/test/ui/showtimes/showtimes_page_view_model_test.dart new file mode 100644 index 00000000..dd89ce6a --- /dev/null +++ b/test/ui/showtimes/showtimes_page_view_model_test.dart @@ -0,0 +1,60 @@ +import 'package:inkino/data/loading_status.dart'; +import 'package:inkino/data/models/show.dart'; +import 'package:inkino/ui/showtimes/showtime_page_view_model.dart'; +import 'package:test/test.dart'; + +void main() { + group('ShowtimesPageViewModel', () { + test('equal', () { + var first = ShowtimesPageViewModel( + status: LoadingStatus.success, + dates: [DateTime(2018)], + selectedDate: null, + shows: [ + Show(id: 'abc123'), + ], + changeCurrentDate: (DateTime newDate) {}, + refreshShowtimes: () {}, + ); + + var second = ShowtimesPageViewModel( + status: LoadingStatus.success, + dates: [DateTime(2018)], + selectedDate: null, + shows: [ + Show(id: 'abc123'), + ], + changeCurrentDate: (DateTime newDate) {}, + refreshShowtimes: () {}, + ); + + expect(first, second); + }); + + test('not equal', () { + var first = ShowtimesPageViewModel( + status: LoadingStatus.success, + dates: [DateTime(2018)], + selectedDate: null, + shows: [ + Show(id: 'abc123'), + ], + changeCurrentDate: (DateTime newDate) {}, + refreshShowtimes: () {}, + ); + + var second = ShowtimesPageViewModel( + status: LoadingStatus.success, + dates: [DateTime(2018)], + selectedDate: null, + shows: [ + Show(id: 'xyz456'), + ], + changeCurrentDate: (DateTime newDate) {}, + refreshShowtimes: () {}, + ); + + expect(first, isNot(second)); + }); + }); +} \ No newline at end of file diff --git a/test/ui/theater_list/theater_list_view_model_test.dart b/test/ui/theater_list/theater_list_view_model_test.dart new file mode 100644 index 00000000..a554db96 --- /dev/null +++ b/test/ui/theater_list/theater_list_view_model_test.dart @@ -0,0 +1,51 @@ +import 'package:inkino/data/models/theater.dart'; +import 'package:inkino/ui/theater_list/theater_list_view_model.dart'; +import 'package:test/test.dart'; + +void main() { + group('TheaterListViewModel', () { + test('equal', () { + var first = TheaterListViewModel( + currentTheater: Theater(id: 'abc123', name: 'Test 1'), + theaters: [ + Theater(id: 'abc123', name: 'Test 1'), + Theater(id: 'xyz456', name: 'Test 2'), + ], + changeCurrentTheater: (Theater newTheater) {}, + ); + + var second = TheaterListViewModel( + currentTheater: Theater(id: 'abc123', name: 'Test 1'), + theaters: [ + Theater(id: 'abc123', name: 'Test 1'), + Theater(id: 'xyz456', name: 'Test 2'), + ], + changeCurrentTheater: (Theater newTheater) {}, + ); + + expect(first, second); + }); + + test('not equal', () { + var first = TheaterListViewModel( + currentTheater: Theater(id: 'abc123', name: 'Test 1'), + theaters: [ + Theater(id: 'abc123', name: 'Test 1'), + Theater(id: 'xyz456', name: 'Test 2'), + ], + changeCurrentTheater: (Theater newTheater) {}, + ); + + var second = TheaterListViewModel( + currentTheater: Theater(id: 'abc123', name: 'Test 1'), + theaters: [ + Theater(id: 'efg123', name: 'Test 3'), + Theater(id: 'hjk456', name: 'Test 4'), + ], + changeCurrentTheater: (Theater newTheater) {}, + ); + + expect(first, isNot(second)); + }); + }); +}