Some visual adjustments.

master
Rafael 2024-06-14 14:28:59 +02:00
parent 94e78e91da
commit 9a7a8f9f39
15 changed files with 270 additions and 241 deletions

View File

@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import '../models/language.dart';
import '../utils/list_utils.dart';
class MyLanguageList extends StatelessWidget {
final List<Language> langList;
final double? iconHeight;
final double? textSize;
const MyLanguageList(
{super.key, required this.langList, this.iconHeight = 16, this.textSize});
@override
Widget build(BuildContext context) {
List<Language> sortedLanguages = sortLanguageList(langList);
return Wrap(
children: sortedLanguages.map(
(language) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
language.iconFile,
height: iconHeight,
),
const SizedBox(width: 4.0),
Text(
language.name,
style: TextStyle(fontSize: textSize),
),
// Space between each language icon pair
const SizedBox(width: 8.0),
],
);
},
).toList(),
);
}
}

View File

@ -5,6 +5,7 @@ import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
import '../forms/risks_form.dart'; import '../forms/risks_form.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
import '../utils/helper_dialogs.dart';
class CultureValuesFormPage extends StatefulWidget { class CultureValuesFormPage extends StatefulWidget {
const CultureValuesFormPage( const CultureValuesFormPage(
@ -85,15 +86,13 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
); );
return true; return true;
} catch (e) { } catch (e) {
_showSnackBar(e.toString()); _showSnackBar('Error saving data: ${e.toString()}');
return false; return false;
} }
} }
void _showSnackBar(String message) { void _showSnackBar(String message) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( showErrorSnackBar(context, message);
content: Text(message),
));
} }
bool isWorkValueSelected() { bool isWorkValueSelected() {
@ -105,18 +104,12 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
Future<void> handleSubmit() async { Future<void> handleSubmit() async {
if (!isWorkValueSelected()) { if (!isWorkValueSelected()) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( _showSnackBar(
content: Text( 'Please select at least ${minWorkValueOption.toString()} and at most ${maxWorkValueOption.toString()} work life values.');
'Please select at least ${minWorkValueOption.toString()} and '
'at most ${maxWorkValueOption.toString()} work life values.',
),
));
return; return;
} }
if (selectedCultureOption == null) { if (selectedCultureOption == null) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar( _showSnackBar('Please select a corporate culture.');
content: Text('Please select a corporate culture.'),
));
return; return;
} }
// Handle the form submission logic here // Handle the form submission logic here
@ -167,8 +160,28 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
'Work life and corporate culture', 'Work life and corporate culture',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
), ),
const Text( const Align(
'What values are most important to you in your working environment?', alignment: Alignment.centerLeft,
child: Text('Which corporate culture suits you best?'),
),
...CultureOption.values.map((option) {
return RadioListTile(
title: Text(option.displayName),
value: option,
groupValue: selectedCultureOption,
onChanged: (CultureOption? value) {
setState(() {
selectedCultureOption = value;
});
},
);
}),
const SizedBox(height: 40),
const Align(
alignment: Alignment.centerLeft,
child: Text(
'What values are most important to you in your working environment?',
),
), ),
...WorkValueOption.values.map((option) { ...WorkValueOption.values.map((option) {
return CheckboxListTile( return CheckboxListTile(
@ -184,36 +197,14 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
selectedValueOptions[option] = value!; selectedValueOptions[option] = value!;
} else if (value == true && } else if (value == true &&
selectedCount >= maxWorkValueOption) { selectedCount >= maxWorkValueOption) {
ScaffoldMessenger.of(context) _showSnackBar(
.showSnackBar(const SnackBar( 'You can only select a maximum of two values.',
content: Text( );
'You can only select a maximum of two values.',
),
));
} }
}); });
}, },
); );
}), }),
const SizedBox(height: 40),
const Align(
alignment: Alignment.centerLeft,
child: Text('Which corporate culture suits you best?')),
DropdownButton<CultureOption>(
hint: const Text('Choose a corporate culture'),
value: selectedCultureOption,
onChanged: (CultureOption? newValue) {
setState(() {
selectedCultureOption = newValue;
});
},
items: CultureOption.values.map((CultureOption option) {
return DropdownMenuItem<CultureOption>(
value: option,
child: Text(option.displayName),
);
}).toList(),
),
const SizedBox(height: 20), const SizedBox(height: 20),
ElevatedButton( ElevatedButton(
onPressed: handleSubmit, onPressed: handleSubmit,

View File

@ -6,7 +6,7 @@ import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
import '../models/swipe.dart'; import '../models/swipe.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
import '../utils/helper.dart'; import '../utils/helper_dialogs.dart';
import 'user_profile_page.dart'; import 'user_profile_page.dart';
class LikedUsersPage extends StatefulWidget { class LikedUsersPage extends StatefulWidget {
@ -125,8 +125,9 @@ class LikedUsersPageState extends State<LikedUsersPage> {
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: const Text('Confirm Unlike'), title: const Text('Confirm Removal'),
content: Text('Are you sure you want to unlike $userName?'), content:
Text('Are you sure you want to remove $userName from your list?'),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(false), onPressed: () => Navigator.of(context).pop(false),

View File

@ -2,7 +2,7 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../components/my_button.dart'; import '../components/my_button.dart';
import '../components/my_textfield.dart'; import '../components/my_textfield.dart';
import '../utils/helper.dart'; import '../utils/helper_dialogs.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
class LoginPage extends StatelessWidget { class LoginPage extends StatelessWidget {

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart';
import '../components/my_button.dart'; import '../components/my_button.dart';
import '../components/my_textfield.dart'; import '../components/my_textfield.dart';
import '../utils/helper.dart'; import '../utils/helper_dialogs.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
import '../services/user_service.dart'; import '../services/user_service.dart';

View File

@ -13,7 +13,7 @@ import '../models/language.dart';
import '../models/language_setting.dart'; import '../models/language_setting.dart';
import '../models/location.dart'; import '../models/location.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
import '../utils/helper.dart'; import '../utils/helper_dialogs.dart';
import '../utils/math.dart'; import '../utils/math.dart';
class UserDataPage extends StatefulWidget { class UserDataPage extends StatefulWidget {

View File

@ -1,11 +1,11 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:percent_indicator/circular_percent_indicator.dart'; import 'package:percent_indicator/circular_percent_indicator.dart';
import 'package:swipable_stack/swipable_stack.dart'; import 'package:swipable_stack/swipable_stack.dart';
import '../components/card_overlay.dart'; import '../components/card_overlay.dart';
import '../components/language_list.dart';
import '../constants.dart'; import '../constants.dart';
import '../forms/matched_screen.dart'; import '../forms/matched_screen.dart';
import '../models/language.dart'; import '../models/language.dart';
@ -409,16 +409,6 @@ class UserMatchingPageState extends State<UserMatchingPage> {
Widget _buildUserCard(UserProfile userProfile) { Widget _buildUserCard(UserProfile userProfile) {
String? profileImageUrl = userProfile.profilePictureUrl; String? profileImageUrl = userProfile.profilePictureUrl;
// Sort the languages according to the given order below
List<Language> sortedLanguages = List.from(userProfile.languages);
sortedLanguages.sort((a, b) {
if (a.code == 'de') return -1; // German first
if (b.code == 'de') return 1; // German first
if (a.code == 'en') return -1; // English second
if (b.code == 'en') return 1; // English second
return a.name.compareTo(b.name); // All others by name ascending
});
String pronoun = getPronoun(userProfile.gender); String pronoun = getPronoun(userProfile.gender);
double shortDist = double shortDist =
@ -499,27 +489,10 @@ class UserMatchingPageState extends State<UserMatchingPage> {
], ],
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Wrap( MyLanguageList(
children: sortedLanguages.map( langList: userProfile.languages,
(language) { iconHeight: 12,
return Row(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
language.iconFile,
height: 12.0,
),
const SizedBox(width: 4.0),
Text(language.name),
// Space between each language icon pair
const SizedBox(width: 8.0),
],
);
},
).toList(),
), ),
//Text('Risk type: ${userProfile.risk.displayName}'),
], ],
), ),
), ),

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart';
import '../components/language_list.dart';
import '../constants.dart'; import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
import '../forms/corporate_culture_form.dart'; import '../forms/corporate_culture_form.dart';
@ -350,7 +351,7 @@ class _UserProfilePageState extends State<UserProfilePage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Vision and Goals', 'Corporate values',
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
@ -502,29 +503,53 @@ class _UserProfilePageState extends State<UserProfilePage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (isOwner) Row(
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
children: [ Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Text(
Text( 'Locations',
'Age', style: TextStyle(
style: TextStyle( color: Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.primary,
),
), ),
),
if (myData.locations.isEmpty)
const Text('n/a', style: TextStyle(fontSize: 16)),
if (myData.locations
.containsKey(Constants.dbDocMainLocation))
Text( Text(
(age > 0 myData.locations[Constants.dbDocMainLocation]
? '$age years old, born ${myData.born}' .toString(),
: 'n/a'), style: const TextStyle(fontSize: 16),
style: const TextStyle(fontSize: 16)), ),
], if (myData.locations
), .containsKey(Constants.dbDocSecondLocation))
Text(
myData.locations[Constants.dbDocSecondLocation]
.toString(),
style: const TextStyle(fontSize: 16),
),
],
),
if (isOwner)
_editButton(context, editUserDataInfo, _editButton(context, editUserDataInfo,
alignment: Alignment.bottomRight), alignment: Alignment.bottomRight),
], ],
),
if (isOwner) const SizedBox(height: 16),
if (isOwner)
Text(
'Age',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (isOwner)
Text(
(age > 0 ? '$age years old, born ${myData.born}' : 'n/a'),
style: const TextStyle(fontSize: 16),
), ),
if (isOwner) const SizedBox(height: 16), if (isOwner) const SizedBox(height: 16),
if (isOwner) if (isOwner)
@ -544,29 +569,10 @@ class _UserProfilePageState extends State<UserProfilePage> {
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
), ),
Text( MyLanguageList(
myData.languages.map((lang) => lang.name).join(', '), langList: myData.languages,
style: const TextStyle(fontSize: 16), textSize: 16,
), ),
const SizedBox(height: 16),
Text(
'Locations',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (myData.locations.isEmpty)
const Text('n/a', style: TextStyle(fontSize: 16)),
if (myData.locations.containsKey(Constants.dbDocMainLocation))
Text(
myData.locations[Constants.dbDocMainLocation].toString(),
style: const TextStyle(fontSize: 16),
),
if (myData.locations.containsKey(Constants.dbDocSecondLocation))
Text(
myData.locations[Constants.dbDocSecondLocation].toString(),
style: const TextStyle(fontSize: 16),
),
], ],
), ),
), ),
@ -603,11 +609,13 @@ class _UserProfilePageState extends State<UserProfilePage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Flexible(
isOwner child: Text(
? myData.name isOwner
: '${myData.name} ${ageInfo(myData.born)}'.trim(), ? myData.name
style: const TextStyle(fontSize: 24), : '${myData.name} ${ageInfo(myData.born)}'.trim(),
style: const TextStyle(fontSize: 24),
),
), ),
genderIcon, genderIcon,
], ],
@ -637,8 +645,7 @@ class _UserProfilePageState extends State<UserProfilePage> {
{Alignment alignment = Alignment.topRight}) { {Alignment alignment = Alignment.topRight}) {
return Align( return Align(
alignment: alignment, alignment: alignment,
child: OutlinedButton.icon( child: IconButton(
label: const Text('Edit'),
icon: const Icon(Icons.edit), icon: const Icon(Icons.edit),
onPressed: onPressedFunction, onPressed: onPressedFunction,
), ),

View File

@ -5,7 +5,7 @@ import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
import '../forms/corporate_culture_form.dart'; import '../forms/corporate_culture_form.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
import '../utils/helper.dart'; import '../utils/helper_dialogs.dart';
class UserVisionPage extends StatefulWidget { class UserVisionPage extends StatefulWidget {
const UserVisionPage( const UserVisionPage(
@ -155,26 +155,6 @@ class UserVisionPageState extends State<UserVisionPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Text(
'Vision and goals',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Text('What is your long-term vision for a startup?'),
...VisionOption.values.map((option) {
return CheckboxListTile(
title: Text(option.displayName),
value: selectedVisionOptions[option],
controlAffinity: ListTileControlAffinity.platform,
onChanged: (bool? value) {
if (value != null) {
setState(() {
selectedVisionOptions[option] = value;
});
}
},
);
}),
const SizedBox(height: 40),
const Text( const Text(
'Availability and commitment', 'Availability and commitment',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
@ -194,6 +174,26 @@ class UserVisionPageState extends State<UserVisionPage> {
}, },
); );
}), }),
const SizedBox(height: 40),
const Text(
'Vision and goals',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Text('What is your long-term vision for a startup?'),
...VisionOption.values.map((option) {
return CheckboxListTile(
title: Text(option.displayName),
value: selectedVisionOptions[option],
controlAffinity: ListTileControlAffinity.platform,
onChanged: (bool? value) {
if (value != null) {
setState(() {
selectedVisionOptions[option] = value;
});
}
},
);
}),
const SizedBox(height: 20), const SizedBox(height: 20),
Center( Center(
child: ElevatedButton( child: ElevatedButton(

View File

@ -1,6 +1,4 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:io' show Platform; import 'dart:io' show Platform;
import '../enumerations.dart'; import '../enumerations.dart';
@ -14,11 +12,6 @@ bool get isMobile {
} }
} }
/// Compare two lists by their content ignoring their elements order.
bool equalContent(List<dynamic> list1, List<dynamic> list2) {
return const DeepCollectionEquality.unordered().equals(list1, list2);
}
/// Creates a composite ID from the passed [ids]. /// Creates a composite ID from the passed [ids].
/// In the format id(1)_id(n) /// In the format id(1)_id(n)
String getCompoundId(List<String> ids) { String getCompoundId(List<String> ids) {
@ -94,38 +87,3 @@ String getDisplayText(dynamic option) {
// Fallback to default toString if not an enum // Fallback to default toString if not an enum
return option.toString().split('.').last; return option.toString().split('.').last;
} }
/// Show a simple message dialog
void showMsg(BuildContext context, String title, String content) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(title),
content: Text(content),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
),
],
),
);
}
/// Show a red colored SnackBar with a [Dismiss] Button
void showErrorSnackBar(BuildContext context, String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red,
action: SnackBarAction(
label: 'Dismiss',
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
}

View File

@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
/// Show a simple message dialog
void showMsg(BuildContext context, String title, String content) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(title),
content: Text(content),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
),
],
),
);
}
/// Show a red colored SnackBar with a [Dismiss] Button
void showErrorSnackBar(BuildContext context, String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red,
action: SnackBarAction(
label: 'Dismiss',
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
}

View File

@ -0,0 +1,23 @@
import 'package:collection/collection.dart';
import '../models/language.dart';
/// Compare two lists by their content ignoring their elements order.
bool equalContent(List<dynamic> list1, List<dynamic> list2) {
return const DeepCollectionEquality.unordered().equals(list1, list2);
}
/// Sort the given list of languages so that German appears first, English second, and all other languages follow in alphabetical order.
List<Language> sortLanguageList(List<Language> langList) {
List<Language> sortedLanguages = List.from(langList);
sortedLanguages.sort((a, b) {
// German first
if (a.code == 'de') return -1;
if (b.code == 'de') return 1;
// English second
if (a.code == 'en') return -1;
if (b.code == 'en') return 1;
// All others by name ascending
return a.name.compareTo(b.name);
});
return sortedLanguages;
}

View File

@ -19,9 +19,7 @@ String ageInfo(int? birthYear) {
return ageInfo; return ageInfo;
} }
///
/// Convert decimal coordinate to degrees minutes seconds (DMS). /// Convert decimal coordinate to degrees minutes seconds (DMS).
///
String convertDecimalToDMS(double decimalValue, {required bool isLatitude}) { String convertDecimalToDMS(double decimalValue, {required bool isLatitude}) {
bool isNegative = decimalValue < 0; bool isNegative = decimalValue < 0;
double absoluteValue = decimalValue.abs(); double absoluteValue = decimalValue.abs();
@ -43,9 +41,7 @@ String convertDecimalToDMS(double decimalValue, {required bool isLatitude}) {
return '${degrees.abs()}° ${minutes.abs()}\' ${seconds.abs().toStringAsFixed(2)}" $direction'; return '${degrees.abs()}° ${minutes.abs()}\' ${seconds.abs().toStringAsFixed(2)}" $direction';
} }
///
/// Distance in kilometers between two location coordinates /// Distance in kilometers between two location coordinates
///
double calculateDistance(double lat1, double lon1, double lat2, double lon2) { double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
const R = 6371; // earth radius in kilometers const R = 6371; // earth radius in kilometers
@ -67,9 +63,7 @@ double _degreesToRadians(double degrees) {
return degrees * pi / 180; return degrees * pi / 180;
} }
///
/// Shortest distance between two users locations /// Shortest distance between two users locations
///
double shortestDistanceBetweenUsers( double shortestDistanceBetweenUsers(
UserProfile currentUser, UserProfile otherUser) { UserProfile currentUser, UserProfile otherUser) {
try { try {
@ -122,7 +116,7 @@ double calculateMatchScore(UserProfile currentUser, UserProfile otherUser) {
communicationWeight); communicationWeight);
if (weightSum != 1) { if (weightSum != 1) {
debugPrint( debugPrint(
'Warning --> calculateMatchScore : Weights Sum $weightSum != 1'); 'DEBUG Info --> calculateMatchScore : Weights Sum $weightSum != 1');
} }
} }

View File

@ -35,51 +35,6 @@ void main() {
}); });
}); });
group('equalContent', () {
test('returns true for lists with the same content in the same order', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2, 3];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns true for lists with the same content in different orders',
() {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [3, 1, 2];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns false for lists with different content', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2, 4];
bool result = equalContent(list1, list2);
expect(result, false);
});
test('returns false for lists with different lengths', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2];
bool result = equalContent(list1, list2);
expect(result, false);
});
test('returns true for empty lists', () {
List<dynamic> list1 = [];
List<dynamic> list2 = [];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns false for one empty and one non-empty list', () {
List<dynamic> list1 = [];
List<dynamic> list2 = [1];
bool result = equalContent(list1, list2);
expect(result, false);
});
});
group('formatTimestamp', () { group('formatTimestamp', () {
test('formatTimestamp returns the expected formatted date for 01.01.1970', test('formatTimestamp returns the expected formatted date for 01.01.1970',
() { () {

View File

@ -0,0 +1,49 @@
import 'package:cofounderella/utils/list_utils.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('equalContent', () {
test('returns true for lists with the same content in the same order', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2, 3];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns true for lists with the same content in different orders',
() {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [3, 1, 2];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns false for lists with different content', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2, 4];
bool result = equalContent(list1, list2);
expect(result, false);
});
test('returns false for lists with different lengths', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2];
bool result = equalContent(list1, list2);
expect(result, false);
});
test('returns true for empty lists', () {
List<dynamic> list1 = [];
List<dynamic> list2 = [];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns false for one empty and one non-empty list', () {
List<dynamic> list1 = [];
List<dynamic> list2 = [1];
bool result = equalContent(list1, list2);
expect(result, false);
});
});
}