1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.annotation.Alerts;
19 import org.htmlunit.junit.annotation.HtmlUnitNYI;
20 import org.junit.jupiter.api.Test;
21 import org.openqa.selenium.WebDriverException;
22
23
24
25
26
27
28 public class FunctionsTest extends WebDriverTestCase {
29
30
31
32
33 @Test
34 @Alerts("function\\sfoo()\\s{\\s\\s\\s\\sreturn\\s\\t'a'\\s+\\s'b'\\s}")
35 public void function_toString() throws Exception {
36 final String html = DOCTYPE_HTML
37 + "<html><head>\n"
38 + "<script>\n"
39 + LOG_TITLE_FUNCTION_NORMALIZE
40 + "function test() {\n"
41 + " function foo() { return \t'a' + 'b' };\n"
42 + " log(foo.toString());\n"
43 + "}\n"
44 + "</script></head>\n"
45 + "<body onload='test()'>\n"
46 + "</body></html>";
47
48 loadPageVerifyTitle2(html);
49 }
50
51
52
53
54 @Test
55 @Alerts("function\\sfoo()\\s\\n{\\s\\n\\sreturn\\s\\t'x'\\s\\n\\n}")
56 public void function_toStringNewLines() throws Exception {
57 final String html = DOCTYPE_HTML
58 + "<html><head>\n"
59 + "<script>\n"
60 + LOG_TITLE_FUNCTION_NORMALIZE
61 + "function test() {\n"
62 + " function foo() \n{ \r\n return \t'x' \n\n};\n"
63 + " log(foo.toString());\n"
64 + "}\n"
65 + "</script></head>\n"
66 + "<body onload='test()'>\n"
67 + "</body></html>";
68
69 loadPageVerifyTitle2(html);
70 }
71
72
73
74
75 @Test
76 @Alerts("()\\s=>\\s{\\s\\nreturn\\s\\s'=>'\\s\\s\\s}")
77 public void arrowFunction_toString() throws Exception {
78 final String html = DOCTYPE_HTML
79 + "<html><head>\n"
80 + "<script>\n"
81 + LOG_TITLE_FUNCTION_NORMALIZE
82 + "function test() {\n"
83 + " var foo = () => { \nreturn '=>' };"
84 + " log(foo.toString());\n"
85 + "}\n"
86 + "</script></head>\n"
87 + "<body onload='test()'>\n"
88 + "</body></html>";
89
90 loadPageVerifyTitle2(html);
91 }
92
93
94
95
96 @Test
97 @Alerts({"function()\\s{\\n\\s\\s\\s\\s\\s\\sreturn\\s'X';\\n\\s\\s\\s\\s}",
98 "function()\\s{\\n\\s\\s\\s\\s\\s\\sreturn\\s'X';\\n\\s\\s\\s\\s}"})
99 public void boundFunction_toString() throws Exception {
100 final String html = DOCTYPE_HTML
101 + "<html><head>\n"
102 + "<script>\n"
103 + LOG_TITLE_FUNCTION_NORMALIZE
104 + "function test() {\n"
105 + " var oobj = {\n"
106 + " getX: function() {\n"
107 + " return 'X';\n"
108 + " }\n"
109 + " };\n"
110
111 + " log(oobj.getX.toString());\n"
112
113 + " var boundGetX = oobj.getX.bind(oobj);"
114 + " log(oobj.getX.toString());\n"
115 + "}\n"
116 + "</script></head>\n"
117 + "<body onload='test()'>\n"
118 + "</body></html>";
119
120 loadPageVerifyTitle2(html);
121 }
122
123
124
125
126 @Test
127 @Alerts({"foo = undefined", "1"})
128 @HtmlUnitNYI(CHROME = "org.htmlunit.ScriptException: ReferenceError: \"foo\" is not defined.",
129 EDGE = "org.htmlunit.ScriptException: ReferenceError: \"foo\" is not defined.",
130 FF = "org.htmlunit.ScriptException: ReferenceError: \"foo\" is not defined.",
131 FF_ESR = "org.htmlunit.ScriptException: ReferenceError: \"foo\" is not defined.")
132 public void conditionallyCreatedFunction() throws Exception {
133 final String html = DOCTYPE_HTML
134 + "<html><head></head>\n"
135 + "<body>\n"
136 + "<script>\n"
137 + LOG_TITLE_FUNCTION
138 + " log('foo = ' + foo);\n"
139 + " if (true) {\n"
140 + " log(foo());\n"
141 + " function foo() { return 1; }\n"
142 + " }\n"
143 + "</script>\n"
144 + "</body></html>";
145
146 try {
147 loadPageVerifyTitle2(html);
148 }
149 catch (final WebDriverException e) {
150 assertTrue(e.getMessage(), e.getMessage().startsWith(getExpectedAlerts()[0]));
151 }
152 }
153
154
155
156
157 @Test
158 @Alerts({"ReferenceError", "1"})
159 public void conditionallyCreatedFunctionStrict() throws Exception {
160 final String html = DOCTYPE_HTML
161 + "<html><head></head>\n"
162 + "<body>\n"
163 + "<script>\n"
164 + " 'use strict';\n"
165 + LOG_TITLE_FUNCTION
166 + " try {\n"
167 + " log('foo = ' + foo);\n"
168 + " } catch(e) { logEx(e); }\n"
169 + " if (true) {\n"
170 + " log(foo());\n"
171 + " function foo() { return 1; }\n"
172 + " }\n"
173 + "</script>\n"
174 + "</body></html>";
175
176 loadPageVerifyTitle2(html);
177 }
178
179
180
181
182 @Test
183 @Alerts("Hello!")
184 public void applyThisFromBoundArgs() throws Exception {
185 final String html = DOCTYPE_HTML
186 + "<html><head></head>\n"
187 + "<body>\n"
188 + "<script>\n"
189 + " 'use strict';\n"
190 + LOG_TITLE_FUNCTION
191 + " var f = function(x) { return this.toString(); };\n"
192 + " var a = f.apply;\n"
193 + " var b = a.bind(f, 'Hello!');\n"
194 + " log(b([1,2]));\n"
195 + "</script>\n"
196 + "</body></html>";
197
198 loadPageVerifyTitle2(html);
199 }
200
201
202
203
204 @Test
205 @Alerts("Hello!")
206 public void applyToApplyCallsCorrectFunction() throws Exception {
207 final String html = DOCTYPE_HTML
208 + "<html><head></head>\n"
209 + "<body>\n"
210 + "<script>\n"
211 + " 'use strict';\n"
212 + LOG_TITLE_FUNCTION
213 + " function foo(x) {return x;};\n"
214 + " var r = Function.prototype.apply.apply(foo, ['b', ['Hello!', 'Goodbye!']]);\n"
215 + " log(r);\n"
216 + "</script>\n"
217 + "</body></html>";
218
219 loadPageVerifyTitle2(html);
220 }
221
222
223
224
225 @Test
226 @Alerts("b")
227 public void applyToApplySetsCorrectFunctionThis() throws Exception {
228 final String html = DOCTYPE_HTML
229 + "<html><head></head>\n"
230 + "<body>\n"
231 + "<script>\n"
232 + " 'use strict';\n"
233 + LOG_TITLE_FUNCTION
234 + " function foo(x) {return this.toString();};\n"
235 + " var r = Function.prototype.apply.apply(foo, ['b', ['Hello!', 'Goodbye!']]);\n"
236 + " log(r);\n"
237 + "</script>\n"
238 + "</body></html>";
239
240 loadPageVerifyTitle2(html);
241 }
242
243
244
245
246 @Test
247 @Alerts("Hello!")
248 public void applyToCallCallsCorrectFunction() throws Exception {
249 final String html = DOCTYPE_HTML
250 + "<html><head></head>\n"
251 + "<body>\n"
252 + "<script>\n"
253 + " 'use strict';\n"
254 + LOG_TITLE_FUNCTION
255 + " function foo(x) {return x;};\n"
256 + " var r = foo.call.apply(foo, ['b', 'Hello!']);\n"
257 + " log(r);\n"
258 + "</script>\n"
259 + "</body></html>";
260
261 loadPageVerifyTitle2(html);
262 }
263
264
265
266
267 @Test
268 @Alerts("b")
269 public void applyToCallSetsCorrectFunctionThis() throws Exception {
270 final String html = DOCTYPE_HTML
271 + "<html><head></head>\n"
272 + "<body>\n"
273 + "<script>\n"
274 + " 'use strict';\n"
275 + LOG_TITLE_FUNCTION
276 + " function foo(x) {return this.toString();};\n"
277 + " var r = foo.call.apply(foo, ['b', 'Hello!']);\n"
278 + " log(r);\n"
279 + "</script>\n"
280 + "</body></html>";
281
282 loadPageVerifyTitle2(html);
283 }
284
285
286
287
288 @Test
289 @Alerts("abcd / undefined")
290 public void boundWithoutArgs() throws Exception {
291 final String html = DOCTYPE_HTML
292 + "<html><head></head>\n"
293 + "<body>\n"
294 + "<script>\n"
295 + LOG_TITLE_FUNCTION
296 + " function foo(x) { return this.toString() + ' / ' + x; };\n"
297 + " var boundThis = 'abcd';\n"
298 + " var boundFoo = Function.prototype.bind.call(foo, boundThis);\n"
299 + " var r = boundFoo.call('Hello!');\n"
300 + " log(r);\n"
301 + "</script>\n"
302 + "</body></html>";
303
304 loadPageVerifyTitle2(html);
305 }
306
307
308
309
310 @Test
311 @Alerts("abcd / world")
312 public void boundWithArg() throws Exception {
313 final String html = DOCTYPE_HTML
314 + "<html><head></head>\n"
315 + "<body>\n"
316 + "<script>\n"
317 + LOG_TITLE_FUNCTION
318 + " function foo(x) { return this.toString() + ' / ' + x; };\n"
319 + " var boundThis = 'abcd';\n"
320 + " var boundFoo = Function.prototype.bind.call(foo, boundThis, 'world');\n"
321 + " var r = boundFoo.call('Hello!');\n"
322 + " log(r);\n"
323 + "</script>\n"
324 + "</body></html>";
325
326 loadPageVerifyTitle2(html);
327 }
328
329
330
331
332 @Test
333 @Alerts("world")
334 public void bound() throws Exception {
335 final String html = DOCTYPE_HTML
336 + "<html><head></head>\n"
337 + "<body>\n"
338 + "<script>\n"
339 + LOG_TITLE_FUNCTION
340 + " function foo() { return 'world'; };\n"
341 + " var boundThis = 'abcd';\n"
342 + " var boundFoo = Function.prototype.bind.call(foo, boundThis);\n"
343 + " var r = boundFoo.call(' dd');\n"
344 + " log(r);\n"
345 + "</script>\n"
346 + "</body></html>";
347
348 loadPageVerifyTitle2(html);
349 }
350
351
352
353
354 @Test
355 @Alerts({"f1", "f2", "f3", "f4", "f5",
356 "f6", "g", "3", "[foo]", ""})
357 public void name() throws Exception {
358 final String html = DOCTYPE_HTML
359 + "<html><head></head>\n"
360 + "<body>\n"
361 + "<script>\n"
362 + LOG_TITLE_FUNCTION
363
364 + "let f1 = function() {}; log(f1.name);\n"
365 + "let f2= () => {}; log(f2.name);\n"
366 + "let f3 = function() {}; log(f3.name);\n"
367 + "let f4 = () => {}; log(f4.name);\n"
368 + "let f5 = function() {}; log(f5.name);\n"
369
370 + "let f6 = () => {}; log(f6.name);\n"
371 + "let f7 = function g() {}; log(f7.name);\n"
372 + "let f8 = { [1 + 2]() {} }; log(f8['3'].name);\n"
373 + "let s = Symbol('foo'); let f9 = { [s]() {} }; log(f9[s].name);\n"
374 + "let s2 = Symbol(); f10 = { [s2]() {} }; log(f10[s2].name);\n"
375
376 + "</script>\n"
377 + "</body></html>";
378
379 loadPageVerifyTitle2(html);
380 }
381 }