@maizzle/framework 3.6.2 → 4.0.0-alpha.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 (39) hide show
  1. package/.github/dependabot.yml +11 -11
  2. package/.github/workflows/nodejs.yml +28 -29
  3. package/package.json +87 -84
  4. package/src/generators/output/to-disk.js +139 -111
  5. package/src/generators/output/to-string.js +71 -64
  6. package/src/generators/posthtml.js +61 -60
  7. package/src/generators/tailwindcss.js +49 -18
  8. package/src/index.js +24 -36
  9. package/src/transformers/{attribute-to-style.js → attributeToStyle.js} +0 -0
  10. package/src/transformers/baseUrl.js +45 -0
  11. package/src/transformers/{extra-attributes.js → extraAttributes.js} +0 -0
  12. package/src/transformers/index.js +13 -13
  13. package/src/transformers/{inline.js → inlineCss.js} +0 -0
  14. package/src/transformers/{posthtml-mso.js → posthtmlMso.js} +0 -0
  15. package/src/transformers/{prevent-widows.js → preventWidows.js} +0 -0
  16. package/src/transformers/{remove-attributes.js → removeAttributes.js} +1 -1
  17. package/src/transformers/{remove-inline-bgcolor.js → removeInlineBackgroundColor.js} +0 -0
  18. package/src/transformers/{remove-inline-sizes.js → removeInlineSizes.js} +0 -0
  19. package/src/transformers/{remove-unused-css.js → removeUnusedCss.js} +0 -0
  20. package/src/transformers/{replace-strings.js → replaceStrings.js} +0 -0
  21. package/src/transformers/{safe-class-names.js → safeClassNames.js} +8 -2
  22. package/src/transformers/{six-hex.js → sixHex.js} +10 -10
  23. package/src/transformers/transform.js +4 -6
  24. package/src/transformers/{url-params.js → urlParameters.js} +0 -0
  25. package/src/utils/helpers.js +2 -8
  26. package/test/expected/transformers/base-image-url.html +83 -0
  27. package/test/expected/transformers/transform-postcss.html +19 -0
  28. package/test/expected/useConfig.html +9 -0
  29. package/test/fixtures/basic.html +9 -0
  30. package/test/fixtures/transformers/base-image-url.html +85 -0
  31. package/test/fixtures/useConfig.html +9 -0
  32. package/test/stubs/tailwind/preserve.html +1 -0
  33. package/test/test-misc.js +8 -8
  34. package/test/test-tailwind.js +100 -73
  35. package/test/test-todisk.js +71 -29
  36. package/test/test-tostring.js +12 -3
  37. package/test/test-transformers.js +343 -314
  38. package/xo.config.js +4 -0
  39. package/src/transformers/base-image-url.js +0 -10
