1// Flags: --no-warnings --expose-internals --experimental-abortcontroller 2'use strict'; 3 4const common = require('../common'); 5const { inspect } = require('util'); 6 7const { ok, strictEqual, throws } = require('assert'); 8const { Event } = require('internal/event_target'); 9 10{ 11 // Tests that abort is fired with the correct event type on AbortControllers 12 const ac = new AbortController(); 13 ok(ac.signal); 14 ac.signal.onabort = common.mustCall((event) => { 15 ok(event); 16 strictEqual(event.type, 'abort'); 17 }); 18 ac.signal.addEventListener('abort', common.mustCall((event) => { 19 ok(event); 20 strictEqual(event.type, 'abort'); 21 }), { once: true }); 22 ac.abort(); 23 ac.abort(); 24 ok(ac.signal.aborted); 25} 26 27{ 28 // Tests that abort events are trusted 29 const ac = new AbortController(); 30 ac.signal.addEventListener('abort', common.mustCall((event) => { 31 ok(event.isTrusted); 32 })); 33 ac.abort(); 34} 35 36{ 37 // Tests that abort events have the same `isTrusted` reference 38 const first = new AbortController(); 39 const second = new AbortController(); 40 let ev1, ev2; 41 const ev3 = new Event('abort'); 42 first.signal.addEventListener('abort', common.mustCall((event) => { 43 ev1 = event; 44 })); 45 second.signal.addEventListener('abort', common.mustCall((event) => { 46 ev2 = event; 47 })); 48 first.abort(); 49 second.abort(); 50 const firstTrusted = Reflect.getOwnPropertyDescriptor(ev1, 'isTrusted').get; 51 const secondTrusted = Reflect.getOwnPropertyDescriptor(ev2, 'isTrusted').get; 52 const untrusted = Reflect.getOwnPropertyDescriptor(ev3, 'isTrusted').get; 53 strictEqual(firstTrusted, secondTrusted); 54 strictEqual(untrusted, firstTrusted); 55} 56 57{ 58 // Tests that AbortSignal is impossible to construct manually 59 const ac = new AbortController(); 60 throws( 61 () => new ac.signal.constructor(), 62 /^TypeError: Illegal constructor$/ 63 ); 64} 65{ 66 // Symbol.toStringTag 67 const toString = (o) => Object.prototype.toString.call(o); 68 const ac = new AbortController(); 69 strictEqual(toString(ac), '[object AbortController]'); 70 strictEqual(toString(ac.signal), '[object AbortSignal]'); 71} 72 73{ 74 const signal = AbortSignal.abort(); 75 ok(signal.aborted); 76} 77 78{ 79 // Test that AbortController properties and methods validate the receiver 80 const acSignalGet = Object.getOwnPropertyDescriptor( 81 AbortController.prototype, 82 'signal' 83 ).get; 84 const acAbort = AbortController.prototype.abort; 85 86 const goodController = new AbortController(); 87 ok(acSignalGet.call(goodController)); 88 acAbort.call(goodController); 89 90 const badAbortControllers = [ 91 null, 92 undefined, 93 0, 94 NaN, 95 true, 96 'AbortController', 97 Object.create(AbortController.prototype), 98 ]; 99 for (const badController of badAbortControllers) { 100 throws( 101 () => acSignalGet.call(badController), 102 { code: 'ERR_INVALID_THIS', name: 'TypeError' } 103 ); 104 throws( 105 () => acAbort.call(badController), 106 { code: 'ERR_INVALID_THIS', name: 'TypeError' } 107 ); 108 } 109} 110 111{ 112 // Test that AbortSignal properties validate the receiver 113 const signalAbortedGet = Object.getOwnPropertyDescriptor( 114 AbortSignal.prototype, 115 'aborted' 116 ).get; 117 118 const goodSignal = new AbortController().signal; 119 strictEqual(signalAbortedGet.call(goodSignal), false); 120 121 const badAbortSignals = [ 122 null, 123 undefined, 124 0, 125 NaN, 126 true, 127 'AbortSignal', 128 Object.create(AbortSignal.prototype), 129 ]; 130 for (const badSignal of badAbortSignals) { 131 throws( 132 () => signalAbortedGet.call(badSignal), 133 { code: 'ERR_INVALID_THIS', name: 'TypeError' } 134 ); 135 } 136} 137 138{ 139 const ac = new AbortController(); 140 strictEqual(inspect(ac, { depth: 1 }), 141 'AbortController { signal: [AbortSignal] }'); 142 strictEqual(inspect(ac, { depth: null }), 143 'AbortController { signal: AbortSignal { aborted: false } }'); 144} 145