Skip to content

Commit 6165bd3

Browse files
decorator added; some tests implemented
1 parent 27efc23 commit 6165bd3

File tree

3 files changed

+142
-2
lines changed

3 files changed

+142
-2
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'reflect-metadata';
2+
import {addOptions} from "../../services/models";
3+
4+
export const Validator: MethodDecorator = (target: Object,
5+
propertyName: string,
6+
descriptor: TypedPropertyDescriptor<any>) => {
7+
addOptions(target, {
8+
validate: {
9+
[propertyName]: descriptor.value
10+
}
11+
});
12+
};

test/specs/validation.spec.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {Table} from "../../lib/annotations/Table";
1515
import {Column} from "../../lib/annotations/Column";
1616
import {Length} from "../../lib/annotations/validation/Length";
1717
import {NotEmpty} from "../../lib/annotations/validation/NotEmpty";
18+
import {Validator} from '../../lib/annotations/validation/Validator';
1819

1920
use(chaiAsPromised);
2021

@@ -209,6 +210,7 @@ describe('validation', () => {
209210
class User extends Model<User> {
210211
@Length({min: 0, max: 5}) @Column name: string;
211212
}
213+
212214
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
213215
sequelizeValidationOnly.addModels([User]);
214216
const user = new User({name: 'elisa'});
@@ -225,6 +227,7 @@ describe('validation', () => {
225227
class User extends Model<User> {
226228
@Length({min: 0, max: 5}) @Column name: string;
227229
}
230+
228231
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
229232
sequelizeValidationOnly.addModels([User]);
230233
const user = new User({name: 'elisa tree'});
@@ -241,6 +244,7 @@ describe('validation', () => {
241244
class User extends Model<User> {
242245
@Length({min: 5, max: 5}) @Column name: string;
243246
}
247+
244248
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
245249
sequelizeValidationOnly.addModels([User]);
246250
const user = new User({name: 'elli'});
@@ -257,6 +261,7 @@ describe('validation', () => {
257261
class User extends Model<User> {
258262
@Length({max: 5}) @Column name: string;
259263
}
264+
260265
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
261266
sequelizeValidationOnly.addModels([User]);
262267
const user = new User({name: 'elisa'});
@@ -273,6 +278,7 @@ describe('validation', () => {
273278
class User extends Model<User> {
274279
@Length({max: 5}) @Column name: string;
275280
}
281+
276282
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
277283
sequelizeValidationOnly.addModels([User]);
278284
const user = new User({name: 'elisa tree'});
@@ -289,6 +295,7 @@ describe('validation', () => {
289295
class User extends Model<User> {
290296
@Length({min: 4}) @Column name: string;
291297
}
298+
292299
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
293300
sequelizeValidationOnly.addModels([User]);
294301
const user = new User({name: 'elisa'});
@@ -305,6 +312,7 @@ describe('validation', () => {
305312
class User extends Model<User> {
306313
@Length({min: 5}) @Column name: string;
307314
}
315+
308316
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
309317
sequelizeValidationOnly.addModels([User]);
310318
const user = new User({name: 'elli'});
@@ -325,6 +333,7 @@ describe('validation', () => {
325333
class User extends Model<User> {
326334
@NotEmpty @Column name: string;
327335
}
336+
328337
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
329338
sequelizeValidationOnly.addModels([User]);
330339
const user = new User({name: 'elisa'});
@@ -341,6 +350,7 @@ describe('validation', () => {
341350
class User extends Model<User> {
342351
@NotEmpty @Column name: string;
343352
}
353+
344354
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
345355
sequelizeValidationOnly.addModels([User]);
346356
const user = new User({name: ''});
@@ -357,6 +367,7 @@ describe('validation', () => {
357367
class User extends Model<User> {
358368
@NotEmpty({msg: 'NotEmpty'}) @Column name: string;
359369
}
370+
360371
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
361372
sequelizeValidationOnly.addModels([User]);
362373
const user = new User({name: 'elisa'});
@@ -373,6 +384,7 @@ describe('validation', () => {
373384
class User extends Model<User> {
374385
@NotEmpty({msg: 'NotEmpty'}) @Column name: string;
375386
}
387+
376388
const sequelizeValidationOnly = createSequelizeValidationOnly(false);
377389
sequelizeValidationOnly.addModels([User]);
378390
const user = new User({name: ''});
@@ -385,6 +397,108 @@ describe('validation', () => {
385397
});
386398
});
387399

400+
describe('Validator', () => {
401+
402+
describe('simple model, one validator', () => {
403+
404+
const VALID_NAME = 'bob';
405+
const ERROR_MESSAGE = `Invalid name: Only '${VALID_NAME}' is valid`;
406+
const _sequelize = createSequelize({modelPaths: []});
407+
408+
@Table
409+
class User extends Model<User> {
410+
@Column name: string;
411+
@Validator userValidator(): void {
412+
if (this.name !== VALID_NAME) {
413+
throw new Error(ERROR_MESSAGE);
414+
}
415+
}
416+
}
417+
418+
_sequelize.addModels([User]);
419+
420+
it('should throw', () => {
421+
const user = new User({name: 'will'});
422+
423+
if (majorVersion === 3) {
424+
return user.validate().then(err => expect(err.errors[0].message).to.eq(ERROR_MESSAGE));
425+
} else if (majorVersion === 4) {
426+
return expect(user.validate()).to.be.rejected;
427+
}
428+
});
429+
430+
it('should not throw', () => {
431+
const user = new User({name: VALID_NAME});
432+
433+
if (majorVersion === 3) {
434+
return user.validate().then(err => expect(err).to.be.null);
435+
} else if (majorVersion === 4) {
436+
return expect(user.validate()).to.be.fulfilled;
437+
}
438+
});
439+
440+
});
441+
442+
describe('simple model, multiple validators', () => {
443+
444+
const VALID_NAME = 'bob';
445+
const NAME_ERROR_MESSAGE = `Invalid name: Only '${VALID_NAME}' is valid`;
446+
const VALID_AGE = 99;
447+
const AGE_ERROR_MESSAGE = `Invalid age: Only '${VALID_AGE}' is valid`;
448+
const _sequelize = createSequelize({modelPaths: []});
449+
450+
@Table
451+
class User extends Model<User> {
452+
@Column name: string;
453+
@Column age: number;
454+
@Validator nameValidator(): void {
455+
if (this.name !== VALID_NAME) {
456+
throw new Error(NAME_ERROR_MESSAGE);
457+
}
458+
}
459+
@Validator ageValidator(): void {
460+
if (this.age !== VALID_AGE) {
461+
throw new Error(AGE_ERROR_MESSAGE);
462+
}
463+
}
464+
}
465+
466+
_sequelize.addModels([User]);
467+
468+
it('should throw due to wrong name', () => {
469+
const user = new User({name: 'will', age: VALID_AGE});
470+
471+
if (majorVersion === 3) {
472+
return user.validate().then(err => expect(err.errors[0].message).to.eq(NAME_ERROR_MESSAGE));
473+
} else if (majorVersion === 4) {
474+
return expect(user.validate()).to.be.rejectedWith(NAME_ERROR_MESSAGE);
475+
}
476+
});
477+
478+
it('should throw due to wrong age', () => {
479+
const user = new User({name: VALID_NAME, age: 1});
480+
481+
if (majorVersion === 3) {
482+
return user.validate().then(err => expect(err.errors[0].message).to.eq(AGE_ERROR_MESSAGE));
483+
} else if (majorVersion === 4) {
484+
return expect(user.validate()).to.be.rejectedWith(AGE_ERROR_MESSAGE);
485+
}
486+
});
487+
488+
// it('should not throw', () => {
489+
// const user = new User({name: VALID_NAME});
490+
//
491+
// if (majorVersion === 3) {
492+
// return user.validate().then(err => expect(err).to.be.null);
493+
// } else if (majorVersion === 4) {
494+
// return expect(user.validate()).to.be.fulfilled;
495+
// }
496+
// });
497+
498+
});
499+
500+
});
501+
388502
});
389503

390504
describe('only', () => {

test/utils/sequelize.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
import {Sequelize} from "../../lib/models/Sequelize";
22
import * as OriginSequelize from "sequelize";
33
import {DefineOptions, Sequelize as SequelizeType} from "sequelize";
4+
import {SequelizeConfig} from '../../lib/types/SequelizeConfig';
45

5-
export function createSequelize(useModelsInPath: boolean = true, define: DefineOptions<any> = {}): Sequelize {
6+
export function createSequelize(partialOptions: Partial<SequelizeConfig>): Sequelize;
7+
export function createSequelize(useModelsInPath?: boolean,
8+
define?: DefineOptions<any>): Sequelize;
9+
export function createSequelize(useModelsInPathOrPartialOptions?: boolean | Partial<SequelizeConfig>,
10+
define: DefineOptions<any> = {}): Sequelize {
11+
12+
let useModelsInPath = true;
13+
let partialOptions = {};
14+
if (typeof useModelsInPathOrPartialOptions === 'object') {
15+
partialOptions = useModelsInPathOrPartialOptions;
16+
} else if (typeof useModelsInPathOrPartialOptions === 'boolean') {
17+
useModelsInPath = useModelsInPathOrPartialOptions;
18+
}
619

720
return new Sequelize({
821
database: '__',
@@ -12,7 +25,8 @@ export function createSequelize(useModelsInPath: boolean = true, define: DefineO
1225
define,
1326
storage: ':memory:',
1427
logging: !('SEQ_SILENT' in process.env),
15-
modelPaths: useModelsInPath ? [__dirname + '/../models'] : []
28+
modelPaths: useModelsInPath ? [__dirname + '/../models'] : [],
29+
...partialOptions,
1630
});
1731
}
1832

0 commit comments

Comments
 (0)