mirror of
https://github.com/hanskokx/arcane_helper_utils.git
synced 2026-05-14 02:19:09 +02:00
v1.4.2
- Added the `isLeapYear` extension to the `DateTime` and `int` objects. - Added the `FixedSizeList` class.
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
## 1.4.2
|
||||
|
||||
- Added the `isLeapYear` extension to the `DateTime` and `int` objects.
|
||||
- Added the `FixedSizeList` class. See the readme and examples for details.
|
||||
|
||||
## 1.4.1
|
||||
|
||||
- Added a `List` equality extension, `equals`.
|
||||
|
||||
@@ -258,6 +258,18 @@ The following operations are now available on a `DateTime` object:
|
||||
final DateTime tomorrow = DateTime(0).tomorrow; // 2024-10-08 00:00:00.000
|
||||
```
|
||||
|
||||
#### Leap Years
|
||||
|
||||
- `isLeapYear`: returns a `bool` corresponding to whether a given year is a leap
|
||||
year. This can also be used directly on an `int`.
|
||||
|
||||
```dart
|
||||
print(DateTime(2024).isLeapYear); // true
|
||||
print(DateTime(2025).isLeapYear); // false
|
||||
print(2024.isLeapYear); // true
|
||||
print(2025.isLeapYear); // false
|
||||
```
|
||||
|
||||
### JWT Parsing
|
||||
|
||||
These extensions enhance the `String` class with JWT-specific functionalities,
|
||||
|
||||
+40
-2
@@ -19,6 +19,11 @@ void main() {
|
||||
print("Yesterday: $yesterday");
|
||||
print("Tomorrow: $tomorrow");
|
||||
|
||||
print(DateTime(2024).isLeapYear); // true
|
||||
print(DateTime(2025).isLeapYear); // false
|
||||
print(2024.isLeapYear); // true
|
||||
print(2025.isLeapYear); // false
|
||||
|
||||
// * Strings
|
||||
const String? nullString = null;
|
||||
const String emptyString = " ";
|
||||
@@ -70,12 +75,45 @@ void main() {
|
||||
|
||||
// * Dynamic debug printing
|
||||
// Debug print the `Person` object before returning the name
|
||||
final String alice = const Person(id: 0, name: "Alice").printValue<Person>().name;
|
||||
final String alice =
|
||||
const Person(id: 0, name: "Alice").printValue<Person>().name;
|
||||
print(alice); // Output: 'Alice'
|
||||
|
||||
// Debug print the `Person` object with a label before returning the name
|
||||
final String bob = const Person(id: 1, name: "Bob").printValue<Person>("Person").name;
|
||||
final String bob =
|
||||
const Person(id: 1, name: "Bob").printValue<Person>("Person").name;
|
||||
print(bob); // Output: 'Bob'
|
||||
|
||||
// * Fixed-size lists
|
||||
// Create a FixedSizeList with a capacity of 3 strings.
|
||||
final recentLogs = FixedSizeList(3);
|
||||
|
||||
// Output: Initial recentLogs: []
|
||||
print("Initial recentLogs: ${recentLogs.items}");
|
||||
|
||||
// Add some log messages.
|
||||
recentLogs.add("Request received at 10:00 AM");
|
||||
print("recentLogs after first add: ${recentLogs.items}");
|
||||
// Output: recentLogs after first add: [Request received at 10:00 AM]
|
||||
recentLogs.add("Processing request...");
|
||||
print("recentLogs after second add: ${recentLogs.items}");
|
||||
// Output: recentLogs after second add: [Request received at 10:00 AM, Processing request...]
|
||||
recentLogs.add("Request completed at 10:05 AM");
|
||||
print("recentLogs after third add: ${recentLogs.items}");
|
||||
// Output: recentLogs after third add: [Request received at 10:00 AM, Processing request..., Request completed at 10:05 AM]
|
||||
|
||||
// Add one more log message, which will cause the oldest one to be removed.
|
||||
recentLogs.add("Sending response...");
|
||||
print("recentLogs after fourth add: ${recentLogs.items}");
|
||||
// Output: recentLogs after fourth add: [Processing request..., Request completed at 10:05 AM, Sending response...]
|
||||
|
||||
// Try to modify the list through the 'items' getter (will throw an error).
|
||||
try {
|
||||
// This will cause an UnsupportedError because 'items' returns an unmodifiable list.
|
||||
recentLogs.items.add("This will fail");
|
||||
} catch (e) {
|
||||
print("Error trying to modify items: $e");
|
||||
}
|
||||
}
|
||||
|
||||
class Person {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
library arcane_helper_utils;
|
||||
|
||||
export "package:arcane_helper_utils/src/classes/fixed_size_list.dart";
|
||||
export "package:arcane_helper_utils/src/extensions/date_time.dart";
|
||||
export "package:arcane_helper_utils/src/extensions/dynamic.dart";
|
||||
export "package:arcane_helper_utils/src/extensions/jwt.dart";
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/// Represents a `List` with a fixed capacity.
|
||||
///
|
||||
/// When a new element is added and the list reaches its maximum capacity,
|
||||
/// the oldest element in the list is automatically removed to make space.
|
||||
class FixedSizeList {
|
||||
final int _capacity;
|
||||
final List<String> _list;
|
||||
|
||||
/// Creates a [FixedSizeList] with the specified [capacity].
|
||||
///
|
||||
/// The initial list will be empty.
|
||||
FixedSizeList(this._capacity) : _list = <String>[];
|
||||
|
||||
/// Adds a new [element] to the list.
|
||||
///
|
||||
/// If the list is already at its maximum [capacity], the oldest element
|
||||
/// will be removed before the new [element] is added.
|
||||
void add(String element) {
|
||||
_list.add(element);
|
||||
if (_list.length > _capacity) {
|
||||
_list.removeAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an unmodifiable view of the current items in the list.
|
||||
///
|
||||
/// This prevents external modification of the internal list.
|
||||
List<String> get items => List.unmodifiable(_list);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import "package:week_number/iso.dart";
|
||||
|
||||
/// An extension on `DateTime` to get the start and end of various time periods.
|
||||
extension StartAndEndOfPeriod on DateTime {
|
||||
/// Returns a `DateTime` object representing the start of the hour.
|
||||
@@ -141,3 +139,17 @@ extension YesterdayAndTomorrow on DateTime {
|
||||
DateTime get tomorrow =>
|
||||
DateTime.now().add(const Duration(days: 1)).startOfDay;
|
||||
}
|
||||
|
||||
extension IsLeapYear on DateTime {
|
||||
/// Returns `true` if the year is a leap year, otherwise returns `false`.
|
||||
bool get isLeapYear => year.isLeapYear;
|
||||
}
|
||||
|
||||
extension IsIntLeapYear on int {
|
||||
/// Returns `true` if the given value would be considered a leap year,
|
||||
/// otherwise returns `false`.
|
||||
bool get isLeapYear =>
|
||||
!this.isNegative &&
|
||||
this > 0 &&
|
||||
((this * 1073750999) & 3221352463) <= 126976;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
name: arcane_helper_utils
|
||||
description: Provides a variety of helpful utilities and extensions for Flutter
|
||||
and Dart.
|
||||
version: 1.4.1
|
||||
version: 1.4.2
|
||||
repository: https://github.com/hanskokx/arcane_helper_utils
|
||||
issue_tracker: https://github.com/hanskokx/arcane_helper_utils/issues
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import "package:arcane_helper_utils/arcane_helper_utils.dart";
|
||||
import "package:test/test.dart";
|
||||
|
||||
void main() {
|
||||
group("FixedSizeList", () {
|
||||
test("initial list is empty", () {
|
||||
final list = FixedSizeList(5);
|
||||
expect(list.items, isEmpty);
|
||||
});
|
||||
|
||||
test("adding elements below capacity", () {
|
||||
final list = FixedSizeList(3);
|
||||
list.add("one");
|
||||
expect(list.items, ["one"]);
|
||||
list.add("two");
|
||||
expect(list.items, ["one", "two"]);
|
||||
});
|
||||
|
||||
test("adding elements up to capacity", () {
|
||||
final list = FixedSizeList(2);
|
||||
list.add("a");
|
||||
list.add("b");
|
||||
expect(list.items, ["a", "b"]);
|
||||
});
|
||||
|
||||
test("adding elements beyond capacity removes the oldest", () {
|
||||
final list = FixedSizeList(2);
|
||||
list.add("first");
|
||||
list.add("second");
|
||||
expect(list.items, ["first", "second"]);
|
||||
list.add("third");
|
||||
expect(list.items, ["second", "third"]);
|
||||
list.add("fourth");
|
||||
expect(list.items, ["third", "fourth"]);
|
||||
});
|
||||
|
||||
test("capacity of zero results in an empty list that stays empty", () {
|
||||
final list = FixedSizeList(0);
|
||||
list.add("anything");
|
||||
expect(list.items, isEmpty);
|
||||
list.add("something else");
|
||||
expect(list.items, isEmpty);
|
||||
});
|
||||
|
||||
test("items getter returns an unmodifiable list", () {
|
||||
final list = FixedSizeList(2);
|
||||
list.add("alpha");
|
||||
list.add("beta");
|
||||
final items = list.items;
|
||||
expect(() => items.add("gamma"), throwsUnsupportedError);
|
||||
|
||||
// Ensure original list is not modified
|
||||
expect(list.items, ["alpha", "beta"]);
|
||||
});
|
||||
|
||||
test("adding multiple elements beyond capacity", () {
|
||||
final list = FixedSizeList(1);
|
||||
list.add("one");
|
||||
list.add("two");
|
||||
list.add("three");
|
||||
list.add("four");
|
||||
expect(list.items, ["four"]);
|
||||
});
|
||||
|
||||
test("adding the same element multiple times", () {
|
||||
final list = FixedSizeList(3);
|
||||
list.add("same");
|
||||
list.add("same");
|
||||
list.add("same");
|
||||
expect(list.items, ["same", "same", "same"]);
|
||||
list.add("different");
|
||||
expect(list.items, ["same", "same", "different"]);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -96,5 +96,16 @@ void main() {
|
||||
DateTime(now.year, now.month, now.day).add(const Duration(days: 1));
|
||||
expect(DateTime.now().tomorrow, expected);
|
||||
});
|
||||
|
||||
test("leap year calculations work as expected", () {
|
||||
expect(DateTime(0).isLeapYear, false);
|
||||
expect(DateTime(2024).isLeapYear, true);
|
||||
expect(DateTime(2025).isLeapYear, false);
|
||||
|
||||
expect((-1).isLeapYear, false);
|
||||
expect(0.isLeapYear, false);
|
||||
expect(2024.isLeapYear, true);
|
||||
expect(2025.isLeapYear, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user