|
1 | | -import { parseMarkdownToReactEmail, styles } from "../src"; |
| 1 | +import { parseMarkdownToReactEmail } from "../src"; |
2 | 2 |
|
3 | 3 | describe("Markdown to React Mail Parser", () => { |
4 | | - it("converts header one correctly", () => { |
| 4 | + it("converts headers correctly", () => { |
5 | 5 | const markdown = "# Hello, World!"; |
6 | | - const expected = `<Section><Heading as="h1" style={${JSON.stringify( |
7 | | - styles.h1 |
8 | | - )}}>Hello, World!</Heading></Section>`; |
| 6 | + const expected = `<Section><Heading as=\"h1\" style={{\"fontWeight\":\"500\",\"paddingTop\":20,\"fontSize\":\"2.5rem\"}}>Hello, World!</Heading></Section>`; |
9 | 7 |
|
10 | 8 | const rendered = parseMarkdownToReactEmail(markdown); |
11 | 9 | expect(rendered).toBe(expected); |
12 | 10 | }); |
13 | 11 |
|
14 | | - it("converts header two correctly", () => { |
15 | | - const markdown = "## Heading Two"; |
16 | | - const expected = `<Section><Heading as="h2" style={${JSON.stringify( |
17 | | - styles.h2 |
18 | | - )}}>Heading Two</Heading></Section>`; |
| 12 | + it("converts paragraphs, headers, lists, and tables correctly", () => { |
| 13 | + const markdown = `# Header 1 |
19 | 14 |
|
20 | | - const result = parseMarkdownToReactEmail(markdown); |
21 | | - expect(result).toEqual(expected); |
22 | | - }); |
| 15 | +This is a paragraph with some text. You can have multiple paragraphs separated by empty lines. |
23 | 16 |
|
24 | | - it("converts header three correctly", () => { |
25 | | - const markdown = "### Heading Three"; |
26 | | - const expected = `<Section><Heading as="h3" style={${JSON.stringify( |
27 | | - styles.h3 |
28 | | - )}}>Heading Three</Heading></Section>`; |
| 17 | +## Header 2 |
29 | 18 |
|
30 | | - const result = parseMarkdownToReactEmail(markdown); |
31 | | - expect(result).toEqual(expected); |
32 | | - }); |
| 19 | +Here is an unordered list: |
| 20 | +- Item 1 |
| 21 | +- Item 2 |
| 22 | +- Item 3 |
33 | 23 |
|
34 | | - it("converts header four correctly", () => { |
35 | | - const markdown = "#### Heading Four"; |
36 | | - const expected = `<Section><Heading as="h4" style={${JSON.stringify( |
37 | | - styles.h4 |
38 | | - )}}>Heading Four</Heading></Section>`; |
| 24 | +### Header 3 |
39 | 25 |
|
40 | | - const result = parseMarkdownToReactEmail(markdown); |
41 | | - expect(result).toEqual(expected); |
42 | | - }); |
| 26 | +Here is an ordered list: |
| 27 | +1. First |
| 28 | +2. Second |
| 29 | +3. Third |
43 | 30 |
|
44 | | - it("converts header five correctly", () => { |
45 | | - const markdown = "##### Heading Five"; |
46 | | - const expected = `<Section><Heading as="h5" style={${JSON.stringify( |
47 | | - styles.h5 |
48 | | - )}}>Heading Five</Heading></Section>`; |
| 31 | +#### Header 4 |
49 | 32 |
|
50 | | - const result = parseMarkdownToReactEmail(markdown); |
51 | | - expect(result).toEqual(expected); |
52 | | - }); |
| 33 | +A table example: |
53 | 34 |
|
54 | | - it("converts header six correctly", () => { |
55 | | - const markdown = "###### Heading Six"; |
56 | | - const expected = `<Section><Heading as="h6" style={${JSON.stringify( |
57 | | - styles.h6 |
58 | | - )}}>Heading Six</Heading></Section>`; |
| 35 | +| Column 1 | Column 2 | |
| 36 | +|----------|----------| |
| 37 | +| Cell 1 | Cell 2 | |
| 38 | +| Cell 3 | Cell 4 | |
| 39 | +`; |
59 | 40 |
|
60 | | - const result = parseMarkdownToReactEmail(markdown); |
61 | | - expect(result).toEqual(expected); |
62 | | - }); |
| 41 | + const expected = `<Section><Heading as="h1" style={{"fontWeight":"500","paddingTop":20,"fontSize":"2.5rem"}}>Header 1</Heading> |
63 | 42 |
|
64 | | - it("should handle block quote", () => { |
65 | | - const markdown = "> This is a block quote."; |
66 | | - const expected = `<Section><Text style={${JSON.stringify( |
67 | | - styles.blockQuote |
68 | | - )}}>This is a block quote.</Text></Section>`; |
| 43 | +<Text>This is a paragraph with some text. You can have multiple paragraphs separated by empty lines.</Text> |
69 | 44 |
|
70 | | - const result = parseMarkdownToReactEmail(markdown); |
71 | | - expect(result).toEqual(expected); |
72 | | - }); |
| 45 | +<Heading as="h2" style={{"fontWeight":"500","paddingTop":20,"fontSize":"2rem"}}>Header 2</Heading> |
73 | 46 |
|
74 | | - it("converts paragraphs correctly", () => { |
75 | | - const markdown = "This is a paragraph."; |
76 | | - const expected = `<Section>This is a paragraph.</Section>`; |
| 47 | +<Text>Here is an unordered list:</Text> |
| 48 | +<ul><li>Item 1</li> |
| 49 | +<li>Item 2</li> |
| 50 | +<li>Item 3</li></ul> |
77 | 51 |
|
78 | | - const rendered = parseMarkdownToReactEmail(markdown); |
79 | | - expect(rendered).toBe(expected); |
80 | | - }); |
| 52 | +<Heading as="h3" style={{"fontWeight":"500","paddingTop":20,"fontSize":"1.75rem"}}>Header 3</Heading> |
81 | 53 |
|
82 | | - it("converts bold text correctly", () => { |
83 | | - const markdown = "**bold text**"; |
84 | | - const expected = `<Section><Text style={${JSON.stringify( |
85 | | - styles.bold |
86 | | - )}}>bold text</Text></Section>`; |
| 54 | +<Text>Here is an ordered list:</Text> |
| 55 | +<ol><li>First</li> |
| 56 | +<li>Second</li> |
| 57 | +<li>Third</li> |
| 58 | +</ol> |
| 59 | +<Heading as="h4" style={{"fontWeight":"500","paddingTop":20,"fontSize":"1.5rem"}}>Header 4</Heading> |
| 60 | +
|
| 61 | +<Text>A table example:</Text> |
| 62 | +<table><thead><tr><th align="center">Column 1</th><th align="center">Column 2</th></tr></thead><tbody><tr><td align="center">Cell 1</td><td align="center">Cell 2</td></tr><tr><td align="center">Cell 3</td><td align="center">Cell 4</td></tr></tbody></table></Section>`; |
87 | 63 |
|
88 | 64 | const rendered = parseMarkdownToReactEmail(markdown); |
89 | 65 | expect(rendered).toBe(expected); |
90 | 66 | }); |
91 | 67 |
|
92 | | - it("converts italic text correctly", () => { |
93 | | - const markdown = "*italic text*"; |
94 | | - const expected = `<Section><Text style={${JSON.stringify( |
95 | | - styles.italic |
96 | | - )}}>italic text</Text></Section>`; |
| 68 | + it("converts images, codeblocks, blockquotes and nested blockquotes correctly", () => { |
| 69 | + const markdown = `##### Header 5 |
97 | 70 |
|
98 | | - const rendered = parseMarkdownToReactEmail(markdown); |
99 | | - expect(rendered).toBe(expected); |
100 | | - }); |
| 71 | +An image example: |
| 72 | + |
101 | 73 |
|
102 | | - it("converts lists correctly", () => { |
103 | | - const markdown = "- Item 1\n- Item 2\n- Item 3"; |
104 | | - const expected = `<Section><ul style={${JSON.stringify( |
105 | | - styles.ul |
106 | | - )}}><li style={${JSON.stringify(styles.li)}}>Item 1</li> |
107 | | -<li style={${JSON.stringify(styles.li)}}>Item 2</li> |
108 | | -<li style={${JSON.stringify(styles.li)}}>Item 3</li></ul></Section>`; |
| 74 | +###### Header 6 |
109 | 75 |
|
110 | | - const rendered = parseMarkdownToReactEmail(markdown); |
111 | | - expect(rendered).toBe(expected); |
112 | | - }); |
| 76 | +Some **bold text** and *italic text* _italic text_. |
113 | 77 |
|
114 | | - it("converts images correctly", () => { |
115 | | - const markdown = ""; |
116 | | - const expected = `<Section><Img style={${JSON.stringify( |
117 | | - styles.image |
118 | | - )}} alt="alt text" src="image.jpg" /></Section>`; |
| 78 | +Code block example: |
| 79 | +\`\`\` |
| 80 | +javascript |
| 81 | +function greet() { |
| 82 | + console.log('Hello!'); |
| 83 | +} |
| 84 | +\`\`\` |
119 | 85 |
|
120 | | - const rendered = parseMarkdownToReactEmail(markdown); |
121 | | - expect(rendered).toBe(expected); |
122 | | - }); |
| 86 | +Here is a block quote example: |
123 | 87 |
|
124 | | - it("converts links correctly", () => { |
125 | | - const markdown = "[Codeskills](https://codeskills.dev)"; |
126 | | - const expected = `<Section><Link href="https://codeskills.dev" style={${JSON.stringify( |
127 | | - styles.link |
128 | | - )}}>Codeskills</Link></Section>`; |
| 88 | +> This is a block quote. |
| 89 | +> It can span multiple lines. |
| 90 | +> > This is a nested quote |
| 91 | +> > With multiple |
| 92 | +> > Lines of code |
129 | 93 |
|
130 | | - const rendered = parseMarkdownToReactEmail(markdown); |
131 | | - expect(rendered).toBe(expected); |
132 | | - }); |
| 94 | +> Block quotes are often used to highlight important information or provide references.`; |
133 | 95 |
|
134 | | - it("converts code blocks correctly", () => { |
135 | | - const markdown = '```javascript\nconsole.log("Hello, World!");\n```'; |
136 | | - const expected = `<Section><pre style={${JSON.stringify( |
137 | | - styles.codeBlock |
138 | | - )}}><Text>{\`javascript |
139 | | -console.log("Hello, World!"); |
140 | | -\`}</Text></pre></Section>`; |
| 96 | + const expected = `<Section><Heading as=\"h5\" style={{\"fontWeight\":\"500\",\"paddingTop\":20,\"fontSize\":\"1.25rem\"}}>Header 5</Heading> |
141 | 97 |
|
142 | | - const rendered = parseMarkdownToReactEmail(markdown); |
143 | | - expect(rendered).toBe(expected); |
144 | | - }); |
| 98 | +<Text>An image example:</Text> |
| 99 | +<Img src=\"https://example.com/image.jpg\" alt=\"Alt Text\" /> |
145 | 100 |
|
146 | | - it("converts tables correctly", () => { |
147 | | - const markdown = ` |
148 | | -| Header 1 | Header 2 | |
149 | | -| -------- | -------- | |
150 | | -| Cell 1 | Cell 2 | |
151 | | -| Cell 3 | Cell 4 | |
152 | | -`; |
153 | | - const expected = |
154 | | - '<Section><table style={{}}><thead style={{}}><tr style={{"color":"red"}}><th style={{}} align="center">Header 1</th><th style={{}} align="center">Header 2</th></tr></thead><tbody style={{}}><tr style={{"color":"red"}}><td style={{}} align="center">Cell 1</td><td style={{}} align="center">Cell 2</td></tr><tr style={{"color":"red"}}><td style={{}} align="center">Cell 3</td><td style={{}} align="center">Cell 4</td></tr></tbody></table></Section>'; |
| 101 | +<Heading as=\"h6\" style={{\"fontWeight\":\"500\",\"paddingTop\":20,\"fontSize\":\"1rem\"}}>Header 6</Heading> |
155 | 102 |
|
156 | | - const rendered = parseMarkdownToReactEmail(markdown, { |
157 | | - tr: { color: "red" }, |
158 | | - }); |
159 | | - expect(rendered).toBe(expected); |
160 | | - }); |
| 103 | +<Text>Some <strong style={{\"fontWeight\":\"bold\"}}>bold text</strong> and <em style={{\"fontStyle\":\"italic\"}}>italic text</em> <em style={{\"fontStyle\":\"italic\"}}>italic text</em>.</Text> |
| 104 | +
|
| 105 | +<Text>Code block example:</Text> |
| 106 | +<pre style={{\"color\":\"#212529\",\"fontSize\":\"87.5%\",\"display\":\"inline\",\"background\":\" #f8f8f8\",\"fontFamily\":\"SFMono-Regular,Menlo,Monaco,Consolas,monospace\",\"paddingTop\":10,\"paddingRight\":10,\"paddingLeft\":10,\"paddingBottom\":1,\"marginBottom\":20,\"wordWrap\":\"break-word\"}}> |
| 107 | + javascript |
| 108 | + function greet() { |
| 109 | + console.log('Hello!'); |
| 110 | + } |
| 111 | +</pre> |
| 112 | +
|
| 113 | +<Text>Here is a block quote example:</Text> |
| 114 | +
|
| 115 | +<Text style={{"background":"#f9f9f9","borderLeft":"10px solid #ccc","margin":"1.5em 10px","padding":"1em 10px"}}> |
| 116 | +<Text>This is a block quote.</Text> |
| 117 | +<Text>It can span multiple lines.</Text> |
| 118 | +<Text style={{"background":"#f9f9f9","borderLeft":"10px solid #ccc","margin":"1.5em 10px","padding":"1em 10px"}}> |
| 119 | +<Text>This is a nested quote</Text> |
| 120 | +<Text>With multiple</Text> |
| 121 | +<Text>Lines of code</Text> |
| 122 | +</Text> |
| 123 | +</Text> |
161 | 124 |
|
162 | | - it("converts strikethrough blocks correctly", () => { |
163 | | - const markdown = "~~This is a paragraph.~~"; |
164 | | - const expected = `<Section><del style={${JSON.stringify( |
165 | | - styles.strikethrough |
166 | | - )}}>This is a paragraph.</del></Section>`; |
| 125 | +<Text style={{"background":"#f9f9f9","borderLeft":"10px solid #ccc","margin":"1.5em 10px","padding":"1em 10px"}}> |
| 126 | +<Text>Block quotes are often used to highlight important information or provide references.</Text> |
| 127 | +</Text></Section>`; |
167 | 128 |
|
168 | 129 | const rendered = parseMarkdownToReactEmail(markdown); |
169 | 130 | expect(rendered).toBe(expected); |
|
0 commit comments