Skip to content

Commit

Permalink
remove unsupported client-side validators: @PastOrPresent and @Future…
Browse files Browse the repository at this point in the history
…OrPresent

It's not trivial to ensure the same granularity of _present_ as on the server-side: year / month / day / minute.
Until there is a sensible client-side implementation that works close enough to the server-side, it's better not to have any client-side validation for these constraints than to have a broken implementaiton.
  • Loading branch information
Viktor Lukashov committed Jul 6, 2020
1 parent 15ae925 commit 0793bfc
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,30 +245,37 @@ export class Past extends AbstractValidator<any> {
}
validate = (value: any) => isBefore(value);
}
export class PastOrPresent extends AbstractValidator<any> {
constructor(attrs?: ValidatorAttributes) {
super({ message: 'must be a date in the past or in the present', ...attrs });
}
validate = (value: string) => {
const futureSecond = new Date().getTime() + 1000;
return isBefore(value, String(new Date(futureSecond)));
};
}
/*
@PastOrPresent has no client-side implementation yet.
It would consider any input valid and let the server-side to do validation.
(It's not trivial to ensure the same granularity of _present_ as on the server-side:
year / month / day / minute).
*/
// export class PastOrPresent extends AbstractValidator<any> {
// constructor(attrs?: ValidatorAttributes) {
// super({ message: 'must be a date in the past or in the present', ...attrs });
// }
// validate = () => true;
// }
export class Future extends AbstractValidator<any> {
constructor(attrs?: ValidatorAttributes) {
super({ message: 'must be a future date', ...attrs });
}
validate = (value: any) => isAfter(value);
}
export class FutureOrPresent extends AbstractValidator<any> {
constructor(attrs?: ValidatorAttributes) {
super({ message: 'must be a date in the present or in the future', ...attrs });
}
validate = (value: string) => {
const pastSecond = new Date().getTime() - 1000;
return isAfter(value, String(new Date(pastSecond)));
};
}

/*
@FutureOrPresent has no client-side implementation yet.
It would consider any input valid and let the server-side to do validation.
(It's not trivial to ensure the same granularity of _present_ as on the server-side:
year / month / day / minute).
*/
// export class FutureOrPresent extends AbstractValidator<any> {
// constructor(attrs?: ValidatorAttributes) {
// super({ message: 'must be a date in the present or in the future', ...attrs });
// }
// validate = () => true;
// }

