From e4eea189d168fb80000ca722630334c018f6fd04 Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Thu, 26 Oct 2023 11:44:27 +0200 Subject: [PATCH 1/6] fix: dataview list format is now correct fix: add tests for result class and helpers --- package-lock.json | 16 +++++++-- package.json | 7 ++-- src/FormModal.ts | 10 +++--- src/core/FormResult.test.ts | 64 ++++++++++++++++++++++++++++++++++ src/{ => core}/FormResult.ts | 21 +++++++++-- src/core/__mocks__/obsidian.ts | 4 +++ 6 files changed, 108 insertions(+), 14 deletions(-) create mode 100644 src/core/FormResult.test.ts rename src/{ => core}/FormResult.ts (75%) create mode 100644 src/core/__mocks__/obsidian.ts diff --git a/package-lock.json b/package-lock.json index 6b4edb09..63bea503 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "obsidian-modal-form", - "version": "1.20.0", + "version": "1.21.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "obsidian-modal-form", - "version": "1.20.0", + "version": "1.21.0", "license": "MIT", "dependencies": { "fp-ts": "^2.16.1", @@ -30,7 +30,8 @@ "ts-jest": "^29.1.1", "ts-node": "^10.9.1", "tslib": "2.4.0", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "yaml": "^2.3.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -5891,6 +5892,15 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", + "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index c097ac44..8e63e44e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "npm run check && node esbuild.config.mjs production", "check": "svelte-check --tsconfig tsconfig.json", "test": "jest", - "test-w": "jest --watch", + "test-w": "jest --watch --no-cache", "version": "node version-bump.mjs && git add manifest.json versions.json" }, "keywords": [], @@ -31,11 +31,12 @@ "ts-jest": "^29.1.1", "ts-node": "^10.9.1", "tslib": "2.4.0", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "yaml": "^2.3.3" }, "dependencies": { "fp-ts": "^2.16.1", "fuse.js": "^6.6.2", "valibot": "^0.19.0" } -} \ No newline at end of file +} diff --git a/src/FormModal.ts b/src/FormModal.ts index c898e35b..43a3f056 100644 --- a/src/FormModal.ts +++ b/src/FormModal.ts @@ -1,6 +1,6 @@ import { App, Modal, Platform, Setting } from "obsidian"; import MultiSelect from "./views/components/MultiSelect.svelte"; -import FormResult, { formDataFromFormOptions, type ModalFormData } from "./FormResult"; +import FormResult, { formDataFromFormOptions, type ModalFormData } from "./core/FormResult"; import { exhaustiveGuard } from "./safety"; import { get_tfiles_from_folder } from "./utils/files"; import type { FormDefinition, FormOptions } from "./core/formDefinition"; @@ -39,7 +39,7 @@ export class FormModal extends Modal { fieldBase.setClass('modal-form-textarea') return fieldBase.addTextArea((textEl) => { if (typeof initialValue === 'string') { textEl.setValue(initialValue); } - textEl.onChange(value => { + textEl.onChange((value) => { this.formResult[definition.name] = value; }); textEl.inputEl.rows = 6; @@ -133,7 +133,7 @@ export class FormModal extends Modal { this.formResult[definition.name] = this.formResult[definition.name] || [] const options = fieldInput.source == 'fixed' ? fieldInput.multi_select_options - : get_tfiles_from_folder(fieldInput.folder, this.app).map(file => file.basename); + : get_tfiles_from_folder(fieldInput.folder, this.app).map((file) => file.basename); this.svelteComponents.push(new MultiSelect({ target: fieldBase.controlEl, props: { @@ -205,7 +205,7 @@ export class FormModal extends Modal { return exhaustiveGuard(type); } }); - + const submit = () => { this.onSubmit(new FormResult(this.formResult, "ok")); this.close(); @@ -230,7 +230,7 @@ export class FormModal extends Modal { onClose() { const { contentEl } = this; - this.svelteComponents.forEach(component => component.$destroy()) + this.svelteComponents.forEach((component) => component.$destroy()) contentEl.empty(); this.formResult = {}; } diff --git a/src/core/FormResult.test.ts b/src/core/FormResult.test.ts new file mode 100644 index 00000000..b3d4cd6a --- /dev/null +++ b/src/core/FormResult.test.ts @@ -0,0 +1,64 @@ +jest.mock("obsidian"); +import FormResult, { ModalFormData } from "./FormResult"; + +describe("FormResult", () => { + const formData: ModalFormData = { + name: "John Doe", + age: 30, + hobbies: ["reading", "swimming"], + isEmployed: true, + }; + + describe("constructor", () => { + it("should create a new FormResult instance with the provided data and status", () => { + const result = new FormResult(formData, "ok"); + expect(result).toBeInstanceOf(FormResult); + expect(result.getData()).toEqual(formData); + expect(result.status).toEqual("ok"); + }); + }); + + describe("asFrontmatterString", () => { + it("should return the data as a YAML frontmatter string", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name: John Doe +age: 30 +hobbies: + - reading + - swimming +isEmployed: true +`; + expect(result.asFrontmatterString()).toEqual(expectedOutput); + }); + }); + + describe("asDataviewProperties", () => { + it("should return the data as a string of dataview properties", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name:: John Doe +age:: 30 +hobbies:: "reading","swimming" +isEmployed:: true`; + expect(result.asDataviewProperties()).toEqual(expectedOutput); + }); + }); + + describe("getData", () => { + it("should return a copy of the data contained in the FormResult instance", () => { + const result = new FormResult(formData, "ok"); + const dataCopy = result.getData(); + expect(dataCopy).toEqual(formData); + expect(dataCopy).not.toBe(formData); + }); + }); + + describe("asString", () => { + it("should return the data formatted as a string matching the provided template", () => { + const result = new FormResult(formData, "ok"); + const template = "My name is {{name}}, and I am {{age}} years old."; + const expectedOutput = + "My name is John Doe, and I am 30 years old."; + expect(result.asString(template)).toEqual(expectedOutput); + }); + }); +}); diff --git a/src/FormResult.ts b/src/core/FormResult.ts similarity index 75% rename from src/FormResult.ts rename to src/core/FormResult.ts index fb3fc6e8..69dc55b0 100644 --- a/src/FormResult.ts +++ b/src/core/FormResult.ts @@ -1,6 +1,8 @@ import { stringifyYaml } from "obsidian"; -import { log_error } from "./utils/Log"; -import { ModalFormError } from "./utils/Error"; +import { log_error } from "../utils/Log"; +import { ModalFormError } from "../utils/Error"; +import { object, optional, array, string, coerce } from "valibot"; +import { parse } from "@std"; type ResultStatus = "ok" | "cancelled"; @@ -15,6 +17,17 @@ function isPrimitiveArray(value: unknown): value is string[] { return Array.isArray(value) && value.every(isPrimitive) } +const KeysSchema = array(coerce(string(), String)) + +const PickOmitSchema = object({ + pick: optional(KeysSchema), + omit: optional(KeysSchema), +}); + +console.log(parse(PickOmitSchema, { pick: ['a', 'b'] })) +console.log(parse(PickOmitSchema, { pick: [11], omit: ['a', 'b'] })) +console.log(parse(PickOmitSchema, undefined)) + export function formDataFromFormOptions(values: Record) { const result: ModalFormData = {}; const invalidKeys = [] @@ -44,7 +57,9 @@ export default class FormResult { */ asDataviewProperties(): string { return Object.entries(this.data) - .map(([key, value]) => `${key}:: ${value}`) + .map(([key, value]) => + `${key}:: ${Array.isArray(value) ? value.map((v) => JSON.stringify(v)) : value}` + ) .join("\n"); } /** diff --git a/src/core/__mocks__/obsidian.ts b/src/core/__mocks__/obsidian.ts new file mode 100644 index 00000000..1bd76732 --- /dev/null +++ b/src/core/__mocks__/obsidian.ts @@ -0,0 +1,4 @@ +import { stringify } from 'yaml' +export function stringifyYaml(data: unknown) { + return stringify(data) +} From efc05a47df41a8b6d730909b81d813da493801cc Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Thu, 26 Oct 2023 11:47:45 +0200 Subject: [PATCH 2/6] chore: fix paths --- src/API.ts | 8 ++++---- src/main.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/API.ts b/src/API.ts index 44a28d69..6f95d3fb 100644 --- a/src/API.ts +++ b/src/API.ts @@ -1,7 +1,7 @@ import { App } from "obsidian"; import { MigrationError, type FormDefinition, type FormOptions } from "./core/formDefinition"; -import FormResult from "./FormResult"; +import FormResult from "./core/FormResult"; import { exampleModalDefinition } from "./exampleModalDefinition"; import ModalFormPlugin from "./main"; import { ModalFormError } from "./utils/Error"; @@ -49,9 +49,9 @@ export class API { getFormByName(name: string): FormDefinition | undefined { const form = this.plugin.settings?.formDefinitions.find((form) => form.name === name); if (form instanceof MigrationError) { - log_notice('🚫 The form you tried to load has an invalid format', - `The form "${name}" has an invalid format.`+ - `We tried to automatically convert it but it failed, please fix it manually in the forms manager. + log_notice('🚫 The form you tried to load has an invalid format', + `The form "${name}" has an invalid format.` + + `We tried to automatically convert it but it failed, please fix it manually in the forms manager. `) return undefined; } else { diff --git a/src/main.ts b/src/main.ts index 33c5e949..a2eb00a5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import { Platform, Plugin, WorkspaceLeaf } from "obsidian"; -import FormResult from "src/FormResult"; +import FormResult from "src/core/FormResult"; import { exampleModalDefinition } from "src/exampleModalDefinition"; import { ModalFormSettingTab } from "src/ModalFormSettingTab"; import { API } from "src/API"; From 1c5bd5f09a2525ffcdb9226834730b044a3aee6c Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Thu, 26 Oct 2023 12:59:59 +0200 Subject: [PATCH 3/6] feat: allow pick/omit in Result helpers this also includes the objectSelect utility and it's tests fixes #101 --- package-lock.json | 7 +++++ package.json | 1 + src/core/FormResult.ts | 36 +++++++++++---------- src/core/objectSelect.test.ts | 59 +++++++++++++++++++++++++++++++++++ src/core/objectSelect.ts | 46 +++++++++++++++++++++++++++ src/std/index.ts | 6 ++-- tsconfig.json | 17 ++++++++-- 7 files changed, 151 insertions(+), 21 deletions(-) create mode 100644 src/core/objectSelect.test.ts create mode 100644 src/core/objectSelect.ts diff --git a/package-lock.json b/package-lock.json index 63bea503..f7ea842a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", + "@unsplash/ts-namespace-import-plugin": "^1.0.0", "builtin-modules": "3.3.0", "esbuild": "0.17.3", "esbuild-svelte": "^0.8.0", @@ -2073,6 +2074,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@unsplash/ts-namespace-import-plugin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@unsplash/ts-namespace-import-plugin/-/ts-namespace-import-plugin-1.0.0.tgz", + "integrity": "sha512-Z/fuSAWte/OP1ctpM/8PtecGeBN358yR1rxMiVlTQ3xIvTTFNpjQuZuqkY3XfvWFQ8mvpqumQvS7hG8XnUkTWg==", + "dev": true + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", diff --git a/package.json b/package.json index 8e63e44e..08624fb9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", + "@unsplash/ts-namespace-import-plugin": "^1.0.0", "builtin-modules": "3.3.0", "esbuild": "0.17.3", "esbuild-svelte": "^0.8.0", diff --git a/src/core/FormResult.ts b/src/core/FormResult.ts index 69dc55b0..7cb4d54b 100644 --- a/src/core/FormResult.ts +++ b/src/core/FormResult.ts @@ -1,8 +1,7 @@ +import { objectSelect } from './objectSelect'; import { stringifyYaml } from "obsidian"; import { log_error } from "../utils/Log"; import { ModalFormError } from "../utils/Error"; -import { object, optional, array, string, coerce } from "valibot"; -import { parse } from "@std"; type ResultStatus = "ok" | "cancelled"; @@ -17,16 +16,6 @@ function isPrimitiveArray(value: unknown): value is string[] { return Array.isArray(value) && value.every(isPrimitive) } -const KeysSchema = array(coerce(string(), String)) - -const PickOmitSchema = object({ - pick: optional(KeysSchema), - omit: optional(KeysSchema), -}); - -console.log(parse(PickOmitSchema, { pick: ['a', 'b'] })) -console.log(parse(PickOmitSchema, { pick: [11], omit: ['a', 'b'] })) -console.log(parse(PickOmitSchema, undefined)) export function formDataFromFormOptions(values: Record) { const result: ModalFormData = {}; @@ -48,15 +37,30 @@ export function formDataFromFormOptions(values: Record) { export default class FormResult { constructor(private data: ModalFormData, public status: ResultStatus) { } - asFrontmatterString() { - return stringifyYaml(this.data); + /** + * Transform the current data into a frontmatter string, which is expected + * to be enclosed in `---` when used in a markdown file. + * This method does not add the enclosing `---` to the string, + * so you can put it anywhere inside the frontmatter. + * @param {Object} [options] an options object describing what options to pick or omit + * @param {string[]} [options.pick] an array of key names to pick from the data + * @param {string[]} [options.omit] an array of key names to omit from the data + * @returns the data formatted as a frontmatter string + */ + asFrontmatterString(options?: unknown) { + const data = objectSelect(this.data, options) + return stringifyYaml(data); } /** * Return the current data as a block of dataview properties + * @param {Object} [options] an options object describing what options to pick or omit + * @param {string[]} [options.pick] an array of key names to pick from the data + * @param {string[]} [options.omit] an array of key names to omit from the data * @returns string */ - asDataviewProperties(): string { - return Object.entries(this.data) + asDataviewProperties(options?: unknown): string { + const data = objectSelect(this.data, options) + return Object.entries(data) .map(([key, value]) => `${key}:: ${Array.isArray(value) ? value.map((v) => JSON.stringify(v)) : value}` ) diff --git a/src/core/objectSelect.test.ts b/src/core/objectSelect.test.ts new file mode 100644 index 00000000..98acdb21 --- /dev/null +++ b/src/core/objectSelect.test.ts @@ -0,0 +1,59 @@ +import { objectSelect } from "./objectSelect"; + +describe("objectSelect", () => { + const obj = { + name: "John Doe", + age: 30, + hobbies: ["reading", "swimming"], + isEmployed: true, + }; + + it("should return the original object if no options are provided", () => { + expect(objectSelect(obj, {})).toEqual(obj); + }); + + it("should pick the specified properties from the object", () => { + const opts = { pick: ["name", "age"] }; + const expectedOutput = { name: "John Doe", age: 30 }; + expect(objectSelect(obj, opts)).toEqual(expectedOutput); + }); + + it("should omit the specified properties from the object", () => { + const opts = { omit: ["name", "hobbies"] }; + const expectedOutput = { age: 30, isEmployed: true }; + expect(objectSelect(obj, opts)).toEqual(expectedOutput); + }); + + it("should pick and omit properties from the object", () => { + const opts = { pick: ["name", "age"], omit: ["age"] }; + const expectedOutput = { name: "John Doe" }; + expect(objectSelect(obj, opts)).toEqual(expectedOutput); + }); + + it("should return the original object if the pick array is empty", () => { + const opts = { pick: [] }; + expect(objectSelect(obj, opts)).toEqual(obj); + }); + + it("should return an empty object if the omit array contains all properties", () => { + const opts = { omit: ["name", "age", "hobbies", "isEmployed"] }; + expect(objectSelect(obj, opts)).toEqual({}); + }); + + it("should return the original object if the omit array is empty", () => { + const opts = { omit: [] }; + expect(objectSelect(obj, opts)).toEqual(obj); + }); + + it("should return the original object if the options argument is not an object", () => { + expect(objectSelect(obj, "invalid options")).toEqual(obj); + }); + + it("should return the original object if the options argument is null", () => { + expect(objectSelect(obj, null)).toEqual(obj); + }); + + it("should return the original object if the options argument is undefined", () => { + expect(objectSelect(obj, undefined)).toEqual(obj); + }); +}); diff --git a/src/core/objectSelect.ts b/src/core/objectSelect.ts new file mode 100644 index 00000000..9adb0c48 --- /dev/null +++ b/src/core/objectSelect.ts @@ -0,0 +1,46 @@ +import { E, parse, pipe } from "@std"; +import * as O from "fp-ts/Option"; +import * as NEA from "fp-ts/NonEmptyArray"; +import { filterWithIndex } from "fp-ts/lib/Record"; +import { object, optional, array, string, coerce } from "valibot"; + +const KeysSchema = array(coerce(string(), String)) + +const PickOmitSchema = object({ + pick: optional(KeysSchema), + omit: optional(KeysSchema), +}); + + + +/** + * Utility to pick/omit keys from an object. + * It is user facing, that's why we are so defensive in the options. + * The object should come from the form results, so we don't need to be that strict. + * @param obj the object you want to pick/omit from + * @param opts the options for picking/omitting based on key names + */ +export function objectSelect(obj: Record, opts: unknown): Record { + return pipe( + parse(PickOmitSchema, opts, { abortEarly: true }), + E.map((opts) => { + const picked = pipe( + O.fromNullable(opts.pick), + O.flatMap(NEA.fromArray), + O.map((pick) => { + return filterWithIndex((k) => pick.includes(k))(obj); + }), + O.getOrElse(() => obj) + ); + return pipe( + O.fromNullable(opts.omit), + O.map((omit) => + filterWithIndex((k) => !omit.includes(k))(picked)), + O.getOrElse(() => picked) + ) + } + ), + E.getOrElse(() => obj) + ) +} + diff --git a/src/std/index.ts b/src/std/index.ts index c01cb50a..2d2a2cbf 100644 --- a/src/std/index.ts +++ b/src/std/index.ts @@ -1,6 +1,6 @@ import { pipe as p } from "fp-ts/function"; import { partitionMap } from "fp-ts/Array"; -import { isLeft, isRight, tryCatchK } from "fp-ts/Either"; +import { isLeft, isRight, tryCatchK, map, getOrElse } from "fp-ts/Either"; import { ValiError, parse as parseV } from "valibot"; export const pipe = p @@ -12,8 +12,8 @@ export const E = { isLeft, isRight, tryCatchK, + getOrElse, + map } -export const O = {} - export const parse = tryCatchK(parseV, (e: unknown) => e as ValiError) diff --git a/tsconfig.json b/tsconfig.json index 1db31acf..ca1dde7b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,9 +30,22 @@ "@std": [ "src/std" ] - } + }, + "plugins": [ + { + "name": "@unsplash/ts-namespace-import-plugin", + "namespaces": { + "O": { + "importPath": "fp-ts/Option" + }, + "NEA": { + "importPath": "fp-ts/NonEmptyArray" + } + } + } + ] }, "include": [ "src/**/*" - ] + ], } \ No newline at end of file From f723a906355fa4dfd4be324b44526a0922bcebb7 Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Thu, 26 Oct 2023 13:19:27 +0200 Subject: [PATCH 4/6] refactor: external picKeys --- src/core/objectSelect.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/objectSelect.ts b/src/core/objectSelect.ts index 9adb0c48..6b007ea4 100644 --- a/src/core/objectSelect.ts +++ b/src/core/objectSelect.ts @@ -11,7 +11,12 @@ const PickOmitSchema = object({ omit: optional(KeysSchema), }); - +function picKeys(obj: Record) { + return (keys: string[]) => + pipe(obj, + filterWithIndex((k) => keys.includes(k)) + ); +} /** * Utility to pick/omit keys from an object. @@ -27,9 +32,7 @@ export function objectSelect(obj: Record, opts: unknown): Recor const picked = pipe( O.fromNullable(opts.pick), O.flatMap(NEA.fromArray), - O.map((pick) => { - return filterWithIndex((k) => pick.includes(k))(obj); - }), + O.map(picKeys(obj)), O.getOrElse(() => obj) ); return pipe( From 65e5c3d65e4781bd8ad9166616f5e36afe218daa Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Thu, 26 Oct 2023 13:22:56 +0200 Subject: [PATCH 5/6] test: add tests for omit/pick in dataview method --- src/core/FormResult.test.ts | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/core/FormResult.test.ts b/src/core/FormResult.test.ts index b3d4cd6a..096e3ec5 100644 --- a/src/core/FormResult.test.ts +++ b/src/core/FormResult.test.ts @@ -61,4 +61,47 @@ isEmployed:: true`; expect(result.asString(template)).toEqual(expectedOutput); }); }); + describe("asDataviewProperties pick/omit", () => { + it("should return the data as a string of dataview properties with only the specified keys using options.pick", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name:: John Doe +age:: 30`; + expect( + result.asDataviewProperties({ pick: ["name", "age"] }) + ).toEqual(expectedOutput); + }); + + it("should return the data as a string of dataview properties with all keys except the specified ones using options.omit", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name:: John Doe +age:: 30`; + expect( + result.asDataviewProperties({ omit: ["hobbies", "isEmployed"] }) + ).toEqual(expectedOutput); + }); + + it("should return the data as a string of dataview properties with only the specified keys using options.pick and ignoring options.omit", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name:: John Doe +age:: 30`; + expect( + result.asDataviewProperties({ + pick: ["name", "age"], + omit: ["hobbies", "isEmployed"], + }) + ).toEqual(expectedOutput); + }); + + it("should return the data as a string of dataview properties with all keys except the specified ones using options.omit and ignoring options.pick", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name:: John Doe +age:: 30`; + expect( + result.asDataviewProperties({ + omit: ["hobbies", "isEmployed"], + pick: ["name", "age"], + }) + ).toEqual(expectedOutput); + }); + }); }); From b5d29ce9dcabd1c201265be62a8ae0bb85d2c474 Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Thu, 26 Oct 2023 13:29:16 +0200 Subject: [PATCH 6/6] tests: frontmatterString pick/omit --- src/core/FormResult.test.ts | 49 +++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/core/FormResult.test.ts b/src/core/FormResult.test.ts index 096e3ec5..c38c1914 100644 --- a/src/core/FormResult.test.ts +++ b/src/core/FormResult.test.ts @@ -104,4 +104,53 @@ age:: 30`; ).toEqual(expectedOutput); }); }); + describe("asFrontmatterString pick/omit", () => { + it("should return the data as a YAML frontmatter string with only the specified keys using options.pick", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name: John Doe +age: 30`; + expect( + result.asFrontmatterString({ pick: ["name", "age"] }).trim() + ).toEqual(expectedOutput); + }); + + it("should return the data as a YAML frontmatter string with all keys except the specified ones using options.omit", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name: John Doe +age: 30`; + expect( + result + .asFrontmatterString({ omit: ["hobbies", "isEmployed"] }) + .trim() + ).toEqual(expectedOutput); + }); + + it("should return the data as a YAML frontmatter string with only the specified keys using options.pick and ignoring options.omit", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name: John Doe +age: 30`; + expect( + result + .asFrontmatterString({ + pick: ["name", "age"], + omit: ["hobbies", "isEmployed"], + }) + .trim() + ).toEqual(expectedOutput); + }); + + it("should return the data as a YAML frontmatter string with all keys except the specified ones using options.omit and ignoring options.pick", () => { + const result = new FormResult(formData, "ok"); + const expectedOutput = `name: John Doe +age: 30`; + expect( + result + .asFrontmatterString({ + omit: ["hobbies", "isEmployed"], + pick: ["name", "age"], + }) + .trim() + ).toEqual(expectedOutput); + }); + }); });