44import "@testing-library/jest-dom" ;
55import { render , createEvent , fireEvent } from "@testing-library/react" ;
66import App from "./App" ;
7+ import { SAMPLE_LOG_DATA_1 , SAMPLE_LOG_DATA_2 } from "./test-data" ;
78
8- describe ( "App" , ( ) => {
9- it ( "does not throw" , ( ) => {
10- render ( < App /> ) ;
11-
12- const inputEl = document . getElementById ( "input-text" ) ;
13- expect ( inputEl ) . toBeTruthy ( ) ;
14- expect ( inputEl ) . toBeVisible ( ) ;
15- } ) ;
9+ const DOM_EL_FAIL = "DOM Element missing" ;
1610
11+ describe ( "App" , ( ) => {
1712 it ( "renders the correct starting elements" , ( ) => {
18- render ( < App /> ) ;
19-
20- const exampleLinkEl = document . getElementById ( "example-link" ) ;
21- expect ( exampleLinkEl ?. innerHTML ) . toBe ( "Load an example log" ) ;
22-
23- const inputEl = document . getElementById ( "input-text" ) ;
24- expect ( inputEl ?. getAttribute ( "placeholder" ) ) . toBe (
25- "Paste a verifier log here or choose a file" ,
26- ) ;
27- expect ( inputEl ?. tagName ) . toBe ( "TEXTAREA" ) ;
28-
29- const fileInputEl = document . getElementById ( "file-input" ) ;
30- expect ( fileInputEl ?. tagName ) . toBe ( "INPUT" ) ;
31-
32- const gotoLineEl = document . getElementById ( "goto-line-input" ) ;
33- expect ( gotoLineEl ?. tagName ) . toBe ( "INPUT" ) ;
34-
35- const gotoStartEl = document . getElementById ( "goto-start" ) ;
36- expect ( gotoStartEl ?. tagName ) . toBe ( "BUTTON" ) ;
37-
38- const gotoEndEl = document . getElementById ( "goto-end" ) ;
39- expect ( gotoEndEl ?. tagName ) . toBe ( "BUTTON" ) ;
40-
41- const clearEl = document . getElementById ( "clear" ) ;
42- expect ( clearEl ?. tagName ) . toBe ( "BUTTON" ) ;
13+ const { container } = render ( < App /> ) ;
14+ expect ( container ) . toMatchSnapshot ( ) ;
4315 } ) ;
4416
4517 it ( "renders the log visualizer when text is pasted" , async ( ) => {
46- render ( < App /> ) ;
18+ const { container , rerender } = render ( < App /> ) ;
4719
4820 const inputEl = document . getElementById ( "input-text" ) ;
4921 if ( ! inputEl ) {
50- fail ( ) ;
22+ throw new Error ( DOM_EL_FAIL ) ;
5123 }
5224
5325 fireEvent (
@@ -60,90 +32,60 @@ describe("App", () => {
6032 } ) ,
6133 ) ;
6234
63- const logContainerEl = document . getElementById ( "log-container" ) ;
64- expect ( logContainerEl ) . toBeTruthy ( ) ;
65- expect ( logContainerEl ) . toBeVisible ( ) ;
66-
67- const logLinesEl = document . getElementById ( "line-numbers-idx" ) ;
68- expect ( logLinesEl ?. innerHTML ) . toBe (
69- '<div class="line-numbers-line">1</div>' ,
70- ) ;
71-
72- const logLinesPcEl = document . getElementById ( "line-numbers-pc" ) ;
73- expect ( logLinesPcEl ?. innerHTML ) . toBe (
74- '<div class="line-numbers-line">314:</div>' ,
75- ) ;
35+ rerender ( < App /> ) ;
36+ expect ( container ) . toMatchSnapshot ( ) ;
7637
38+ expect ( document . getElementById ( "c-source-container" ) ) . toBeTruthy ( ) ;
7739 expect ( document . getElementById ( "formatted-log-lines" ) ) . toBeTruthy ( ) ;
78-
79- const firstLine = document . getElementById ( "line-0" ) ;
80- expect ( firstLine ?. innerHTML ) . toBe (
81- '*(u8 *)(<span id="mem-slot-r7-line-0" class="mem-slot r7" data-id="r7">r7</span> +1303) = <span id="mem-slot-r1-line-0" class="mem-slot r1" data-id="r1">r1</span>' ,
82- ) ;
83-
84- const hintSelectedLineEl = document . getElementById ( "hint-selected-line" ) ;
85- expect ( hintSelectedLineEl ?. innerHTML ) . toBe (
86- "<span>[selected raw line] 1:</span> 314: (73) *(u8 *)(r7 +1303) = r1 ; frame1: R1_w=0 R7=map_value(off=0,ks=4,vs=2808,imm=0)" ,
87- ) ;
88-
89- expect ( document . getElementById ( "state-panel-shown" ) ) . toBeTruthy ( ) ;
90-
91- const statePanelHeader = document . getElementById ( "state-panel-header" ) ;
92- expect ( statePanelHeader ?. innerHTML ) . toBe (
93- "<div>Line: 1</div><div>PC: 314</div><div>Frame: 0</div>" ,
94- ) ;
95-
96- //TODO: add tests for state panel content
40+ expect ( document . getElementById ( "state-panel" ) ) . toBeTruthy ( ) ;
9741
9842 // Hit the clear button and make sure we go back to the intial state
9943 const clearEl = document . getElementById ( "clear" ) ;
10044 if ( ! clearEl ) {
101- fail ( ) ;
45+ throw new Error ( DOM_EL_FAIL ) ;
10246 }
10347 fireEvent ( clearEl , createEvent . click ( clearEl ) ) ;
104- expect ( document . getElementById ( "log-container" ) ) . toBeFalsy ( ) ;
105- expect ( document . getElementById ( "state-panel-shown" ) ) . toBeFalsy ( ) ;
106- expect ( document . getElementById ( "input-text" ) ) . toBeTruthy ( ) ;
107- expect ( document . getElementById ( "input-text" ) ) . toBeVisible ( ) ;
48+
49+ rerender ( < App /> ) ;
50+ expect ( container ) . toMatchSnapshot ( ) ;
51+
52+ expect ( document . getElementById ( "c-source-container" ) ) . toBeFalsy ( ) ;
53+ expect ( document . getElementById ( "formatted-log-lines" ) ) . toBeFalsy ( ) ;
54+ expect ( document . getElementById ( "state-panel" ) ) . toBeFalsy ( ) ;
10855 } ) ;
10956
11057 it ( "jumps to the next/prev instruction on key up/down" , async ( ) => {
11158 render ( < App /> ) ;
11259
11360 const inputEl = document . getElementById ( "input-text" ) ;
11461 if ( ! inputEl ) {
115- fail ( ) ;
62+ throw new Error ( DOM_EL_FAIL ) ;
11663 }
11764
11865 fireEvent (
11966 inputEl ,
12067 createEvent . paste ( inputEl , {
12168 clipboardData : {
122- getData : ( ) =>
123- `
124- 0: (18) r1 = 0x11 ; R1_w=17
125- 2: (b7) r2 = 0 ; R2_w=0
126- 3: (85) call bpf_obj_new_impl#54651 ; R0_w=ptr_or_null_node_data(id=2,ref_obj_id=2) refs=2
127- 4: (bf) r6 = r0 ; R0_w=ptr_or_null_node_data(id=2,ref_obj_id=2) R6_w=ptr_or_null_node_data(id=2,ref_obj_id=2) refs=2
128- 5: (b7) r7 = 1 ; R7_w=1 refs=2
129- ; if (!n) @ rbtree.c:199
130- 6: (15) if r6 == 0x0 goto pc+104 ; R6_w=ptr_node_data(ref_obj_id=2) refs=2
131- 7: (b7) r1 = 4 ; R1_w=4 ref
132- ` ,
69+ getData : ( ) => SAMPLE_LOG_DATA_1 ,
13370 } ,
13471 } ) ,
13572 ) ;
13673
74+ // Need to show all log lines
75+ const checkboxEl = document . getElementById ( "show-full-log" ) ;
76+ if ( ! checkboxEl ) {
77+ throw new Error ( DOM_EL_FAIL ) ;
78+ }
79+ fireEvent ( checkboxEl , createEvent . click ( checkboxEl ) ) ;
80+
13781 const logContainerEl = document . getElementById ( "log-container" ) ;
138- expect ( logContainerEl ) . toBeTruthy ( ) ;
139- expect ( logContainerEl ) . toBeVisible ( ) ;
14082
14183 const line5 = document . getElementById ( "line-5" ) ;
14284 const line6 = document . getElementById ( "line-6" ) ;
14385 const line7 = document . getElementById ( "line-7" ) ;
14486
145- if ( ! line5 || ! line6 || ! line7 || ! logContainerEl ) {
146- fail ( ) ;
87+ if ( ! line5 || ! line7 || ! line6 || ! logContainerEl ) {
88+ throw new Error ( DOM_EL_FAIL ) ;
14789 }
14890
14991 expect ( line5 . innerHTML ) . toBe (
@@ -174,4 +116,110 @@ describe("App", () => {
174116 expect ( line6 . classList . contains ( "selected-line" ) ) . toBeFalsy ( ) ;
175117 expect ( line7 . classList . contains ( "selected-line" ) ) . toBeFalsy ( ) ;
176118 } ) ;
119+
120+ it ( "c lines and state panel containers are collapsible" , async ( ) => {
121+ render ( < App /> ) ;
122+
123+ const inputEl = document . getElementById ( "input-text" ) ;
124+ if ( ! inputEl ) {
125+ throw new Error ( "Input text is missing" ) ;
126+ }
127+
128+ fireEvent (
129+ inputEl ,
130+ createEvent . paste ( inputEl , {
131+ clipboardData : {
132+ getData : ( ) => SAMPLE_LOG_DATA_1 ,
133+ } ,
134+ } ) ,
135+ ) ;
136+
137+ const cSourceEl = document . getElementById ( "c-source-container" ) ;
138+ const cSourceFile = cSourceEl ?. querySelector ( ".c-source-file" ) ;
139+
140+ expect ( cSourceFile ) . toBeVisible ( ) ;
141+
142+ const cSourceHideShow = cSourceEl ?. querySelector ( ".hide-show-button" ) ;
143+
144+ if ( ! cSourceHideShow ) {
145+ throw new Error ( DOM_EL_FAIL ) ;
146+ }
147+
148+ fireEvent ( cSourceHideShow , createEvent . click ( cSourceHideShow ) ) ;
149+ expect ( cSourceFile ) . not . toBeVisible ( ) ;
150+
151+ const statePanelEl = document . getElementById ( "state-panel" ) ;
152+ const statePanelHeader = document . getElementById ( "state-panel-header" ) ;
153+
154+ expect ( statePanelHeader ) . toBeVisible ( ) ;
155+
156+ const statePanelHideShow = statePanelEl ?. querySelector ( ".hide-show-button" ) ;
157+
158+ if ( ! statePanelHideShow ) {
159+ throw new Error ( DOM_EL_FAIL ) ;
160+ }
161+
162+ fireEvent ( statePanelHideShow , createEvent . click ( statePanelHideShow ) ) ;
163+ expect ( statePanelHeader ) . not . toBeVisible ( ) ;
164+ } ) ;
165+
166+ it ( "highlights the associated c source or log line(s) when the other is clicked " , async ( ) => {
167+ render ( < App /> ) ;
168+
169+ const inputEl = document . getElementById ( "input-text" ) ;
170+ if ( ! inputEl ) {
171+ throw new Error ( DOM_EL_FAIL ) ;
172+ }
173+
174+ fireEvent (
175+ inputEl ,
176+ createEvent . paste ( inputEl , {
177+ clipboardData : {
178+ getData : ( ) => SAMPLE_LOG_DATA_2 ,
179+ } ,
180+ } ) ,
181+ ) ;
182+
183+ const line4El = document . getElementById ( "line-4" ) ;
184+ const cLineEl = document . getElementById ( "line-rbtree.c:198" ) ;
185+ if ( ! line4El || ! cLineEl ) {
186+ throw new Error ( DOM_EL_FAIL ) ;
187+ }
188+
189+ expect ( line4El . classList ) . not . toContain ( "selected-line" ) ;
190+ expect ( cLineEl . classList ) . not . toContain ( "selected-line" ) ;
191+
192+ // Click on the first instruction log line
193+ fireEvent ( line4El , createEvent . click ( line4El ) ) ;
194+
195+ expect ( line4El . classList ) . toContain ( "selected-line" ) ;
196+ expect ( cLineEl . classList ) . toContain ( "selected-line" ) ;
197+
198+ // Click on another log line
199+ const line10El = document . getElementById ( "line-10" ) ;
200+ if ( ! line10El ) {
201+ throw new Error ( DOM_EL_FAIL ) ;
202+ }
203+
204+ fireEvent ( line10El , createEvent . click ( line10El ) ) ;
205+
206+ expect ( line4El . classList ) . not . toContain ( "selected-line" ) ;
207+ expect ( cLineEl . classList ) . not . toContain ( "selected-line" ) ;
208+
209+ // Click on the first c source line
210+ fireEvent ( cLineEl , createEvent . click ( cLineEl ) ) ;
211+
212+ expect ( line4El . classList ) . toContain ( "selected-line" ) ;
213+ expect ( cLineEl . classList ) . toContain ( "selected-line" ) ;
214+
215+ // The other instructions for this source line should also be selected
216+ const followingIns = [ "line-5" , "line-6" , "line-7" , "line-8" ] ;
217+ followingIns . forEach ( ( lineId ) => {
218+ const el = document . getElementById ( lineId ) ;
219+ if ( ! el ) {
220+ throw new Error ( DOM_EL_FAIL ) ;
221+ }
222+ expect ( el . classList ) . toContain ( "selected-line" ) ;
223+ } ) ;
224+ } ) ;
177225} ) ;
0 commit comments