UNPKG

9.43 kBJavaScriptView Raw
1const fs = require('fs')
2const path = require('path')
3const test = require('ava')
4const rimraf = require('rimraf')
5const sinon = require('sinon')
6const markdownMagic= require('../index')
7
8const DEBUG = false
9const testMarkdownPath = path.join(__dirname, 'fixtures', 'test.md')
10const outputDir = path.join(__dirname, 'fixtures', 'output')
11const delay = (ms) => new Promise(res => setTimeout(res, ms))
12const matchWord = 'AUTO-GENERATED-CONTENTX'
13const defaultConfig = {
14 matchWord: matchWord
15}
16/**
17 * Test markdownMagic Function
18 */
19test('if valid string path supplied', t => {
20 markdownMagic(testMarkdownPath, defaultConfig)
21 t.pass()
22 // emptyDirectory(outputDir)
23})
24
25test('if valid glob pattern supplied', t => {
26 const config = {
27 outputDir: outputDir
28 }
29 markdownMagic(['test/fixtures/**/*md', '!test/fixtures/output/*.md'], config)
30 t.pass()
31 // empty dir
32 // rimraf.sync(outputDir)
33})
34
35test('if valid config supplied', t => {
36 markdownMagic(testMarkdownPath, defaultConfig)
37 t.pass()
38 // emptyDirectory(outputDir)
39})
40
41test.cb('if callback function supplied, call it once', t => {
42 const callback = sinon.spy()
43 markdownMagic(testMarkdownPath, defaultConfig, () => {
44 callback()
45 t.true(callback.calledOnce)
46 t.end()
47 })
48 // emptyDirectory(outputDir)
49})
50
51test.cb('if callback function supplied, as second arg, call it once', t => {
52 const callback = sinon.spy()
53 markdownMagic(testMarkdownPath, defaultConfig, () => {
54 callback()
55 t.true(callback.calledOnce)
56 t.end()
57 })
58
59 // emptyDirectory(outputDir)
60})
61
62/**
63 * Test Config settings
64 */
65
66test.cb('if config.outputDir supplied, make new file', t => {
67 const config = {
68 outputDir: outputDir,
69 ...defaultConfig
70 }
71 markdownMagic(testMarkdownPath, config, function() {
72 const newfile = path.join(outputDir, 'test.md')
73 const fileWasCreated = filePathExists(newfile)
74 t.true(fileWasCreated)
75 t.end()
76 // remove test file after assertion
77 // emptyDirectory(outputDir)
78 })
79})
80
81test.cb('if config.matchWord supplied, use it for comment matching', t => {
82 const filePath = path.join(__dirname, 'fixtures', 'custom-match-word-test.md')
83 const config = {
84 matchWord: 'YOLO',
85 outputDir: outputDir
86 }
87 markdownMagic(filePath, config, () => {
88 const newfile = path.join(config.outputDir, 'custom-match-word-test.md')
89 const newContent = fs.readFileSync(newfile, 'utf8')
90 t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted')
91 t.end()
92 })
93 // remove test file after assertion
94 // rimraf.sync(outputDir)
95})
96
97test.cb('<!-- AUTO-GENERATED-CONTENT:START (TOC)-->', t => {
98 const filePath = path.join(__dirname, 'fixtures', 'TOC-test.md')
99 const config = {
100 outputDir: outputDir
101 }
102 markdownMagic(filePath, config, () => {
103 const newfile = path.join(config.outputDir, 'TOC-test.md')
104 const newContent = fs.readFileSync(newfile, 'utf8')
105
106 const expectedTest1 = `
107<!-- AUTO-GENERATED-CONTENT:START (TOC) - Test #1: without option and the content with empty line -->
108- [Title A](#title-a)
109 * [Subtitle z](#subtitle-z)
110 * [Subtitle x](#subtitle-x)
111- [Title B](#title-b)
112- [Title C](#title-c)
113<!-- AUTO-GENERATED-CONTENT:END -->`
114 const regexTest1 = new RegExp(`(?=${expectedTest1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
115 t.regex(newContent, regexTest1, 'Test #1 : without option and the content with empty line')
116
117 const expectedTest2 = `
118<!-- AUTO-GENERATED-CONTENT:START (TOC:collapse=true&collapseText=Click Me) - Test #2: with collapse options and the content with 'aaaaaaaaa' -->
119<details>
120<summary>Click Me</summary>
121
122- [Title A](#title-a)
123 * [Subtitle z](#subtitle-z)
124 * [Subtitle x](#subtitle-x)
125- [Title B](#title-b)
126- [Title C](#title-c)
127
128</details>
129<!-- AUTO-GENERATED-CONTENT:END -->`
130 const regexTest2 = new RegExp(`(?=${expectedTest2.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
131 t.regex(newContent, regexTest2, "Test #2: with collapse options and the content with 'aaaaaaaaa'")
132
133 const expectedTest3 = `
134<!-- AUTO-GENERATED-CONTENT:START (TOC:collapse=true&collapseText=Click Me=I have the power) - Test #3: with collapseText contains character '=' -->
135<details>
136<summary>Click Me=I have the power</summary>
137
138- [Title A](#title-a)
139 * [Subtitle z](#subtitle-z)
140 * [Subtitle x](#subtitle-x)
141- [Title B](#title-b)
142- [Title C](#title-c)
143
144</details>
145<!-- AUTO-GENERATED-CONTENT:END -->`
146 const regexTest3 = new RegExp(`(?=${expectedTest3.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
147 t.regex(newContent, regexTest3, "Test #3: with collapseText contains character '='")
148
149 const expectedTest4 = `
150<!-- AUTO-GENERATED-CONTENT:START (TOC) - Test #4: without option and the content is empty -->
151- [Title A](#title-a)
152 * [Subtitle z](#subtitle-z)
153 * [Subtitle x](#subtitle-x)
154- [Title B](#title-b)
155- [Title C](#title-c)
156<!-- AUTO-GENERATED-CONTENT:END -->`
157 const regexTest4 = new RegExp(`(?=${expectedTest4.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
158 t.regex(newContent, regexTest4, 'Test #4 : without option and the content is empty')
159
160 const expectedTest5 = `
161<!-- AUTO-GENERATED-CONTENT:START (TOC) - Test #5: without option and tags with same line -->
162- [Title A](#title-a)
163 * [Subtitle z](#subtitle-z)
164 * [Subtitle x](#subtitle-x)
165- [Title B](#title-b)
166- [Title C](#title-c)
167<!-- AUTO-GENERATED-CONTENT:END -->`
168 const regexTest5 = new RegExp(`(?=${expectedTest5.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
169 t.regex(newContent, regexTest5, 'Test #5 : without option and tags with same line')
170
171 t.end()
172 })
173
174})
175
176/**
177 * Test Built in transforms
178 */
179test.cb('<!-- AUTO-GENERATED-CONTENT:START (CODE)-->', t => {
180 const filePath = path.join(__dirname, 'fixtures', 'CODE-test.md')
181 const config = { outputDir: outputDir }
182 const newfile = path.join(config.outputDir, 'CODE-test.md')
183
184 markdownMagic(filePath, config, function(err, data) {
185 // console.log('data', data)
186 const newContent = fs.readFileSync(newfile, 'utf8')
187 // check local code
188 t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted')
189 // check local code with range lines
190 t.regex(newContent, /```js\n const baz = 'foobar'\n console\.log\(`Hello \${baz}`\)\n```/, 'local code snippet with range lines inserted')
191 // check remotely fetched code
192 t.regex(newContent, /require\('dox'\)/, 'remote code snippet inserted')
193 // check remotely fetched code with range lines
194 t.regex(newContent, /```json\n "author": "David Wells",\n "license": "MIT",\n```/, 'remote code snippet with range lines inserted')
195
196 t.end()
197 })
198
199 if (filePathExists(newfile)) {
200 // rimraf.sync(outputDir)
201 }
202 // remove test file after assertion
203})
204
205test.cb('<!-- AUTO-GENERATED-CONTENT:START (REMOTE)-->', t => {
206 const filePath = path.join(__dirname, 'fixtures', 'REMOTE-test.md')
207
208 const config = { outputDir: outputDir }
209 markdownMagic(filePath, config, function() {
210 const newfile = path.join(config.outputDir, 'REMOTE-test.md')
211 const newContent = fs.readFileSync(newfile, 'utf8')
212 // check local code
213 t.regex(newContent, /Markdown Magic/, 'word "Markdown Magic" not found in remote block')
214 t.end()
215 // remove test file after assertion
216 // rimraf.sync(outputDir)
217 })
218})
219
220test.cb('<!-- AUTO-GENERATED-CONTENT:START (customTransform)-->', t => {
221 const filePath = path.join(__dirname, 'fixtures', 'CUSTOM-test.md')
222
223 const config = {
224 outputDir: outputDir,
225 transforms: {
226 /* Match <!-- AUTO-GENERATED-CONTENT:START (customTransform:optionOne=hi&optionOne=DUDE) --> */
227 customTransform(content, options) {
228 // options = { optionOne: hi, optionOne: DUDE}
229 return `This will replace all the contents of inside the comment ${options.optionOne}`
230 }
231 }
232 }
233 markdownMagic(filePath, config, function() {
234 console.log('Callback')
235 const newfile = path.join(config.outputDir, 'CUSTOM-test.md')
236 console.log('newfile', newfile)
237 const newContent = fs.readFileSync(newfile, 'utf8')
238 console.log('newContent', newContent)
239 // check local code
240 t.regex(newContent, /will replace all the contents/, 'has custom transform data')
241 t.end()
242 // remove test file after assertion
243 // rimraf.sync(outputDir)
244 })
245})
246
247test.cb('Async <!-- AUTO-GENERATED-CONTENT:START (customAsync)-->', t => {
248 const filePath = path.join(__dirname, 'fixtures', 'CUSTOM-async.md')
249
250 const config = {
251 outputDir: outputDir,
252 transforms: {
253 /* Match <!-- AUTO-GENERATED-CONTENT:START (customAsync:optionOne=hi) --> */
254 async customAsync(content, options) {
255 await delay(500)
256 // options = { optionOne: hi, optionOne: DUDE}
257 return `async data here ${options.optionOne}`
258 }
259 }
260 }
261 markdownMagic(filePath, config, function() {
262 const newfile = path.join(config.outputDir, 'CUSTOM-async.md')
263 const newContent = fs.readFileSync(newfile, 'utf8')
264 // check local code
265 t.regex(newContent, /async data here hi/, 'has custom transform data')
266 t.end()
267 // remove test file after assertion
268 // rimraf.sync(outputDir)
269 })
270})
271
272test.after.always('cleanup', async t => {
273 rimraf.sync(outputDir)
274})
275
276/*
277 Util functions
278*/
279function filePathExists(fp) {
280 try {
281 fs.accessSync(fp)
282 return true
283 } catch (err) {
284 return false
285 }
286}
287
288function emptyDirectory(filePath, callBack) {
289 rimraf.sync(filePath)
290 callBack && callBack(null)
291}