@@ -21,6 +21,7 @@ import {
2121 immerable ,
2222} from 'immer' ;
2323import { create , apply , current } from '../src' ;
24+ import { deepClone } from '../src/utils' ;
2425
2526enableMapSet ( ) ;
2627
@@ -801,3 +802,110 @@ test('apply - symbol key on object', () => {
801802 }
802803} ) ;
803804
805+
806+ test ( '#70 - deep copy patches with Custom Set/Map' , ( ) => {
807+ {
808+ // immer
809+ class CustomSet < T > extends Set < T > {
810+ // @ts -ignore
811+ [ immerable ] = true ;
812+ }
813+ class CustomMap < K , V > extends Map < K , V > {
814+ // @ts -ignore
815+ [ immerable ] = true ;
816+ }
817+ const baseState = {
818+ map : new CustomMap < any , any > ( ) ,
819+ set : new CustomSet < any > ( ) ,
820+ } ;
821+ setUseStrictShallowCopy ( true ) ;
822+ const [ state , patches , inversePatches ] = produceWithPatches (
823+ baseState ,
824+ ( draft ) => {
825+ draft . map = new CustomMap < any , any > ( [ [ 1 , 1 ] ] ) ;
826+ draft . set = new CustomSet < any > ( [ 1 ] ) ;
827+ } ,
828+ ) ;
829+ const nextState = applyPatches ( baseState , patches ) ;
830+ expect ( patches [ 0 ] . value ) . toBeInstanceOf ( CustomMap ) ;
831+ expect ( patches [ 1 ] . value ) . toBeInstanceOf ( CustomSet ) ;
832+ // !!! it should be true, but it's false
833+ expect ( nextState . map instanceof CustomMap ) . toBe ( false ) ;
834+ expect ( nextState . set instanceof CustomSet ) . toBe ( false ) ;
835+ // expect(nextState).toEqual(state);
836+ // const prevState = applyPatches(state, inversePatches);
837+ // expect(inversePatches[0].value).toBeInstanceOf(CustomMap);
838+ // expect(inversePatches[1].value).toBeInstanceOf(CustomSet);
839+ // expect(prevState).toEqual(baseState);
840+ }
841+ {
842+ // mutative
843+ class CustomSet < T > extends Set < T > { }
844+ class CustomMap < K , V > extends Map < K , V > { }
845+ const baseState = {
846+ map : new CustomMap < any , any > ( ) ,
847+ set : new CustomSet < any > ( ) ,
848+ } ;
849+ const [ state , patches , inversePatches ] = create (
850+ baseState ,
851+ ( draft ) => {
852+ draft . map = new CustomMap < any , any > ( [ [ 1 , 1 ] ] ) ;
853+ draft . set = new CustomSet < any > ( [ 1 ] ) ;
854+ } ,
855+ {
856+ enablePatches : true ,
857+ }
858+ ) ;
859+ const nextState = apply ( baseState , patches ) ;
860+ expect ( patches [ 0 ] . value ) . toBeInstanceOf ( CustomMap ) ;
861+ expect ( patches [ 1 ] . value ) . toBeInstanceOf ( CustomSet ) ;
862+ expect ( nextState . map instanceof CustomMap ) . toBe ( true ) ;
863+ expect ( nextState . set instanceof CustomSet ) . toBe ( true ) ;
864+ expect ( nextState ) . toEqual ( state ) ;
865+ const prevState = apply ( state , inversePatches ) ;
866+ expect ( inversePatches [ 0 ] . value ) . toBeInstanceOf ( CustomMap ) ;
867+ expect ( inversePatches [ 1 ] . value ) . toBeInstanceOf ( CustomSet ) ;
868+ expect ( prevState ) . toEqual ( baseState ) ;
869+ }
870+ } ) ;
871+
872+ test ( 'enablePatches and assign with ref array' , ( ) => {
873+ function checkMutativePatches < T > ( data : T , fn : ( checkPatches : T ) => void ) {
874+ const [ state , patches , inversePatches ] = create ( data as any , fn , {
875+ enablePatches : true ,
876+ } ) as any ;
877+ const mutatedResult = deepClone ( data ) ;
878+ fn ( mutatedResult ) ;
879+ expect ( state ) . toEqual ( mutatedResult ) ;
880+ const prevState = apply ( state , inversePatches ) ;
881+ expect ( prevState ) . toEqual ( data ) ;
882+ const nextState = apply ( data as any , patches ) ;
883+ expect ( nextState ) . toEqual ( state ) ;
884+ }
885+
886+ function checkImmerPatches < T > ( data : T , fn : ( checkPatches : T ) => void ) {
887+ const [ state , patches , inversePatches ] = produceWithPatches ( data as any , fn ) as any ;
888+ const mutatedResult = deepClone ( data ) ;
889+ fn ( mutatedResult ) ;
890+ expect ( state ) . toEqual ( mutatedResult ) ;
891+ const prevState = applyPatches ( state , inversePatches ) ;
892+ // !!! immer: it should be equal
893+ expect ( prevState ) . not . toEqual ( data ) ;
894+ const nextState = applyPatches ( data as any , patches ) ;
895+ // !!! immer: it should be equal
896+ expect ( nextState ) . not . toEqual ( state ) ;
897+ }
898+ const state = { a : { b : { c : 1 } } , arr0 : [ { a : 1 } ] , arr1 : [ { a : 1 } ] } ;
899+ const fn = ( draft : any ) => {
900+ draft . arr0 . push ( draft . arr1 ) ;
901+ draft . arr1 [ 0 ] . a = 222 ;
902+ } ;
903+ checkImmerPatches (
904+ state ,
905+ fn
906+ ) ;
907+ checkMutativePatches (
908+ state ,
909+ fn
910+ ) ;
911+ } ) ;
0 commit comments