Skip to content

Commit

Permalink
Implement modified event
Browse files Browse the repository at this point in the history
  • Loading branch information
NoelDeMartin committed May 25, 2024
1 parent 1143544 commit 740a273
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Added

- Augmenting the `ModelEvents` interface it is now possible to extend model events with custom events.
- The following model events: `modified`, `relation-loaded`.

### Changed

Expand Down
19 changes: 18 additions & 1 deletion src/models/Model.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { faker } from '@noeldemartin/faker';
import { after, seconds, tt } from '@noeldemartin/utils';
import { after, afterAnimationFrame, seconds, tt } from '@noeldemartin/utils';

Check failure on line 2 in src/models/Model.test.ts

View workflow job for this annotation

GitHub Actions / ci

'afterAnimationFrame' is defined but never used
import type { Assert, Equals, Expect, Extends, HasKey , Not } from '@noeldemartin/utils';

import InvalidModelDefinition from '@/errors/InvalidModelDefinition';
Expand Down Expand Up @@ -50,25 +50,42 @@ describe('Model', () => {

it('emits events', async () => {
// Arrange
const modifiedHistory: string[] = [];
let createCount = 0;
let updateCount = 0;
let deleteCount = 0;

Post.on('modified', (_, field) => modifiedHistory.push(field));
Post.on('created', () => createCount++);
Post.on('updated', () => updateCount++);
Post.on('deleted', () => deleteCount++);

// Act
const post = await Post.create({ title: faker.random.words() });

post.title = faker.random.words();
post.title = faker.random.words();
post.body = faker.lorem.paragraphs();

await after({ ms: 10 });
post.update({ title: faker.random.words() });

await after({ ms: 10 });
post.update({ title: faker.random.words() });

await after({ ms: 10 });
post.update({ title: faker.random.words() });

await after({ ms: 10 });
await Post.create({ title: faker.random.words() });
await post.delete();

// Assert
expect(modifiedHistory).toHaveLength(13);
expect(modifiedHistory.filter(field => field === 'title')).toHaveLength(5);
expect(modifiedHistory.filter(field => field === 'body')).toHaveLength(1);
expect(modifiedHistory.filter(field => field === 'createdAt')).toHaveLength(2);
expect(modifiedHistory.filter(field => field === 'updatedAt')).toHaveLength(5);
expect(createCount).toBe(2);
expect(updateCount).toBe(3);
expect(deleteCount).toBe(1);
Expand Down
10 changes: 6 additions & 4 deletions src/models/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ export type ModelCastAttributeOptions = {
export interface ModelEvents {
created: void;
deleted: void;
'relation-loaded': Relation;
updated: void;
modified: string;
'relation-loaded': Relation;
}

export type ModelEmitArgs<T extends keyof ModelEvents> =
Expand Down Expand Up @@ -593,9 +594,10 @@ export class Model {
}

public setAttribute(field: string, value: unknown): void {
return this.hasAttributeSetter(field)
? this.callAttributeSetter(field, value)
: this.setAttributeValue(field, value);
const previousValue = this.getAttribute(field);

this.hasAttributeSetter(field) ? this.callAttributeSetter(field, value) : this.setAttributeValue(field, value);
this.attributeValueChanged(previousValue, value) && this.emit('modified', field);
}

public setAttributeValue(field: string, value: unknown): void {
Expand Down

0 comments on commit 740a273

Please sign in to comment.