Equatable v0.6.0 (#34)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55bd410..d37e202 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 0.6.0
+
+- The `props` getter override is required for both `Equatable` and `EquatableMixin`
+- Performance Improvements
+
# 0.5.1
- Allow const constructors on `Equatable` class
diff --git a/README.md b/README.md
index 793f89b..3dcd30c 100644
--- a/README.md
+++ b/README.md
@@ -101,7 +101,7 @@
```yaml
dependencies:
- equatable: ^0.5.0
+ equatable: ^0.6.0
```
Next, we need to install it:
@@ -122,7 +122,10 @@
class Person extends Equatable {
final String name;
- Person(this.name) : super([name]);
+ Person(this.name);
+
+ @override
+ List<Object> get props => [name];
}
```
@@ -134,7 +137,10 @@
class Person extends Equatable {
final String name;
- Person(this.name) : super([name]);
+ Person(this.name);
+
+ @override
+ List<Object> get props => [name];
factory Person.fromJson(Map<String, dynamic> json) {
return Person(json['name']);
@@ -145,7 +151,7 @@
We can now compare instances of `Person` just like before without the pain of having to write all of that boilerplate.
**Note:** Equatable is designed to only work with immutable objects so all member variables must be final.
-Equatable also supports `const` constructors but you'll need to override `props` instead of passing the props to super.
+Equatable also supports `const` constructors:
```dart
import 'package:equatable/equatable.dart';
@@ -190,7 +196,10 @@
class Person extends Equatable {
final String name;
- Person(this.name) : super([name]);
+ Person(this.name);
+
+ @override
+ List<Object> get props => [name];
}
```
@@ -256,16 +265,18 @@
#### Equality Comparison A == A
-| Class | Runtime (microseconds) |
-| ------------------ | ---------------------- |
-| RAW | 0.143 |
-| Empty Equatable | 0.124 |
-| Hydrated Equatable | 0.126 |
+| Class | Runtime (μs) |
+| ------------------ | ------------ |
+| RAW | 0.193 |
+| Empty Equatable | 0.191 |
+| Hydrated Equatable | 0.190 |
#### Instantiation A()
-| Class | Runtime (microseconds) |
-| ------------------ | ---------------------- |
-| RAW | 0.099 |
-| Empty Equatable | 0.121 |
-| Hydrated Equatable | 0.251 |
+| Class | Runtime (μs) |
+| ------------------ | ------------ |
+| RAW | 0.165 |
+| Empty Equatable | 0.181 |
+| Hydrated Equatable | 0.182 |
+
+\*_Performance Tests run using: Dart VM version: 2.4.0_
diff --git a/example/main.dart b/example/main.dart
index 6f3975f..0286a15 100644
--- a/example/main.dart
+++ b/example/main.dart
@@ -4,14 +4,7 @@
final String username;
final String password;
- Credentials({this.username, this.password}) : super([username, password]);
-}
-
-class ConstCredentials extends Equatable {
- final String username;
- final String password;
-
- ConstCredentials({this.username, this.password});
+ const Credentials({this.username, this.password});
@override
List<Object> get props => [username, password];
@@ -38,25 +31,14 @@
void main() {
// Extending Equatable
final credentialsA = Credentials(username: 'Joe', password: 'password123');
- final constCredentialsA =
- ConstCredentials(username: 'Joe', password: 'password123');
final credentialsB = Credentials(username: 'Bob', password: 'password!');
- final constCredentialsB =
- ConstCredentials(username: 'Bob', password: 'password!');
final credentialsC = Credentials(username: 'Bob', password: 'password!');
- final constCredentialsC =
- ConstCredentials(username: 'Bob', password: 'password!');
print(credentialsA == credentialsA); // true
- print(constCredentialsA == constCredentialsA); // true
print(credentialsB == credentialsB); // true
- print(constCredentialsB == constCredentialsB); // true
print(credentialsC == credentialsC); // true
- print(constCredentialsC == constCredentialsC); // true
print(credentialsA == credentialsB); // false
- print(constCredentialsA == constCredentialsB); // false
print(credentialsB == credentialsC); // true
- print(constCredentialsB == constCredentialsC); // true
// Equatable Mixin
final dateTimeA = EquatableDateTime(2019);
diff --git a/lib/src/equatable.dart b/lib/src/equatable.dart
index 1abd033..f5b0674 100644
--- a/lib/src/equatable.dart
+++ b/lib/src/equatable.dart
@@ -20,18 +20,12 @@
abstract class Equatable {
/// The [List] of `props` (properties) which will be used to determine whether
/// two [Equatables] are equal.
- final List props;
+ List<Object> get props;
/// A class that helps implement equality
/// without needing to explicitly override == and [hashCode].
- /// Equatables override their own == and [hashCode] based on
- /// the provided `properties`.
- ///
- /// The constructor takes an optional [List] of `props` (properties) which
- /// will be used to determine whether two [Equatables] are equal.
- /// If no properties are provided, `props` will be initialized to
- /// an empty [List].
- const Equatable([this.props = const []]);
+ /// Equatables override their own `==` operator and [hashCode] based on their `props`.
+ const Equatable();
@override
bool operator ==(Object other) =>
diff --git a/lib/src/equatable_mixin.dart b/lib/src/equatable_mixin.dart
index b1a9f6f..72400dc 100644
--- a/lib/src/equatable_mixin.dart
+++ b/lib/src/equatable_mixin.dart
@@ -5,6 +5,8 @@
///
/// [EquatableMixin] does the override of the `==` operator as well as `hashCode`.
mixin EquatableMixin {
+ /// The [List] of `props` (properties) which will be used to determine whether
+ /// two [Equatables] are equal.
List<Object> get props;
@override
diff --git a/performance_tests/main.dart b/performance_tests/main.dart
index 1dbd241..cb3dc24 100644
--- a/performance_tests/main.dart
+++ b/performance_tests/main.dart
@@ -1,13 +1,21 @@
import 'package:equatable/equatable.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
-class EmptyEquatable extends Equatable {}
+class EmptyEquatable extends Equatable {
+ const EmptyEquatable();
+
+ @override
+ List<Object> get props => null;
+}
class LoginEvent extends Equatable {
final String username;
final String password;
- LoginEvent({this.username, this.password}) : super([username, password]);
+ const LoginEvent({this.username, this.password});
+
+ @override
+ List get props => [username, password];
}
class LoginEventRaw {
diff --git a/pubspec.yaml b/pubspec.yaml
index 74f50f1..57e1659 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: equatable
description: An abstract class that helps to implement equality without needing to explicitly override == and hashCode.
-version: 0.5.1
+version: 0.6.0
author: Felix Angelov <felangelov@gmail.com>
homepage: https://github.com/felangel/equatable
diff --git a/test/equatable_test.dart b/test/equatable_test.dart
index 0f4eb71..d7f1ce6 100644
--- a/test/equatable_test.dart
+++ b/test/equatable_test.dart
@@ -8,25 +8,39 @@
class NonEquatable {}
-class EmptyEquatable extends Equatable {}
+class EmptyEquatable extends Equatable {
+ @override
+ List<Object> get props => [];
+
+ const EmptyEquatable();
+}
class SimpleEquatable<T> extends Equatable {
final T data;
- SimpleEquatable(this.data) : super([data]);
+ const SimpleEquatable(this.data);
+
+ @override
+ List<Object> get props => [data];
}
class MultipartEquatable<T> extends Equatable {
final T d1;
final T d2;
- MultipartEquatable(this.d1, this.d2) : super([d1, d2]);
+ MultipartEquatable(this.d1, this.d2);
+
+ @override
+ List<Object> get props => [d1, d2];
}
class OtherEquatable extends Equatable {
final String data;
- OtherEquatable(this.data) : super([data]);
+ const OtherEquatable(this.data);
+
+ @override
+ List<Object> get props => [data];
}
enum Color { blonde, black, brown }
@@ -37,22 +51,27 @@
final Color hairColor;
final List<String> children;
- ComplexEquatable({this.name, this.age, this.hairColor, this.children})
- : super([name, age, hairColor, children]);
+ const ComplexEquatable({this.name, this.age, this.hairColor, this.children});
+
+ @override
+ List<Object> get props => [name, age, hairColor, children];
}
class EquatableData extends Equatable {
final String key;
final dynamic value;
- EquatableData({this.key, this.value}) : super([key, value]);
+ const EquatableData({this.key, this.value});
+
+ @override
+ List<Object> get props => [key, value];
}
class Credentials extends Equatable {
final String username;
final String password;
- Credentials({this.username, this.password}) : super([username, password]);
+ const Credentials({this.username, this.password});
factory Credentials.fromJson(Map<String, dynamic> json) {
return Credentials(
@@ -67,6 +86,9 @@
data['password'] = this.password;
return data;
}
+
+ @override
+ List<Object> get props => [username, password];
}
void main() {