Skip to content

Commit

Permalink
test: should work with chained patch functions
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver committed Mar 13, 2024
1 parent 172c901 commit 9383dca
Showing 1 changed file with 72 additions and 23 deletions.
95 changes: 72 additions & 23 deletions src/signals/tests/immer-patch-state.jest.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { signalStore, withComputed, withState } from '@ngrx/signals';
import {
PartialStateUpdater,
signalStore,
withComputed,
withState,
} from '@ngrx/signals';
import { immerPatchState } from 'ngrx-immer/signals';
import { computed, effect } from '@angular/core';
import { TestBed } from '@angular/core/testing';

const UserState = signalStore(withState({
id: 1,
name: { firstname: 'Konrad', lastname: 'Schultz' },
address: { city: 'Vienna', zip: '1010' },
}), withComputed(({ name }) => ({ prettyName: computed(() => `${name.firstname()} ${name.lastname()}`) })));

const UserState = signalStore(
withState({
id: 1,
name: { firstname: 'Konrad', lastname: 'Schultz' },
address: { city: 'Vienna', zip: '1010' },
}),
withComputed(({ name }) => ({
prettyName: computed(() => `${name.firstname()} ${name.lastname()}`),
})),
);

describe('immerPatchState', () => {
const setup = () => {
return new UserState;
return new UserState();
};

it('should do a sanity check', () => {
Expand All @@ -27,20 +36,56 @@ describe('immerPatchState', () => {
immerPatchState(userState, { number: 1 });

//@ts-expect-error number is not a property
immerPatchState(userState, state => ({ number: 1 }));
immerPatchState(userState, (state) => ({ number: 1 }));
});

it('should allow patching with object literal', () => {
const userState = setup();
immerPatchState(userState, { name: { firstname: 'Lucy', lastname: 'Sanders' } });
immerPatchState(userState, {
name: { firstname: 'Lucy', lastname: 'Sanders' },
});
expect(userState.prettyName()).toBe('Lucy Sanders');
});

describe('update with return value', () => {
it('should work with the default patch function', () => {
const userState = setup();
immerPatchState(userState, ({ name }) => ({ name: { firstname: name.firstname, lastname: 'Sanders' } }));
immerPatchState(userState, ({ name }) => ({
name: { firstname: name.firstname, lastname: 'Sanders' },
}));
expect(userState.prettyName()).toBe('Konrad Sanders');
});

it('should work with chained patch functions', () => {
const userState = setup();

function updateNames<
T extends {
name: { firstname: string; lastname: string };
},
>(newState: T): PartialStateUpdater<T> {
return (state) => {
return {
...state,
...newState
};
};
}

immerPatchState(
userState,
updateNames({ name: { firstname: 'Konrad', lastname: 'Sanders' } }),
(state) => {
state.id = 2;
},
(state) => {
state.address = { city: 'Updated', zip: '1234' };
},
);

expect(userState.prettyName()).toBe('Konrad Sanders');
expect(userState.id()).toBe(2);
expect(userState.address()).toEqual({ city: 'Updated', zip: '1234' });
});

it('should not emit other signals', () => {
Expand All @@ -54,7 +99,9 @@ describe('immerPatchState', () => {
TestBed.flushEffects();

expect(effectCounter).toBe(1);
immerPatchState(userState, ({ name }) => ({ name: { firstname: name.firstname, lastname: 'Sanders' } }));
immerPatchState(userState, ({ name }) => ({
name: { firstname: name.firstname, lastname: 'Sanders' },
}));

TestBed.flushEffects();
expect(effectCounter).toBe(1);
Expand All @@ -68,16 +115,19 @@ describe('immerPatchState', () => {
immerPatchState(userState, (state) => {
state.name.lastname = 'Sanders';
return state;
})).toThrow('[Immer] An immer producer returned a new value *and* modified its draft.');
}),
).toThrow(
'[Immer] An immer producer returned a new value *and* modified its draft.',
);
});
});

describe('update without returning a value', () => {
it('should allow a mutable update', () => {
const userState = setup();
immerPatchState(userState, (state => {
immerPatchState(userState, (state) => {
state.name = { firstname: 'Lucy', lastname: 'Sanders' };
}));
});
expect(userState.prettyName()).toBe('Lucy Sanders');
});

Expand All @@ -92,9 +142,9 @@ describe('immerPatchState', () => {
TestBed.flushEffects();

expect(effectCounter).toBe(1);
immerPatchState(userState, (state => {
immerPatchState(userState, (state) => {
state.name = { firstname: 'Lucy', lastname: 'Sanders' };
}));
});

TestBed.flushEffects();
expect(effectCounter).toBe(1);
Expand All @@ -115,25 +165,24 @@ describe('immerPatchState', () => {
});
effect(() => {
userState.address();
addressEffectCounter++
addressEffectCounter++;
});
effect(() => {
userState.name();
nameEffectCounter++
nameEffectCounter++;
});


// first run
TestBed.flushEffects();
expect(idEffectCounter).toBe(1);
expect(addressEffectCounter).toBe(1);
expect(nameEffectCounter).toBe(1);

// change
immerPatchState(userState, (state => {
immerPatchState(userState, (state) => {
state.name = { firstname: 'Lucy', lastname: 'Sanders' };
state.address.zip = '1020'
}));
state.address.zip = '1020';
});

// second run
TestBed.flushEffects();
Expand Down

0 comments on commit 9383dca

Please sign in to comment.