Is there real case scenarios of not following immutable leading to wrong hash outcome?
I've made a test case to test the non-immutable class and was expecting it to have an error. In reality we do not have any problems with that and HashSet actually works fine here.
Can you show us a simple real case scenario where not following immutable will lead to wrong hashcode value
import 'dart:collection';
import 'package:equatable/equatable.dart';
import 'package:flutter_test/flutter_test.dart';
class _EquatableTest extends Equatable {
final HashSet values;
const _EquatableTest({required this.values});
@override
List<Object> get props => [values];
_EquatableTest copyWith({
HashSet? values,
}) {
return _EquatableTest(
values: values ?? this.values,
);
}
}
class _EquatableTestNonImmutable extends Equatable {
HashSet values;
_EquatableTestNonImmutable({required this.values});
@override
List<Object> get props => [values];
}
class _AdditionalValue extends Equatable {
HashSet<String> letters;
_AdditionalValue({required this.letters});
void add(String letter) {
letters.add(letter);
}
@override
List<Object> get props => [letters];
}
void main() {
test('NonImmutable created same with _AdditionalValue value', () {
_EquatableTest equatableImmune1;
_EquatableTest equatableImmune2;
equatableImmune1 = _EquatableTest(values: HashSet<_AdditionalValue>());
equatableImmune2 = _EquatableTest(values: HashSet<_AdditionalValue>());
equatableImmune1.values.add(_AdditionalValue(letters: HashSet.from(['a', 'b'])));
equatableImmune1.values.add(_AdditionalValue(letters: HashSet.from(['c', 'd'])));
equatableImmune2.values.add(_AdditionalValue(letters: HashSet.from(['a', 'b'])));
equatableImmune2.values.add(_AdditionalValue(letters: HashSet.from(['c', 'd'])));
expect(equatableImmune1, equatableImmune2);
});
test('NonImmutable changed same with _AdditionalValue value', () {
_EquatableTest equatableImmune1;
_EquatableTest equatableImmune2;
equatableImmune1 = _EquatableTest(values: HashSet<_AdditionalValue>());
equatableImmune2 = _EquatableTest(values: HashSet<_AdditionalValue>());
_AdditionalValue value1 = _AdditionalValue(letters: HashSet<String>());
_AdditionalValue value2 = _AdditionalValue(letters: HashSet<String>());
value1.add('a');
value2.add('a');
equatableImmune1.values.add(value1);
equatableImmune2.values.add(value2);
expect(equatableImmune1, equatableImmune2);
if (equatableImmune1.values.first.runtimeType == _AdditionalValue &&
equatableImmune2.values.first.runtimeType == _AdditionalValue) {
equatableImmune1.values.first.add('b');
equatableImmune2.values.first.add('b');
}
expect(equatableImmune1, equatableImmune2);
expect(equatableImmune1.hashCode, equatableImmune2.hashCode);
});
}
A trivial example:
So now the
Setis in an inconsistent state where it doesn't even think it contains its only element.