@maizzle/framework 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +9 -9
- package/.github/workflows/nodejs.yml +28 -28
- package/LICENSE +21 -21
- package/bin/maizzle +3 -3
- package/package.json +2 -2
- package/src/generators/config.js +32 -32
- package/src/generators/output/index.js +4 -4
- package/src/generators/output/to-disk.js +208 -208
- package/src/generators/output/to-string.js +67 -67
- package/src/generators/postcss.js +29 -29
- package/src/generators/posthtml.js +66 -66
- package/src/index.js +17 -17
- package/src/transformers/attributeToStyle.js +90 -90
- package/src/transformers/baseUrl.js +69 -69
- package/src/transformers/extraAttributes.js +26 -26
- package/src/transformers/filters/defaultFilters.js +126 -126
- package/src/transformers/filters/index.js +55 -55
- package/src/transformers/inlineCss.js +37 -37
- package/src/transformers/markdown.js +19 -19
- package/src/transformers/minify.js +21 -21
- package/src/transformers/plaintext.js +23 -23
- package/src/transformers/posthtmlMso.js +10 -10
- package/src/transformers/prettify.js +27 -27
- package/src/transformers/preventWidows.js +13 -13
- package/src/transformers/removeAttributes.js +17 -17
- package/src/transformers/removeInlineBackgroundColor.js +52 -52
- package/src/transformers/removeInlineSizes.js +41 -41
- package/src/transformers/replaceStrings.js +14 -14
- package/src/transformers/safeClassNames.js +24 -24
- package/src/transformers/shorthandInlineCSS.js +19 -19
- package/src/transformers/sixHex.js +33 -33
- package/src/transformers/urlParameters.js +17 -17
- package/src/utils/helpers.js +17 -17
- package/test/expected/posthtml/extend-template.html +2 -2
- package/test/expected/posthtml/fetch.html +5 -5
- package/test/expected/posthtml/layout.html +3 -3
- package/test/expected/transformers/base-url.html +99 -99
- package/test/fixtures/posthtml/extend-template.html +7 -7
- package/test/fixtures/posthtml/fetch.html +9 -9
- package/test/fixtures/posthtml/layout.html +11 -11
- package/test/fixtures/transformers/base-url.html +101 -101
- package/test/stubs/assets/foo.bar +1 -1
- package/test/stubs/breaking/bad.html +5 -5
- package/test/stubs/config/config.js +10 -10
- package/test/stubs/config/config.maizzle-ci.js +10 -10
- package/test/stubs/data.json +14 -14
- package/test/stubs/events/before-create.html +1 -1
- package/test/stubs/layouts/basic.html +1 -1
- package/test/stubs/layouts/full.html +12 -12
- package/test/stubs/layouts/template.html +5 -5
- package/test/stubs/main.css +5 -5
- package/test/stubs/tailwind/content-source.html +1 -1
- package/test/stubs/tailwind/tailwind.css +3 -3
- package/test/stubs/template.html +10 -10
- package/test/test-posthtml.js +72 -72
- package/test/test-todisk.js +511 -511
- package/test/test-transformers.js +1 -0
- package/xo.config.js +22 -22
package/test/test-todisk.js
CHANGED
|
@@ -1,511 +1,511 @@
|
|
|
1
|
-
const test = require('ava')
|
|
2
|
-
const fs = require('fs-extra')
|
|
3
|
-
const Maizzle = require('../src')
|
|
4
|
-
|
|
5
|
-
test.beforeEach(t => {
|
|
6
|
-
t.context.folder = '_temp_' + Math.random().toString(36).slice(2, 9)
|
|
7
|
-
t.context.log = console.log()
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
test.afterEach.always(async t => {
|
|
11
|
-
if (t.context.folder) {
|
|
12
|
-
await fs.remove(t.context.folder)
|
|
13
|
-
delete t.context.folder
|
|
14
|
-
}
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
test('throws if config cannot be computed', async t => {
|
|
18
|
-
await t.throwsAsync(async () => {
|
|
19
|
-
await Maizzle.build('missing')
|
|
20
|
-
}, {instanceOf: Error, message: `could not load config.missing.js`})
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test('skips if no templates found', async t => {
|
|
24
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
25
|
-
build: {
|
|
26
|
-
fail: 'silent',
|
|
27
|
-
templates: {
|
|
28
|
-
source: 'test/stubs/templates',
|
|
29
|
-
filetypes: 'fake',
|
|
30
|
-
destination: {
|
|
31
|
-
path: t.context.folder
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
tailwind: {
|
|
35
|
-
config: {
|
|
36
|
-
purge: false
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
t.is(files.length, 0)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test('outputs files at the correct location', async t => {
|
|
46
|
-
const {files: string} = await Maizzle.build('maizzle-ci', {
|
|
47
|
-
build: {
|
|
48
|
-
fail: 'silent',
|
|
49
|
-
templates: {
|
|
50
|
-
source: 'test/stubs/templates',
|
|
51
|
-
destination: {
|
|
52
|
-
path: t.context.folder
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
const {files: array} = await Maizzle.build('maizzle-ci', {
|
|
59
|
-
build: {
|
|
60
|
-
fail: 'silent',
|
|
61
|
-
templates: {
|
|
62
|
-
source: ['test/stubs/templates'],
|
|
63
|
-
destination: {
|
|
64
|
-
path: t.context.folder
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
t.true(await fs.pathExists(t.context.folder))
|
|
71
|
-
t.is(string.length, 2)
|
|
72
|
-
t.is(array.length, 2)
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
test('outputs files at the correct location if multiple template sources are used', async t => {
|
|
76
|
-
const {files} = await Maizzle.build('local', {
|
|
77
|
-
build: {
|
|
78
|
-
fail: 'silent',
|
|
79
|
-
templates: [
|
|
80
|
-
{
|
|
81
|
-
source: 'test/stubs/templates',
|
|
82
|
-
destination: {
|
|
83
|
-
path: t.context.folder
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
source: 'test/stubs/plaintext',
|
|
88
|
-
destination: {
|
|
89
|
-
path: t.context.folder
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
]
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
t.true(await fs.pathExists(t.context.folder))
|
|
97
|
-
t.is(files.length, 3)
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
test('copies all files in the `filetypes` option to destination', async t => {
|
|
101
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
102
|
-
build: {
|
|
103
|
-
fail: 'silent',
|
|
104
|
-
templates: {
|
|
105
|
-
source: 'test/stubs/templates',
|
|
106
|
-
filetypes: ['html', 'test'],
|
|
107
|
-
destination: {
|
|
108
|
-
path: t.context.folder
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
tailwind: {
|
|
112
|
-
config: {
|
|
113
|
-
purge: false
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
t.true(await fs.pathExists(t.context.folder))
|
|
120
|
-
t.is(files.length, 3)
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
test('outputs files with the correct extension', async t => {
|
|
124
|
-
await Maizzle.build('maizzle-ci', {
|
|
125
|
-
build: {
|
|
126
|
-
fail: 'silent',
|
|
127
|
-
templates: {
|
|
128
|
-
source: 'test/stubs/templates',
|
|
129
|
-
destination: {
|
|
130
|
-
path: t.context.folder,
|
|
131
|
-
extension: 'blade.php'
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
tailwind: {
|
|
135
|
-
config: {
|
|
136
|
-
purge: false
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
const filelist = await fs.readdir(t.context.folder)
|
|
143
|
-
|
|
144
|
-
t.true(filelist.includes('1.blade.php'))
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
test('outputs plaintext files', async t => {
|
|
148
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
149
|
-
fail: 'silent',
|
|
150
|
-
build: {
|
|
151
|
-
templates: {
|
|
152
|
-
source: 'test/stubs/plaintext',
|
|
153
|
-
destination: {
|
|
154
|
-
path: t.context.folder
|
|
155
|
-
},
|
|
156
|
-
plaintext: true
|
|
157
|
-
},
|
|
158
|
-
tailwind: {
|
|
159
|
-
config: {
|
|
160
|
-
purge: false
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
const plaintext = files.filter(file => file.includes('.txt'))
|
|
167
|
-
const html = files.filter(file => file.includes('.html'))
|
|
168
|
-
const plaintextContent = await fs.readFile(plaintext[0], 'utf8')
|
|
169
|
-
const htmlContent = await fs.readFile(html[0], 'utf8')
|
|
170
|
-
|
|
171
|
-
t.is(plaintext[0], `${t.context.folder}/plaintext.txt`)
|
|
172
|
-
t.is(plaintextContent, 'Show in HTML\nShow in plaintext')
|
|
173
|
-
t.is(htmlContent, '<div>Show in HTML</div>\n\n')
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
test('outputs plaintext files (custom path)', async t => {
|
|
177
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
178
|
-
fail: 'silent',
|
|
179
|
-
build: {
|
|
180
|
-
templates: {
|
|
181
|
-
source: 'test/stubs/plaintext',
|
|
182
|
-
destination: {
|
|
183
|
-
path: t.context.folder
|
|
184
|
-
},
|
|
185
|
-
plaintext: {
|
|
186
|
-
destination: {
|
|
187
|
-
path: `${t.context.folder}/nested/plain.text`
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
tailwind: {
|
|
192
|
-
config: {
|
|
193
|
-
purge: false
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
const plaintext = files.filter(file => file.includes('.text'))
|
|
200
|
-
|
|
201
|
-
t.is(plaintext[0], `${t.context.folder}/nested/plain.text`)
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
test('renders plaintext string', async t => {
|
|
205
|
-
const html = await fs.readFile('test/stubs/plaintext/plaintext.html', 'utf8')
|
|
206
|
-
const {plaintext} = await Maizzle.plaintext(html)
|
|
207
|
-
|
|
208
|
-
t.is(plaintext, 'Show in HTML\nShow in plaintext')
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
test('copies assets to destination', async t => {
|
|
212
|
-
await Maizzle.build('maizzle-ci', {
|
|
213
|
-
build: {
|
|
214
|
-
fail: 'silent',
|
|
215
|
-
templates: {
|
|
216
|
-
source: 'test/stubs/templates',
|
|
217
|
-
destination: {
|
|
218
|
-
path: t.context.folder
|
|
219
|
-
},
|
|
220
|
-
assets: {
|
|
221
|
-
source: 'test/stubs/assets',
|
|
222
|
-
destination: 'images'
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
tailwind: {
|
|
226
|
-
config: {
|
|
227
|
-
purge: false
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
const filelist = await fs.readdir(`${t.context.folder}/images`)
|
|
234
|
-
|
|
235
|
-
t.is(await fs.pathExists(`${t.context.folder}/images`), true)
|
|
236
|
-
t.is(filelist.length, 1)
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
test('runs the `beforeCreate` event', async t => {
|
|
240
|
-
await Maizzle.build('maizzle-ci', {
|
|
241
|
-
build: {
|
|
242
|
-
fail: 'silent',
|
|
243
|
-
templates: {
|
|
244
|
-
source: 'test/stubs/events',
|
|
245
|
-
destination: {
|
|
246
|
-
path: t.context.folder
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
tailwind: {
|
|
250
|
-
config: {
|
|
251
|
-
purge: false
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
},
|
|
255
|
-
events: {
|
|
256
|
-
beforeCreate(config) {
|
|
257
|
-
config.foo = 'bar'
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
const filename = await fs.readdir(t.context.folder)
|
|
263
|
-
const html = await fs.readFile(`${t.context.folder}/${filename[0]}`, 'utf8')
|
|
264
|
-
|
|
265
|
-
t.is(html.trim(), 'Foo is bar')
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
test('runs the `afterBuild` event', async t => {
|
|
269
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
270
|
-
build: {
|
|
271
|
-
fail: 'silent',
|
|
272
|
-
templates: {
|
|
273
|
-
source: 'test/stubs/templates',
|
|
274
|
-
destination: {
|
|
275
|
-
path: t.context.folder
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
tailwind: {
|
|
279
|
-
config: {
|
|
280
|
-
purge: false
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
},
|
|
284
|
-
events: {
|
|
285
|
-
afterBuild(files) {
|
|
286
|
-
t.context.afterBuild = files
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
})
|
|
290
|
-
|
|
291
|
-
const getIntersection = (a, ...array) => [...new Set(a)].filter(v => array.every(b => b.includes(v)))
|
|
292
|
-
|
|
293
|
-
t.deepEqual(getIntersection(t.context.afterBuild, files), files)
|
|
294
|
-
})
|
|
295
|
-
|
|
296
|
-
test('supports multiple asset paths', async t => {
|
|
297
|
-
await Maizzle.build('maizzle-ci', {
|
|
298
|
-
build: {
|
|
299
|
-
fail: 'silent',
|
|
300
|
-
templates: {
|
|
301
|
-
source: 'test/stubs/templates',
|
|
302
|
-
destination: {
|
|
303
|
-
path: t.context.folder
|
|
304
|
-
},
|
|
305
|
-
assets: {
|
|
306
|
-
source: ['test/stubs/assets', 'test/stubs/plaintext', 'test/stubs/invalid'],
|
|
307
|
-
destination: 'extras'
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
tailwind: {
|
|
311
|
-
config: {
|
|
312
|
-
purge: false
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
t.true(await fs.pathExists(`${t.context.folder}/extras/foo.bar`))
|
|
319
|
-
t.true(await fs.pathExists(`${t.context.folder}/extras/plaintext.html`))
|
|
320
|
-
t.false(await fs.pathExists(`${t.context.folder}/extras/invalid`))
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
test('warns if a template cannot be rendered and `fail` option is undefined', async t => {
|
|
324
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
325
|
-
build: {
|
|
326
|
-
templates: {
|
|
327
|
-
source: 'test/stubs/breaking',
|
|
328
|
-
destination: {
|
|
329
|
-
path: t.context.folder
|
|
330
|
-
}
|
|
331
|
-
},
|
|
332
|
-
tailwind: {
|
|
333
|
-
config: {
|
|
334
|
-
purge: false
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
t.false(files.includes('empty.html'))
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
test('warns if a template cannot be rendered and `fail` option is `verbose`', async t => {
|
|
344
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
345
|
-
build: {
|
|
346
|
-
fail: 'verbose',
|
|
347
|
-
templates: {
|
|
348
|
-
source: 'test/stubs/breaking',
|
|
349
|
-
destination: {
|
|
350
|
-
path: t.context.folder
|
|
351
|
-
}
|
|
352
|
-
},
|
|
353
|
-
tailwind: {
|
|
354
|
-
config: {
|
|
355
|
-
purge: false
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
t.false(files.includes('empty.html'))
|
|
362
|
-
})
|
|
363
|
-
|
|
364
|
-
test('warns if a template cannot be rendered and `fail` option is `silent`', async t => {
|
|
365
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
366
|
-
build: {
|
|
367
|
-
fail: 'silent',
|
|
368
|
-
templates: {
|
|
369
|
-
source: 'test/stubs/breaking',
|
|
370
|
-
destination: {
|
|
371
|
-
path: t.context.folder
|
|
372
|
-
}
|
|
373
|
-
},
|
|
374
|
-
tailwind: {
|
|
375
|
-
config: {
|
|
376
|
-
purge: false
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
t.false(files.includes('empty.html'))
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
test('spins up local development server', async t => {
|
|
386
|
-
await Maizzle.serve('local', {
|
|
387
|
-
build: {
|
|
388
|
-
browsersync: {
|
|
389
|
-
ui: false
|
|
390
|
-
},
|
|
391
|
-
templates: {
|
|
392
|
-
source: 'test/stubs/templates',
|
|
393
|
-
destination: {
|
|
394
|
-
path: t.context.folder
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
t.true(await fs.pathExists(t.context.folder))
|
|
401
|
-
})
|
|
402
|
-
|
|
403
|
-
test('local server does not compile unwanted file types', async t => {
|
|
404
|
-
await Maizzle.serve('local', {
|
|
405
|
-
build: {
|
|
406
|
-
console: {
|
|
407
|
-
clear: true
|
|
408
|
-
},
|
|
409
|
-
browsersync: {
|
|
410
|
-
ui: false
|
|
411
|
-
},
|
|
412
|
-
templates: {
|
|
413
|
-
source: 'test/stubs/templates',
|
|
414
|
-
destination: {
|
|
415
|
-
path: `${t.context.folder}`
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
},
|
|
419
|
-
events: {
|
|
420
|
-
beforeCreate(config) {
|
|
421
|
-
config.foo = 'bar'
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
t.true(await fs.pathExists(`${t.context.folder}`))
|
|
427
|
-
t.true(await fs.pathExists(`${t.context.folder}/2.test`))
|
|
428
|
-
|
|
429
|
-
// Tests watching changes to files
|
|
430
|
-
await fs.outputFile('test/stubs/templates/1.html', 'html\n')
|
|
431
|
-
t.is(await fs.readFile('test/stubs/templates/1.html', 'utf8'), 'html\n')
|
|
432
|
-
|
|
433
|
-
// Don't trigger rebuilds on files not in filetypes
|
|
434
|
-
await fs.outputFile('test/stubs/templates/2.test', 'test\n')
|
|
435
|
-
t.is(await fs.readFile('test/stubs/templates/2.test', 'utf8'), 'test\n')
|
|
436
|
-
})
|
|
437
|
-
|
|
438
|
-
test('throws if it cannot spin up local development server', async t => {
|
|
439
|
-
await t.throwsAsync(async () => {
|
|
440
|
-
await Maizzle.serve('local', {})
|
|
441
|
-
}, {instanceOf: TypeError})
|
|
442
|
-
})
|
|
443
|
-
|
|
444
|
-
test('works with templates.source defined as function (string paths)', async t => {
|
|
445
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
446
|
-
build: {
|
|
447
|
-
fail: 'silent',
|
|
448
|
-
templates: {
|
|
449
|
-
source: () => 'test/stubs/templates',
|
|
450
|
-
destination: {
|
|
451
|
-
path: t.context.folder
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
})
|
|
456
|
-
|
|
457
|
-
t.true(await fs.pathExists(t.context.folder))
|
|
458
|
-
t.is(files.length, 2)
|
|
459
|
-
})
|
|
460
|
-
|
|
461
|
-
test('works with templates.source defined as function (array paths)', async t => {
|
|
462
|
-
const {files} = await Maizzle.build('maizzle-ci', {
|
|
463
|
-
build: {
|
|
464
|
-
fail: 'silent',
|
|
465
|
-
customSources: ['test/stubs/templates', 'test/stubs/templates'],
|
|
466
|
-
templates: {
|
|
467
|
-
source: config => {
|
|
468
|
-
return config.build.customSources
|
|
469
|
-
},
|
|
470
|
-
destination: {
|
|
471
|
-
path: t.context.folder
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
t.true(await fs.pathExists(t.context.folder))
|
|
478
|
-
t.is(files.length, 2)
|
|
479
|
-
})
|
|
480
|
-
|
|
481
|
-
test('throws if templates path is invalid', async t => {
|
|
482
|
-
await t.throwsAsync(async () => {
|
|
483
|
-
await Maizzle.build('maizzle-ci', {
|
|
484
|
-
build: {
|
|
485
|
-
fail: 'silent',
|
|
486
|
-
templates: {
|
|
487
|
-
source: false,
|
|
488
|
-
destination: {
|
|
489
|
-
path: t.context.folder
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
})
|
|
494
|
-
}, {instanceOf: TypeError})
|
|
495
|
-
})
|
|
496
|
-
|
|
497
|
-
test('throws if templates path is invalid (function)', async t => {
|
|
498
|
-
await t.throwsAsync(async () => {
|
|
499
|
-
await Maizzle.build('maizzle-ci', {
|
|
500
|
-
build: {
|
|
501
|
-
fail: 'silent',
|
|
502
|
-
templates: {
|
|
503
|
-
source: () => {},
|
|
504
|
-
destination: {
|
|
505
|
-
path: t.context.folder
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
})
|
|
510
|
-
}, {instanceOf: TypeError})
|
|
511
|
-
})
|
|
1
|
+
const test = require('ava')
|
|
2
|
+
const fs = require('fs-extra')
|
|
3
|
+
const Maizzle = require('../src')
|
|
4
|
+
|
|
5
|
+
test.beforeEach(t => {
|
|
6
|
+
t.context.folder = '_temp_' + Math.random().toString(36).slice(2, 9)
|
|
7
|
+
t.context.log = console.log()
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test.afterEach.always(async t => {
|
|
11
|
+
if (t.context.folder) {
|
|
12
|
+
await fs.remove(t.context.folder)
|
|
13
|
+
delete t.context.folder
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('throws if config cannot be computed', async t => {
|
|
18
|
+
await t.throwsAsync(async () => {
|
|
19
|
+
await Maizzle.build('missing')
|
|
20
|
+
}, {instanceOf: Error, message: `could not load config.missing.js`})
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('skips if no templates found', async t => {
|
|
24
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
25
|
+
build: {
|
|
26
|
+
fail: 'silent',
|
|
27
|
+
templates: {
|
|
28
|
+
source: 'test/stubs/templates',
|
|
29
|
+
filetypes: 'fake',
|
|
30
|
+
destination: {
|
|
31
|
+
path: t.context.folder
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
tailwind: {
|
|
35
|
+
config: {
|
|
36
|
+
purge: false
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
t.is(files.length, 0)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('outputs files at the correct location', async t => {
|
|
46
|
+
const {files: string} = await Maizzle.build('maizzle-ci', {
|
|
47
|
+
build: {
|
|
48
|
+
fail: 'silent',
|
|
49
|
+
templates: {
|
|
50
|
+
source: 'test/stubs/templates',
|
|
51
|
+
destination: {
|
|
52
|
+
path: t.context.folder
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const {files: array} = await Maizzle.build('maizzle-ci', {
|
|
59
|
+
build: {
|
|
60
|
+
fail: 'silent',
|
|
61
|
+
templates: {
|
|
62
|
+
source: ['test/stubs/templates'],
|
|
63
|
+
destination: {
|
|
64
|
+
path: t.context.folder
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
t.true(await fs.pathExists(t.context.folder))
|
|
71
|
+
t.is(string.length, 2)
|
|
72
|
+
t.is(array.length, 2)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('outputs files at the correct location if multiple template sources are used', async t => {
|
|
76
|
+
const {files} = await Maizzle.build('local', {
|
|
77
|
+
build: {
|
|
78
|
+
fail: 'silent',
|
|
79
|
+
templates: [
|
|
80
|
+
{
|
|
81
|
+
source: 'test/stubs/templates',
|
|
82
|
+
destination: {
|
|
83
|
+
path: t.context.folder
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
source: 'test/stubs/plaintext',
|
|
88
|
+
destination: {
|
|
89
|
+
path: t.context.folder
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
t.true(await fs.pathExists(t.context.folder))
|
|
97
|
+
t.is(files.length, 3)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('copies all files in the `filetypes` option to destination', async t => {
|
|
101
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
102
|
+
build: {
|
|
103
|
+
fail: 'silent',
|
|
104
|
+
templates: {
|
|
105
|
+
source: 'test/stubs/templates',
|
|
106
|
+
filetypes: ['html', 'test'],
|
|
107
|
+
destination: {
|
|
108
|
+
path: t.context.folder
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
tailwind: {
|
|
112
|
+
config: {
|
|
113
|
+
purge: false
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
t.true(await fs.pathExists(t.context.folder))
|
|
120
|
+
t.is(files.length, 3)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('outputs files with the correct extension', async t => {
|
|
124
|
+
await Maizzle.build('maizzle-ci', {
|
|
125
|
+
build: {
|
|
126
|
+
fail: 'silent',
|
|
127
|
+
templates: {
|
|
128
|
+
source: 'test/stubs/templates',
|
|
129
|
+
destination: {
|
|
130
|
+
path: t.context.folder,
|
|
131
|
+
extension: 'blade.php'
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
tailwind: {
|
|
135
|
+
config: {
|
|
136
|
+
purge: false
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const filelist = await fs.readdir(t.context.folder)
|
|
143
|
+
|
|
144
|
+
t.true(filelist.includes('1.blade.php'))
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
test('outputs plaintext files', async t => {
|
|
148
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
149
|
+
fail: 'silent',
|
|
150
|
+
build: {
|
|
151
|
+
templates: {
|
|
152
|
+
source: 'test/stubs/plaintext',
|
|
153
|
+
destination: {
|
|
154
|
+
path: t.context.folder
|
|
155
|
+
},
|
|
156
|
+
plaintext: true
|
|
157
|
+
},
|
|
158
|
+
tailwind: {
|
|
159
|
+
config: {
|
|
160
|
+
purge: false
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
const plaintext = files.filter(file => file.includes('.txt'))
|
|
167
|
+
const html = files.filter(file => file.includes('.html'))
|
|
168
|
+
const plaintextContent = await fs.readFile(plaintext[0], 'utf8')
|
|
169
|
+
const htmlContent = await fs.readFile(html[0], 'utf8')
|
|
170
|
+
|
|
171
|
+
t.is(plaintext[0], `${t.context.folder}/plaintext.txt`)
|
|
172
|
+
t.is(plaintextContent, 'Show in HTML\nShow in plaintext')
|
|
173
|
+
t.is(htmlContent, '<div>Show in HTML</div>\n\n')
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
test('outputs plaintext files (custom path)', async t => {
|
|
177
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
178
|
+
fail: 'silent',
|
|
179
|
+
build: {
|
|
180
|
+
templates: {
|
|
181
|
+
source: 'test/stubs/plaintext',
|
|
182
|
+
destination: {
|
|
183
|
+
path: t.context.folder
|
|
184
|
+
},
|
|
185
|
+
plaintext: {
|
|
186
|
+
destination: {
|
|
187
|
+
path: `${t.context.folder}/nested/plain.text`
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
tailwind: {
|
|
192
|
+
config: {
|
|
193
|
+
purge: false
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
const plaintext = files.filter(file => file.includes('.text'))
|
|
200
|
+
|
|
201
|
+
t.is(plaintext[0], `${t.context.folder}/nested/plain.text`)
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
test('renders plaintext string', async t => {
|
|
205
|
+
const html = await fs.readFile('test/stubs/plaintext/plaintext.html', 'utf8')
|
|
206
|
+
const {plaintext} = await Maizzle.plaintext(html)
|
|
207
|
+
|
|
208
|
+
t.is(plaintext, 'Show in HTML\nShow in plaintext')
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
test('copies assets to destination', async t => {
|
|
212
|
+
await Maizzle.build('maizzle-ci', {
|
|
213
|
+
build: {
|
|
214
|
+
fail: 'silent',
|
|
215
|
+
templates: {
|
|
216
|
+
source: 'test/stubs/templates',
|
|
217
|
+
destination: {
|
|
218
|
+
path: t.context.folder
|
|
219
|
+
},
|
|
220
|
+
assets: {
|
|
221
|
+
source: 'test/stubs/assets',
|
|
222
|
+
destination: 'images'
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
tailwind: {
|
|
226
|
+
config: {
|
|
227
|
+
purge: false
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
const filelist = await fs.readdir(`${t.context.folder}/images`)
|
|
234
|
+
|
|
235
|
+
t.is(await fs.pathExists(`${t.context.folder}/images`), true)
|
|
236
|
+
t.is(filelist.length, 1)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
test('runs the `beforeCreate` event', async t => {
|
|
240
|
+
await Maizzle.build('maizzle-ci', {
|
|
241
|
+
build: {
|
|
242
|
+
fail: 'silent',
|
|
243
|
+
templates: {
|
|
244
|
+
source: 'test/stubs/events',
|
|
245
|
+
destination: {
|
|
246
|
+
path: t.context.folder
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
tailwind: {
|
|
250
|
+
config: {
|
|
251
|
+
purge: false
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
events: {
|
|
256
|
+
beforeCreate(config) {
|
|
257
|
+
config.foo = 'bar'
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
const filename = await fs.readdir(t.context.folder)
|
|
263
|
+
const html = await fs.readFile(`${t.context.folder}/${filename[0]}`, 'utf8')
|
|
264
|
+
|
|
265
|
+
t.is(html.trim(), 'Foo is bar')
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
test('runs the `afterBuild` event', async t => {
|
|
269
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
270
|
+
build: {
|
|
271
|
+
fail: 'silent',
|
|
272
|
+
templates: {
|
|
273
|
+
source: 'test/stubs/templates',
|
|
274
|
+
destination: {
|
|
275
|
+
path: t.context.folder
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
tailwind: {
|
|
279
|
+
config: {
|
|
280
|
+
purge: false
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
events: {
|
|
285
|
+
afterBuild(files) {
|
|
286
|
+
t.context.afterBuild = files
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
const getIntersection = (a, ...array) => [...new Set(a)].filter(v => array.every(b => b.includes(v)))
|
|
292
|
+
|
|
293
|
+
t.deepEqual(getIntersection(t.context.afterBuild, files), files)
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
test('supports multiple asset paths', async t => {
|
|
297
|
+
await Maizzle.build('maizzle-ci', {
|
|
298
|
+
build: {
|
|
299
|
+
fail: 'silent',
|
|
300
|
+
templates: {
|
|
301
|
+
source: 'test/stubs/templates',
|
|
302
|
+
destination: {
|
|
303
|
+
path: t.context.folder
|
|
304
|
+
},
|
|
305
|
+
assets: {
|
|
306
|
+
source: ['test/stubs/assets', 'test/stubs/plaintext', 'test/stubs/invalid'],
|
|
307
|
+
destination: 'extras'
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
tailwind: {
|
|
311
|
+
config: {
|
|
312
|
+
purge: false
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
t.true(await fs.pathExists(`${t.context.folder}/extras/foo.bar`))
|
|
319
|
+
t.true(await fs.pathExists(`${t.context.folder}/extras/plaintext.html`))
|
|
320
|
+
t.false(await fs.pathExists(`${t.context.folder}/extras/invalid`))
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
test('warns if a template cannot be rendered and `fail` option is undefined', async t => {
|
|
324
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
325
|
+
build: {
|
|
326
|
+
templates: {
|
|
327
|
+
source: 'test/stubs/breaking',
|
|
328
|
+
destination: {
|
|
329
|
+
path: t.context.folder
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
tailwind: {
|
|
333
|
+
config: {
|
|
334
|
+
purge: false
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
t.false(files.includes('empty.html'))
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
test('warns if a template cannot be rendered and `fail` option is `verbose`', async t => {
|
|
344
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
345
|
+
build: {
|
|
346
|
+
fail: 'verbose',
|
|
347
|
+
templates: {
|
|
348
|
+
source: 'test/stubs/breaking',
|
|
349
|
+
destination: {
|
|
350
|
+
path: t.context.folder
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
tailwind: {
|
|
354
|
+
config: {
|
|
355
|
+
purge: false
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
t.false(files.includes('empty.html'))
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
test('warns if a template cannot be rendered and `fail` option is `silent`', async t => {
|
|
365
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
366
|
+
build: {
|
|
367
|
+
fail: 'silent',
|
|
368
|
+
templates: {
|
|
369
|
+
source: 'test/stubs/breaking',
|
|
370
|
+
destination: {
|
|
371
|
+
path: t.context.folder
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
tailwind: {
|
|
375
|
+
config: {
|
|
376
|
+
purge: false
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
t.false(files.includes('empty.html'))
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
test('spins up local development server', async t => {
|
|
386
|
+
await Maizzle.serve('local', {
|
|
387
|
+
build: {
|
|
388
|
+
browsersync: {
|
|
389
|
+
ui: false
|
|
390
|
+
},
|
|
391
|
+
templates: {
|
|
392
|
+
source: 'test/stubs/templates',
|
|
393
|
+
destination: {
|
|
394
|
+
path: t.context.folder
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
t.true(await fs.pathExists(t.context.folder))
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
test('local server does not compile unwanted file types', async t => {
|
|
404
|
+
await Maizzle.serve('local', {
|
|
405
|
+
build: {
|
|
406
|
+
console: {
|
|
407
|
+
clear: true
|
|
408
|
+
},
|
|
409
|
+
browsersync: {
|
|
410
|
+
ui: false
|
|
411
|
+
},
|
|
412
|
+
templates: {
|
|
413
|
+
source: 'test/stubs/templates',
|
|
414
|
+
destination: {
|
|
415
|
+
path: `${t.context.folder}`
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
events: {
|
|
420
|
+
beforeCreate(config) {
|
|
421
|
+
config.foo = 'bar'
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
t.true(await fs.pathExists(`${t.context.folder}`))
|
|
427
|
+
t.true(await fs.pathExists(`${t.context.folder}/2.test`))
|
|
428
|
+
|
|
429
|
+
// Tests watching changes to files
|
|
430
|
+
await fs.outputFile('test/stubs/templates/1.html', 'html\n')
|
|
431
|
+
t.is(await fs.readFile('test/stubs/templates/1.html', 'utf8'), 'html\n')
|
|
432
|
+
|
|
433
|
+
// Don't trigger rebuilds on files not in filetypes
|
|
434
|
+
await fs.outputFile('test/stubs/templates/2.test', 'test\n')
|
|
435
|
+
t.is(await fs.readFile('test/stubs/templates/2.test', 'utf8'), 'test\n')
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
test('throws if it cannot spin up local development server', async t => {
|
|
439
|
+
await t.throwsAsync(async () => {
|
|
440
|
+
await Maizzle.serve('local', {})
|
|
441
|
+
}, {instanceOf: TypeError})
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
test('works with templates.source defined as function (string paths)', async t => {
|
|
445
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
446
|
+
build: {
|
|
447
|
+
fail: 'silent',
|
|
448
|
+
templates: {
|
|
449
|
+
source: () => 'test/stubs/templates',
|
|
450
|
+
destination: {
|
|
451
|
+
path: t.context.folder
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
t.true(await fs.pathExists(t.context.folder))
|
|
458
|
+
t.is(files.length, 2)
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
test('works with templates.source defined as function (array paths)', async t => {
|
|
462
|
+
const {files} = await Maizzle.build('maizzle-ci', {
|
|
463
|
+
build: {
|
|
464
|
+
fail: 'silent',
|
|
465
|
+
customSources: ['test/stubs/templates', 'test/stubs/templates'],
|
|
466
|
+
templates: {
|
|
467
|
+
source: config => {
|
|
468
|
+
return config.build.customSources
|
|
469
|
+
},
|
|
470
|
+
destination: {
|
|
471
|
+
path: t.context.folder
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
t.true(await fs.pathExists(t.context.folder))
|
|
478
|
+
t.is(files.length, 2)
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
test('throws if templates path is invalid', async t => {
|
|
482
|
+
await t.throwsAsync(async () => {
|
|
483
|
+
await Maizzle.build('maizzle-ci', {
|
|
484
|
+
build: {
|
|
485
|
+
fail: 'silent',
|
|
486
|
+
templates: {
|
|
487
|
+
source: false,
|
|
488
|
+
destination: {
|
|
489
|
+
path: t.context.folder
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
})
|
|
494
|
+
}, {instanceOf: TypeError})
|
|
495
|
+
})
|
|
496
|
+
|
|
497
|
+
test('throws if templates path is invalid (function)', async t => {
|
|
498
|
+
await t.throwsAsync(async () => {
|
|
499
|
+
await Maizzle.build('maizzle-ci', {
|
|
500
|
+
build: {
|
|
501
|
+
fail: 'silent',
|
|
502
|
+
templates: {
|
|
503
|
+
source: () => {},
|
|
504
|
+
destination: {
|
|
505
|
+
path: t.context.folder
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
})
|
|
510
|
+
}, {instanceOf: TypeError})
|
|
511
|
+
})
|