Skip to content

Commit

Permalink
Run prettier.
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamn committed Sep 28, 2023
1 parent 1b4aad3 commit dad8607
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 33 deletions.
35 changes: 14 additions & 21 deletions src/utilities/common/__tests__/canonicalStringify.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import {
canonicalStringify,
lookupSortedKeys,
} from "../canonicalStringify";
import { canonicalStringify, lookupSortedKeys } from "../canonicalStringify";

function forEachPermutation(
keys: string[],
callback: (permutation: string[]) => void,
callback: (permutation: string[]) => void
) {
if (keys.length <= 1) {
callback(keys);
Expand All @@ -15,22 +12,17 @@ function forEachPermutation(
const rest = keys.slice(1);
forEachPermutation(rest, (permutation) => {
for (let i = 0; i <= permutation.length; ++i) {
callback([
...permutation.slice(0, i),
first,
...permutation.slice(i),
]);
callback([...permutation.slice(0, i), first, ...permutation.slice(i)]);
}
});
}

function allObjectPermutations<T extends Record<string, any>>(obj: T) {
const keys = Object.keys(obj);
const permutations: T[] = [];
forEachPermutation(keys, permutation => {
const permutationObj =
Object.create(Object.getPrototypeOf(obj));
permutation.forEach(key => {
forEachPermutation(keys, (permutation) => {
const permutationObj = Object.create(Object.getPrototypeOf(obj));
permutation.forEach((key) => {
permutationObj[key] = obj[key];
});
permutations.push(permutationObj);
Expand Down Expand Up @@ -72,7 +64,7 @@ describe("canonicalStringify", () => {
c: 3,
a: 1,
b: 2,
}).forEach(obj => {
}).forEach((obj) => {
unstableStrings.add(JSON.stringify(obj));
stableStrings.add(canonicalStringify(obj));

Expand All @@ -82,9 +74,9 @@ describe("canonicalStringify", () => {
z: "z",
y: ["y", obj, "why"],
x: "x",
}).forEach(parent => {
}).forEach((parent) => {
expect(canonicalStringify(parent)).toBe(
'{"x":"x","y":["y",{"a":1,"b":2,"c":3},"why"],"z":"z"}',
'{"x":"x","y":["y",{"a":1,"b":2,"c":3},"why"],"z":"z"}'
);
});
});
Expand All @@ -97,7 +89,7 @@ describe("canonicalStringify", () => {
const keys = ["z", "a", "c", "b"];
const sorted = lookupSortedKeys(["z", "a", "b", "c"], false);
expect(sorted).toEqual(["a", "b", "c", "z"]);
forEachPermutation(keys, permutation => {
forEachPermutation(keys, (permutation) => {
expect(lookupSortedKeys(permutation, false)).toBe(sorted);
});
});
Expand All @@ -107,15 +99,16 @@ describe("canonicalStringify", () => {
const sorted = lookupSortedKeys(keys, true);
expect(sorted).toBe(keys);

forEachPermutation(keys, permutation => {
forEachPermutation(keys, (permutation) => {
const sortedTrue = lookupSortedKeys(permutation, true);
const sortedFalse = lookupSortedKeys(permutation, false);

expect(sortedTrue).toEqual(sorted);
expect(sortedFalse).toEqual(sorted);

const wasPermutationSorted =
permutation.every((key, i) => key === keys[i]);
const wasPermutationSorted = permutation.every(
(key, i) => key === keys[i]
);

if (wasPermutationSorted) {
expect(sortedTrue).toBe(permutation);
Expand Down
26 changes: 14 additions & 12 deletions src/utilities/common/canonicalStringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,16 @@ type SortingTrie = Map<string, SortingTrie> & {
// The contents of the Map represent the next level(s) of the trie, branching
// out for each possible next key.
sorted?: readonly string[];
}
};

const sortingTrieRoot: SortingTrie = new Map;
const sortingTrieRoot: SortingTrie = new Map();

// Sort the given keys using a lookup trie, with an option to return the same
// (===) array in case it was already sorted, so we can avoid always creating a
// new object in the replacer function above.
export function lookupSortedKeys(
keys: readonly string[],
returnKeysIfAlreadySorted: boolean,
returnKeysIfAlreadySorted: boolean
): readonly string[] {
let node = sortingTrieRoot;
let alreadySorted = true;
Expand All @@ -81,17 +81,19 @@ export function lookupSortedKeys(
if (k > 0 && keys[k - 1] > key) {
alreadySorted = false;
}
node = node.get(key) || node.set(key, new Map).get(key)!;
node = node.get(key) || node.set(key, new Map()).get(key)!;
}

if (alreadySorted) {
return node.sorted
// There may already be a node.sorted array that's equivalent to the
// already-sorted keys array, but if keys was already sorted, we want to
// return the keys reference as-is when returnKeysIfAlreadySorted is true.
// This behavior helps us decide whether we need to create a new object in
// the stableObjectReplacer function above.
? (returnKeysIfAlreadySorted ? keys : node.sorted)
? // There may already be a node.sorted array that's equivalent to the
// already-sorted keys array, but if keys was already sorted, we want to
// return the keys reference as-is when returnKeysIfAlreadySorted is true.
// This behavior helps us decide whether we need to create a new object in
// the stableObjectReplacer function above.
returnKeysIfAlreadySorted
? keys
: node.sorted
: (node.sorted = keys);
}

Expand All @@ -109,7 +111,7 @@ export function lookupSortedKeys(
// be stored as the one true array and returned here. Since we are passing in
// an array that is definitely already sorted, this call to lookupSortedKeys
// will never actually have to call .sort(), so this lookup is always linear.
return node.sorted || (
node.sorted = lookupSortedKeys(keys.slice(0).sort(), false)
return (
node.sorted || (node.sorted = lookupSortedKeys(keys.slice(0).sort(), false))
);
}

0 comments on commit dad8607

Please sign in to comment.