@@ -14,7 +14,9 @@ import {
1414 watchEffect ,
1515 createVNode ,
1616 resolveDynamicComponent ,
17- renderSlot
17+ renderSlot ,
18+ onErrorCaptured ,
19+ onServerPrefetch
1820} from 'vue'
1921import { escapeHtml } from '@vue/shared'
2022import { renderToString } from '../src/renderToString'
@@ -859,5 +861,211 @@ function testRender(type: string, render: typeof renderToString) {
859861 )
860862 ) . toBe ( `<div>A</div><div>B</div>` )
861863 } )
864+
865+ test ( 'onServerPrefetch' , async ( ) => {
866+ const msg = Promise . resolve ( 'hello' )
867+ const app = createApp ( {
868+ setup ( ) {
869+ const message = ref ( '' )
870+ onServerPrefetch ( async ( ) => {
871+ message . value = await msg
872+ } )
873+ return {
874+ message
875+ }
876+ } ,
877+ render ( ) {
878+ return h ( 'div' , this . message )
879+ }
880+ } )
881+ const html = await render ( app )
882+ expect ( html ) . toBe ( `<div>hello</div>` )
883+ } )
884+
885+ test ( 'multiple onServerPrefetch' , async ( ) => {
886+ const msg = Promise . resolve ( 'hello' )
887+ const msg2 = Promise . resolve ( 'hi' )
888+ const msg3 = Promise . resolve ( 'bonjour' )
889+ const app = createApp ( {
890+ setup ( ) {
891+ const message = ref ( '' )
892+ const message2 = ref ( '' )
893+ const message3 = ref ( '' )
894+ onServerPrefetch ( async ( ) => {
895+ message . value = await msg
896+ } )
897+ onServerPrefetch ( async ( ) => {
898+ message2 . value = await msg2
899+ } )
900+ onServerPrefetch ( async ( ) => {
901+ message3 . value = await msg3
902+ } )
903+ return {
904+ message,
905+ message2,
906+ message3
907+ }
908+ } ,
909+ render ( ) {
910+ return h ( 'div' , `${ this . message } ${ this . message2 } ${ this . message3 } ` )
911+ }
912+ } )
913+ const html = await render ( app )
914+ expect ( html ) . toBe ( `<div>hello hi bonjour</div>` )
915+ } )
916+
917+ test ( 'onServerPrefetch are run in parallel' , async ( ) => {
918+ const first = jest . fn ( ( ) => Promise . resolve ( ) )
919+ const second = jest . fn ( ( ) => Promise . resolve ( ) )
920+ let checkOther = [ false , false ]
921+ let done = [ false , false ]
922+ const app = createApp ( {
923+ setup ( ) {
924+ onServerPrefetch ( async ( ) => {
925+ checkOther [ 0 ] = done [ 1 ]
926+ await first ( )
927+ done [ 0 ] = true
928+ } )
929+ onServerPrefetch ( async ( ) => {
930+ checkOther [ 1 ] = done [ 0 ]
931+ await second ( )
932+ done [ 1 ] = true
933+ } )
934+ } ,
935+ render ( ) {
936+ return h ( 'div' , '' )
937+ }
938+ } )
939+ await render ( app )
940+ expect ( first ) . toHaveBeenCalled ( )
941+ expect ( second ) . toHaveBeenCalled ( )
942+ expect ( checkOther ) . toEqual ( [ false , false ] )
943+ expect ( done ) . toEqual ( [ true , true ] )
944+ } )
945+
946+ test ( 'onServerPrefetch with serverPrefetch option' , async ( ) => {
947+ const msg = Promise . resolve ( 'hello' )
948+ const msg2 = Promise . resolve ( 'hi' )
949+ const app = createApp ( {
950+ data ( ) {
951+ return {
952+ message : ''
953+ }
954+ } ,
955+
956+ async serverPrefetch ( ) {
957+ this . message = await msg
958+ } ,
959+
960+ setup ( ) {
961+ const message2 = ref ( '' )
962+ onServerPrefetch ( async ( ) => {
963+ message2 . value = await msg2
964+ } )
965+ return {
966+ message2
967+ }
968+ } ,
969+ render ( ) {
970+ return h ( 'div' , `${ this . message } ${ this . message2 } ` )
971+ }
972+ } )
973+ const html = await render ( app )
974+ expect ( html ) . toBe ( `<div>hello hi</div>` )
975+ } )
976+
977+ test ( 'mixed in serverPrefetch' , async ( ) => {
978+ const msg = Promise . resolve ( 'hello' )
979+ const app = createApp ( {
980+ data ( ) {
981+ return {
982+ msg : ''
983+ }
984+ } ,
985+ mixins : [
986+ {
987+ async serverPrefetch ( ) {
988+ this . msg = await msg
989+ }
990+ }
991+ ] ,
992+ render ( ) {
993+ return h ( 'div' , this . msg )
994+ }
995+ } )
996+ const html = await render ( app )
997+ expect ( html ) . toBe ( `<div>hello</div>` )
998+ } )
999+
1000+ test ( 'many serverPrefetch' , async ( ) => {
1001+ const foo = Promise . resolve ( 'foo' )
1002+ const bar = Promise . resolve ( 'bar' )
1003+ const baz = Promise . resolve ( 'baz' )
1004+ const app = createApp ( {
1005+ data ( ) {
1006+ return {
1007+ foo : '' ,
1008+ bar : '' ,
1009+ baz : ''
1010+ }
1011+ } ,
1012+ mixins : [
1013+ {
1014+ async serverPrefetch ( ) {
1015+ this . foo = await foo
1016+ }
1017+ } ,
1018+ {
1019+ async serverPrefetch ( ) {
1020+ this . bar = await bar
1021+ }
1022+ }
1023+ ] ,
1024+ async serverPrefetch ( ) {
1025+ this . baz = await baz
1026+ } ,
1027+ render ( ) {
1028+ return h ( 'div' , `${ this . foo } ${ this . bar } ${ this . baz } ` )
1029+ }
1030+ } )
1031+ const html = await render ( app )
1032+ expect ( html ) . toBe ( `<div>foobarbaz</div>` )
1033+ } )
1034+
1035+ test ( 'onServerPrefetch throwing error' , async ( ) => {
1036+ let renderError : Error | null = null
1037+ let capturedError : Error | null = null
1038+
1039+ const Child = {
1040+ setup ( ) {
1041+ onServerPrefetch ( async ( ) => {
1042+ throw new Error ( 'An error' )
1043+ } )
1044+ } ,
1045+ render ( ) {
1046+ return h ( 'span' )
1047+ }
1048+ }
1049+
1050+ const app = createApp ( {
1051+ setup ( ) {
1052+ onErrorCaptured ( e => {
1053+ capturedError = e
1054+ return false
1055+ } )
1056+ } ,
1057+ render ( ) {
1058+ return h ( 'div' , h ( Child ) )
1059+ }
1060+ } )
1061+
1062+ try {
1063+ await render ( app )
1064+ } catch ( e ) {
1065+ renderError = e
1066+ }
1067+ expect ( renderError ) . toBe ( null )
1068+ expect ( ( ( capturedError as unknown ) as Error ) . message ) . toBe ( 'An error' )
1069+ } )
8621070 } )
8631071}
0 commit comments