SceneObject: Prevent state mutation by using Object.freeze (#58936)

This commit is contained in:
Torkel Ödegaard
2022-11-18 10:35:27 +01:00
committed by GitHub
parent b77c3946a5
commit 38b980bd81
2 changed files with 20 additions and 4 deletions
@@ -76,6 +76,20 @@ describe('SceneObject', () => {
expect(clone.state.name).toBe('new name');
});
it('Cannot modify state', () => {
const scene = new TestScene({ name: 'name' });
expect(() => {
scene.state.name = 'new name';
}).toThrow();
scene.setState({ name: 'new name' });
expect(scene.state.name).toBe('new name');
expect(() => {
scene.state.name = 'other name';
}).toThrow();
});
describe('When activated', () => {
const scene = new TestScene({
$data: new SceneDataNode({}),
@@ -32,7 +32,7 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = SceneObj
state.key = uuidv4();
}
this._state = state;
this._state = Object.freeze(state);
this._subject.next(state);
this.setParent();
}
@@ -92,19 +92,21 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = SceneObj
public setState(update: Partial<TState>) {
const prevState = this._state;
this._state = {
const newState: TState = {
...this._state,
...update,
};
this._state = Object.freeze(newState);
this.setParent();
this._subject.next(this._state);
this._subject.next(newState);
// Bubble state change event. This is event is subscribed to by UrlSyncManager and UndoManager
this.publishEvent(
new SceneObjectStateChangedEvent({
prevState,
newState: this._state,
newState,
partialUpdate: update,
changedObject: this,
}),