Remove update package

This commit is contained in:
christianesperar 2016-05-10 23:27:55 +08:00
parent c6d4823f1c
commit ea7a7997a7
154 changed files with 0 additions and 14743 deletions

View file

@ -1,14 +0,0 @@
{
"name": "update",
"homepage": "https://github.com/jonschlinkert/update",
"_release": "cf42344639",
"_resolution": {
"type": "branch",
"branch": "master",
"commit": "cf423446393d68666c9f591b8eee7458191cea45"
},
"_source": "https://github.com/jonschlinkert/update.git",
"_target": "*",
"_originalSource": "update",
"_direct": true
}

View file

@ -1,22 +0,0 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
end_of_line = lf
charset = utf-8
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
insert_final_newline = false
[test/**]
trim_trailing_whitespace = false
insert_final_newline = false
[templates/**]
trim_trailing_whitespace = false
insert_final_newline = false

View file

@ -1,278 +0,0 @@
{
"ecmaFeatures": {
"modules": true,
"experimentalObjectRestSpread": true
},
"env": {
"browser": false,
"es6": true,
"node": true,
"mocha": true
},
"globals": {
"document": false,
"navigator": false,
"window": false
},
"rules": {
"accessor-pairs": 2,
"arrow-spacing": [
2,
{
"before": true,
"after": true
}
],
"block-spacing": [
2,
"always"
],
"brace-style": [
2,
"1tbs",
{
"allowSingleLine": true
}
],
"comma-dangle": [
2,
"never"
],
"comma-spacing": [
2,
{
"before": false,
"after": true
}
],
"comma-style": [
2,
"last"
],
"constructor-super": 2,
"curly": [
2,
"multi-line"
],
"dot-location": [
2,
"property"
],
"eol-last": 2,
"eqeqeq": [
2,
"allow-null"
],
"generator-star-spacing": [
2,
{
"before": true,
"after": true
}
],
"handle-callback-err": [
2,
"^(err|error)$"
],
"indent": [
2,
2,
{
"SwitchCase": 1
}
],
"key-spacing": [
2,
{
"beforeColon": false,
"afterColon": true
}
],
"new-cap": [
2,
{
"newIsCap": true,
"capIsNew": false
}
],
"new-parens": 2,
"no-array-constructor": 2,
"no-caller": 2,
"no-class-assign": 2,
"no-cond-assign": 2,
"no-const-assign": 2,
"no-control-regex": 2,
"no-debugger": 2,
"no-delete-var": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-empty-character-class": 2,
"no-empty-label": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": [
2,
"functions"
],
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-implied-eval": 2,
"no-inner-declarations": [
2,
"functions"
],
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-mixed-spaces-and-tabs": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-multiple-empty-lines": [
2,
{
"max": 1
}
],
"no-native-reassign": 2,
"no-negated-in-lhs": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-require": 2,
"no-new-wrappers": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 2,
"no-proto": 0,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-return-assign": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-sparse-arrays": 2,
"no-this-before-super": 2,
"no-throw-literal": 2,
"no-trailing-spaces": 0,
"no-undef": 2,
"no-undef-init": 2,
"no-unexpected-multiline": 2,
"no-unneeded-ternary": [
2,
{
"defaultAssignment": false
}
],
"no-unreachable": 2,
"no-unused-vars": [
2,
{
"vars": "all",
"args": "none"
}
],
"no-useless-call": 0,
"no-with": 2,
"one-var": [
0,
{
"initialized": "never"
}
],
"operator-linebreak": [
0,
"after",
{
"overrides": {
"?": "before",
":": "before"
}
}
],
"padded-blocks": [
0,
"never"
],
"quotes": [
2,
"single",
"avoid-escape"
],
"radix": 2,
"semi": [
2,
"always"
],
"semi-spacing": [
2,
{
"before": false,
"after": true
}
],
"space-after-keywords": [
2,
"always"
],
"space-before-blocks": [
2,
"always"
],
"space-before-function-paren": [
2,
"never"
],
"space-before-keywords": [
2,
"always"
],
"space-in-parens": [
2,
"never"
],
"space-infix-ops": 2,
"space-return-throw-case": 2,
"space-unary-ops": [
2,
{
"words": true,
"nonwords": false
}
],
"spaced-comment": [
0,
"always",
{
"markers": [
"global",
"globals",
"eslint",
"eslint-disable",
"*package",
"!",
","
]
}
],
"use-isnan": 2,
"valid-typeof": 2,
"wrap-iife": [
2,
"any"
],
"yoda": [
2,
"never"
]
}
}

View file

@ -1,10 +0,0 @@
# Enforce Unix newlines
* text eol=lf
# binaries
*.ai binary
*.psd binary
*.jpg binary
*.gif binary
*.png binary
*.jpeg binary

View file

@ -1,15 +0,0 @@
*.DS_Store
*.sublime-*
_gh_pages
bower_components
node_modules
npm-debug.log
actual
test/actual
temp
tmp
TODO.md
vendor
.idea
benchmark
coverage

View file

@ -1,12 +0,0 @@
sudo: false
language: node_js
node_js:
- "stable"
- "5"
- "4"
- "0.12"
- "0.10"
matrix:
fast_finish: true
allow_failures:
- node_js: "0.10"

View file

@ -1,147 +0,0 @@
# {%= name %} {%= badge("fury") %} {%= badge("travis") %}
> {%= description %}
## CLI
### Install
{%= include("install-global") %}
### Commands
```sh
$ update <command> [options]
```
**List updaters**
Choose from a list of updaters and tasks to run:
```sh
$ update list
```
**Run a specific updater**
The following would run updater `foo`:
```sh
$ update foo
# run updater "foo" with options
$ update foo --bar=baz
```
### tasks
_(TODO)_
### plugins
_(TODO)_
#### pipeline plugins
_(TODO)_
#### instance plugins
_(TODO)_
### middleware
A middleware is a function that exposes the following parameters:
- `file`: **{Object}** [vinyl][] file object
- `next`: **{Function}** must be called to continue on to the next file.
```js
function rename(file, next) {
file.path = 'foo/' + file.path;
next();
}
// example usage: prefix all `.js` file paths with `foo/`
app.onLoad(/\.js/, rename);
```
The `onStream` method is a custom [middleware](docs/middleware.md) handler that the `update`
```js
app.onStream(/lib\//, rename);
```
## API
### Install
{%= include("install-npm", {save: true}) %}
```js
var update = require('{%= name %}');
```
## API
{%= apidocs("index.js") %}
## Related projects
{%= related(verb.related.list) %}
## Authoring
### Updaters
_(TODO)_
#### Tasks
_(TODO)_
#### Middleware
_(TODO)_
#### Plugins
> Updater plugins follow the same signature as gulp plugins
**Example**
```js
function myPlugin(options) {
return through.obj(function(file, enc, next) {
var str = file.contents.toString();
// do stuff to `file`
file.contents = new Buffer(file.contents);
next(null, file);
});
}
```
### Publish
1. Name your project following the convention: `updater-*`
2. Don't use dots in the name (e.g `.js`)
3. Make sure you add `updater` to the keywords in `package.json`
4. Tweet about your updater!
## Running tests
{%= include("tests") %}
## Contributing
{%= include("contributing") %}
## Author
{%= include("author") %}
## License
{%= copyright() %}
{%= license %}
***
{%= include("footer") %}

View file

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015-2016, Jon Schlinkert.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,185 +0,0 @@
# update [![NPM version](https://img.shields.io/npm/v/update.svg)](https://www.npmjs.com/package/update) [![Build Status](https://img.shields.io/travis/update/update.svg)](https://travis-ci.org/update/update)
> Easily keep anything in your project up-to-date by installing the updaters you want to use and running `update` in the command line! Update the copyright date, licence type, ensure that a project uses your latest eslint or jshint configuration, remove deprecated package.json fields, or anything you can think of!
## CLI
### Install
Install globally with [npm](https://www.npmjs.com/)
```sh
$ npm i -g update
```
### Commands
```sh
$ update <command> [options]
```
**List updaters**
Choose from a list of updaters and tasks to run:
```sh
$ update list
```
**Run a specific updater**
The following would run updater `foo`:
```sh
$ update foo
# run updater "foo" with options
$ update foo --bar=baz
```
### tasks
_(TODO)_
### plugins
_(TODO)_
#### pipeline plugins
_(TODO)_
#### instance plugins
_(TODO)_
### middleware
A middleware is a function that exposes the following parameters:
* `file`: **{Object}** [vinyl](http://github.com/gulpjs/vinyl) file object
* `next`: **{Function}** must be called to continue on to the next file.
```js
function rename(file, next) {
file.path = 'foo/' + file.path;
next();
}
// example usage: prefix all `.js` file paths with `foo/`
app.onLoad(/\.js/, rename);
```
The `onStream` method is a custom [middleware](docs/middleware.md) handler that the `update`
```js
app.onStream(/lib\//, rename);
```
## API
### Install
Install with [npm](https://www.npmjs.com/):
```sh
$ npm i update --save
```
```js
var update = require('update');
```
## API
### [Update](index.js#L30)
Create an `update` application. This is the main function exported by the update module.
**Params**
* `options` **{Object}**
**Example**
```js
var Update = require('update');
var update = new Update();
```
## Related projects
* [assemble](https://www.npmjs.com/package/assemble): Assemble is a powerful, extendable and easy to use static site generator for node.js. Used… [more](https://www.npmjs.com/package/assemble) | [homepage](https://github.com/assemble/assemble)
* [boilerplate](https://www.npmjs.com/package/boilerplate): Tools and conventions for authoring and publishing boilerplates that can be generated by any build… [more](https://www.npmjs.com/package/boilerplate) | [homepage](http://boilerplates.io)
* [composer](https://www.npmjs.com/package/composer): API-first task runner with three methods: task, run and watch. | [homepage](https://github.com/jonschlinkert/composer)
* [generate](https://www.npmjs.com/package/generate): Fast, composable, highly extendable project generator with a user-friendly and expressive API. | [homepage](https://github.com/generate/generate)
* [scaffold](https://www.npmjs.com/package/scaffold): Conventions and API for creating declarative configuration objects for project scaffolds - similar in format… [more](https://www.npmjs.com/package/scaffold) | [homepage](https://github.com/jonschlinkert/scaffold)
* [templates](https://www.npmjs.com/package/templates): System for creating and managing template collections, and rendering templates with any node.js template engine.… [more](https://www.npmjs.com/package/templates) | [homepage](https://github.com/jonschlinkert/templates)
* [update](https://www.npmjs.com/package/update): Update | [homepage](https://github.com/jonschlinkert/update)
* [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://www.npmjs.com/package/verb) | [homepage](https://github.com/verbose/verb)
## Authoring
### Updaters
_(TODO)_
#### Tasks
_(TODO)_
#### Middleware
_(TODO)_
#### Plugins
> Updater plugins follow the same signature as gulp plugins
**Example**
```js
function myPlugin(options) {
return through.obj(function(file, enc, next) {
var str = file.contents.toString();
// do stuff to `file`
file.contents = new Buffer(file.contents);
next(null, file);
});
}
```
### Publish
1. Name your project following the convention: `updater-*`
2. Don't use dots in the name (e.g `.js`)
3. Make sure you add `updater` to the keywords in `package.json`
4. Tweet about your updater!
## Running tests
Install dev dependencies:
```sh
$ npm i -d && npm test
```
## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/update/issues/new).
## Author
**Jon Schlinkert**
* [github/jonschlinkert](https://github.com/jonschlinkert)
* [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright © 2016 [Jon Schlinkert](https://github.com/jonschlinkert)
Released under the MIT license.
***
_This file was generated by [verb](https://github.com/verbose/verb) on January 09, 2016._

View file

@ -1,38 +0,0 @@
#!/usr/bin/env node
var path = require('path');
var gm = require('global-modules');
var Runner = require('../lib/runner/runner')();
var utils = require('../lib/utils');
var argv = require('minimist')(process.argv.slice(2), {
alias: {verbose: 'v'}
});
var cmd = utils.commands(argv);
var runner = new Runner(argv);
runner.base.option(argv);
runner.option(argv);
var task = cmd.list ? ['list', 'default'] : ['default'];
runner.on('*', function(method, key, val) {
console.log(method + ':', key, val);
});
if (argv.verbose) {
runner.on('register', function(key) {
utils.ok(utils.gray('registered'), 'updater', utils.cyan(key));
});
}
runner.registerEach('update-*', {cwd: gm});
runner.base.task('run', function(cb) {
runner.run(cb);
});
runner.base.build(task, function(err) {
if (err) return console.error(err);
utils.timestamp('finished ' + utils.green(utils.successSymbol));
});

View file

@ -1,27 +0,0 @@
'use strict';
var gulp = require('gulp');
var mocha = require('gulp-mocha');
var istanbul = require('gulp-istanbul');
var eslint = require('gulp-eslint');
var lint = ['index.js', 'lib/*.js', 'test/*.js'];
gulp.task('coverage', function () {
return gulp.src(lint)
.pipe(istanbul())
.pipe(istanbul.hookRequire());
});
gulp.task('mocha', ['coverage'], function () {
return gulp.src('test/*.js')
.pipe(mocha({reporter: 'spec'}))
.pipe(istanbul.writeReports());
});
gulp.task('eslint', function () {
return gulp.src(lint)
.pipe(eslint())
});
gulp.task('default', ['mocha', 'eslint']);

View file

@ -1,169 +0,0 @@
/*!
* update <https://github.com/jonschlinkert/update>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var path = require('path');
var Base = require('assemble-core');
var expand = require('expand-args');
var minimist = require('minimist');
var config = require('./lib/config');
var locals = require('./lib/locals');
var utils = require('./lib/utils');
/**
* Create an `update` application. This is the main function exported
* by the update module.
*
* ```js
* var Update = require('update');
* var update = new Update();
* ```
* @param {Object} `options`
* @api public
*/
function Update(options) {
if (!(this instanceof Update)) {
return new Update(options);
}
Base.call(this, options);
this.name = this.options.name || 'update';
this.isUpdate = true;
this.initUpdate(this);
}
/**
* Inherit assemble-core
*/
Base.extend(Update);
/**
* Initialize Updater defaults
*/
Update.prototype.initUpdate = function(base) {
this.set('updaters', {});
// custom middleware handlers
this.handler('onStream');
this.handler('preWrite');
this.handler('postWrite');
// parse command line arguments
var argv = expand(minimist(process.argv.slice(2)), {
alias: {v: 'verbose'}
});
this.option('argv', argv);
// expose `argv` on the instance
this.mixin('argv', function(prop) {
var args = [].slice.call(arguments);
args.unshift(argv);
return utils.get.apply(null, args);
});
// load the package.json for the updater
this.data(utils.pkg.sync(this.options.path));
config(this);
this.use(locals('update'))
.use(utils.runtimes({
displayName: function(key) {
return base.name === key ? key : (base.name + ':' + key);
}
}))
.use(utils.store())
.use(utils.pipeline())
.use(utils.loader())
.use(utils.cli())
.use(utils.defaults())
.use(utils.opts())
var data = utils.get(this.cache.data, 'update');
this.config.process(utils.extend({}, data, argv));
this.engine(['md', 'tmpl'], require('engine-base'));
this.onLoad(/\.(md|tmpl)$/, function(view, next) {
utils.matter.parse(view, next);
});
};
/**
* Returns a function for resolving filepaths from the given `directory`
* or from the user's current working directory if no directory
* is passed.
*
* ```js
* var cwd = update.cwd('foo');
* var a = cwd('bar');
* var b = cwd('baz');
* ```
* @param {String} `dir`
* @return {Function}
*/
Update.prototype.cwd = function(dir) {
var cwd = dir || process.cwd();
return function() {
var args = [].slice.call(arguments);
args.unshift(cwd);
return path.resolve.apply(null, args);
};
};
/**
* Temporary logger method.
* TODO: add event logger
*/
Update.prototype.log = function() {
this.emit.bind(this, 'log').apply(this, arguments);
if (this.enabled('verbose')) {
console.log.apply(console, arguments);
}
};
/**
* Register updater `name` with the given `update`
* instance.
*
* @param {String} `name`
* @param {Object} `update` Instance of update
* @return {Object} Returns the instance for chaining
*/
Update.prototype.updater = function(name, app) {
if (arguments.length === 1 && typeof name === 'string') {
return this.updaters[name];
}
app.use(utils.runtimes({
displayName: function(key) {
return app.name === key ? key : (app.name + ':' + key);
}
}));
this.emit('updater', name, app);
this.updaters[name] = app;
return app;
};
/**
* Expose `Update`
*/
module.exports = Update;
/**
* Expose `utils` and package.json metadata
*/
module.exports.utils = utils;
module.exports.pkg = require('./package');

View file

@ -1,30 +0,0 @@
'use strict';
module.exports = function(app) {
if (!app.isUpdate) return;
var config = require('base-config');
app.use(config());
app.config
.map('addViews')
.map('addView')
.map('helpers')
.map('asyncHelpers')
.map('plugins', function(val) {
app.visit('plugin', val);
})
.map('data', function(val) {
app.visit('data', val);
})
.map('collections', function(val) {
app.visit('create', val);
})
.map('reflinks', function(val) {
app.data({reflinks: val});
})
.map('related', function(val) {
app.data({related: val});
});
};

View file

@ -1,26 +0,0 @@
'use strict';
var get = require('get-value');
var set = require('set-value');
var utils = require('./utils');
module.exports = function(name) {
name = name || utils.project(process.cwd());
return function(app) {
app.define('locals', new Locals(name, this));
};
};
function Locals(name, app) {
this.cache = get(app, ['cache.data', name]) || {};
}
Locals.prototype.get = function(key) {
return get(this.cache, key);
};
Locals.prototype.set = function(key, value) {
set(this.cache, key, value);
return this;
};

View file

@ -1 +0,0 @@
module.exports = require('export-files')(__dirname);

View file

@ -1,22 +0,0 @@
'use strict';
var sortArrays = require('sort-object-arrays');
module.exports = function(app, base, env) {
base.onLoad(/(\.eslintrc|\.js(on|hintrc))$/, function(file, next) {
file.json = JSON.parse(file.content);
next();
});
base.preWrite(/\.js(on|hintrc)$/, function(file, next) {
if (typeof file.json === 'undefined') {
next(new Error('json middleware expects `file.json` to be an object'));
return;
}
file.json = sortArrays(file.json);
file.content = JSON.stringify(file.json, null, 2);
file.content += '\n';
next();
});
};

View file

@ -1,55 +0,0 @@
'use strict';
var utils = require('../utils');
module.exports = function(options) {
return function(app) {
this.define('argv', function(argv, commands, fn) {
var args = {};
args.argv = argv;
args.commands = [];
args.updaters = {};
args.flags = utils.expandArgs(utils.omit(argv, ['_', 'files']));
args.flagskeys = Object.keys(args.flags);
var files = argv.files ? utils.pick(argv, 'files') : null;
if (files) args.flags.files = files;
var arr = argv._;
var len = arr.length, i = -1;
while (++i < len) {
var key = arr[i];
if (/\W/.test(key)) {
var obj = utils.expand(key);
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
var val = obj[prop];
utils.union(args, 'updaters.' + prop, val);
}
}
continue;
}
if (utils.contains(commands, key)) {
args.commands.push(key);
continue;
}
// fn(key, args);
var updaters = this.base.updaters;
if (key in updaters) {
utils.union(args, 'updaters.' + key, 'default');
} else if (key !== 'base') {
utils.union(args, 'updaters.base', key);
}
}
return args;
});
};
};

