|
1 |
| -import { createFacet } from '@react-facet/core' |
| 1 | +import { createFacet, Facet } from '@react-facet/core' |
2 | 2 | import React, { ReactElement, useEffect, useState } from 'react'
|
| 3 | +import { Fiber } from 'react-reconciler' |
3 | 4 | import { createFiberRoot } from './createFiberRoot'
|
4 | 5 | import { createReconciler } from './createReconciler'
|
5 |
| -import { InputType } from './types' |
| 6 | +import { setupHostConfig } from './setupHostConfig' |
| 7 | +import { InputType, ElementContainer, ElementProps, Props } from './types' |
6 | 8 |
|
7 | 9 | document.body.innerHTML = `<div id="root"></div>`
|
8 | 10 |
|
@@ -898,3 +900,202 @@ describe('update', () => {
|
898 | 900 | })
|
899 | 901 | })
|
900 | 902 | })
|
| 903 | + |
| 904 | +describe('commitUpdate style prop', () => { |
| 905 | + it('subscribes when updating from null', () => { |
| 906 | + const hostConfig = setupHostConfig() |
| 907 | + const instance: ElementContainer = { |
| 908 | + element: document.createElement('div'), |
| 909 | + styleUnsubscribers: new Map(), |
| 910 | + } |
| 911 | + |
| 912 | + const oldProps: ElementProps<HTMLDivElement> = { |
| 913 | + style: { |
| 914 | + color: undefined, |
| 915 | + }, |
| 916 | + } |
| 917 | + |
| 918 | + const newColorFacet: Facet<string> = { |
| 919 | + get: () => 'blue', |
| 920 | + observe: jest.fn(), |
| 921 | + } |
| 922 | + |
| 923 | + const newProps: ElementProps<HTMLDivElement> = { |
| 924 | + style: { |
| 925 | + color: newColorFacet, |
| 926 | + }, |
| 927 | + } |
| 928 | + |
| 929 | + hostConfig.commitUpdate?.( |
| 930 | + instance, |
| 931 | + true, |
| 932 | + 'fast-div', |
| 933 | + oldProps as Props<HTMLDivElement>, |
| 934 | + newProps as Props<HTMLDivElement>, |
| 935 | + null as unknown as Fiber, |
| 936 | + ) |
| 937 | + |
| 938 | + // Adds a new subscription to the new Facet |
| 939 | + expect(newColorFacet.observe).toHaveBeenCalledTimes(1) |
| 940 | + }) |
| 941 | + |
| 942 | + it('unsubscribes when updating to null', () => { |
| 943 | + const colorUnsubscriber = jest.fn() |
| 944 | + |
| 945 | + const hostConfig = setupHostConfig() |
| 946 | + const instance: ElementContainer = { |
| 947 | + element: document.createElement('div'), |
| 948 | + styleUnsubscribers: new Map([['color', colorUnsubscriber]]), |
| 949 | + } |
| 950 | + |
| 951 | + const oldColorFacet: Facet<string> = { |
| 952 | + get: () => 'blue', |
| 953 | + observe: jest.fn(), |
| 954 | + } |
| 955 | + |
| 956 | + const oldProps: ElementProps<HTMLDivElement> = { |
| 957 | + style: { |
| 958 | + color: oldColorFacet, |
| 959 | + }, |
| 960 | + } |
| 961 | + |
| 962 | + const newProps: ElementProps<HTMLDivElement> = { |
| 963 | + style: { |
| 964 | + color: undefined, |
| 965 | + }, |
| 966 | + } |
| 967 | + |
| 968 | + hostConfig.commitUpdate?.( |
| 969 | + instance, |
| 970 | + true, |
| 971 | + 'fast-div', |
| 972 | + oldProps as Props<HTMLDivElement>, |
| 973 | + newProps as Props<HTMLDivElement>, |
| 974 | + null as unknown as Fiber, |
| 975 | + ) |
| 976 | + |
| 977 | + expect(colorUnsubscriber).toHaveBeenCalledTimes(1) |
| 978 | + }) |
| 979 | + |
| 980 | + it('unsubscribes from previous facet when changing to a primitive value', () => { |
| 981 | + const colorUnsubscriber = jest.fn() |
| 982 | + |
| 983 | + const hostConfig = setupHostConfig() |
| 984 | + const instance: ElementContainer = { |
| 985 | + element: document.createElement('div'), |
| 986 | + styleUnsubscribers: new Map([['color', colorUnsubscriber]]), |
| 987 | + } |
| 988 | + |
| 989 | + const oldProps: ElementProps<HTMLDivElement> = { |
| 990 | + style: { |
| 991 | + color: createFacet({ initialValue: 'blue' }), |
| 992 | + }, |
| 993 | + } |
| 994 | + |
| 995 | + const newProps: ElementProps<HTMLDivElement> = { |
| 996 | + style: { |
| 997 | + color: 'yellow', |
| 998 | + }, |
| 999 | + } |
| 1000 | + |
| 1001 | + hostConfig.commitUpdate?.( |
| 1002 | + instance, |
| 1003 | + true, |
| 1004 | + 'fast-div', |
| 1005 | + oldProps as Props<HTMLDivElement>, |
| 1006 | + newProps as Props<HTMLDivElement>, |
| 1007 | + null as unknown as Fiber, |
| 1008 | + ) |
| 1009 | + |
| 1010 | + expect(colorUnsubscriber).toHaveBeenCalledTimes(1) |
| 1011 | + }) |
| 1012 | + |
| 1013 | + it('unsubscribes from previous facet when changing to a new facet', () => { |
| 1014 | + const colorUnsubscriber = jest.fn() |
| 1015 | + |
| 1016 | + const hostConfig = setupHostConfig() |
| 1017 | + const instance: ElementContainer = { |
| 1018 | + element: document.createElement('div'), |
| 1019 | + styleUnsubscribers: new Map([['color', colorUnsubscriber]]), |
| 1020 | + } |
| 1021 | + |
| 1022 | + const oldColorFacet: Facet<string> = { |
| 1023 | + get: () => 'blue', |
| 1024 | + observe: jest.fn(), |
| 1025 | + } |
| 1026 | + |
| 1027 | + const oldProps: ElementProps<HTMLDivElement> = { |
| 1028 | + style: { |
| 1029 | + color: oldColorFacet, |
| 1030 | + }, |
| 1031 | + } |
| 1032 | + |
| 1033 | + const newColorFacet: Facet<string> = { |
| 1034 | + get: () => 'blue', |
| 1035 | + observe: jest.fn(), |
| 1036 | + } |
| 1037 | + |
| 1038 | + const newProps: ElementProps<HTMLDivElement> = { |
| 1039 | + style: { |
| 1040 | + color: newColorFacet, |
| 1041 | + }, |
| 1042 | + } |
| 1043 | + |
| 1044 | + hostConfig.commitUpdate?.( |
| 1045 | + instance, |
| 1046 | + true, |
| 1047 | + 'fast-div', |
| 1048 | + oldProps as Props<HTMLDivElement>, |
| 1049 | + newProps as Props<HTMLDivElement>, |
| 1050 | + null as unknown as Fiber, |
| 1051 | + ) |
| 1052 | + |
| 1053 | + // Unsubscribes from the old subscription, since it is a new Facet |
| 1054 | + expect(colorUnsubscriber).toHaveBeenCalledTimes(1) |
| 1055 | + |
| 1056 | + // Adds a new subscription to the new Facet |
| 1057 | + expect(newColorFacet.observe).toHaveBeenCalledTimes(1) |
| 1058 | + }) |
| 1059 | + |
| 1060 | + it('keeps the same subscription when updating with the same facet', () => { |
| 1061 | + const colorUnsubscriber = jest.fn() |
| 1062 | + |
| 1063 | + const hostConfig = setupHostConfig() |
| 1064 | + const instance: ElementContainer = { |
| 1065 | + element: document.createElement('div'), |
| 1066 | + styleUnsubscribers: new Map([['color', colorUnsubscriber]]), |
| 1067 | + } |
| 1068 | + |
| 1069 | + const colorFacet: Facet<string> = { |
| 1070 | + get: () => 'blue', |
| 1071 | + observe: jest.fn(), |
| 1072 | + } |
| 1073 | + |
| 1074 | + const oldProps: ElementProps<HTMLDivElement> = { |
| 1075 | + style: { |
| 1076 | + color: colorFacet, |
| 1077 | + }, |
| 1078 | + } |
| 1079 | + |
| 1080 | + const newProps: ElementProps<HTMLDivElement> = { |
| 1081 | + style: { |
| 1082 | + color: colorFacet, |
| 1083 | + }, |
| 1084 | + } |
| 1085 | + |
| 1086 | + hostConfig.commitUpdate?.( |
| 1087 | + instance, |
| 1088 | + true, |
| 1089 | + 'fast-div', |
| 1090 | + oldProps as Props<HTMLDivElement>, |
| 1091 | + newProps as Props<HTMLDivElement>, |
| 1092 | + null as unknown as Fiber, |
| 1093 | + ) |
| 1094 | + |
| 1095 | + // I shouldn't unsubscribe, since it is the same Facet |
| 1096 | + expect(colorUnsubscriber).not.toHaveBeenCalled() |
| 1097 | + |
| 1098 | + // So I must not also observe again, since I should stick with the previous subscription |
| 1099 | + expect(colorFacet.observe).toHaveBeenCalledTimes(0) |
| 1100 | + }) |
| 1101 | +}) |
0 commit comments