Skip to content

Conversation

serhii-lekariev
Copy link
Contributor

This PR closes #197.

Before, attempting to use (required) = true on all numeric types and the boolean type resulted in false-positive violations of ValidatingException - the numeric fields were compared against 0 and boolean fields were compared against false, and if they were equal to those default values, the fields were considered unset.

This is semantically incorrect, because both 0 and false, while being a default, are valid values nonetheless.

Now, when trying to validate required fields of the following numeric types:

  • int32
  • int64
  • float
  • double

or a required field of type bool, a warning is produced, telling that doing so is incorrect.

doing so requires comparing it against a default value, which in case
of numeric types is `0` - a perfectly valid field value
@serhii-lekariev
Copy link
Contributor Author

@dmdashenkov, PTAL.

Copy link
Contributor

@dmdashenkov dmdashenkov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@serhii-lekariev, please see my comments.

*
* @return whether a field that is being validated can be {@code required}
*/
protected abstract boolean requiredAllowed();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method name is complicated. It uses 2 past form verbs. Please think of a better name.

/**
* Checks whether a field can be {@code (required) = true}.
*
* Validators can define that for their respective types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<p> is missing.

return result;
}

private void canBeRequired() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name does not reflect the action. I'd expect a method starting with can to return a boolean. Please rename.

*/
@SuppressWarnings("ConstantConditions")
// `isFirstTimeSet` controls for `null`s.
// `isFirstTimeSet` controls for `null`s.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please undo this change.

* <p>If the field is repeated, it must have at least one value set, and all its values
* must be valid.
*
* <p>If the field is of a numeric type, it's always considered set.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about bools?


@Override
protected boolean requiredAllowed() {
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the overloads of this method return a constant. Please consider passing the value in a super(...) ctor call.

* @implNote Attempting to define whether a numeric field is set or not is semantically
* incorrect, because the way to define whether a value is set or not is to compare it against
* its default value, which for numeric fields is {@code 0}, which is sometimes a desired and
* valid value for a field.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one sentence is too long. Please split it up and simplify. Also, I'm not sure if <p> paragraphs are supported in @implNote.

serhii.lekariev and others added 2 commits December 24, 2018 18:17
@serhii-lekariev serhii-lekariev changed the base branch from set_once_message_option to master December 25, 2018 13:35
@codecov
Copy link

codecov bot commented Dec 25, 2018

Codecov Report

Merging #266 into master will increase coverage by 0.02%.
The diff coverage is 100%.

@@             Coverage Diff              @@
##             master     #266      +/-   ##
============================================
+ Coverage     74.74%   74.76%   +0.02%     
  Complexity      689      689              
============================================
  Files           302      302              
  Lines          8236     8240       +4     
  Branches        551      551              
============================================
+ Hits           6156     6161       +5     
  Misses         1944     1944              
+ Partials        136      135       -1

`validateOwnRules` method, since it's already done in the
`FieldValidator#validate()`
@serhii-lekariev
Copy link
Contributor Author

@dmdashenkov, PTAL.

Copy link
Contributor

@dmdashenkov dmdashenkov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@serhii-lekariev, please see some new comments.

private void checkCanBeRequired() {
boolean fieldIsRequired = isRequiredField();
if (!canBeRequired && fieldIsRequired) {
String messageFormat = "Fields of type %s can't be declared as `(required)`.";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
String messageFormat = "Fields of type %s can't be declared as `(required)`.";
String messageFormat = "Fields of type %s shouldn't be declared as `(required)`.";

FloatFieldValidatorTest() {
super(HALF, -HALF, new FloatFieldValidator(FieldValue.of(HALF, fieldContext)));
super(HALF, -HALF, new FloatFieldValidator(FieldValue.of(HALF, fieldContext)),
requiredFieldValidator());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please allocate each next param on a new line.

.descriptor()
.getType()
.name();
log().warn(messageFormat, typeName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Logging._warn() and similar methods instead.

String typeName = this.field()
.descriptor()
.getType()
.name();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ugly. Please use FieldDeclaration methods. If there is no such method, please add one.

@serhii-lekariev
Copy link
Contributor Author

@dmdashenkov, PTAL again.

@SpineEventEngine SpineEventEngine deleted a comment Dec 26, 2018
Copy link
Contributor

@dmdashenkov dmdashenkov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@serhii-lekariev, LGTM after a single comment is addressed.

if (isRequiredField()) {
log().warn("'required' option not allowed for boolean field");
}
// NOP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the reason.

@SpineEventEngine SpineEventEngine deleted a comment Dec 30, 2018
@SpineEventEngine SpineEventEngine deleted a comment Jan 2, 2019
@serhii-lekariev serhii-lekariev merged commit 8ee75f1 into master Jan 2, 2019
@serhii-lekariev serhii-lekariev deleted the required_option_for_numbers branch January 2, 2019 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid required validation for number fields
2 participants