View file

@ -1,39 +0,0 @@
'use strict';
var path = require('path');
var utils = require('../utils');
module.exports = function(options) {
return function(app) {
this.define('decorate', function(name, app, options) {
app.option('name', name)
.option('fullname', options.fullname || name)
.option('path', options.path || '');
app.create('templates', {
cwd: path.resolve(options.path, 'templates'),
renameKey: function(key) {
return path.basename(key);
}
});
var base = this.base;
app.define('getFile', function(name) {
var view = base.files.getView.apply(base.files, arguments);
if (!view) {
view = app.templates.getView.apply(app.templates, arguments);
}
if (!view) return null;
view.basename = view.basename.replace(/^_/, '.');
view.basename = view.basename.replace(/^$/, '');
return view;
});
base.define('getFile', app.getFile);
base.files.getFile = base.files.getView.bind(base.files);
return this;
});
};
};

View file

@ -1,53 +0,0 @@
'use strict';
var path = require('path');
var define = require('define-property');
var extend = require('extend-shallow');
var get = require('get-value');
var set = require('set-value');
function Env(options) {
this.options = options || {};
define(this, 'cache', {});
}
Env.prototype.set = function(key, value) {
set(this, key, value);
return this;
};
Env.prototype.get = function(key) {
return get(this, key);
};
Object.defineProperty(Env.prototype, 'cwd', {
set: function(dir) {
this.cache.cwd = dir;
},
get: function() {
return this.cache.cwd || process.cwd();
}
});
Object.defineProperty(Env.prototype, 'pkg', {
set: function() {
throw new Error('env.pkg is a getter and cannot be set directly.');
},
get: function() {
if (!this.cache.pkg) {
this.cache.pkg = require(path.resolve(this.cwd, 'package.json'));
}
return this.cache.pkg;
}
});
/**
* Expose `Env`
*/
module.exports = function(options) {
return function(app) {
var opts = extend({}, this.options, options);
app.define('env', new Env(opts));
};
};

View file

@ -1,40 +0,0 @@
'use strict';
var utils = require('../utils');
module.exports = function(options) {
return function(app) {
this.define('list', function(cb) {
var questions = utils.questions(this.base.options);
var choices = utils.list(this.base.updaters);
if (!choices.length) {
console.log(utils.cyan(' No updater tasks found.'));
return cb(null, {
updaters: {}
});
}
var question = {
updaters: {
message: 'pick an updater to run',
type: 'checkbox',
choices: choices
}
};
questions.ask(question, function(err, answers) {
if (err) return cb(err);
var args = {
updaters: {}
};
answers.updaters.forEach(function(answer) {
var segs = answer.split(':');
if (segs.length === 1) return;
utils.union(args.updaters, segs[0], (segs[1] || 'default').split(','));
});
return cb(null, args);
});
});
};
};

View file

@ -1,30 +0,0 @@
'use strict';
module.exports = function(options) {
return function(app) {
this.define('_listen', function() {
if (this.base.disabled('verbose')) return;
var store = ['store.set', 'store.has', 'store.get', 'store.del'];
var methods = ['set', 'has', 'get', 'del', 'option', 'data'];
var names = store.concat(methods);
var len = names.length, i = -1;
var multi = this;
while (++i < len) {
var method = names[i];
var prop = method.split('.');
if (prop.length === 2) {
this.base[prop[0]].on(prop[1], multi.emit.bind(multi, method));
this.base[prop[0]].on(prop[1], multi.emit.bind(multi, '*', method));
} else {
this.base.on(method, function(key, val) {
multi.emit(method, key, val);
multi.emit('*', method, key, val);
});
}
}
});
};
};

View file

@ -1,46 +0,0 @@
'use strict';
var utils = require('../utils');
module.exports = function(options) {
return function(app) {
this.define('getApp', function(name) {
return name !== 'base'
? this.base.updater(name)
: this.base;
});
this.define('run', function(args, cb) {
if (typeof args === 'function') {
cb = args;
args = null;
}
if (!args) {
var commands = this.options.commands || this.commands;
args = this.argv(this.base.get('argv'), commands);
}
if (args.commands && args.commands.length > 1) {
var cmd = '"' + args.commands.join(', ') + '"';
return cb(new Error('Error: only one root level command may be given: ' + cmd));
}
this.base.cli.process(args.flags);
var self = this;
utils.async.eachOf(args.updaters, function(tasks, name, next) {
var app = self.getApp(name);
tasks = tasks.filter(Boolean);
if (!tasks.length) return next();
self.emit('task', name, tasks);
app.build(tasks, next);
}, cb);
return this;
});
};
};

View file

@ -1,107 +0,0 @@
'use strict';
var path = require('path');
var Base = require('base');
var option = require('base-options');
var store = require('base-store');
var fns = require('../middleware');
var Updater = require('./updater');
var tasks = require('../tasks');
var utils = require('../utils');
var decorate = require('./decorate');
var listen = require('./listen');
var args = require('./argv');
var list = require('./list');
var run = require('./run');
var Update = require('../..');
module.exports = function(namespace, config) {
function Runner(argv, options) {
if (!(this instanceof Runner)) {
return new Runner(argv, options);
}
Base.call(this);
this.use(option());
this.use(store());
this.use(decorate());
this.use(listen());
this.use(args());
this.use(list());
this.use(run());
this.options = options || {};
this.commands = ['set', 'get', 'del', 'store', 'init', 'option', 'data', 'list'];
this.base = new Update()
.on('error', console.error)
.set('argv', argv)
// register middleware
for (var fn in fns) {
fns[fn](this.base, this.base, this);
}
// register tasks
for (var key in tasks) {
this.base.task(key, tasks[key](this.base, this.base, this));
}
this._listen();
}
Base.extend(Runner);
Runner.prototype.updater = function(name) {
return this.base.updater(name);
};
Runner.prototype.build = function() {
this.base.build.apply(this.base, arguments);
return this;
};
Runner.prototype.register = function(name, options, updater) {
if (arguments.length === 2) {
updater = options;
options = {};
}
var Ctor = options.Update || Update;
var app = new Ctor(this.base.options);
this.decorate(name, app, options);
updater.call(app, app, this.base, this);
this.base.updater(name, app);
this.emit('register', name, app);
return this;
};
Runner.prototype.registerEach = function(patterns, options) {
utils.matchFiles(patterns, options).forEach(function(fp) {
var filepath = path.resolve(fp, 'updatefile.js');
var updater = require(filepath);
// get the full project name ('updater-foo')
var fullname = utils.project(fp);
// get the updater name ('foo')
var name = utils.renameFn(fullname, options);
var opts = {};
// get the constructor to use (node_modules or our 'Update')
opts.Update = utils.resolveModule(fp);
opts.fullname = fullname;
opts.path = fp;
this.register(name, opts, updater);
}.bind(this));
return this;
};
/**
* Expose `Runner`
*/
return Runner;
};

View file

@ -1,127 +0,0 @@
'use strict';
var path = require('path');
var set = require('set-value');
var define = require('define-property');
var use = require('use');
/**
* Create an instance of `Updater`, optionally passing
* a default object to initialize with.
*
* ```js
* var app = new Updater({
* path: 'foo.html'
* });
* ```
* @param {Object} `app`
* @api public
*/
function Updater(name, config, fn) {
if (!(this instanceof Updater)) {
return new Updater(config);
}
if (typeof config === 'function') {
fn = config;
config = {};
}
this.isUpdater = true;
define(this, 'cache', {});
config = config || {};
config.fn = fn;
for (var key in config) {
if (!(key in this)) {
this.set(key, config[key]);
}
}
use(this);
}
/**
* Set `key` on the instance with the given `value`.
*
* @param {String} `key`
* @param {Object} `value`
* @return {Object} Returns the instance for chaining
*/
Updater.prototype.set = function(key, value) {
set(this, key, value);
return this;
};
/**
* Custom `inspect` method.
*/
// Updater.prototype.inspect = function() {
// var name = this.name || 'Updater';
// var inspect = [];
// if (this.alias) {
// inspect.push('"' + this.alias + '"');
// }
// return '<' + name + ' ' + inspect.join(' ') + '>';
// };
/**
* Get the `cwd` (current working directory) for the updater.
*/
define(Updater.prototype, 'cwd', {
set: function(dir) {
this.cache.cwd = dir;
},
get: function() {
return this.cache.cwd || (this.cache.cwd = process.cwd());
}
});
/**
* Get the `dirname` for the updater.
*/
define(Updater.prototype, 'dirname', {
set: function(dir) {
this.path = path.join(dir, path.basename(this.path));
},
get: function() {
return path.dirname(this.path);
}
});
/**
* Get the `basename` for the updater.
*/
define(Updater.prototype, 'basename', {
set: function(basename) {
this.path = path.join(path.dirname(this.path), basename);
},
get: function() {
return path.basename(this.path);
}
});
/**
* Get the `filename` for the updater.
*/
define(Updater.prototype, 'filename', {
set: function(filename) {
this.path = path.join(path.dirname(this.path), filename + this.extname);
},
get: function() {
return path.basename(this.path, this.extname);
}
});
/**
* Expose `Updater`
*/
module.exports = Updater;

View file

@ -1,5 +0,0 @@
'use strict';
module.exports = function(app, base, env) {
return ['del', 'files', 'run', 'dest'];
};

View file

@ -1,17 +0,0 @@
'use strict';
var path = require('path');
var async = require('async');
var rimraf = require('rimraf');
var list = ['.npmignore', '.jshintrc', '.eslintrc'];
module.exports = function(app, base, env) {
var files = base.option('delete') || list;
return function(cb) {
async.each(files, function(fp, next) {
rimraf(path.resolve(process.cwd(), fp), next);
}, cb);
};
};

View file

@ -1,29 +0,0 @@
'use strict';
var utils = require('../utils');
module.exports = function(app, base, env) {
var plugins = base.get('argv.plugins');
function handle(stage) {
return utils.through.obj(function(file, enc, next) {
if (file.isNull()) return next();
app.handle(stage, file, next);
});
}
return function(cb) {
app.toStream('files')
.on('error', cb)
.pipe(handle('onStream'))
.on('error', cb)
.pipe(app.pipeline(plugins))
.on('error', cb)
.pipe(handle('preWrite'))
.on('error', cb)
.pipe(app.dest('.'))
.pipe(utils.exhaust(handle('postWrite')))
.on('error', cb)
.on('end', cb);
};
};

View file

@ -1,24 +0,0 @@
'use strict';
var path = require('path');
module.exports = function(app, base, env) {
base.create('files', {
renameKey: function(key) {
return path.basename(key);
}
});
var glob = base.get('argv.files');
if (glob) {
glob = glob.split(',');
} else {
glob = ['*', 'lib/*', 'bin/*'];
}
return function(cb) {
base.files(glob, {dot: true, ignore: ['.DS_Store']});
base.emit('loaded', base.files);
cb();
}
};

View file

@ -1 +0,0 @@
module.exports = require('export-files')(__dirname);

View file

@ -1,18 +0,0 @@
'use strict';
var through = require('through2');
var eslint = require('gulp-eslint');
module.exports = function(app, base, env) {
return function() {
return base.toStream('files')
.pipe(through.obj(function(file, enc, cb) {
if (/\.js$/.test(file.path)) {
this.push(file);
}
cb();
}))
.pipe(eslint())
.pipe(eslint.format())
};
};

View file

@ -1,10 +0,0 @@
'use strict';
module.exports = function(app, base, env) {
return function(cb) {
env.list(function(err, args) {
if (err) return cb(err);
env.run(args, cb);
});
};
};

View file

@ -1,7 +0,0 @@
'use strict';
module.exports = function(app, base, env) {
return function(cb) {
return cb();
};
};

View file

@ -1,65 +0,0 @@
'use strict';
var path = require('path');
var rimraf = require('rimraf');
var through = require('through2');
var mapping = {
'LICENSE': 'LICENSE-MIT',
'readme.md': 'README.md'
};
module.exports = function(app, base, env) {
var config = base.option('rename') || mapping;
app.task('undo', function() {
return base.toStream('files')
.pipe(rename(config, {invert: true}));
});
return function() {
return base.toStream('files')
.pipe(rename(config));
};
};
function rename(mapping, options) {
options = options || {};
if (options.invert === true) {
mapping = invert(mapping);
}
return through.obj(function(file, enc, next) {
if (file.isNull()) return next(null, file);
var fp = file.path;
function del(err) {
if (err) return next(err);
next(null, file);
}
for (var key in mapping) {
if (isMatch(file, mapping[key])) {
file.path = path.resolve(file.base, key);
rimraf(fp, del);
return;
}
}
next(null, file);
});
}
function isMatch(file, src) {
file.basename = path.basename(file.path);
if (src instanceof RegExp) {
return src.test(file.basename) || src.test(file.path);
}
if (typeof src === 'string') {
return src === file.path || src === file.basename;
}
}
function invert(obj) {
var res = {};
for (var key in obj) {
res[obj[key]] = key;
}
return res;
}

View file

@ -1,10 +0,0 @@
'use strict';
var utils = require('../utils');
module.exports = function(app, base, env) {
return function(cb) {
console.log(utils.tree(base.updaters));
cb();
};
};

View file

@ -1,329 +0,0 @@
'use strict';
var fs = require('fs');
var path = require('path');
var pkg = require(path.resolve(__dirname, '../package'));
/**
* Module dependencies
*/
var utils = require('lazy-cache')(require);
var fn = require;
require = utils;
require('assemble-loader', 'loader');
require('async');
require('base-cli', 'cli');
require('base-pipeline', 'pipeline');
require('base-store', 'store');
require('composer-runtimes', 'runtimes');
require('expand-args');
require('expand-object', 'expand');
require('extend-shallow', 'extend');
require('for-own');
require('get-value', 'get');
require('load-pkg', 'pkg');
require('matched', 'glob');
require('micromatch', 'mm');
require('object.omit', 'omit');
require('object.pick', 'pick');
require('parser-front-matter', 'matter');
require('project-name', 'project');
require('question-cache', 'questions');
require('set-value', 'set');
require('stream-exhaust', 'exhaust');
require('through2', 'through');
require('union-value', 'union');
require('success-symbol');
require('ansi-yellow', 'yellow');
require('ansi-green', 'green');
require('ansi-gray', 'gray');
require('ansi-cyan', 'cyan');
require('ansi-red', 'red');
require('time-stamp', 'stamp');
require = fn;
/**
* Logging utils
*/
utils.timestamp = function(msg) {
var time = '[' + utils.gray(utils.stamp('HH:mm:ss', new Date())) + ']';
return console.log(time, msg);
};
function Status(status) {
status = status || {};
this.err = status.err || null;
this.code = status.code || null;
this.name = status.name || '';
this.msg = status.msg || '';
}
utils.ok = function() {
var args = utils.toArray(arguments) || [];
args.unshift(' ' + utils.green(utils.successSymbol));
console.log.apply(console, args);
};
utils.success = function() {
var args = utils.toArray(arguments) || [];
args[0] = utils.green(args[0] || '');
console.log.apply(console, args);
};
utils.error = function() {
var args = utils.toArray(arguments);
args.unshift(utils.red('Error:'));
console.error.apply(console, args);
};
/**
* CLI utils
*/
utils.commands = function(argv) {
argv._ = argv._ || [];
var commands = {};
argv._.forEach(function(key) {
commands[key] = true;
});
return commands;
};
utils.identity = function(val) {
return val;
};
utils.arrayify = function(val) {
return Array.isArray(val) ? val : [val];
};
utils.toArgv = function(args) {
var argv = args.flags;
argv._ = args.commands;
return argv;
};
utils.toArray = function(val) {
if (Array.isArray(val)) return val;
if (val && val.length) {
return [].slice.call(val);
}
};
utils.contains = function(arr, key) {
return arr.indexOf(key) > -1;
};
utils.npm = function(name) {
return utils.tryRequire(name) || utils.tryRequire(path.resolve(name));
};
utils.exists = function(fp) {
return fs.existsSync(fp);
};
/**
* Rename a filepath to the "nickname" of the project.
*
* ```js
* renameFn('updater-foo');
* //=> 'foo'
* ```
*/
utils.renameFn = function(filename, options) {
if (options && typeof options.renameFn === 'function') {
return options.renameFn(filename);
}
return filename.slice(filename.indexOf('-') + 1);
};
/**
* Return a glob of file paths
*/
utils.matchFiles = function(pattern, options) {
options = options || {};
var isMatch = utils.mm.matcher(pattern);
var files = fs.readdirSync(options.cwd);
var len = files.length, i = -1;
var res = [];
while (++i < len) {
var name = files[i];
if (name === 'update') continue;
var fp = path.join(options.cwd, name);
if (isMatch(fp) || isMatch(name)) {
res.push(fp);
}
}
return res;
};
/**
* Resolve the correct updater module to instantiate.
* If `update` exists in `node_modules` of the cwd,
* then that will be used to create the instance,
* otherwise this module will be used.
*/
utils.resolveModule = function(dir) {
dir = path.join(dir, 'node_modules/', pkg.name);
if (utils.exists(dir)) {
return require(path.resolve(dir));
}
return null;
};
/**
* Print a tree of "updaters" and their tasks
*
* ```js
* utils.tree(updaters);
* ```
*/
utils.tree = function(updaters) {
var res = '';
for (var key in updaters) {
res += utils.cyan(key) + '\n';
for (var task in updaters[key].tasks) {
res += ' - ' + task + '\n';
}
}
return res;
};
/**
* Return a list of "updaters" and their tasks
*
* ```js
* utils.list(updaters);
* ```
*/
utils.list = function(updaters) {
var list = [];
for (var key in updaters) {
var updater = updaters[key];
if (!Object.keys(updater.tasks).length) {
continue;
}
var hasDefault = updater.tasks['default'];
var name = updater.option('name');
var item = {
name: name + (hasDefault ? ' (default)' : ''),
value: key,
short: name + (hasDefault ? ':default' : '')
};
list.push(item);
for (var task in updater.tasks) {
if (task === 'default') continue;
list.push({
name: ' - ' + task,
value: key + ':' + task,
short: key + ':' + task
});
}
}
return list;
};
/**
* Try to require a file
*/
utils.tryRequire = function(name) {
try {
return require(name);
} catch (err) {
console.log(err);
}
return null;
};
/**
* Try to read a file
*/
utils.tryRead = function(fp) {
try {
return fs.readFileSync(fp);
} catch (err) {}
return null;
};
utils.tryParse = function(str) {
try {
return JSON.parse(str);
} catch (err) {}
return {};
};
utils.register = function(pattern, base, update, options) {
utils.matchFiles(pattern, options).forEach(function(fp) {
var name = utils.project(fp);
var mod = utils.resolveModule(fp) || update;
var app = mod(base.options)
.option('name', name)
.set('path', fp);
require(utils.updatefile(fp))(app, base);
base.updater(name, app);
});
};
utils.opts = function(key) {
key = key || 'opts';
return function(app) {
var name = this.options.name || 'base';
this.define(key, function() {
var config = this.defaults.apply(this, arguments);
return function(key, opts) {
var args = [].concat.apply([], [].slice.call(arguments));
var prop = typeof key === 'string' ? args.shift() : null;
var val;
if (prop && !args.length) {
val = utils.get(config, prop);
if (val) return val;
}
var options = utils.extend.apply(utils.extend, [config].concat(args));
return prop ? utils.get(options, prop) : options;
};
});
};
};
utils.defaults = function(key) {
key = key || 'defaults';
return function(app) {
this.define(key, function() {
var args = [].concat.apply([], [].slice.call(arguments));
args.unshift({}, this.options);
return utils.extend.apply(utils.extend, args);
});
};
};
/**
* Restore `require`
*/
require = fn;
/**
* Expose `utils`
*/
module.exports = utils;
/**
* Expose utils
*/
module.exports = utils;

