equatable icon indicating copy to clipboard operation
equatable copied to clipboard

Some thoughts on EquatableConfig

Open lbel opened this issue 4 years ago • 7 comments

Is your feature request related to a problem? Please describe. I really like being able to configure my Equatable classes globally using EquatableConfig (#68), since it saves me a lot of stringify overrides in the various classes. However, I'm worried about the global, shared state of this class.

First of all, there's no logical place for me to put the statement EquatableConfig.stringify = true; – every single test has its own main class, and in addition my project has various main classes for different environments, which leads to a lot of code duplication and makes it very easy to forget this call somewhere. I can also easily mess up by adding it in the unit tests but then forgetting it in the application, which basically invalidates all the toString calls in my unit tests.

Secondly, and more worryingly, any part of my code can now change this static value, which suddenly causes a behaviour change in all of my Equatable classes. This is dangerous from reproducibility perspective (for which we can't even test, because the value might be different in the unit tests), as well as from a security perspective: any part of my code can now make change other classes to have sensitive data show up in my logs, or hide the data I want from my logs, by simply changing this one variable. Currently, the only safeguard against this behaviour is overriding stringify in every Equatable class, which defeats the whole purpose of having this configurable field in the first place.

Describe the solution you'd like The first part of this problem can be solved in a non-breaking way, by defaulting EquatableConfig.stringify to a compile-time constant, eg. EquatableConfig.stringify = bool.fromEnvironment('equatable.defaultStringify', false);. This would already save a lot of trouble in getting the change consistent across my various main classes without having to specify them. However, this doesn't solve the reproducibility/security issue, unless the value were to be made const – but that'd be a breaking change and possibly make a lot of people very sad. It also doesn't guarantee that the production behaviour is identical to what was run in the unit tests, but at least it makes it a lot harder to randomly mess it up somewhere in the code.

I'm not entirely sure if I'm making a valid point or if I'm just spewing nonsense here, so I'm very curious to hear the developers' opinions about this! And as a final remark, I love the project and use it extensively, so thanks for all the work that went into it :) really appreciate it!

lbel avatar Jun 05 '20 15:06 lbel

Hi @lbel 👋 Thanks for opening an issue and for the positive feedback! I really appreciate it 🙏

I think the compile-time constant enhancement makes sense and I would love to hear what others think about making the value const (cc @jorgecoca).

felangel avatar Jun 08 '20 05:06 felangel

I'm thinking of a separate issue regarding EquatableConfig. In your example code

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  final String name;

  const Person(this.name);

  @override
  List<Object> get props => [name];

  @override
  bool get stringify => true;
}

this prints Person(Bob). But when it has too many (named)parameters it can be hard to determine which values have been set to null or numbers we referred to(like latitude & longitude). I really hope we can get the variable names like this -> Person(firstName: Bob, secondName: Martin).

vinceramcesoliveros avatar Jun 18 '20 12:06 vinceramcesoliveros

@felangel, I agree with @lbel that having to specify EquatableConfig.stringify = true; in every test still causes quite a bit of code duplication. Basically, we've moved the stringify code from the implementing Equatable classes to our tests...

zepfietje avatar Jun 23 '20 13:06 zepfietje

@ram231 I don't think that's possible without code-generation unfortunately.

@zepfietje Can you please explain why stringify needs to be enabled for tests? Do you have explicit tests to ensure toString returns the correct String?

felangel avatar Jun 23 '20 14:06 felangel

@felangel, stringify actually takes away the need to test for a correct toString. However, when testing blocs, stringify is really useful for debugging failing tests. Otherwise, you can't really distinguish the actual and expected emitted states for example.

zepfietje avatar Jun 23 '20 14:06 zepfietje

@zepfietje got it, thanks for clarifying 👍

felangel avatar Jun 23 '20 14:06 felangel

Hi there' I was about to ask this question, luckily for me I've found this, I'm thinking of using this config directly into the main.dart file. I think it's a good place, what do you think?

normancarcamo avatar Dec 02 '20 06:12 normancarcamo