1425bb815Sopenharmony_ci// Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci//
3425bb815Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci// you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci// You may obtain a copy of the License at
6425bb815Sopenharmony_ci//
7425bb815Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci//
9425bb815Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci// See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci// limitations under the License.
14425bb815Sopenharmony_ci
15425bb815Sopenharmony_civar obj = {
16425bb815Sopenharmony_ci  prop: function() {},
17425bb815Sopenharmony_ci  foo: 'bar'
18425bb815Sopenharmony_ci};
19425bb815Sopenharmony_ci// New properties may be added, existing properties may be changed or removed.
20425bb815Sopenharmony_ciobj.foo = 'baz';
21425bb815Sopenharmony_ciobj.lumpy = 'woof';
22425bb815Sopenharmony_cidelete obj.prop;
23425bb815Sopenharmony_ci
24425bb815Sopenharmony_civar o = Object.seal(obj);
25425bb815Sopenharmony_ci
26425bb815Sopenharmony_ciassert (o === obj);
27425bb815Sopenharmony_ciassert (Object.isSealed (obj) === true);
28425bb815Sopenharmony_ci
29425bb815Sopenharmony_ci// Changing property values on a sealed object still works.
30425bb815Sopenharmony_ciobj.foo = 'quux';
31425bb815Sopenharmony_ciassert (obj.foo === 'quux');
32425bb815Sopenharmony_ci// But you can't convert data properties to accessors, or vice versa.
33425bb815Sopenharmony_citry {
34425bb815Sopenharmony_ci    Object.defineProperty(obj, 'foo', { get: function() { return 42; } }); // throws a TypeError
35425bb815Sopenharmony_ci    assert (false);
36425bb815Sopenharmony_ci} catch (e) {
37425bb815Sopenharmony_ci    assert (e instanceof TypeError);
38425bb815Sopenharmony_ci}
39425bb815Sopenharmony_ci
40425bb815Sopenharmony_ci// Now any changes, other than to property values, will fail.
41425bb815Sopenharmony_ciobj.quaxxor = 'the friendly duck'; // silently doesn't add the property
42425bb815Sopenharmony_cidelete obj.foo; // silently doesn't delete the property
43425bb815Sopenharmony_ci
44425bb815Sopenharmony_ciassert (obj.quaxxor === undefined);
45425bb815Sopenharmony_ciassert (obj.foo === 'quux')
46425bb815Sopenharmony_ci
47425bb815Sopenharmony_citry {
48425bb815Sopenharmony_ci    // Attempted additions through Object.defineProperty will also throw.
49425bb815Sopenharmony_ci    Object.defineProperty (obj, 'ohai', { value: 17 }); // throws a TypeError
50425bb815Sopenharmony_ci    assert (false);
51425bb815Sopenharmony_ci} catch (e) {
52425bb815Sopenharmony_ci    assert (e instanceof TypeError);
53425bb815Sopenharmony_ci}
54425bb815Sopenharmony_ci
55425bb815Sopenharmony_citry {
56425bb815Sopenharmony_ci    Object.defineProperties (obj, { 'ohai' : { value: 17 } });
57425bb815Sopenharmony_ci    assert (false);
58425bb815Sopenharmony_ci} catch (e) {
59425bb815Sopenharmony_ci    assert (e instanceof TypeError);
60425bb815Sopenharmony_ci}
61425bb815Sopenharmony_ci
62425bb815Sopenharmony_ciObject.defineProperty (obj, 'foo', { value: 'eit' });
63425bb815Sopenharmony_ciassert (obj.foo === 'eit')
64425bb815Sopenharmony_ci
65425bb815Sopenharmony_ci// Objects aren't sealed by default.
66425bb815Sopenharmony_civar empty = {};
67425bb815Sopenharmony_ciassert (Object.isSealed (empty) === false);
68425bb815Sopenharmony_ci
69425bb815Sopenharmony_ci// If you make an empty object non-extensible, it is vacuously sealed.
70425bb815Sopenharmony_ciObject.preventExtensions (empty);
71425bb815Sopenharmony_ciassert (Object.isSealed (empty) === true);
72425bb815Sopenharmony_ci
73425bb815Sopenharmony_ci// The same is not true of a non-empty object, unless its properties are all non-configurable.
74425bb815Sopenharmony_civar hasProp = { fee: 'fie foe fum' };
75425bb815Sopenharmony_ciObject.preventExtensions (hasProp);
76425bb815Sopenharmony_ciassert (Object.isSealed (hasProp) === false);
77425bb815Sopenharmony_ci
78425bb815Sopenharmony_ci// But make them all non-configurable and the object becomes sealed.
79425bb815Sopenharmony_ciObject.defineProperty (hasProp, 'fee', { configurable: false });
80425bb815Sopenharmony_ciassert (Object.isSealed (hasProp) === true);
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci// The easiest way to seal an object, of course, is Object.seal.
83425bb815Sopenharmony_civar sealed = {};
84425bb815Sopenharmony_ciObject.seal (sealed);
85425bb815Sopenharmony_ciassert (Object.isSealed (sealed) === true);
86