View file

@ -1,155 +0,0 @@
{
"name": "update",
"description": "Easily keep anything in your project up-to-date by installing the updaters you want to use and running `update` in the command line! Update the copyright date, licence type, ensure that a project uses your latest eslint or jshint configuration, remove deprecated package.json fields, or anything you can think of!",
"version": "0.4.2",
"homepage": "https://github.com/update/update",
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
"authors": [
"Brian Woodward <brian.woodward@gmail.com> (https://github.com/doowb)",
"Jon Schlinkert (https://github.com/jonschlinkert)"
],
"contributors": [
"Brian Woodward <brian.woodward@gmail.com> (https://github.com/doowb)",
"Jon Schlinkert (https://github.com/jonschlinkert)"
],
"repository": "update/update",
"bugs": {
"url": "https://github.com/update/update/issues"
},
"license": "MIT",
"files": [
"bin",
"index.js",
"lib/"
],
"main": "index.js",
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
},
"preferGlobal": true,
"bin": {
"update": "bin/update.js"
},
"dependencies": {
"ansi-cyan": "^0.1.1",
"ansi-gray": "^0.1.1",
"ansi-green": "^0.1.1",
"ansi-red": "^0.1.1",
"ansi-yellow": "^0.1.1",
"assemble-core": "^0.8.0",
"assemble-loader": "^0.2.6",
"async": "^1.5.2",
"base": "^0.6.3",
"base-cli": "^0.4.0",
"base-config": "^0.3.3",
"base-options": "^0.5.4",
"base-pipeline": "^0.1.4",
"base-store": "^0.3.2",
"composer-runtimes": "^0.7.0",
"define-property": "^0.2.5",
"engine-base": "^0.1.2",
"expand-args": "^0.3.1",
"expand-object": "^0.4.1",
"export-files": "^2.1.0",
"extend-shallow": "^2.0.1",
"for-own": "^0.1.3",
"get-value": "^2.0.2",
"global-modules": "^0.2.0",
"gulp-eslint": "^1.1.1",
"lazy-cache": "^1.0.3",
"load-pkg": "^3.0.1",
"matched": "^0.4.1",
"micromatch": "^2.3.7",
"minimist": "^1.2.0",
"object.omit": "^2.0.0",
"object.pick": "^1.1.1",
"parser-front-matter": "^1.3.0",
"project-name": "^0.2.3",
"question-cache": "^0.3.5",
"rimraf": "^2.5.0",
"set-value": "^0.3.2",
"sort-object-arrays": "^0.1.1",
"stream-exhaust": "^1.0.1",
"success-symbol": "^0.1.0",
"through2": "^2.0.0",
"time-stamp": "^0.1.3",
"union-value": "^0.2.1",
"use": "^1.1.2"
},
"devDependencies": {
"buffer-equal": "^1.0.0",
"consolidate": "^0.13.1",
"coveralls": "^2.11.6",
"data-store": "^0.12.1",
"engine-handlebars": "^0.8.0",
"event-stream": "^3.3.2",
"graceful-fs": "^4.1.2",
"gulp": "^3.9.0",
"gulp-format-md": "^0.1.5",
"gulp-istanbul": "^0.10.3",
"gulp-mocha": "^2.2.0",
"is-buffer": "^1.1.1",
"istanbul": "^0.4.1",
"kind-of": "^3.0.2",
"mocha": "^2.3.4",
"resolve-glob": "^0.1.8",
"should": "^8.0.2",
"sinon": "^1.17.2",
"swig": "^1.4.2",
"vinyl": "^1.1.0"
},
"keywords": [
"lint",
"next",
"repo",
"update"
],
"verb": {
"related": {
"list": [
"assemble",
"boilerplate",
"composer",
"generate",
"scaffold",
"templates",
"update",
"verb"
],
"description": ""
},
"reflinks": [
"boilerplate",
"scaffold",
"template",
"verb",
"vinyl"
],
"plugins": [
"gulp-format-md"
],
"data": {
"author": {
"username": "jonschlinkert"
}
}
},
"update": {
"note": "this is just pseudo data for tests. I'll update with real stuff soon.",
"cwd": "lib/pipeline",
"helpers": {
"related": "@/helper-related"
},
"plugins": {
"./lib/pipeline/a": {},
"./lib/pipeline/b": {},
"./lib/pipeline/c": {}
},
"set": {
"aaa": "yyy"
}
}
}

View file

@ -1,87 +0,0 @@
'use strict';
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
var page = {
content: '<%= name %>',
layout: 'default.tmpl',
locals: {
name: 'Halle'
}
};
describe('helpers', function() {
describe('rendering', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('layout', { viewType: 'layout' });
app.create('page');
});
it('should throw an error when a layout cannot be found:', function(cb) {
app.layout('fofof.tmpl', {content: '..'});
app.page('a.tmpl', page)
.render(function(err) {
assert.equal(err.message, 'Templates#layouts layout "default.tmpl" was defined on view "a.tmpl"\nbut cannot be not found (common causes are incorrect glob patterns,\nrenameKey function modifying the key, and typos in search pattern)');
cb();
});
});
it('should emit an error when a layout cannot be found:', function(cb) {
app.layout('fofof.tmpl', {content: '..'});
app.on('error', function(err) {
assert.equal(err.message, 'Templates#layouts layout "default.tmpl" was defined on view "a.tmpl"\nbut cannot be not found (common causes are incorrect glob patterns,\nrenameKey function modifying the key, and typos in search pattern)');
cb();
});
app.page('a.tmpl', page)
.render(function() {
});
});
it('should throw an error - layout defined but no layouts registered:', function(cb) {
app.page('a.tmpl', page)
.render(function(err) {
assert.equal(err.message, 'Templates#layouts layout "default.tmpl" was defined on view "a.tmpl"\nbut cannot be not found (common causes are incorrect glob patterns,\nrenameKey function modifying the key, and typos in search pattern)');
cb();
});
});
it('should emit an error - layout defined but no layouts registered:', function(cb) {
app.on('error', function(err) {
assert.equal(err.message, 'Templates#layouts layout "default.tmpl" was defined on view "a.tmpl"\nbut cannot be not found (common causes are incorrect glob patterns,\nrenameKey function modifying the key, and typos in search pattern)');
cb();
});
app.page('a.tmpl', page)
.render(function() {
});
});
it('should wrap a view with a layout (view.render):', function(cb) {
app.layout('default.tmpl', {content: 'before {% body %} after'});
app.page('a.tmpl', page)
.render(function(err) {
if (err) return cb(err);
cb();
});
});
it('should wrap a view with a layout (app.render):', function(cb) {
app.layout('default.tmpl', {content: 'before {% body %} after'});
app.page('a.tmpl', page);
var view = app.pages.getView('a.tmpl');
app.render(view, function(err, res) {
if (err) return cb(err);
assert(res.contents.toString() === 'before Halle after');
cb();
});
});
});
});

View file

@ -1,50 +0,0 @@
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var Views = App.Views;
var views;
describe('compile', function() {
beforeEach(function() {
views = new Views();
});
it('should throw an error when an engine cannot be found:', function() {
views.addView('foo.bar', {content: '<%= name %>'});
var page = views.getView('foo.bar');
(function() {
views.compile(page);
}).should.throw('Views#compile cannot find an engine for: .bar');
});
it('should compile a template:', function() {
views.engine('tmpl', require('engine-base'));
views.addView('a.tmpl', {path: 'a.tmpl', content: '<%= a %>', a: 'b'});
var page = views.getView('a.tmpl');
var view = views.compile(page);
assert.equal(typeof view.fn, 'function');
});
it('should compile a template by name:', function() {
views.engine('tmpl', require('engine-base'));
views.addView('a.tmpl', {path: 'a.tmpl', content: '<%= a %>', a: 'b'});
var view = views.compile('a.tmpl');
assert.equal(typeof view.fn, 'function');
});
it('should throw an error when a callback is given:', function() {
views.engine('md', require('engine-base'));
views.addView('foo.md', {content: '<%= name %>'});
var page = views.getView('foo.md');
(function() {
views.compile(page, function() {});
}).should.throw('Views#compile is sync and does not take a callback function');
(function() {
views.compile(page, {}, function() {});
}).should.throw('Views#compile is sync and does not take a callback function');
});
});

View file

@ -1,186 +0,0 @@
'use strict';
require('mocha');
require('should');
var fs = require('fs');
var path = require('path');
var assert = require('assert');
var define = require('define-property');
var support = require('./support');
var App = support.resolve();
var Collection = App.Collection;
var app;
describe('collection', function() {
describe('method', function() {
beforeEach(function() {
app = new App();
});
it('should expose the collection method', function() {
assert(typeof app.collection === 'function');
});
it('should return a new collection', function() {
var collection = app.collection();
assert(typeof collection === 'object');
});
it('should have isCollection property', function() {
var collection = app.collection();
assert(collection.isCollection === true);
});
});
describe('adding views', function() {
beforeEach(function() {
app = new App()
.use(function() {
return function() {
define(this, 'count', {
get: function() {
return Object.keys(this.views).length;
},
set: function() {
throw new Error('count is a read-only getter and cannot be defined.');
}
});
};
});
app.engine('tmpl', require('engine-base'));
app.create('pages', {
renameKey: function(fp) {
return path.relative(process.cwd(), fp);
}
});
});
it('should load a view onto the respective collection:', function() {
app.pages('test/fixtures/pages/a.hbs');
app.views.pages.should.have.property('test/fixtures/pages/a.hbs');
});
it('should allow collection methods to be chained:', function() {
app
.pages('test/fixtures/pages/a.hbs')
.pages('test/fixtures/pages/b.hbs')
.pages('test/fixtures/pages/c.hbs');
app.views.pages.should.have.properties([
'test/fixtures/pages/a.hbs',
'test/fixtures/pages/b.hbs',
'test/fixtures/pages/c.hbs'
]);
});
it('should expose the `option` method:', function() {
app.pages.option('foo', 'bar')
.pages('test/fixtures/pages/a.hbs')
.pages('test/fixtures/pages/b.hbs')
.pages('test/fixtures/pages/c.hbs');
app.pages.options.should.have.property('foo', 'bar');
app.views.pages.should.have.properties([
'test/fixtures/pages/a.hbs',
'test/fixtures/pages/b.hbs',
'test/fixtures/pages/c.hbs'
]);
});
it('should expose the `option` method:', function() {
app.pages.option('foo', 'bar')
.pages('test/fixtures/pages/a.hbs')
.pages('test/fixtures/pages/b.hbs')
.pages('test/fixtures/pages/c.hbs');
assert(app.pages.count === 3);
});
});
describe('addItem', function() {
beforeEach(function() {
app = new App();
});
it('should add items to a collection', function() {
var pages = app.collection({Collection: Collection});
pages.addItem('foo');
pages.addItem('bar');
pages.addItem('baz');
pages.items.hasOwnProperty('foo');
pages.items.hasOwnProperty('bar');
pages.items.hasOwnProperty('baz');
});
it('should create a collection from an existing collection:', function() {
var pages = app.collection({Collection: Collection});
pages.addItem('foo');
pages.addItem('bar');
pages.addItem('baz');
var posts = app.collection(pages);
posts.items.hasOwnProperty('foo');
posts.items.hasOwnProperty('bar');
posts.items.hasOwnProperty('baz');
});
});
describe('rendering views', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('pages');
app.cache.data = {};
});
it('should render a view with inherited app.render', function(cb) {
app.page('test/fixtures/templates/a.tmpl')
.use(function(view) {
view.contents = fs.readFileSync(view.path);
})
.set('data.name', 'Brian')
.render(function(err, res) {
if (err) return cb(err);
assert(res.content === 'Brian');
cb();
});
});
});
});
describe('collection singular method', function() {
describe('create', function() {
beforeEach(function() {
app = new App();
});
it('should add a pluralized collection from singular name', function() {
app.create('page');
assert(typeof app.views.pages === 'object');
});
});
describe('adding views', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('page', {
renameKey: function(fp) {
return path.relative(process.cwd(), fp);
}
});
});
it('should add a view to the created collection:', function() {
app.page('test/fixtures/pages/a.hbs');
assert(typeof app.views.pages['test/fixtures/pages/a.hbs'] === 'object');
});
it('should expose the `option` method:', function() {
app.pages.option('foo', 'bar');
app.pages.options.should.have.property('foo', 'bar');
});
});
});

View file

