undeexcepturi
Version:
TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.
174 lines (129 loc) • 3.49 kB
text/typescript
import { Collection, Entity, LoadStrategy, ManyToOne, MikroORM, OneToMany, OneToOne, PrimaryKey, Property } from '@mikro-orm/sqlite';
import { v4 } from 'uuid';
@Entity()
export class A {
@PrimaryKey()
id: string = v4();
@Property({ unique: true })
value!: string;
}
@Entity()
export class T {
@PrimaryKey()
id: string = v4();
@Property({ unique: true })
value!: string;
}
@Entity()
export class I {
@OneToOne({ entity: 'V', joinColumn: 'id', primary: true, mapToPk: true })
id!: string;
@Property({ unique: true })
value!: number;
}
@Entity()
export class V {
@PrimaryKey()
id: string = v4();
@OneToOne({ entity: 'I', mappedBy: 'id', nullable: true })
i?: I;
}
@Entity()
export class E {
@PrimaryKey()
id: string = v4();
@ManyToOne({ entity: 'A' })
a!: A;
@ManyToOne({ entity: 'T' })
t!: T;
@ManyToOne({ entity: 'V' })
v!: V;
}
@Entity()
export class M {
@PrimaryKey()
id: string = v4();
@ManyToOne({ entity: 'N', hidden: true, mapToPk: true })
n!: string;
@ManyToOne({ entity: 'E' })
e!: E;
}
@Entity()
export class N {
@OneToOne({ entity: 'E', joinColumn: 'id', primary: true })
id!: E;
@ManyToOne({ entity: 'A' })
a!: A;
@OneToMany({ entity: 'M', mappedBy: 'n' })
m = new Collection<M>(this);
}
async function createEntities(orm: MikroORM) {
const a = orm.em.create(A, { value: 'A' });
const t = orm.em.create(T, { value: 'T' });
const v = orm.em.create(V, {});
const a2 = orm.em.create(A, { value: 'A2' });
const t2 = orm.em.create(T, { value: 'T2' });
const v2 = orm.em.create(V, {});
const e = orm.em.create(E, { a, t, v });
const e2 = orm.em.create(E, { a: a2, t: t2, v: v2 });
const n = orm.em.create(N, { id: e, a });
const m = orm.em.create(M, { n: n.id.id, e: e2 });
await orm.em.persistAndFlush([m, n]);
const i = orm.em.create(I, { id: v.id, value: 5 });
const i2 = orm.em.create(I, { id: v2.id, value: 6 });
await orm.em.persistAndFlush([i, i2]);
orm.em.clear();
}
describe('GH issue 1134', () => {
let orm: MikroORM;
beforeAll(async () => {
orm = await MikroORM.init({
entities: [E, T, A, V, I, N, M],
dbName: ':memory:',
});
await orm.schema.createSchema();
await createEntities(orm);
});
beforeEach(() => orm.em.clear());
afterAll(() => orm.close(true));
test('Load nested data with smart populate (select-in strategy)', async () => {
const entity = await orm.em.getRepository(N).findAll({ populate: ['*'] });
const json = JSON.parse(JSON.stringify(entity));
// check both entity and DTO
[entity, json].forEach(item => {
expect(item[0].m[0].e).toMatchObject({
a: {
value: 'A2',
},
t: {
value: 'T2',
},
v: {
i: {
value: 6,
},
},
});
});
});
test('Load nested data with smart populate (select-in strategy will be forced due to `populate: true`)', async () => {
const entity = await orm.em.getRepository(N).findAll({ populate: ['*'], strategy: LoadStrategy.JOINED });
const json = JSON.parse(JSON.stringify(entity));
// check both entity and DTO
const expected = {
a: {
value: 'A2',
},
t: {
value: 'T2',
},
v: {
i: {
value: 6,
},
},
};
expect(entity[0].m[0].e).toMatchObject(expected);
expect(json[0].m[0].e).toMatchObject(expected);
});
});