Skip to content

Commit c2dcc64

Browse files
committed
test: add camel case and snake case naming strategy test cases
1 parent cc22879 commit c2dcc64

File tree

6 files changed

+159
-27
lines changed

6 files changed

+159
-27
lines changed

test/columnNamingStrategy.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { expect } from 'chai';
2+
import { createConnection, getConnection } from 'typeorm';
3+
4+
import { createQueryBuilder } from './utils/createQueryBuilder';
5+
import {
6+
prepareData,
7+
prepareSnakeData,
8+
} from './utils/prepareData';
9+
import { User } from './entities/User';
10+
import { Photo } from './entities/Photo';
11+
import { Snake } from './entities/Snake';
12+
import { buildPaginator } from '../src/index';
13+
14+
describe('TypeORM cursor-based pagination column naming strategy test', () => {
15+
describe('Camel case naming strategy', () => {
16+
before(async () => {
17+
await createConnection({
18+
type: 'postgres',
19+
host: 'localhost',
20+
port: 5432,
21+
username: 'test',
22+
password: 'test',
23+
database: 'test',
24+
synchronize: true,
25+
entities: [User, Photo],
26+
logging: true,
27+
});
28+
29+
await prepareData();
30+
});
31+
32+
it('should correctly paginate entities with camel case pagination keys', async () => {
33+
const queryBuilder = createQueryBuilder(User, 'user');
34+
const paginator = buildPaginator({
35+
entity: User,
36+
query: {
37+
limit: 1,
38+
},
39+
paginationKeys: ['camelCaseColumn'],
40+
});
41+
const result = await paginator.paginate(queryBuilder.clone());
42+
43+
const nextPagePaginator = buildPaginator({
44+
entity: User,
45+
query: {
46+
limit: 1,
47+
afterCursor: result.cursor.afterCursor as string,
48+
},
49+
paginationKeys: ['camelCaseColumn'],
50+
});
51+
const nextResult = await nextPagePaginator.paginate(queryBuilder.clone());
52+
53+
expect(nextResult.data).length(1);
54+
});
55+
56+
after(async () => {
57+
await getConnection().query('TRUNCATE TABLE users RESTART IDENTITY CASCADE;');
58+
await getConnection().close();
59+
});
60+
});
61+
62+
describe('Snake case naming strategy test', () => {
63+
before(async () => {
64+
await createConnection({
65+
type: 'postgres',
66+
host: 'localhost',
67+
port: 5432,
68+
username: 'test',
69+
password: 'test',
70+
database: 'test',
71+
synchronize: true,
72+
entities: [Snake],
73+
logging: true,
74+
});
75+
76+
await prepareSnakeData();
77+
});
78+
79+
it('should correctly paginate entities with snake case pagination keys', async () => {
80+
const queryBuilder = createQueryBuilder(Snake, 'snake');
81+
const paginator = buildPaginator({
82+
entity: Snake,
83+
query: {
84+
limit: 1,
85+
},
86+
paginationKeys: ['snakeCaseColumn'],
87+
});
88+
const result = await paginator.paginate(queryBuilder.clone());
89+
90+
const nextPagePaginator = buildPaginator({
91+
entity: Snake,
92+
query: {
93+
limit: 1,
94+
afterCursor: result.cursor.afterCursor as string,
95+
},
96+
paginationKeys: ['snakeCaseColumn'],
97+
});
98+
const nextResult = await nextPagePaginator.paginate(queryBuilder.clone());
99+
100+
expect(nextResult.data).length(1);
101+
});
102+
103+
after(async () => {
104+
await getConnection().query('TRUNCATE TABLE snakes RESTART IDENTITY CASCADE;');
105+
await getConnection().close();
106+
});
107+
});
108+
});

test/entities/Snake.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {
2+
Entity,
3+
Column,
4+
PrimaryGeneratedColumn,
5+
} from 'typeorm';
6+
7+
@Entity({ name: 'snakes' })
8+
export class Snake {
9+
@PrimaryGeneratedColumn()
10+
public id!: number;
11+
12+
@Column({
13+
name: 'snake_case_column',
14+
type: 'timestamp',
15+
nullable: false,
16+
})
17+
public snakeCaseColumn!: Date
18+
}

test/entities/User.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class User {
2424
type: 'timestamp',
2525
nullable: false,
2626
})
27-
public timestamp!: Date
27+
public camelCaseColumn!: Date
2828