@ -1,157 +0,0 @@
'use strict';
require('mocha');
require('should');
var async = require('async');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var List = App.List;
var pages, app;
describe('render', function() {
describe('rendering', function() {
beforeEach(function() {
app = App();
pages = app.create('pages');
app.engine('tmpl', require('engine-base'));
pages.engine('tmpl', require('engine-base'));
});
it('should throw an error when no callback is given:', function() {
(function() {
app.pages.render({});
}).should.throw('Views#render is async and expects a callback function');
});
it('should throw an error when an engine is not defined:', function(done) {
pages.addView('foo.bar', { content: '<%= name %>' });
var page = pages.getView('foo.bar');
app.pages.render(page, function(err) {
assert(err.message === 'Views#render cannot find an engine for: .bar');
done();
});
});
it('should use helpers defined on app to render a view:', function(done) {
var locals = {name: 'Halle'};
app.helper('upper', function(str) {
return str.toUpperCase(str) + 'app';
});
pages.addView('a.tmpl', {content: 'a <%= upper(name) %> b', locals: locals});
var page = pages.getView('a.tmpl');
app.render(page, function(err, res) {
if (err) return done(err);
assert(res.content === 'a HALLEapp b');
done();
});
});
it('should use helpers defined on app to render a view with collection.render:', function(done) {
var locals = {name: 'Halle'};
app.helper('upper', function(str) {
return str.toUpperCase(str) + 'app';
});
pages.addView('a.tmpl', {content: 'a <%= upper(name) %> b', locals: locals});
pages.helper('upper', app._.helpers.sync.upper);
var page = pages.getView('a.tmpl');
pages.render(page, function(err, res) {
if (err) return done(err);
assert(res.content === 'a HALLEapp b');
done();
});
});
it('should use helpers when rendering a view:', function(done) {
var locals = {name: 'Halle'};
pages.helper('upper', function(str) {
return str.toUpperCase(str);
});
pages.addView('a.tmpl', {content: 'a <%= upper(name) %> b', locals: locals});
var page = pages.getView('a.tmpl');
pages.render(page, function(err, res) {
if (err) return done(err);
assert(res.content === 'a HALLE b');
done();
});
});
it('should render a template when contents is a buffer:', function(done) {
pages.addView('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
var view = pages.getView('a.tmpl');
pages.render(view, function(err, view) {
if (err) return done(err);
assert(view.contents.toString() === 'b');
done();
});
});
it('should render a template when content is a string:', function(done) {
pages.addView('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
var view = pages.getView('a.tmpl');
pages.render(view, function(err, view) {
if (err) return done(err);
assert(view.contents.toString() === 'b');
done();
});
});
it('should render a view from its path:', function(done) {
pages.addView('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
pages.render('a.tmpl', function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
it('should use a plugin for rendering:', function(done) {
pages.engine('tmpl', require('engine-base'));
pages.option('engine', 'tmpl');
pages.addViews({
'a': {content: '<%= title %>', locals: {title: 'aaa'}},
'b': {content: '<%= title %>', locals: {title: 'bbb'}},
'c': {content: '<%= title %>', locals: {title: 'ccc'}},
'd': {content: '<%= title %>', locals: {title: 'ddd'}},
'e': {content: '<%= title %>', locals: {title: 'eee'}},
'f': {content: '<%= title %>', locals: {title: 'fff'}},
'g': {content: '<%= title %>', locals: {title: 'ggg'}},
'h': {content: '<%= title %>', locals: {title: 'hhh'}},
'i': {content: '<%= title %>', locals: {title: 'iii'}},
'j': {content: '<%= title %>', locals: {title: 'jjj'}}
});
pages.use(function(collection) {
collection.option('pager', false);
collection.renderEach = function(cb) {
var list = new List(collection);
async.map(list.items, function(item, next) {
collection.render(item, next);
}, cb);
};
});
pages.renderEach(function(err, items) {
if (err) return done(err);
assert(items[0].content === 'aaa');
assert(items[9].content === 'jjj');
assert(items.length === 10);
done();
});
});
});
});

View file

@ -1,52 +0,0 @@
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('compile', function() {
beforeEach(function() {
app = new App();
app.create('page');
});
it('should throw an error when an engine cannot be found:', function() {
app.page('foo.bar', {content: '<%= name %>'});
var page = app.pages.getView('foo.bar');
(function() {
app.compile(page);
}).should.throw('Templates#compile cannot find an engine for: .bar');
});
it('should compile a template:', function() {
app.engine('tmpl', require('engine-base'));
app.pages('a.tmpl', {path: 'a.tmpl', content: '<%= a %>', a: 'b'});
var page = app.pages.getView('a.tmpl');
var view = app.compile(page);
assert.equal(typeof view.fn, 'function');
});
it('should compile a template by name:', function() {
app.engine('tmpl', require('engine-base'));
app.pages('a.tmpl', {path: 'a.tmpl', content: '<%= a %>', a: 'b'});
var view = app.compile('a.tmpl');
assert.equal(typeof view.fn, 'function');
});
it('should throw an error when a callback is given:', function() {
app.engine('md', require('engine-base'));
app.page('foo.md', {content: '<%= name %>'});
var page = app.pages.getView('foo.md');
(function() {
app.compile(page, function() {
});
}).should.throw('Templates#compile is sync and does not take a callback function');
(function() {
app.compile(page, {}, function() {
});
}).should.throw('Templates#compile is sync and does not take a callback function');
});
});

View file

@ -1,31 +0,0 @@
require('mocha');
var path = require('path');
var assert = require('assert');
var rimraf = require('rimraf');
var App = require('..');
var app;
var fixtures = path.join(__dirname, 'fixtures/copy/*.txt');
var actual = path.join(__dirname, 'actual');
describe('copy()', function() {
beforeEach(function(done) {
rimraf(actual, done);
app = new App();
});
afterEach(function(done) {
rimraf(actual, done);
});
describe('streams', function() {
it('should copy files', function(done) {
app.copy(fixtures, path.join(__dirname, 'actual'))
.on('error', done)
.on('data', function(file) {
assert.equal(typeof file, 'object');
})
.on('end', done);
});
});
});

View file

@ -1,244 +0,0 @@
require('mocha');
require('should');
var fs = require('fs');
var path = require('path');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('create', function() {
describe('inflections', function() {
beforeEach(function() {
app = new App();
});
it('should expose the create method', function() {
assert(typeof app.create === 'function');
});
it('should add a collection to `views`', function() {
app.create('pages');
assert(typeof app.views.pages === 'object');
assert(typeof app.pages === 'function');
});
it('should add a pluralized collection to `views`', function() {
app.create('page');
assert(typeof app.views.pages === 'object');
assert(typeof app.page === 'function');
});
});
describe('renderable views', function() {
beforeEach(function() {
app = new App();
app.create('pages');
app.create('partials', {viewType: 'partial'});
app.create('layout', {viewType: 'layout'});
});
it('should add renderable views when no type is defined', function() {
app.pages.addView('foo', {content: 'bar'});
assert(app.views.pages.hasOwnProperty('foo'));
});
it('should add view Ctor names to views', function() {
app.pages.addView('foo', {content: 'bar'});
assert(app.views.pages.foo._name === 'Page');
});
it('should add partial views when partial type is defined', function() {
app.partials.addView('abc', {content: 'xyz'});
assert(app.views.partials.hasOwnProperty('abc'));
});
it('should add layout views when layout type is defined', function() {
app.layouts.addView('foo', {content: 'bar'});
assert(app.views.layouts.hasOwnProperty('foo'));
});
it('should set viewType on renderable views', function() {
app.pages.addView('foo', {content: 'bar'});
var view = app.pages.getView('foo');
assert(view.isType('renderable'));
assert(!view.isType('layout'));
assert(!view.isType('partial'));
});
it('should set viewType on partial views', function() {
app.partials.addView('foo', {content: 'bar'});
var view = app.partials.getView('foo');
assert(view.isType('partial'));
assert(!view.isType('layout'));
assert(!view.isType('renderable'));
});
it('should set viewType on layout views', function() {
app.layouts.addView('foo', {content: 'bar'});
var view = app.layouts.getView('foo');
assert(view.isType('layout'));
assert(!view.isType('renderable'));
assert(!view.isType('partial'));
});
});
describe('custom constructors', function() {
beforeEach(function() {
var Vinyl = require('vinyl');
Vinyl.prototype.custom = function(key) {
this[key] = 'nonsense';
return this;
};
app = new App({View: Vinyl});
app.create('pages');
});
it('should create views from key-value pairs:', function() {
app.page('a.hbs', {path: 'a.hbs', content: 'a'});
app.page('b.hbs', {path: 'b.hbs', content: 'b'});
app.page('c.hbs', {path: 'c.hbs', content: 'c'});
var a = app.pages.getView('a.hbs');
a.custom('foo');
a.foo.should.equal('nonsense');
});
});
describe('custom instances', function() {
it('should create views from custom `View` and `Views` instance/ctor:', function() {
var Vinyl = require('vinyl');
Vinyl.prototype.read = function(file) {
return fs.readFileSync(file.path);
};
var Views = App.Views;
var views = new Views({View: Vinyl});
views.addView('a.hbs', {path: 'a.hbs', content: 'a'});
views.addView('b.hbs', {path: 'b.hbs', content: 'b'});
views.addView('c.hbs', {path: 'c.hbs', content: 'c'});
app = new App();
app.create('pages', views);
var a = app.pages.getView('a.hbs');
assert(a instanceof Vinyl);
assert(Vinyl.isVinyl(a));
assert(typeof a.read === 'function');
views.addView('d.hbs', {path: 'd.hbs', content: 'd'});
var d = app.pages.getView('d.hbs');
assert(d instanceof Vinyl);
assert(Vinyl.isVinyl(d));
});
});
describe('chaining', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('page', {
renameKey: function(fp) {
return path.relative(process.cwd(), fp);
}
});
});
it('should create views from key-value pairs:', function() {
app.page('a.hbs', {content: 'a'});
app.page('b.hbs', {content: 'b'});
app.page('c.hbs', {content: 'c'});
app.views.pages.should.have.properties(['a.hbs', 'b.hbs', 'c.hbs']);
assert(app.views.pages['a.hbs'].contents.toString() === 'a');
});
it('should create views from file paths:', function() {
app.page('test/fixtures/pages/a.hbs');
app.page('test/fixtures/pages/b.hbs');
app.page('test/fixtures/pages/c.hbs');
app.views.pages.should.have.properties([
'test/fixtures/pages/a.hbs',
'test/fixtures/pages/b.hbs',
'test/fixtures/pages/c.hbs'
]);
});
});
describe('instance', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
});
it('should return the collection instance', function() {
var collection = app.create('pages');
assert(collection instanceof App.Views);
collection.option('renameKey', function(key) {
return path.basename(key);
});
collection
.use(function(views) {
views.read = function(name) {
var view = this.getView(name);
view.contents = fs.readFileSync(view.path);
};
});
collection.addView('test/fixtures/templates/a.tmpl');
collection.read('a.tmpl');
assert(collection.getView('a.tmpl').contents.toString() === '<%= name %>');
});
});
describe('viewType', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
});
it('should add collection to the given viewType', function() {
app.create('layout', {viewType: 'layout'});
assert(app.layouts.options.viewType[0] === 'layout');
});
it('should add a collection to multiple viewTypes', function() {
app.create('foo', {viewType: ['layout', 'renderable']});
assert.deepEqual(app.foos.options.viewType, ['layout', 'renderable']);
});
});
describe('events', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
});
it('should emit `create` when a collection is created:', function() {
app.on('create', function(collection) {
if (collection.options.plural === 'layouts') {
collection.options.foo = 'bar';
}
});
app.create('layout');
app.layout('one', {path: 'two', contents: '...'});
assert(app.layouts.options.foo === 'bar');
});
});
describe('collection instantiation', function() {
it('should expose collection instance methods that are created after instantiation on the app collection loader', function() {
app.create('pages');
app.pages.use(function(collection) {
collection.define('foo', function(msg) {
return 'foo ' + msg;
});
});
assert(app.pages.foo);
assert(typeof app.pages.foo === 'function');
});
});
});

View file

