Как мне использовать глоток с лентой?

Я пытаюсь интегрировать Gulp с Tape ( https://github.com/substack/tape), тестовым жгутом NodeJ.

Как я могу это сделать? Там, кажется, не существует существующего плагина gulp.

Я видел это, но выглядит действительно не элегантно:

var shell = require('gulp-shell')

gulp.task('exec-tests', shell.task([
  'tape test/* | faucet',
]));

gulp.task('autotest', ['exec-tests'], function() {
  gulp.watch(['app/**/*.js', 'test/**/*.js'], ['exec-tests']);
});

Я пробовал это, похоже, это должно работать:

var tape = require('tape');
var spec = require('tap-spec');


gulp.task('test', function() {
    return gulp.src(paths.serverTests, {
            read: false
        })
        .pipe(tape.createStream())
        .pipe(spec())
        .pipe(process.stdout);
});

но я получаю TypeError: Invalid non-string/buffer chunk ошибка

6 ответов

Решение

Твой "не элегантный" ответ - самый лучший. Не все проблемы лучше всего решить с помощью потоков, и использование gulp просто как обертка не является грехом.

Правильно, ваша задача не будет работать, потому что потоки gulp основаны на виниле, виртуальной абстракции файла. Я не думаю, что есть хороший способ справиться с этим в gulp, похоже, что вы должны использовать API ленты напрямую. Я имею в виду, вы могли бы добавить немного сахарного напитка, если хотите:

var test = require('tape');
var spec = require('tap-spec');
var path = require('path');
var gulp = require('gulp');
var glob = require('glob');

gulp.task('default', function () {
    var stream = test.createStream()
        .pipe(spec())
        .pipe(process.stdout);

    glob.sync('path/to/tests/**/*.js').forEach(function (file) {
        require(path.resolve(file));
    });

    return stream;
});

Мне кажется, это немного грязно; не только потому, что мы не используем потоковую абстракцию gulp, но мы даже не ставим ее так, чтобы впоследствии она могла подключиться к конвейеру gulp. Кроме того, вы не можете получить сообщение о завершении задачи gulp при использовании этого кода. Если кто-нибудь знает способ обойти это, тогда, пожалуйста, будьте моим гостем.:-)

Я думаю, что я предпочел бы использовать ленту в командной строке. Но, если вы хотите, чтобы все ваши шаги шага сборки в вашем gulpfile, это может быть путь.

Просто используйте код ниже и gulp tdd и имея TDD:) с лентой

const tapNotify = require('tap-notify');
const colorize = require('tap-colorize');
const tape = require('gulp-tape');
const through = require('through2');
gulp.task('test',function(){
    process.stdout.write('\x1Bc');
    const reporter = through.obj();
    reporter.pipe(tapNotify({
        passed: {title: 'ok', wait:false},
        failed: {title: 'missing',wait:false}
    }));
    reporter
        .pipe(colorize())
        .pipe(process.stdout);
    return gulp.src('test/**/*.js')
        .pipe(tape({
            outputStream: through.obj(),
            reporter: reporter
        }));
});
gulp.task('tdd', function() {
    gulp.run('test');
    gulp.watch(['app/scripts/**/*.js*', 'test/**/*.js'],['test']);
});
// npm i --save-dev gulp-tape
// npm i --save-dev faucet (just an example of using a TAP reporter)

import gulp from 'gulp';
import tape from 'gulp-tape'; 
import faucet from 'faucet';

gulp.task('test:js', () => {
    return gulp.src('src/**/*test.js')
        .pipe(tape({
            reporter: faucet()
        }));
});

Вот пример моего решения:

var gulp = require('gulp');
var tape = require('tape');
var File = require('vinyl');
var through = require('through2');
var exec = (require('child_process')).execSync;

function execShell(shcmd, opts) {
    var out = '';
    try {
        out = exec(shcmd, opts);
    } catch (e) {
        if (e.error) throw e.error;
        if (e.stdout) out = e.stdout.toString();
    }
    return out;
};

gulp.task('testreport', function(){
    return gulp.src(
        'testing/specs/tape_unit.js', {read: false}
    ).pipe(
        through.obj(function(file, encoding, next) {
            try{
                // get tape's report
                var tapout = execShell(
                    "./node_modules/.bin/tape " + file.path
                );
                // show the report in a console with tap-spec
                execShell(
                    "./node_modules/.bin/tap-spec", { input: tapout, stdio: [null, 1, 2] }
                );
                // make a json report
                var jsonout = execShell(
                    "./node_modules/.bin/tap-json", { input: tapout }
                );
                // do something with report's object
                // or prepare it for something like Bamboo
                var report = JSON.parse(jsonout.toString());
                // continue the stream with the json report
                next(null, new File({
                    path: 'spec_report.json',
                    contents: new Buffer(JSON.stringify(report, null, 2))
                }));
            }catch(err){ next(err) }
        })
    ).pipe(
        gulp.dest('testing/reports')
    );
});

В выпуске GitHub для ленты jokeyrhyme упоминает, что задачи gulp могут быть Promises, и предлагает способ использовать это для выполнения тестов ленты. Основываясь на этом совете, я сделал это:

gulpfile.babel.js:

import glob from "glob";

gulp.task("test", () => {
    let module = process.argv[process.argv.length - 1];

    return new Promise(resolve => {
        // Crude test for 'gulp test' vs. 'gulp test --module mod'
        if (module !== "test") {
            require(`./js/tape/${module}.js`);
            resolve();
            return;
        }

        glob.sync("./js/tape/*.js").forEach(f => require(f)));
        resolve();
    });
});

Глядя на ответ Бена, я подозреваю, что то, что я сделал, не очень хорошо, хотя, с одной стороны, я заметил, что неудачные тесты не приводят к ненулевому коду выхода (хотя я не пробовал подход Бена для проверки будь то)

Другие вопросы по тегам