Skip to content

Commit 4113d34

Browse files
Robin BuschmannRobin Buschmann
authored andcommitted
more tests added; coverage added; some cleanups
1 parent 37cf800 commit 4113d34

File tree

13 files changed

+171
-84
lines changed

13 files changed

+171
-84
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ node_modules
1010

1111
# testing
1212
coverage
13+
.nyc_output
1314

1415
#logs
1516
npm-debug.log

.travis.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ node_js:
66
install:
77
- npm install
88

9-
before_script:
10-
119
script:
12-
- npm test
10+
- npm run lint
11+
- npm run build
12+
- npm run cover
13+
14+
after_success:
15+
- 'nyc report --reporter=lcov > coverage.lcov && codecov'

README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Your `tsconfig.json` needs the following flags:
4444

4545
## Model definition
4646
```typescript
47-
import {Table, Column, Model} from 'sequelize-typescript';
47+
import {Table, Column, Model, HasMany} from 'sequelize-typescript';
4848

4949
@Table
5050
class Person extends Model<Person> {
@@ -53,7 +53,10 @@ class Person extends Model<Person> {
5353
name: string;
5454

5555
@Column
56-
age: number;
56+
birthday: Date;
57+
58+
@HasMany(() => Hobby)
59+
hobbies: Hobby[];
5760
}
5861
```
5962
The model needs to extend the `Model` class and has to be annotated with the `@Table` decorator. All properties, that
@@ -161,6 +164,23 @@ Design type | Sequelize data type
161164
`Date` | `DATE`
162165
`Buffer` | `BLOB`
163166