@ -1,94 +0,0 @@
require('mocha');
require('should');
var path = require('path');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('app.data', function() {
beforeEach(function() {
app = new App();
});
it('should set a key-value pair on cache.data:', function() {
app.data('a', 'b');
assert(app.cache.data.a === 'b');
});
it('should set an object on cache.data:', function() {
app.data({c: 'd'});
assert(app.cache.data.c === 'd');
});
it('should load data from a file onto cache.data:', function() {
app.data('test/fixtures/data/a.json');
assert(app.cache.data.a.one.a === 'aaa');
});
it('should load a glob of data onto cache.data:', function() {
app.data('test/fixtures/data/*.json');
assert(app.cache.data.a.one.a === 'aaa');
assert(app.cache.data.b.two.b === 'bbb');
assert(app.cache.data.c.three.c === 'ccc');
});
it('should use `namespace` defined on global opts:', function() {
app.option('namespace', function(key) {
return 'prefix_' + path.basename(key, path.extname(key));
});
app.data('test/fixtures/data/*.json');
assert(app.cache.data.prefix_a.one.a === 'aaa');
assert(app.cache.data.prefix_b.two.b === 'bbb');
assert(app.cache.data.prefix_c.three.c === 'ccc');
});
it('should use `namespace` defined on data opts:', function() {
app.data('test/fixtures/data/*.json', {
namespace: function(key) {
return 'prefix_' + path.basename(key, path.extname(key));
}
});
assert(app.cache.data.prefix_a.one.a === 'aaa');
assert(app.cache.data.prefix_b.two.b === 'bbb');
assert(app.cache.data.prefix_c.three.c === 'ccc');
});
it('should use `renameKey` defined on data opts:', function() {
app.data('test/fixtures/data/*.json', {
renameKey: function(key) {
return 'prefix_' + path.basename(key, path.extname(key));
}
});
assert(app.cache.data.prefix_a.one.a === 'aaa');
assert(app.cache.data.prefix_b.two.b === 'bbb');
assert(app.cache.data.prefix_c.three.c === 'ccc');
});
it('should extend `cache.data`', function() {
app.data({a: 'aaa', b: 'bbb', c: 'ccc'});
app.data({x: 'xxx', y: 'yyy', z: 'zzz'});
assert(app.cache.data.a === 'aaa');
assert(app.cache.data.b === 'bbb');
assert(app.cache.data.c === 'ccc');
assert(app.cache.data.x === 'xxx');
assert(app.cache.data.y === 'yyy');
assert(app.cache.data.z === 'zzz');
});
it('should extend the `cache.data` object when the first param is a string.', function() {
app.data('foo', {x: 'xxx', y: 'yyy', z: 'zzz'});
app.data('bar', {a: 'aaa', b: 'bbb', c: 'ccc'});
assert(app.cache.data.foo.x === 'xxx');
assert(app.cache.data.bar.a === 'aaa');
});
it('should be chainable.', function() {
app
.data({x: 'xxx', y: 'yyy', z: 'zzz'})
.data({a: 'aaa', b: 'bbb', c: 'ccc'});
assert(app.cache.data.x === 'xxx');
assert(app.cache.data.a === 'aaa');
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,160 +0,0 @@
'use strict';
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('engine support', function() {
beforeEach(function() {
app = new App();
});
it('should throw an error when engine name is invalid:', function() {
(function() {
app.engine(null, {});
}).should.throw('expected engine ext to be a string or array.');
});
it('should register an engine to the given extension', function() {
app.engine('hbs', function() {});
assert(typeof app.engines['.hbs'] === 'object');
});
it('should set an engine with the given extension', function() {
var hbs = function() {};
hbs.render = function() {};
hbs.renderFile = function() {};
app.engine('hbs', hbs);
assert(app.engines['.hbs']);
assert(app.engines['.hbs'].renderFile);
assert(app.engines['.hbs'].render);
});
it('should get an engine:', function() {
app.engine('hbs', function() {});
var hbs = app.engine('hbs');
assert(typeof hbs === 'object');
assert(hbs.hasOwnProperty('render'));
assert(hbs.hasOwnProperty('compile'));
});
it('should return undefined if no engine is found:', function() {
var hbs = app.getEngine();
assert.equal(typeof hbs, 'undefined');
});
it('should register multiple engines to the given extension', function() {
app.engine(['hbs', 'md'], function() {});
assert(typeof app.engines['.hbs'] === 'object');
assert(typeof app.engines['.md'] === 'object');
});
});
describe('engines', function() {
beforeEach(function() {
app = new App();
app.create('pages');
app.pages('foo.tmpl', {content: 'A <%= letter %> {{= letter }} C'});
app.pages('bar.tmpl', {content: 'A <%= letter %> {{ letter }} C'});
});
it('should register an engine:', function() {
app.engine('a', {render: function() {}});
app.engines.should.have.property('.a');
});
it('should use custom delimiters:', function(cb) {
app.engine('tmpl', require('engine-base'), {
delims: ['{{', '}}']
});
app.render('foo.tmpl', {letter: 'B'}, function(err, res) {
if (err) return cb(err);
res.contents.toString().should.equal('A <%= letter %> B C');
cb();
});
});
it('should override individual delims values:', function(cb) {
app.engine('tmpl', require('engine-base'), {
interpolate: /\{{([^}]+)}}/g,
evaluate: /\{{([^}]+)}}/g,
escape: /\{{-([^}]+)}}/g
});
app.render('bar.tmpl', {letter: 'B'}, function(err, res) {
if (err) return cb(err);
res.contents.toString().should.equal('A <%= letter %> B C');
cb();
});
});
it('should get an engine:', function() {
app.engine('a', {
render: function() {}
});
var a = app.engine('a');
a.should.have.property('render');
});
});
describe('engine selection:', function() {
beforeEach(function(cb) {
app = new App();
app.engine('tmpl', require('engine-base'));
app.engine('hbs', require('engine-handlebars'));
app.create('pages');
cb();
});
it('should get the engine from file extension:', function(cb) {
app.page('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}})
.render(function(err, view) {
if (err) return cb(err);
assert(view.content === 'b');
cb();
});
});
it('should use the engine defined on the collection:', function(cb) {
app.create('posts', {engine: 'hbs'});
app.post('a', {content: '{{a}}', locals: {a: 'b'}})
.render(function(err, view) {
if (err) return cb(err);
assert(view.content === 'b');
cb();
});
});
it('should use the engine defined on the view:', function(cb) {
app.create('posts');
app.post('a', {content: '{{a}}', engine: 'hbs', locals: {a: 'b'}})
.render(function(err, view) {
if (err) return cb(err);
assert(view.content === 'b');
cb();
});
});
it('should use the engine defined on `view.data`:', function(cb) {
app.create('posts');
app.post('a', {content: '{{a}}', locals: {a: 'b'}, data: {engine: 'hbs'}})
.render(function(err, view) {
if (err) return cb(err);
assert(view.content === 'b');
cb();
});
});
it('should use the engine defined on render locals:', function(cb) {
app.create('posts');
app.post('a', {content: '{{a}}', locals: {a: 'b'}})
.render({engine: 'hbs'}, function(err, view) {
if (err) return cb(err);
assert(view.content === 'b');
cb();
});
});
});

View file

@ -1,113 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('events', function() {
beforeEach(function() {
app = new App();
});
it('should listen for an event:', function() {
var app = new App();
app.on('foo', function() {});
assert(Array.isArray(app._callbacks['$foo']));
});
it('should emit an event:', function(done) {
var app = new App();
app.on('foo', function(val) {
assert(val === 'bar');
done();
});
assert(Array.isArray(app._callbacks['$foo']));
app.emit('foo', 'bar');
});
it('should listen for `view` events:', function() {
app = new App();
app.on('view', function(view) {
view.foo = 'bar';
});
var view = app.view({path: 'a', content: 'b'});
assert(view.foo === 'bar');
});
});
describe('onLoad', function() {
beforeEach(function() {
app = new App();
});
describe('app.collection', function() {
it('should emit a `view` event when view is created', function(done) {
var collection = app.collection();
app.on('view', function(view) {
assert(view.path === 'blog/foo.js');
done();
});
app.onLoad('blog/:title', function(view, next) {
assert(view.path === 'blog/foo.js');
next();
});
collection.addView('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
it('should emit an onLoad event when view is created', function(done) {
var collection = app.collection();
app.on('onLoad', function(view) {
assert(view.path === 'blog/foo.js');
done();
});
app.onLoad('blog/:title', function(view, next) {
assert(view.path === 'blog/foo.js');
next();
});
collection.addView('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
});
describe('view collections', function() {
it('should emit a view event when view is created', function(done) {
app.create('posts');
app.on('view', function(view) {
assert(view.path === 'blog/foo.js');
done();
});
app.onLoad('blog/:title', function(view, next) {
assert(view.path === 'blog/foo.js');
next();
});
app.post('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
it('should emit an onLoad event when view is created', function(done) {
app.create('posts');
app.on('onLoad', function(view) {
assert(view.path === 'blog/foo.js');
done();
});
app.onLoad('blog/:title', function(view, next) {
assert(view.path === 'blog/foo.js');
next();
});
app.post('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
});
});

View file

@ -1,72 +0,0 @@
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('app.set()', function() {
beforeEach(function() {
app = new App();
});
it('should set a value', function() {
app.set('a', 'b');
app.get('a').should.equal('b');
});
it('should set properties on the instance.', function() {
app.set('a', 'b');
app.a.should.equal('b');
});
it('should allow an object to be set directly.', function() {
app.set({x: 'y'});
app.x.should.equal('y');
app.get('x').should.equal('y');
});
it('should set nested properties on the instance.', function() {
app.set('c', {d: 'e'});
app.get('c').d.should.equal('e');
});
it('should use dot notation to `set` values.', function() {
app.set('h.i', 'j');
app.get('h').should.eql({i: 'j'});
});
it('should use dot notation to `get` values.', function() {
app.set('h', {i: 'j'});
app.get('h.i').should.equal('j');
});
it('should return `this` for chaining', function() {
app.set('a', 'b').should.equal(app);
app
.set('aa', 'bb')
.set('bb', 'cc')
.set('cc', 'dd');
app.get('aa').should.equal('bb');
app.get('bb').should.equal('cc');
app.get('cc').should.equal('dd');
});
it('should return undefined when not set', function() {
app.set('a', undefined).should.equal(app);
});
});
describe('app.get()', function() {
beforeEach(function() {
app = new App();
});
it('should return undefined when no set', function() {
assert(app.get('a') === undefined);
});
it('should otherwise return the value', function() {
app.set('a', 'b');
app.get('a').should.equal('b');
});
});

View file

@ -1,37 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('handler', function() {
beforeEach(function() {
app = new App();
app.create('pages');
app.handlers(['foo']);
});
it('should support custom handle methods:', function(done) {
var page = app.page('foo', {contents: null});
app.handle('foo', page, function(err, view) {
if (err) return done(err);
assert(typeof view.path === 'string');
done();
});
});
it('should not blow up if `options.handled` does not exist:', function(done) {
var page = app.page('foo', {contents: null});
delete page.options.handled;
app.handle('foo', page, function(err, view) {
if (err) return done(err);
assert(typeof view.path === 'string');
done();
});
});
});

View file

@ -1,72 +0,0 @@
require('should');
var fs = require('fs');
var path = require('path');
var assert = require('assert');
var resolve = require('resolve-glob');
var support = require('./support');
var App = support.resolve();
var app;
function decorateViews(views) {
var fn = views.decorateView;
views.decorateView = function() {
var view = fn.apply(fn, arguments);
view.read = function() {
if (!this.contents) {
this.contents = fs.readFileSync(this.path);
}
};
return view;
};
views.loader = function(pattern) {
var files = resolve.sync(pattern);
return files.reduce(function(acc, fp) {
acc[fp] = {path: fp};
return acc;
}, {});
};
return views;
}
describe('handlers', function() {
describe('custom handlers', function() {
beforeEach(function() {
app = new App();
app.create('pages')
.use(decorateViews)
.option('renameKey', function(key) {
return path.basename(key);
});
});
it('should add custom middleware handlers:', function() {
app.handler('foo');
app.router.should.have.property('foo');
assert.equal(typeof app.router.foo, 'function');
});
it('should add custom middleware handlers:', function() {
app.handler('foo');
app.handler('bar');
app.foo(/./, function(view, next) {
view.one = 'aaa';
next();
});
app.bar(/./, function(view, next) {
view.two = 'zzz';
next();
});
app.page('abc', {content: '...'})
.use(function(view) {
app.handleView('foo', view);
app.handleView('bar', view);
});
app.views.pages.abc.should.have.property('one', 'aaa');
app.views.pages.abc.should.have.property('two', 'zzz');
});
});
});

View file

@ -1,130 +0,0 @@
/* deps: coveralls istanbul */
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var Base = App.Base;
var app;
describe('app', function() {
describe('constructor', function() {
it('should create an instance of App:', function() {
app = new App();
assert(app instanceof App);
});
it('should new up without new:', function() {
app = App();
assert(app instanceof App);
});
});
describe('static methods', function() {
it('should expose `extend`:', function() {
assert(typeof App.extend === 'function');
});
});
describe('prototype methods', function() {
beforeEach(function() {
app = new App();
});
it('should expose `set`', function() {
assert(typeof app.set === 'function');
});
it('should expose `get`', function() {
assert(typeof app.get === 'function');
});
it('should expose `visit`', function() {
assert(typeof app.visit === 'function');
});
it('should expose `define`', function() {
assert(typeof app.define === 'function');
});
it('should expose `views`', function() {
assert(typeof app.views === 'object');
});
});
describe('instance', function() {
beforeEach(function() {
app = new App();
});
it('should set a value on the instance:', function() {
app.set('a', 'b');
assert(app.a === 'b');
});
it('should get a value from the instance:', function() {
app.set('a', 'b');
assert(app.get('a') === 'b');
});
});
describe('initialization', function() {
it('should listen for errors:', function(done) {
app = new App();
app.on('error', function(err) {
assert(err.message === 'foo');
done();
});
app.emit('error', new Error('foo'));
});
it('should mixin methods after init:', function() {
app = new App();
app.option({
mixins: {
foo: function() {}
}
});
assert(typeof app.foo === 'function');
});
it('should expose constructors from `lib`:', function() {
app = new App();
app.expose('Collection');
assert(typeof app.Collection === 'function');
});
it('should update constructors after init:', function() {
var Group = App.Group;
function MyGroup() {
Base.call(this);
}
Base.extend(MyGroup);
app = new App();
assert.equal(app.Group, Group);
assert.equal(app.get('Group'), Group);
app.option('Group', MyGroup);
assert.equal(app.Group, MyGroup);
assert.equal(app.get('Group'), MyGroup);
});
it('should mixin prototype methods defined on options:', function() {
app = new App({
mixins: {
foo: function() {}
}
});
assert(typeof app.foo === 'function');
delete App.prototype.foo;
});
it('should expose `_` on app:', function() {
app = new App();
assert(typeof app._ === 'object');
});
it('should not re-add `_` in init:', function() {
app = new App();
app._.foo = 'bar';
app.defaultConfig();
assert(app._.foo === 'bar');
});
});
});

View file

@ -1,44 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var List = App.List;
var list;
describe('app.list.compile', function() {
beforeEach(function() {
list = new List();
list.engine('tmpl', require('engine-base'));
});
it('should compile an item:', function() {
var buffer = new Buffer('a b c');
var item = list.addItem('a.tmpl', {contents: buffer})
.compile();
assert(typeof item.fn === 'function');
});
it('should use the compiled function to render:', function() {
var buffer = new Buffer('a <%= title %> c');
var item = list.addItem('a.tmpl', {contents: buffer})
.compile();
assert(item.fn({title: 'z'}));
assert(typeof item.fn({title: 'z'}) === 'string');
assert(item.fn({title: 'z'}) === 'a z c');
});
it('should compile a view by name:', function() {
var buffer = new Buffer('a <%= title %> c');
list.addItem('a.tmpl', {contents: buffer});
var item = list.compile('a.tmpl');
assert(item.fn({title: 'z'}));
assert(typeof item.fn({title: 'z'}) === 'string');
assert(item.fn({title: 'z'}) === 'a z c');
});
});

View file

@ -1,111 +0,0 @@
'use strict';
require('mocha');
require('should');
var fs = require('fs');
var path = require('path');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var List = App.List;
var app;
describe('list', function() {
describe('method', function() {
beforeEach(function() {
app = new App();
});
it('should expose the list method', function() {
assert(typeof app.list === 'function');
});
it('should return a new list', function() {
var list = app.list();
assert(typeof list === 'object');
});
it('should have isList property', function() {
var list = app.list();
assert(list.isList === true);
});
});
describe('adding items', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('pages', {
renameKey: function(fp) {
return path.relative(process.cwd(), fp);
}
});
});
it('should add an item to a list:', function() {
app.pages('test/fixtures/pages/a.hbs');
var list = app.list();
list.addItem(app.pages.getView('test/fixtures/pages/a.hbs'));
assert(list.hasItem('test/fixtures/pages/a.hbs'));
});
it('should expose the `option` method from a list:', function() {
var list = app.list();
list.option('a', 'b');
assert(list.options);
assert(list.options.a === 'b');
});
});
describe('addItem', function() {
beforeEach(function() {
app = new App();
});
it('should add items to a list', function() {
var pages = app.list({List: List});
pages.addItem('foo');
pages.addItem('bar');
pages.addItem('baz');
pages.items.hasOwnProperty('foo');
pages.items.hasOwnProperty('bar');
pages.items.hasOwnProperty('baz');
});
it('should create a list from an existing list:', function() {
var pages = app.list({List: List});
pages.addItem('foo');
pages.addItem('bar');
pages.addItem('baz');
var posts = app.list(pages);
posts.items.hasOwnProperty('foo');
posts.items.hasOwnProperty('bar');
posts.items.hasOwnProperty('baz');
});
});
describe('rendering items', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('pages');
});
it('should render a item with inherited app.render', function(done) {
app.page('test/fixtures/templates/a.tmpl')
.use(function(item) {
if (!item.content) {
item.contents = fs.readFileSync(item.path);
}
})
.set('data.name', 'Brian')
.render(function(err, res) {
if (err) return done(err);
assert(res.contents.toString() === 'Brian');
done();
});
});
});
});

View file

@ -1,112 +0,0 @@
require('mocha');
require('should');
var fs = require('fs');
var path = require('path');
var assert = require('assert');
var resolve = require('resolve-glob');
var support = require('./support');
var App = support.resolve();
var app;
describe('lookups', function() {
beforeEach(function() {
app = new App();
app.option('renameKey', function(key) {
return path.basename(key);
});
app.create('pages')
.use(function(pages) {
pages.on('addViews', function(glob) {
var files = resolve.sync(glob);
files.forEach(function(fp) {
pages.addView(fp, {path: fp});
});
pages.loaded = true;
});
return function(view) {
view.read = function() {
this.contents = fs.readFileSync(this.path);
};
return view;
};
});
app.pages('test/fixtures/templates/*.tmpl');
});
describe('getView', function() {
it('should find a view', function() {
var view = app.getView('pages', 'a.tmpl');
assert(typeof view.path === 'string');
});
it('should find a view using the renameKey function', function() {
var view = app.getView('pages', 'test/fixtures/templates/a.tmpl');
assert(typeof view.path === 'string');
});
it('should return null when nothing is found', function() {
var view = app.getView('pages', 'test/fixtures/templates/foo.tmpl');
assert(view === null);
});
it('should find a view using a glob pattern', function() {
var view = app.getView('pages', 'a', function(key) {
return key + '.tmpl';
});
assert(typeof view.path === 'string');
});
});
describe('getViews', function() {
it('should return the collection object if passed:', function() {
var views = app.getViews(app.views.pages);
assert(Object.keys(views).length > 1);
});
it('should return the specified collection with the plural name:', function() {
var views = app.getViews('pages');
assert(Object.keys(views).length > 1);
});
it('should return the specified collection with the singular name:', function() {
var views = app.getViews('page');
assert(Object.keys(views).length > 1);
});
it('should return null when the collection is not found:', function() {
(function() {
app.getViews('nada');
}).should.throw('getViews cannot find collection: nada');
});
});
describe('find', function() {
it('should return null when a view is not found:', function() {
(function() {
app.find({});
}).should.throw('expected name to be a string.');
});
it('should find a view by collection name:', function() {
var view = app.find('a.tmpl', 'pages');
assert(typeof view.path === 'string');
});
it('should find a view by collection name:', function() {
app = new App();
app.option('renameKey', function(key) {
return path.basename(key);
});
app.create('pages');
app.page('a/b/c.md', {content: '...'});
var view = app.find('a/b/c.md');
assert(typeof view.path === 'string');
});
it('should find a view without a collection name:', function() {
var view = app.find('a.tmpl');
assert(typeof view.path === 'string');
});
});
});

View file

@ -1,60 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('middleware', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('pages');
});
it('should call the all method for every middleware method:', function() {
var i = 0;
app.all(/./, function(view, next) {
assert(typeof view.path === 'string');
i++;
next();
});
assert(i === 0);
app.page('foo.tmpl', {content: 'foo'});
assert(i === 1);
});
it('should call the onLoad method when a view is loaded:', function() {
var i = 0;
app.onLoad(/./, function(view, next) {
assert(typeof view.path === 'string');
i++;
next();
});
assert(i === 0);
app.page('foo.tmpl', {content: 'foo'});
assert(i === 1);
});
it('should emit an event when a handler is called:', function(done) {
var i = 0;
app.on('onLoad', function() {
i++;
});
app.on('preRender', function() {
i++;
});
app.on('preCompile', function() {
i++;
});
app.page('foo.tmpl', {content: 'foo'})
.render(function(err) {
if (err) return done(err);
assert(i === 3);
done();
});
});
});

View file

@ -1,48 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('onLoad', function() {
beforeEach(function() {
app = new App();
});
describe('app.collection', function() {
it('should emit an onLoad when view is created', function(done) {
var collection = app.collection();
app.on('onLoad', function(view) {
assert(view.path === 'blog/foo.js');
done();
});
app.onLoad('blog/:title', function(view, next) {
assert(view.path === 'blog/foo.js');
next();
});
collection.addView('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
});
describe('view collections', function() {
it('should emit an onLoad when view is created', function(done) {
app.create('posts');
app.on('onLoad', function(view) {
assert(view.path === 'blog/foo.js');
done();
});
app.onLoad('blog/:title', function(view, next) {
assert(view.path === 'blog/foo.js');
next();
});
app.post('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
});
});

View file

@ -1,98 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('app.option', function() {
beforeEach(function() {
app = new App();
});
it('should set a key-value pair on options:', function() {
app.option('a', 'b');
assert(app.options.a === 'b');
});
it('should set an object on options:', function() {
app.option({c: 'd'});
assert(app.options.c === 'd');
});
it('should set an option.', function() {
app.option('a', 'b');
app.options.should.have.property('a');
});
it('should get an option.', function() {
app.option('a', 'b');
app.option('a').should.equal('b');
});
it('should extend the `options` object.', function() {
app.option({x: 'xxx', y: 'yyy', z: 'zzz'});
app.option('x').should.equal('xxx');
app.option('y').should.equal('yyy');
app.option('z').should.equal('zzz');
});
it('options should be on the `options` object.', function() {
app.option({x: 'xxx', y: 'yyy', z: 'zzz'});
app.options.x.should.equal('xxx');
app.options.y.should.equal('yyy');
app.options.z.should.equal('zzz');
});
it('should be chainable.', function() {
app.option({x: 'xxx', y: 'yyy', z: 'zzz'});
app.option({a: 'aaa', b: 'bbb', c: 'ccc'});
app.option('x').should.equal('xxx');
app.option('a').should.equal('aaa');
});
it('should extend the `options` object when the first param is a string.', function() {
app.option('foo', {x: 'xxx', y: 'yyy', z: 'zzz'});
app.option('bar', {a: 'aaa', b: 'bbb', c: 'ccc'});
app.option('foo').should.have.property('x');
app.option('bar').should.have.property('a');
app.options.foo.should.have.property('x');
app.options.bar.should.have.property('a');
});
it('should set an option.', function() {
app.option('a', 'b');
app.options.should.have.property('a');
});
it('should get an option.', function() {
app.option('a', 'b');
app.option('a').should.equal('b');
});
it('should extend the `options` object.', function() {
app.option({x: 'xxx', y: 'yyy', z: 'zzz'});
app.option('x').should.equal('xxx');
app.option('y').should.equal('yyy');
app.option('z').should.equal('zzz');
});
it('options should be on the `options` object.', function() {
app.option({x: 'xxx', y: 'yyy', z: 'zzz'});
app.options.x.should.equal('xxx');
app.options.y.should.equal('yyy');
app.options.z.should.equal('zzz');
});
it('should be chainable.', function() {
app
.option({x: 'xxx', y: 'yyy', z: 'zzz'})
.option({a: 'aaa', b: 'bbb', c: 'ccc'});
app.option('x').should.equal('xxx');
app.option('a').should.equal('aaa');
});
});

View file

@ -1,88 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('render', function() {
describe('rendering', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('page');
});
it('should throw an error when no callback is given:', function() {
(function() {
app.render({});
}).should.throw('Templates#render is async and expects a callback function');
});
it('should throw an error when an engine is not defined:', function(done) {
app.page('foo.bar', {content: '<%= name %>'});
var page = app.pages.getView('foo.bar');
app.render(page, function(err) {
assert(err.message === 'Templates#render cannot find an engine for: .bar');
done();
});
});
it('should use helpers to render a view:', function(done) {
var locals = {name: 'Halle'};
app.helper('upper', function(str) {
return str.toUpperCase(str);
});
app.page('a.tmpl', {content: 'a <%= upper(name) %> b', locals: locals});
var page = app.pages.getView('a.tmpl');
app.render(page, function(err, res) {
if (err) return done(err);
assert(res.contents.toString() === 'a HALLE b');
done();
});
});
it('should use helpers when rendering a view:', function(done) {
var locals = {name: 'Halle'};
app.helper('upper', function(str) {
return str.toUpperCase(str);
});
app.page('a.tmpl', {content: 'a <%= upper(name) %> b', locals: locals});
var page = app.pages.getView('a.tmpl');
app.render(page, function(err, res) {
if (err) return done(err);
assert(res.contents.toString() === 'a HALLE b');
done();
});
});
it('should render a template when contents is a buffer:', function(done) {
app.pages('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
var view = app.pages.getView('a.tmpl');
app.render(view, function(err, view) {
if (err) return done(err);
assert(view.contents.toString() === 'b');
done();
});
});
it('should render a template when content is a string:', function(done) {
app.pages('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
var view = app.pages.getView('a.tmpl');
app.render(view, function(err, view) {
if (err) return done(err);
assert(view.contents.toString() === 'b');
done();
});
});
});
});

View file

@ -1,135 +0,0 @@
'use strict';
var assemble = require('..');
var assert = require('assert');
var should = require('should');
var path = require('path');
var app;
describe('app.renderFile()', function() {
beforeEach(function() {
app = assemble();
app.engine('hbs', require('engine-handlebars'));
app.engine('*', require('engine-base'));
app.create('files', {engine: '*'});
app.file('a', {content: 'this is <%= title() %>'});
app.file('b', {content: 'this is <%= title() %>'});
app.file('c', {content: 'this is <%= title() %>'});
app.option('renameKey', function(key) {
return path.basename(key, path.extname(key));
});
app.helper('title', function() {
var view = this.context.view;
var key = view.key;
var ctx = this.context[key];
if (ctx && ctx.title) return ctx.title;
return key;
});
});
it('should render views from src', function(done) {
var stream = app.src(path.join(__dirname, 'fixtures/pages/*.hbs'));
var files = [];
stream.pipe(app.renderFile())
.on('error', done)
.on('data', function(file) {
files.push(file);
})
.on('end', function() {
assert.equal(files[0].basename, 'a.hbs');
assert.equal(files[1].basename, 'b.hbs');
assert.equal(files[2].basename, 'c.hbs');
done();
});
});
it('should render views with the engine that matches the file extension', function(done) {
var stream = app.src(path.join(__dirname, 'fixtures/pages/*.hbs'));
var files = [];
stream.pipe(app.renderFile())
.on('error', done)
.on('data', function(file) {
files.push(file);
})
.on('end', function() {
assert(/<h1>a<\/h1>/.test(files[0].content));
assert(/<h1>b<\/h1>/.test(files[1].content));
assert(/<h1>c<\/h1>/.test(files[2].content));
done();
});
});
it('should render views from src with the engine passed on the opts', function(done) {
var stream = app.src(path.join(__dirname, 'fixtures/pages/*.hbs'));
var files = [];
stream.pipe(app.renderFile({engine: '*'}))
.on('error', done)
.on('data', function(file) {
files.push(file);
})
.on('end', function() {
assert(/<h2>a<\/h2>/.test(files[0].content));
assert(/<h2>b<\/h2>/.test(files[1].content));
assert(/<h2>c<\/h2>/.test(files[2].content));
done();
});
});
it('should use the context passed on the opts', function(done) {
var stream = app.src(path.join(__dirname, 'fixtures/pages/*.hbs'));
var files = [];
stream.pipe(app.renderFile({a: {title: 'foo'}}))
.on('error', done)
.on('data', function(file) {
files.push(file);
})
.on('end', function() {
assert(/<h1>foo<\/h1>/.test(files[0].content));
assert(/<h1>b<\/h1>/.test(files[1].content));
assert(/<h1>c<\/h1>/.test(files[2].content));
done();
});
});
it('should render the files in a collection', function(cb) {
var files = [];
app.toStream('files')
.pipe(app.renderFile())
.on('error', cb)
.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
files.push(file);
})
.on('end', function() {
assert(/this is a/.test(files[0].content));
assert(/this is b/.test(files[1].content));
assert(/this is c/.test(files[2].content));
assert.equal(files.length, 3);
cb();
});
});
it('should handle engine errors', function(cb) {
app.create('notdefined', {engine: '*'});
app.notdefined('foo', {content: '<%= bar %>'});
app.toStream('notdefined')
.pipe(app.renderFile())
.on('error', function(err) {
assert.equal(typeof err, 'object');
assert.equal(err.message, 'bar is not defined');
cb();
})
.on('end', function() {
cb(new Error('expected renderFile to handle the error.'));
});
});
});

View file

@ -1,93 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('routes', function() {
beforeEach(function() {
app = new App();
});
describe('routes', function() {
it('should create a route for the given path:', function(done) {
app = new App();
app.create('posts');
app.on('all', function(msg) {
assert(msg === 'done');
done();
});
app.route('blog/:title')
.all(function(view, next) {
app.emit('all', 'done');
next();
});
app.post('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
it('should emit events when a route method is called:', function(done) {
app = new App();
app.create('posts');
app.on('onLoad', function(view) {
assert(view.path === 'blog/foo.js');
done();
});
app.param('title', function(view, next, title) {
assert(title === 'foo.js');
next();
});
app.onLoad('blog/:title', function(view, next) {
assert(view.path === 'blog/foo.js');
next();
});
app.post('whatever', {path: 'blog/foo.js', content: 'bar baz'});
});
it('should emit errors', function(done) {
app = new App();
app.create('posts');
app.on('error', function(err) {
assert(err.message === 'false == true');
done();
});
// wrong...
app.param('title', function(view, next, title) {
assert(title === 'fo.js');
next();
});
app.onLoad('/blog/:title', function(view, next) {
assert(view.path === '/blog/foo.js');
next();
});
app.post('whatever', {path: '/blog/foo.js', content: 'bar baz'});
});
it('should have path property', function() {
var route = new app.Route('/blog/:year/:month/:day/:slug').all([
function() {}
]);
route.path.should.equal('/blog/:year/:month/:day/:slug');
});
it('should have stack property', function() {
var route = new app.Route('/blog/:year/:month/:day/:slug').all([
function() {}
]);
route.stack.should.be.instanceof(Array);
route.stack.should.have.length(1);
});
});
});

View file

@ -1,295 +0,0 @@
'use strict';
var App = require('..');
var assert = require('assert');
var should = require('should');
var join = require('path').join;
var app;
describe('src()', function() {
beforeEach(function() {
app = new App();
});
it('should return a stream', function(done) {
var stream = app.src(join(__dirname, './fixtures/*.coffee'));
assert(stream);
assert.equal(typeof stream.on, 'function');
assert.equal(typeof stream.pipe, 'function');
done();
});
it('should return an input stream from a flat glob', function(done) {
var stream = app.src(join(__dirname, './fixtures/*.coffee'));
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee'));
String(file.contents).should.equal('Hello world!');
});
stream.on('end', function() {
done();
});
});
it('should return an input stream for multiple globs', function(done) {
var globArray = [
join(__dirname, './fixtures/generic/run.dmc'),
join(__dirname, './fixtures/generic/test.dmc')
];
var stream = app.src(globArray);
var files = [];
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
files.push(file);
});
stream.on('end', function() {
files.length.should.equal(2);
files[0].path.should.equal(globArray[0]);
files[1].path.should.equal(globArray[1]);
done();
});
});
it('should return an input stream for multiple globs with negation', function(done) {
var expectedPath = join(__dirname, './fixtures/generic/run.dmc');
var globArray = [
join(__dirname, './fixtures/generic/*.dmc'),
'!' + join(__dirname, './fixtures/generic/test.dmc'),
];
var stream = app.src(globArray);
var files = [];
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
files.push(file);
});
stream.on('end', function() {
files.length.should.equal(1);
files[0].path.should.equal(expectedPath);
done();
});
});
it('should return an input stream with no contents when read is false', function(done) {
var stream = app.src(join(__dirname, './fixtures/*.coffee'), {read: false});
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.not.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee'));
});
stream.on('end', function() {
done();
});
});
it('should return an input stream with contents as stream when buffer is false', function(done) {
var stream = app.src(join(__dirname, './fixtures/*.coffee'), {buffer: false});
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
var buf = '';
file.contents.on('data', function(d) {
buf += d;
});
file.contents.on('end', function() {
buf.should.equal('Hello world!');
done();
});
join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee'));
});
});
it('should return an input stream from a deep glob', function(done) {
var stream = app.src(join(__dirname, './fixtures/**/*.jade'));
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test/run.jade'));
String(file.contents).should.equal('test template');
});
stream.on('end', function() {
done();
});
});
it('should return an input stream from a deeper glob', function(done) {
var stream = app.src(join(__dirname, './fixtures/**/*.dmc'));
var a = 0;
stream.on('error', done);
stream.on('data', function() {
++a;
});
stream.on('end', function() {
a.should.equal(2);
done();
});
});
it('should return a file stream from a flat path', function(done) {
var a = 0;
var stream = app.src(join(__dirname, './fixtures/test.coffee'));
stream.on('error', done);
stream.on('data', function(file) {
++a;
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee'));
String(file.contents).should.equal('Hello world!');
});
stream.on('end', function() {
a.should.equal(1);
done();
});
});
it('should return a stream', function(done) {
var stream = app.src(join(__dirname, './fixtures/*.coffee'));
should.exist(stream);
should.exist(stream.on);
done();
});
it('should return an input stream from a flat glob', function(done) {
var stream = app.src(join(__dirname, './fixtures/*.coffee'));
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee'));
String(file.contents).should.equal('Hello world!');
});
stream.on('end', function() {
done();
});
});
it('should return an input stream for multiple globs', function(done) {
var globArray = [
join(__dirname, './fixtures/generic/run.dmc'),
join(__dirname, './fixtures/generic/test.dmc')
];
var stream = app.src(globArray);
var files = [];
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
files.push(file);
});
stream.on('end', function() {
files.length.should.equal(2);
files[0].path.should.equal(globArray[0]);
files[1].path.should.equal(globArray[1]);
done();
});
});
it('should return an input stream for multiple globs, with negation', function(done) {
var expectedPath = join(__dirname, './fixtures/generic/run.dmc');
var globArray = [
join(__dirname, './fixtures/generic/*.dmc'),
'!' + join(__dirname, './fixtures/generic/test.dmc'),
];
var stream = app.src(globArray);
var files = [];
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
files.push(file);
});
stream.on('end', function() {
files.length.should.equal(1);
files[0].path.should.equal(expectedPath);
done();
});
});
it('should return an input stream with no contents when read is false', function(done) {
var stream = app.src(join(__dirname, './fixtures/*.coffee'), {read: false});
stream.on('error', done);
stream.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.not.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee'));
});
stream.on('end', function() {
done();
});
});
it.skip('should throw an error when buffer is false', function(done) {
app.src(join(__dirname, './fixtures/*.coffee'), {buffer: false})
.on('error', function() {
done();
})
.on('data', function() {
done(new Error('should have thrown an error'));
});
});
it('should return an input stream from a deep glob', function(done) {
app.src(join(__dirname, './fixtures/**/*.jade'))
.on('error', done)
.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test/run.jade'));
String(file.contents).should.equal('test template');
})
.on('end', function() {
done();
});
});
it('should return an input stream from a deeper glob', function(done) {
var stream = app.src(join(__dirname, './fixtures/**/*.dmc'));
var a = 0;
stream.on('error', done);
stream.on('data', function() {
++a;
});
stream.on('end', function() {
a.should.equal(2);
done();
});
});
it('should return a file stream from a flat path', function(done) {
var a = 0;
var stream = app.src(join(__dirname, './fixtures/test.coffee'));
stream.on('error', done);
stream.on('data', function(file) {
++a;
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee'));
String(file.contents).should.equal('Hello world!');
});
stream.on('end', function() {
a.should.equal(1);
done();
});
});
});

