tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

range.js (7867B)


      1 // |reftest| shell-option(--enable-iterator-range) skip-if(!Iterator.hasOwnProperty('range'))
      2 
      3 /*---
      4 features: [Iterator.range]
      5 ---*/
      6 
      7 // Invalid start parameter types
      8 assertThrowsInstanceOf(() => Iterator.range('1'), TypeError);
      9 assertThrowsInstanceOf(() => Iterator.range(null), TypeError);
     10 assertThrowsInstanceOf(() => Iterator.range(undefined), TypeError);
     11 assertThrowsInstanceOf(() => Iterator.range({}), TypeError);
     12 assertThrowsInstanceOf(() => Iterator.range([]), TypeError);
     13 assertThrowsInstanceOf(() => Iterator.range(true), TypeError);
     14 assertThrowsInstanceOf(() => Iterator.range(Symbol()), TypeError);
     15 
     16 // Invalid end parameter types
     17 assertThrowsInstanceOf(() => Iterator.range(0, '1'), TypeError);
     18 assertThrowsInstanceOf(() => Iterator.range(0, null), TypeError);
     19 assertThrowsInstanceOf(() => Iterator.range(0, undefined), TypeError);
     20 assertThrowsInstanceOf(() => Iterator.range(0, {}), TypeError);
     21 assertThrowsInstanceOf(() => Iterator.range(0, []), TypeError);
     22 assertThrowsInstanceOf(() => Iterator.range(0, true), TypeError);
     23 assertThrowsInstanceOf(() => Iterator.range(0, Symbol()), TypeError);
     24 
     25 // Invalid step parameter types
     26 assertThrowsInstanceOf(() => Iterator.range(0, 10, '1'), TypeError);
     27 assertThrowsInstanceOf(() => Iterator.range(0, 10, true), TypeError);
     28 assertThrowsInstanceOf(() => Iterator.range(0, 10, Symbol()), TypeError);
     29 
     30 // NaN and Infinity tests
     31 assertThrowsInstanceOf(() => Iterator.range(NaN), RangeError);
     32 assertThrowsInstanceOf(() => Iterator.range(0, NaN), RangeError);
     33 assertThrowsInstanceOf(() => Iterator.range(Infinity), TypeError);
     34 
     35 // Step type and value tests
     36 assertThrowsInstanceOf(() => Iterator.range(0, 10, NaN), RangeError);
     37 assertThrowsInstanceOf(() => Iterator.range(0, 10, Infinity), RangeError);
     38 
     39 // Zero step tests
     40 assertThrowsInstanceOf(() => Iterator.range(0, 10, 0), RangeError);
     41 Iterator.range(0, 0, 0);
     42 
     43 // Step configuration object tests
     44 Iterator.range(0, 10, { step: 2 });
     45 Iterator.range(0, 10, { step: -1 });
     46 Iterator.range(0, 10, { inclusiveEnd: true });
     47 assertThrowsInstanceOf(() => Iterator.range(0, 10, { step: '2' }), TypeError);
     48 
     49 // Basic number inputs
     50 Iterator.range(0, 10);
     51 Iterator.range(0, 10, 2);
     52 
     53 
     54 // Basic sequences with increasing steps of 1
     55 const result1 = Array.from(Iterator.range(0, 10));
     56 assertDeepEq(result1, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
     57 
     58 const result2 = Array.from(Iterator.range(2, 6));
     59 assertDeepEq(result2, [2, 3, 4, 5]);
     60 
     61 // Test empty range
     62 const result3 = Array.from(Iterator.range(0, 0));
     63 assertDeepEq(result3, []);
     64 
     65 const result4 = Array.from(Iterator.range(5, 5));
     66 assertDeepEq(result4, []);
     67 
     68 // testing reverse range
     69 const result5 = Array.from(Iterator.range(10, 0, -2));
     70 assertDeepEq(result5, [10, 8, 6, 4, 2]);
     71 
     72 // inclusive end
     73 const result6 = Array.from(Iterator.range(0, 10, { step: 2, inclusiveEnd: true }));
     74 assertDeepEq(result6, [0, 2, 4, 6, 8, 10]);
     75 
     76 // overlapping step with range limits
     77 const result7 = Array.from(Iterator.range(0, 10, 15));
     78 assertDeepEq(result7, [0]);
     79 
     80 // negative numbers in the range
     81 const result8 = Array.from(Iterator.range(-10, 0));
     82 assertDeepEq(result8, [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1]);
     83 
     84 // floating point
     85 const resultFloat1 = Array.from(Iterator.range(0.5, 3.5));
     86 assertDeepEq(resultFloat1, [0.5, 1.5, 2.5]);
     87 
     88 const resultFloat3 = Array.from(Iterator.range(0, 0.3, 0.1));
     89 assertDeepEq(resultFloat3, [0, 0.1, 0.2]);
     90 
     91 
     92 // floating point precision
     93 function approximatelyEqual(a, b) {
     94    // If inputs are arrays, compare each element
     95    if (Array.isArray(a) && Array.isArray(b)) {
     96        assertEq(a.length, b.length);
     97        // Compare each element
     98        for (let i = 0; i < a.length; i++) {
     99            approximatelyEqual(a[i], b[i]);
    100        }
    101        return true;
    102    }
    103 
    104    // For single numbers
    105    var r = (a != a && b != b) || Math.abs(a - b) < 0.001;
    106    if (!r) {
    107        print('Got', a, ', to be approximately equal to', b);
    108        assertEq(false, true);
    109    }
    110    return true;
    111 }
    112 
    113 const resultFloat2 = Array.from(Iterator.range(0, 1, 0.2));
    114 approximatelyEqual(resultFloat2, [0, 0.2, 0.4, 0.6, 0.8]);
    115 
    116 const resultStep2 = Array.from(Iterator.range(0, 10, 3.3));
    117 approximatelyEqual(resultStep2, [0, 3.3, 6.6, 9.9]);
    118 
    119 // invalid mixed-type parameters
    120 assertThrowsInstanceOf(() => Iterator.range(0, 10, { step: NaN, inclusiveEnd: true }), RangeError);
    121 
    122 // bigint
    123 Iterator.range(0n, 10n);
    124 Iterator.range(0n, 10n, 2n);
    125 
    126 const bigintResult1 = Array.from(Iterator.range(0n, 5n));
    127 assertDeepEq(bigintResult1, [0n, 1n, 2n, 3n, 4n]);
    128 
    129 const bigintResult2 = Array.from(Iterator.range(0n, 10n, 2n));
    130 assertDeepEq(bigintResult2, [0n, 2n, 4n, 6n, 8n]);
    131 
    132 // inclusive end with BigInt
    133 const bigintResult3 = Array.from(Iterator.range(0n, 5n, { step: 2n, inclusiveEnd: true }));
    134 assertDeepEq(bigintResult3, [0n, 2n, 4n]);
    135 
    136 // empty BigInt range
    137 const bigintResult4 = Array.from(Iterator.range(0n, 0n));
    138 assertDeepEq(bigintResult4, []);
    139 
    140 // negative step with BigInt
    141 const bigintResult5 = Array.from(Iterator.range(5n, 0n, -1n));
    142 assertDeepEq(bigintResult5, [5n, 4n, 3n, 2n, 1n]);
    143 
    144 
    145 // test invalid this
    146 const invalidValues = [
    147    null,
    148    undefined,
    149    42,
    150    'string',
    151    true,
    152    {},
    153    Symbol('test'),
    154    [],
    155    new Date()
    156 ];
    157 
    158 const iterator = Iterator.range(0, 10);
    159 
    160 invalidValues.forEach(value => {
    161    assertThrowsInstanceOf(() => {
    162        iterator.next.call(value);
    163    }, TypeError, `Should throw TypeError for ${typeof value}`);
    164 });
    165 
    166 // this value is a valid iterator object from another compartment
    167 const g = newGlobal({ newCompartment: true });
    168 const localIterator = Iterator.range(0, 10);
    169 const otherIterator = g.eval("Iterator.range(0, 10)");
    170 
    171 const result = localIterator.next.call(otherIterator);
    172 
    173 assertEq(typeof result, 'object');
    174 assertEq(result.value, 0);
    175 assertEq(result.done, false);
    176 
    177 // infinite tests for iterator sequences
    178 const infiniteRange = Iterator.range(0, Infinity);
    179 assertEq(typeof infiniteRange.next, 'function');
    180 
    181 const first = infiniteRange.next();
    182 assertEq(first.value, 0);
    183 assertEq(infiniteRange.next().value, 1);
    184 assertEq(first.done, false);
    185 
    186 // negative infinity
    187 const negativeInfiniteRange = Iterator.range(0, -Infinity, -1);
    188 assertEq(negativeInfiniteRange.next().value, 0);
    189 assertEq(negativeInfiniteRange.next().value, -1);
    190 assertEq(negativeInfiniteRange.next().value, -2);
    191 
    192 // steps
    193 const stepRange = Iterator.range(0, Infinity, 2);
    194 assertEq(stepRange.next().value, 0);
    195 assertEq(stepRange.next().value, 2);
    196 assertEq(stepRange.next().value, 4);
    197 
    198 // test with an option object
    199 const options = Iterator.range(0, Infinity, { step: 3 });
    200 assertEq(options.next().value, 0);
    201 assertEq(options.next().value, 3);
    202 assertEq(options.next().value, 6);
    203 
    204 // test that inclusive end is ignored for infinite ranges
    205 const infiniteRangeInclusive = Iterator.range(0, Infinity, { inclusiveEnd: true });
    206 assertEq(infiniteRangeInclusive.next().value, 0);
    207 assertEq(infiniteRangeInclusive.next().value, 1);
    208 
    209 // test negative infinity with inclusive end
    210 const negativeInfiniteRangeInclusive = Iterator.range(0, -Infinity, -1, { inclusiveEnd: true });
    211 assertEq(negativeInfiniteRangeInclusive.next().value, 0);
    212 assertEq(negativeInfiniteRangeInclusive.next().value, -1);
    213 assertEq(negativeInfiniteRangeInclusive.next().value, -2);
    214 
    215 // test negative infinity with step and inclusive end
    216 const negativeInfiniteRangeStepInclusive = Iterator.range(0, -Infinity, -2, { inclusiveEnd: true });
    217 assertEq(negativeInfiniteRangeStepInclusive.next().value, 0);
    218 assertEq(negativeInfiniteRangeStepInclusive.next().value, -2);
    219 
    220 // bigint and infinite range
    221 assertThrowsInstanceOf(() => Iterator.range(0n, Infinity), TypeError);
    222 assertThrowsInstanceOf(() => Iterator.range(0n, -Infinity), TypeError);
    223 assertThrowsInstanceOf(() => Iterator.range(0, Infinity, 2n), TypeError);
    224 assertThrowsInstanceOf(() => Iterator.range(0, 10, Infinity), RangeError);
    225 
    226 
    227 if (typeof reportCompare === 'function')
    228    reportCompare(0, 0);