Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 // Flags: --harmony-simd
     29 
     30 /**
     31  * This test uses assert{True,False}(... == ...) instead of
     32  * assertEquals(..., ...) to not rely on the details of the
     33  * implementation of assertEquals.
     34  */
     35 
     36 function testEqual(a, b) {
     37   assertTrue(a == b);
     38   assertTrue(b == a);
     39   assertFalse(a != b);
     40   assertFalse(b != a);
     41 }
     42 
     43 function testNotEqual(a, b) {
     44   assertFalse(a == b);
     45   assertFalse(b == a);
     46   assertTrue(a != b);
     47   assertTrue(b != a);
     48 }
     49 
     50 // Object where ToPrimitive returns value.
     51 function Wrapper(value) {
     52   this.value = value;
     53   this.valueOf = function () { return this.value; };
     54 }
     55 
     56 // Object where ToPrimitive returns value by failover to toString when
     57 // valueOf isn't a function.
     58 function Wrapper2(value) {
     59   this.value = value;
     60   this.valueOf = null;
     61   this.toString = function () { return this.value; };
     62 }
     63 
     64 
     65 // Compare values of same type.
     66 
     67 // Numbers are equal if same, unless NaN, which isn't equal to anything, and
     68 // +/-0 being equal.
     69 
     70 testNotEqual(NaN, NaN);
     71 testNotEqual(NaN, 0);
     72 testNotEqual(NaN, Infinity);
     73 
     74 testEqual(Number.MAX_VALUE, Number.MAX_VALUE);
     75 testEqual(Number.MIN_VALUE, Number.MIN_VALUE);
     76 testEqual(Infinity, Infinity);
     77 testEqual(-Infinity, -Infinity);
     78 
     79 testEqual(0, 0);
     80 testEqual(0, -0);
     81 testEqual(-0, -0);
     82 
     83 testNotEqual(0.9, 1);
     84 testNotEqual(0.999999, 1);
     85 testNotEqual(0.9999999999, 1);
     86 testNotEqual(0.9999999999999, 1);
     87 
     88 // Strings are equal if containing the same code points.
     89 
     90 testEqual('hello', 'hello');
     91 testEqual('hello', 'hel' + 'lo');
     92 testEqual('', '');
     93 testEqual('\u0020\x20', '  ');  // Escapes are not part of the value.
     94 
     95 // Booleans are equal if they are the same.
     96 
     97 testEqual(true, true);
     98 testEqual(false, false);
     99 testNotEqual(true, false);
    100 
    101 // Null and undefined are equal to themselves.
    102 
    103 testEqual(null, null);
    104 testEqual(undefined, undefined);
    105 
    106 // Objects are equal if they are the same object only.
    107 
    108 testEqual(Math, Math);
    109 testEqual(Object.prototype, Object.prototype);
    110 
    111 
    112 (function () {
    113   var x = new Wrapper(null);
    114   var y = x, z = x;
    115    testEqual(y, x);
    116 })();
    117 
    118 (function () {
    119   var x = new Boolean(true);
    120   var y = x, z = x;
    121    testEqual(y, x);
    122 })();
    123 
    124 (function () {
    125   var x = new Boolean(false);
    126   var y = x, z = x;
    127    testEqual(y, x);
    128 })();
    129 
    130 // Test comparing values of different types.
    131 
    132 // Null and undefined are equal to each-other, and to nothing else.
    133 testEqual(null, undefined);
    134 testEqual(undefined, null);
    135 
    136 testNotEqual(null, new Wrapper(null));
    137 testNotEqual(null, 0);
    138 testNotEqual(null, false);
    139 testNotEqual(null, "");
    140 testNotEqual(null, new Object());
    141 testNotEqual(undefined, new Wrapper(undefined));
    142 testNotEqual(undefined, 0);
    143 testNotEqual(undefined, false);
    144 testNotEqual(undefined, "");
    145 testNotEqual(undefined, new Object());
    146 
    147 // Numbers compared to Strings will convert the string to a number using
    148 // the internal ToNumber conversion.
    149 
    150 testEqual(1, '1');
    151 testEqual(255, '0xff');
    152 testEqual(0, '\r');  // ToNumber ignores tailing and trailing whitespace.
    153 testEqual(1e19, '1e19');
    154 testEqual(Infinity, "Infinity");
    155 
    156 // Booleans compared to anything else will be converted to numbers.
    157 testEqual(false, 0);
    158 testEqual(true, 1);
    159 testEqual(false, "0");  // String also converted to number.
    160 testEqual(true, "1");
    161 
    162 // Objects compared to Number or String (or Boolean, since that's converted
    163 // to Number too) is converted to primitive using ToPrimitive with NO HINT.
    164 // Having no hint means Date gets a string hint, and everything else gets
    165 // a number hint.
    166 
    167 testEqual(new Boolean(true), true);
    168 testEqual(new Boolean(true), 1);  // First to primtive boolean, then to number.
    169 testEqual(new Boolean(false), false);
    170 testEqual(new Boolean(false), 0);
    171 
    172 testEqual(new Wrapper(true), true);
    173 testEqual(new Wrapper(true), 1);
    174 testEqual(new Wrapper(false), false);
    175 testEqual(new Wrapper(false), 0);
    176 
    177 testEqual(new Wrapper2(true), true);
    178 testEqual(new Wrapper2(true), 1);
    179 testEqual(new Wrapper2(false), false);
    180 testEqual(new Wrapper2(false), 0);
    181 
    182 testEqual(new Number(1), true);
    183 testEqual(new Number(1), 1);
    184 testEqual(new Number(0), false);
    185 testEqual(new Number(0), 0);
    186 
    187 // Date objects convert to string, not number (and the string does not
    188 // convert to the number).
    189 testEqual(new Date(42), String(new Date(42)));
    190 testNotEqual(new Date(42), Number(new Date(42)));
    191 var dnow = new Date();
    192 testEqual(dnow, dnow);
    193 testEqual(dnow, String(dnow));
    194 testNotEqual(dnow, Number(dnow));
    195 
    196 // Doesn't just call toString, but uses ToPrimitive which tries toString first
    197 // and valueOf second.
    198 dnow.toString = null;
    199 testEqual(dnow, Number(dnow));
    200 dnow.valueOf = function () { return "42"; };
    201 testEqual(dnow, 42);
    202 dnow.toString = function () { return "1"; };
    203 testEqual(dnow, true);
    204 
    205 
    206 // Objects compared to other objects, or to null and undefined, are not
    207 // converted to primitive.
    208 testNotEqual(new Wrapper(null), new Wrapper(null));
    209 testNotEqual(new Boolean(true), new Boolean(true));
    210 testNotEqual(new Boolean(false), new Boolean(false));
    211 testNotEqual(new String("a"), new String("a"));
    212 testNotEqual(new Number(42), new Number(42));
    213 testNotEqual(new Date(42), new Date(42));
    214 testNotEqual(new Array(42), new Array(42));
    215 testNotEqual(new Object(), new Object());
    216 
    217 // Object that can't be converted to primitive.
    218 var badObject = {
    219   valueOf: null,
    220   toString: function() {
    221     return this;  // Not primitive.
    222   }
    223 };
    224 
    225 testEqual(badObject, badObject);
    226 testNotEqual(badObject, {});
    227 testNotEqual(badObject, null);
    228 testNotEqual(badObject, undefined);
    229 // Forcing conversion will throw.
    230 function testBadConversion(value) {
    231   assertThrows(function() { return badObject == value; });
    232   assertThrows(function() { return badObject != value; });
    233   assertThrows(function() { return value == badObject; });
    234   assertThrows(function() { return value != badObject; });
    235 }
    236 testBadConversion(0);
    237 testBadConversion("string");
    238 testBadConversion(true);
    239 
    240 var s = Symbol();
    241 testEqual(s, s);
    242 testEqual(Object(s), s);
    243 testEqual(new Wrapper(s), s);
    244 testNotEqual(Object(s), Object(s));
    245 
    246 var simd = SIMD.Float32x4(1, 2, 3, 4);
    247 testEqual(simd, simd);
    248 testEqual(Object(simd), simd);
    249 testEqual(new Wrapper(simd), simd);
    250 testNotEqual(Object(simd), Object(simd));
    251