Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to execute a gulp plugin programatically (integration testing) #494

Closed
toranb opened this issue May 27, 2014 · 6 comments
Closed

How to execute a gulp plugin programatically (integration testing) #494

toranb opened this issue May 27, 2014 · 6 comments

Comments

@toranb
Copy link

toranb commented May 27, 2014

I have a simple function that does 3 things and then I return that fn and register a name w/ gulp so I can invoke it later.

module.exports = function(gulp, options) {
    var concat = require('gulp-concat');
    var react = require('gulp-react');

    gulp.task('foo', [], function(){
        return gulp.src("/**/*.jsx")
            .pipe(react())
            .pipe(concat('react.js'))
            .pipe(gulp.dest('./build'));
    });
};

On the surface this appears to return something that's streaming because when I print it from a test I get the usual writable/readable/end/destroy/pause/resume

I'm trying to test this by doing the following

describe("react task integration tests", function() {
    it("should transform jsx to vanilla javascript", function(done) {
        //this require will pull in the above module
        var react = require('../tasks/react')(gulp, options);
        var outstream = gulp.tasks.foo.fn();
        outstream.on('end', function() {
            //here I expect to see the content written but .. sadly no
            done();
        });
    });
});

But when I get into the stream.end I see the file is not written like I expect. If I do the following it does work. (notice I'm doing the entire thing by hand, and I'd much prefer to invoke the function you see above that does all the src/pipe/concat/react/dest work

describe("react task integration tests", function() {
    it("should transform jsx to vanilla javascript", function(done) {
            var react = require('gulp-react');
            var concat = require('gulp-concat');
            var instream = gulp.src(join(__dirname, "./src/react.jsx"));
            var outstream = instream.pipe(react());
            var outstream2 = outstream.pipe(concat('react.js'));
            var outstream3 = outstream2.pipe(gulp.dest('./test/tasks/build'));
            outstream3.on('end', function() {
                        //at this point when I read from the filesystem I have the output
                        done();
                    });
        });
});

Is it possible to test gulp functions that batch up a few operations into a single streamable like this? What am I doing wrong? Thanks for the help!

@sindresorhus
Copy link
Contributor

The contnet is written to disk by gulp.dest. You can get the contents in memory by listening to the data event and buffer it up until the end event or use something like concat-stream to do it for you.

@toranb
Copy link
Author

toranb commented May 27, 2014

Interestingly enough when I listen on data and do the close inside that callback (not doing the end at all) - I just timeout. Does this mean the on.data does not work as the stream would expect or is end something I must call to get this working?

@toranb
Copy link
Author

toranb commented May 28, 2014

One last question related this this (and a change that happened in gulp 3.5)

If i wanted to run a task manually before 3.5 I "could" do something like this

        gulp.run(['example']);

But if I run this today I get the deprecation warning below ...

gulp.run() has been deprecated. Use task dependencies or gulp.watch task triggering instead.

How should I "run" the example task from above using the latest gulp master?

**I assume when run is killed I won't be able to do this either?

        gulp.start.apply(gulp, ['example']);

@yocontra
Copy link
Member

@toranb

gulp.start('example');

@toranb
Copy link
Author

toranb commented May 31, 2014

I still plan to blog about this topic but for now the TL;DR

Say you wanted to test the react task using gulp. The trick is to register an example (fake) task that requires the task you want to get under test. Then using an async test framework like mocha or jasmine you kick off the fake / example task using grunt.start and throw the done() inside the example so you can assert any given output.

describe("react gulp tests", function() {
        it("react transforms any jsx to vanilla javascript", function(done) {
            var react = require('gulp-react');
            var concat = require('gulp-concat');
            gulp.task('foo', function(){
                return gulp.src(join(__dirname, "**/*.jsx"))
                    .pipe(react())
                    .pipe(concat('react.js'))
                    .pipe(gulp.dest('dist'));
            });
            gulp.task('example', ['foo'], function() {
                //now get your expected output and compare it ....
                //expect(resultingFile).to.equal(expectedFile);
                done();
            });
            gulp.start(['example']);
        });
    });

@deksden
Copy link

deksden commented Sep 14, 2016

@toranb : small correction for script.

In task declaration:

gulp.task('example', ['foo'], function()

its better to add parameter "done" (or it will be undefined):

gulp.task('example', ['foo'], function(done)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants