summaryrefslogtreecommitdiff
path: root/ui/lib/swatch
diff options
context:
space:
mode:
Diffstat (limited to 'ui/lib/swatch')
-rw-r--r--ui/lib/swatch/derive.js6
-rw-r--r--ui/lib/swatch/json.js7
-rw-r--r--ui/lib/swatch/json.test.js36
-rw-r--r--ui/lib/swatch/setup.js0
4 files changed, 44 insertions, 5 deletions
diff --git a/ui/lib/swatch/derive.js b/ui/lib/swatch/derive.js
index 85547e8..22ceb13 100644
--- a/ui/lib/swatch/derive.js
+++ b/ui/lib/swatch/derive.js
@@ -5,16 +5,12 @@ function tryDerive(args, func, fallback) {
try {
return func(...args);
} catch (e) {
- console.debug('deriver threw exception', e, func, args);
return fallback;
}
}
// A "deriver" is a function that never raises; if the underlying function would raise, the
// corresponding deriver instead returns a fallback value (or `undefined`).
-export function makeDeriver(func, fallback) {
+export function makeDeriver(func, fallback = undefined) {
return (...args) => tryDerive(args, func, fallback);
}
-
-// Some widely-used derivers, for convenience.
-export const json = makeDeriver(JSON.parse);
diff --git a/ui/lib/swatch/json.js b/ui/lib/swatch/json.js
new file mode 100644
index 0000000..3ebbc0d
--- /dev/null
+++ b/ui/lib/swatch/json.js
@@ -0,0 +1,7 @@
+import { makeDeriver } from '$lib/swatch/derive.js';
+
+export const decode = makeDeriver(JSON.parse);
+
+export function encode(value) {
+ return JSON.stringify(value, /* replacer */ null, /* space */ 2);
+}
diff --git a/ui/lib/swatch/json.test.js b/ui/lib/swatch/json.test.js
new file mode 100644
index 0000000..e01017d
--- /dev/null
+++ b/ui/lib/swatch/json.test.js
@@ -0,0 +1,36 @@
+import * as json from './json.js';
+import { expect, describe, it } from 'vitest';
+
+describe('encode', async () => {
+ it('converts atoms', async () => {
+ expect(json.encode(0)).toStrictEqual('0');
+ expect(json.encode('hello')).toStrictEqual('"hello"');
+ expect(json.encode(null)).toStrictEqual('null');
+ expect(json.encode(true)).toStrictEqual('true');
+ });
+
+ it('converts lists with indentation', async () => {
+ expect(json.encode([])).toStrictEqual('[]');
+ expect(json.encode(['hello', 'world'])).toStrictEqual('[\n "hello",\n "world"\n]');
+ });
+
+ it('converts objects with indentation', async () => {
+ expect(json.encode({})).toStrictEqual('{}');
+ expect(json.encode({ field: 'value' })).toStrictEqual('{\n "field": "value"\n}');
+ });
+});
+
+describe('decode', async () => {
+ it('converts valid json values', async () => {
+ expect(json.decode('0')).toStrictEqual(0);
+ expect(json.decode('null')).toStrictEqual(null);
+ expect(json.decode('{}')).toStrictEqual({});
+ expect(json.decode('[1, 2, "3"]')).toStrictEqual([1, 2, '3']);
+ });
+
+ it('converts invalid json to `undefined`', async () => {
+ expect(json.decode('')).toBeUndefined();
+ expect(json.decode('{"foo":')).toBeUndefined();
+ expect(json.decode('arbitrary nonsense')).toBeUndefined();
+ });
+});
diff --git a/ui/lib/swatch/setup.js b/ui/lib/swatch/setup.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ui/lib/swatch/setup.js