/* * SameValue() (E5 Section 9.12). * * SameValue() is difficult to test indirectly. It appears in E5 Section * 8.12.9, [[DefineOwnProperty]] several times. * * One relatively simple approach is to create a non-configurable, non-writable * property, and attempt to use Object.defineProperty() to set a new value for * the property. If SameValue(oldValue,newValue), no exception is thrown. * Otherwise, reject (TypeError); see E5 Section 8.12.9, step 10.a.ii.1. */ function sameValue(x,y) { var obj = {}; try { Object.defineProperty(obj, 'test', { writable: false, enumerable: false, configurable: false, value: x }); Object.defineProperty(obj, 'test', { value: y }); } catch (e) { if (e.name === 'TypeError') { return false; } else { throw e; } } return true; } function test(x,y) { print(sameValue(x,y)); } /*=== test: different types, first undefined false false false false false false ===*/ /* Different types, first is undefined */ print('test: different types, first undefined') test(undefined, null); test(undefined, true); test(undefined, false); test(undefined, 123.0); test(undefined, 'foo'); test(undefined, {}); /*=== test: different types, first null false false false false false false ===*/ /* Different types, first is null */ print('test: different types, first null') test(null, undefined); test(null, true); test(null, false); test(null, 123.0); test(null, 'foo'); test(null, {}); /*=== test: different types, first boolean false false false false false false false false false false ===*/ /* Different types, first is boolean */ print('test: different types, first boolean') test(true, undefined); test(true, null); test(true, 123.0); test(true, 'foo'); test(true, {}); test(false, undefined); test(false, null); test(false, 123.0); test(false, 'foo'); test(false, {}); /*=== test: different types, first number false false false false false false ===*/ /* Different types, first is number */ print('test: different types, first number') test(123.0, undefined); test(123.0, null); test(123.0, true); test(123.0, false); test(123.0, 'foo'); test(123.0, {}); /*=== test: different types, first string false false false false false false ===*/ /* Different types, first is string */ print('test: different types, first string') test('foo', undefined); test('foo', null); test('foo', true); test('foo', false); test('foo', 123.0); test('foo', {}); /*=== test: different types, first object false false false false false false ===*/ /* Different types, first is object */ print('test: different types, first object') test({}, undefined); test({}, null); test({}, true); test({}, false); test({}, 123.0); test({}, 'foo'); /*=== test: same types, undefined true ===*/ /* Same types: undefined */ print('test: same types, undefined') test(undefined, undefined); /*=== test: same types, null true ===*/ /* Same types: null */ print('test: same types, null') test(null, null); /*=== test: same types, boolean true false false true ===*/ /* Same types: boolean */ print('test: same types, boolean') test(true, true); test(true, false); test(false, true); test(false, false); /*=== test: same types, number true true false false true true false false true true true ===*/ /* Same types: number */ print('test: same types, number') test(NaN, NaN); test(-0, -0); test(-0, +0); test(+0, -0); test(+0, +0); test(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); test(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); test(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY); test(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); test(-123.0, -123.0); test(123.0, 123.0); /*=== test: same types, string true false false true ===*/ /* Same types: string */ print('test: same types, string') test('', ''); test('foo', '') test('', 'foo'); test('foo', 'foo'); /*=== test: same types, object true false false true ===*/ /* Same types: object */ var obj1 = {}; var obj2 = {}; print('test: same types, object') test(obj1, obj1); test(obj1, obj2); test(obj2, obj1); test(obj2, obj2);