2929
@OneToMany(
3030
() => Photo,
Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ describe('TypeORM cursor-based pagination test', () => {
2525
});
2626

2727
it('should paginate correctly with before and after cursor', async () => {
28-
const queryBuilder = createQueryBuilder().leftJoinAndSelect('user.photos', 'photo');
28+
const queryBuilder = createQueryBuilder(User, 'user').leftJoinAndSelect('user.photos', 'photo');
2929
const firstPagePaginator = buildPaginator({
3030
entity: User,
31-
paginationKeys: ['id', 'name', 'timestamp'],
31+
paginationKeys: ['id', 'name'],
3232
query: {
3333
limit: 1,
3434
},
@@ -37,7 +37,7 @@ describe('TypeORM cursor-based pagination test', () => {
3737

3838
const nextPagePaginator = buildPaginator({
3939
entity: User,
40-
paginationKeys: ['id', 'name', 'timestamp'],
40+
paginationKeys: ['id', 'name'],
4141
query: {
4242
limit: 1,
4343
afterCursor: firstPageResult.cursor.afterCursor as string,
@@ -47,7 +47,7 @@ describe('TypeORM cursor-based pagination test', () => {
4747

4848
const prevPagePaginator = buildPaginator({
4949
entity: User,
50-
paginationKeys: ['id', 'name', 'timestamp'],
50+
paginationKeys: ['id', 'name'],
5151
query: {
5252
limit: 1,
5353
beforeCursor: nextPageResult.cursor.beforeCursor as string,
@@ -69,7 +69,7 @@ describe('TypeORM cursor-based pagination test', () => {
6969
});
7070

7171
it('should return entities with given order', async () => {
72-
const queryBuilder = createQueryBuilder();
72+
const queryBuilder = createQueryBuilder(User, 'user');
7373
const ascPaginator = buildPaginator({
7474
entity: User,
7575
query: {
@@ -93,21 +93,21 @@ describe('TypeORM cursor-based pagination test', () => {
9393
});
9494

9595
it('should return entities with given limit', async () => {
96-
const queryBuilder = createQueryBuilder();
96+
const queryBuilder = createQueryBuilder(User, 'user');
9797
const paginator = buildPaginator({
9898
entity: User,
9999
query: {
100-
limit: 10,
100+
limit: 5,
101101
},
102102
});
103103

104104
const result = await paginator.paginate(queryBuilder);
105105

106-
expect(result.data).length(10);
106+
expect(result.data).length(5);
107107
});
108108

109109
it('should return empty array and null cursor if no data', async () => {
110-
const queryBuilder = createQueryBuilder().where('user.id > :id', { id: 10 });
110+
const queryBuilder = createQueryBuilder(User, 'user').where('user.id > :id', { id: 10 });
111111
const paginator = buildPaginator({
112112
entity: User,
113113
});
@@ -118,17 +118,6 @@ describe('TypeORM cursor-based pagination test', () => {
118118
expect(result.cursor.afterCursor).to.eq(null);
119119
});
120120

121-
it('should correctly paginate entities with camel-cased pagination keys', async () => {
122-
const queryBuilder = createQueryBuilder();
123-
const paginator = buildPaginator({
124-
entity: User,
125-
paginationKeys: ['createdAt', 'id'],
126-
});
127-
const result = await paginator.paginate(queryBuilder);
128-
129-
expect(result.data).length(10);
130-
});
131-
132121
after(async () => {
133122
await getConnection().query('TRUNCATE TABLE users RESTART IDENTITY CASCADE;');
134123
await getConnection().close();

test/utils/createQueryBuilder.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { getConnection, SelectQueryBuilder } from 'typeorm';
2-
import { User } from '../entities/User';
1+
import { getConnection, SelectQueryBuilder, ObjectType } from 'typeorm';
32

4-
export function createQueryBuilder(): SelectQueryBuilder<User> {
3+
export function createQueryBuilder<T>(entity: ObjectType<T>, alias: string): SelectQueryBuilder<T> {
54
return getConnection()
6-
.getRepository(User)
7-
.createQueryBuilder('user');
5+
.getRepository(entity)
6+
.createQueryBuilder(alias);
87
}

test/utils/prepareData.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import { getConnection } from 'typeorm';
22
import { User } from '../entities/User';
3+
import { Snake } from '../entities/Snake';
4+
5+
function setTimestamp(i: number): Date {
6+
const now = new Date();
7+
now.setMinutes(now.getMinutes() + i);
8+
9+
return now;
10+
}
311

412
export async function prepareData(): Promise<void> {
513
const data = [...Array(10).keys()].map((i) => ({
614
name: `user${i}`,
7-
timestamp: new Date(),
15+
camelCaseColumn: setTimestamp(i),
816
photos: [
917
{
1018
link: `http://photo.com/${i}`,
@@ -16,3 +24,13 @@ export async function prepareData(): Promise<void> {
1624
.getRepository(User)
1725
.save(data);
1826
}
27+
28+
export async function prepareSnakeData(): Promise<void> {
29+
const data = [...Array(10).keys()].map((i) => ({
30+
snakeCaseColumn: setTimestamp(i),
31+
}));
32+
33+
await getConnection()
34+
.getRepository(Snake)
35+
.save(data);
36+
}

0 commit comments

Comments
 (0)