Skip to content

Commit c83bb1e

Browse files
authored
Support Dictionary for Error Messages (#10)
* Support Dictionary for Error Messages * Use array merge, so we dont loose the defaults if we only want to update one key * Add test for missing key, resulting in default * remove static return type remove 7.3
1 parent b8c9cd8 commit c83bb1e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+475
-268
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
strategy:
1616
matrix:
17-
php: [ 7.3, 7.4, 8.0 ]
17+
php: [ 7.4, 8.0 ]
1818
steps:
1919
- name: Checkout
2020
uses: actions/checkout@v3

index.test.js

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,69 @@ import {DecimalValidator} from './js/validators/DecimalValidator';
1515
import {ConfirmationValidator} from './js/validators/ConfirmationValidator.js';
1616
import {RegexValidator} from './js/validators/RegexValidator.js';
1717

18-
function testSuccess(response)
19-
{
18+
function testSuccess(response) {
2019
expect(response).toHaveProperty('errors', []);
2120
}
2221

23-
function testFailure(response, errors, potentiallyValid = false)
24-
{
22+
function testFailure(response, errors, potentiallyValid = false) {
2523
expect(response).toHaveProperty('errors', errors);
2624
expect(response).toHaveProperty('potentiallyValid', potentiallyValid);
2725
}
2826

2927
test(
3028
'deserialize',
31-
() =>
32-
{
29+
() => {
3330
let v = Validator.fromJsonObject({t: 'String', c: {'minLength': 2, 'maxLength': 5}});
3431
expect(v).toBeInstanceOf(StringValidator);
3532
expect(v._minLength).toStrictEqual(2);
3633
expect(v._maxLength).toStrictEqual(5);
3734
}
3835
);
3936

37+
test(
38+
'TranslatedStringValidator',
39+
() => {
40+
let v = new StringValidator(2, 5);
41+
v.dictionary = {
42+
invalid: 'kein gültiger Wert',
43+
min: 'muss mindestens sein %s characters',
44+
max: 'darf nicht mehr als sein %s characters'
45+
};
46+
47+
testFailure(v.validate(), ['kein gültiger Wert']);
48+
testFailure(v.validate(''), ['muss mindestens sein 2 characters']);
49+
testFailure(v.validate('testtest'), ['darf nicht mehr als sein 5 characters']);
50+
}
51+
);
52+
53+
test(
54+
'MissinKeyTranslatedStringValidator',
55+
() => {
56+
let v = new StringValidator(2, 5);
57+
v.dictionary = {
58+
invalid: 'kein gültiger Wert',
59+
min: 'muss mindestens sein %s characters'
60+
// max is missing
61+
};
62+
63+
testFailure(v.validate(), ['kein gültiger Wert']);
64+
testFailure(v.validate(''), ['muss mindestens sein 2 characters']);
65+
testFailure(v.validate('testesttest'), ['must be no more than 5 characters']); // default error message
66+
}
67+
)
68+
69+
test(
70+
'TranslatedRequiredValidator',
71+
() => {
72+
let v = new RequiredValidator();
73+
v.dictionary = {invalid: 'kein gültiger Wert'};
74+
testFailure(v.validate(), ['kein gültiger Wert']);
75+
}
76+
);
77+
4078
test(
4179
'StringValidator',
42-
() =>
43-
{
80+
() => {
4481
let v = new StringValidator();
4582
testSuccess(v.validate('test'));
4683
testSuccess(v.validate(''));
@@ -70,8 +107,7 @@ test(
70107

71108
test(
72109
'BoolValidator',
73-
() =>
74-
{
110+
() => {
75111
const v = new BoolValidator();
76112
testFailure(v.validate('test'), ['Invalid boolean value']);
77113
testFailure(v.validate(''), ['Invalid boolean value']);
@@ -90,8 +126,7 @@ test(
90126

91127
test(
92128
'EnumValidator',
93-
() =>
94-
{
129+
() => {
95130
let v = new EnumValidator();
96131
testSuccess(v.validate(''));
97132
testFailure(v.validate('test'), ['not a valid value']);
@@ -117,8 +152,7 @@ test(
117152

118153
test(
119154
'ConstEnumValidator',
120-
() =>
121-
{
155+
() => {
122156
let v = new ConstEnumValidator();
123157
testSuccess(v.validate(''));
124158
testFailure(v.validate('test'), ['not a valid value']);
@@ -144,8 +178,7 @@ test(
144178

145179
test(
146180
'EqualValidator',
147-
() =>
148-
{
181+
() => {
149182
let v = new EqualValidator('test');
150183
testFailure(v.validate(''), ['value does not match']);
151184
testSuccess(v.validate('test'));
@@ -157,8 +190,7 @@ test(
157190

158191
test(
159192
'NotEqualValidator',
160-
() =>
161-
{
193+
() => {
162194
let v = new NotEqualValidator('test');
163195
testFailure(v.validate('test'), ['value must not match']);
164196
testSuccess(v.validate(''));
@@ -170,8 +202,7 @@ test(
170202

171203
test(
172204
'RequiredValidator',
173-
() =>
174-
{
205+
() => {
175206
let v = new RequiredValidator();
176207
testSuccess(v.validate(true));
177208
testSuccess(v.validate(false));
@@ -189,8 +220,7 @@ test(
189220

190221
test(
191222
'EmailValidator',
192-
() =>
193-
{
223+
() => {
194224
let v = new EmailValidator();
195225
testSuccess(v.validate('[email protected]'));
196226
testSuccess(v.validate('[email protected]'));
@@ -202,8 +232,7 @@ test(
202232

203233
test(
204234
'IPv4Validator',
205-
() =>
206-
{
235+
() => {
207236
let v = new IPv4Validator();
208237
testSuccess(v.validate('0.0.0.0'));
209238
testSuccess(v.validate('255.255.255.255'));
@@ -222,8 +251,7 @@ test(
222251

223252
test(
224253
'NumberValidator',
225-
() =>
226-
{
254+
() => {
227255
let v = new NumberValidator();
228256
testFailure(v.validate('test'), ['must be a number']);
229257
testSuccess(v.validate(1));
@@ -246,28 +274,26 @@ test(
246274

247275
test(
248276
'RegexValidator',
249-
() =>
250-
{
277+
() => {
251278
let v = new RegexValidator('not valid regex');
252279
testFailure(v.validate('test'), ['not a valid regular expression']);
253280

254281
v = new RegexValidator({});
255282
testFailure(v.validate('test'), ['not a valid regular expression']);
256283

257-
v = new RegexValidator('/test/', 'not test');
258-
testFailure(v.validate('abc'), ['not test']);
284+
v = new RegexValidator('/test/');
285+
testFailure(v.validate('abc'), ['not a valid regular expression']);
259286

260287
v = new RegexValidator('/test/');
261-
testFailure(v.validate('abc'), ['does not match regular expression']);
262-
testFailure(v.validate('1'), ['does not match regular expression']);
288+
testFailure(v.validate('abc'), ['not a valid regular expression']);
289+
testFailure(v.validate('1'), ['not a valid regular expression']);
263290
testSuccess(v.validate('test'));
264291
}
265292
);
266293

267294
test(
268295
'IntegerValidator',
269-
() =>
270-
{
296+
() => {
271297
let v = new IntegerValidator();
272298
testFailure(v.validate('test'), ['must be a number']);
273299
testSuccess(v.validate(1));
@@ -296,8 +322,7 @@ test(
296322

297323
test(
298324
'DecimalValidator',
299-
() =>
300-
{
325+
() => {
301326
let v = new DecimalValidator();
302327
testFailure(v.validate('test'), ['must be a number']);
303328
testSuccess(v.validate(1));
@@ -328,8 +353,7 @@ test(
328353

329354
test(
330355
'ConfirmationValidator',
331-
() =>
332-
{
356+
() => {
333357
let v = new ConfirmationValidator('field2');
334358
v.setData({'field1': 10});
335359
testFailure(v.validate(v.getData()['field1']), ['value does not match']);

js/validator.js

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
2-
* @typedef {function(new: Validator), deserialize} ValidatorType
2+
* @typedef {function(new: Validator)} ValidatorType
3+
* @property deserialize
34
*/
45

56
/**
@@ -8,24 +9,22 @@
89
*/
910
const _validatorMap = new Map();
1011

11-
export class Validator
12-
{
12+
export class Validator {
1313
/**
1414
* @param {Object} obj
1515
* @return {Validator}
1616
*/
17-
static fromJsonObject(obj)
18-
{
19-
if(!_validatorMap.has(obj.t))
20-
{
17+
static fromJsonObject(obj) {
18+
if(!_validatorMap.has(obj.t)) {
2119
throw 'unrecognised type ' + obj.t;
2220
}
23-
const c = _validatorMap.get(obj.t);
24-
return c.deserialize(obj.c);
21+
const validator = _validatorMap.get(obj.t);
22+
const initializedValidator = validator.deserialize(obj.c);
23+
initializedValidator.dictionary = obj.d;
24+
return initializedValidator;
2525
}
2626

27-
static deserialize(config)
28-
{
27+
static deserialize(config) {
2928
return new this();
3029
}
3130

@@ -34,70 +33,63 @@ export class Validator
3433
* @return {ValidationResponse}
3534
* @throws
3635
*/
37-
validate(value)
38-
{
36+
validate(value) {
3937
throw 'validate not implemented on ' + this.constructor.name;
4038
}
39+
40+
/**
41+
* @param {Object} dictionary
42+
*/
43+
set dictionary(dictionary) {
44+
this._dictionary = dictionary || {};
45+
}
4146
}
4247

43-
export class DataSetValidator extends Validator
44-
{
48+
export class DataSetValidator extends Validator {
4549
_data = {};
4650

47-
setData(data)
48-
{
51+
setData(data) {
4952
this._data = data;
5053
}
5154

52-
getData()
53-
{
55+
getData() {
5456
return this._data;
5557
}
5658
}
5759

58-
export class ValidationResponse
59-
{
60-
constructor(errors, potentiallyValid)
61-
{
60+
export class ValidationResponse {
61+
constructor(errors, potentiallyValid) {
6262
this._errors = errors || [];
6363
this._potentiallyValid = potentiallyValid || false;
6464
}
6565

66-
get errors()
67-
{
66+
get errors() {
6867
return this._errors;
6968
}
7069

71-
get potentiallyValid()
72-
{
70+
get potentiallyValid() {
7371
return this._potentiallyValid;
7472
}
7573

76-
static success()
77-
{
74+
static success() {
7875
return new ValidationResponse([], true);
7976
}
8077

81-
static potentiallyValid(errors = [])
82-
{
78+
static potentiallyValid(errors = []) {
8379
return new ValidationResponse(errors, true);
8480
}
8581

86-
static error(errors = [])
87-
{
82+
static error(errors = []) {
8883
return new ValidationResponse(errors, false);
8984
}
9085

9186
/**
9287
* @param {...ValidationResponse} responses
9388
*/
94-
combine(...responses)
95-
{
89+
combine(...responses) {
9690
responses.forEach(
97-
r =>
98-
{
99-
if(r instanceof ValidationResponse)
100-
{
91+
r => {
92+
if(r instanceof ValidationResponse) {
10193
this._errors.push(...r._errors);
10294
this._potentiallyValid = this._potentiallyValid && r._potentiallyValid;
10395
}
@@ -110,7 +102,6 @@ export class ValidationResponse
110102
* @param {string} name
111103
* @param {ValidatorType} validator
112104
*/
113-
export function addValidator(name, validator)
114-
{
105+
export function addValidator(name, validator) {
115106
_validatorMap.set(name, validator);
116107
}

0 commit comments

Comments
 (0)