diff --git a/packages/wyatt_type_utils/README.md b/packages/wyatt_type_utils/README.md index 84de5044..75750496 100644 --- a/packages/wyatt_type_utils/README.md +++ b/packages/wyatt_type_utils/README.md @@ -77,3 +77,72 @@ final Result todo1 = await requestTodo(); // In Flutter: todo1.either(buildWidgetWithTodo, buildSizedBox); ``` + +## Pair\ + +**Pair** is a simple object which contains pair of two values. + +```dart +const Pair myPair = Pair(42, 16); +print(myPair.left); // prints '42' +print(myPair.right); // prints '16' +print(myPair); // prints '(42, 16)' +final List myList = myPair.toList(); +print(myList); // prints '[42, 16]' +``` + +## Extensions + +This package also provides extensions for Dart types. + +- Object + - isNull + - isNotNull + - log +- Iterable + - isNullOrEmpty + - isNotNullOrEmpty + - For bytes iterables + - toTypedList + - toStr +- String + - isNullOrEmpty + - isNotNullOrEmpty + - toBytes + +String 🔁 Uint8List works with encoding: + +```dart +const String myString = 'abc'; +final Uint8List bytes = myString.toBytes(from : Encoding.utf16); +print(bytes.toStr(to : Encoding.utf16)); // prints 'abc' +``` + +- DateTime + - fromSecondsSinceEpoch + - secondsSinceEpoch + - timestamp + - tomorrow + - yesterday + - today + - add/sub/set + - nextDay + - previousDay + - nextMonth + - previousMonth + - nextYear + - previousYear + - nextWeek + - previousWeek + - isFuture + - isPast + - isLeapYear + - format + - operators + +The date formatter works with `String` formatter: + +```dart +final DateTime date = DateTime(1999, 6, 30); +print(date.format([dd, '/', mm, '/', yy])); // prints '30/06/99' +``` diff --git a/packages/wyatt_type_utils/lib/src/extensions/date_time_extension.dart b/packages/wyatt_type_utils/lib/src/extensions/date_time_extension.dart new file mode 100644 index 00000000..d80717df --- /dev/null +++ b/packages/wyatt_type_utils/lib/src/extensions/date_time_extension.dart @@ -0,0 +1,620 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program 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 +// any later version. +// +// This program 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 . + +// ignore_for_file: constant_identifier_names + +/// Outputs year as four digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989), [yyyy]); +/// // => 1989 +/// ``` +const String yyyy = 'yyyy'; + +/// Outputs year as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989), [yy]); +/// // => 89 +/// ``` +const String yy = 'yy'; + +/// Outputs month as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 11), [mm]); +/// // => 11 +/// formatDate(DateTime(1989, 5), [mm]); +/// // => 05 +/// ``` +const String mm = 'mm'; + +/// Outputs month compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 11), [mm]); +/// // => 11 +/// formatDate(DateTime(1989, 5), [m]); +/// // => 5 +/// ``` +const String m = 'm'; + +/// Outputs day as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 2, 21), [dd]); +/// // => 21 +/// formatDate(DateTime(1989, 2, 5), [dd]); +/// // => 05 +/// ``` +const String dd = 'dd'; + +/// Outputs day compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 2, 21), [d]); +/// // => 21 +/// formatDate(DateTime(1989, 2, 5), [d]); +/// // => 5 +/// ``` +const String d = 'd'; + +/// Outputs week in month +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 2, 21), [w]); +/// // => 4 +/// ``` +const String w = 'w'; + +/// Outputs week in year as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 12, 31), [W]); +/// // => 53 +/// formatDate(DateTime(1989, 2, 21), [W]); +/// // => 08 +/// ``` +const String WW = 'WW'; + +/// Outputs week in year compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 2, 21), [W]); +/// // => 8 +/// ``` +const String W = 'W'; + +/// Outputs hour (0 - 11) as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15), [hh]); +/// // => 03 +/// ``` +const String hh = 'hh'; + +/// Outputs hour (0 - 11) compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15), [h]); +/// // => 3 +/// ``` +const String h = 'h'; + +/// Outputs hour (0 to 23) as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15), [HH]); +/// // => 15 +/// ``` +const String HH = 'HH'; + +/// Outputs hour (0 to 23) compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 5), [H]); +/// // => 5 +/// ``` +const String H = 'H'; + +/// Outputs minute as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40), [nn]); +/// // => 40 +/// formatDate(DateTime(1989, 02, 1, 15, 4), [nn]); +/// // => 04 +/// ``` +const String nn = 'nn'; + +/// Outputs minute compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 4), [n]); +/// // => 4 +/// ``` +const String n = 'n'; + +/// Outputs second as two digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10), [ss]); +/// // => 10 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 5), [ss]); +/// // => 05 +/// ``` +const String ss = 'ss'; + +/// Outputs second compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40, 5), [s]); +/// // => 5 +/// ``` +const String s = 's'; + +/// Outputs millisecond as three digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 999), [SSS]); +/// // => 999 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]); +/// // => 099 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0), [SS]); +/// // => 009 +/// ``` +const String SSS = 'SSS'; + +/// Outputs millisecond compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 999), [SSS]); +/// // => 999 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]); +/// // => 99 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 9), [SS]); +/// // => 9 +/// ``` +const String S = 'S'; + +/// Outputs microsecond as three digits +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [uuu]); +/// // => 999 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [uuu]); +/// // => 099 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [uuu]); +/// // => 009 +/// ``` +const String uuu = 'uuu'; + +/// Outputs millisecond compactly +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [u]); +/// // => 999 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [u]); +/// // => 99 +/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [u]); +/// // => 9 +/// ``` +const String u = 'u'; + +/// Outputs timezone as time offset +const String z = 'z'; +const String Z = 'Z'; + +/// Escape delimiters to be used as normal string. +/// +/// Example: +/// ``` +/// formatDate(DateTime(1989, 02, 1, 15, 40), [HH,'\\h',nn]); +/// // => 15h40 +///``` +const String escape = r'\'; + +extension DateTimeExtension on DateTime { + /// {@template unix} + /// Number of seconds since epoch time / A.K.A Unix timestamp + /// + /// The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the + /// number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), + /// not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). + /// Literally speaking the epoch is Unix time 0 (midnight 1/1/1970). + /// {@endtemplate} + static DateTime fromSecondsSinceEpoch( + int secondsSinceEpoch, { + bool isUtc = false, + }) => + DateTime.fromMillisecondsSinceEpoch( + secondsSinceEpoch * 1000, + isUtc: isUtc, + ); + + /// {@macro unix} + int get secondsSinceEpoch => millisecondsSinceEpoch ~/ 1000; + + /// Get the numer of milliseconds since epoch + int get timestamp => millisecondsSinceEpoch; + + /// Tomorrow at same hour / minute / second than now + static DateTime get tomorrow => DateTime.now().nextDay; + + /// Yesterday at same hour / minute / second than now + static DateTime get yesterday => DateTime.now().previousDay; + + /// Current date (Same as [DateTime.now]) + static DateTime get today => DateTime.now(); + + /// Subtracts a [Duration] from this [DateTime] + DateTime sub(Duration duration) => add(Duration.zero - duration); + + /// Add a certain amount of milliseconds to this date + DateTime addMilliseconds(int amount) => add(Duration(milliseconds: amount)); + + /// Add a certain amount of microseconds to this date + DateTime addMicroseconds(int amount) => add(Duration(microseconds: amount)); + + /// Add a certain amount of minutes to this date + DateTime addMinutes(int amount, {bool ignoreDaylightSavings = false}) => + ignoreDaylightSavings + ? DateTime( + year, + month, + day, + hour, + minute + amount, + second, + millisecond, + microsecond, + ) + : add(Duration(minutes: amount)); + + /// Add a certain amount of hours to this date + DateTime addHours(int amount, {bool ignoreDaylightSavings = false}) => + ignoreDaylightSavings + ? DateTime( + year, + month, + day, + hour + amount, + minute, + second, + millisecond, + microsecond, + ) + : add(Duration(hours: amount)); + + /// Add a certain amount of days to this date + DateTime addDays(int amount, {bool ignoreDaylightSavings = false}) => + ignoreDaylightSavings + ? DateTime( + year, + month, + day + amount, + hour, + minute, + second, + millisecond, + microsecond, + ) + : add(Duration(days: amount)); + + /// The day after this [DateTime] + DateTime get nextDay => addDays(1); + + /// The day previous this [DateTime] + DateTime get previousDay => addDays(-1); + + /// The month after this [DateTime] + DateTime get nextMonth => setMonth(month + 1); + + /// The month previous this [DateTime] + DateTime get previousMonth => setMonth(month - 1); + + /// The year after this [DateTime] + DateTime get nextYear => setYear(year + 1); + + /// The year previous this [DateTime] + DateTime get previousYear => setYear(year - 1); + + /// The week after this [DateTime] + DateTime get nextWeek => addDays(7); + + /// The week previous this [DateTime] + DateTime get previousWeek => addDays(-7); + + /// Return true if this date [isAfter] [DateTime.now] + bool get isFuture => isAfter(DateTime.now()); + + /// Return true if this date [isBefore] [DateTime.now] + bool get isPast => isBefore(DateTime.now()); + + /// Is the given date in the leap year? + bool get isLeapYear => year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); + + /// Change [year] of this date + DateTime setYear( + int year, [ + int? month, + int? day, + int? hour, + int? minute, + int? second, + int? millisecond, + int? microsecond, + ]) => + DateTime( + year, + month ?? this.month, + day ?? this.day, + hour ?? this.hour, + minute ?? this.minute, + second ?? this.second, + millisecond ?? this.millisecond, + microsecond ?? this.microsecond, + ); + + /// Change [month] of this date + DateTime setMonth( + int month, [ + int? day, + int? hour, + int? minute, + int? second, + int? millisecond, + int? microsecond, + ]) => + DateTime( + year, + month, + day ?? this.day, + hour ?? this.hour, + minute ?? this.minute, + second ?? this.second, + millisecond ?? this.millisecond, + microsecond ?? this.microsecond, + ); + + /// Change [day] of this date + DateTime setDay( + int day, [ + int? hour, + int? minute, + int? second, + int? millisecond, + int? microsecond, + ]) => + DateTime( + year, + month, + day, + hour ?? this.hour, + minute ?? this.minute, + second ?? this.second, + millisecond ?? this.millisecond, + microsecond ?? this.microsecond, + ); + + /// Change [hour] of this date + DateTime setHour( + int hour, [ + int? minute, + int? second, + int? millisecond, + int? microsecond, + ]) => + DateTime( + year, + month, + day, + hour, + minute ?? this.minute, + second ?? this.second, + millisecond ?? this.millisecond, + microsecond ?? this.microsecond, + ); + + /// Change [minute] of this date + DateTime setMinute( + int minute, [ + int? second, + int? millisecond, + int? microsecond, + ]) => + DateTime( + year, + month, + day, + hour, + minute, + second ?? this.second, + millisecond ?? this.millisecond, + microsecond ?? this.microsecond, + ); + + /// Change [second] of this date + DateTime setSecond( + int second, [ + int? millisecond, + int? microsecond, + ]) => + DateTime( + year, + month, + day, + hour, + minute, + second, + millisecond ?? this.millisecond, + microsecond ?? this.microsecond, + ); + + /// Change [millisecond] of this date + DateTime setMillisecond( + int millisecond, [ + int? microsecond, + ]) => + DateTime( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond ?? this.microsecond, + ); + + /// Change [microsecond] of this date + DateTime setMicrosecond( + int microsecond, + ) => + DateTime( + year, + month, + day, + hour, + minute, + second, + millisecond, + microsecond, + ); + + String format(List formats) { + String digits(int value, int length) { + String ret = '$value'; + if (ret.length < length) { + ret = '0' * (length - ret.length) + ret; + } + return ret; + } + + int dayInYear(DateTime date) => date.difference(DateTime(date.year)).inDays; + + final sb = StringBuffer(); + + for (String format in formats) { + if (format.startsWith(escape)) { + format = format.substring(1); + sb.write(format); + } else if (format == yyyy) { + sb.write(digits(year, 4)); + } else if (format == yy) { + sb.write(digits(year % 100, 2)); + } else if (format == mm) { + sb.write(digits(month, 2)); + } else if (format == m) { + sb.write(month); + } else if (format == dd) { + sb.write(digits(day, 2)); + } else if (format == d) { + sb.write(day); + } else if (format == w) { + sb.write((day + 7) ~/ 7); + } else if (format == W) { + sb.write((dayInYear(this) + 7) ~/ 7); + } else if (format == WW) { + sb.write(digits((dayInYear(this) + 7) ~/ 7, 2)); + } else if (format == HH) { + sb.write(digits(hour, 2)); + } else if (format == H) { + sb.write(hour); + } else if (format == hh) { + int h = hour % 12; + if (h == 0) { + h = 12; + } + sb.write(digits(h, 2)); + } else if (format == h) { + int h = hour % 12; + if (h == 0) { + h = 12; + } + sb.write(h); + } else if (format == nn) { + sb.write(digits(minute, 2)); + } else if (format == n) { + sb.write(minute); + } else if (format == ss) { + sb.write(digits(second, 2)); + } else if (format == s) { + sb.write(second); + } else if (format == SSS) { + sb.write(digits(millisecond, 3)); + } else if (format == S) { + sb.write(millisecond); + } else if (format == uuu) { + sb.write(digits(microsecond, 3)); + } else if (format == u) { + sb.write(microsecond); + } else if (format == z) { + if (timeZoneOffset.inMinutes == 0) { + sb.write('Z'); + } else { + if (timeZoneOffset.isNegative) { + sb + ..write('-') + ..write(digits((-timeZoneOffset.inHours) % 24, 2)) + ..write(digits((-timeZoneOffset.inMinutes) % 60, 2)); + } else { + sb + ..write('+') + ..write(digits(timeZoneOffset.inHours % 24, 2)) + ..write(digits(timeZoneOffset.inMinutes % 60, 2)); + } + } + } else if (format == Z) { + sb.write(timeZoneName); + } else { + sb.write(format); + } + } + + return sb.toString(); + } + + bool operator <(DateTime other) => isBefore(other); + + bool operator <=(DateTime other) => + isBefore(other) || isAtSameMomentAs(other); + + bool operator >(DateTime other) => isAfter(other); + + bool operator >=(DateTime other) => isAfter(other) || isAtSameMomentAs(other); +} diff --git a/packages/wyatt_type_utils/lib/src/extensions/encoding.dart b/packages/wyatt_type_utils/lib/src/extensions/encoding.dart new file mode 100644 index 00000000..4a6fb8f7 --- /dev/null +++ b/packages/wyatt_type_utils/lib/src/extensions/encoding.dart @@ -0,0 +1,22 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program 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 +// any later version. +// +// This program 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 . + +enum Encoding { + utf8, + utf16, + base64, + base16, +} diff --git a/packages/wyatt_type_utils/lib/src/extensions/iterable_extension.dart b/packages/wyatt_type_utils/lib/src/extensions/iterable_extension.dart new file mode 100644 index 00000000..d69fd22b --- /dev/null +++ b/packages/wyatt_type_utils/lib/src/extensions/iterable_extension.dart @@ -0,0 +1,55 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program 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 +// any later version. +// +// This program 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 . + +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:wyatt_type_utils/src/extensions/encoding.dart'; + +extension IterableExtension on Iterable? { + /// Returns true if this nullable iterable is either null or empty. + bool get isNullOrEmpty => this == null || this!.isEmpty; + + /// Returns false if this nullable iterable is either null or empty. + bool get isNotNullOrEmpty => this != null && this!.isNotEmpty; +} + +extension IterableIntExtension on Iterable? { + /// Converts an [Iterable] of [int] to a [Uint8List]. + Uint8List toTypedList() => Uint8List.fromList(this?.toList() ?? []); + + /// Converts a [Uint8List] to a [String] using the specified [Encoding]. + String toStr({final Encoding to = Encoding.utf16}) { + String str; + switch (to) { + case Encoding.utf8: + str = utf8.decode(this?.toList() ?? []); + break; + case Encoding.utf16: + str = String.fromCharCodes(this ?? []); + break; + case Encoding.base64: + str = base64.encode(this?.toList() ?? []); + break; + case Encoding.base16: + str = List.generate( + (this ?? []).length, + (i) => (this ?? []).elementAt(i).toRadixString(16).padLeft(2, '0'), + ).join(); + } + return str; + } +} diff --git a/packages/wyatt_type_utils/lib/src/extensions/object_extension.dart b/packages/wyatt_type_utils/lib/src/extensions/object_extension.dart new file mode 100644 index 00000000..11051beb --- /dev/null +++ b/packages/wyatt_type_utils/lib/src/extensions/object_extension.dart @@ -0,0 +1,28 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program 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 +// any later version. +// +// This program 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 . + +import 'dart:developer' as developer; + +extension ObjectExtension on O? { + /// Returns true if the object is null. + bool get isNull => this == null; + + /// Returns true if the object is not null. + bool get isNotNull => this != null; + + /// Prints the object to the console. + void log() => developer.log(toString()); +} diff --git a/packages/wyatt_type_utils/lib/src/extensions/string_extension.dart b/packages/wyatt_type_utils/lib/src/extensions/string_extension.dart new file mode 100644 index 00000000..3e28b3c7 --- /dev/null +++ b/packages/wyatt_type_utils/lib/src/extensions/string_extension.dart @@ -0,0 +1,56 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program 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 +// any later version. +// +// This program 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 . + +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:wyatt_type_utils/src/extensions/encoding.dart'; +import 'package:wyatt_type_utils/src/extensions/iterable_extension.dart'; + +extension StringExtension on String? { + /// Returns true if this string is either null or empty. + bool get isNullOrEmpty => this == null || this!.isEmpty; + + /// Returns false if this string is either null or empty. + bool get isNotNullOrEmpty => this != null && this!.isNotEmpty; + + /// Converts a [String] to a [Uint8List] using the specified [Encoding]. + Uint8List toBytes({final Encoding from = Encoding.utf16}) { + Uint8List bytes; + switch (from) { + case Encoding.utf8: + bytes = utf8.encode(this ?? '').toTypedList(); + break; + case Encoding.utf16: + bytes = (this ?? '').runes.toList().toTypedList(); + break; + case Encoding.base64: + bytes = base64.decode(this ?? ''); + break; + case Encoding.base16: + assert( + (this ?? '').length.isEven, + 'String needs to be an even length.', + ); + bytes = List.generate( + (this ?? '').length ~/ 2, + (i) => + int.parse((this ?? '').substring(i * 2, (i * 2) + 2), radix: 16), + ).toList().toTypedList(); + } + return bytes; + } +} diff --git a/packages/wyatt_type_utils/lib/src/src.dart b/packages/wyatt_type_utils/lib/src/src.dart index 28295d72..34d55694 100644 --- a/packages/wyatt_type_utils/lib/src/src.dart +++ b/packages/wyatt_type_utils/lib/src/src.dart @@ -14,4 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -export 'either_base.dart'; +export 'either/either_base.dart'; +export 'extensions/date_time_extension.dart'; +export 'extensions/encoding.dart'; +export 'extensions/iterable_extension.dart'; +export 'extensions/object_extension.dart'; +export 'extensions/string_extension.dart'; +export 'pair/pair.dart'; diff --git a/packages/wyatt_type_utils/test/extensions_test.dart b/packages/wyatt_type_utils/test/extensions_test.dart new file mode 100644 index 00000000..b7ee4bc0 --- /dev/null +++ b/packages/wyatt_type_utils/test/extensions_test.dart @@ -0,0 +1,116 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program 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 +// any later version. +// +// This program 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 . + +import 'dart:typed_data'; + +import 'package:test/test.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; + +void main() { + group('ObjectExtension ', () { + test('isNull returns true on null object', () { + const int? myObject = null; + expect(myObject.isNull, true); + }); + test('isNull returns false on non-null object', () { + // ignore: unnecessary_nullable_for_final_variable_declarations + const int? myObject = 123; + expect(myObject.isNull, false); + }); + test('isNotNull returns false on null object', () { + const int? myObject = null; + expect(myObject.isNotNull, false); + }); + test('isNotNull returns true on non-null object', () { + // ignore: unnecessary_nullable_for_final_variable_declarations + const int? myObject = 123; + expect(myObject.isNotNull, true); + }); + }); + + group('IterableExtension ', () { + test('isNullOrEmpty returns true on null List', () { + const List? myIterable = null; + expect(myIterable.isNullOrEmpty, true); + }); + test('isNullOrEmpty returns true on empty List', () { + const List myIterable = []; + expect(myIterable.isNullOrEmpty, true); + }); + test('isNotNullOrEmpty returns false on null List', () { + const List? myIterable = null; + expect(myIterable.isNotNullOrEmpty, false); + }); + test('isNotNullOrEmpty returns true on empty List', () { + const List myIterable = []; + expect(myIterable.isNotNullOrEmpty, false); + }); + }); + + group('IterableIntExtension ', () { + test('toTypedList() returns right Uint8List on [1, 2]', () { + const List myIterable = [1, 2]; + expect(myIterable.toTypedList(), Uint8List.fromList([1, 2])); + }); + test('toTypedList() returns empty Uint8List on []', () { + const List myIterable = []; + expect(myIterable.toTypedList(), Uint8List(0)); + }); + test('toStr() returns "abc" on [97,98,99]', () { + const List myIterable = [97, 98, 99]; + expect(myIterable.toStr(), 'abc'); + }); + + test('toStr() returns empty String on []', () { + const List myIterable = []; + expect(myIterable.toStr(), ''); + }); + }); + + group('StringExtension ', () { + test('isNullOrEmpty returns true on null String', () { + const String? myString = null; + expect(myString.isNullOrEmpty, true); + }); + test('isNullOrEmpty returns true on empty String', () { + const String myString = ''; + expect(myString.isNullOrEmpty, true); + }); + test('isNotNullOrEmpty returns false on null String', () { + const String? myString = null; + expect(myString.isNotNullOrEmpty, false); + }); + test('isNotNullOrEmpty returns true on empty String', () { + const String myString = ''; + expect(myString.isNotNullOrEmpty, false); + }); + test('toBytes() returns right Uint8List on "abc"', () { + const String myString = 'abc'; + expect(myString.toBytes(), Uint8List.fromList([97, 98, 99])); + }); + test('toBytes() returns empty Uint8List on empty String', () { + const String myString = ''; + expect(myString.toBytes(), Uint8List(0)); + }); + }); + + group('DateTimeExtension ', () { + test('format() with [dd, mm, yy] works', () { + final DateTime date = DateTime(1999, 6, 30); + expect(date.format([dd, '/', mm, '/', yy]), '30/06/99'); + }); + }); +}