├── test
├── fixtures
│ ├── a.hbs
│ ├── b.hbs
│ └── c.hbs
└── test.js
├── .gitattributes
├── .travis.yml
├── .editorconfig
├── .gitignore
├── utils.js
├── .verb.md
├── LICENSE
├── package.json
├── .eslintrc.json
├── index.js
└── README.md
/test/fixtures/a.hbs:
--------------------------------------------------------------------------------
1 |
A
2 |
--------------------------------------------------------------------------------
/test/fixtures/b.hbs:
--------------------------------------------------------------------------------
1 | B
2 |
--------------------------------------------------------------------------------
/test/fixtures/c.hbs:
--------------------------------------------------------------------------------
1 | C
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Enforce Unix newlines
2 | * text eol=lf
3 |
4 | # binaries
5 | *.ai binary
6 | *.psd binary
7 | *.jpg binary
8 | *.gif binary
9 | *.png binary
10 | *.jpeg binary
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | os:
3 | - linux
4 | - osx
5 | language: node_js
6 | node_js:
7 | - node
8 | - '6'
9 | - '4'
10 | - '0.12'
11 | - '0.10'
12 | matrix:
13 | allow_failures:
14 | - node_js: '4'
15 | - node_js: '0.12'
16 | - node_js: '0.10'
17 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | end_of_line = lf
6 | charset = utf-8
7 | indent_size = 2
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [{**/{actual,fixtures,expected,templates}/**,*.md}]
12 | trim_trailing_whitespace = false
13 | insert_final_newline = false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # always ignore files
2 | *.DS_Store
3 | *.sublime-*
4 |
5 | # test related, or directories generated by tests
6 | test/actual
7 | actual
8 | coverage
9 | .nyc*
10 |
11 | # npm
12 | node_modules
13 | npm-debug.log
14 |
15 | # yarn
16 | yarn.lock
17 | yarn-error.log
18 |
19 | # misc
20 | _gh_pages
21 | _draft
22 | _drafts
23 | bower_components
24 | vendor
25 | temp
26 | tmp
27 | TODO.md
28 |
--------------------------------------------------------------------------------
/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('lazy-cache')(require);
4 | var fn = require;
5 | require = utils;
6 |
7 | /**
8 | * Lazily required module dependencies
9 | */
10 |
11 | require('assemble-handle', 'handle');
12 | require('define-property', 'define');
13 | require('is-valid-app', 'isValid');
14 | require('kind-of', 'typeOf');
15 | require('match-file', 'match');
16 | require('src-stream', 'src');
17 | require('through2', 'through');
18 | require = fn;
19 |
20 | /**
21 | * Expose `utils` modules
22 | */
23 |
24 | module.exports = utils;
25 |
--------------------------------------------------------------------------------
/.verb.md:
--------------------------------------------------------------------------------
1 | ## Usage
2 |
3 | This plugin can be used with [assemble][], [verb][] or any other application based on [templates][].
4 |
5 | ```js
6 | var assemble = require('assemble');
7 | var streams = require('{%= name %}');
8 |
9 | // create your application
10 | var app = assemble();
11 | // register the plugin
12 | app.use(stream());
13 |
14 | // use the plugin on app
15 | app.toStream('pages')
16 | .pipe(app.dest('site/'));
17 |
18 | // use the plugin on a collection
19 | app.pages.toStream()
20 | .pipe(app.dest('site/'));
21 |
22 | // use the plugin on a view
23 | app.pages.getView('home').toStream()
24 | .pipe(app.dest('site/'));
25 | ```
26 |
27 | See the [tests](./test.js) for more examples.
28 |
29 | ## API
30 | {%= apidocs("index.js") %}
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2017, Jon Schlinkert
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "assemble-streams",
3 | "description": "Assemble pipeline plugin for pushing views into a vinyl stream.",
4 | "version": "1.0.1",
5 | "homepage": "https://github.com/assemble/assemble-streams",
6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)",
7 | "repository": "assemble/assemble-streams",
8 | "bugs": {
9 | "url": "https://github.com/assemble/assemble-streams/issues"
10 | },
11 | "license": "MIT",
12 | "files": [
13 | "index.js",
14 | "utils.js"
15 | ],
16 | "main": "index.js",
17 | "engines": {
18 | "node": ">=0.10.0"
19 | },
20 | "scripts": {
21 | "test": "mocha"
22 | },
23 | "dependencies": {
24 | "assemble-handle": "^0.1.3",
25 | "define-property": "^0.2.5",
26 | "is-valid-app": "^0.2.1",
27 | "kind-of": "^3.1.0",
28 | "lazy-cache": "^2.0.2",
29 | "match-file": "^0.2.1",
30 | "src-stream": "^0.1.1",
31 | "through2": "^2.0.3"
32 | },
33 | "devDependencies": {
34 | "assemble-fs": "^1.0.0",
35 | "gulp-format-md": "^0.1.11",
36 | "mocha": "^3.2.0",
37 | "templates": "^1.2.6"
38 | },
39 | "keywords": [
40 | "assemble",
41 | "assembleplugin",
42 | "boilerplate",
43 | "build",
44 | "cli",
45 | "cli-app",
46 | "collection",
47 | "command-line",
48 | "create",
49 | "dev",
50 | "development",
51 | "framework",
52 | "front",
53 | "frontend",
54 | "plugin",
55 | "project",
56 | "projects",
57 | "scaffold",
58 | "scaffolder",
59 | "scaffolding",
60 | "source",
61 | "src",
62 | "stream",
63 | "streams",
64 | "template",
65 | "templates",
66 | "vinyl",
67 | "webapp",
68 | "yeoman",
69 | "yo"
70 | ],
71 | "verb": {
72 | "run": true,
73 | "toc": false,
74 | "layout": "default",
75 | "tasks": [
76 | "readme"
77 | ],
78 | "plugins": [
79 | "gulp-format-md"
80 | ],
81 | "related": {
82 | "list": [
83 | "assemble",
84 | "assemble-loader",
85 | "assemble-render-file"
86 | ]
87 | },
88 | "reflinks": [
89 | "assemble",
90 | "base",
91 | "generate",
92 | "templates",
93 | "update",
94 | "verb"
95 | ],
96 | "lint": {
97 | "reflinks": true
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "ecmaFeatures": {
3 | "modules": true,
4 | "experimentalObjectRestSpread": true
5 | },
6 |
7 | "env": {
8 | "browser": false,
9 | "es6": true,
10 | "node": true,
11 | "mocha": true
12 | },
13 |
14 | "globals": {
15 | "document": false,
16 | "navigator": false,
17 | "window": false
18 | },
19 |
20 | "rules": {
21 | "accessor-pairs": 2,
22 | "arrow-spacing": [2, { "before": true, "after": true }],
23 | "block-spacing": [2, "always"],
24 | "brace-style": [2, "1tbs", { "allowSingleLine": true }],
25 | "comma-dangle": [2, "never"],
26 | "comma-spacing": [2, { "before": false, "after": true }],
27 | "comma-style": [2, "last"],
28 | "constructor-super": 2,
29 | "curly": [2, "multi-line"],
30 | "dot-location": [2, "property"],
31 | "eol-last": 2,
32 | "eqeqeq": [2, "allow-null"],
33 | "generator-star-spacing": [2, { "before": true, "after": true }],
34 | "handle-callback-err": [2, "^(err|error)$" ],
35 | "indent": [2, 2, { "SwitchCase": 1 }],
36 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
37 | "keyword-spacing": [2, { "before": true, "after": true }],
38 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
39 | "new-parens": 2,
40 | "no-array-constructor": 2,
41 | "no-caller": 2,
42 | "no-class-assign": 2,
43 | "no-cond-assign": 2,
44 | "no-const-assign": 2,
45 | "no-control-regex": 2,
46 | "no-debugger": 2,
47 | "no-delete-var": 2,
48 | "no-dupe-args": 2,
49 | "no-dupe-class-members": 2,
50 | "no-dupe-keys": 2,
51 | "no-duplicate-case": 2,
52 | "no-empty-character-class": 2,
53 | "no-eval": 2,
54 | "no-ex-assign": 2,
55 | "no-extend-native": 2,
56 | "no-extra-bind": 2,
57 | "no-extra-boolean-cast": 2,
58 | "no-extra-parens": [2, "functions"],
59 | "no-fallthrough": 2,
60 | "no-floating-decimal": 2,
61 | "no-func-assign": 2,
62 | "no-implied-eval": 2,
63 | "no-inner-declarations": [2, "functions"],
64 | "no-invalid-regexp": 2,
65 | "no-irregular-whitespace": 2,
66 | "no-iterator": 2,
67 | "no-label-var": 2,
68 | "no-labels": 2,
69 | "no-lone-blocks": 2,
70 | "no-mixed-spaces-and-tabs": 2,
71 | "no-multi-spaces": 2,
72 | "no-multi-str": 2,
73 | "no-multiple-empty-lines": [2, { "max": 1 }],
74 | "no-native-reassign": 0,
75 | "no-negated-in-lhs": 2,
76 | "no-new": 2,
77 | "no-new-func": 2,
78 | "no-new-object": 2,
79 | "no-new-require": 2,
80 | "no-new-wrappers": 2,
81 | "no-obj-calls": 2,
82 | "no-octal": 2,
83 | "no-octal-escape": 2,
84 | "no-proto": 0,
85 | "no-redeclare": 2,
86 | "no-regex-spaces": 2,
87 | "no-return-assign": 2,
88 | "no-self-compare": 2,
89 | "no-sequences": 2,
90 | "no-shadow-restricted-names": 2,
91 | "no-spaced-func": 2,
92 | "no-sparse-arrays": 2,
93 | "no-this-before-super": 2,
94 | "no-throw-literal": 2,
95 | "no-trailing-spaces": 0,
96 | "no-undef": 2,
97 | "no-undef-init": 2,
98 | "no-unexpected-multiline": 2,
99 | "no-unneeded-ternary": [2, { "defaultAssignment": false }],
100 | "no-unreachable": 2,
101 | "no-unused-vars": [2, { "vars": "all", "args": "none" }],
102 | "no-useless-call": 0,
103 | "no-with": 2,
104 | "one-var": [0, { "initialized": "never" }],
105 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }],
106 | "padded-blocks": [0, "never"],
107 | "quotes": [2, "single", "avoid-escape"],
108 | "radix": 2,
109 | "semi": [2, "always"],
110 | "semi-spacing": [2, { "before": false, "after": true }],
111 | "space-before-blocks": [2, "always"],
112 | "space-before-function-paren": [2, "never"],
113 | "space-in-parens": [2, "never"],
114 | "space-infix-ops": 2,
115 | "space-unary-ops": [2, { "words": true, "nonwords": false }],
116 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
117 | "use-isnan": 2,
118 | "valid-typeof": 2,
119 | "wrap-iife": [2, "any"],
120 | "yoda": [2, "never"]
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * assemble-streams
3 | *
4 | * Copyright (c) 2015-2017, Jon Schlinkert.
5 | * Released under the MIT License.
6 | */
7 |
8 | 'use strict';
9 |
10 | var utils = require('./utils');
11 |
12 | module.exports = function(options) {
13 | return function plugin(app) {
14 | if (utils.isValid(app, 'assemble-streams')) {
15 | app.define('toStream', appStream(app));
16 | app.on('view', function(view) {
17 | viewPlugin.call(view, view);
18 | });
19 | return collectionPlugin;
20 | }
21 |
22 | function collectionPlugin(collection) {
23 | if (utils.isValid(collection, 'assemble-streams', ['collection'])) {
24 | collection.define('toStream', collectionStream(app, this));
25 | }
26 | return viewPlugin;
27 | }
28 |
29 | function viewPlugin(view) {
30 | if (utils.isValid(this, 'assemble-streams', ['item', 'file'])) {
31 | utils.define(this, 'toStream', viewStream(app));
32 | }
33 | }
34 | return plugin;
35 | };
36 | };
37 |
38 | /**
39 | * Push a view collection into a vinyl stream.
40 | *
41 | * ```js
42 | * app.toStream('posts', function(file) {
43 | * return file.path !== 'index.hbs';
44 | * })
45 | * ```
46 | * @name app.toStream
47 | * @param {String} `collection` Name of the collection to push into the stream.
48 | * @param {Function} Optionally pass a filter function to use for filtering views.
49 | * @return {Stream}
50 | * @api public
51 | */
52 |
53 | function appStream(app) {
54 | if (!hasHandler(app, 'onStream')) {
55 | app.handler('onStream');
56 | }
57 |
58 | return function(name, filterFn) {
59 | var stream = utils.through.obj();
60 | stream.setMaxListeners(0);
61 |
62 | if (typeof name === 'undefined') {
63 | process.nextTick(stream.end.bind(stream));
64 | return utils.src(stream);
65 | }
66 |
67 | var write = writeStream(stream);
68 | var collection = this[name];
69 | var views = collection && collection.views;
70 |
71 | if (!views && typeof name !== 'undefined') {
72 | filterFn = name;
73 | setImmediate(function() {
74 | Object.keys(this.views).forEach(function(key) {
75 | views = this.views[key];
76 | write(views, filterFn);
77 | }, this);
78 | stream.end();
79 | }.bind(this));
80 |
81 | return outStream(stream, this);
82 | }
83 |
84 | setImmediate(function() {
85 | write(views, filterFn);
86 | stream.end();
87 | });
88 |
89 | return outStream(stream, this);
90 | };
91 | }
92 |
93 | /**
94 | * Push a view collection into a vinyl stream.
95 | *
96 | * ```js
97 | * app.posts.toStream(function(file) {
98 | * return file.path !== 'index.hbs';
99 | * })
100 | * ```
101 |
102 | * @name collection.toStream
103 | * @param {Function} Optionally pass a filter function to use for filtering views.
104 | * @return {Stream}
105 | * @api public
106 | */
107 |
108 | function collectionStream(collection) {
109 | if (!hasHandler(collection, 'onStream')) {
110 | collection.handler('onStream');
111 | }
112 |
113 | return function(filterFn) {
114 | var stream = utils.through.obj();
115 | stream.setMaxListeners(0);
116 |
117 | var views = this.views;
118 | var write = writeStream(stream);
119 |
120 | setImmediate(function() {
121 | write(views, filterFn);
122 | stream.end();
123 | });
124 |
125 | return outStream(stream, collection);
126 | };
127 | }
128 |
129 | /**
130 | * Push the current view into a vinyl stream.
131 | *
132 | * ```js
133 | * app.pages.getView('a.html').toStream()
134 | * .on('data', function(file) {
135 | * console.log(file);
136 | * //=> >
137 | * });
138 | * ```
139 | *
140 | * @name view.toStream
141 | * @return {Stream}
142 | * @api public
143 | */
144 |
145 | function viewStream(view) {
146 | return function() {
147 | var stream = utils.through.obj();
148 | stream.setMaxListeners(0);
149 | setImmediate(function(item) {
150 | stream.write(item);
151 | stream.end();
152 | }, this);
153 | return outStream(stream, view);
154 | };
155 | }
156 |
157 | function writeStream(stream) {
158 | return function(views, filterFn) {
159 | for (var key in views) {
160 | if (filter(key, views[key], filterFn)) {
161 | stream.write(views[key]);
162 | }
163 | }
164 | };
165 | }
166 |
167 | function outStream(stream, instance) {
168 | return utils.src(stream.pipe(utils.handle.once(instance, 'onStream')));
169 | }
170 |
171 | function hasHandler(app, name) {
172 | return typeof app.handler === 'function' && typeof app[name] === 'function';
173 | }
174 |
175 | function filter(key, view, val) {
176 | switch (utils.typeOf(val)) {
177 | case 'array':
178 | var len = val.length;
179 | var idx = -1;
180 | while (++idx < len) {
181 | var name = val[idx];
182 | if (utils.match(name, view)) {
183 | return true;
184 | }
185 | }
186 | return false;
187 | case 'function':
188 | return val(key, view);
189 | case 'string':
190 | return utils.match(val, view);
191 | default: {
192 | return true;
193 | }
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # assemble-streams [](https://www.npmjs.com/package/assemble-streams) [](https://npmjs.org/package/assemble-streams) [](https://npmjs.org/package/assemble-streams) [](https://travis-ci.org/assemble/assemble-streams)
2 |
3 | > Assemble pipeline plugin for pushing views into a vinyl stream.
4 |
5 | ## Install
6 |
7 | Install with [npm](https://www.npmjs.com/):
8 |
9 | ```sh
10 | $ npm install --save assemble-streams
11 | ```
12 |
13 | ## Usage
14 |
15 | This plugin can be used with [assemble](https://github.com/assemble/assemble), [verb](https://github.com/verbose/verb) or any other application based on [templates](https://github.com/jonschlinkert/templates).
16 |
17 | ```js
18 | var assemble = require('assemble');
19 | var streams = require('assemble-streams');
20 |
21 | // create your application
22 | var app = assemble();
23 | // register the plugin
24 | app.use(streams());
25 |
26 | // use the plugin on app
27 | app.toStream('pages')
28 | .pipe(app.dest('site/'));
29 |
30 | // use the plugin on a collection
31 | app.pages.toStream()
32 | .pipe(app.dest('site/'));
33 |
34 | // use the plugin on a view
35 | app.pages.getView('home').toStream()
36 | .pipe(app.dest('site/'));
37 | ```
38 |
39 | See the [tests](./test/test.js) for more examples.
40 |
41 | ## API
42 |
43 | ### [app.toStream](index.js#L53)
44 |
45 | Push a view collection into a vinyl stream.
46 |
47 | **Params**
48 |
49 | * `collection` **{String}**: Name of the collection to push into the stream.
50 | * **{Function}**: Optionally pass a filter function to use for filtering views.
51 | * `returns` **{Stream}**
52 |
53 | **Example**
54 |
55 | ```js
56 | app.toStream('posts', function(file) {
57 | return file.path !== 'index.hbs';
58 | })
59 | ```
60 |
61 | ### [collection.toStream](index.js#L108)
62 |
63 | Push a view collection into a vinyl stream.
64 |
65 | **Params**
66 |
67 | * **{Function}**: Optionally pass a filter function to use for filtering views.
68 | * `returns` **{Stream}**
69 |
70 | **Example**
71 |
72 | ```js
73 | app.posts.toStream(function(file) {
74 | return file.path !== 'index.hbs';
75 | })
76 | ```
77 |
78 | ### [view.toStream](index.js#L145)
79 |
80 | Push the current view into a vinyl stream.
81 |
82 | * `returns` **{Stream}**
83 |
84 | **Example**
85 |
86 | ```js
87 | app.pages.getView('a.html').toStream()
88 | .on('data', function(file) {
89 | console.log(file);
90 | //=> >
91 | });
92 | ```
93 |
94 | ## About
95 |
96 | ### Related projects
97 |
98 | * [assemble-loader](https://www.npmjs.com/package/assemble-loader): Assemble plugin (^0.6.0) for loading globs of views onto custom view collections. Also works with… [more](https://github.com/assemble/assemble-loader) | [homepage](https://github.com/assemble/assemble-loader "Assemble plugin (^0.6.0) for loading globs of views onto custom view collections. Also works with verb or other Templates.js based applications.")
99 | * [assemble-render-file](https://www.npmjs.com/package/assemble-render-file): Assemble plugin for rendering views in a vinyl pipeline. | [homepage](https://github.com/assemble/assemble-render-file "Assemble plugin for rendering views in a vinyl pipeline.")
100 | * [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit")
101 |
102 | ### Contributing
103 |
104 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
105 |
106 | ### Contributors
107 |
108 | | **Commits** | **Contributor** |
109 | | --- | --- |
110 | | 34 | [jonschlinkert](https://github.com/jonschlinkert) |
111 | | 21 | [doowb](https://github.com/doowb) |
112 |
113 | ### Building docs
114 |
115 | _(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
116 |
117 | To generate the readme, run the following command:
118 |
119 | ```sh
120 | $ npm install -g verbose/verb#dev verb-generate-readme && verb
121 | ```
122 |
123 | ### Running tests
124 |
125 | Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
126 |
127 | ```sh
128 | $ npm install && npm test
129 | ```
130 |
131 | ### Author
132 |
133 | **Jon Schlinkert**
134 |
135 | * [github/jonschlinkert](https://github.com/jonschlinkert)
136 | * [twitter/jonschlinkert](https://twitter.com/jonschlinkert)
137 |
138 | ### License
139 |
140 | Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
141 | MIT
142 |
143 | ***
144 |
145 | _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.2, on February 11, 2017._
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('mocha');
4 | var path = require('path');
5 | var assert = require('assert');
6 | var templates = require('templates');
7 | var fs = require('assemble-fs');
8 | var streams = require('../');
9 | var app;
10 |
11 | describe('src()', function() {
12 | beforeEach(function() {
13 | app = templates();
14 | app.use(streams());
15 | app.use(fs());
16 |
17 | app.create('pages');
18 | app.create('posts');
19 |
20 | app.page('a.html', {content: '...'});
21 | app.page('b.html', {content: '...'});
22 | app.page('c.html', {content: '...'});
23 |
24 | app.post('x.html', {content: '...'});
25 | app.post('y.html', {content: '...'});
26 | app.post('z.html', {content: '...'});
27 | });
28 |
29 | it('should return add the `toStream` method to the instance', function(done) {
30 | assert(app.toStream);
31 | assert.equal(typeof app.toStream, 'function');
32 | done();
33 | });
34 |
35 | it('should return an input stream on a view collection', function(done) {
36 | var files = [];
37 | app.toStream('pages')
38 | .on('error', done)
39 | .on('data', function(file) {
40 | files.push(file.path);
41 | })
42 | .on('end', function() {
43 | assert.equal(files.length, 3);
44 | assert.equal(files[0], 'a.html');
45 | assert.equal(files[1], 'b.html');
46 | assert.equal(files[2], 'c.html');
47 | done();
48 | });
49 | });
50 |
51 | it('should stack multiple collections', function(done) {
52 | var files = [];
53 | app.toStream('pages')
54 | .pipe(app.toStream('posts'))
55 | .on('error', done)
56 | .on('data', function(file) {
57 | files.push(file.path);
58 | })
59 | .on('end', function() {
60 | assert.equal(files.length, 6);
61 | assert.equal(files[0], 'a.html');
62 | assert.equal(files[1], 'b.html');
63 | assert.equal(files[2], 'c.html');
64 |
65 | assert.equal(files[3], 'x.html');
66 | assert.equal(files[4], 'y.html');
67 | assert.equal(files[5], 'z.html');
68 | done();
69 | });
70 | });
71 |
72 | it('should work with `.src`', function(done) {
73 | var files = [];
74 | app.src(__dirname + '/fixtures/*.hbs')
75 | .pipe(app.toStream('posts'))
76 | .on('error', done)
77 | .on('data', function(file) {
78 | files.push(file.path);
79 | })
80 | .on('end', function() {
81 | assert.equal(files.length, 6);
82 | assert.equal(files[0], 'x.html');
83 | assert.equal(files[1], 'y.html');
84 | assert.equal(files[2], 'z.html');
85 |
86 | assert.equal(path.basename(files[3]), 'a.hbs');
87 | assert.equal(path.basename(files[4]), 'b.hbs');
88 | assert.equal(path.basename(files[5]), 'c.hbs');
89 | done();
90 | });
91 | });
92 |
93 | it('should emit `app.onStream` when using `app.toStream`', function(done) {
94 | var files = [];
95 | app.onStream(/\.html/, function(file, next) {
96 | files.push(file.path);
97 | next();
98 | });
99 |
100 | app.toStream('pages')
101 | .on('error', done)
102 | .on('data', function() {})
103 | .on('end', function() {
104 | assert.equal(files.length, 3);
105 | assert.equal(files[0], 'a.html');
106 | assert.equal(files[1], 'b.html');
107 | assert.equal(files[2], 'c.html');
108 | done();
109 | });
110 | });
111 |
112 | it('should emit `app.onStream` and `app.pages.onStream` when using `app.toStream`', function(done) {
113 | var files = [];
114 | var pages = [];
115 | app.onStream(/\.html/, function(file, next) {
116 | files.push(file.path);
117 | next();
118 | });
119 |
120 | app.pages.onStream(/\.html/, function(file, next) {
121 | pages.push(file.path);
122 | next();
123 | });
124 |
125 | app.toStream('pages')
126 | .on('error', done)
127 | .on('data', function() {})
128 | .on('end', function() {
129 | assert.equal(files.length, 3);
130 | assert.equal(files[0], 'a.html');
131 | assert.equal(files[1], 'b.html');
132 | assert.equal(files[2], 'c.html');
133 |
134 | assert.equal(pages.length, 3);
135 | assert.equal(pages[0], 'a.html');
136 | assert.equal(pages[1], 'b.html');
137 | assert.equal(pages[2], 'c.html');
138 | done();
139 | });
140 | });
141 |
142 | it('should emit `app.onStream` and `app.pages.onStream` when using `app.pages.toStream`', function(done) {
143 | var files = [];
144 | var pages = [];
145 | app.onStream(/\.html/, function(file, next) {
146 | files.push(file.path);
147 | next();
148 | });
149 |
150 | app.pages.onStream(/\.html/, function(file, next) {
151 | pages.push(file.path);
152 | next();
153 | });
154 |
155 | app.pages.toStream()
156 | .on('error', done)
157 | .on('data', function() {})
158 | .on('end', function() {
159 | assert.equal(files.length, 3);
160 | assert.equal(files[0], 'a.html');
161 | assert.equal(files[1], 'b.html');
162 | assert.equal(files[2], 'c.html');
163 |
164 | assert.equal(pages.length, 3);
165 | assert.equal(pages[0], 'a.html');
166 | assert.equal(pages[1], 'b.html');
167 | assert.equal(pages[2], 'c.html');
168 | done();
169 | });
170 | });
171 |
172 | it('should pipe a collection', function(done) {
173 | var files = [];
174 | app.pages.toStream()
175 | .on('error', done)
176 | .on('data', function(file) {
177 | files.push(file.path);
178 | })
179 | .on('end', function() {
180 | assert.equal(files.length, 3);
181 | assert.equal(files[0], 'a.html');
182 | assert.equal(files[1], 'b.html');
183 | assert.equal(files[2], 'c.html');
184 | done();
185 | });
186 | });
187 |
188 | it('should add `toStream` to a view that is not on a collection', function(done) {
189 | var files = [];
190 |
191 | var view = app.view('foo.bar', {content: 'this is foo'});
192 | view.toStream()
193 | .on('error', done)
194 | .on('data', function(view) {
195 | files.push(view);
196 | })
197 | .on('end', function() {
198 | assert.equal(files.length, 1);
199 | assert.equal(files[0].path, 'foo.bar');
200 | done();
201 | });
202 | });
203 |
204 | it('should emit `onStream` for a view that is not on a collection', function(done) {
205 | var files = [];
206 | app.onStream(/\.bar$/, function(file, next) {
207 | files.push(file);
208 | next();
209 | });
210 |
211 | var view = app.view('foo.bar', {content: 'this is foo'});
212 | view.toStream()
213 | .on('error', done)
214 | .on('data', function(view) {
215 | files.push(view);
216 | })
217 | .on('end', function() {
218 | assert.equal(files.length, 2);
219 | assert.equal(files[0].path, 'foo.bar');
220 | assert.equal(files[1].path, 'foo.bar');
221 | done();
222 | });
223 | });
224 |
225 | it('should emit `app.onStream` when using `app.pages.toStream`', function(done) {
226 | var files = [];
227 |
228 | app.onStream(/\.html$/, function(file, next) {
229 | files.push(file.path);
230 | next();
231 | });
232 |
233 | app.pages.toStream()
234 | .on('error', done)
235 | .on('data', function() {})
236 | .on('end', function() {
237 | assert.equal(files.length, 3);
238 | assert.equal(files[0], 'a.html');
239 | assert.equal(files[1], 'b.html');
240 | assert.equal(files[2], 'c.html');
241 | done();
242 | });
243 | });
244 |
245 | it('should pipe from one collection to another', function(done) {
246 | var files = [];
247 | app.pages.toStream()
248 | .pipe(app.toStream('posts'))
249 | .on('error', done)
250 | .on('data', function(file) {
251 | files.push(file.path);
252 | })
253 | .on('end', function() {
254 | assert.equal(files.length, 6);
255 | assert.equal(files[0], 'a.html');
256 | assert.equal(files[1], 'b.html');
257 | assert.equal(files[2], 'c.html');
258 |
259 | assert.equal(files[3], 'x.html');
260 | assert.equal(files[4], 'y.html');
261 | assert.equal(files[5], 'z.html');
262 | done();
263 | });
264 | });
265 |
266 | it('should support an optional filter function as the second argument', function(done) {
267 | var files = [];
268 | app.toStream('pages', function(key, view) {
269 | return key !== 'a.html';
270 | })
271 | .on('error', done)
272 | .on('data', function(file) {
273 | files.push(file.path);
274 | })
275 | .on('end', function() {
276 | assert.equal(files.length, 2);
277 | assert.equal(files[0], 'b.html');
278 | assert.equal(files[1], 'c.html');
279 | assert.equal(files.indexOf('a.html'), -1);
280 | done();
281 | });
282 | });
283 |
284 | it('should support an array as the second argument', function(done) {
285 | var files = [];
286 | app.toStream('pages', ['a.html', 'c.html'])
287 | .on('error', done)
288 | .on('data', function(file) {
289 | files.push(file.path);
290 | })
291 | .on('end', function() {
292 | assert.equal(files.length, 2);
293 | assert.equal(files[0], 'a.html');
294 | assert.equal(files[1], 'c.html');
295 | assert.equal(files.indexOf('b.html'), -1);
296 | done();
297 | });
298 | });
299 |
300 | it('should support a string as the second argument', function(done) {
301 | var files = [];
302 | app.toStream('pages', 'c.html')
303 | .on('error', done)
304 | .on('data', function(file) {
305 | files.push(file.path);
306 | })
307 | .on('end', function() {
308 | assert.equal(files.length, 1);
309 | assert.equal(files[0], 'c.html');
310 | assert.equal(files.indexOf('a.html'), -1);
311 | assert.equal(files.indexOf('b.html'), -1);
312 | done();
313 | });
314 | });
315 |
316 | it('should support matching a file path on any collection', function(done) {
317 | var files = [];
318 | app.toStream('c.html')
319 | .on('error', done)
320 | .on('data', function(file) {
321 | files.push(file.path);
322 | })
323 | .on('end', function() {
324 | assert.equal(files.length, 1);
325 | assert.equal(files[0], 'c.html');
326 | assert.equal(files.indexOf('a.html'), -1);
327 | assert.equal(files.indexOf('b.html'), -1);
328 | done();
329 | });
330 | });
331 |
332 | it('should support an array of files on any collection', function(done) {
333 | var files = [];
334 | app.toStream(['b.html', 'y.html'])
335 | .on('error', done)
336 | .on('data', function(file) {
337 | files.push(file.path);
338 | })
339 | .on('end', function() {
340 | assert.equal(files.length, 2);
341 | assert.equal(files[0], 'b.html');
342 | assert.equal(files[1], 'y.html');
343 | assert.equal(files.indexOf('a.html'), -1);
344 | assert.equal(files.indexOf('c.html'), -1);
345 | assert.equal(files.indexOf('x.html'), -1);
346 | assert.equal(files.indexOf('z.html'), -1);
347 | done();
348 | });
349 | });
350 |
351 | it('should pipe an individual view into a stream', function(done) {
352 | var files = [];
353 | app.pages.getView('b.html')
354 | .toStream()
355 | .on('error', done)
356 | .on('data', function(file) {
357 | files.push(file.path);
358 | })
359 | .on('end', function() {
360 | assert.equal(files.length, 1);
361 | assert.equal(files[0], 'b.html');
362 | assert.equal(files.indexOf('a.html'), -1);
363 | assert.equal(files.indexOf('c.html'), -1);
364 | assert.equal(files.indexOf('x.html'), -1);
365 | assert.equal(files.indexOf('y.html'), -1);
366 | assert.equal(files.indexOf('z.html'), -1);
367 | done();
368 | });
369 | });
370 |
371 | it('should pipe multiple individual views into a stream', function(done) {
372 | var files = [];
373 | app.pages.getView('b.html').toStream()
374 | .pipe(app.posts.getView('y.html').toStream())
375 | .on('error', done)
376 | .on('data', function(file) {
377 | files.push(file.path);
378 | })
379 | .on('end', function() {
380 | assert.equal(files.length, 2);
381 | assert.equal(files[0], 'b.html');
382 | assert.equal(files[1], 'y.html');
383 | assert.equal(files.indexOf('a.html'), -1);
384 | assert.equal(files.indexOf('c.html'), -1);
385 | assert.equal(files.indexOf('x.html'), -1);
386 | assert.equal(files.indexOf('z.html'), -1);
387 | done();
388 | });
389 | });
390 |
391 | it('should emit `app.onStream` when using `view.toStream`', function(done) {
392 | var files = [];
393 | app.onStream(/\.html/, function(file, next) {
394 | files.push(file.path);
395 | next();
396 | });
397 |
398 | app.pages.getView('b.html').toStream()
399 | .on('error', done)
400 | .on('data', function() {})
401 | .on('end', function() {
402 | assert.equal(files.length, 1);
403 | assert.equal(files[0], 'b.html');
404 | done();
405 | });
406 | });
407 | });
408 |
--------------------------------------------------------------------------------