gulp-metalsmith
Advanced tools
Comparing version 0.3.0 to 1.0.0
131
lib/index.js
@@ -11,43 +11,25 @@ var path = require('path'); | ||
var PLUGIN_NAME = 'gulp-metalsmith'; | ||
var TYPE_VINYL = 'vinyl'; | ||
var TYPE_JSON = 'json'; | ||
var plugin = _.partial(pluginFn, TYPE_VINYL); | ||
plugin.json = _.partial(pluginFn, TYPE_JSON); | ||
plugin.PLUGIN_NAME = PLUGIN_NAME; | ||
module.exports = plugin; | ||
function pluginFn(type, opts) { | ||
function plugin(opts) { | ||
var s = through.obj(transform, flush); | ||
var add = type === TYPE_JSON ? addJsonDefinedFiles : addVinylFile; | ||
var files = {}; | ||
opts = _.isObject(opts) ? opts : {}; | ||
opts.root = opts.root || process.cwd(); | ||
opts.use = (_.isFunction(opts.use) ? [opts.use] : opts.use) || []; | ||
opts.frontmatter = opts.frontmatter !== false; | ||
opts.json = opts.json === true ? '**/*.json' : opts.json; | ||
var root = opts.root || process.cwd(); | ||
var m = metalsmith(root); | ||
var ignored = prepareIgnored(); | ||
var m = metalsmith(opts.root); | ||
var ignored = matchGlobs(opts.ignore, opts.root); | ||
var jsonDefinitions = matchGlobs(opts.json, opts.root); | ||
prepareMiddleware().forEach(m.use); | ||
m.metadata(opts.metadata || {}); | ||
opts.use.forEach(m.use); | ||
return s; | ||
function prepareMiddleware() { | ||
var use = opts.use || []; | ||
return _.isFunction(use) ? [use] : use; | ||
} | ||
function prepareIgnored() { | ||
if (!_.isString(opts.ignore) && !_.isArray(opts.ignore)) { | ||
return []; | ||
} | ||
return globby.sync(opts.ignore, {cwd: root}).map(function (match) { | ||
return path.join(root, match); | ||
}); | ||
} | ||
function transform(file, enc, cb) { | ||
@@ -57,7 +39,4 @@ if (file.isStream()) { | ||
} | ||
if (file.isBuffer() && ignored.indexOf(file.path) < 0) { | ||
var key = file.path.replace(file.base, ''); | ||
var contents = file.contents; | ||
add(key, contents); | ||
else if (file.isBuffer() && !isIgnored(file)) { | ||
processFile(file); | ||
} | ||
@@ -68,2 +47,25 @@ | ||
function processFile(file) { | ||
var key = file.path.replace(file.base, ''); | ||
var contents = file.contents; | ||
if (isJsonDefinition(file) && utf8(contents)) { | ||
_.extend(files, createFilesFromJsonDefinition(contents.toString())); | ||
} | ||
else if (opts.frontmatter && utf8(contents)) { | ||
files[key] = parseFrontmatter(contents.toString()); | ||
} | ||
else { | ||
files[key] = {contents: contents}; | ||
} | ||
} | ||
function isIgnored(file) { | ||
return ignored.indexOf(file.path) > -1; | ||
} | ||
function isJsonDefinition(file) { | ||
return jsonDefinitions.indexOf(file.path) > -1; | ||
} | ||
function flush(cb) { | ||
@@ -87,36 +89,9 @@ m.run(files, function (err, transformed) { | ||
function addVinylFile(key, contents) { | ||
if (opts.frontmatter && utf8(contents)) { | ||
var parsed = fm(contents.toString()); | ||
var bodyBuf = new Buffer(parsed.body); | ||
files[key] = _.extend({contents: bodyBuf}, parsed.attributes); | ||
} else { | ||
files[key] = {contents: contents}; | ||
} | ||
} | ||
function addJsonDefinedFiles(key, contents) { | ||
if (!utf8(contents)) { | ||
files[key] = {contents: contents}; | ||
return; | ||
} | ||
var parsed = {}; | ||
function createFilesFromJsonDefinition(contents) { | ||
try { | ||
parsed = JSON.parse(contents.toString()); | ||
return createFilesExtension(parseJsonDefinition(contents)); | ||
} catch (err) { | ||
emitError(err); | ||
return {}; | ||
} | ||
if (!_.isPlainObject(parsed)) { | ||
emitError('JSON file should contain a single root object.'); | ||
} | ||
_.forOwn(parsed, function (value, key) { | ||
if (_.isObject(value)) { | ||
value.contents = new Buffer(value.contents || ''); | ||
files[key] = value; | ||
} | ||
}); | ||
} | ||
@@ -130,1 +105,35 @@ | ||
} | ||
function matchGlobs(globs, root) { | ||
if (!_.isString(globs) && !_.isArray(globs)) { | ||
return []; | ||
} | ||
return globby.sync(globs, {cwd: root}).map(function (match) { | ||
return path.join(root, match); | ||
}); | ||
} | ||
function parseFrontmatter(contents) { | ||
var parsed = fm(contents); | ||
var bodyBuf = new Buffer(parsed.body); | ||
return _.extend({contents: bodyBuf}, parsed.attributes); | ||
} | ||
function createFilesExtension(files) { | ||
return _.transform(files, function (result, value, key) { | ||
if (_.isPlainObject(value)) { | ||
value.contents = new Buffer(value.contents || ''); | ||
result[key] = value; | ||
} | ||
}, {}); | ||
} | ||
function parseJsonDefinition(contents) { | ||
var parsed = JSON.parse(contents); | ||
if (_.isPlainObject(parsed)) { | ||
return parsed; | ||
} else { | ||
throw new Error('JSON file should contain a single root object.'); | ||
} | ||
} |
{ | ||
"name": "gulp-metalsmith", | ||
"version": "0.3.0", | ||
"version": "1.0.0", | ||
"description": "Lightweight gulp plugin for Metalsmith", | ||
@@ -17,7 +17,7 @@ "keywords": [ | ||
"scripts": { | ||
"lint": "jshint lib/*.js test/*.js example/*.js", | ||
"lint": "jshint lib/*.js test/*.js tutorial/*.js", | ||
"hint": "npm run lint", | ||
"test": "faucet test/*.js", | ||
"test-all": "npm run lint && npm test", | ||
"clean": "rm -rf node_modules example/build", | ||
"clean": "rm -rf node_modules coverage tutorial/node_modules tutorial/build", | ||
"coverage": "istanbul cover tape test/*.js", | ||
@@ -38,12 +38,7 @@ "coverage-codecov": "cat ./coverage/coverage.json | codecov" | ||
"codecov": "^1.0.1", | ||
"del": "^2.2.0", | ||
"faucet": "0.0.1", | ||
"gulp": "^3.8.11", | ||
"istanbul": "^0.4.2", | ||
"jshint": "^2.9.1", | ||
"metalsmith-layouts": "^1.0.0", | ||
"metalsmith-permalinks": "^0.5.0", | ||
"swig": "^1.4.2", | ||
"tape": "^4.5.0" | ||
} | ||
} |
@@ -10,8 +10,30 @@ # gulp-metalsmith | ||
`gulp-metalsmith` is a [gulp](https://github.com/gulpjs/gulp) plugin that incorporates [Metalsmith](http://www.metalsmith.io) builds into gulp pipelines. It aims to be as lightweight as possible. It ships with Metalsmith's replacement that has compatible API (can reuse Metalsmith plugins) and is able to recive JavaScript object containing page definitions. After build, it streams out `vinyl` files. The main difference between bundled Metalsmith and normal Metalsmith is that it does not perform any disc read/write operations, leaving it out to `gulp`. | ||
`gulp-metalsmith` can be feed with specially formatted JSON. It allows building static pages using content providers, like [prismic.io](https://prismic.io) or [Contentful](https://www.contentful.com). | ||
## API changes! | ||
### Installation | ||
Please note that as of v1.0.0 `metalsmith.json()` method is not available. Use | ||
the [`json` configuration option](#use-it-with-json) instead. | ||
## Tutorial | ||
This README file doesn't make sense at first glance or is too technical? **See | ||
[the `gulp-metalsmith` tutorial](./tutorial)**! | ||
## About | ||
`gulp-metalsmith` is a [gulp](https://github.com/gulpjs/gulp) plugin that | ||
incorporates [Metalsmith](http://www.metalsmith.io) builds into gulp pipelines. | ||
It aims to be as lightweight as possible. It is shipped with an API-compatible | ||
Metalsmith replacement that can reuse Metalsmith plugins. It can be [fed with | ||
JSON files containing page definitions](#use-it-with-json). | ||
After build `gulp-metalsmith` streams out `vinyl`files. The main difference | ||
between the bundled Metalsmith and the normal Metalsmith is that it does not | ||
perform any disc read/write operations, leaving it to `gulp`. | ||
## Installation | ||
```sh | ||
@@ -21,7 +43,9 @@ $ npm install --save-dev gulp-metalsmith | ||
### Use it with gulp | ||
## Usage | ||
The simplest build task (just copies all files from `src/` to `build/`): | ||
```js | ||
gulp.task('metalsmith', ['clean'], function() { | ||
gulp.task('metalsmith', function() { | ||
return gulp.src('src/**') | ||
@@ -34,23 +58,32 @@ .pipe(metalsmith()) | ||
All options: | ||
```js | ||
s.pipe(metalsmith({ | ||
// set Metalsmith's root directory, for example for locating templates, defaults to CWD | ||
gulp.src('src/**').pipe(metalsmith({ | ||
// Metalsmith's root directory, for example for locating templates, defaults to CWD | ||
root: __dirname, | ||
// files to exclude from the build | ||
// Files to exclude from the build | ||
ignore: ['src/*.tmp'], | ||
// read frontmatter, defaults to true | ||
// Parsing frontmatter, defaults to true | ||
frontmatter: true, | ||
// Metalsmith plugins to use | ||
use: [ permalinks(), layouts({ engine: 'swig' }) ], | ||
// Initial Metalsmith metadata: | ||
// Metalsmith plugins to use: | ||
use: [ | ||
markdown(), | ||
layouts({engine: 'swig'}) | ||
], | ||
// Initial Metalsmith metadata, defaults to {} | ||
metadata: { | ||
site_title: 'Sample static site' | ||
} | ||
}, | ||
// List of JSON files that contain page definitions | ||
// true means "all JSON files", see the section below | ||
json: ['src/pages.json'] | ||
})); | ||
``` | ||
### Feed it with JSON | ||
## Use it with JSON | ||
Given the file `src/pages.json`: | ||
```json | ||
```js | ||
{ | ||
@@ -71,22 +104,30 @@ "index.html": { | ||
You can do this: | ||
```js | ||
gulp.task('metalsmith-json', ['clean'], function() { | ||
return gulp.src('src/pages.json') | ||
.pipe(metalsmith.json({ use: [ layouts({ engine: 'swig' }) ])) | ||
.pipe(gulp.dest('build')); | ||
}); | ||
gulp.src('src/**').pipe(metalsmith({ | ||
use: [layouts({engine: 'swig'})], | ||
json: true | ||
})); | ||
``` | ||
Multiple JSON files (`*.json`) are also accepted. | ||
This way your Metalsmith build will contain two additional files, `index.html` | ||
and `contact.html`. The source file `pages.json` won't be included. Following | ||
rules apply: | ||
### Examples, tests | ||
- be default all JSON files in the pipeline are included "as is" | ||
- when the `json` configuration options is set to `true`, all JSON files are | ||
parsed and replaced with files defined in their content | ||
- when the `json` configuration option is a glob string or an array of globs, | ||
only JSON files matching these globs are parsed and define new files. The rest | ||
of JSON files is passed "as is" | ||
Examples are stored in `example/`. Tests can be run with `npm test`. | ||
### Author | ||
## Author | ||
[Jakub Elżbieciak](https://elzbieciak.pl) | ||
[Jakub Elżbieciak](https://elzbieciak.pl) / | ||
[@jelzbieciak](https://twitter.com/jelzbieciak) | ||
### License | ||
## License | ||
MIT |
@@ -7,39 +7,30 @@ var test = require('tape'); | ||
test('Metalsmith-compatible API', function (t) { | ||
var API = [ | ||
'build', | ||
'source', | ||
'destination', | ||
'clean', | ||
'frontmatter', | ||
'use', | ||
'run', | ||
'metadata', | ||
'path' | ||
test('Metalsmith exposes a compatible API', function (t) { | ||
var m = metalsmith(); | ||
var methods = [ | ||
'build', 'source', 'destination', 'clean', | ||
'frontmatter', 'use', 'run', 'metadata', 'path' | ||
]; | ||
var m = metalsmith(); | ||
t.plan(API.length); | ||
API.forEach(function (method) { | ||
t.true(_.isFunction(m[method])); | ||
methods.forEach(function (method) { | ||
t.ok(_.isFunction(m[method])); | ||
}); | ||
t.end(); | ||
}); | ||
test('Not implemented methods', function (t) { | ||
test('Metalsmith throws for not implemented methods', function (t) { | ||
var m = metalsmith(); | ||
var NOT_IMPLEMENTED = metalsmith.NOT_IMPLEMENTED; | ||
t.plan(NOT_IMPLEMENTED.length); | ||
NOT_IMPLEMENTED.forEach(function (method) { | ||
metalsmith.NOT_IMPLEMENTED.forEach(function (method) { | ||
t.throws(m[method]); | ||
}); | ||
t.end(); | ||
}); | ||
test('Metadata getter/setter', function (t) { | ||
test('Metalsmith exposes a metadata getter/setter', function (t) { | ||
var m = metalsmith(); | ||
var value = {test: 123, nested: {msg: 'Hello'}}; | ||
t.deepEquals(m.metadata(), {}); | ||
t.equals(m.metadata(value), m); | ||
t.equals(m.metadata(), value); | ||
t.equal(m.metadata(value), m); | ||
t.equal(m.metadata(), value); | ||
t.deepEquals(m.metadata(), {test: 123, nested: {msg: 'Hello'}}); | ||
@@ -49,15 +40,15 @@ t.end(); | ||
test('Path getter', function (t) { | ||
test('Metalsmith exposes a path getter', function (t) { | ||
var cwd = process.cwd(); | ||
var m = metalsmith(); | ||
t.equals(m.path(), cwd); | ||
t.equals(m.path('../hello.txt'), path.resolve(cwd, '..', 'hello.txt')); | ||
t.equal(m.path(), cwd); | ||
t.equal(m.path('../hello.txt'), path.resolve(cwd, '..', 'hello.txt')); | ||
m = metalsmith('/tmp/metalsmith'); | ||
t.equals(m.path(), '/tmp/metalsmith'); | ||
t.equals(m.path('test/hello.txt'), '/tmp/metalsmith/test/hello.txt'); | ||
t.equals(m.path('../../test.html'), '/test.html'); | ||
t.equal(m.path(), '/tmp/metalsmith'); | ||
t.equal(m.path('test/hello.txt'), '/tmp/metalsmith/test/hello.txt'); | ||
t.equal(m.path('../../test.html'), '/test.html'); | ||
t.end(); | ||
}); | ||
test('Middleware flow', function (t) { | ||
test('Metalsmith flows files through middleware functions', function (t) { | ||
var m = metalsmith(); | ||
@@ -75,8 +66,6 @@ t.plan(3); | ||
m.run({}, function () { | ||
t.pass(); | ||
}); | ||
m.run({}, t.pass); | ||
}); | ||
test('Running middleware functions', function (t) { | ||
test('Metalsmith passes the same files/metadata to middleware', function (t) { | ||
var m = metalsmith(); | ||
@@ -95,9 +84,9 @@ t.plan(3); | ||
m.run({}, function (err, files) { | ||
t.true(_.isNull(err)); | ||
t.true(_.isObject(files.added_file)); | ||
t.equals(m.metadata().added_metadata, 123); | ||
t.ok(_.isNull(err)); | ||
t.ok(_.isObject(files.added_file)); | ||
t.equal(m.metadata().added_metadata, 123); | ||
}); | ||
}); | ||
test('Handling middleware errors', function (t) { | ||
test('Metalsmith handles middleware errors', function (t) { | ||
var m = metalsmith(); | ||
@@ -117,5 +106,5 @@ t.plan(2); | ||
m.run({}, function (err) { | ||
t.true(_.isError(err)); | ||
t.equals(err.message, 'Second middleware error.'); | ||
t.ok(_.isError(err)); | ||
t.equal(err.message, 'Second middleware error.'); | ||
}); | ||
}); |
@@ -5,3 +5,3 @@ var test = require('tape'); | ||
var vinyl = require('vinyl-fs'); | ||
var path = require('path'); | ||
var pm = require('path'); | ||
var fs = require('fs'); | ||
@@ -12,16 +12,16 @@ var _ = require('lodash'); | ||
var base = _.partial(path.join, __dirname, 'fixtures'); | ||
var prepare = _.partial(prepareFn, 'src'); | ||
var prepareJson = _.partial(prepareFn, 'json'); | ||
function base(path) { | ||
return pm.join(__dirname, 'fixtures', path || ''); | ||
} | ||
function prepareFn(dir, globs, opts) { | ||
var fn = dir === 'json' ? plugin.json : plugin; | ||
globs = _.isString(globs) ? [globs] : globs; | ||
globs = _.map(globs, function (glob) { | ||
return base(dir, glob || ''); | ||
}); | ||
function read(path) { | ||
return fs.readFileSync(base(path)); | ||
} | ||
function prepare(globs, opts) { | ||
opts = _.extend({root: base()}, opts); | ||
globs = _.isString(globs) ? [globs] : globs; | ||
globs = _.map(globs, base); | ||
return vinyl.src(globs).pipe(fn(opts)); | ||
return vinyl.src(globs).pipe(plugin(opts)); | ||
} | ||
@@ -33,3 +33,3 @@ | ||
if (fn && fileMatches && contentMatches) { | ||
if (_.isFunction(fn) && fileMatches && contentMatches) { | ||
fn(); | ||
@@ -39,19 +39,14 @@ } | ||
test('Plugin API', function (t) { | ||
t.true(_.isFunction(plugin)); | ||
t.true(_.isFunction(plugin.json)); | ||
t.end(); | ||
}); | ||
test('Plugin returns a stream', function (t) { | ||
var methods = ['emit', 'on', 'pipe', 'push', 'write', 'end']; | ||
test('Plugin is a function that returns a stream', function (t) { | ||
t.ok(_.isFunction(plugin)); | ||
var p = plugin(); | ||
t.plan(methods.length); | ||
methods.forEach(function (m) { | ||
t.true(_.isFunction(p[m])); | ||
['emit', 'on', 'pipe', 'push', 'write', 'end'].forEach(function (method) { | ||
t.ok(_.isFunction(p[method])); | ||
}); | ||
t.end(); | ||
}); | ||
test('Failure on a file containing a stream', function (t) { | ||
test('Plugin emits error for vinyl files of type "stream"', function (t) { | ||
var file = new gutil.File({contents: through.obj()}); | ||
@@ -62,14 +57,14 @@ var s = plugin(); | ||
s.on('error', function (err) { | ||
t.true(err instanceof gutil.PluginError); | ||
t.equals(err.plugin, plugin.PLUGIN_NAME); | ||
t.true(_.includes(err.message, 'not supported')); | ||
t.ok(err instanceof gutil.PluginError); | ||
t.equal(err.plugin, plugin.PLUGIN_NAME); | ||
t.ok(_.includes(err.message, 'not supported')); | ||
}); | ||
t.true(file.isStream()); | ||
t.ok(file.isStream()); | ||
s.end(file); | ||
}); | ||
test('Handle a stream of buffered vinyl files', function (t) { | ||
test('Plugin handles a stream of vinyl files of type "buffer"', function (t) { | ||
t.plan(3); | ||
prepare('**').pipe(through.obj(function (f, enc, cb) { | ||
prepare('*').pipe(through.obj(function (f, enc, cb) { | ||
testContent(f, 'index.html', 'Index page', t.pass); | ||
@@ -81,49 +76,37 @@ testContent(f, 'contact.html', 'Contact page', t.pass); | ||
test('Omit ignored files', function (t) { | ||
t.plan(5); | ||
prepare('**', {ignore: 'src/index.html', use: testSingle}); | ||
prepare('**', {ignore: ['src/**', '!src/*.jpg'], use: testMultiple}); | ||
test('Plugin omits ignored files defined in opts.ignore', function (t) { | ||
t.plan(6); | ||
prepare('*.html', {ignore: 'index.html', use: testSingle}); | ||
prepare('*', {ignore: ['*', '!*.jpg'], use: testMultiple}); | ||
function testSingle(files) { | ||
t.equals(_.values(files).length, 2); | ||
t.equals(files['contact.html'].title, 'Contact'); | ||
t.ok(files['trees.jpg']); | ||
t.equal(_.values(files).length, 1); | ||
t.equal(files['contact.html'].title, 'Contact'); | ||
t.notOk(files['index.html']); | ||
} | ||
function testMultiple(files) { | ||
t.equals(_.values(files).length, 1); | ||
t.equal(_.values(files).length, 1); | ||
t.ok(files['trees.jpg']); | ||
t.notOk(files['pc.png']); | ||
} | ||
}); | ||
test('Do not touch non-utf8 files', function (t) { | ||
t.plan(6); | ||
test('Plugin does not touch non-UTF8 files', function (t) { | ||
t.plan(3); | ||
prepare('*.jpg').pipe(through.obj(function (f, enc, cb) { | ||
t.true(f.isBuffer()); | ||
t.true(f.contents.equals(fs.readFileSync(base('src', 'trees.jpg')))); | ||
t.ok(f.isBuffer()); | ||
t.ok(f.contents.equals(read('trees.jpg'))); | ||
cb(); | ||
}, t.pass)); | ||
prepareJson('*.png').pipe(through.obj(function (f, enc, cb) { | ||
t.true(f.isBuffer()); | ||
t.true(f.contents.equals(fs.readFileSync(base('json', 'pc.png')))); | ||
cb(); | ||
}, t.pass)); | ||
}); | ||
test('Accept a single middleware function', function (t) { | ||
test('Plugin accepts a single middleware function', function (t) { | ||
t.plan(1); | ||
prepare('index.html', { | ||
use: function () { | ||
t.pass(); | ||
} | ||
}); | ||
prepare('index.html', {use: t.pass}); | ||
}); | ||
test('Add metadata from configuration options', function (t) { | ||
test('Plugin adds metadata items from opts.metadata', function (t) { | ||
t.plan(3); | ||
prepare('index.html', { | ||
prepare('*.html', { | ||
metadata: { | ||
@@ -133,14 +116,14 @@ item1: true, | ||
}, | ||
use: [testMiddleware] | ||
use: [testMetadata] | ||
}); | ||
function testMiddleware(files, m, next) { | ||
function testMetadata(files, m, next) { | ||
var meta = m.metadata(); | ||
t.true(meta.item1); | ||
t.equals(meta.item2.length, 3); | ||
t.equals(meta.item2[2], 'things'); | ||
t.ok(meta.item1); | ||
t.equal(meta.item2.length, 3); | ||
t.equal(meta.item2[2], 'things'); | ||
} | ||
}); | ||
test('Frontmatter configuration option', function (t) { | ||
test('Plugin parses frontmatter if opts.frontmatter is true', function (t) { | ||
t.plan(2); | ||
@@ -152,3 +135,3 @@ prepare('index.html').pipe(stillIncludes(false)); | ||
return through.obj(function (f, enc, cb) { | ||
t[method ? 'true' : 'false'](_.includes(f.contents.toString(), '---')); | ||
t[method ? 'ok' : 'notOk'](_.includes(f.contents.toString(), '---')); | ||
cb(); | ||
@@ -159,34 +142,45 @@ }); | ||
test('Failure when Metalsmith fails', function (t) { | ||
var s = prepare('**', { | ||
use: [function (f, m, next) { | ||
next(new Error('boom!')); | ||
}] | ||
}); | ||
test('Plugin fails when Metalsmith or middleware fails', function (t) { | ||
t.plan(2); | ||
var s = prepare('**', {use: failingMiddleware}); | ||
s.on('error', function (err) { | ||
t.true(err instanceof gutil.PluginError); | ||
t.equals(err.message, 'boom!'); | ||
t.ok(err instanceof gutil.PluginError); | ||
t.equal(err.message, 'boom!'); | ||
}); | ||
function failingMiddleware(f, m, next) { | ||
next(new Error('boom!')); | ||
} | ||
}); | ||
test('Failure on an invalid JSON', function (t) { | ||
test('Plugin does not touch JSON files if are not definitions', function (t) { | ||
t.plan(3); | ||
prepare('**', {use: testJson}); | ||
prepareJson('invalid_page.json').on('error', isPluginError); | ||
prepareJson('array.json').on('error', function (err) { | ||
function testJson(files) { | ||
t.ok(files['json/invalid.json']); | ||
t.ok(files['json/pages.json']); | ||
t.ok(files['json/pages.json'].contents.equals(read('json/pages.json'))); | ||
} | ||
}); | ||
test('Plugin fails when JSON definitions are invalid', function (t) { | ||
t.plan(3); | ||
prepare('**', {json: 'json/invalid.json'}).on('error', isPluginError); | ||
prepare('**', {json: 'json/array.json'}).on('error', function (err) { | ||
isPluginError(err); | ||
t.true(_.includes(err.message, 'single root object')); | ||
t.ok(_.includes(err.message, 'single root object')); | ||
}); | ||
function isPluginError(err) { | ||
t.true(err instanceof gutil.PluginError); | ||
t.ok(err instanceof gutil.PluginError); | ||
} | ||
}); | ||
test('Handle JSON input', function (t) { | ||
test('Plugin creates pages from JSON definitions', function (t) { | ||
t.plan(3); | ||
prepareJson('pages.json').pipe(through.obj(function (f, enc, cb) { | ||
var s = prepare('**/*.json', {json: 'json/pages.json'}); | ||
s.pipe(through.obj(function (f, enc, cb) { | ||
testContent(f, 'index.html', 'Index page', t.pass); | ||
@@ -198,5 +192,6 @@ testContent(f, 'contact.html', 'Contact page', t.pass); | ||
test('Handle a multi-file JSON input', function (t) { | ||
var s = prepareJson(['pages.json', 'offer_page.json']); | ||
test('Plugin merges and creates pages from multiple JSON inputs', function (t) { | ||
t.plan(4); | ||
var json = ['json/pages.json', 'json/offer_page.json']; | ||
var s = prepare('**/*.json', {json: json}); | ||
@@ -211,16 +206,47 @@ s.pipe(through.obj(function (f, enc, cb) { | ||
test('Handle a JSON defined page w/o contents', function (t) { | ||
t.plan(2); | ||
prepareJson('empty_page.json').pipe(through.obj(function (f) { | ||
t.equals(f.path, 'empty.html'); | ||
t.equals(f.contents.toString(), ''); | ||
})); | ||
test('Plugin mixes both regular and JSON defined files', function (t) { | ||
t.plan(5); | ||
var globs = ['*.html', 'json/map_page.json']; | ||
var s = prepare(globs, {json: 'json/*.json', use: testFiles}); | ||
function testFiles(files) { | ||
t.equal(_.values(files).length, 3); | ||
t.ok(files['index.html']); | ||
t.ok(files['index.html'].contents.toString().indexOf('Index') > -1); | ||
t.ok(files['map.html']); | ||
t.equal(files['map.html'].contents.toString(), '<h2>Map page</h2>'); | ||
} | ||
}); | ||
test('Ignore invalid file keys', function (t) { | ||
test('Plugin converts all JSON files if opts.json is true', function (t) { | ||
t.plan(3); | ||
var globs = ['json/pages.json', 'json/*_page.json']; | ||
var s = prepare(globs, {json: true, use: testFiles}); | ||
function testFiles(files) { | ||
t.equal(_.values(files).length, 5); | ||
t.ok(files['index.html']); | ||
t.ok(files['map.html']); | ||
} | ||
}); | ||
test('Plugin handles a JSON defined page w/o contents', function (t) { | ||
t.plan(3); | ||
var s = prepare('json/empty_page.json', {json: true}); | ||
s.pipe(through.obj(function (f, enc, cb) { | ||
t.equal(f.path, 'empty.html'); | ||
t.equal(f.contents.toString(), ''); | ||
cb(); | ||
}, t.pass)); | ||
}); | ||
test('Plugin ignores invalid file keys in JSON definition', function (t) { | ||
t.plan(2); | ||
prepareJson('map_page.json').pipe(through.obj(function (f, enc, cb) { | ||
t.equals(f.path, 'map.html'); | ||
var s = prepare('json/map_page.json', {json: true}); | ||
s.pipe(through.obj(function (f, enc, cb) { | ||
t.equal(f.path, 'map.html'); | ||
cb(); | ||
}, t.pass)); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
264710
5
30
583
1
130
3