diff --git a/fixtures/paragraph-confusing-####/expected.json b/fixtures/paragraph-confusing-####/expected.json new file mode 100644 index 0000000..34954d8 --- /dev/null +++ b/fixtures/paragraph-confusing-####/expected.json @@ -0,0 +1,3 @@ +{ + "textarea-one": "Textarea input text 1 ####" +} diff --git a/fixtures/paragraph-confusing-####/form.yml b/fixtures/paragraph-confusing-####/form.yml new file mode 100644 index 0000000..cb5bf9f --- /dev/null +++ b/fixtures/paragraph-confusing-####/form.yml @@ -0,0 +1,9 @@ +body: + - type: textarea + id: textarea-one + attributes: + label: My textarea input + - type: textarea + id: textarea-two + attributes: + label: Another textarea input diff --git a/fixtures/paragraph-confusing-####/issue-body.md b/fixtures/paragraph-confusing-####/issue-body.md new file mode 100644 index 0000000..38a4b14 --- /dev/null +++ b/fixtures/paragraph-confusing-####/issue-body.md @@ -0,0 +1,3 @@ +### My textarea input + +Textarea input text 1 #### diff --git a/fixtures/paragraph-confusing-####/issue.js b/fixtures/paragraph-confusing-####/issue.js new file mode 100644 index 0000000..d8098d4 --- /dev/null +++ b/fixtures/paragraph-confusing-####/issue.js @@ -0,0 +1,8 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = fileURLToPath(new URL(".", import.meta.url)); +const issueBodyPath = resolve(__dirname, "issue-body.md"); + +export default readFileSync(issueBodyPath, "utf-8"); diff --git a/fixtures/paragraph-ignore-```/expected.json b/fixtures/paragraph-ignore-```/expected.json new file mode 100644 index 0000000..2f8fdda --- /dev/null +++ b/fixtures/paragraph-ignore-```/expected.json @@ -0,0 +1,3 @@ +{ + "textarea-one": "Textarea input text 1\n\n```\n### To be ignored tag\n```" +} diff --git a/fixtures/paragraph-ignore-```/form.yml b/fixtures/paragraph-ignore-```/form.yml new file mode 100644 index 0000000..cb5bf9f --- /dev/null +++ b/fixtures/paragraph-ignore-```/form.yml @@ -0,0 +1,9 @@ +body: + - type: textarea + id: textarea-one + attributes: + label: My textarea input + - type: textarea + id: textarea-two + attributes: + label: Another textarea input diff --git a/fixtures/paragraph-ignore-```/issue-body.md b/fixtures/paragraph-ignore-```/issue-body.md new file mode 100644 index 0000000..ebe88ce --- /dev/null +++ b/fixtures/paragraph-ignore-```/issue-body.md @@ -0,0 +1,7 @@ +### My textarea input + +Textarea input text 1 + +``` +### To be ignored tag +``` diff --git a/fixtures/paragraph-ignore-```/issue.js b/fixtures/paragraph-ignore-```/issue.js new file mode 100644 index 0000000..d8098d4 --- /dev/null +++ b/fixtures/paragraph-ignore-```/issue.js @@ -0,0 +1,8 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = fileURLToPath(new URL(".", import.meta.url)); +const issueBodyPath = resolve(__dirname, "issue-body.md"); + +export default readFileSync(issueBodyPath, "utf-8"); diff --git a/fixtures/paragraph-ignore-```sh/expected.json b/fixtures/paragraph-ignore-```sh/expected.json new file mode 100644 index 0000000..1026cc4 --- /dev/null +++ b/fixtures/paragraph-ignore-```sh/expected.json @@ -0,0 +1,3 @@ +{ + "textarea-one": "Textarea input text 1\n\n```sh\n### To be ignored tag\n```" +} diff --git a/fixtures/paragraph-ignore-```sh/form.yml b/fixtures/paragraph-ignore-```sh/form.yml new file mode 100644 index 0000000..cb5bf9f --- /dev/null +++ b/fixtures/paragraph-ignore-```sh/form.yml @@ -0,0 +1,9 @@ +body: + - type: textarea + id: textarea-one + attributes: + label: My textarea input + - type: textarea + id: textarea-two + attributes: + label: Another textarea input diff --git a/fixtures/paragraph-ignore-```sh/issue-body.md b/fixtures/paragraph-ignore-```sh/issue-body.md new file mode 100644 index 0000000..cf4981e --- /dev/null +++ b/fixtures/paragraph-ignore-```sh/issue-body.md @@ -0,0 +1,7 @@ +### My textarea input + +Textarea input text 1 + +```sh +### To be ignored tag +``` diff --git a/fixtures/paragraph-ignore-```sh/issue.js b/fixtures/paragraph-ignore-```sh/issue.js new file mode 100644 index 0000000..d8098d4 --- /dev/null +++ b/fixtures/paragraph-ignore-```sh/issue.js @@ -0,0 +1,8 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = fileURLToPath(new URL(".", import.meta.url)); +const issueBodyPath = resolve(__dirname, "issue-body.md"); + +export default readFileSync(issueBodyPath, "utf-8"); diff --git a/index.js b/index.js index cab1bce..0ee6160 100644 --- a/index.js +++ b/index.js @@ -111,9 +111,35 @@ export async function run(env, body, fs, core) { return result } - result = body - .trim() - .split("###") + function parseBody(body) { + let result = []; + let ignore = false; + + body.split("\n").reduce((str, line, idx, arr) => { + // ``` Section must be ignored and not parsed as new section + if (line.startsWith("```")) + ignore = !ignore + + // Parse new setion only if they start with ### SPACE + if (!ignore && line.startsWith("### ")) { + result.push(str.trim()) + + return line.replace(/^### /, "")+"\n"; + } + + str += line + "\n" + + // Push the last string if we are at the end of lines + if (arr.length - 1 == idx) + result.push(str.trim()) + + return str; + }, "") + + return result; + } + + result = parseBody(body) .filter(Boolean) .map((line) => { return line diff --git a/test.spec.js b/test.spec.js index a7d380d..5ec0985 100644 --- a/test.spec.js +++ b/test.spec.js @@ -7,6 +7,9 @@ import readmeExampleIssue from "./fixtures/readme-example/issue.js"; import fullExampleIssue from "./fixtures/full-example/issue.js"; import mismatchedParsingIssue from "./fixtures/mismatched-parsing/issue.js"; import multipleParagraphsIssue from "./fixtures/multiple-paragraphs/issue.js"; +import paragraphConfusingHashesIssue from "./fixtures/paragraph-confusing-####/issue.js"; +import paragraphIgnoreCodeblockIssue from "./fixtures/paragraph-ignore-```/issue.js"; +import paragraphIgnoreCodeblockShIssue from "./fixtures/paragraph-ignore-```sh/issue.js"; function loadJson(path) { return JSON.parse(readFileSync(path, "utf-8")); @@ -184,6 +187,123 @@ it("multiple paragraphs", () => { expect(core.setOutput.mock.calls.length).toBe(3) }); +it("paragraph with confusing ####", () => { + const expectedOutput = loadJson("./fixtures/paragraph-confusing-####/expected.json"); + const expectedOutputJson = JSON.stringify(expectedOutput, null, 2); + + // mock ENV + const env = { + HOME: "", + }; + + // mock event payload + const eventPayload = paragraphConfusingHashesIssue; + + // mock fs + const fs = { + readFileSync(path, encoding) { + expect(path).toBe(""); + expect(encoding).toBe("utf8"); + return readFileSync("fixtures/paragraph-confusing-####/form.yml", "utf-8"); + }, + writeFileSync(path, content) { + expect(path).toBe("/issue-parser-result.json"); + expect(content).toBe(expectedOutputJson); + }, + }; + + // mock core + const core = { + getInput: jest.fn(() => ''), + setOutput: jest.fn(), + }; + + run(env, eventPayload, fs, core); + + expect(core.getInput).toHaveBeenCalledWith('template-path') + expect(core.setOutput).toHaveBeenCalledWith('jsonString', JSON.stringify(expectedOutput, null, 2)) + expect(core.setOutput).toHaveBeenCalledWith('issueparser_textarea-one', 'Textarea input text 1 ####') + expect(core.setOutput.mock.calls.length).toBe(2) +}); + +it("paragraph with ``` section", () => { + const expectedOutput = loadJson("./fixtures/paragraph-ignore-```/expected.json"); + const expectedOutputJson = JSON.stringify(expectedOutput, null, 2); + + // mock ENV + const env = { + HOME: "", + }; + + // mock event payload + const eventPayload = paragraphIgnoreCodeblockIssue; + + // mock fs + const fs = { + readFileSync(path, encoding) { + expect(path).toBe(""); + expect(encoding).toBe("utf8"); + return readFileSync("fixtures/paragraph-ignore-```/form.yml", "utf-8"); + }, + writeFileSync(path, content) { + expect(path).toBe("/issue-parser-result.json"); + expect(content).toBe(expectedOutputJson); + }, + }; + + // mock core + const core = { + getInput: jest.fn(() => ''), + setOutput: jest.fn(), + }; + + run(env, eventPayload, fs, core); + + expect(core.getInput).toHaveBeenCalledWith('template-path') + expect(core.setOutput).toHaveBeenCalledWith('jsonString', JSON.stringify(expectedOutput, null, 2)) + expect(core.setOutput).toHaveBeenCalledWith('issueparser_textarea-one', 'Textarea input text 1\n\n```\n### To be ignored tag\n```') + expect(core.setOutput.mock.calls.length).toBe(2) +}); + +it("paragraph with ```sh section", () => { + const expectedOutput = loadJson("./fixtures/paragraph-ignore-```sh/expected.json"); + const expectedOutputJson = JSON.stringify(expectedOutput, null, 2); + + // mock ENV + const env = { + HOME: "", + }; + + // mock event payload + const eventPayload = paragraphIgnoreCodeblockShIssue; + + // mock fs + const fs = { + readFileSync(path, encoding) { + expect(path).toBe(""); + expect(encoding).toBe("utf8"); + return readFileSync("fixtures/paragraph-ignore-```sh/form.yml", "utf-8"); + }, + writeFileSync(path, content) { + expect(path).toBe("/issue-parser-result.json"); + expect(content).toBe(expectedOutputJson); + }, + }; + + // mock core + const core = { + getInput: jest.fn(() => ''), + setOutput: jest.fn(), + }; + + run(env, eventPayload, fs, core); + + expect(core.getInput).toHaveBeenCalledWith('template-path') + expect(core.setOutput).toHaveBeenCalledWith('jsonString', JSON.stringify(expectedOutput, null, 2)) + expect(core.setOutput).toHaveBeenCalledWith('issueparser_textarea-one', 'Textarea input text 1\n\n```sh\n### To be ignored tag\n```') + expect(core.setOutput.mock.calls.length).toBe(2) +}); + it("blank", () => { const expectedOutput = loadJson("./fixtures/blank/expected.json"); const expectedOutputJson = JSON.stringify(expectedOutput, null, 2);