function _regexp(attrs: PatternAttributes | string | RegExp) {
return typeof attrs === 'string' ? new RegExp(attrs)
Expand Down
30 changes: 14 additions & 16 deletions flow-client/src/test/frontend/form/ValidatorsTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
Digits,
Email,
Future,
FutureOrPresent,
Max,
Min,
Negative,
Expand All @@ -20,7 +19,6 @@ import {
NotNull,
Null,
Past,
PastOrPresent,
Pattern,
Positive,
PositiveOrZero,
Expand Down Expand Up @@ -230,13 +228,13 @@ suite("form/Validators", () => {
assert.isFalse(validator.validate("3000-01-01"), 'future');
});

test("PastOrPresent", () => {
const validator = new PastOrPresent();
assert.isNotTrue(validator.impliesRequired);
assert.isTrue(validator.validate("2019-12-31"), 'past');
assert.isTrue(validator.validate(String(new Date())), 'present');
assert.isFalse(validator.validate("3000-01-01"), 'future');
});
// test("PastOrPresent", () => {
// const validator = new PastOrPresent();
// assert.isNotTrue(validator.impliesRequired);
// assert.isTrue(validator.validate("2019-12-31"), 'past');
// assert.isTrue(validator.validate(String(new Date())), 'present');
// assert.isFalse(validator.validate("3000-01-01"), 'future');
// });

test("Future", () => {
const validator = new Future();
Expand All @@ -246,13 +244,13 @@ suite("form/Validators", () => {
assert.isTrue(validator.validate("3000-01-01"), 'future');
});

test("FutureOrPresent", () => {
const validator = new FutureOrPresent();
assert.isNotTrue(validator.impliesRequired);
assert.isFalse(validator.validate("2019-12-31"), 'past');
assert.isTrue(validator.validate(String(new Date())), 'present');
assert.isTrue(validator.validate("3000-01-01"), 'future');
});
// test("FutureOrPresent", () => {
// const validator = new FutureOrPresent();
// assert.isNotTrue(validator.impliesRequired);
// assert.isFalse(validator.validate("2019-12-31"), 'past');
// assert.isTrue(validator.validate(String(new Date())), 'present');
// assert.isTrue(validator.validate("3000-01-01"), 'future');
// });

test("Pattern", () => {
let validator = new Pattern(/^(\+\d+)?([ -]?\d+){4,14}$/);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ private void addFieldAnnotationsToSchema(FieldDeclaration field,
str += str.contains("(") ? "" : "()";

if (str.matches(
"(Email|Null|NotNull|NotEmpty|NotBlank|AssertTrue|AssertFalse|Negative|NegativeOrZero|Positive|PositiveOrZero|Size|Past|PastOrPresent|Future|FutureOrPresent|Digits|Min|Max|Pattern|DecimalMin|DecimalMax)\\(.+")) {
"(Email|Null|NotNull|NotEmpty|NotBlank|AssertTrue|AssertFalse|Negative|NegativeOrZero|Positive|PositiveOrZero|Size|Past|Future|Digits|Min|Max|Pattern|DecimalMin|DecimalMax)\\(.+")) {
annotations.add(str);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {{{getClassNameFromImports classname ../../imports}}} from './{{{getClass
import {ObjectModel,StringModel,NumberModel,ArrayModel,BooleanModel,Required,ModelType} from '@vaadin/form';

// @ts-ignore
import {Email,Null,NotNull,NotEmpty,NotBlank,AssertTrue,AssertFalse,Negative,NegativeOrZero,Positive,PositiveOrZero,Size,Past,PastOrPresent,Future,FutureOrPresent,Digits,Min,Max,Pattern,DecimalMin,DecimalMax} from '@vaadin/form';
import {Email,Null,NotNull,NotEmpty,NotBlank,AssertTrue,AssertFalse,Negative,NegativeOrZero,Positive,PositiveOrZero,Size,Past,Future,Digits,Min,Max,Pattern,DecimalMin,DecimalMax} from '@vaadin/form';

{{#models}}
{{#model}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import javax.validation.constraints.Digits;
import javax.validation.constraints.Email;
import javax.validation.constraints.Future;
import javax.validation.constraints.FutureOrPresent;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Negative;
Expand All @@ -33,7 +32,6 @@
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Past;
import javax.validation.constraints.PastOrPresent;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Positive;
import javax.validation.constraints.PositiveOrZero;
Expand Down Expand Up @@ -94,9 +92,7 @@ public static class MyEntity extends MyEntityId {
@Size(min = 1) String size1;
@Digits(integer=5, fraction = 2) String digits;
@Past LocalDate past;
@PastOrPresent LocalTime pastOrPresent;
@Future LocalDate future;
@FutureOrPresent LocalTime futureOrPresent;
@Pattern(regexp = "\\d+\\..+") String pattern;
List<MyEntity> children;
String[] stringArray;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import MyEntity from './MyEntity';
import {ObjectModel,StringModel,NumberModel,ArrayModel,BooleanModel,Required,ModelType} from '@vaadin/form';

// @ts-ignore
import {Email,Null,NotNull,NotEmpty,NotBlank,AssertTrue,AssertFalse,Negative,NegativeOrZero,Positive,PositiveOrZero,Size,Past,PastOrPresent,Future,FutureOrPresent,Digits,Min,Max,Pattern,DecimalMin,DecimalMax} from '@vaadin/form';
import {Email,Null,NotNull,NotEmpty,NotBlank,AssertTrue,AssertFalse,Negative,NegativeOrZero,Positive,PositiveOrZero,Size,Past,Future,Digits,Min,Max,Pattern,DecimalMin,DecimalMax} from '@vaadin/form';

/**
* This module is generated from com.vaadin.flow.server.connect.generator.tsmodel.TsFormEndpoint.MyEntity.
Expand All @@ -28,7 +28,6 @@ export default class MyEntityModel<T extends MyEntity = MyEntity> extends MyEnti
public readonly entityMatrix = new ArrayModel<ModelType<ArrayModel<ModelType<MyEntityModel>, MyEntityModel>>, ArrayModel<ModelType<MyEntityModel>, MyEntityModel>>(this, 'entityMatrix', ArrayModel, [MyEntityModel, []]);
public readonly foo = new StringModel(this, 'foo');
public readonly future = new StringModel(this, 'future', new Future());
public readonly futureOrPresent = new ObjectModel(this, 'futureOrPresent', new FutureOrPresent());
public readonly isNull = new StringModel(this, 'isNull', new Null());
public readonly list = new ArrayModel(this, 'list', StringModel, [], new NotEmpty());
public readonly max = new NumberModel(this, 'max', new Max(2));
Expand All @@ -40,7 +39,6 @@ export default class MyEntityModel<T extends MyEntity = MyEntity> extends MyEnti
public readonly notNull = new StringModel(this, 'notNull', new NotNull());
public readonly numberMatrix = new ArrayModel(this, 'numberMatrix', ArrayModel, [NumberModel, []]);
public readonly past = new StringModel(this, 'past', new Past());
public readonly pastOrPresent = new ObjectModel(this, 'pastOrPresent', new PastOrPresent());
public readonly pattern = new StringModel(this, 'pattern', new Pattern({regexp:"\\d+\\..+"}));
public readonly positive = new NumberModel(this, 'positive', new Positive());
public readonly positiveOrCero = new NumberModel(this, 'positiveOrCero', new PositiveOrZero());
Expand Down

0 comments on commit 0793bfc

Please sign in to comment.