Last active
December 19, 2019 10:11
-
-
Save Jerska/11bd6a8e7c19521ffa20afc65e21b96c to your computer and use it in GitHub Desktop.
Stable JSON stringify
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Make sure JSON keys are always in the same order, to allow for easy comparison | |
// This uses JSON.stringify's replacer twice: | |
// - once to get the list of keys, including of nested children | |
// - once in its lesser known form: as a array of keys | |
// this filters keys to only ones in the list - (we don't use this feature) | |
// but also sorts them, and this is why this is useful to us | |
export function stableJSONStringify(obj: any) { | |
const allKeys: string[] = []; | |
// Use the replacer function to get the keys | |
JSON.stringify(obj, (k, v) => { | |
if (k !== '') allKeys.push(k); | |
return v; | |
}); | |
// Sorted and unique list of keys | |
const uniqueKeys = allKeys.filter((k, i) => allKeys.indexOf(k) === i); | |
const sortedKeys = uniqueKeys.sort(); | |
// Use the "filter" behavior (that also sorts keys in the order provided) | |
// of the replacer parameter of JSON.stringify to ensure a stable stringification | |
return JSON.stringify(obj, sortedKeys); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { stableJSONStringify } from './stableJSONStringify'; | |
// Numbers are used as values and are used to represent the order they should be showing up in the output | |
describe('stableJSONStringify', () => { | |
it('should sort keys', () => { | |
const obj = { | |
b: 2, | |
a: 1, | |
}; | |
expect(stableJSONStringify(obj)).toMatchSnapshot(); | |
}); | |
it('should sort nested keys', () => { | |
const obj = { | |
b: 3, | |
a: { | |
d: 2, | |
c: 1, | |
}, | |
}; | |
expect(stableJSONStringify(obj)).toMatchSnapshot(); | |
}); | |
it('should sort nested keys in an array', () => { | |
const obj = { | |
b: 3, | |
a: [ | |
{ | |
d: 2, | |
c: 1, | |
}, | |
], | |
}; | |
expect(stableJSONStringify(obj)).toMatchSnapshot(); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Jest Snapshot v1, https://goo.gl/fbAQLP | |
exports[`stableJSONStringify should sort keys 1`] = `"{\\"a\\":1,\\"b\\":2}"`; | |
exports[`stableJSONStringify should sort nested keys 1`] = `"{\\"a\\":{\\"c\\":1,\\"d\\":2},\\"b\\":3}"`; | |
exports[`stableJSONStringify should sort nested keys in an array 1`] = `"{\\"a\\":[{\\"c\\":1,\\"d\\":2}],\\"b\\":3}"`; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment