Skip to content

Commit 5f0ef13

Browse files
committed
[middleware] DidSetRow tests
1 parent ff148d0 commit 5f0ef13

1 file changed

Lines changed: 268 additions & 0 deletions

File tree

‎test/unit/core/other/middleware.test.ts‎

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,6 +3028,274 @@ describe('fluent API', () => {
30283028
});
30293029
});
30303030

3031+
describe('didSetRow', () => {
3032+
test('fires after transaction with correct oldRow and newRow', () => {
3033+
store.setRow('pets', 'fido', {species: 'dog'});
3034+
const seen: {oldRow: object; newRow: object}[] = [];
3035+
middleware.addDidSetRowCallback(
3036+
'pets',
3037+
(_tableId, _rowId, oldRow, newRow) => {
3038+
seen.push({oldRow: {...oldRow}, newRow: {...newRow}});
3039+
return newRow;
3040+
},
3041+
);
3042+
store.setCell('pets', 'fido', 'name', 'Fido');
3043+
expect(seen).toEqual([
3044+
{oldRow: {species: 'dog'}, newRow: {species: 'dog', name: 'Fido'}},
3045+
]);
3046+
});
3047+
3048+
test('multiple cell changes in one transaction produce one callback', () => {
3049+
let callCount = 0;
3050+
let finalOld: object | undefined;
3051+
let finalNew: object | undefined;
3052+
middleware.addDidSetRowCallback(
3053+
'pets',
3054+
(_tableId, _rowId, oldRow, newRow) => {
3055+
callCount++;
3056+
finalOld = {...oldRow};
3057+
finalNew = {...newRow};
3058+
return newRow;
3059+
},
3060+
);
3061+
store.transaction(() => {
3062+
store.setCell('pets', 'fido', 'species', 'dog');
3063+
store.setCell('pets', 'fido', 'name', 'Fido');
3064+
store.setCell('pets', 'fido', 'legs', 4);
3065+
});
3066+
expect(callCount).toBe(1);
3067+
expect(finalOld).toEqual({});
3068+
expect(finalNew).toEqual({species: 'dog', name: 'Fido', legs: 4});
3069+
});
3070+
3071+
test('returning newRow leaves store unchanged', () => {
3072+
store.setRow('pets', 'fido', {species: 'dog'});
3073+
middleware.addDidSetRowCallback(
3074+
'pets',
3075+
(_tableId, _rowId, _oldRow, newRow) => newRow,
3076+
);
3077+
store.setCell('pets', 'fido', 'name', 'Fido');
3078+
expect(store.getRow('pets', 'fido')).toEqual({
3079+
species: 'dog',
3080+
name: 'Fido',
3081+
});
3082+
});
3083+
3084+
test('returning oldRow explicitly reverts the row', () => {
3085+
store.setRow('pets', 'fido', {species: 'dog'});
3086+
middleware.addDidSetRowCallback(
3087+
'pets',
3088+
(_tableId, _rowId, oldRow, _newRow) => oldRow,
3089+
);
3090+
store.setCell('pets', 'fido', 'name', 'Fido');
3091+
expect(store.getRow('pets', 'fido')).toEqual({species: 'dog'});
3092+
});
3093+
3094+
test('returning a different Row applies that Row', () => {
3095+
store.setRow('pets', 'fido', {species: 'dog'});
3096+
middleware.addDidSetRowCallback(
3097+
'pets',
3098+
(_tableId, _rowId, _oldRow, newRow) => ({
3099+
...newRow,
3100+
validated: true,
3101+
}),
3102+
);
3103+
store.setCell('pets', 'fido', 'name', 'Fido');
3104+
expect(store.getRow('pets', 'fido')).toEqual({
3105+
species: 'dog',
3106+
name: 'Fido',
3107+
validated: true,
3108+
});
3109+
});
3110+
3111+
test('only fires for the registered table, not others', () => {
3112+
let fired = false;
3113+
middleware.addDidSetRowCallback('pets', (_t, _r, _o, newRow) => {
3114+
fired = true;
3115+
return newRow;
3116+
});
3117+
store.setCell('species', 'dog', 'legs', 4);
3118+
expect(fired).toBe(false);
3119+
expect(store.getCell('species', 'dog', 'legs')).toBe(4);
3120+
store.setCell('pets', 'fido', 'name', 'Fido');
3121+
expect(fired).toBe(true);
3122+
});
3123+
3124+
test('not called when net cell change is zero', () => {
3125+
store.setRow('pets', 'fido', {species: 'dog'});
3126+
let callCount = 0;
3127+
middleware.addDidSetRowCallback(
3128+
'pets',
3129+
(_tableId, _rowId, _oldRow, newRow) => {
3130+
callCount++;
3131+
return newRow;
3132+
},
3133+
);
3134+
store.transaction(() => {
3135+
store.setCell('pets', 'fido', 'name', 'Fido');
3136+
store.delCell('pets', 'fido', 'name');
3137+
});
3138+
3139+
expect(callCount).toBe(0);
3140+
expect(store.getRow('pets', 'fido')).toEqual({species: 'dog'});
3141+
});
3142+
3143+
test('chaining: multiple callbacks run in order', () => {
3144+
const order: number[] = [];
3145+
middleware
3146+
.addDidSetRowCallback('pets', (_tableId, _rowId, _oldRow, newRow) => {
3147+
order.push(1);
3148+
return {...newRow, step1: true};
3149+
})
3150+
.addDidSetRowCallback('pets', (_tableId, _rowId, _oldRow, newRow) => {
3151+
order.push(2);
3152+
return {...newRow, step2: true};
3153+
});
3154+
store.setCell('pets', 'fido', 'species', 'dog');
3155+
expect(order).toEqual([1, 2]);
3156+
expect(store.getRow('pets', 'fido')).toEqual({
3157+
species: 'dog',
3158+
step1: true,
3159+
step2: true,
3160+
});
3161+
});
3162+
3163+
test('chaining: all callbacks always run, including after a revert', () => {
3164+
const order: number[] = [];
3165+
store.setRow('pets', 'fido', {species: 'dog'});
3166+
middleware
3167+
.addDidSetRowCallback('pets', (_tableId, _rowId, _oldRow, newRow) => {
3168+
order.push(1);
3169+
return newRow;
3170+
})
3171+
.addDidSetRowCallback('pets', (_tableId, _rowId, oldRow) => {
3172+
order.push(2);
3173+
return oldRow;
3174+
})
3175+
.addDidSetRowCallback('pets', (_tableId, _rowId, _oldRow, newRow) => {
3176+
order.push(3);
3177+
return {...newRow, step3: true};
3178+
});
3179+
store.setCell('pets', 'fido', 'name', 'Fido');
3180+
expect(order).toEqual([1, 2, 3]);
3181+
expect(store.getRow('pets', 'fido')).toEqual({species: 'dog', step3: true});
3182+
});
3183+
3184+
test('fires for rows touched by setCell', () => {
3185+
let fired = false;
3186+
middleware.addDidSetRowCallback(
3187+
'pets',
3188+
(_tableId, _rowId, _oldRow, newRow) => {
3189+
fired = true;
3190+
return newRow;
3191+
},
3192+
);
3193+
store.setCell('pets', 'fido', 'species', 'dog');
3194+
expect(fired).toBe(true);
3195+
});
3196+
3197+
test('fires for rows touched by setPartialRow', () => {
3198+
store.setRow('pets', 'fido', {species: 'dog'});
3199+
let fired = false;
3200+
middleware.addDidSetRowCallback(
3201+
'pets',
3202+
(_tableId, _rowId, _oldRow, newRow) => {
3203+
fired = true;
3204+
return newRow;
3205+
},
3206+
);
3207+
store.setPartialRow('pets', 'fido', {name: 'Fido'});
3208+
expect(fired).toBe(true);
3209+
});
3210+
3211+
test('fires for rows touched by applyChanges', () => {
3212+
let seen: object | undefined;
3213+
middleware.addDidSetRowCallback(
3214+
'pets',
3215+
(_tableId, _rowId, _oldRow, newRow) => {
3216+
seen = {...newRow};
3217+
return newRow;
3218+
},
3219+
);
3220+
store.applyChanges([{pets: {fido: {species: 'dog'}}}, {}, 1]);
3221+
expect(seen).toEqual({species: 'dog'});
3222+
});
3223+
3224+
test('fires for deleted row (newRow is empty)', () => {
3225+
store.setRow('pets', 'fido', {species: 'dog'});
3226+
const seen: object[] = [];
3227+
middleware.addDidSetRowCallback(
3228+
'pets',
3229+
(_tableId, _rowId, _oldRow, newRow) => {
3230+
seen.push({...newRow});
3231+
return newRow;
3232+
},
3233+
);
3234+
store.delRow('pets', 'fido');
3235+
expect(seen).toEqual([{}]);
3236+
});
3237+
3238+
test('reverting a deletion restores the row', () => {
3239+
store.setRow('pets', 'fido', {species: 'dog'});
3240+
middleware.addDidSetRowCallback(
3241+
'pets',
3242+
(_tableId, _rowId, oldRow, _newRow) => oldRow,
3243+
);
3244+
store.delRow('pets', 'fido');
3245+
expect(store.getRow('pets', 'fido')).toEqual({species: 'dog'});
3246+
});
3247+
3248+
test('mutating listener changes are visible to didSetRow', () => {
3249+
store.addRowListener(
3250+
'pets',
3251+
'fido',
3252+
(store) => {
3253+
store.setCell('pets', 'fido', 'validated', true);
3254+
},
3255+
true,
3256+
);
3257+
let seenNew: object | undefined;
3258+
middleware.addDidSetRowCallback(
3259+
'pets',
3260+
(_tableId, _rowId, _oldRow, newRow) => {
3261+
seenNew = {...newRow};
3262+
return newRow;
3263+
},
3264+
);
3265+
store.setCell('pets', 'fido', 'species', 'dog');
3266+
expect(seenNew).toEqual({species: 'dog', validated: true});
3267+
});
3268+
3269+
test('will* middleware does not re-run when didSetRow applies a Row', () => {
3270+
const willSetCellCalls: string[] = [];
3271+
middleware.addWillSetCellCallback((_tableId, _rowId, cellId, cell) => {
3272+
willSetCellCalls.push(cellId);
3273+
return cell;
3274+
});
3275+
middleware.addDidSetRowCallback(
3276+
'pets',
3277+
(_tableId, _rowId, _oldRow, newRow) => ({
3278+
...newRow,
3279+
fromDid: true,
3280+
}),
3281+
);
3282+
store.setCell('pets', 'fido', 'species', 'dog');
3283+
expect(willSetCellCalls.filter((c) => c === 'fromDid').length).toBe(0);
3284+
expect(store.getRow('pets', 'fido')).toEqual({
3285+
species: 'dog',
3286+
fromDid: true,
3287+
});
3288+
});
3289+
3290+
test('fluent chaining', () => {
3291+
const result = middleware.addDidSetRowCallback(
3292+
'pets',
3293+
(_t, _r, _o, newRow) => newRow,
3294+
);
3295+
expect(result).toBe(middleware);
3296+
});
3297+
});
3298+
30313299
describe('callback granularity', () => {
30323300
let calls: Record<string, number>;
30333301

0 commit comments

Comments
 (0)