@@ -723,61 +723,17 @@ describe('suspense hydration', () => {
723
723
} ) ;
724
724
} ) ;
725
725
726
- // Currently not supported. Hydration doesn't set attributes... but should it
727
- // when coming back from suspense if props were updated?
728
- it . skip ( 'should hydrate and update attributes with latest props' , ( ) => {
729
- const originalHtml = '<p>Count: 0</p><p data-count="0">Lazy count: 0</p>' ;
730
- scratch . innerHTML = originalHtml ;
731
- clearLog ( ) ;
732
-
733
- /** @type {() => void } */
734
- let increment ;
735
- const [ Lazy , resolve ] = createLazy ( ) ;
736
- function App ( ) {
737
- const [ count , setCount ] = useState ( 0 ) ;
738
- increment = ( ) => setCount ( c => c + 1 ) ;
739
-
740
- return (
741
- < Suspense >
742
- < p > Count: { count } </ p >
743
- < Lazy count = { count } />
744
- </ Suspense >
745
- ) ;
746
- }
747
-
748
- hydrate ( < App /> , scratch ) ;
749
- rerender ( ) ; // Flush rerender queue to mimic what preact will really do
750
- expect ( scratch . innerHTML ) . to . equal ( originalHtml ) ;
751
- // Re: DOM OP below - Known issue with hydrating merged text nodes
752
- expect ( getLog ( ) ) . to . deep . equal ( [ '<p>Count: .appendChild(#text)' ] ) ;
753
- clearLog ( ) ;
754
-
755
- increment ( ) ;
756
- rerender ( ) ;
757
-
758
- expect ( scratch . innerHTML ) . to . equal (
759
- '<p>Count: 1</p><p data-count="0">Lazy count: 0</p>'
760
- ) ;
761
- expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
762
- clearLog ( ) ;
763
-
764
- return resolve ( ( { count } ) => (
765
- < p data-count = { count } > Lazy count: { count } </ p >
766
- ) ) . then ( ( ) => {
767
- rerender ( ) ;
768
- expect ( scratch . innerHTML ) . to . equal (
769
- '<p>Count: 1</p><p data-count="1">Lazy count: 1</p>'
770
- ) ;
771
- // Re: DOM OP below - Known issue with hydrating merged text nodes
772
- expect ( getLog ( ) ) . to . deep . equal ( [ '<p>Lazy count: .appendChild(#text)' ] ) ;
773
- clearLog ( ) ;
774
- } ) ;
775
- } ) ;
776
-
777
- // Currently not supported, but I wrote the test before I realized that so
778
- // leaving it here in case we do support it eventually
779
- it . skip ( 'should properly hydrate suspense when resolves to a Fragment' , ( ) => {
780
- const originalHtml = ul ( [ li ( 0 ) , li ( 1 ) , li ( 2 ) , li ( 3 ) , li ( 4 ) , li ( 5 ) ] ) ;
726
+ it ( 'should properly hydrate suspense when resolves to a Fragment' , ( ) => {
727
+ const originalHtml = ul ( [
728
+ li ( 0 ) ,
729
+ li ( 1 ) ,
730
+ '<!--$s-->' ,
731
+ li ( 2 ) ,
732
+ li ( 3 ) ,
733
+ '<!--/$s-->' ,
734
+ li ( 4 ) ,
735
+ li ( 5 )
736
+ ] ) ;
781
737
782
738
const listeners = [
783
739
sinon . spy ( ) ,
@@ -809,8 +765,8 @@ describe('suspense hydration', () => {
809
765
scratch
810
766
) ;
811
767
rerender ( ) ; // Flush rerender queue to mimic what preact will really do
812
- expect ( scratch . innerHTML ) . to . equal ( originalHtml ) ;
813
768
expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
769
+ expect ( scratch . innerHTML ) . to . equal ( originalHtml ) ;
814
770
expect ( listeners [ 5 ] ) . not . to . have . been . called ;
815
771
816
772
clearLog ( ) ;
@@ -839,4 +795,228 @@ describe('suspense hydration', () => {
839
795
expect ( listeners [ 5 ] ) . to . have . been . calledTwice ;
840
796
} ) ;
841
797
} ) ;
798
+
799
+ it ( 'should properly hydrate suspense when resolves to a Fragment without children' , ( ) => {
800
+ const originalHtml = ul ( [
801
+ li ( 0 ) ,
802
+ li ( 1 ) ,
803
+ '<!--$s-->' ,
804
+ '<!--/$s-->' ,
805
+ li ( 2 ) ,
806
+ li ( 3 )
807
+ ] ) ;
808
+
809
+ const listeners = [ sinon . spy ( ) , sinon . spy ( ) , sinon . spy ( ) , sinon . spy ( ) ] ;
810
+
811
+ scratch . innerHTML = originalHtml ;
812
+ clearLog ( ) ;
813
+
814
+ const [ Lazy , resolve ] = createLazy ( ) ;
815
+ hydrate (
816
+ < List >
817
+ < Fragment >
818
+ < ListItem onClick = { listeners [ 0 ] } > 0</ ListItem >
819
+ < ListItem onClick = { listeners [ 1 ] } > 1</ ListItem >
820
+ </ Fragment >
821
+ < Suspense >
822
+ < Lazy />
823
+ </ Suspense >
824
+ < Fragment >
825
+ < ListItem onClick = { listeners [ 2 ] } > 2</ ListItem >
826
+ < ListItem onClick = { listeners [ 3 ] } > 3</ ListItem >
827
+ </ Fragment >
828
+ </ List > ,
829
+ scratch
830
+ ) ;
831
+ rerender ( ) ; // Flush rerender queue to mimic what preact will really do
832
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
833
+ expect ( scratch . innerHTML ) . to . equal ( originalHtml ) ;
834
+ expect ( listeners [ 3 ] ) . not . to . have . been . called ;
835
+
836
+ clearLog ( ) ;
837
+ scratch . querySelector ( 'li:last-child' ) . dispatchEvent ( createEvent ( 'click' ) ) ;
838
+ expect ( listeners [ 3 ] ) . to . have . been . calledOnce ;
839
+
840
+ return resolve ( ( ) => null ) . then ( ( ) => {
841
+ rerender ( ) ;
842
+ expect ( scratch . innerHTML ) . to . equal ( originalHtml ) ;
843
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
844
+ clearLog ( ) ;
845
+
846
+ scratch
847
+ . querySelector ( 'li:nth-child(2)' )
848
+ . dispatchEvent ( createEvent ( 'click' ) ) ;
849
+ expect ( listeners [ 1 ] ) . to . have . been . calledOnce ;
850
+
851
+ scratch
852
+ . querySelector ( 'li:last-child' )
853
+ . dispatchEvent ( createEvent ( 'click' ) ) ;
854
+ expect ( listeners [ 3 ] ) . to . have . been . calledTwice ;
855
+ } ) ;
856
+ } ) ;
857
+
858
+ it ( 'Should hydrate a fragment with multiple children correctly' , ( ) => {
859
+ scratch . innerHTML = '<!--$s--><div>Hello</div><div>World!</div><!--/$s-->' ;
860
+ clearLog ( ) ;
861
+
862
+ const [ Lazy , resolve ] = createLazy ( ) ;
863
+ hydrate (
864
+ < Suspense >
865
+ < Lazy />
866
+ </ Suspense > ,
867
+ scratch
868
+ ) ;
869
+ rerender ( ) ; // Flush rerender queue to mimic what preact will really do
870
+ expect ( scratch . innerHTML ) . to . equal (
871
+ '<!--$s--><div>Hello</div><div>World!</div><!--/$s-->'
872
+ ) ;
873
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
874
+ clearLog ( ) ;
875
+
876
+ return resolve ( ( ) => (
877
+ < >
878
+ < div > Hello</ div >
879
+ < div > World!</ div >
880
+ </ >
881
+ ) ) . then ( ( ) => {
882
+ rerender ( ) ;
883
+ expect ( scratch . innerHTML ) . to . equal (
884
+ '<!--$s--><div>Hello</div><div>World!</div><!--/$s-->'
885
+ ) ;
886
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
887
+
888
+ clearLog ( ) ;
889
+ } ) ;
890
+ } ) ;
891
+
892
+ it ( 'Should hydrate a fragment with no children correctly' , ( ) => {
893
+ scratch . innerHTML = '<!--$s--><!--/$s--><div>Hello world</div>' ;
894
+ clearLog ( ) ;
895
+
896
+ const [ Lazy , resolve ] = createLazy ( ) ;
897
+ hydrate (
898
+ < >
899
+ < Suspense >
900
+ < Lazy />
901
+ </ Suspense >
902
+ < div > Hello world</ div >
903
+ </ > ,
904
+ scratch
905
+ ) ;
906
+ rerender ( ) ; // Flush rerender queue to mimic what preact will really do
907
+ expect ( scratch . innerHTML ) . to . equal (
908
+ '<!--$s--><!--/$s--><div>Hello world</div>'
909
+ ) ;
910
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
911
+ clearLog ( ) ;
912
+
913
+ return resolve ( ( ) => null ) . then ( ( ) => {
914
+ rerender ( ) ;
915
+ expect ( scratch . innerHTML ) . to . equal (
916
+ '<!--$s--><!--/$s--><div>Hello world</div>'
917
+ ) ;
918
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
919
+
920
+ clearLog ( ) ;
921
+ } ) ;
922
+ } ) ;
923
+
924
+ it ( 'Should hydrate a fragment with no children correctly deeply' , ( ) => {
925
+ scratch . innerHTML =
926
+ '<!--$s--><!--$s--><!--/$s--><!--/$s--><div>Hello world</div>' ;
927
+ clearLog ( ) ;
928
+
929
+ const [ Lazy , resolve ] = createLazy ( ) ;
930
+ const [ Lazy2 , resolve2 ] = createLazy ( ) ;
931
+ hydrate (
932
+ < >
933
+ < Suspense >
934
+ < Lazy >
935
+ < Suspense >
936
+ < Lazy2 />
937
+ </ Suspense >
938
+ </ Lazy >
939
+ </ Suspense >
940
+ < div > Hello world</ div >
941
+ </ > ,
942
+ scratch
943
+ ) ;
944
+ rerender ( ) ; // Flush rerender queue to mimic what preact will really do
945
+ expect ( scratch . innerHTML ) . to . equal (
946
+ '<!--$s--><!--$s--><!--/$s--><!--/$s--><div>Hello world</div>'
947
+ ) ;
948
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
949
+ clearLog ( ) ;
950
+
951
+ return resolve ( p => p . children ) . then ( ( ) => {
952
+ rerender ( ) ;
953
+ expect ( scratch . innerHTML ) . to . equal (
954
+ '<!--$s--><!--$s--><!--/$s--><!--/$s--><div>Hello world</div>'
955
+ ) ;
956
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
957
+
958
+ clearLog ( ) ;
959
+ return resolve2 ( ( ) => null ) . then ( ( ) => {
960
+ rerender ( ) ;
961
+ expect ( scratch . innerHTML ) . to . equal (
962
+ '<!--$s--><!--$s--><!--/$s--><!--/$s--><div>Hello world</div>'
963
+ ) ;
964
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
965
+
966
+ clearLog ( ) ;
967
+ } ) ;
968
+ } ) ;
969
+ } ) ;
970
+
971
+ it ( 'Should hydrate a fragment with multiple children correctly deeply' , ( ) => {
972
+ scratch . innerHTML =
973
+ '<!--$s--><!--$s--><p>I am</p><span>Fragment</span><!--/$s--><!--/$s--><div>Hello world</div>' ;
974
+ clearLog ( ) ;
975
+
976
+ const [ Lazy , resolve ] = createLazy ( ) ;
977
+ const [ Lazy2 , resolve2 ] = createLazy ( ) ;
978
+ hydrate (
979
+ < >
980
+ < Suspense >
981
+ < Lazy >
982
+ < Suspense >
983
+ < Lazy2 />
984
+ </ Suspense >
985
+ </ Lazy >
986
+ </ Suspense >
987
+ < div > Hello world</ div >
988
+ </ > ,
989
+ scratch
990
+ ) ;
991
+ rerender ( ) ; // Flush rerender queue to mimic what preact will really do
992
+ expect ( scratch . innerHTML ) . to . equal (
993
+ '<!--$s--><!--$s--><p>I am</p><span>Fragment</span><!--/$s--><!--/$s--><div>Hello world</div>'
994
+ ) ;
995
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
996
+ clearLog ( ) ;
997
+
998
+ return resolve ( p => p . children ) . then ( ( ) => {
999
+ rerender ( ) ;
1000
+ expect ( scratch . innerHTML ) . to . equal (
1001
+ '<!--$s--><!--$s--><p>I am</p><span>Fragment</span><!--/$s--><!--/$s--><div>Hello world</div>'
1002
+ ) ;
1003
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
1004
+
1005
+ clearLog ( ) ;
1006
+ return resolve2 ( ( ) => (
1007
+ < >
1008
+ < p > I am</ p >
1009
+ < span > Fragment</ span >
1010
+ </ >
1011
+ ) ) . then ( ( ) => {
1012
+ rerender ( ) ;
1013
+ expect ( scratch . innerHTML ) . to . equal (
1014
+ '<!--$s--><!--$s--><p>I am</p><span>Fragment</span><!--/$s--><!--/$s--><div>Hello world</div>'
1015
+ ) ;
1016
+ expect ( getLog ( ) ) . to . deep . equal ( [ ] ) ;
1017
+
1018
+ clearLog ( ) ;
1019
+ } ) ;
1020
+ } ) ;
1021
+ } ) ;
842
1022
} ) ;
0 commit comments