All files / src/internal/client/dev equality.js

74.77% Statements 83/111
60% Branches 9/15
71.42% Functions 5/7
74.31% Lines 81/109

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 1102x 2x 2x 2x 4x 4x 4x 4x 4x 4x     4x 4x 4x 4x 634404x 634404x 634404x 308934x 308934x 308934x           308934x 634404x 634404x 4x 4x 4x 39344x 39344x 39344x 39344x 39344x 6x 6x 6x 6x 6x 6x 6x 6x 6x           6x 39344x 39344x 4x 4x 4x 661328x 661328x 661328x 588122x 588122x 588122x           588122x 661328x 661328x 4x 4x 4x 4x       4x 4x 2x 2x 2x 2x 2x 2x 2x 2x 18x     18x 18x 18x 2x 2x 2x 2x 2x 2x 2x 2x              
import * as w from '../warnings.js';
import { get_proxied_value } from '../proxy.js';
 
export function init_array_prototype_warnings() {
	const array_prototype = Array.prototype;
	// The REPL ends up here over and over, and this prevents it from adding more and more patches
	// of the same kind to the prototype, which would slow down everything over time.
	// @ts-expect-error
	const cleanup = Array.__svelte_cleanup;
	if (cleanup) {
		cleanup();
	}
 
	const { indexOf, lastIndexOf, includes } = array_prototype;
 
	array_prototype.indexOf = function (item, from_index) {
		const index = indexOf.call(this, item, from_index);
 
		if (index === -1) {
			const test = indexOf.call(get_proxied_value(this), get_proxied_value(item), from_index);
 
			if (test !== -1) {
				w.state_proxy_equality_mismatch(
					'array.indexOf(...)',
					': `array.findIndex(entry => $state.is(entry, item))`'
				);
			}
		}
 
		return index;
	};
 
	array_prototype.lastIndexOf = function (item, from_index) {
		// we need to specify this.length - 1 because it's probably using something like
		// `arguments` inside so passing undefined is different from not passing anything
		const index = lastIndexOf.call(this, item, from_index ?? this.length - 1);
 
		if (index === -1) {
			// we need to specify this.length - 1 because it's probably using something like
			// `arguments` inside so passing undefined is different from not passing anything
			const test = lastIndexOf.call(
				get_proxied_value(this),
				get_proxied_value(item),
				from_index ?? this.length - 1
			);
 
			if (test !== -1) {
				w.state_proxy_equality_mismatch(
					'array.lastIndexOf(...)',
					': `array.findLastIndex(entry => $state.is(entry, item))`'
				);
			}
		}
 
		return index;
	};
 
	array_prototype.includes = function (item, from_index) {
		const has = includes.call(this, item, from_index);
 
		if (!has) {
			const test = includes.call(get_proxied_value(this), get_proxied_value(item), from_index);
 
			if (test) {
				w.state_proxy_equality_mismatch(
					'array.includes(...)',
					': `array.some(entry => $state.is(entry, item))`'
				);
			}
		}
 
		return has;
	};
 
	// @ts-expect-error
	Array.__svelte_cleanup = () => {
		array_prototype.indexOf = indexOf;
		array_prototype.lastIndexOf = lastIndexOf;
		array_prototype.includes = includes;
	};
}
 
/**
 * @param {any} a
 * @param {any} b
 * @param {boolean} equal
 * @returns {boolean}
 */
export function strict_equals(a, b, equal = true) {
	if ((a === b) !== (get_proxied_value(a) === get_proxied_value(b))) {
		w.state_proxy_equality_mismatch(equal ? '===' : '!==', '');
	}
 
	return (a === b) === equal;
}
 
/**
 * @param {any} a
 * @param {any} b
 * @param {boolean} equal
 * @returns {boolean}
 */
export function equals(a, b, equal = true) {
	if ((a == b) !== (get_proxied_value(a) == get_proxied_value(b))) {
		w.state_proxy_equality_mismatch(equal ? '==' : '!=', '');
	}

	return (a == b) === equal;
}