jscript: Support getting value of accessor property.
[wine.git] / dlls / mshtml / tests / es5.js
blob4e7b83b579f1d63dc1e31736c6bac8dde6bd77a0
1 /*
2  * Copyright 2018 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
19 var JS_E_PROP_DESC_MISMATCH = 0x800a01bd;
20 var JS_E_INVALID_WRITABLE_PROP_DESC = 0x800a13ac;
21 var JS_E_NONCONFIGURABLE_REDEFINED = 0x800a13d6;
22 var JS_E_NONWRITABLE_MODIFIED = 0x800a13d7;
24 function test_date_now() {
25     var now = Date.now();
26     var time = (new Date()).getTime();
28     ok(time >= now && time-now < 50, "unexpected Date.now() result " + now + " expected " + time);
30     Date.now(1, 2, 3);
32     next_test();
35 function test_toISOString() {
36     function expect(date, expected) {
37         var s = date.toISOString();
38         ok(s === expected, "toISOString returned " + s + " expected " + expected);
39     }
41     function expect_exception(func) {
42         try {
43             func();
44         }catch(e) {
45             return;
46         }
47         ok(false, "expected exception");
48     }
50     expect(new Date(0), "1970-01-01T00:00:00.000Z");
51     expect(new Date(0xdeadbeef), "1970-02-13T05:45:28.559Z");
52     expect(new Date(10928309128301), "2316-04-22T01:25:28.301Z");
53     expect(new Date(-1), "1969-12-31T23:59:59.999Z");
54     expect(new Date(-62167219200000), "0000-01-01T00:00:00.000Z");
55     expect(new Date(-62167219200001), "-000001-12-31T23:59:59.999Z");
56     expect(new Date(-6216721920000100), "-195031-12-03T23:59:59.900Z");
57     expect(new Date(1092830912830100), "+036600-06-07T22:27:10.100Z");
59     expect_exception(function() { new Date(NaN).toISOString(); });
60     expect_exception(function() { new Date(31494784780800001).toISOString(); });
62     next_test();
65 function test_indexOf() {
66     function expect(array, args, exr) {
67         var r = Array.prototype.indexOf.apply(array, args);
68         ok(r == exr, "indexOf returned " + r + " expected " + exr);
69     }
71     ok(Array.prototype.indexOf.length == 1, "indexOf.length = " + Array.prototype.indexOf.length);
73     expect([1,2,3], [2], 1);
74     expect([1,undefined,3], [undefined], 1);
75     expect([1,undefined,3], [], 1);
76     expect([1,,3], [undefined], -1);
77     expect([1,2,3,4,5,6], [2, 2], -1);
78     expect([1,2,3,4,5,6], [5, -1], -1);
79     expect([1,2,3,4,5,6], [5, -2], 4);
80     expect([1,2,3,4,5,6], [5, -20], 4);
81     expect([1,2,3,4,5,6], [5, 20], -1);
82     expect("abc", ["b"], 1);
83     expect(true, [true], -1);
84     expect({"4": 4, length: 5}, [4], 4);
85     expect({"4": 4, length: 5}, [undefined], -1);
86     expect({"4": 4, length: 3}, [4], -1);
87     expect({"test": true}, [true], -1);
88     expect([1,2,3], [2, 1.9], 1);
90     next_test();
93 function test_isArray() {
94     function expect_array(a, exr) {
95         var r = Array.isArray(a);
96         ok(r === exr, "isArray returned " + r + " expected " + exr);
97     }
99     expect_array([1], true);
100     expect_array(Array, false);
101     expect_array(new Array(), true);
102     expect_array({"1": 1, "2": 2, length: 2}, false);
104     function C() {}
105     C.prototype = Array.prototype;
106     expect_array(new C(), false);
108     next_test();
111 function test_identifier_keywords() {
112     var o = {
113         if: 1,
114         default: 2,
115         function: 3,
116         break: true,
117         case: true,
118         catch: true,
119         continue: true,
120         delete: true,
121         do: true,
122         else: true,
123         finally: true,
124         for: true,
125         in: true,
126         instanceof: true,
127         new: true,
128         return: true,
129         switch: true,
130         throw: true,
131         try: true,
132         typeof: true,
133         var: true,
134         void: true,
135         while: true,
136         with: true,
137         true: true,
138         false: true,
139         null: true,
140         this: true
141     };
142     function ro() { return o; };
144     ok(o.if === 1, "o.if = " + o.if);
145     ok(ro().default === 2, "ro().default = " + ro().default);
146     ok(o.false === true, "o.false = " + o.false);
148     next_test();
151 function test_own_data_prop_desc(obj, prop, expected_writable, expected_enumerable,
152                             expected_configurable) {
153     var desc = Object.getOwnPropertyDescriptor(obj, prop);
154     ok("value" in desc, "value is not in desc");
155     ok(desc.value === obj[prop], "desc.value = " + desc.value + " expected " + obj[prop]);
156     ok(desc.writable === expected_writable, "desc(" + prop + ").writable = " + desc.writable
157        + " expected " + expected_writable);
158     ok(desc.enumerable === expected_enumerable, "desc.enumerable = " + desc.enumerable
159        + " expected " + expected_enumerable);
160     ok(desc.configurable === expected_configurable, "desc.configurable = " + desc.configurable
161        + " expected " + expected_configurable);
164 function test_getOwnPropertyDescriptor() {
165     var obj;
167     obj = { test: 1 };
168     test_own_data_prop_desc(obj, "test", true, true, true);
170     test_own_data_prop_desc(Object, "getOwnPropertyDescriptor", true, false, true);
171     test_own_data_prop_desc(Math, "PI", false, false, false);
173     var obj = new String();
174     test_own_data_prop_desc(obj, "length", false, false, false);
175     ok(Object.getOwnPropertyDescriptor(obj, "slice") === undefined,
176        "getOwnPropertyDescriptor(slice) did not return undefined");
177     test_own_data_prop_desc(String.prototype, "slice", true, false, true);
179     obj = new Array();
180     test_own_data_prop_desc(obj, "length", true, false, false);
182     obj = new Function();
183     test_own_data_prop_desc(obj, "length", false, false, false);
184     test_own_data_prop_desc(obj, "arguments", false, false, false);
186     obj = /test/;
187     test_own_data_prop_desc(obj, "global", false, false, false);
188     test_own_data_prop_desc(obj, "ignoreCase", false, false, false);
189     test_own_data_prop_desc(obj, "lastIndex", true, false, false);
190     test_own_data_prop_desc(obj, "multiline", false, false, false);
191     test_own_data_prop_desc(obj, "source", false, false, false);
193     (function() {
194         test_own_data_prop_desc(arguments, "length", true, false, true);
195         test_own_data_prop_desc(arguments, "callee", true, false, true);
196     })();
198     test_own_data_prop_desc(String, "prototype", false, false, false);
199     test_own_data_prop_desc(function(){}, "prototype", true, false, false);
200     test_own_data_prop_desc(Function, "prototype", false, false, false);
201     test_own_data_prop_desc(String.prototype, "constructor", true, false, true);
203     next_test();
206 function test_defineProperty() {
207     function test_accessor_prop_desc(obj, prop, orig_desc) {
208         var expected_enumerable = "enumerable" in orig_desc && !!orig_desc.enumerable;
209         var expected_configurable = "configurable" in orig_desc && !!orig_desc.configurable;
211         var desc = Object.getOwnPropertyDescriptor(obj, prop);
212         ok(desc.enumerable === expected_enumerable, "desc.enumerable = " + desc.enumerable
213            + " expected " + expected_enumerable);
214         ok(desc.configurable === expected_configurable, "desc.configurable = " + desc.configurable
215            + " expected " + expected_configurable);
216         ok(desc.get === orig_desc.get, "desc.get = " + desc.get);
217         ok(desc.set === orig_desc.set, "desc.set = " + desc.set);
218     }
220     function expect_exception(func, expected_number) {
221         try {
222             func();
223         }catch(e) {
224             var n = e.number + 0x100000000; /* make it unsigned like HRESULT */
225             todo_wine_if(expected_number == JS_E_PROP_DESC_MISMATCH).
226             ok(n === expected_number, "got exception " + n.toString(16)
227                + " expected " + expected_number.toString(16));
228             ok(e.name === "TypeError", "e.name = " + e.name);
229             return;
230         }
231         ok(false, "expected exception");
232     }
234     var obj = new Object();
235     Object.defineProperty(obj, "test", {});
236     ok("test" in obj, "test is not in obj");
237     test_own_data_prop_desc(obj, "test", false, false, false);
238     ok(obj.test === undefined, "obj.test = " + obj.test);
240     Object.defineProperty(obj, "all", {writable: true, enumerable: true, configurable: true, value: 1});
241     test_own_data_prop_desc(obj, "all", true, true, true);
242     ok(obj.all === 1, "obj.test = " + obj.test);
244     Object.defineProperty(obj, "all", {writable: false});
245     test_own_data_prop_desc(obj, "all", false, true, true);
246     ok(obj.all === 1, "obj.test = " + obj.test);
248     var getsetprop_value = 1;
249     var desc = {
250         get: function() {
251             return getsetprop_value;
252         },
253         set: function(v) {
254             getsetprop_value = v;
255         }
256     };
257     Object.defineProperty(obj, "getsetprop", desc);
258     test_accessor_prop_desc(obj, "getsetprop", desc);
260     ok(obj.getsetprop === 1, "getsetprop = " + obj.getsetprop);
262     Object.defineProperty(obj, "notConf", {writable: true, enumerable: true, configurable: false, value: 1});
263     test_own_data_prop_desc(obj, "notConf", true, true, false);
265     expect_exception(function() {
266         Object.defineProperty(obj, "notConf",
267                               {writable: true, enumerable: true, configurable: true, value: 1});
268     }, JS_E_NONCONFIGURABLE_REDEFINED);
270     expect_exception(function() {
271         Object.defineProperty(obj, "notConf",
272                               {writable: true, enumerable: false, configurable: false, value: 1});
273     }, JS_E_NONCONFIGURABLE_REDEFINED);
275     Object.defineProperty(obj, "notConf",
276                           {writable: true, enumerable: true, configurable: false, value: 2});
277     test_own_data_prop_desc(obj, "notConf", true, true, false);
279     Object.defineProperty(obj, "notConf", {writable: true, value: 2});
280     test_own_data_prop_desc(obj, "notConf", true, true, false);
282     Object.defineProperty(obj, "notConf2",
283                           {writable: false, enumerable: false, configurable: false, value: 1});
284     test_own_data_prop_desc(obj, "notConf2", false, false, false);
285     obj.notConf2 = 2;
286     ok(obj.notConf2 === 1, "obj.notConf2 = " + obj.notConf2)
288     expect_exception(function() {
289         Object.defineProperty(obj, "notConf2",
290                               {writable: false, enumerable: false, configurable: true, value: 1});
291     }, JS_E_NONCONFIGURABLE_REDEFINED);
293     expect_exception(function() {
294         Object.defineProperty(obj, "notConf2",
295                               {writable: false, enumerable: true, configurable: false, value: 1});
296     }, JS_E_NONCONFIGURABLE_REDEFINED);
298     expect_exception(function() {
299         Object.defineProperty(obj, "notConf2", {writable: true, value: 1});
300     }, JS_E_NONWRITABLE_MODIFIED);
302     expect_exception(function() {
303         Object.defineProperty(obj, "notConf2", {value: 2});
304     }, JS_E_NONWRITABLE_MODIFIED);
306     Object.defineProperty(obj, "notConf2",
307                           {writable: false, enumerable: false, configurable: false, value: 1});
308     test_own_data_prop_desc(obj, "notConf2", false, false, false);
310     Object.defineProperty(obj, "notConf2", {writable: false, value: 1});
311     test_own_data_prop_desc(obj, "notConf2", false, false, false);
313     desc = {
314         get: function() {
315             return getsetprop_value;
316         },
317         set: function(v) {
318             getsetprop_value = v;
319         },
320         configurable: false
321     };
322     Object.defineProperty(obj, "notConfAcc", desc);
323     test_accessor_prop_desc(obj, "notConfAcc", desc);
325     expect_exception(function() {
326         Object.defineProperty(obj, "notConfAcc", {value: 1});
327     }, JS_E_NONCONFIGURABLE_REDEFINED);
329     expect_exception(function() {
330         Object.defineProperty(obj, "notConfAcc", {get: desc.get, set: function () {}});
331     }, JS_E_NONCONFIGURABLE_REDEFINED);
333     expect_exception(function() {
334         Object.defineProperty(obj, "notConfAcc", {get: undefined, set: desc.set});
335     }, JS_E_NONCONFIGURABLE_REDEFINED);
337     expect_exception(function() {
338         Object.defineProperty(obj, "notConfAcc", {writable: true});
339     }, JS_E_NONCONFIGURABLE_REDEFINED);
341     Object.defineProperty(obj, "notConfAcc", {get: desc.get});
342     test_accessor_prop_desc(obj, "notConfAcc", desc);
344     Object.defineProperty(obj, "notConfAcc", {set: desc.set});
345     test_accessor_prop_desc(obj, "notConfAcc", desc);
347     Object.defineProperty(obj, "notConfAcc", {configurable: false});
348     test_accessor_prop_desc(obj, "notConfAcc", desc);
350     desc = {
351         get: function() {
352             return getsetprop_value;
353         },
354         set: function(v) {
355             getsetprop_value = v;
356         },
357         configurable: true
358     };
359     Object.defineProperty(obj, "confAcc", desc);
360     test_accessor_prop_desc(obj, "confAcc", desc);
362     Object.defineProperty(obj, "confAcc", {writable: 1});
363     test_own_data_prop_desc(obj, "confAcc", true, false, true);
365     Object.defineProperty(obj, "confAcc", desc);
366     test_accessor_prop_desc(obj, "confAcc", desc);
368     desc.get = function() {};
369     desc.set = undefined;
370     Object.defineProperty(obj, "confAcc", desc);
371     test_accessor_prop_desc(obj, "confAcc", desc);
373     expect_exception(function() {
374         Object.defineProperty(obj, "invaliddesc", {get: undefined, value: 1});
375     }, JS_E_PROP_DESC_MISMATCH);
377     expect_exception(function() {
378         Object.defineProperty(obj, "invaliddesc", {set: undefined, writable: true});
379     }, JS_E_INVALID_WRITABLE_PROP_DESC);
381     function child() {}
382     desc = {
383         get: function() {
384             ok(this === obj, "this != obj");
385             return getsetprop_value;
386         },
387         set: function(v) {
388             ok(this === obj, "this != obj");
389             getsetprop_value = v;
390         },
391         configurable: true
392     };
393     Object.defineProperty(child.prototype, "parent_accessor", desc);
395     obj = new child();
396     getsetprop_value = 6;
397     ok(obj.parent_accessor === 6, "parent_accessor = " + obj.parent_accessor);
399     ok(Object.getOwnPropertyDescriptor(obj, "parent_accessor") === undefined,
400        "getOwnPropertyDescriptor(parent_accessor) did not return undefined");
401     test_accessor_prop_desc(child.prototype, "parent_accessor", desc);
403     desc.get = undefined;
404     Object.defineProperty(child.prototype, "parent_accessor", desc);
405     ok(obj.parent_accessor === undefined, "parent_accessor = " + obj.parent_accessor);
407     next_test();
410 function test_global_properties() {
411     var o;
413     /* Make sure that global properties are not writable. */
414     o = NaN;
415     NaN = 1;
416     ok(isNaN(NaN), "NaN = " + NaN);
417     o = undefined;
418     undefined = 1;
419     ok(undefined === o, "NaN = " + NaN);
420     o = Infinity;
421     Infinity = 1;
422     ok(Infinity === o, "Infinity = " + NaN);
424     next_test();
427 var tests = [
428     test_date_now,
429     test_toISOString,
430     test_indexOf,
431     test_isArray,
432     test_identifier_keywords,
433     test_getOwnPropertyDescriptor,
434     test_defineProperty,
435     test_global_properties