@@ -1,5 +1,3 @@
1
- const readline = require('readline')
2
-
3
1
  module.exports = {
4
2
  asyncForEach: async (array, callback) => {
5
3
  for (let index = 0; index < array.length; index++) {
@@ -14,10 +12,6 @@ module.exports = {
14
12
  throw new Error(`could not load ${module}`)
15
13
  }
16
14
  },
17
- clearConsole: () => {
18
- const blank = '\n'.repeat(process.stdout.rows)
19
- console.log(blank)
20
- readline.cursorTo(process.stdout, 0, 0)
21
- readline.clearScreenDown(process.stdout)
22
- }
15
+ // https://github.com/lukeed/console-clear
16
+ clearConsole: () => process.stdout.write('\x1B[H\x1B[2J')
23
17
  }
@@ -0,0 +1,83 @@
1
+ <html>
2
+ <head>
3
+ <style>.test {
4
+ background-image: url('https://example.com/image.jpg');
5
+ background: url('https://example.com/image.jpg');
6
+ background-image: url('https://preserve.me/image.jpg');
7
+ background: url('https://preserve.me/image.jpg');
8
+ }
9
+
10
+ .test-2 {
11
+ background-image: url("https://example.com/image.jpg");
12
+ background: url("https://example.com/image.jpg");
13
+ background-image: url("https://preserve.me/image.jpg");
14
+ background: url("https://preserve.me/image.jpg");
15
+ }
16
+
17
+ .test-3 {
18
+ background-image: url(https://example.com/image.jpg);
19
+ background: url(https://example.com/image.jpg);
20
+ background-image: url(https://preserve.me/image.jpg);
21
+ background: url(https://preserve.me/image.jpg);
22
+ }</style>
23
+ </head>
24
+
25
+ <body>
26
+ <img src="https://example.com/test.jpg">
27
+ <img src="https://example.com/test.jpg">
28
+
29
+ <img src="https://example.com/image1.jpg" srcset="https://example.com/image1-HD.jpg 2x, https://example.com/image1-phone.jpg 100w">
30
+
31
+ <img src="https://example.com/image2.jpg" srcset="https://example.com/image2-HD.jpg 2x, https://example.com/image2-phone.jpg 100w">
32
+
33
+ <picture>
34
+ <source media="(max-width: 799px)" srcset="https://example.com/elva-480w-close-portrait.jpg">
35
+ <source media="(min-width: 800px)" srcset="https://example.com/elva-800w.jpg">
36
+ <img src="https://example.com/elva-800w.jpg" alt="...">
37
+ </picture>
38
+
39
+ <video width="250" poster="https://example.com/flower.jpg">
40
+ <source src="https://example.com/media/flower.webm" type="video/webm">
41
+ <source src="https://example.tv/media/flower.mp4" type="video/mp4">
42
+ <track default="" kind="captions" srclang="en" src="https://example.com/media/tracks/friday.vtt">
43
+ </video>
44
+
45
+ <audio src="https://example.com/media/sample.mp3">
46
+ Fallback content
47
+ </audio>
48
+
49
+ <embed type="video/webm" src="https://example.com/media/flower.mp4" width="250" height="200">
50
+
51
+ <iframe width="300" height="200" src="https://example.com/embed.html"></iframe>
52
+
53
+ <input type="image" src="https://example.com/image.jpg" alt="">
54
+
55
+ <script src="https://example.com/javascript.js"></script>
56
+
57
+ <div>
58
+ <!--[if mso]>
59
+ <v:image xmlns:v="urn:schemas-microsoft-com:vml" src="https://example.com/image.jpg" style="600px;height:400px;" />
60
+ <v:rect fill="false" stroke="false" style="position:absolute;600px;height:400px;">
61
+ <v:textbox inset="0,0,0,0"><div><![endif]-->
62
+ <div>test</div>
63
+ <!--[if mso]></div></v:textbox></v:rect><![endif]-->
64
+ </div>
65
+
66
+ <table>
67
+ <tr>
68
+ <td background="https://example.com/image.png" bgcolor="#7bceeb" width="120" height="92" valign="top">
69
+ <!--[if gte mso 9]>
70
+ <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="width:120px;height:92px;">
71
+ <v:fill type="tile" src="https://example.com/image.png" color="#7bceeb" />
72
+ <v:textbox inset="0,0,0,0">
73
+ <![endif]-->
74
+ <div>test</div>
75
+ <!--[if gte mso 9]>
76
+ </v:textbox>
77
+ </v:rect>
78
+ <![endif]-->
79
+ </td>
80
+ </tr>
81
+ </table>
82
+ </body>
83
+ </html>
@@ -0,0 +1,19 @@
1
+ <style>.inline { display: inline !important
2
+ } .table { display: table !important
3
+ } .contents { display: contents !important
4
+ } .hidden { display: none !important
5
+ } .transform { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important
6
+ } div { width: 100%
7
+ } @media (min-width: 640px) { div { max-width: 640px
8
+ }
9
+ } @media (min-width: 768px) { div { max-width: 768px
10
+ }
11
+ } @media (min-width: 1024px) { div { max-width: 1024px
12
+ }
13
+ } @media (min-width: 1280px) { div { max-width: 1280px
14
+ }
15
+ } @media (min-width: 1536px) { div { max-width: 1536px
16
+ }
17
+ } div { display: none
18
+ }
19
+ </style>
@@ -0,0 +1,9 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>test></title>
5
+ </head>
6
+ <body>
7
+ <div>build_production</div>
8
+ </body>
9
+ </html>
@@ -0,0 +1,9 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>test></title>
5
+ </head>
6
+ <body>
7
+ <div>test</div>
8
+ </body>
9
+ </html>
@@ -0,0 +1,85 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ .test {
5
+ background-image: url('image.jpg');
6
+ background: url('image.jpg');
7
+ background-image: url('https://preserve.me/image.jpg');
8
+ background: url('https://preserve.me/image.jpg');
9
+ }
10
+
11
+ .test-2 {
12
+ background-image: url("image.jpg");
13
+ background: url("image.jpg");
14
+ background-image: url("https://preserve.me/image.jpg");
15
+ background: url("https://preserve.me/image.jpg");
16
+ }
17
+
18
+ .test-3 {
19
+ background-image: url(image.jpg);
20
+ background: url(image.jpg);
21
+ background-image: url(https://preserve.me/image.jpg);
22
+ background: url(https://preserve.me/image.jpg);
23
+ }
24
+ </style>
25
+ </head>
26
+
27
+ <body>
28
+ <img src="test.jpg">
29
+ <img src="https://example.com/test.jpg">
30
+
31
+ <img src="image1.jpg" srcset="image1-HD.jpg 2x,image1-phone.jpg 100w">
32
+
33
+ <img src="https://example.com/image2.jpg" srcset="https://example.com/image2-HD.jpg 2x, https://example.com/image2-phone.jpg 100w">
34
+
35
+ <picture>
36
+ <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
37
+ <source media="(min-width: 800px)" srcset="elva-800w.jpg">
38
+ <img src="elva-800w.jpg" alt="...">
39
+ </picture>
40
+
41
+ <video width="250" poster="flower.jpg">
42
+ <source src="media/flower.webm" type="video/webm">
43
+ <source src="https://example.tv/media/flower.mp4" type="video/mp4">
44
+ <track default kind="captions" srclang="en" src="media/tracks/friday.vtt">
45
+ </video>
46
+
47
+ <audio src="media/sample.mp3">
48
+ Fallback content
49
+ </audio>
50
+
51
+ <embed type="video/webm" src="media/flower.mp4" width="250" height="200">
52
+
53
+ <iframe width="300" height="200" src="embed.html"></iframe>
54
+
55
+ <input type="image" src="image.jpg" alt="">
56
+
57
+ <script src="javascript.js"></script>
58
+
59
+ <div>
60
+ <!--[if mso]>
61
+ <v:image xmlns:v="urn:schemas-microsoft-com:vml" src="image.jpg" style="600px;height:400px;" />
62
+ <v:rect fill="false" stroke="false" style="position:absolute;600px;height:400px;">
63
+ <v:textbox inset="0,0,0,0"><div><![endif]-->
64
+ <div>test</div>
65
+ <!--[if mso]></div></v:textbox></v:rect><![endif]-->
66
+ </div>
67
+
68
+ <table>
69
+ <tr>
70
+ <td background="image.png" bgcolor="#7bceeb" width="120" height="92" valign="top">
71
+ <!--[if gte mso 9]>
72
+ <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="width:120px;height:92px;">
73
+ <v:fill type="tile" src="image.png" color="#7bceeb" />
74
+ <v:textbox inset="0,0,0,0">
75
+ <![endif]-->
76
+ <div>test</div>
77
+ <!--[if gte mso 9]>
78
+ </v:textbox>
79
+ </v:rect>
80
+ <![endif]-->
81
+ </td>
82
+ </tr>
83
+ </table>
84
+ </body>
85
+ </html>
@@ -0,0 +1,9 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>test></title>
5
+ </head>
6
+ <body>
7
+ <div>{{ page.build.templates.destination.path }}</div>
8
+ </body>
9
+ </html>
@@ -0,0 +1 @@
1
+ <div class="hidden"></div>
package/test/test-misc.js CHANGED
@@ -1,8 +1,8 @@
1
- const test = require('ava')
2
- const path = require('path')
3
- const {requireUncached} = require('../src/utils/helpers')
4
-
5
- test('requires an uncached module', t => {
6
- const helpers = requireUncached(path.resolve(process.cwd(), 'src/utils/helpers'))
7
- t.is(typeof helpers.requireUncached, 'function')
8
- })
1
+ const test = require('ava')
2
+ const path = require('path')
3
+ const {requireUncached} = require('../src/utils/helpers')
4
+
5
+ test('requires an uncached module', t => {
6
+ const helpers = requireUncached(path.resolve(process.cwd(), 'src/utils/helpers'))
7
+ t.is(typeof helpers.requireUncached, 'function')
8
+ })
@@ -1,73 +1,100 @@
1
- const test = require('ava')
2
- const Tailwind = require('../src/generators/tailwindcss')
3
-
4
- test('uses Tailwind defaults if no config specified', async t => {
5
- const css = await Tailwind.compile('@tailwind utilities', '<p class="xl:z-0"></p>', {}, {env: 'production'})
6
-
7
- t.not(css, undefined)
8
- t.true(css.includes('.xl\\:z-0'))
9
- })
10
-
11
- test('uses CSS file provided in environment config', async t => {
12
- const config = {
13
- env: 'production',
14
- build: {
15
- tailwind: {
16
- css: './test/stubs/main.css'
17
- }
18
- }
19
- }
20
-
21
- const css = await Tailwind.compile('', '<div class="text-center foo">test</div>', {}, config)
22
-
23
- t.not(css, undefined)
24
- t.true(css.includes('.text-center'))
25
- t.true(css.includes('.foo'))
26
- })
27
-
28
- test('uses purgeCSS options provided in the maizzle config', async t => {
29
- const arrayConfig = {
30
- purgeCSS: {
31
- safelist: ['z-10'],
32
- blocklist: ['text-center']
33
- }
34
- }
35
-
36
- const objectConfig = {
37
- purgeCSS: {
38
- safelist: {
39
- standard: ['z-10']
40
- },
41
- blocklist: ['text-center']
42
- }
43
- }
44
-
45
- const css1 = await Tailwind.compile('@tailwind utilities', '<div class="z-0 text-center"></div>', {}, arrayConfig)
46
- const css2 = await Tailwind.compile('@tailwind utilities', '<div class="z-0 text-center"></div>', {}, objectConfig)
47
-
48
- t.true(css1.includes('.z-0'))
49
- t.true(css1.includes('.z-10'))
50
- t.false(css1.includes('.text-center'))
51
-
52
- t.true(css2.includes('.z-0'))
53
- t.true(css2.includes('.z-10'))
54
- t.false(css2.includes('.text-center'))
55
- })
56
-
57
- test('uses postcss plugins from the maizzle config when compiling from string', async t => {
58
- const maizzleConfig = {
59
- env: 'production',
60
- build: {
61
- postcss: {
62
- plugins: [
63
- require('autoprefixer')({overrideBrowserslist: ['> 0.1%']})
64
- ]
65
- }
66
- }
67
- }
68
-
69
- const css = await Tailwind.compile('.test {transform: scale(0.5)}', '<div class="test">Test</a>', {}, maizzleConfig)
70
-
71
- t.not(css, undefined)
72
- t.is(css.trim(), '/* purgecss start ignore */\n\n.test {\n -webkit-transform: scale(0.5);\n transform: scale(0.5)\n}\n\n/* purgecss end ignore */')
73
- })
1
+ const test = require('ava')
2
+ const ora = require('ora')
3
+ const Tailwind = require('../src/generators/tailwindcss')
4
+
5
+ test('throws on compile error', async t => {
6
+ await t.throwsAsync(async () => {
7
+ const spinner = ora('Compiling Tailwind CSS...').start()
8
+ await Tailwind.compile('.test {@apply inexistent;}', '<div class="test">Test</a>', {}, {}, spinner)
9
+ }, {instanceOf: Error, message: 'Tailwind CSS compilation failed'})
10
+ })
11
+
12
+ test('uses Tailwind defaults if no config specified', async t => {
13
+ const css = await Tailwind.compile(
14
+ '@tailwind utilities;',
15
+ '<p class="xl:z-0"></p>',
16
+ {},
17
+ {env: 'production'}
18
+ )
19
+
20
+ t.not(css, undefined)
21
+ t.true(css.includes('.xl\\:z-0'))
22
+ })
23
+
24
+ test('uses CSS file provided in environment config', async t => {
25
+ const config = {
26
+ env: 'production',
27
+ build: {
28
+ tailwind: {
29
+ css: './test/stubs/main.css'
30
+ }
31
+ }
32
+ }
33
+
34
+ const css = await Tailwind.compile('', '<div class="text-center foo">test</div>', {}, config)
35
+
36
+ t.not(css, undefined)
37
+ t.true(css.includes('.text-center'))
38
+ t.true(css.includes('.foo'))
39
+ })
40
+
41
+ test('works with custom `content` sources', async t => {
42
+ const css = await Tailwind.compile(
43
+ '@tailwind utilities;',
44
+ '<div class="hidden"></div>',
45
+ {
46
+ content: ['./test/stubs/tailwind/*.*']
47
+ }
48
+ )
49
+
50
+ t.true(css.includes('.hidden'))
51
+ })
52
+
53
+ test('works with custom `files` sources', async t => {
54
+ const css = await Tailwind.compile(
55
+ '@tailwind utilities;',
56
+ '<div></div>',
57
+ {
58
+ content: {
59
+ files: ['./test/stubs/tailwind/*.*']
60
+ }
61
+ }
62
+ )
63
+
64
+ t.true(css.includes('.hidden'))
65
+ })
66
+
67
+ test('uses maizzle template paths when purging', async t => {
68
+ const css = await Tailwind.compile(
69
+ '@tailwind utilities;',
70
+ '<div></div>',
71
+ {},
72
+ {
73
+ build: {
74
+ templates: {
75
+ source: './test/stubs/tailwind'
76
+ }
77
+ }
78
+ }
79
+ )
80
+
81
+ t.true(css.includes('.hidden'))
82
+ })
83
+
84
+ test('uses custom postcss plugins from the maizzle config', async t => {
85
+ const maizzleConfig = {
86
+ env: 'production',
87
+ build: {
88
+ postcss: {
89
+ plugins: [
90
+ require('autoprefixer')({overrideBrowserslist: ['> 0.1%']})
91
+ ]
92
+ }
93
+ }
94
+ }
95
+
96
+ const css = await Tailwind.compile('.test {transform: scale(0.5)}', '<div class="test">Test</a>', {}, maizzleConfig)
97
+
98
+ t.not(css, undefined)
99
+ t.is(css.trim(), '.test {-webkit-transform: scale(0.5);transform: scale(0.5)}')
100
+ })
@@ -16,12 +16,12 @@ test.afterEach.always(async t => {
16
16
 
17
17
  test('throws if config cannot be computed', async t => {
18
18
  await t.throwsAsync(async () => {
19
- await Maizzle.build('production')
20
- }, {instanceOf: Error, message: `could not load config.production.js`})
19
+ await Maizzle.build('missing')
20
+ }, {instanceOf: Error, message: `could not load config.missing.js`})
21
21
  })
22
22
 
23
23
  test('skips if no templates found', async t => {
24
- const {files} = await Maizzle.build('production', {
24
+ const {files} = await Maizzle.build('maizzle-ci', {
25
25
  build: {
26
26
  fail: 'silent',
27
27
  templates: {
@@ -43,7 +43,7 @@ test('skips if no templates found', async t => {
43
43
  })
44
44
 
45
45
  test('outputs files at the correct location', async t => {
46
- const {files} = await Maizzle.build('production', {
46
+ const {files: string} = await Maizzle.build('maizzle-ci', {
47
47
  build: {
48
48
  fail: 'silent',
49
49
  templates: {
@@ -51,17 +51,25 @@ test('outputs files at the correct location', async t => {
51
51
  destination: {
52
52
  path: t.context.folder
53
53
  }
54
- },
55
- tailwind: {
56
- config: {
57
- purge: false
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
58
65
  }
59
66
  }
60
67
  }
61
68
  })
62
69
 
63
70
  t.true(fs.pathExistsSync(t.context.folder))
64
- t.is(files.length, 3)
71
+ t.is(string.length, 3)
72
+ t.is(array.length, 3)
65
73
  })
66
74
 
67
75
  test('outputs files at the correct location if multiple template sources are used', async t => {
@@ -90,7 +98,7 @@ test('outputs files at the correct location if multiple template sources are use
90
98
  })
91
99
 
92
100
  test('copies all files in the `filetypes` option to destination', async t => {
93
- const {files} = await Maizzle.build('production', {
101
+ const {files} = await Maizzle.build('maizzle-ci', {
94
102
  build: {
95
103
  fail: 'silent',
96
104
  templates: {
@@ -113,7 +121,7 @@ test('copies all files in the `filetypes` option to destination', async t => {
113
121
  })
114
122
 
115
123
  test('outputs files with the correct extension', async t => {
116
- await Maizzle.build('production', {
124
+ await Maizzle.build('maizzle-ci', {
117
125
  build: {
118
126
  fail: 'silent',
119
127
  templates: {
@@ -135,22 +143,22 @@ test('outputs files with the correct extension', async t => {
135
143
  })
136
144
 
137
145
  test('outputs plaintext files', async t => {
138
- const {files} = await Maizzle.build('production', {
146
+ const {files} = await Maizzle.build('maizzle-ci', {
139
147
  fail: 'silent',
140
148
  build: {
141
149
  templates: {
142
150
  source: 'test/stubs/plaintext',
143
151
  destination: {
144
152
  path: t.context.folder
145
- }
153
+ },
154
+ plaintext: true
146
155
  },
147
156
  tailwind: {
148
157
  config: {
149
158
  purge: false
150
159
  }
151
160
  }
152
- },
153
- plaintext: true
161
+ }
154
162
  })
155
163
 
156
164
  const plaintext = files.filter(file => file.includes('.txt'))
@@ -164,13 +172,18 @@ test('outputs plaintext files', async t => {
164
172
  })
165
173
 
166
174
  test('outputs plaintext files (custom path)', async t => {
167
- const {files} = await Maizzle.build('production', {
175
+ const {files} = await Maizzle.build('maizzle-ci', {
168
176
  fail: 'silent',
169
177
  build: {
170
178
  templates: {
171
179
  source: 'test/stubs/plaintext',
172
180
  destination: {
173
181
  path: t.context.folder
182
+ },
183
+ plaintext: {
184
+ destination: {
185
+ path: `${t.context.folder}/nested/plain.text`
186
+ }
174
187
  }
175
188
  },
176
189
  tailwind: {
@@ -178,11 +191,6 @@ test('outputs plaintext files (custom path)', async t => {
178
191
  purge: false
179
192
  }
180
193
  }
181
- },
182
- plaintext: {
183
- destination: {
184
- path: `${t.context.folder}/nested/plain.text`
185
- }
186
194
  }
187
195
  })
188
196
 
@@ -199,7 +207,7 @@ test('renders plaintext string', async t => {
199
207
  })
200
208
 
201
209
  test('copies assets to destination', async t => {
202
- await Maizzle.build('production', {
210
+ await Maizzle.build('maizzle-ci', {
203
211
  build: {
204
212
  fail: 'silent',
205
213
  templates: {
@@ -225,7 +233,7 @@ test('copies assets to destination', async t => {
225
233
  })
226
234
 
227
235
  test('runs the `beforeCreate` event', async t => {
228
- await Maizzle.build('production', {
236
+ await Maizzle.build('maizzle-ci', {
229
237
  build: {
230
238
  fail: 'silent',
231
239
  templates: {
@@ -253,7 +261,7 @@ test('runs the `beforeCreate` event', async t => {
253
261
  })
254
262
 
255
263
  test('runs the `afterBuild` event', async t => {
256
- const {files} = await Maizzle.build('production', {
264
+ const {files} = await Maizzle.build('maizzle-ci', {
257
265
  build: {
258
266
  fail: 'silent',
259
267
  templates: {
@@ -281,7 +289,7 @@ test('runs the `afterBuild` event', async t => {
281
289
  })
282
290
 
283
291
  test('supports multiple asset paths', async t => {
284
- await Maizzle.build('production', {
292
+ await Maizzle.build('maizzle-ci', {
285
293
  build: {
286
294
  fail: 'silent',
287
295
  templates: {
@@ -308,7 +316,7 @@ test('supports multiple asset paths', async t => {
308
316
  })
309
317
 
310
318
  test('warns if a template cannot be rendered and `fail` option is undefined', async t => {
311
- const {files} = await Maizzle.build('production', {
319
+ const {files} = await Maizzle.build('maizzle-ci', {
312
320
  build: {
313
321
  templates: {
314
322
  source: 'test/stubs/breaking',
@@ -328,7 +336,7 @@ test('warns if a template cannot be rendered and `fail` option is undefined', as
328
336
  })
329
337
 
330
338
  test('warns if a template cannot be rendered and `fail` option is `verbose`', async t => {
331
- const {files} = await Maizzle.build('production', {
339
+ const {files} = await Maizzle.build('maizzle-ci', {
332
340
  build: {
333
341
  fail: 'verbose',
334
342
  templates: {
@@ -349,7 +357,7 @@ test('warns if a template cannot be rendered and `fail` option is `verbose`', as
349
357
  })
350
358
 
351
359
  test('warns if a template cannot be rendered and `fail` option is `silent`', async t => {
352
- const {files} = await Maizzle.build('production', {
360
+ const {files} = await Maizzle.build('maizzle-ci', {
353
361
  build: {
354
362
  fail: 'silent',
355
363
  templates: {
@@ -414,5 +422,39 @@ test('local server does not compile unwanted file types', async t => {
414
422
  test('throws if it cannot spin up local development server', async t => {
415
423
  await t.throwsAsync(async () => {
416
424
  await Maizzle.serve('local', {})
417
- }, {instanceOf: TypeError, message: `Cannot read property 'source' of undefined`})
425
+ }, {instanceOf: TypeError})
426
+ })
427
+
428
+ test('works with templates.source defined as function (string paths)', async t => {
429
+ const {files} = await Maizzle.build('maizzle-ci', {
430
+ build: {
431
+ fail: 'silent',
432
+ templates: {
433
+ source: () => 'test/stubs/templates',
434
+ destination: {
435
+ path: t.context.folder
436
+ }
437
+ }
438
+ }
439
+ })
440
+
441
+ t.true(fs.pathExistsSync(t.context.folder))
442
+ t.is(files.length, 3)
443
+ })
444
+
445
+ test('works with templates.source defined as function (array paths)', async t => {
446
+ const {files} = await Maizzle.build('maizzle-ci', {
447
+ build: {
448
+ fail: 'silent',
449
+ templates: {
450
+ source: () => ['test/stubs/templates', 'test/stubs/templates'],
451
+ destination: {
452
+ path: t.context.folder
453
+ }
454
+ }
455
+ }
456
+ })
457
+
458
+ t.true(fs.pathExistsSync(t.context.folder))
459
+ t.is(files.length, 3)
418
460
  })