Skip to content

Commit

Permalink
Update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hkan committed Mar 27, 2024
1 parent 2df08dd commit cecbe60
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 186 deletions.
50 changes: 24 additions & 26 deletions spec/CircularDeps/CircularDeps.spec.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
import { BlogPost } from './blog';
import Comment from './comment';
import { EntityBuilder } from '../../src/EntityBuilder';
import { BlogPost } from "./blog";
import Comment from "./comment";
import { EntityBuilder } from "../../src";

describe('Entity with circular dependency', () => {
it('decodes circularly depended annotated entity', () => {
const blog = EntityBuilder.buildOne(BlogPost, {
title: 'Decahedron/Entity gets circdep',
body: 'hooray!',
comments: [
{ body: 'Yay!' },
],
});

expect(blog.comments).toBeDefined();
expect(blog.comments[0]).toBeDefined();
expect(blog.comments[0].body).toEqual('Yay!');
describe("Entity with circular dependency", () => {
it("decodes circularly depended annotated entity", () => {
const blog = EntityBuilder.buildOne(BlogPost, {
title: "Decahedron/Entity gets circdep",
body: "hooray!",
comments: [{ body: "Yay!" }],
});

it('decodes circularly depended annotated entity other way around', () => {
const comment = EntityBuilder.buildOne(Comment, {
body: 'hooray!',
blog: {
title: 'Decahedron/Entity gets circdep',
body: 'hooray!',
},
});
expect(blog.comments).toBeDefined();
expect(blog.comments[0]).toBeDefined();
expect(blog.comments[0].body).toEqual("Yay!");
});

expect(comment.blog).toBeDefined();
expect(comment.blog.body).toEqual('hooray!');
it("decodes circularly depended annotated entity other way around", () => {
const comment = EntityBuilder.buildOne(Comment, {
body: "hooray!",
blog: {
title: "Decahedron/Entity gets circdep",
body: "hooray!",
},
});

expect(comment.blog).toBeDefined();
expect(comment.blog.body).toEqual("hooray!");
});
});
14 changes: 7 additions & 7 deletions spec/CircularDeps/blog.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Entity } from '../../src/Entity';
import { Type } from '../../src/support/Type';
import Comment from './comment';
import { Entity } from "../../src";
import { Type } from "../../src";
import Comment from "./comment";

export class BlogPost extends Entity {
public title: string = null;
public body: string = null;
public title!: string;
public body!: string;

@Type(() => require('./comment'))
public comments: Comment[] = [];
@Type(() => Comment)
public comments: Comment[] = [];
}
12 changes: 6 additions & 6 deletions spec/CircularDeps/comment.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Entity } from '../../src/Entity';
import { Type } from '../../src/support/Type';
import { BlogPost } from './blog';
import { Entity } from "../../src";
import { Type } from "../../src";
import { BlogPost } from "./blog";

export default class Comment extends Entity {
public body: string = null;
public body!: string;

@Type(() => require('./blog').BlogPost)
public blog: BlogPost = null;
@Type(() => BlogPost)
public blog!: BlogPost;
}
66 changes: 21 additions & 45 deletions spec/EntityBuilder.spec.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
import { EntityBuilder } from "../src";
import { Entity, PartialProps } from "../src";
import { Type } from "../src";
import { JsonExclude } from "../src/support/JsonExclude";
import { Entity, EntityBuilder, JsonExclude, Type } from "../src";

class User extends Entity {
public name: string = undefined;
public email: string = undefined;
public daysAvailable: string[] = [];
public name!: string;
public email!: string;
public daysAvailable!: string[];
}

class Address extends Entity {
public street: string = null;
public city: string = null;
public zip: string = null;
public country: string = null;
public street!: string;
public city!: string;
public zip!: string;
public country!: string;
}

class Post extends Entity {
public title: string = null;
public content: string = null;
public title!: string;
public content!: string;
}

class UserWithAddress extends User {
public address: Address = null;
public address!: Address;
}

class UserWithAnnotatedAddress extends User {
@Type(Address)
public address: Address;
public address!: Address;
}

class UserWithAnnotatedPosts extends User {
Expand All @@ -37,21 +34,16 @@ class UserWithAnnotatedPosts extends User {

class UserWithAnnotatedObject extends User {
@Type(Object)
public address: { [key: string]: string };
public address!: { [key: string]: string };
}

class UserWithExcludedOutput extends User {
@JsonExclude()
public value: string = "test";
}

class UserWithAliasedPrimitive extends User {
@Type(String, "second_name")
public middleName: string;
}

class UserWithDefaultValue extends User {
public company: string = "Jobilla Oy";
public company: string | null = "Jobilla Oy";
}

describe("EntityBuilder", () => {
Expand Down Expand Up @@ -122,9 +114,9 @@ describe("EntityBuilder", () => {
});

expect(user.posts).toBeDefined();
expect(user.posts[0]).toBeDefined();
expect(user.posts[0].title).toEqual("About");
expect(user.posts[0].content).toEqual("Lorem ipsum dolor sit amet");
expect(user.posts?.[0]).toBeDefined();
expect(user.posts?.[0].title).toEqual("About");
expect(user.posts?.[0].content).toEqual("Lorem ipsum dolor sit amet");
});

it("decodes an annotated optional nested array object to empty array", async () => {
Expand All @@ -139,22 +131,6 @@ describe("EntityBuilder", () => {
expect(user.posts).toEqual([]);
});

it("interprets an annotated primitive as an alias", () => {
/*
* Type casting at the end is because EntityBuilder would not accept explicit aliased keys,
* but a real application will likely pass data directly from an API response, so this
* casting is not something consumer codebases will need to do most of the time.
*/
const user = EntityBuilder.buildOne(UserWithAliasedPrimitive, {
name: "Decahedron Technologies Ltd",
email: "hello@decahedron.io",
days_available: ["Monday", "Wednesday", "Friday"],
second_name: "A Middle Name",
} as PartialProps<UserWithAliasedPrimitive>);

expect(user.middleName).toEqual("A Middle Name");
});

it("persists default value if nothing is provided for a property", () => {
const user = EntityBuilder.buildOne(UserWithDefaultValue, {
name: "Decahedron Technologies Ltd",
Expand Down Expand Up @@ -292,21 +268,21 @@ describe("EntityBuilder", () => {
name: "Decahedron Technologies Ltd.",
email: "hello@decahedron.io",
days_available: ["Monday", "Wednesday", "Friday"],
address: null,
address: undefined,
});

expect(user.toJson()).toEqual({
name: "Decahedron Technologies Ltd.",
email: "hello@decahedron.io",
days_available: ["Monday", "Wednesday", "Friday"],
address: null,
address: undefined,
});
});

it("should preserve null values for non-annotated attributes", async () => {
const user = EntityBuilder.buildOne(UserWithAnnotatedAddress, {
name: "Decahedron Technologies Ltd.",
email: null,
email: undefined,
days_available: ["Monday", "Wednesday", "Friday"],
address: {
street: "20-22 Wenlock Road",
Expand All @@ -318,7 +294,7 @@ describe("EntityBuilder", () => {

expect(user.toJson()).toEqual({
name: "Decahedron Technologies Ltd.",
email: null,
email: undefined,
days_available: ["Monday", "Wednesday", "Friday"],
address: {
street: "20-22 Wenlock Road",
Expand Down
76 changes: 33 additions & 43 deletions spec/Type.spec.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,37 @@
import { Type } from '../src/support/Type';
import { defaultMetadataStorage } from '../src/support/storage';
import { Entity } from '../src/Entity';

class Decorated extends Entity {

}

describe('Decorators - Type', () => {
describe('Inferred attribute names', () => {
it('Stores the target type, attribute name and infers the source attribute name', () => {
let decorator = Type(Decorated);
let fn = (): null => null;
decorator(fn as unknown as Entity, 'attribute');

let storedMetadata = defaultMetadataStorage.findTypeMetadata(fn.constructor, 'attribute');
expect(storedMetadata).not.toBeUndefined();
expect(storedMetadata.propertyName).toEqual('attribute');
expect(storedMetadata.sourcePropertyName).toEqual('attribute');
expect(storedMetadata.type).toEqual(Decorated);
});

it('Infers that the source name should be snake_case', () => {
let decorator = Type(Decorated);
let fn = (): null => null;
decorator(fn as unknown as Entity, 'camelAttribute');

let storedMetadata = defaultMetadataStorage.findTypeMetadata(fn.constructor, 'camel_attribute');
expect(storedMetadata).not.toBeUndefined();
expect(storedMetadata.propertyName).toEqual('camelAttribute');
expect(storedMetadata.sourcePropertyName).toEqual('camel_attribute');
expect(storedMetadata.type).toEqual(Decorated);
});
import { Type } from "../src";
import { defaultMetadataStorage } from "../src/support/storage";
import { Entity } from "../src";

class Decorated extends Entity {}

describe("Decorators - Type", () => {
describe("Inferred attribute names", () => {
it("Stores the target type, attribute name and infers the source attribute name", () => {
let decorator = Type(Decorated);
let fn = (): null => null;
decorator(fn as unknown as Entity, "attribute");

let storedMetadata = defaultMetadataStorage.findTypeMetadata(
fn.constructor,
"attribute",
);
expect(storedMetadata).not.toBeUndefined();
expect(storedMetadata.propertyName).toEqual("attribute");
expect(storedMetadata.type).toEqual(Decorated);
});

it('Allows manually overriding the source attribute name', () => {
let decorator = Type(Decorated, 'camelAttribute');
let fn = (): null => null;
decorator(fn as unknown as Entity, 'camelAttribute');

let storedMetadata = defaultMetadataStorage.findTypeMetadata(fn.constructor, 'camelAttribute');
expect(storedMetadata).not.toBeUndefined();
expect(storedMetadata.propertyName).toEqual('camelAttribute');
expect(storedMetadata.sourcePropertyName).toEqual('camelAttribute');
expect(storedMetadata.type).toEqual(Decorated);
it("Infers that the source name should be snake_case", () => {
let decorator = Type(Decorated);
let fn = (): null => null;
decorator(fn as unknown as Entity, "camelAttribute");

let storedMetadata = defaultMetadataStorage.findTypeMetadata(
fn.constructor,
"camel_attribute",
);
expect(storedMetadata).not.toBeUndefined();
expect(storedMetadata.propertyName).toEqual("camel_attribute");
expect(storedMetadata.type).toEqual(Decorated);
});
});
});
Loading

0 comments on commit cecbe60

Please sign in to comment.