Beispiel
equatable 2.1.0: Prove that EquatableMixin enables deep value equality and collection hashing across custom class hierarchies, comparing nested collections value-wise with order-sensitive lists and order-insensitive sets.
Verifiziertes Beispiel für pub equatable 2.1.0: Prove that EquatableMixin enables deep value equality and collection hashing across custom class hierarchies…
sha256:c163a38f5194f0eb07aa45ccd20fc7a734b270d21970668425694c9f4f7cdf14
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 2
- Signaturschlüssel, die es gebaut haben
- 2
Deklarierte Umgebung
dart linux x64 dart dart pub
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| dart 3 · linux debian/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · pub@1 |
2026-08-17 |
| dart 3 · linux debian/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · pub@1 |
2026-08-18 |
Fall
HOW- Ziel
- Prove that EquatableMixin enables deep value equality and collection hashing across custom class hierarchies, comparing nested collections value-wise with order-sensitive lists and order-insensitive sets.
- Pakete
- Symbole
-
- EquatableMixin
- Equatable.props
- Equatable.hashCode
- Equatable.==
- Umgebung
- dart
- Erstellt
- 2026-08-17T18:01:36Z
Contract
- A class applying EquatableMixin compares equal and produces identical hash codes to matching instances across deep nested collections, evaluating lists order-sensitively and sets order-insensitively.
- EquatableMixin allows classes in single-inheritance hierarchies to obtain value equality and hash code parity based on overridden props.
- Nested lists in props require matching element order, whereas nested sets compare equal regardless of element insertion order.
- Deeply nested collections including maps of lists evaluate equality recursively down to leaf elements.
- Equal EquatableMixin instances properly deduplicate in Set collections and look up correctly as Map keys.
- Props containing null values or empty props lists are safely compared without runtime exceptions.
Dateien
- NOTES.md
- csx.json
- lib/equatable_models.dart
- pubspec.lock
- pubspec.yaml
- test/contract.dart
Quelltext
# Equatable Value Equality and EquatableMixin Deep Collection Semantics
## Prior Search Findings
Querying known solutions returned existing samples:
- `sha256:bec4ea595f73e58cfacf6eb4297d3478d35d6f1994148f087b6ebcf9904d4aec` (focused on `toString()` defaulting to class name unless `stringify` is enabled)
- `sha256:5c27c62458688e4ad17910025eef68c78ea3ce05d37db332add13fcfe5ddc813` (focused on generic type arguments `Box<num>` vs `Box<int>` across `runtimeType` equality checks)
- `sha256:638569f72975ef43e0399c530603821213e7e6af72feecd957cbdbbe96b32af5` (focused on assertion mode and `toString()` output)
This sample tests and verifies a distinct set of behaviors: utilizing `EquatableMixin` in classes with existing inheritance hierarchies, and the precise deep collection equality rules across nested lists, sets, maps, null props, and empty props.
## Pinned Release
- `equatable`: `2.1.0` (hosted on pub.dev)
- Transitive dependencies: `collection: 1.19.1`, `meta: 1.19.0`
- Dart SDK constraint: `>=3.5.0 <4.0.0`
## Observed Behavior
1. **Hierarchy Integration via `EquatableMixin`**: Dart does not support multiple inheritance. Classes that already extend a base class can mix in `EquatableMixin` to gain value equality and consistent `hashCode` computation without inheriting from `Equatable`.
2. **Deep Collection Equality in `props`**:
- **`List` Properties**: Evaluated element-by-element with index order preserved. Two lists containing identical elements in different order (`['a', 'b']` vs `['b', 'a']`) evaluate as not equal.
- **`Set` Properties**: Evaluated with set semantics where insertion order is ignored. Two sets containing identical elements in different orders (`{'read', 'write'}` vs `{'write', 'read'}`) evaluate as equal and share the same hash code.
- **`Map` Properties**: Evaluated by key-value pairing regardless of key insertion order.
- **Arbitrarily Nested Collections**: Heterogeneous nested structures (e.g. `List<Map<String, List<int>>>`) are traversed recursively and compared value-wise down to the leaf values.
3. **Collection Integration**: Equal `EquatableMixin` instances correctly deduplicate in Dart `Set` instances and function deterministically as keys in `Map` lookups.
4. **Nullable and Empty Props**: Instances with `null` fields in `props` compare safely without null reference exceptions, and instances with empty `props` (`[]`) evaluate as equal to matching empty instances of the same class.
{"case":{"caseId":"case:sha256:24b0ffe65236719c5468e80c6385116993d65fdb8029692c143c4a9440e67ce2","contract":["A class applying EquatableMixin compares equal and produces identical hash codes to matching instances across deep nested collections, evaluating lists order-sensitively and sets order-insensitively.","EquatableMixin allows classes in single-inheritance hierarchies to obtain value equality and hash code parity based on overridden props.","Nested lists in props require matching element order, whereas nested sets compare equal regardless of element insertion order.","Deeply nested collections including maps of lists evaluate equality recursively down to leaf elements.","Equal EquatableMixin instances properly deduplicate in Set collections and look up correctly as Map keys.","Props containing null values or empty props lists are safely compared without runtime exceptions."],"goal":"Prove that EquatableMixin enables deep value equality and collection hashing across custom class hierarchies, comparing nested collections value-wise with order-sensitive lists and order-insensitive sets.","kind":"HOW","packages":["pkg:pub/equatable@2.1.0"],"schemaVersion":1,"symbols":["EquatableMixin","Equatable.props","Equatable.hashCode","Equatable.=="]},"contractCommand":["dart","test/contract.dart"],"environment":{"arch":"x64","ecosystem":"pub","executionContext":"dart","language":"dart","os":"linux","packageManager":"pub","runtime":"dart","schemaVersion":1},"license":"MIT-0","packages":["pkg:pub/equatable@2.1.0"],"schemaVersion":1,"symbols":["EquatableMixin","Equatable.props","Equatable.hashCode","Equatable.=="],"verifierAdapter":"pub@1"}
import 'package:equatable/equatable.dart';
/// An abstract base entity representing an item with an identifier.
abstract class BaseEntity {
const BaseEntity({required this.id});
final String id;
}
/// A domain model that inherits from [BaseEntity] and mixes in [EquatableMixin]
/// to gain value-based equality and hash code calculation without multiple inheritance.
class UserProfile extends BaseEntity with EquatableMixin {
const UserProfile({
required super.id,
required this.name,
required this.tags,
required this.roles,
required this.metadata,
});
final String name;
final List<String> tags;
final Set<String> roles;
final Map<String, dynamic> metadata;
@override
List<Object?> get props => [id, name, tags, roles, metadata];
}
/// An entity with empty props demonstrating identity equality fallback behavior.
class EmptyEntity extends Equatable {
const EmptyEntity();
@override
List<Object?> get props => [];
}
/// An entity with nullable fields demonstrating safe null comparison in props.
class NullableEntity extends Equatable {
const NullableEntity(this.first, this.second);
final String? first;
final int? second;
@override
List<Object?> get props => [first, second];
}
/// A container with deep nested collections (lists of maps containing lists).
class NestedContainer extends BaseEntity with EquatableMixin {
const NestedContainer({
required super.id,
required this.matrix,
});
final List<Map<String, List<int>>> matrix;
@override
List<Object?> get props => [id, matrix];
}
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
collection:
dependency: transitive
description:
name: collection
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.19.1"
equatable:
dependency: "direct main"
description:
name: equatable
sha256: "3bce007a596ff8b3119c45d68aaef631272537c03d30e5d4534dd24bf4c5eaa2"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
meta:
dependency: transitive
description:
name: meta
sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9"
url: "https://pub.dev"
source: hosted
version: "1.19.0"
sdks:
dart: ">=3.5.0 <4.0.0"
name: equatable_value_equality
description: Proves EquatableMixin deep value equality and collection hashing semantics.
publish_to: none
environment:
sdk: '>=3.5.0 <4.0.0'
dependencies:
equatable: 2.1.0
import 'package:equatable_value_equality/equatable_models.dart';
void check(bool condition, String message) {
if (!condition) {
throw StateError('Assertion failed: $message');
}
}
void main() {
// 1. EquatableMixin on classes extending a custom base class
final user1 = UserProfile(
id: 'user_100',
name: 'Alice',
tags: ['admin', 'editor'],
roles: {'read', 'write'},
metadata: {
'settings': {'darkMode': true, 'level': 5},
'scores': [90, 95],
},
);
final user2 = UserProfile(
id: 'user_100',
name: 'Alice',
tags: ['admin', 'editor'],
roles: {'write', 'read'}, // Different Set insertion order -> still equal
metadata: {
'settings': {'level': 5, 'darkMode': true}, // Different Map insertion order -> still equal
'scores': [90, 95],
},
);
// Equal instances verify == and hashCode parity
check(user1 == user2, 'Instances with identical props must be equal');
check(
user1.hashCode == user2.hashCode,
'Equal instances must produce identical hashCodes',
);
// 2. Order-sensitivity in Lists vs Order-insensitivity in Sets
final userWithReversedList = UserProfile(
id: 'user_100',
name: 'Alice',
tags: ['editor', 'admin'], // Different List order -> NOT equal
roles: {'read', 'write'},
metadata: {
'settings': {'darkMode': true, 'level': 5},
'scores': [90, 95],
},
);
check(
user1 != userWithReversedList,
'Lists in props are order-sensitive and must not compare equal when reordered',
);
// 3. Set deduplication and Map key lookup
final userSet = <UserProfile>{user1};
check(userSet.contains(user2), 'Set must recognize equal instance as present');
userSet.add(user2);
check(userSet.length == 1, 'Set must deduplicate equal instances');
final userMap = <UserProfile, String>{user1: 'AliceProfile'};
check(
userMap[user2] == 'AliceProfile',
'Map must retrieve value using an equal instance key',
);
check(
userMap.containsKey(user2),
'Map must confirm key existence for equal instance',
);
// 4. Arbitrarily deep nested collection equality
final nestedA = NestedContainer(
id: 'matrix_01',
matrix: [
{
'coords': [10, 20, 30],
'weights': [1, 2],
},
{
'bounds': [0, 100],
},
],
);
final nestedB = NestedContainer(
id: 'matrix_01',
matrix: [
{
'weights': [1, 2], // Reordered map keys
'coords': [10, 20, 30],
},
{
'bounds': [0, 100],
},
],
);
final nestedC = NestedContainer(
id: 'matrix_01',
matrix: [
{
'coords': [10, 20, 31], // Changed nested leaf element
'weights': [1, 2],
},
{
'bounds': [0, 100],
},
],
);
check(nestedA == nestedB, 'Deep nested collections must evaluate equal');
check(
nestedA.hashCode == nestedB.hashCode,
'Deep nested collections with equivalent values must share hashCode',
);
check(
nestedA != nestedC,
'Deep nested collections with differing leaf elements must not be equal',
);
// 5. Safe handling of nullable properties
const nullEntity1 = NullableEntity(null, null);
const nullEntity2 = NullableEntity(null, null);
const nonNullEntity = NullableEntity('active', null);
check(
nullEntity1 == nullEntity2,
'Instances with matching null props must compare equal',
);
check(
nullEntity1.hashCode == nullEntity2.hashCode,
'Null prop instances must share identical hashCodes',
);
check(
nullEntity1 != nonNullEntity,
'Instances with mismatched null vs non-null props must not compare equal',
);
// 6. Empty props equality
const empty1 = EmptyEntity();
const empty2 = EmptyEntity();
check(empty1 == empty2, 'Instances with empty props must compare equal');
check(
empty1.hashCode == empty2.hashCode,
'Empty props instances must share identical hashCodes',
);
}