Skip to content

Commit

Permalink
Updates documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
jqno committed Mar 22, 2022
1 parent 7a68097 commit f15882c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<a name="3.x"/>

## [Unreleased]
### Fixed
- Support records that don't allow 0 values in their fields, with Warning.ZERO_FIELDS. ([Issue 613](https://github.com/jqno/equalsverifier/issues/613))

## [3.9.1] - 2022-03-19
### Fixed
Expand Down
32 changes: 32 additions & 0 deletions docs/_errormessages/record-failed-to-invoke-constructor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: Record: failed to invoke constructor
---
Record: failed to invoke constructor
If the record does not accept 0 as a value for its fields, consider providing valid prefab values for those fields and suppressing Warning.ZERO_FIELDS.

Sometimes, a constructor needs to validate its input, throwing an exception on certain values. This can lead to problems when the value `0` is not allowed, and the constructor is part of a record instead of a regular class, like this:

{% highlight java %}
public record Foo(int i) {
public Foo {
if (i < 42) {
throw new IllegalArgumentException();
}
}
}
{% endhighlight %}

One of the things EqualsVerifier does, is to run checks with fields set to their default values. For reference types, the default value is `null`, which has its own [chapter in the manual](/equalsverifier/manual/null). For primitive types, the default value is `0` (or `0.0`, `\u0000`, `false`). In regular classes, EqualsVerifier bypasses the constructor, so the exception can never be thrown. However, reflection support is much more limited for records, and their constructors cannot be bypassed.

Therefore, we need to signal EqualsVerifier to skip the checks with default values, by suppressing `Warning.ZERO_FIELDS`.

Another thing EqualsVerifier does, is to run checks with fields set to certain prefab values. For integral types, these values are `1` and `2`. If these values are not allowed by the record's constructor either, we need to provide new prefab values as well.

In these cases, the call to EqualsVerifier will look like this:

{% highlight java %}
EqualsVerifier.forClass(Foo.class)
.suppress(Warning.ZERO_FIELDS)
.withPrefabValues(int.class, 42, 1337)
.verify();
{% endhighlight %}
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private T callRecordConstructor(List<?> params) {
() -> constructor.newInstance(params.toArray(new Object[0])),
"Record: failed to invoke constructor.\n" +
" If the record does not accept 0 as a value for its fields," +
" consider providing valid prefab values for those fields and suppressing Warning.ZERO_FIELDS"
" consider providing valid prefab values for those fields and suppressing Warning.ZERO_FIELDS."
);
}
}

0 comments on commit f15882c

Please sign in to comment.