View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript;
16  
17  import org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.junit.BrowserRunner;
19  import org.htmlunit.junit.annotation.Alerts;
20  import org.junit.Test;
21  import org.junit.runner.RunWith;
22  
23  /**
24   * Tests for org.mozilla.javascript.Arguments, which is the object for "function.arguments".
25   *
26   * @author Ahmed Ashour
27   * @author Marc Guillemot
28   * @author Ronald Brill
29   */
30  @RunWith(BrowserRunner.class)
31  public class ArgumentsTest extends WebDriverTestCase {
32  
33      /**
34       * @throws Exception if the test fails
35       */
36      @Test
37      @Alerts({"0", "0", "1", "0"})
38      public void arguments() throws Exception {
39          final String html = DOCTYPE_HTML
40              + "<html><head>\n"
41              + "<script>\n"
42              + LOG_TITLE_FUNCTION
43              + "function test() {\n"
44              + "  log(test.arguments.length);\n"
45              + "  test1('hi');\n"
46              + "}\n"
47              + "function test1(hello) {\n"
48              + "  log(test.arguments.length);\n"
49              + "  log(test1.arguments.length);\n"
50              + "  log(arguments.callee.caller.arguments.length);\n"
51              + "}\n"
52              + "</script></head><body onload='test()'>\n"
53              + "</body></html>";
54  
55          loadPageVerifyTitle2(html);
56      }
57  
58      /**
59       * @throws Exception if the test fails
60       */
61      @Test
62      @Alerts({"null", "null"})
63      public void argumentsShouldBeNullOutsideFunction() throws Exception {
64          final String html = DOCTYPE_HTML
65              + "<html><body>"
66              + "<script>\n"
67              + LOG_TITLE_FUNCTION
68              + "function test() {\n"
69              + "}\n"
70              + "log(test.arguments);\n"
71              + "test();\n"
72              + "log(test.arguments);\n"
73              + "</script></body></html>";
74  
75          loadPageVerifyTitle2(html);
76      }
77  
78      /**
79       * @throws Exception if the test fails
80       */
81      @Test
82      @Alerts("callee,length")
83      public void argumentsPropertyNames() throws Exception {
84          final String html = DOCTYPE_HTML
85              + "<html><body>"
86              + "<script>\n"
87              + LOG_TITLE_FUNCTION
88              + "function test() {\n"
89              + "  let p = Object.getOwnPropertyNames(arguments);\n"
90              + "  p.sort();\n"
91              + "  log(p);"
92              + "}\n"
93              + "test();"
94              + "</script></body></html>";
95  
96          loadPageVerifyTitle2(html);
97      }
98  
99  
100     /**
101      * @throws Exception if the test fails
102      */
103     @Test
104     @Alerts("callee,length")
105     public void argumentsPropertyNamesStrict() throws Exception {
106         final String html = DOCTYPE_HTML
107             + "<html><body>"
108             + "<script>\n"
109             + "'use strict';"
110             + LOG_TITLE_FUNCTION
111             + "function test() {\n"
112             + "  let p = Object.getOwnPropertyNames(arguments);\n"
113             + "  p.sort();\n"
114             + "  log(p);"
115             + "}\n"
116             + "test();"
117             + "</script></body></html>";
118 
119         loadPageVerifyTitle2(html);
120     }
121 
122     /**
123      * @throws Exception if the test fails
124      */
125     @Test
126     @Alerts("2")
127     public void passedCountDifferentFromDeclared() throws Exception {
128         final String html = DOCTYPE_HTML
129             + "<html><head>\n"
130             + "<script>\n"
131             + LOG_TITLE_FUNCTION
132             + "function test() {\n"
133             + "  test1('hi', 'there');\n"
134             + "}\n"
135             + "function test1() {\n"
136             + "  log(test1.arguments.length);\n"
137             + "}\n"
138             + "</script></head><body onload='test()'>\n"
139             + "</body></html>";
140 
141         loadPageVerifyTitle2(html);
142     }
143 
144     /**
145      * @throws Exception if the test fails
146      */
147     @Test
148     @Alerts({"2", "world", "undefined", "undefined"})
149     public void readOnlyWhenAccessedThroughFunction() throws Exception {
150         final String html = DOCTYPE_HTML
151             + "<html><head>\n"
152             + "<script>\n"
153             + LOG_TITLE_FUNCTION
154             + "function test() {\n"
155             + "  test1('hello', 'world');\n"
156             + "}\n"
157             + "function test1() {\n"
158             + "  test1.arguments[1] = 'hi';\n"
159             + "  test1.arguments[3] = 'you';\n"
160             + "  log(test1.arguments.length);\n"
161             + "  log(test1.arguments[1]);\n"
162             + "  log(test1.arguments[2]);\n"
163             + "  log(test1.arguments[3]);\n"
164             + "}\n"
165             + "</script></head><body onload='test()'>\n"
166             + "</body></html>";
167 
168         loadPageVerifyTitle2(html);
169     }
170 
171     /**
172      * @throws Exception if the test fails
173      */
174     @Test
175     @Alerts({"2", "hi", "undefined", "you"})
176     public void writableWithinFunction() throws Exception {
177         final String html = DOCTYPE_HTML
178             + "<html><body>\n"
179             + "<script>\n"
180             + LOG_TITLE_FUNCTION
181             + "function test1() {\n"
182             + "  arguments[1] = 'hi';\n"
183             + "  arguments[3] = 'you';\n"
184             + "  log(arguments.length);\n"
185             + "  log(arguments[1]);\n"
186             + "  log(arguments[2]);\n"
187             + "  log(arguments[3]);\n"
188             + "}\n"
189             + "test1('hello', 'world');\n"
190             + "</script></body></html>";
191 
192         loadPageVerifyTitle2(html);
193     }
194 
195     /**
196      * @throws Exception if the test fails
197      */
198     @Test
199     @Alerts("false")
200     public void argumentsEqualsFnArguments() throws Exception {
201         final String html = DOCTYPE_HTML
202             + "<html><body>\n"
203             + "<script>\n"
204             + LOG_TITLE_FUNCTION
205             + "function test1() {\n"
206             + "  log(arguments == test1.arguments);\n"
207             + "}\n"
208             + "test1('hello', 'world');\n"
209             + "</script></body></html>";
210 
211         loadPageVerifyTitle2(html);
212     }
213 
214     /**
215      * @throws Exception if the test fails
216      */
217     @Test
218     @Alerts("hi")
219     public void argumentsAsParameter() throws Exception {
220         final String html = DOCTYPE_HTML
221             + "<html><body>"
222             + "<script>\n"
223             + LOG_TITLE_FUNCTION
224             + "function test1(arguments) {\n"
225             + "  log(arguments);\n"
226             + "}\n"
227             + "test1('hi');\n"
228             + "</script></body></html>";
229 
230         loadPageVerifyTitle2(html);
231     }
232 
233     /**
234      * @throws Exception if the test fails
235      */
236     @Test
237     @Alerts({"function/", "function/", "true"})
238     public void argumentsCallee() throws Exception {
239         final String html = DOCTYPE_HTML
240                 + "<html><body>"
241                 + "<script>\n"
242                 + "  'use strict';\n"
243                 + LOG_TITLE_FUNCTION
244                 + "function foo() {\n"
245                 + "  let desc = Object.getOwnPropertyDescriptor(arguments, 'callee');\n"
246                 + "  log(typeof desc.get + '/' + desc.get.name);\n"
247                 + "  log(typeof desc.set + '/' + desc.set.name);\n"
248                 + "  log(desc.get === desc.set);\n"
249                 + "}\n"
250                 + "foo();\n"
251                 + "</script></body></html>";
252 
253         loadPageVerifyTitle2(html);
254     }
255 
256     /**
257      * @throws Exception if the test fails
258      */
259     @Test
260     @Alerts({"true", "true"})
261     public void argumentsCalleeDifferentFunctions() throws Exception {
262         final String html = DOCTYPE_HTML
263                 + "<html><body>"
264                 + "<script>\n"
265                 + "  'use strict';\n"
266                 + LOG_TITLE_FUNCTION
267                 + "function foo1() {\n"
268                 + "  return Object.getOwnPropertyDescriptor(arguments, 'callee');\n"
269                 + "}\n"
270                 + "function foo2() {\n"
271                 + "  return Object.getOwnPropertyDescriptor(arguments, 'callee');\n"
272                 + "}\n"
273                 + "let desc1 = foo1();\n"
274                 + "let desc2 = foo2();\n"
275                 + "log(desc1.get === desc2.get);\n"
276                 + "log(desc1.set === desc2.set);\n"
277                 + "</script></body></html>";
278 
279         loadPageVerifyTitle2(html);
280     }
281 }