11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_cirequire('../common');
31cb0ef41Sopenharmony_ciconst assert = require('assert');
41cb0ef41Sopenharmony_ciconst { Writable } = require('stream');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci// Test interaction between calling .destroy() on a writable and pending
71cb0ef41Sopenharmony_ci// writes.
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cifor (const withPendingData of [ false, true ]) {
101cb0ef41Sopenharmony_ci  for (const useEnd of [ false, true ]) {
111cb0ef41Sopenharmony_ci    const callbacks = [];
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci    const w = new Writable({
141cb0ef41Sopenharmony_ci      write(data, enc, cb) {
151cb0ef41Sopenharmony_ci        callbacks.push(cb);
161cb0ef41Sopenharmony_ci      },
171cb0ef41Sopenharmony_ci      // Effectively disable the HWM to observe 'drain' events more easily.
181cb0ef41Sopenharmony_ci      highWaterMark: 1
191cb0ef41Sopenharmony_ci    });
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci    let chunksWritten = 0;
221cb0ef41Sopenharmony_ci    let drains = 0;
231cb0ef41Sopenharmony_ci    w.on('drain', () => drains++);
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci    function onWrite(err) {
261cb0ef41Sopenharmony_ci      if (err) {
271cb0ef41Sopenharmony_ci        assert.strictEqual(w.destroyed, true);
281cb0ef41Sopenharmony_ci        assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED');
291cb0ef41Sopenharmony_ci      } else {
301cb0ef41Sopenharmony_ci        chunksWritten++;
311cb0ef41Sopenharmony_ci      }
321cb0ef41Sopenharmony_ci    }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci    w.write('abc', onWrite);
351cb0ef41Sopenharmony_ci    assert.strictEqual(chunksWritten, 0);
361cb0ef41Sopenharmony_ci    assert.strictEqual(drains, 0);
371cb0ef41Sopenharmony_ci    callbacks.shift()();
381cb0ef41Sopenharmony_ci    assert.strictEqual(chunksWritten, 1);
391cb0ef41Sopenharmony_ci    assert.strictEqual(drains, 1);
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci    if (withPendingData) {
421cb0ef41Sopenharmony_ci      // Test 2 cases: There either is or is not data still in the write queue.
431cb0ef41Sopenharmony_ci      // (The second write will never actually get executed either way.)
441cb0ef41Sopenharmony_ci      w.write('def', onWrite);
451cb0ef41Sopenharmony_ci    }
461cb0ef41Sopenharmony_ci    if (useEnd) {
471cb0ef41Sopenharmony_ci      // Again, test 2 cases: Either we indicate that we want to end the
481cb0ef41Sopenharmony_ci      // writable or not.
491cb0ef41Sopenharmony_ci      w.end('ghi', onWrite);
501cb0ef41Sopenharmony_ci    } else {
511cb0ef41Sopenharmony_ci      w.write('ghi', onWrite);
521cb0ef41Sopenharmony_ci    }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci    assert.strictEqual(chunksWritten, 1);
551cb0ef41Sopenharmony_ci    w.destroy();
561cb0ef41Sopenharmony_ci    assert.strictEqual(chunksWritten, 1);
571cb0ef41Sopenharmony_ci    callbacks.shift()();
581cb0ef41Sopenharmony_ci    assert.strictEqual(chunksWritten, useEnd && !withPendingData ? 1 : 2);
591cb0ef41Sopenharmony_ci    assert.strictEqual(callbacks.length, 0);
601cb0ef41Sopenharmony_ci    assert.strictEqual(drains, 1);
611cb0ef41Sopenharmony_ci  }
621cb0ef41Sopenharmony_ci}
63