@maizzle/framework 3.7.3 → 4.0.0-alpha.3

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