167+
### Accessors
168+
Get/set accessors do work as well
169+
```typescript
170+
@Table
171+
class Person extends Model<Person> {
172+
173+
@Column
174+
get name(): string {
175+
return 'My name is ' + this.getDataValue('name');
176+
}
177+
178+
set name(value: string) {
179+
this.setDataValue('name', value);
180+
}
181+
}
182+
```
183+
164184
## Usage
165185
Except for minor variations *sequelize-typescript* will work like pure sequelize.
166186
(See sequelize [docs](http://docs.sequelizejs.com/en/v3/docs/models-usage/))

index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export {IsIn} from "./lib/annotations/validation/IsIn";
3232
export {IsInt} from "./lib/annotations/validation/IsInt";
3333
export {IsIP} from "./lib/annotations/validation/IsIP";
3434
export {IsIPv4} from "./lib/annotations/validation/IsIPv4";
35+
export {IsArray} from "./lib/annotations/validation/IsArray";
3536
export {IsIPv6} from "./lib/annotations/validation/IsIPv6";
3637
export {IsLowercase} from "./lib/annotations/validation/IsLowercase";
3738
export {IsNull} from "./lib/annotations/validation/IsNull";

lib/services/models.ts

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import * as fs from 'fs';
33
import * as path from 'path';
44
import {DataTypeAbstract, DefineOptions} from 'sequelize';
55
import {Model} from "../models/Model";
6-
import {ISequelizeForeignKeyConfig} from "../interfaces/ISequelizeForeignKeyConfig";
76
import {IPartialDefineAttributeColumnOptions} from "../interfaces/IPartialDefineAttributeColumnOptions";
87
import {inferDataType} from "../utils/data-type";
98
import {deepAssign} from "../utils/object";
@@ -15,7 +14,6 @@ const MODEL_NAME_KEY = 'sequelize:modelName';
1514
const SCOPES_KEY = 'sequelize:scopes';
1615
const ATTRIBUTES_KEY = 'sequelize:attributes';
1716
const OPTIONS_KEY = 'sequelize:options';
18-
const FOREIGN_KEYS_KEY = 'sequelize:foreignKey';
1917
const DEFAULT_OPTIONS: DefineOptions<any> = {
2018
timestamps: false
2119
};
@@ -153,26 +151,6 @@ export function getSequelizeTypeByDesignType(target: any, propertyName: string):
153151
define the data type manually`);
154152
}
155153

156-
/**
157-
* Adds foreign key meta data for specified class
158-
*/
159-
export function addForeignKey(target: any,
160-
relatedClassGetter: () => typeof Model,
161-
propertyName: string): void {
162-
163-
let foreignKeys = getForeignKeys(target);
164-
165-
if (!foreignKeys) {
166-
foreignKeys = [];
167-
setForeignKeys(target, foreignKeys);
168-
}
169-
170-
foreignKeys.push({
171-
relatedClassGetter,
172-
foreignKey: propertyName
173-
});
174-
}
175-
176154
/**
177155
* Determines models from value
178156
*/
@@ -349,20 +327,3 @@ function setScopeOptions(target: any, options: IScopeOptions): void {
349327

350328
Reflect.defineMetadata(SCOPES_KEY, options, target);
351329
}
352-
353-
354-
/**
355-
* Returns foreign key meta data from specified class
356-
*/
357-
function getForeignKeys(target: any): ISequelizeForeignKeyConfig[]|undefined {
358-
359-
return Reflect.getMetadata(FOREIGN_KEYS_KEY, target);
360-
}
361-
362-
/**
363-
* Set foreign key meta data for specified prototype
364-
*/
365-
function setForeignKeys(target: any, foreignKeys: ISequelizeForeignKeyConfig[]): void {
366-
367-
Reflect.defineMetadata(FOREIGN_KEYS_KEY, foreignKeys, target);
368-
}

lib/utils/validation.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

package.json

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
"build": "tsc && tsc --project lib/models/v4",
77
"build-tests-es5": "tsc --project test",
88
"build-tests-es6": "tsc --project test --target es6",
9-
"prepare-test-v3": "npm install [email protected] && npm run build && npm run build-tests-es5",
10-
"prepare-test-v4": "npm install [email protected] && npm run build && npm run build-tests-es6",
9+
"prepare-test-v3": "npm install [email protected] && npm run build-tests-es5",
10+
"prepare-test-v4": "npm install [email protected] && npm run build-tests-es6",
1111
"test-v3": "npm run prepare-test-v3 && npm run exec-tests",
1212
"test-v4": "npm run prepare-test-v4 && npm run exec-tests",
13+
"cover-v3": "npm run prepare-test-v3 && SEQ_SILENT=true nyc --exclude 'lib/models/v4/**/*.js' --all --require source-map-support/register mocha 'test/specs/**/*.js'",
14+
"cover-v4": "npm run prepare-test-v4 && SEQ_SILENT=true nyc --exclude 'lib/models/v3/**/*.js' --all --require source-map-support/register mocha 'test/specs/**/*.js'",
1315
"exec-tests": "SEQ_SILENT=true mocha 'test/specs/**/*.js'",
14-
"test": "npm run test-v4 && npm run test-v3"
16+
"test": "npm run test-v4 && npm run test-v3",
17+
"cover": "npm run cover-v4 && npm run cover-v3",
18+
"lint": "tslint ."
1519
},
1620
"repository": {
1721
"type": "git",
@@ -47,16 +51,38 @@
4751
"mocha": "3.2.0",
4852
"moment": "2.17.1",
4953
"mysql": "2.13.0",
54+
"nyc": "10.1.2",
5055
"prettyjson": "1.2.1",
5156
"reflect-metadata": "0.1.9",
5257
"sinon": "1.17.7",
5358
"sinon-chai": "2.8.0",
59+
"source-map-support": "0.4.14",
5460
"sqlite3": "3.1.8",
5561
"tslint": "4.3.1",
5662
"typescript": "2.2.1",
5763
"uuid-validate": "0.0.2"
5864
},
5965
"engines": {
6066
"node": ">=0.8.15"
67+
},
68+
"nyc": {
69+
"lines": 85,
70+
"statements": 85,
71+
"functions": 85,
72+
"branches": 85,
73+
"include": [
74+
"lib/**/*.js"
75+
],
76+
"exclude": [
77+
"test/**/*.js"
78+
],
79+
"reporter": [
80+
"lcov",
81+
"text-summary"
82+
],
83+
"cache": true,
84+
"all": true,
85+
"check-coverage": true,
86+
"report-dir": "./coverage"
6187
}
6288
}

test/models/ShoeWithScopes.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export class ShoeWithScopes extends Model<ShoeWithScopes> {
2828
@Column
2929
secondaryColor: string;
3030

31+
@Column
32+
img: Buffer;
33+
3134
@Column
3235
producedAt: Date;
3336

test/models/ShoeWithValidation.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
Equals, Contains, Is, IsDate, Length, IsUrl, IsAfter, IsBefore,
44
IsUUID, IsAlpha, IsAlphanumeric, IsEmail, IsInt, IsDecimal, IsFloat,
55
IsIn, IsIP, IsIPv4, IsIPv6, IsLowercase, IsUppercase, Max, Min,
6-
Not, NotContains, NotIn, NotNull, Validate
6+
Not, NotContains, NotIn, NotNull, Validate, NotEmpty, IsNumeric,
7+
IsNull, IsArray
78
} from "../../index";
89
import {IsCreditCard} from "../../lib/annotations/validation/IsCreditCard";
910

@@ -80,6 +81,10 @@ export class ShoeWithValidation extends Model<ShoeWithValidation> {
8081
@IsLowercase
8182
@IsUppercase
8283
@NotNull
84+
@NotEmpty
85+
@IsArray
86+
@IsNull
87+
@IsNumeric
8388
@Max(MAX)
8489
@Min(MIN)
8590
@Not(NOT)

test/specs/table_column.spec.ts

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {User} from "../models/User";
66
import {getOptions, getAttributes} from "../../lib/services/models";
77
import {Shoe, SHOE_TABLE_NAME} from "../models/Shoe";
88

9+
/* tslint:disable:max-classes-per-file */
10+
911
describe('table_column', () => {
1012

1113
const sequelize = createSequelize();
@@ -195,49 +197,94 @@ describe('table_column', () => {
195197

196198
});
197199

198-
describe('implicit get', () => {
200+
describe('accessors', () => {
199201

200-
@Table
201-
class User extends Model<User> {
202+
describe('get', () => {
202203

203-
@Column
204-
get name(): string {
205-
return 'My name is ' + this.getDataValue('name');
206-
}
204+
@Table
205+
class User extends Model<User> {
206+
207+
@Column
208+
get name(): string {
209+
return 'My name is ' + this.getDataValue('name');
210+
}
207211

208-
set name(value: string) {
209-
this.setDataValue('name', value);
212+
set name(value: string) {
213+
this.setDataValue('name', value);
214+
}
210215
}
211-
}
212216

213-
sequelize.addModels([User]);
217+
sequelize.addModels([User]);
214218

215-
it('should consider getter', () => {
219+
it('should consider getter', () => {
216220

217-
const user = new User({});
218-
user.name = 'Peter';
221+
const user = new User({});
222+
user.name = 'Peter';
219223

220-
expect(user.name).to.equal('My name is Peter');
221-
});
224+
expect(user.name).to.equal('My name is Peter');
225+
});
222226

223-
it('shouldn\'t store value from getter', () => {
227+
it('shouldn\'t store value from getter into db', () => {
224228

225-
const user = new User({});
229+
const user = new User({});
226230

227-
user.name = 'elli';
231+
user.name = 'elli';
228232

229-
return user
230-
.save()
231-
.then(() => User.findById(user.id))
232-
.then(_user => {
233+
return user
234+
.save()
235+
.then(() => User.findById(user.id))
236+
.then(_user => {
237+
238+
expect(_user.getDataValue('name')).to.equal('elli');
239+
});
240+
});
233241

234-
expect(_user.getDataValue('name')).to.equal('elli');
235-
});
236242
});
237243

238-
});
244+
describe('set', () => {
245+
246+
@Table
247+
class User extends Model<User> {
248+
249+
@Column
250+
get name(): string {
251+
return this.getDataValue('name');
252+
}
253+
254+
set name(value: string) {
255+
this.setDataValue('name', value.toUpperCase());
256+
}
257+
}
239258

240-
describe('implicit set', () => {
259+
sequelize.addModels([User]);
260+
261+
it('should consider setter', () => {
262+
263+
const name = 'Peter';
264+
265+
const user = new User({});
266+
user.name = name;
267+
268+
expect(user.name).to.equal(name.toUpperCase());
269+
});
270+
271+
it('should store value from setter into db', () => {
272+
273+
const name = 'elli';
274+
const user = new User({});
275+
276+
user.name = name;
277+
278+
return user
279+
.save()
280+
.then(() => User.findById(user.id))
281+
.then(_user => {
282+
283+
expect(_user.getDataValue('name')).to.equal(name.toUpperCase());
284+
});
285+
});
286+
287+
});
241288

242289
});
243290

0 commit comments

Comments
 (0)