Skip to content

Commit

Permalink
feat!: nullsafety (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
felangel authored Mar 2, 2021
1 parent a1a7791 commit d7f5053
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 184 deletions.
10 changes: 4 additions & 6 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,21 @@ on:
branches:
- master
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
container:
image: google/dart:2.8.4
image: google/dart:2.12-dev
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: pub get
- name: Format
run: dartfmt --dry-run --set-exit-if-changed .
run: dart format .
- name: Analyze
run: dartanalyzer --fatal-infos --fatal-warnings lib test
- name: Run tests
run: pub run test_coverage
run: dart test --coverage=coverage && dart run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.packages --report-on=lib
- name: Check Code Coverage
uses: ChicagoFlutter/lcov-cop@v1.0.0
uses: VeryGoodOpenSource/very_good_coverage@v1.1.1
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
# 2.0.0

- **BREAKING**: opt into null safety
- feat!: upgrade Dart SDK constraints to `>=2.12.0-0 <3.0.0`
- **BREAKING**: stringify prints "null" for null properties instead of ""
- feat: `EquatableConfig.stringify` defaults to `true` in debug mode.
- fix: support legacy equality overrides with `EquatableMixin`
- fix: iterable equality comparisons ([#101](https://github.com/felangel/equatable/issues/101))
- fix: stringify instance with long properties ([#94](https://github.com/felangel/equatable/issues/94))
- chore: update dependencies
- `collection: ^1.15.0`
- `meta: ^1.3.0`
- docs: minor updates to `README` and `example`

# 2.0.0-nullsafety.4

- feat: `EquatableConfig.stringify` defaults to `true` in debug mode.
- fix: support legacy equality overrides with `EquatableMixin`

# 2.0.0-nullsafety.3

- chore: update dependencies
- `collection: ^1.15.0`
- `meta: ^1.3.0`

# 2.0.0-nullsafety.2

- fix: iterable equality comparisons ([#101](https://github.com/felangel/equatable/issues/101))
- fix: stringify instance with long properties ([#94](https://github.com/felangel/equatable/issues/94))

# 2.0.0-nullsafety.1

- **BREAKING**: stringify prints "null" for null properties instead of ""

# 2.0.0-nullsafety.0

- **BREAKING**: opt into null safety
- feat!: upgrade Dart SDK constraints to `>=2.12.0-0 <3.0.0`
- docs: minor updates to `README` and `example`

# 1.2.6

- fix: iterable equality comparisons ([#101](https://github.com/felangel/equatable/issues/101))
Expand Down
42 changes: 22 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ Let's say we have the following class:

```dart
class Person {
final String name;
const Person(this.name);
final String name;
}
```

Expand All @@ -68,10 +68,10 @@ In order to be able to compare two instances of `Person` we need to change our c

```dart
class Person {
final String name;
const Person(this.name);
final String name;
@override
bool operator ==(Object other) =>
identical(this, other) ||
Expand Down Expand Up @@ -108,7 +108,7 @@ First, we need to do add `equatable` to the dependencies of the `pubspec.yaml`

```yaml
dependencies:
equatable: ^1.2.5
equatable: ^2.0.0
```
Next, we need to install it:
Expand All @@ -127,9 +127,9 @@ Lastly, we need to extend `Equatable`
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
const Person(this.name);
Person(this.name);
final String name;
@override
List<Object> get props => [name];
Expand All @@ -142,9 +142,9 @@ When working with json:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
const Person(this.name);
Person(this.name);
final String name;
@override
List<Object> get props => [name];
Expand All @@ -164,22 +164,22 @@ Equatable also supports `const` constructors:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
const Person(this.name);
final String name;
@override
List<Object> get props => [name];
}
```

### `toString` Implementation

Equatable can implement `toString` method including all the given props. If you want that behaviour, just include the following:
Equatable can implement `toString` method including all the given props. If you want that behaviour for a specific `Equatable` object, just include the following:

```dart
@override
bool get stringify => true;
@override
bool get stringify => true;
```

For instance:
Expand All @@ -188,10 +188,10 @@ For instance:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
const Person(this.name);
final String name;
@override
List<Object> get props => [name];
Expand Down Expand Up @@ -219,16 +219,18 @@ EquatableConfig.stringify = true;
If `stringify` is overridden for a specific `Equatable` class, then the value of `EquatableConfig.stringify` is ignored.
In other words, the local configuration always takes precedence over the global configuration.

_Note: `EquatableConfig.stringify` defaults to `true` in debug mode and `false` in release mode._

## Recap

### Without Equatable

```dart
class Person {
final String name;
const Person(this.name);
final String name;
@override
bool operator ==(Object other) =>
identical(this, other) ||
Expand All @@ -247,9 +249,9 @@ class Person {
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
const Person(this.name);
Person(this.name);
final String name;
@override
List<Object> get props => [name];
Expand Down
2 changes: 1 addition & 1 deletion example/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:equatable/equatable.dart';

class Credentials extends Equatable {
const Credentials({this.username, this.password});
const Credentials({required this.username, required this.password});

final String username;
final String password;
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: example

environment:
sdk: ">=2.0.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"

dependencies:
equatable:
Expand Down
4 changes: 2 additions & 2 deletions lib/src/equatable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ abstract class Equatable {
/// The list of properties that will be used to determine whether
/// two instances are equal.
/// {@endtemplate}
List<Object> get props;
List<Object?> get props;

/// {@template equatable_stringify}
/// If set to `true`, the [toString] method will be overridden to output
Expand All @@ -40,7 +40,7 @@ abstract class Equatable {
/// `false`.
/// {@endtemplate}
// ignore: avoid_returning_null
bool get stringify => null;
bool? get stringify => null;

@override
bool operator ==(Object other) =>
Expand Down
19 changes: 17 additions & 2 deletions lib/src/equatable_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,27 @@ import 'equatable.dart';
/// See also:
/// * [Equatable.stringify]
class EquatableConfig {
/// {@template stringify}
/// Global [stringify] setting for all [Equatable] instances.
///
/// If [stringify] is overridden for a particular [Equatable] instance,
/// then the local [stringify] value takes precedence
/// over [EquatableConfig.stringify].
///
/// This value defaults to false.
static bool stringify = false;
/// This value defaults to true in debug mode and false in release mode.
/// {@endtemplate}
static bool get stringify {
if (_stringify == null) {
assert(() {
_stringify = true;
return true;
}());
}
return _stringify ??= false;
}

/// {@macro stringify}
static set stringify(bool value) => _stringify = value;

static bool? _stringify;
}
6 changes: 3 additions & 3 deletions lib/src/equatable_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import 'equatable_utils.dart';
/// [operator ==] as well as the [hashCode] based on the provided [props].
mixin EquatableMixin {
/// {@macro equatable_props}
List<Object> get props;
List<Object?> get props;

/// {@macro equatable_stringify}
// ignore: avoid_returning_null
bool get stringify => null;
bool? get stringify => null;

@override
bool operator ==(Object other) {
bool operator ==(Object? other) {
return identical(this, other) ||
other is EquatableMixin &&
runtimeType == other.runtimeType &&
Expand Down
10 changes: 5 additions & 5 deletions lib/src/equatable_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import 'package:collection/collection.dart';
import 'package:equatable/equatable.dart';

/// Returns a `hashCode` for [props].
int mapPropsToHashCode(Iterable props) =>
_finish(props?.fold(0, _combine) ?? 0);
int mapPropsToHashCode(Iterable? props) =>
_finish(props == null ? 0 : props.fold(0, _combine));

const DeepCollectionEquality _equality = DeepCollectionEquality();

/// Determines whether [list1] and [list2] are equal.
bool equals(List list1, List list2) {
bool equals(List? list1, List? list2) {
if (identical(list1, list2)) return true;
if (list1 == null || list2 == null) return false;
final length = list1.length;
Expand Down Expand Up @@ -63,5 +63,5 @@ int _finish(int hash) {
}

/// Returns a string for [props].
String mapPropsToString(Type runtimeType, List<Object> props) =>
'$runtimeType(${props?.map((prop) => prop.toString())?.join(', ') ?? ""})';
String mapPropsToString(Type runtimeType, List<Object?> props) =>
'$runtimeType(${props.map((prop) => prop.toString()).join(', ')})';
14 changes: 7 additions & 7 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: equatable
description: An abstract class that helps to implement equality without needing to explicitly override == and hashCode.
version: 1.2.6
description: A Dart package that helps to implement value based equality without needing to explicitly override == and hashCode.
version: 2.0.0
repository: https://github.com/felangel/equatable
issue_tracker: https://github.com/felangel/equatable/issues
homepage: https://github.com/felangel/equatable
documentation: https://github.com/felangel/equatable

environment:
sdk: ">=2.0.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"

dependencies:
collection: ^1.14.11
meta: ^1.1.6
collection: ^1.15.0
meta: ^1.3.0

dev_dependencies:
test: ^1.14.3
test_coverage: ^0.4.1
coverage: ^0.14.2
test: ^1.16.0
Loading

0 comments on commit d7f5053

Please sign in to comment.