@@ -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+
30313299describe ( 'callback granularity' , ( ) => {
30323300 let calls : Record < string , number > ;
30333301
0 commit comments