Skip to content

Commit

Permalink
feat: enable serialization of enumerable and actions (#79)
Browse files Browse the repository at this point in the history
* feat: add reflective serialization of objects with getters

* feat: enable serialization of enumerable

* feat: enable serialization of action instances

* fix: linting

* test: add tests for KeyAction and DialAction serialization

---------

Co-authored-by: Richard Herman <[email protected]>
  • Loading branch information
GeekyEggo and GeekyEggo authored Jan 17, 2025
1 parent e7bdd5f commit 7d0cd10
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/common/__tests__/enumerable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -813,4 +813,24 @@ describe("Enumerable", () => {
expect(res).toHaveLength(0);
});
});

/**
* Provides assertions for {@link Enumerable.toJSON}.
*/
test("toJSON", () => {
const arr = ["One", "Two"];
const enumerable = new Enumerable(arr);

expect(JSON.stringify(arr)).toEqual(JSON.stringify(enumerable));
});

/**
* Provides assertions for {@link Enumerable.toString}.
*/
test("toString", () => {
const arr = ["One", "Two"];
const enumerable = new Enumerable(arr);

expect(arr.toString()).toEqual(enumerable.toString());
});
});
16 changes: 16 additions & 0 deletions src/common/enumerable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,4 +339,20 @@ export class Enumerable<T> implements IterableIterator<T> {
public toArray(): T[] {
return Array.from(this);
}

/**
* Converts this iterator to serializable collection.
* @returns The serializable collection of items.
*/
public toJSON(): T[] {
return this.toArray();
}

/**
* Converts this iterator to a string.
* @returns The string.
*/
public toString(): string {
return `${this.toArray()}`;
}
}
33 changes: 33 additions & 0 deletions src/plugin/actions/__tests__/dial.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,39 @@ describe("DialAction", () => {
expect(() => new DialAction(keypadSource)).toThrow();
});

/**
* Asserts {@link DialAction.toJSON} includes properties.
*/
it("JSON has properties", () => {
// Array.
const action = new DialAction({
action: "action1",
context: "com.test.action.one",
device: "dev1",
event: "willAppear",
payload: {
controller: "Encoder",
settings: {},
isInMultiAction: false,
coordinates: {
column: 1,
row: 2,
},
},
});

// Act.
const jsonStr = JSON.stringify(action);
const jsonObj: DialAction = JSON.parse(jsonStr);

// Assert.
expect(jsonObj.controllerType).toBe(action.controllerType);
expect(jsonObj.coordinates).toStrictEqual(action.coordinates);
expect(jsonObj.device).toStrictEqual({ id: action.device.id });
expect(jsonObj.id).toBe(action.id);
expect(jsonObj.manifestId).toBe(action.manifestId);
});

describe("sending", () => {
let action!: DialAction;
beforeAll(() => (action = new DialAction(source)));
Expand Down
34 changes: 34 additions & 0 deletions src/plugin/actions/__tests__/key.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,40 @@ describe("KeyAction", () => {
expect(action.coordinates).toBeUndefined();
});

/**
* Asserts {@link KeyAction.toJSON} includes properties.
*/
it("JSON has properties", () => {
// Array.
const action = new KeyAction({
action: "action1",
context: "com.test.action.one",
device: "dev1",
event: "willAppear",
payload: {
controller: "Keypad",
settings: {},
isInMultiAction: false,
coordinates: {
column: 1,
row: 2,
},
},
});

// Act.
const jsonStr = JSON.stringify(action);
const jsonObj: KeyAction = JSON.parse(jsonStr);

// Assert.
expect(jsonObj.controllerType).toBe(action.controllerType);
expect(jsonObj.coordinates).toStrictEqual(action.coordinates);
expect(jsonObj.device).toStrictEqual({ id: action.device.id });
expect(jsonObj.id).toBe(action.id);
expect(jsonObj.isInMultiAction).toBe(action.isInMultiAction());
expect(jsonObj.manifestId).toBe(action.manifestId);
});

describe("sending", () => {
let action!: KeyAction;
beforeAll(() => (action = new KeyAction(source)));
Expand Down
13 changes: 13 additions & 0 deletions src/plugin/actions/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,17 @@ export class ActionContext {
public get manifestId(): string {
return this.#source.action;
}

/**
* Converts this instance to a serializable object.
* @returns The serializable object.
*/
public toJSON(): object {
return {
controllerType: this.controllerType,
device: this.device,
id: this.id,
manifestId: this.manifestId,
};
}
}
10 changes: 10 additions & 0 deletions src/plugin/actions/dial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ export class DialAction<T extends JsonObject = JsonObject> extends Action<T> {
payload: descriptions || {},
});
}

/**
* @inheritdoc
*/
public override toJSON(): object {
return {
...super.toJSON(),
coordinates: this.coordinates,
};
}
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/plugin/actions/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ export class KeyAction<T extends JsonObject = JsonObject> extends Action<T> {
context: this.id,
});
}

/**
* @inheritdoc
*/
public override toJSON(): object {
return {
...super.toJSON(),
coordinates: this.coordinates,
isInMultiAction: this.isInMultiAction(),
};
}
}

/**
Expand Down

0 comments on commit 7d0cd10

Please sign in to comment.