View file

@ -1,396 +0,0 @@
require('mocha');
var should = require('should');
var fs = require('graceful-fs');
var path = require('path');
var rimraf = require('rimraf');
var bufEqual = require('buffer-equal');
var through = require('through2');
var File = require('vinyl');
var assemble = require('..');
var spies = require('./support/spy');
var chmodSpy = spies.chmodSpy;
var statSpy = spies.statSpy;
var app, bufferStream;
var wipeOut = function(cb) {
rimraf(path.join(__dirname, './actual/'), cb);
spies.setError('false');
statSpy.reset();
chmodSpy.reset();
app = assemble();
};
var dataWrap = function(fn) {
return function(data, enc, cb) {
fn(data);
cb();
};
};
var realMode = function(n) {
return n & 07777;
};
describe('symlink stream', function() {
beforeEach(wipeOut);
afterEach(wipeOut);
it('should pass through writes with cwd', function(done) {
var inputPath = path.join(__dirname, './fixtures/test.coffee');
var expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
var onEnd = function(){
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
var stream = app.symlink('./actual/', {cwd: __dirname});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should pass through writes with default cwd', function(done) {
var inputPath = path.join(__dirname, './fixtures/test.coffee');
var expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
var onEnd = function(){
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
var stream = app.symlink(path.join(__dirname, './actual/'));
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should make link to the right folder with relative cwd', function(done) {
var inputPath = path.join(__dirname, './fixtures/test.coffee');
var inputBase = path.join(__dirname, './fixtures/');
var expectedPath = path.join(__dirname, './actual/test.coffee');
var expectedBase = path.join(__dirname, './actual');
var expectedContents = fs.readFileSync(inputPath);
var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents
});
var onEnd = function(){
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
var stream = app.symlink('./actual/', {cwd: path.relative(process.cwd(), __dirname)});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder with function and relative cwd', function(done) {
var inputPath = path.join(__dirname, './fixtures/test.coffee');
var inputBase = path.join(__dirname, './fixtures/');
var expectedPath = path.join(__dirname, './actual/test.coffee');
var expectedBase = path.join(__dirname, './actual');
var expectedContents = fs.readFileSync(inputPath);
var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents
});
var onEnd = function(){
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
var stream = app.symlink(function(file){
should.exist(file);
file.should.equal(expectedFile);
return './actual';
}, {cwd: path.relative(process.cwd(), __dirname)});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder', function(done) {
var inputPath = path.join(__dirname, './fixtures/test.coffee');
var inputBase = path.join(__dirname, './fixtures/');
var expectedPath = path.join(__dirname, './actual/test.coffee');
var expectedContents = fs.readFileSync(inputPath);
var expectedBase = path.join(__dirname, './actual');
var expectedMode = 0655;
var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: {
mode: expectedMode
}
});
var onEnd = function(){
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
var stream = app.symlink('./actual/', {cwd: __dirname});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write streaming files to the right folder', function(done) {
var inputPath = path.join(__dirname, './fixtures/test.coffee');
var inputBase = path.join(__dirname, './fixtures/');
var expectedPath = path.join(__dirname, './actual/test.coffee');
var expectedContents = fs.readFileSync(inputPath);
var expectedBase = path.join(__dirname, './actual');
var expectedMode = 0655;
var contentStream = through.obj();
var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: contentStream,
stat: {
mode: expectedMode
}
});
var onEnd = function(){
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
var stream = app.symlink('./actual/', {cwd: __dirname});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
setTimeout(function(){
contentStream.write(expectedContents);
contentStream.end();
}, 100);
stream.end();
});
it('should write directories to the right folder', function(done) {
var inputPath = path.join(__dirname, './fixtures/wow');
var inputBase = path.join(__dirname, './fixtures/');
var expectedPath = path.join(__dirname, './actual/wow');
var expectedBase = path.join(__dirname, './actual');
var expectedMode = 0655;
var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: null,
stat: {
isDirectory: function(){
return true;
},
mode: expectedMode
}
});
var onEnd = function(){
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.readlinkSync(expectedPath).should.equal(inputPath);
fs.lstatSync(expectedPath).isDirectory().should.equal(false);
fs.statSync(expectedPath).isDirectory().should.equal(true);
done();
};
var stream = app.symlink('./actual/', {cwd: __dirname});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should use different modes for files and directories', function(done) {
var inputBase = path.join(__dirname, './fixtures');
var inputPath = path.join(__dirname, './fixtures/wow/suchempty');
var expectedBase = path.join(__dirname, './actual/wow');
var expectedDirMode = 0755;
var expectedFileMode = 0655;
var firstFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
stat: fs.statSync(inputPath)
});
var onEnd = function(){
realMode(fs.lstatSync(expectedBase).mode).should.equal(expectedDirMode);
realMode(buffered[0].stat.mode).should.equal(expectedFileMode);
done();
};
var stream = app.symlink('./actual/', {
cwd: __dirname,
mode: expectedFileMode,
dirMode: expectedDirMode
});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(firstFile);
stream.end();
});
it('should change to the specified base', function(done) {
var inputBase = path.join(__dirname, './fixtures');
var inputPath = path.join(__dirname, './fixtures/wow/suchempty');
var firstFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
stat: fs.statSync(inputPath)
});
var onEnd = function(){
buffered[0].base.should.equal(inputBase);
done();
};
var stream = app.symlink('./actual/', {
cwd: __dirname,
base: inputBase
});
var buffered = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(firstFile);
stream.end();
});
it('should report IO errors', function(done) {
var inputPath = path.join(__dirname, './fixtures/test.coffee');
var inputBase = path.join(__dirname, './fixtures/');
var expectedContents = fs.readFileSync(inputPath);
var expectedBase = path.join(__dirname, './actual');
var expectedMode = 0722;
var expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: {
mode: expectedMode
}
});
fs.mkdirSync(expectedBase);
fs.chmodSync(expectedBase, 0);
var stream = app.symlink('./actual/', {cwd: __dirname});
stream.on('error', function(err) {
err.code.should.equal('EACCES');
done();
});
stream.write(expectedFile);
});
['end', 'finish'].forEach(function(eventName) {
it('should emit ' + eventName + ' event', function(done) {
var srcPath = path.join(__dirname, './fixtures/test.coffee');
var stream = app.symlink('./actual/', {cwd: __dirname});
stream.on(eventName, function() {
done();
});
var file = new File({
path: srcPath,
cwd: __dirname,
contents: new Buffer("1234567890")
});
stream.write(file);
stream.end();
});
});
});

View file

@ -1,159 +0,0 @@
'use strict';
var assert = require('assert');
var App = require('..');
var app;
describe('task()', function() {
beforeEach(function() {
app = new App();
app.tasks = {};
});
it('should register a task', function() {
var fn = function(done) {
done();
};
app.task('default', fn);
assert.equal(typeof app.tasks.default, 'object');
assert.equal(app.tasks.default.fn, fn);
});
it('should register a task with an array of dependencies', function() {
app.task('default', ['foo', 'bar'], function(done) {
done();
});
assert.equal(typeof app.tasks.default, 'object');
assert.deepEqual(app.tasks.default.deps, ['foo', 'bar']);
});
it('should register a task with a list of strings as dependencies', function() {
app.task('default', 'foo', 'bar', function(done) {
done();
});
assert.equal(typeof app.tasks.default, 'object');
assert.deepEqual(app.tasks.default.deps, ['foo', 'bar']);
});
it('should run a task', function(done) {
var count = 0;
app.task('default', function(cb) {
count++;
cb();
});
app.build('default', function(err) {
if (err) return done(err);
assert.equal(count, 1);
done();
});
});
it('should throw an error when a task with unregistered dependencies is run', function(done) {
var count = 0;
app.task('default', ['foo', 'bar'], function(cb) {
count++;
cb();
});
app.build('default', function(err) {
if (!err) return done(new Error('Expected an error to be thrown.'));
assert.equal(count, 0);
done();
});
});
it('should throw an error when `.build` is called without a callback function.', function() {
try {
app.build('default');
throw new Error('Expected an error to be thrown.');
} catch (err) {
}
});
it('should emit task events', function(done) {
var events = [];
app.on('task:starting', function(task) {
events.push('starting.' + task.name);
});
app.on('task:finished', function(task) {
events.push('finished.' + task.name);
});
app.on('task:error', function(err, task) {
events.push('error.' + task.name);
});
app.task('foo', function(cb) {
cb();
});
app.task('bar', ['foo'], function(cb) {
cb();
});
app.task('default', ['bar']);
app.build('default', function(err) {
if (err) return done(err);
assert.deepEqual(events, [
'starting.default',
'starting.bar',
'starting.foo',
'finished.foo',
'finished.bar',
'finished.default'
]);
done();
});
});
it('should emit an error event when an error is passed back in a task', function(done) {
app.on('error', function(err) {
assert(err);
assert.equal(err.message, 'This is an error');
});
app.task('default', function(cb) {
return cb(new Error('This is an error'));
});
app.build('default', function(err) {
if (err) return done();
done(new Error('Expected an error'));
});
});
it('should emit an error event when an error is thrown in a task', function(done) {
var errors = 0;
app.on('error', function(err) {
errors++;
assert(err);
assert.equal(err.message, 'This is an error');
});
app.task('default', function(cb) {
cb(new Error('This is an error'));
});
app.build('default', function(err) {
assert.equal(errors, 1);
if (err) return done();
done(new Error('Expected an error'));
});
});
it('should run dependencies before running the dependent task.', function(done) {
var seq = [];
app.task('foo', function(cb) {
seq.push('foo');
cb();
});
app.task('bar', function(cb) {
seq.push('bar');
cb();
});
app.task('default', ['foo', 'bar'], function(cb) {
seq.push('default');
cb();
});
app.build('default', function(err) {
if (err) return done(err);
assert.deepEqual(seq, ['foo', 'bar', 'default']);
done();
});
});
});

View file

@ -1,64 +0,0 @@
'use strict';
var assemble = require('..');
var assert = require('assert');
var should = require('should');
var app;
describe('toStream()', function() {
beforeEach(function() {
app = assemble();
app.create('pages');
app.page('a', {content: 'this is A'});
app.page('b', {content: 'this is B'});
app.page('c', {content: 'this is C'});
app.create('posts');
app.post('x', {content: 'this is X'});
app.post('y', {content: 'this is Y'});
app.post('z', {content: 'this is Z'});
});
it('should return a stream', function(cb) {
var stream = app.toStream();
should.exist(stream);
should.exist(stream.on);
cb();
});
it('should return a stream for a collection', function(cb) {
var stream = app.toStream('pages');
should.exist(stream);
should.exist(stream.on);
cb();
});
it('should stack handle multiple collections', function(cb) {
var files = [];
app.toStream('pages')
.pipe(app.toStream('posts'))
.on('data', function(file) {
files.push(file);
})
.on('end', function() {
assert.equal(files.length, 6);
cb();
});
});
it('should push each item in the collection into the stream', function(cb) {
var files = [];
app.toStream('pages')
.on('error', cb)
.on('data', function(file) {
should.exist(file);
should.exist(file.path);
should.exist(file.contents);
files.push(file.path);
})
.on('end', function() {
assert.equal(files.length, 3);
cb();
});
});
});

View file

