4
4
import "@testing-library/jest-dom" ;
5
5
import { render , createEvent , fireEvent } from "@testing-library/react" ;
6
6
import App from "./App" ;
7
+ import { SAMPLE_LOG_DATA_1 , SAMPLE_LOG_DATA_2 } from "./test-data" ;
7
8
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" ;
16
10
11
+ describe ( "App" , ( ) => {
17
12
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 ( ) ;
43
15
} ) ;
44
16
45
17
it ( "renders the log visualizer when text is pasted" , async ( ) => {
46
- render ( < App /> ) ;
18
+ const { container , rerender } = render ( < App /> ) ;
47
19
48
20
const inputEl = document . getElementById ( "input-text" ) ;
49
21
if ( ! inputEl ) {
50
- fail ( ) ;
22
+ throw new Error ( DOM_EL_FAIL ) ;
51
23
}
52
24
53
25
fireEvent (
@@ -60,90 +32,60 @@ describe("App", () => {
60
32
} ) ,
61
33
) ;
62
34
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 ( ) ;
76
37
38
+ expect ( document . getElementById ( "c-source-container" ) ) . toBeTruthy ( ) ;
77
39
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 ( ) ;
97
41
98
42
// Hit the clear button and make sure we go back to the intial state
99
43
const clearEl = document . getElementById ( "clear" ) ;
100
44
if ( ! clearEl ) {
101
- fail ( ) ;
45
+ throw new Error ( DOM_EL_FAIL ) ;
102
46
}
103
47
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 ( ) ;
108
55
} ) ;
109
56
110
57
it ( "jumps to the next/prev instruction on key up/down" , async ( ) => {
111
58
render ( < App /> ) ;
112
59
113
60
const inputEl = document . getElementById ( "input-text" ) ;
114
61
if ( ! inputEl ) {
115
- fail ( ) ;
62
+ throw new Error ( DOM_EL_FAIL ) ;
116
63
}
117
64
118
65
fireEvent (
119
66
inputEl ,
120
67
createEvent . paste ( inputEl , {
121
68
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 ,
133
70
} ,
134
71
} ) ,
135
72
) ;
136
73
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
+
137
81
const logContainerEl = document . getElementById ( "log-container" ) ;
138
- expect ( logContainerEl ) . toBeTruthy ( ) ;
139
- expect ( logContainerEl ) . toBeVisible ( ) ;
140
82
141
83
const line5 = document . getElementById ( "line-5" ) ;
142
84
const line6 = document . getElementById ( "line-6" ) ;
143
85
const line7 = document . getElementById ( "line-7" ) ;
144
86
145
- if ( ! line5 || ! line6 || ! line7 || ! logContainerEl ) {
146
- fail ( ) ;
87
+ if ( ! line5 || ! line7 || ! line6 || ! logContainerEl ) {
88
+ throw new Error ( DOM_EL_FAIL ) ;
147
89
}
148
90
149
91
expect ( line5 . innerHTML ) . toBe (
@@ -174,4 +116,110 @@ describe("App", () => {
174
116
expect ( line6 . classList . contains ( "selected-line" ) ) . toBeFalsy ( ) ;
175
117
expect ( line7 . classList . contains ( "selected-line" ) ) . toBeFalsy ( ) ;
176
118
} ) ;
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
+ } ) ;
177
225
} ) ;
0 commit comments