@@ -48,6 +48,118 @@ describe('DevTools - AtomViewer', () => {
4848 expect ( container ) . toMatchSnapshot ( ) ;
4949 } ) ;
5050
51+ describe ( 'private atoms' , ( ) => {
52+ const PrivateAtomsWithDevTools = ( {
53+ markAtomPrivate = true ,
54+ shouldShowPrivateAtoms = false ,
55+ } : {
56+ markAtomPrivate ?: boolean ;
57+ shouldShowPrivateAtoms ?: boolean ;
58+ } ) => {
59+ // Create atoms inside the component so that they are recreated for each test
60+ const countAtom = useMemo ( ( ) => atom ( 0 ) , [ ] ) ;
61+ countAtom . debugLabel = 'countAtom' ;
62+
63+ const privateAtom = useMemo (
64+ ( ) => atom ( ( get ) => get ( countAtom ) * 0 ) ,
65+ [ countAtom ] ,
66+ ) ;
67+ privateAtom . debugLabel = 'privateAtom' ;
68+ privateAtom . debugPrivate = markAtomPrivate ;
69+
70+ const doubleAtom = useMemo (
71+ ( ) => atom ( ( get ) => get ( countAtom ) * get ( privateAtom ) ) ,
72+ [ countAtom , privateAtom ] ,
73+ ) ;
74+
75+ useAtomValue ( countAtom ) ;
76+ useAtomValue ( doubleAtom ) ;
77+ useAtomValue ( privateAtom ) ;
78+
79+ return (
80+ < DevTools
81+ isInitialOpen = { true }
82+ options = { {
83+ shouldShowPrivateAtoms : shouldShowPrivateAtoms ,
84+ } }
85+ />
86+ ) ;
87+ } ;
88+
89+ it ( 'should not render private atoms' , async ( ) => {
90+ customRender ( < PrivateAtomsWithDevTools /> ) ;
91+ expect ( screen . queryByText ( 'privateAtom' ) ) . not . toBeInTheDocument ( ) ;
92+ expect ( screen . getByText ( 'countAtom' ) ) . toBeInTheDocument ( ) ;
93+ expect ( screen . getByText ( '<unlabeled-atom>' ) ) . toBeInTheDocument ( ) ;
94+ } ) ;
95+
96+ it ( 'should render private atoms when shouldShowPrivateAtoms is marked as true' , async ( ) => {
97+ customRender ( < PrivateAtomsWithDevTools shouldShowPrivateAtoms /> ) ;
98+ expect ( screen . getByText ( 'privateAtom' ) ) . toBeInTheDocument ( ) ;
99+ } ) ;
100+
101+ it ( 'should hide private atoms from dependents list when shouldShowPrivateAtoms is marked as false' , async ( ) => {
102+ const { container } = customRender ( < PrivateAtomsWithDevTools /> ) ;
103+
104+ await act ( async ( ) => {
105+ await userEvent . click ( screen . getByText ( 'countAtom' ) ) ;
106+ } ) ;
107+
108+ expect ( screen . getByText ( 'Atom Details' ) ) . toBeInTheDocument ( ) ;
109+ expect ( screen . getByText ( 'Meta' ) ) . toBeInTheDocument ( ) ;
110+ expect ( screen . getByText ( 'Debug Label' ) ) . toBeInTheDocument ( ) ;
111+ expect (
112+ screen . getByTestId ( 'display-detail-item-value-countAtom' ) ,
113+ ) . toHaveTextContent ( 'countAtom' ) ;
114+ expect ( screen . getByText ( 'Value type' ) ) . toBeInTheDocument ( ) ;
115+ expect ( screen . getByText ( 'number' ) ) . toBeInTheDocument ( ) ;
116+ expect ( screen . queryByText ( 'Private' ) ) . not . toBeInTheDocument ( ) ;
117+ expect ( screen . queryByText ( 'Yes' ) ) . not . toBeInTheDocument ( ) ;
118+
119+ expect ( screen . getByText ( 'Raw value' ) ) . toBeInTheDocument ( ) ;
120+ expect ( screen . getByTestId ( 'atom-parsed-value' ) ) . toHaveTextContent ( '0' ) ;
121+
122+ expect ( screen . getByText ( 'Dependents' ) ) . toBeInTheDocument ( ) ;
123+ expect (
124+ screen . queryByTestId ( 'dependents-list-item-<unlabeled-atom>-0' ) ,
125+ ) . toBeInTheDocument ( ) ;
126+ expect (
127+ screen . queryByTestId ( 'dependents-list-item-privateAtom-0' ) ,
128+ ) . not . toBeInTheDocument ( ) ;
129+ expect ( container ) . toMatchSnapshot ( ) ;
130+ } ) ;
131+
132+ it ( 'should mark private atoms in atom details' , async ( ) => {
133+ const { container } = customRender (
134+ < PrivateAtomsWithDevTools shouldShowPrivateAtoms /> ,
135+ ) ;
136+
137+ await act ( async ( ) => {
138+ await userEvent . click ( screen . getByText ( 'privateAtom' ) ) ;
139+ } ) ;
140+
141+ expect ( screen . getByText ( 'Atom Details' ) ) . toBeInTheDocument ( ) ;
142+ expect ( screen . getByText ( 'Meta' ) ) . toBeInTheDocument ( ) ;
143+ expect ( screen . getByText ( 'Debug Label' ) ) . toBeInTheDocument ( ) ;
144+ expect (
145+ screen . getByTestId ( 'display-detail-item-value-privateAtom' ) ,
146+ ) . toHaveTextContent ( 'privateAtom' ) ;
147+ expect ( screen . getByText ( 'Value type' ) ) . toBeInTheDocument ( ) ;
148+ expect ( screen . getByText ( 'number' ) ) . toBeInTheDocument ( ) ;
149+ expect ( screen . getByText ( 'Private' ) ) . toBeInTheDocument ( ) ;
150+ expect ( screen . getByText ( 'Yes' ) ) . toBeInTheDocument ( ) ;
151+
152+ expect ( screen . getByText ( 'Raw value' ) ) . toBeInTheDocument ( ) ;
153+ expect ( screen . getByTestId ( 'atom-parsed-value' ) ) . toHaveTextContent ( '0' ) ;
154+
155+ expect ( screen . getByText ( 'Dependents' ) ) . toBeInTheDocument ( ) ;
156+ expect (
157+ screen . getByTestId ( 'dependents-list-item-<unlabeled-atom>-0' ) ,
158+ ) . toBeInTheDocument ( ) ;
159+ expect ( container ) . toMatchSnapshot ( ) ;
160+ } ) ;
161+ } ) ;
162+
51163 describe ( 'Search' , ( ) => {
52164 it ( 'should search for atoms correctly' , async ( ) => {
53165 const { container } = customRender ( < BasicAtomsWithDevTools /> ) ;
@@ -81,6 +193,45 @@ describe('DevTools - AtomViewer', () => {
81193
82194 describe ( 'Atom details' , ( ) => {
83195 describe ( 'Raw value' , ( ) => {
196+ it ( 'should display an error when we are not able to parse the value' , async ( ) => {
197+ class CircularClass {
198+ circular : any ;
199+ constructor ( ) {
200+ this . circular = this ;
201+ }
202+ }
203+
204+ const circularObject : InstanceType < typeof CircularClass > =
205+ new CircularClass ( ) ;
206+
207+ const CircularAtomWithDevTools = ( ) => {
208+ // Create atoms inside the component so that they are recreated for each test
209+ const circularAtom = useMemo ( ( ) => atom ( circularObject ) , [ ] ) ;
210+ circularAtom . debugLabel = 'circularAtom' ;
211+
212+ useAtomValue ( circularAtom ) ;
213+ return < DevTools isInitialOpen = { true } /> ;
214+ } ;
215+
216+ const { container } = customRender ( < CircularAtomWithDevTools /> ) ;
217+
218+ await act ( async ( ) => {
219+ await userEvent . click ( screen . getByText ( 'circularAtom' ) ) ;
220+ } ) ;
221+
222+ expect ( screen . getByText ( 'Atom Details' ) ) . toBeInTheDocument ( ) ;
223+ expect ( screen . getByText ( 'Meta' ) ) . toBeInTheDocument ( ) ;
224+ expect ( screen . getByText ( 'Debug Label' ) ) . toBeInTheDocument ( ) ;
225+
226+ expect ( screen . getByText ( 'Raw value' ) ) . toBeInTheDocument ( ) ;
227+ expect (
228+ screen . getByText ( 'Failed to parse the value of the atom' ) ,
229+ ) . toBeInTheDocument ( ) ;
230+ expect ( screen . getByText ( 'Dependents' ) ) . toBeInTheDocument ( ) ;
231+ expect ( screen . getByText ( 'No dependents' ) ) . toBeInTheDocument ( ) ;
232+ expect ( container ) . toMatchSnapshot ( ) ;
233+ } ) ;
234+
84235 it ( 'should display atom details when an atom is selected' , async ( ) => {
85236 const { container } = customRender ( < BasicAtomsWithDevTools /> ) ;
86237
0 commit comments