diff --git a/CHANGELOG.md b/CHANGELOG.md index 0037edf..f60dc45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +## 1.9.31 + +- Bug fixes: + - `ConditionSQLEncoder.valueToParameterValue`: fixed encoding of a `List` of values containing `ConditionParameter`s; each element is now resolved individually instead of passing the whole list to every element. + - `ConditionEncoder.resolveValueToType`: fixed resolution of a single-element `Iterable` to a primitive type (was a no-op comparison instead of an assignment, leaving the value as a `List`). + - `MapGetterExtension.matchKeyIgnoreCase`: fixed case-insensitive key matching that always returned `null` (empty loop body); now returns the matching key. Also fixes `setMultiValue(..., ignoreCase: true)`. + - `Time`: `millisecond`/`microsecond` range validation now correctly rejects `1000` (valid range is `0..999`). + - `Time._bytesInStringFormat`: fixed the second-byte digit check that was effectively disabled (`length < 2` instead of `length >= 2`). + - `APISession.isExpired`: now honors the provided `now` argument instead of always using `DateTime.now()`. + - `APIServerResponseCache` cached entry: `replaceFileStat` no longer compares a variable to itself (`identical(myFileStat, myFileStat)`), so the file stat is correctly replaced. + - `WeakList.set`: now increments the internal modification counter, consistent with the other mutating methods. + +- Tests: + - Added tests covering the bug fixes above (`Time` range/string parsing, `matchKeyIgnoreCase`/`getIgnoreCase`/`setMultiValue`, `APISession.isExpired`, and `ConditionSQLEncoder`/`ConditionEncoder` value resolution). + ## 1.9.30 - `APIRootStarter`: diff --git a/lib/src/bones_api_base.dart b/lib/src/bones_api_base.dart index 576447a..de2336e 100644 --- a/lib/src/bones_api_base.dart +++ b/lib/src/bones_api_base.dart @@ -48,7 +48,7 @@ typedef APILogger = /// Bones API Library class. class BonesAPI { // ignore: constant_identifier_names - static const String VERSION = '1.9.30'; + static const String VERSION = '1.9.31'; static bool _boot = false; diff --git a/lib/src/bones_api_condition_encoder.dart b/lib/src/bones_api_condition_encoder.dart index a8047a5..25f42c0 100644 --- a/lib/src/bones_api_condition_encoder.dart +++ b/lib/src/bones_api_condition_encoder.dart @@ -1543,7 +1543,7 @@ abstract class ConditionEncoder { if (listLength == 0) { return null; } else if (listLength == 1) { - value == list.first; + value = list.first; } else { throw ArgumentError( "Can't resolve a `List` with mutiple values to a primitive type: $valueTypeInfo >> $value", @@ -1551,6 +1551,8 @@ abstract class ConditionEncoder { } } + if (value == null) return null; + var parsedValue = valueParser(value); if (parsedValue != null) { return parsedValue; diff --git a/lib/src/bones_api_condition_sql.dart b/lib/src/bones_api_condition_sql.dart index 6fe2c4b..1c4414e 100644 --- a/lib/src/bones_api_condition_sql.dart +++ b/lib/src/bones_api_condition_sql.dart @@ -633,7 +633,7 @@ class ConditionSQLEncoder extends ConditionEncoder { value.map((v) { if (v is ConditionParameter) { return conditionParameterToParameterValue( - value, + v, context, fieldKey, fieldType, @@ -641,7 +641,7 @@ class ConditionSQLEncoder extends ConditionEncoder { ); } else { return _valueToParameterValueImpl( - value, + v, fieldType, key: fieldKey, valueAsList: valueAsList, diff --git a/lib/src/bones_api_extension.dart b/lib/src/bones_api_extension.dart index 304a70c..16de970 100644 --- a/lib/src/bones_api_extension.dart +++ b/lib/src/bones_api_extension.dart @@ -248,7 +248,9 @@ extension MapGetterExtension on Map { var keyStr = key.toString(); for (var k in keys) { - if (equalsIgnoreAsciiCase(keyStr, k.toString())) {} + if (equalsIgnoreAsciiCase(keyStr, k.toString())) { + return k; + } } return null; diff --git a/lib/src/bones_api_server_cache.dart b/lib/src/bones_api_server_cache.dart index 6a2299f..a113b85 100644 --- a/lib/src/bones_api_server_cache.dart +++ b/lib/src/bones_api_server_cache.dart @@ -834,7 +834,7 @@ abstract class _CachedResponse if (fileStat == null) return; var myFileStat = _fileStat; - if (identical(myFileStat, myFileStat)) return; + if (identical(myFileStat, fileStat)) return; if (myFileStat == null || myFileStat.file == fileStat.file) { fileStat.updateFrom(myFileStat); diff --git a/lib/src/bones_api_session.dart b/lib/src/bones_api_session.dart index 3d0c5ad..fbc43a9 100644 --- a/lib/src/bones_api_session.dart +++ b/lib/src/bones_api_session.dart @@ -66,7 +66,7 @@ class APISession { bool isExpired(Duration timeout, {DateTime? now}) { now ??= DateTime.now(); - var elapsedTime = lastAccessElapsedTime; + var elapsedTime = now.difference(lastAccessTime); return elapsedTime.compareTo(timeout) > 0; } diff --git a/lib/src/bones_api_test_utils_freeport.dart b/lib/src/bones_api_test_utils_freeport.dart index 5d7e669..ec19918 100644 --- a/lib/src/bones_api_test_utils_freeport.dart +++ b/lib/src/bones_api_test_utils_freeport.dart @@ -5,7 +5,6 @@ import 'package:docker_commander/docker_commander_vm.dart'; final Set _initFreePorts = {}; -@override Future resolveFreePort(int port) { var startPort = port - 100; var endPort = port + 100; diff --git a/lib/src/bones_api_types.dart b/lib/src/bones_api_types.dart index 4a2d4a8..a8809bf 100644 --- a/lib/src/bones_api_types.dart +++ b/lib/src/bones_api_types.dart @@ -43,7 +43,7 @@ class Time implements Comparable