@ -1,281 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var Views = App.Views;
var View = App.View;
var app;
describe('app.use', function() {
beforeEach(function() {
app = new App();
});
it('should expose the instance to `use`:', function(done) {
app.use(function(inst) {
assert(inst instanceof App);
done();
});
});
it('should be chainable:', function(done) {
app.use(function(inst) {
assert(inst instanceof App);
})
.use(function(inst) {
assert(inst instanceof App);
})
.use(function(inst) {
assert(inst instanceof App);
done();
});
});
it('should pass to collection `use` if a function is returned:', function() {
app.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
collection.foo = collection.addView;
assert(collection instanceof Views);
return collection;
};
});
app.create('pages')
.foo({path: 'a.md', content: '...'})
.addView({path: 'b.md', content: '...'})
.addView({path: 'c.md', content: '...'});
assert(app.views.pages.hasOwnProperty('a.md'));
assert(app.views.pages.hasOwnProperty('b.md'));
assert(app.views.pages.hasOwnProperty('c.md'));
});
it('should be chainable when a collection function is returned:', function() {
app
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
collection.foo = collection.addView;
assert(collection instanceof Views);
return collection;
};
})
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
collection.bar = collection.addView;
assert(collection instanceof Views);
return collection;
};
})
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
collection.baz = collection.addView;
assert(collection instanceof Views);
return collection;
};
});
var pages = app.create('pages');
pages.foo({path: 'a.md', content: '...'});
pages.bar({path: 'b.md', content: '...'});
pages.baz({path: 'c.md', content: '...'});
assert(app.views.pages.hasOwnProperty('a.md'));
assert(app.views.pages.hasOwnProperty('b.md'));
assert(app.views.pages.hasOwnProperty('c.md'));
});
it('should pass to view `use` if collection.use returns a function:', function() {
app.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
assert(collection instanceof Views);
collection.foo = collection.addView;
return function(view) {
assert(view instanceof View);
view.foo = collection.addView.bind(collection);
return view;
};
};
});
app.create('pages')
.foo({path: 'a.md', content: '...'})
.foo({path: 'b.md', content: '...'})
.foo({path: 'c.md', content: '...'});
assert(app.views.pages.hasOwnProperty('a.md'));
assert(app.views.pages.hasOwnProperty('b.md'));
assert(app.views.pages.hasOwnProperty('c.md'));
});
it('should be chainable when a view function is returned:', function() {
app
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
assert(collection instanceof Views);
collection.foo = collection.addView;
return function(view) {
assert(view instanceof View);
view.a = collection.addView.bind(collection);
return view;
};
};
})
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
assert(collection instanceof Views);
collection.bar = collection.addView;
return function(view) {
assert(view instanceof View);
view.b = collection.addView.bind(collection);
return view;
};
};
})
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
assert(collection instanceof Views);
collection.baz = collection.addView;
return function(view) {
assert(view instanceof View);
view.c = collection.addView.bind(collection);
return view;
};
};
});
var pages = app.create('pages');
pages.foo({path: 'a.md', content: '...'});
pages.bar({path: 'b.md', content: '...'});
pages.baz({path: 'c.md', content: '...'})
.a({path: 'x.md', content: '...'})
.b({path: 'y.md', content: '...'})
.c({path: 'z.md', content: '...'});
assert(app.views.pages.hasOwnProperty('a.md'));
assert(app.views.pages.hasOwnProperty('b.md'));
assert(app.views.pages.hasOwnProperty('c.md'));
assert(app.views.pages.hasOwnProperty('x.md'));
assert(app.views.pages.hasOwnProperty('y.md'));
assert(app.views.pages.hasOwnProperty('z.md'));
});
it('should work with multiple collections:', function() {
app
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
assert(collection instanceof Views);
collection.foo = collection.addView;
return function(view) {
assert(view instanceof View);
view.a = collection.addView.bind(collection);
return view;
};
};
})
.use(function(inst) {
assert(inst instanceof App);
return function(collection) {
assert(collection instanceof Views);
collection.bar = collection.addView;
return function(view) {
assert(view instanceof View);
view.b = collection.addView.bind(collection);
return view;
};
};
})
.use(function(inst) {
assert(inst instanceof App);
assert(this instanceof App);
return function(collection) {
collection.baz = collection.addView;
assert(collection instanceof Views);
assert(this instanceof Views);
return function(view) {
assert(this instanceof View);
assert(view instanceof View);
view.c = collection.addView.bind(collection);
return view;
};
};
});
var pages = app.create('pages');
pages.foo({path: 'a.md', content: '...'});
pages.bar({path: 'b.md', content: '...'});
pages.baz({path: 'c.md', content: '...'})
.a({path: 'x.md', content: '...'})
.b({path: 'y.md', content: '...'})
.c({path: 'z.md', content: '...'});
assert(app.views.pages.hasOwnProperty('a.md'));
assert(app.views.pages.hasOwnProperty('b.md'));
assert(app.views.pages.hasOwnProperty('c.md'));
assert(app.views.pages.hasOwnProperty('x.md'));
assert(app.views.pages.hasOwnProperty('y.md'));
assert(app.views.pages.hasOwnProperty('z.md'));
var posts = app.create('posts');
posts.foo({path: 'a.md', content: '...'});
posts.bar({path: 'b.md', content: '...'});
posts.baz({path: 'c.md', content: '...'})
.a({path: 'x.md', content: '...'})
.b({path: 'y.md', content: '...'})
.c({path: 'z.md', content: '...'});
assert(app.views.posts.hasOwnProperty('a.md'));
assert(app.views.posts.hasOwnProperty('b.md'));
assert(app.views.posts.hasOwnProperty('c.md'));
assert(app.views.posts.hasOwnProperty('x.md'));
assert(app.views.posts.hasOwnProperty('y.md'));
assert(app.views.posts.hasOwnProperty('z.md'));
var docs = app.create('docs');
docs.foo({path: 'a.md', content: '...'});
docs.bar({path: 'b.md', content: '...'});
docs.baz({path: 'c.md', content: '...'})
.a({path: 'x.md', content: '...'})
.b({path: 'y.md', content: '...'})
.c({path: 'z.md', content: '...'});
assert(app.views.docs.hasOwnProperty('a.md'));
assert(app.views.docs.hasOwnProperty('b.md'));
assert(app.views.docs.hasOwnProperty('c.md'));
assert(app.views.docs.hasOwnProperty('x.md'));
assert(app.views.docs.hasOwnProperty('y.md'));
assert(app.views.docs.hasOwnProperty('z.md'));
});
});

View file

@ -1,38 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('app.view.compile', function() {
describe('compile method', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('page');
});
it('should compile a view:', function() {
var buffer = new Buffer('a b c');
var view = app.page('a.tmpl', {contents: buffer})
.compile();
assert(typeof view.fn === 'function');
});
it('should compile a view with settings:', function() {
var buffer = new Buffer('a b c');
var view = app.page('a.tmpl', {contents: buffer})
.compile({foo: 'bar'});
assert(typeof view.fn === 'function');
});
it('should compile a view with isAsync flag:', function() {
var buffer = new Buffer('a b c');
var view = app.page('a.tmpl', {contents: buffer})
.compile(true);
assert(typeof view.fn === 'function');
});
});
});

View file

@ -1,92 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('helpers', function() {
describe('rendering', function() {
beforeEach(function() {
app = new App();
app.engine('tmpl', require('engine-base'));
app.create('page');
});
it('should use helpers to render a view:', function(done) {
var locals = {name: 'Halle'};
app.helper('upper', function(str) {
return str.toUpperCase(str);
});
var buffer = new Buffer('a <%= upper(name) %> b');
app.page('a.tmpl', {contents: buffer, locals: locals})
.render(function(err, res) {
if (err) return done(err);
assert(res.contents.toString() === 'a HALLE b');
done();
});
});
it('should support helpers as an array:', function(done) {
var locals = {name: 'Halle'};
app.helpers([
{
lower: function(str) {
return str.toLowerCase(str);
}
}
]);
var buffer = new Buffer('a <%= lower(name) %> b');
app.page('a.tmpl', {contents: buffer, locals: locals})
.render(function(err, res) {
if (err) return done(err);
assert(res.contents.toString() === 'a halle b');
done();
});
});
it('should support helpers as an object:', function(done) {
var locals = {name: 'Halle'};
app.helpers({
prepend: function(prefix, str) {
return prefix + str;
}
});
var buffer = new Buffer('a <%= prepend("foo ", name) %> b');
app.page('a.tmpl', {contents: buffer, locals: locals})
.render(function(err, res) {
if (err) return done(err);
assert(res.contents.toString() === 'a foo Halle b');
done();
});
});
it('should use the engine defined on view options:', function(done) {
app.engine('hbs', require('engine-handlebars'));
var locals = {name: 'Halle'};
app.helpers({
prepend: function(prefix, str) {
return prefix + str;
}
});
var buffer = new Buffer('a {{prepend "foo " name}} b');
app.page('a.tmpl', {contents: buffer, locals: locals, options: {engine: 'hbs'}})
.render(function(err, res) {
if (err) return done(err);
assert(res.contents.toString() === 'a foo Halle b');
done();
});
});
});
});

View file

@ -1,42 +0,0 @@
'use strict';
var assert = require('assert');
var fs = require('fs');
var App = require('..');
var app;
describe.skip('watch()', function() {
beforeEach(function() {
app = new App({runtimes: false});
});
it('should watch files and run a task when files change', function(done) {
this.timeout(750);
var count = 0, watch;
app.task('default', function(cb) {
count++;
cb();
});
app.task('close', function(cb) {
watch.close();
app.emit('close');
cb();
});
app.task('watch', function(cb) {
watch = app.watch('test/fixtures/watch/*.txt', ['default', 'close']);
fs.writeFile('test/fixtures/watch/test.txt', 'test', function(err) {
if (err) return cb(err);
app.on('close', cb);
});
});
app.build(['watch'], function(err) {
if (err) return done(err);
assert.equal(count, 1);
done();
});
});
});

View file

