11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ciconst dc = require('diagnostics_channel'); 61cb0ef41Sopenharmony_ciconst { AsyncLocalStorage } = require('async_hooks'); 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_cilet n = 0; 91cb0ef41Sopenharmony_ciconst thisArg = new Date(); 101cb0ef41Sopenharmony_ciconst inputs = [ 111cb0ef41Sopenharmony_ci { foo: 'bar' }, 121cb0ef41Sopenharmony_ci { baz: 'buz' }, 131cb0ef41Sopenharmony_ci]; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciconst channel = dc.channel('test'); 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci// Bind a storage directly to published data 181cb0ef41Sopenharmony_ciconst store1 = new AsyncLocalStorage(); 191cb0ef41Sopenharmony_cichannel.bindStore(store1); 201cb0ef41Sopenharmony_cilet store1bound = true; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci// Bind a store with transformation of published data 231cb0ef41Sopenharmony_ciconst store2 = new AsyncLocalStorage(); 241cb0ef41Sopenharmony_cichannel.bindStore(store2, common.mustCall((data) => { 251cb0ef41Sopenharmony_ci assert.strictEqual(data, inputs[n]); 261cb0ef41Sopenharmony_ci return { data }; 271cb0ef41Sopenharmony_ci}, 4)); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci// Regular subscribers should see publishes from runStores calls 301cb0ef41Sopenharmony_cichannel.subscribe(common.mustCall((data) => { 311cb0ef41Sopenharmony_ci if (store1bound) { 321cb0ef41Sopenharmony_ci assert.deepStrictEqual(data, store1.getStore()); 331cb0ef41Sopenharmony_ci } 341cb0ef41Sopenharmony_ci assert.deepStrictEqual({ data }, store2.getStore()); 351cb0ef41Sopenharmony_ci assert.strictEqual(data, inputs[n]); 361cb0ef41Sopenharmony_ci}, 4)); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci// Verify stores are empty before run 391cb0ef41Sopenharmony_ciassert.strictEqual(store1.getStore(), undefined); 401cb0ef41Sopenharmony_ciassert.strictEqual(store2.getStore(), undefined); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_cichannel.runStores(inputs[n], common.mustCall(function(a, b) { 431cb0ef41Sopenharmony_ci // Verify this and argument forwarding 441cb0ef41Sopenharmony_ci assert.strictEqual(this, thisArg); 451cb0ef41Sopenharmony_ci assert.strictEqual(a, 1); 461cb0ef41Sopenharmony_ci assert.strictEqual(b, 2); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci // Verify store 1 state matches input 491cb0ef41Sopenharmony_ci assert.strictEqual(store1.getStore(), inputs[n]); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci // Verify store 2 state has expected transformation 521cb0ef41Sopenharmony_ci assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // Should support nested contexts 551cb0ef41Sopenharmony_ci n++; 561cb0ef41Sopenharmony_ci channel.runStores(inputs[n], common.mustCall(function() { 571cb0ef41Sopenharmony_ci // Verify this and argument forwarding 581cb0ef41Sopenharmony_ci assert.strictEqual(this, undefined); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // Verify store 1 state matches input 611cb0ef41Sopenharmony_ci assert.strictEqual(store1.getStore(), inputs[n]); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci // Verify store 2 state has expected transformation 641cb0ef41Sopenharmony_ci assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); 651cb0ef41Sopenharmony_ci })); 661cb0ef41Sopenharmony_ci n--; 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci // Verify store 1 state matches input 691cb0ef41Sopenharmony_ci assert.strictEqual(store1.getStore(), inputs[n]); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci // Verify store 2 state has expected transformation 721cb0ef41Sopenharmony_ci assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); 731cb0ef41Sopenharmony_ci}), thisArg, 1, 2); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci// Verify stores are empty after run 761cb0ef41Sopenharmony_ciassert.strictEqual(store1.getStore(), undefined); 771cb0ef41Sopenharmony_ciassert.strictEqual(store2.getStore(), undefined); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci// Verify unbinding works 801cb0ef41Sopenharmony_ciassert.ok(channel.unbindStore(store1)); 811cb0ef41Sopenharmony_cistore1bound = false; 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci// Verify unbinding a store that is not bound returns false 841cb0ef41Sopenharmony_ciassert.ok(!channel.unbindStore(store1)); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_cin++; 871cb0ef41Sopenharmony_cichannel.runStores(inputs[n], common.mustCall(() => { 881cb0ef41Sopenharmony_ci // Verify after unbinding store 1 will remain undefined 891cb0ef41Sopenharmony_ci assert.strictEqual(store1.getStore(), undefined); 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci // Verify still bound store 2 receives expected data 921cb0ef41Sopenharmony_ci assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); 931cb0ef41Sopenharmony_ci})); 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci// Contain transformer errors and emit on next tick 961cb0ef41Sopenharmony_ciconst fail = new Error('fail'); 971cb0ef41Sopenharmony_cichannel.bindStore(store1, () => { 981cb0ef41Sopenharmony_ci throw fail; 991cb0ef41Sopenharmony_ci}); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_cilet calledRunStores = false; 1021cb0ef41Sopenharmony_ciprocess.once('uncaughtException', common.mustCall((err) => { 1031cb0ef41Sopenharmony_ci assert.strictEqual(calledRunStores, true); 1041cb0ef41Sopenharmony_ci assert.strictEqual(err, fail); 1051cb0ef41Sopenharmony_ci})); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_cichannel.runStores(inputs[n], common.mustCall()); 1081cb0ef41Sopenharmony_cicalledRunStores = true; 109