/** * @typedef {import("../../ecma/AnyankaKeys.ecma.js") AnyankaKeys} AnyankaKeys */ /** * @constructor * @returns {void} * @access public */ const AnyankaKeysTestsEncode = function(){ /** @type {AnyankaKeysTestsEncode} */ const self = this; /** * @returns {void} * @access private */ const constructor = () => {}; constructor(); }; /** * @param {!string} mode * @param {!Array.} array * @param {!Array.} encoded * @param {!Array.} decoded * @param {boolean} ok * @returns {void} * @access public * @static */ AnyankaKeysTestsEncode.prototype.show_results = (mode, array, encoded, decoded, ok) => { switch(mode){ case "array_named": console.log(["array", ...array]); console.log(["encoded", ...encoded]); console.log(["decoded", ...decoded]); break; case "array": console.log(array); console.log(encoded); console.log(decoded); break; case "only_errors": console.log(ok); if(!ok){ console.log(array); console.log(encoded); console.log(decoded); }; break; }; }; /** * @param {!(Object.|Array.>)} inputs * @returns {Array., Array., boolean>} * @access public * @static */ AnyankaKeysTestsEncode.prototype.get_parameters = inputs => { /** @type {number} */ const items = AnyankaKeys.prototype.get_value("items", inputs || (inputs = {}), 10) - 1, /** @type {Array.} */ base = AnyankaKeys.prototype.get_value("base", inputs, [256, 58]), /** @type {Array.} */ array = inputs.array || (new Array((Math.random() * items >> 0) + 1)).fill(0).map((value, i) => { while(!(value = Math.random() * base[0] >> 0) && !i); return value; }), /** @type {boolean} */ show_mode = AnyankaKeys.prototype.get_value(["show_mode", "show"], inputs, "only_errors"); return [base, array, show_mode]; }; /** * @param {!(Object.|Array.>)} [inputs] * @returns {boolean} * @access public */ AnyankaKeysTestsEncode.prototype.check = inputs => { /** @type {Array., Array., boolean>} */ const [base, array, show_mode] = AnyankaKeysTestsEncode.prototype.get_parameters(inputs), /** @type {Array.} */ encoded = AnyankaKeys.prototype.encode(array, {base : base})[0], /** @type {Array.} */ decoded = AnyankaKeys.prototype.encode(encoded, {base : base.reverse()})[0], /** @type {boolean} */ ok = array.every((value, i) => decoded[i] == value); AnyankaKeysTestsEncode.prototype.show_results(show_mode, array, encoded, decoded, ok); return ok; }; /** * @callback anyanka_keys_test_encode_asynchronous_callback * @param {boolean} ok * @returns {void} */ /** * @param {!(Object.|Array.>)} inputs * @param {!anyanka_keys_test_encode_asynchronous_callback} callback * @returns {void} * @access public * @static */ AnyankaKeysTestsEncode.prototype.check_asynchronous = (inputs, callback) => { /** @type {Array., Array., boolean>} */ const [base, array, show_mode] = AnyankaKeysTestsEncode.prototype.get_parameters(inputs); AnyankaKeys.prototype.encode(array, { base : base, synchronous : false, set : (_, data, ended) => { if(!ended) return; /** @type {Array.} */ const encoded = data.results; AnyankaKeys.prototype.encode(encoded, { base : base.reverse(), synchronous : false, set : (_, data, ended) => { if(!ended) return; /** @type {Array.} */ const decoded = data.results, /** @type {boolean} */ ok = array.every((value, i) => decoded[i] == value); AnyankaKeysTestsEncode.prototype.show_results(show_mode, array, encoded, decoded, ok); AnyankaKeys.prototype.execute(callback, ok); } }); } }); }; /** * @param {!(number|Object.|Array.>)} [inputs = 100] * @returns {void} * @access public */ AnyankaKeysTestsEncode.prototype.check_bucle = (inputs = 100) => { if(typeof inputs == "number") inputs = {iterations : inputs}; else if(!AnyankaKeys.prototype.is_object(inputs)) inputs = {}; /** @type {number} */ let i = 0, /** @type {boolean} */ has_error = false; /** @type {number} */ const iterations = AnyankaKeys.prototype.get_value("iterations", inputs, 100), /** @type {boolean} */ retry_ok = AnyankaKeys.prototype.get_value("retry_ok", inputs, true), /** @type {number} */ timer = AnyankaKeys.prototype.get_value(["timer", "timeout"], inputs, 500); /** @type {number} */ const interval = setInterval(() => { if(++ i == iterations){ if(has_error || !retry_ok){ clearInterval(interval); return; }else i = 0; }; !AnyankaKeysTestsEncode.prototype.check(inputs) && !has_error && (has_error = true); }, timer); }; /** * @constructor * @param {!(Object.|Array.>)} inputs * @param {!(Object.)} [extra = {}] * @returns {void} * @access public */ const AnyankaKeysTestsEncodeBucleData = function(inputs, extra = {}){ /** @type {AnyankaKeysTestsEncodeBucleData} */ const self = this; /** @type {number} */ this.iterations = 100; /** @type {boolean} */ this.retry_ok = true; /** @type {number} */ this.timer = 100; /** @type {number} */ this.i = 0; /** @type {boolean} */ this.has_error = false; /** @type {Object.} */ this.inputs = {}; /** * @returns {void} * @access private */ const constructor = () => { self.inputs = {...AnyankaKeys.prototype.get_dictionary( typeof inputs == "number" ? {iterations : inputs} : inputs), ...extra}; self.iterations = AnyankaKeys.prototype.get_value("iterations", self.inputs, self.iterations); self.retry_ok = AnyankaKeys.prototype.get_value("retry_ok", self.inputs, self.retry_ok); self.timer = AnyankaKeys.prototype.get_value(["timer", "timeout"], self.inputs, self.timer); }; constructor(); }; /** * @param {!(AnyankaKeysTestsEncodeBucleData|number|Object.|Array.>)} [inputs = 100] * @returns {void} * @access public */ AnyankaKeysTestsEncode.prototype.check_asynchronous_bucle = (data = 100) => { (!data || !(data instanceof AnyankaKeysTestsEncodeBucleData)) && (data = new AnyankaKeysTestsEncodeBucleData(data, {synchronous : false})); if(++ data.i < data.iterations){ AnyankaKeysTestsEncode.prototype.check_asynchronous(data.inputs, ok => { ok || data.has_error || (data.has_error = true); AnyankaKeysTestsEncode.prototype.check_asynchronous_bucle(data); }); }else if(!data.has_error && data.retry_ok){ data.i = 0; AnyankaKeysTestsEncode.prototype.check_asynchronous_bucle(data); }; };