@ -1,176 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var Views = App.Views;
var collection, pages;
describe('collection engines', function() {
beforeEach(function() {
pages = new Views();
});
it('should throw an error when engine name is invalid:', function() {
(function() {
pages.engine(null, {});
}).should.throw('expected engine ext to be a string or array.');
});
it('should register an engine to the given extension', function() {
pages.engine('hbs', function() {});
assert(typeof pages.engines['.hbs'] === 'object');
});
it('should set an engine with the given extension', function() {
var hbs = function() {};
hbs.render = function() {};
hbs.renderFile = function() {};
pages.engine('hbs', hbs);
assert(pages.engines['.hbs']);
assert(pages.engines['.hbs'].renderFile);
assert(pages.engines['.hbs'].render);
});
it('should get an engine:', function() {
pages.engine('hbs', function() {});
var hbs = pages.engine('hbs');
assert(typeof hbs === 'object');
assert(hbs.hasOwnProperty('render'));
assert(hbs.hasOwnProperty('compile'));
});
it('should register multiple engines to the given extension', function() {
pages.engine(['hbs', 'md'], function() {});
assert(typeof pages.engines['.hbs'] === 'object');
assert(typeof pages.engines['.md'] === 'object');
});
});
describe('engines', function() {
beforeEach(function() {
pages = new Views();
pages.addView('foo.tmpl', {content: 'A <%= letter %> {{= letter }} C'});
pages.addView('bar.tmpl', {content: 'A <%= letter %> {{ letter }} C'});
});
it('should register an engine:', function() {
pages.engine('a', {render: function() {}});
pages.engines.should.have.property('.a');
});
it('should use custom delimiters:', function(done) {
pages.engine('tmpl', require('engine-base'), {
delims: ['{{', '}}']
});
pages.render('foo.tmpl', {letter: 'B'}, function(err, res) {
if (err) return done(err);
res.content.should.equal('A <%= letter %> B C');
done();
});
});
it('should override individual delims values:', function(done) {
pages.engine('tmpl', require('engine-base'), {
interpolate: /\{{([^}]+)}}/g,
evaluate: /\{{([^}]+)}}/g,
escape: /\{{-([^}]+)}}/g
});
pages.render('bar.tmpl', {letter: 'B'}, function(err, res) {
if (err) return done(err);
res.content.should.equal('A <%= letter %> B C');
done();
});
});
it('should get an engine:', function() {
pages.engine('a', {
render: function() {}
});
var a = pages.engine('a');
a.should.have.property('render');
});
});
describe('engine selection:', function() {
beforeEach(function(done) {
collection = new Views();
collection.engine('tmpl', require('engine-base'));
collection.engine('hbs', require('engine-handlebars'));
done();
});
it('should get the engine from file extension:', function(done) {
var pages = new Views();
pages.engine('tmpl', require('engine-base'));
pages.engine('hbs', require('engine-handlebars'));
pages.addView('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}})
.render(function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
it('should use the engine defined on the collection:', function(done) {
var posts = new Views({engine: 'hbs'});
posts.engine('tmpl', require('engine-base'));
posts.engine('hbs', require('engine-handlebars'));
posts.addView('a', {content: '{{a}}', locals: {a: 'b'}})
.render(function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
it('should use the engine defined on the view:', function(done) {
var posts = new Views();
posts.engine('tmpl', require('engine-base'));
posts.engine('hbs', require('engine-handlebars'));
posts.addView('a', {content: '{{a}}', engine: 'hbs', locals: {a: 'b'}})
.render(function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
it('should use the engine defined on view.options:', function(done) {
var posts = new Views();
posts.engine('tmpl', require('engine-base'));
posts.engine('hbs', require('engine-handlebars'));
posts.addView('a', {content: '{{a}}', data: {a: 'b'}, options: {engine: 'hbs'}})
.render(function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
it('should use the engine defined on view.data:', function(done) {
var posts = new Views();
posts.engine('tmpl', require('engine-base'));
posts.engine('hbs', require('engine-handlebars'));
posts.addView('a', {content: '{{a}}', locals: {a: 'b'}, data: {engine: 'hbs'}})
.render(function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
it('should use the engine defined on render locals:', function(done) {
var posts = new Views();
posts.engine('tmpl', require('engine-base'));
posts.engine('hbs', require('engine-handlebars'));
posts.addView('a', {content: '{{a}}', locals: {a: 'b'}})
.render({engine: 'hbs'}, function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
});

View file

@ -1,27 +0,0 @@
require('should');
var support = require('./support');
var App = support.resolve();
var app;
describe('collection events', function() {
beforeEach(function() {
app = new App();
app.create('page');
});
it('should emit events:', function() {
app.pages('a.tmpl', {path: 'a.tmpl', content: '<%= a %>'});
var events = [];
app.pages.on('option', function(key) {
events.push(key);
});
app.pages.option('a', 'b');
app.pages.option('c', 'd');
app.pages.option('e', 'f');
app.pages.option({g: 'h'});
events.should.eql(['a', 'c', 'e', 'g']);
});
});

View file

@ -1,34 +0,0 @@
'use strict';
var path = require('path');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var app;
describe('collection.getView', function() {
beforeEach(function() {
app = new App();
app.create('page');
app.page('foo', {content: 'this is foo'});
app.page('bar.md', {content: 'this is bar'});
app.page('a/b/c/baz.md', {content: 'this is baz'});
app.page('test/fixtures/templates/a.tmpl');
});
it('should get a view by name', function() {
assert(app.pages.getView('foo'));
});
it('should get a view with the key modified by the given function', function() {
var view = app.pages.getView('foo.md', function(key) {
return path.basename(key, path.extname(key));
});
assert(view);
});
it('should get a view by full path', function() {
assert(app.pages.getView('a/b/c/baz.md'));
});
});

View file

@ -1,540 +0,0 @@
require('mocha');
require('should');
var path = require('path');
var assert = require('assert');
var typeOf = require('kind-of');
var isBuffer = require('is-buffer');
var support = require('./support');
var App = support.resolve();
var List = App.List;
var Item = App.Item;
var Collection = App.Collection;
var collection;
describe('collection', function() {
describe('constructor', function() {
it('should create an instance of Collection', function() {
var collection = new Collection();
assert(collection instanceof Collection);
assert(typeof collection === 'object');
});
it('should instantiate without new', function() {
var collection = Collection();
assert(collection instanceof Collection);
assert(typeof collection === 'object');
});
});
describe('static methods', function() {
it('should expose `extend`', function() {
assert(typeof Collection.extend === 'function');
});
});
describe('prototype methods', function() {
beforeEach(function() {
collection = new Collection();
});
var methods = [
'use',
'setItem',
'addItem',
'addItems',
'addList',
'getItem',
'constructor',
'set',
'get',
'del',
'define',
'visit',
'on',
'once',
'off',
'emit',
'listeners',
'hasListeners'
];
methods.forEach(function(method) {
it('should expose ' + method + ' method', function() {
assert(typeof collection[method] === 'function');
});
});
it('should expose isCollection property', function() {
assert(typeof collection.isCollection === 'boolean');
});
it('should expose queue property', function() {
assert(Array.isArray(collection.queue));
});
it('should expose items property', function() {
assert(typeOf(collection.items) === 'object');
});
it('should expose options property', function() {
assert(typeOf(collection.options) === 'object');
});
});
});
describe('methods', function() {
beforeEach(function() {
collection = new Collection();
});
describe('chaining', function() {
it('should allow collection methods to be chained', function() {
collection
.addItems({'a.hbs': {path: 'a.hbs'}})
.addItems({'b.hbs': {path: 'b.hbs'}})
.addItems({'c.hbs': {path: 'c.hbs'}});
collection.items.should.have.properties([
'a.hbs',
'b.hbs',
'c.hbs'
]);
});
});
describe('use', function() {
it('should expose the instance to plugins', function() {
collection
.use(function(inst) {
inst.foo = 'bar';
});
assert(collection.foo === 'bar');
});
it('should expose `item` when the plugin returns a function', function() {
collection
.use(function() {
return function(item) {
item.foo = 'bar';
};
});
collection.addItem('aaa');
collection.addItem('bbb');
collection.addItem('ccc');
assert(collection.items.aaa.foo === 'bar');
assert(collection.items.bbb.foo === 'bar');
assert(collection.items.ccc.foo === 'bar');
});
});
describe('get / set', function() {
it('should set a value on the instance', function() {
collection.set('a', 'b');
assert(collection.a === 'b');
});
it('should get a value from the instance', function() {
collection.set('a', 'b');
assert(collection.get('a') === 'b');
});
});
describe('adding items', function() {
beforeEach(function() {
collection = new Collection();
});
it('should load a item onto the respective collection', function() {
collection.addItem('a.hbs');
collection.items.should.have.property('a.hbs');
});
});
describe('item', function() {
beforeEach(function() {
collection = new Collection();
});
it('should return a single collection item from a key-value pair', function() {
var one = collection.item('one', {content: 'foo'});
var two = collection.item('two', {content: 'bar'});
assert(one instanceof Item);
assert(one instanceof collection.Item);
assert(one.path === 'one');
assert(two instanceof Item);
assert(two instanceof collection.Item);
assert(two.path === 'two');
});
it('should return a single collection item from an object', function() {
var one = collection.item({path: 'one', content: 'foo'});
var two = collection.item({path: 'two', content: 'bar'});
assert(one instanceof Item);
assert(one.path === 'one');
assert(two instanceof Item);
assert(two.path === 'two');
});
});
describe('addItem', function() {
beforeEach(function() {
collection = new Collection();
});
it('should throw an error when args are invalid', function() {
(function() {
collection.addItem(function() {});
}).should.throw('expected value to be an object.');
});
it('should add a item to `items`', function() {
collection.addItem('foo');
collection.items.should.have.property('foo');
collection.addItem('one', {content: '...'});
assert(typeof collection.items.one === 'object');
assert(isBuffer(collection.items.one.contents));
});
it('should create an instance of `Item`', function() {
collection.addItem('one', {content: '...'});
assert(collection.items.one instanceof collection.Item);
});
it('should allow an `Item` constructor to be passed', function() {
Item.prototype.foo = function(key, value) {
this[key] = value;
};
collection = new Collection({Item: Item});
collection.addItem('one', {content: '...'});
collection.items.one.foo('bar', 'baz');
assert(collection.items.one.bar === 'baz');
});
it('should allow an instance of `Item` to be passed', function() {
var collection = new Collection({Item: Item});
var item = new Item({content: '...'});
collection.addItem('one', item);
item.set('abc', 'xyz');
assert(collection.items.one instanceof collection.Item);
assert(isBuffer(collection.items.one.contents));
assert(collection.items.one.abc === 'xyz');
});
});
describe('addItems', function() {
beforeEach(function() {
collection = new Collection();
});
it('should add multiple items', function() {
collection.addItems({
one: {content: 'foo'},
two: {content: 'bar'}
});
assert(isBuffer(collection.items.one.contents));
assert(isBuffer(collection.items.two.contents));
});
it('should create items from an instance of Collection', function() {
collection.addItems({
one: {content: 'foo'},
two: {content: 'bar'}
});
var pages = new Collection(collection);
assert(isBuffer(pages.items.one.contents));
assert(isBuffer(pages.items.two.contents));
});
it('should add an array of plain-objects', function() {
collection.addItems([
{path: 'one', content: 'foo'},
{path: 'two', content: 'bar'}
]);
assert(isBuffer(collection.items.one.contents));
assert(isBuffer(collection.items.two.contents));
});
it('should add an array of items', function() {
var list = new List([
{path: 'one', content: 'foo'},
{path: 'two', content: 'bar'}
]);
collection.addItems(list.items);
assert(isBuffer(collection.items.one.contents));
assert(isBuffer(collection.items.two.contents));
});
});
describe('addList', function() {
beforeEach(function() {
collection = new Collection();
});
it('should add a list of items', function() {
collection.addList([
{path: 'one', content: 'foo'},
{path: 'two', content: 'bar'}
]);
assert(isBuffer(collection.items.one.contents));
assert(isBuffer(collection.items.two.contents));
});
it('should add a list of items from the constructor', function() {
var list = new List([
{path: 'one', content: 'foo'},
{path: 'two', content: 'bar'}
]);
collection = new Collection(list);
assert(isBuffer(collection.items.one.contents));
assert(isBuffer(collection.items.two.contents));
});
it('should throw an error when list is not an array', function() {
var items = new Collection();
(function() {
items.addList();
}).should.throw('expected list to be an array.');
(function() {
items.addList({});
}).should.throw('expected list to be an array.');
(function() {
items.addList('foo');
}).should.throw('expected list to be an array.');
});
it('should load an array of items from an event', function() {
var collection = new Collection();
collection.on('addList', function(list) {
while (list.length) {
collection.addItem({path: list.pop()});
}
});
collection.addList(['a.txt', 'b.txt', 'c.txt']);
assert(collection.items.hasOwnProperty('a.txt'));
assert(collection.items['a.txt'].path === 'a.txt');
});
it('should load an array of items from the addList callback:', function() {
var collection = new Collection();
collection.addList(['a.txt', 'b.txt', 'c.txt'], function(fp) {
return {path: fp};
});
assert(collection.items.hasOwnProperty('a.txt'));
assert(collection.items['a.txt'].path === 'a.txt');
});
it('should load an object of items from an event', function() {
var collection = new Collection();
collection.on('addItems', function(items) {
for (var key in items) {
collection.addItem('foo/' + key, items[key]);
delete items[key];
}
});
collection.addItems({
a: {path: 'a.txt'},
b: {path: 'b.txt'},
c: {path: 'c.txt'}
});
assert(collection.items.hasOwnProperty('foo/a'));
assert(collection.items['foo/a'].path === 'a.txt');
});
it('should signal `loaded` when finished (addItems)', function() {
var collection = new Collection();
collection.on('addItems', function(items) {
for (var key in items) {
if (key === 'c') {
collection.loaded = true;
break;
}
collection.addItem('foo/' + key, items[key]);
}
});
collection.addItems({
a: {path: 'a.txt'},
b: {path: 'b.txt'},
c: {path: 'c.txt'}
});
assert(collection.items.hasOwnProperty('foo/a'));
assert(!collection.items.hasOwnProperty('foo/c'));
assert(collection.items['foo/a'].path === 'a.txt');
});
it('should signal `loaded` when finished (addList)', function() {
var collection = new Collection();
collection.on('addList', function(items) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.key === 'c') {
collection.loaded = true;
break;
}
item.key = 'foo/' + item.key;
collection.addItem(item.key, item);
}
});
collection.addList([
{key: 'a', path: 'a.txt'},
{key: 'b', path: 'b.txt'},
{key: 'c', path: 'c.txt'}
]);
assert(collection.items.hasOwnProperty('foo/a'));
assert(collection.items['foo/a'].path === 'a.txt');
assert(!collection.items.hasOwnProperty('foo/c'));
});
});
describe('getItem', function() {
beforeEach(function() {
collection = new Collection();
});
it('should get a item from `items`', function() {
collection.addItem('one', {content: 'aaa'});
collection.addItem('two', {content: 'zzz'});
assert(isBuffer(collection.items.one.contents));
assert(isBuffer(collection.getItem('one').contents));
assert(collection.getItem('one').contents.toString() === 'aaa');
assert(collection.getItem('two').contents.toString() === 'zzz');
});
});
});
describe('queue', function() {
beforeEach(function() {
collection = new Collection();
});
it('should emit arguments on addItem', function(done) {
collection.on('addItem', function(args) {
assert(args[0] === 'a');
assert(args[1] === 'b');
assert(args[2] === 'c');
assert(args[3] === 'd');
assert(args[4] === 'e');
done();
});
collection.addItem('a', 'b', 'c', 'd', 'e');
});
it('should expose the `queue` property for loading items', function() {
collection.queue.push(collection.item('b', {path: 'b'}));
collection.addItem('a', {path: 'a'});
assert(collection.items.hasOwnProperty('a'));
assert(collection.items.hasOwnProperty('b'));
});
it('should load all items on the queue when addItem is called', function() {
collection.on('addItem', function(args) {
var len = args.length;
var last = args[len - 1];
if (typeof last === 'string') {
args[len - 1] = { content: last };
}
});
collection.addItem('a.html', 'aaa');
collection.addItem('b.html', 'bbb');
collection.addItem('c.html', 'ccc');
assert(collection.items.hasOwnProperty('a.html'));
assert(collection.getItem('a.html').content === 'aaa');
assert(collection.items.hasOwnProperty('b.html'));
assert(collection.getItem('b.html').content === 'bbb');
assert(collection.items.hasOwnProperty('c.html'));
assert(collection.getItem('c.html').content === 'ccc');
});
});
describe('options', function() {
describe('option', function() {
beforeEach(function() {
collection = new Collection();
});
it('should expose the `option` method', function() {
collection.option('foo', 'bar');
collection.options.should.have.property('foo', 'bar');
});
it('should be chainable', function() {
collection.option('foo', 'bar')
.addItems('a.hbs')
.addItems('b.hbs')
.addItems('c.hbs');
collection.options.should.have.property('foo', 'bar');
collection.items.should.have.properties([
'a.hbs',
'b.hbs',
'c.hbs'
]);
});
it('should set a key/value pair on options', function() {
collection.option('a', 'b');
assert(collection.options.a === 'b');
});
it('should set an object on options', function() {
collection.option({c: 'd'});
assert(collection.options.c === 'd');
});
it('should get an option', function() {
collection.option({c: 'd'});
var c = collection.option('c');
assert(c === 'd');
});
});
describe('options.renameKey', function() {
beforeEach(function() {
collection = new Collection({
renameKey: function(key) {
return path.basename(key);
}
});
});
it('should use a custom rename key function on item keys', function() {
collection.addItem('a/b/c/d.hbs', {content: 'foo bar baz'});
assert(collection.items['d.hbs'].contents.toString() === 'foo bar baz');
});
it('should get a item with the renamed key', function() {
collection.addItem('a/b/c/d.hbs', {content: 'foo bar baz'});
assert(collection.getItem('d.hbs').contents.toString() === 'foo bar baz');
});
it('should get a item with the original key', function() {
collection.addItem('a/b/c/d.hbs', {content: 'foo bar baz'});
assert(collection.getItem('a/b/c/d.hbs').contents.toString() === 'foo bar baz');
});
});
});

View file

@ -1,25 +0,0 @@
require('should');
var support = require('./support');
var App = support.resolve();
var app;
describe('collection.option()', function() {
beforeEach(function() {
app = new App();
app.create('page');
});
it('should set an option:', function() {
app.pages.options.should.not.have.property('foo');
app.pages.option('foo', 'bar');
app.pages.options.should.have.property('foo');
});
it('should extend options:', function() {
app.pages('a.tmpl', {path: 'a.tmpl', content: '<%= a %>'});
app.pages.option('a', 'b');
app.pages.option('c', 'd');
app.pages.option('e', 'f');
app.pages.options.should.have.properties(['a', 'c', 'e']);
});
});

View file

@ -1,138 +0,0 @@
require('mocha');
require('should');
var async = require('async');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var List = App.List;
var Views = App.Views;
var pages;
describe('render', function() {
describe('rendering', function() {
beforeEach(function() {
pages = new Views();
pages.engine('tmpl', require('engine-base'));
});
it('should throw an error when no callback is given:', function() {
(function() {
pages.render({});
}).should.throw('Views#render is async and expects a callback function');
});
it('should throw an error when an engine is not defined:', function(done) {
pages.addView('foo.bar', {content: '<%= name %>'});
var page = pages.getView('foo.bar');
pages.render(page, function(err) {
assert(err.message === 'Views#render cannot find an engine for: .bar');
done();
});
});
it('should use helpers to render a view:', function(done) {
var locals = {name: 'Halle'};
pages.helper('upper', function(str) {
return str.toUpperCase(str);
});
pages.addView('a.tmpl', {content: 'a <%= upper(name) %> b', locals: locals});
var page = pages.getView('a.tmpl');
pages.render(page, function(err, res) {
if (err) return done(err);
assert(res.content === 'a HALLE b');
done();
});
});
it('should use helpers when rendering a view:', function(done) {
var locals = {name: 'Halle'};
pages.helper('upper', function(str) {
return str.toUpperCase(str);
});
pages.addView('a.tmpl', {content: 'a <%= upper(name) %> b', locals: locals});
var page = pages.getView('a.tmpl');
pages.render(page, function(err, res) {
if (err) return done(err);
assert(res.content === 'a HALLE b');
done();
});
});
it('should render a template when contents is a buffer:', function(done) {
pages.addView('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
var view = pages.getView('a.tmpl');
pages.render(view, function(err, view) {
if (err) return done(err);
assert(view.contents.toString() === 'b');
done();
});
});
it('should render a template when content is a string:', function(done) {
pages.addView('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
var view = pages.getView('a.tmpl');
pages.render(view, function(err, view) {
if (err) return done(err);
assert(view.contents.toString() === 'b');
done();
});
});
it('should render a view from its path:', function(done) {
pages.addView('a.tmpl', {content: '<%= a %>', locals: {a: 'b'}});
pages.render('a.tmpl', function(err, view) {
if (err) return done(err);
assert(view.content === 'b');
done();
});
});
it('should use a plugin for rendering:', function(done) {
pages.engine('tmpl', require('engine-base'));
pages.option('engine', 'tmpl');
pages.addViews({
'a': {content: '<%= title %>', locals: {title: 'aaa'}},
'b': {content: '<%= title %>', locals: {title: 'bbb'}},
'c': {content: '<%= title %>', locals: {title: 'ccc'}},
'd': {content: '<%= title %>', locals: {title: 'ddd'}},
'e': {content: '<%= title %>', locals: {title: 'eee'}},
'f': {content: '<%= title %>', locals: {title: 'fff'}},
'g': {content: '<%= title %>', locals: {title: 'ggg'}},
'h': {content: '<%= title %>', locals: {title: 'hhh'}},
'i': {content: '<%= title %>', locals: {title: 'iii'}},
'j': {content: '<%= title %>', locals: {title: 'jjj'}}
});
pages.use(function(collection) {
collection.option('pager', false);
collection.renderEach = function(cb) {
var list = new List(collection);
async.map(list.items, function(item, next) {
collection.render(item, next);
}, cb);
};
});
pages.renderEach(function(err, items) {
if (err) return done(err);
assert(items[0].content === 'aaa');
assert(items[9].content === 'jjj');
assert(items.length === 10);
done();
});
});
});
});

View file

@ -1,156 +0,0 @@
require('mocha');
require('should');
var assert = require('assert');
var support = require('./support');
var App = support.resolve();
var Collection = App.Collection;
var Item = App.Item;
var collection;
describe('collection.use', function() {
beforeEach(function() {
collection = new Collection();
});
it('should expose the instance to `use`:', function(done) {
collection.use(function(inst) {
assert(inst instanceof Collection);
done();
});
});
it('should be chainable:', function(done) {
collection.use(function(inst) {
assert(inst instanceof Collection);
})
.use(function(inst) {
assert(inst instanceof Collection);
})
.use(function(inst) {
assert(inst instanceof Collection);
done();
});
});
it('should expose the collection to a plugin:', function() {
collection.use(function(items) {
assert(items instanceof Collection);
items.foo = items.addItem.bind(items);
});
collection.foo('a', {content: '...'});
assert(collection.items.hasOwnProperty('a'));
});
it('should expose collection when chained:', function() {
collection
.use(function(items) {
assert(items instanceof Collection);
items.foo = items.addItem.bind(items);
})
.use(function(items) {
assert(items instanceof Collection);
items.bar = items.addItem.bind(items);
})
.use(function(items) {
assert(items instanceof Collection);
items.baz = items.addItem.bind(items);
});
var pages = collection;
pages.foo({path: 'a', content: '...'});
pages.bar({path: 'b', content: '...'});
pages.baz({path: 'c', content: '...'});
assert(collection.items.hasOwnProperty('a'));
assert(collection.items.hasOwnProperty('b'));
assert(collection.items.hasOwnProperty('c'));
});
it('should work when a custom `Item` constructor is passed:', function() {
collection = new Collection({Item: require('vinyl')});
collection
.use(function(items) {
assert(items instanceof Collection);
items.foo = items.addItem.bind(items);
})
.use(function(items) {
assert(items instanceof Collection);
items.bar = items.addItem.bind(items);
})
.use(function(items) {
assert(items instanceof Collection);
items.baz = items.addItem.bind(items);
});
var pages = collection;
pages.foo({path: 'a', content: '...'});
pages.bar({path: 'b', content: '...'});
pages.baz({path: 'c', content: '...'});
assert(collection.items.hasOwnProperty('a'));
assert(collection.items.hasOwnProperty('b'));
assert(collection.items.hasOwnProperty('c'));
});
it('should pass to item `use` if a function is returned:', function() {
collection.use(function(items) {
assert(items instanceof Collection);
return function(item) {
item.foo = items.addItem.bind(items);
assert(item instanceof Item);
};
});
collection.addItem('a', {content: '...'})
.foo({path: 'b', content: '...'})
.foo({path: 'c', content: '...'})
.foo({path: 'd', content: '...'});
assert(collection.items.hasOwnProperty('a'));
assert(collection.items.hasOwnProperty('b'));
assert(collection.items.hasOwnProperty('c'));
assert(collection.items.hasOwnProperty('d'));
});
it('should be chainable when a item function is returned:', function() {
collection
.use(function(items) {
assert(items instanceof Collection);
return function(item) {
item.foo = items.addItem.bind(items);
assert(item instanceof Item);
};
})
.use(function(items) {
assert(items instanceof Collection);
return function(item) {
item.bar = items.addItem.bind(items);
assert(item instanceof Item);
};
})
.use(function(items) {
assert(items instanceof Collection);
return function(item) {
item.baz = items.addItem.bind(items);
assert(item instanceof Item);
};
});
collection.addItem('a', {content: '...'})
.foo({path: 'b', content: '...'})
.bar({path: 'c', content: '...'})
.baz({path: 'd', content: '...'});
assert(collection.items.hasOwnProperty('a'));
assert(collection.items.hasOwnProperty('b'));
assert(collection.items.hasOwnProperty('c'));
assert(collection.items.hasOwnProperty('d'));
});
});

Binary file not shown.

Binary file not shown.

View file

@ -1 +0,0 @@
This file is saved as UTF-8 with BOM. 𝌆

View file

@ -1 +0,0 @@
aaa

View file

@ -1 +0,0 @@
bbb

View file

@ -1 +0,0 @@
ccc

View file

@ -1 +0,0 @@
Hello world!

View file

@ -1,3 +0,0 @@
{
"one": {"a": "aaa"}
}

View file

@ -1,7 +0,0 @@
{
"success": {
"test": true,
"strong": "Heads up! This is a warning!",
"text": "You forgot a field!"
}
}

View file

@ -1,3 +0,0 @@
{
"two": {"b": "bbb"}
}

View file

@ -1,3 +0,0 @@
{
"three": {"c": "ccc"}
}

View file

@ -1,3 +0,0 @@
{
"root": "Whoa, I should be at the root!"
}

View file

@ -1,4 +0,0 @@
{
"alpha": "one",
"beta": "two"
}

View file

@ -1 +0,0 @@
this is a test

View file

@ -1,5 +0,0 @@
---
title: autodetect-no-lang
user: jonschlinkert
---
Content

View file

@ -1,5 +0,0 @@
---yaml
title: autodetect-yaml
user: jonschlinkert
---
Content

View file

@ -1,5 +0,0 @@
---
title: YAML
---
# This page has YAML front matter!

View file

@ -1 +0,0 @@
# run.dmc

View file

@ -1 +0,0 @@
# test.dmc

View file

@ -1,3 +0,0 @@
module.exports = function aaa() {
};

View file

@ -1,3 +0,0 @@
module.exports = function bbb() {
};

View file

@ -1,3 +0,0 @@
module.exports = function ccc() {
};

View file

@ -1,9 +0,0 @@
exports.one = function one() {
};
exports.two = function two() {
};
exports.three = function three() {
};

View file

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015, Jon Schlinkert.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,2 +0,0 @@
<h1>{{title}}</h1>
<h2><%= title() %></h2>

Some files were not shown because too many files have changed in this diff Show more