@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.
Files changed (58) hide show
  1. package/.editorconfig +9 -9
  2. package/.github/workflows/nodejs.yml +28 -28
  3. package/LICENSE +21 -21
  4. package/bin/maizzle +3 -3
  5. package/package.json +2 -2
  6. package/src/generators/config.js +32 -32
  7. package/src/generators/output/index.js +4 -4
  8. package/src/generators/output/to-disk.js +208 -208
  9. package/src/generators/output/to-string.js +67 -67
  10. package/src/generators/postcss.js +29 -29
  11. package/src/generators/posthtml.js +66 -66
  12. package/src/index.js +17 -17
  13. package/src/transformers/attributeToStyle.js +90 -90
  14. package/src/transformers/baseUrl.js +69 -69
  15. package/src/transformers/extraAttributes.js +26 -26
  16. package/src/transformers/filters/defaultFilters.js +126 -126
  17. package/src/transformers/filters/index.js +55 -55
  18. package/src/transformers/inlineCss.js +37 -37
  19. package/src/transformers/markdown.js +19 -19
  20. package/src/transformers/minify.js +21 -21
  21. package/src/transformers/plaintext.js +23 -23
  22. package/src/transformers/posthtmlMso.js +10 -10
  23. package/src/transformers/prettify.js +27 -27
  24. package/src/transformers/preventWidows.js +13 -13
  25. package/src/transformers/removeAttributes.js +17 -17
  26. package/src/transformers/removeInlineBackgroundColor.js +52 -52
  27. package/src/transformers/removeInlineSizes.js +41 -41
  28. package/src/transformers/replaceStrings.js +14 -14
  29. package/src/transformers/safeClassNames.js +24 -24
  30. package/src/transformers/shorthandInlineCSS.js +19 -19
  31. package/src/transformers/sixHex.js +33 -33
  32. package/src/transformers/urlParameters.js +17 -17
  33. package/src/utils/helpers.js +17 -17
  34. package/test/expected/posthtml/extend-template.html +2 -2
  35. package/test/expected/posthtml/fetch.html +5 -5
  36. package/test/expected/posthtml/layout.html +3 -3
  37. package/test/expected/transformers/base-url.html +99 -99
  38. package/test/fixtures/posthtml/extend-template.html +7 -7
  39. package/test/fixtures/posthtml/fetch.html +9 -9
  40. package/test/fixtures/posthtml/layout.html +11 -11
  41. package/test/fixtures/transformers/base-url.html +101 -101
  42. package/test/stubs/assets/foo.bar +1 -1
  43. package/test/stubs/breaking/bad.html +5 -5
  44. package/test/stubs/config/config.js +10 -10
  45. package/test/stubs/config/config.maizzle-ci.js +10 -10
  46. package/test/stubs/data.json +14 -14
  47. package/test/stubs/events/before-create.html +1 -1
  48. package/test/stubs/layouts/basic.html +1 -1
  49. package/test/stubs/layouts/full.html +12 -12
  50. package/test/stubs/layouts/template.html +5 -5
  51. package/test/stubs/main.css +5 -5
  52. package/test/stubs/tailwind/content-source.html +1 -1
  53. package/test/stubs/tailwind/tailwind.css +3 -3
  54. package/test/stubs/template.html +10 -10
  55. package/test/test-posthtml.js +72 -72
  56. package/test/test-todisk.js +511 -511
  57. package/test/test-transformers.js +1 -0
  58. package/xo.config.js +22 -22
@@ -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
+ })