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() {