GithubHelp home page GithubHelp logo

stream-adventure's Introduction

Workshopper

Join the chat at https://gitter.im/nodeschool/workshoppers

Workshopper is no longer maintained

In mid-term workshopper will be replaced with workshopper-adventure. Please try to build new workshoppers against workshopper-adventure. Thanks. (your maintainer)

Readme until now:

A terminal workshop runner framework

NPM NPM

Learn You The Node.js For Much Win!

Workshopper is used by learnyounode, and other Node.js command-line workshop applications.

*Documentation is being written for the v1 rewrite right now! Ping @rvagg if you need anything. learnyounode is now using this new version, for now you can use it to see how this works.

For now, @linclark has written a good introduction on creating your own workshop, available here.

High-level overview

Workshopper is essentially a test-runner with a fancy terminal UI. The Workshopper package itself is largely concerned with the menu system and some of the basic command-line parsing. Much of the work for executing the exercise validation is handled by workshopper-exercise.

Contributors

workshopper is proudly brought to you by the following hackers:

Maintainers

License

Workshopper is Copyright (c) 2013-2015 Rod Vagg @rvagg and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.

Workshopper builds on the excellent work by @substack and @maxogden who created stream-adventure which serves as the original foundation for Workshopper and learnyounode. Portions of Workshopper may also be Copyright (c) 2013 @substack and @maxogden given that it builds on their original code.

stream-adventure's People

Contributors

aks- avatar appajee avatar bengarnett avatar bidego avatar calvinmetcalf avatar ccarruitero avatar codelahoma avatar ehpc avatar finnp avatar gield avatar haio avatar jordansu avatar julianduque avatar kalinchernev avatar max-mapper avatar mbrehin avatar mcoquet avatar michaelficarra avatar mrxinu avatar nadgerz avatar pietrosld avatar ralphtheninja avatar robbiethegeek avatar sequoia avatar stcruy avatar thibaudcolas avatar thiruppathi avatar tioback avatar tklun avatar yihangho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stream-adventure's Issues

Issue in problems/duplexer/problem.txt

This says:

"The duplexer module exports a single function duplexer(writable, readable) that joins together a writable stream and readable stream into a single, readable/writable duplex stream."

... but it should be:

"...a single function duplexer(readable, writable) that joins ..."

You have the arguments flip-flopped.

Stream Adventure HTTP Server fails when I split out functions

Why does the following code pass:

var http = require('http')
    through = require('through');

var server = http.createServer(function(req, res){
    if(req.method === 'POST') {
        req.pipe(through(function(data){
            this.queue(data.toString().toUpperCase());
        })).pipe(res);
    }
}).listen(process.argv[2]);

but when I split out the pipe+through function:

var http = require('http')
    through = require('through');

var tr = through(write);

function write(buf) {
    this.queue(buf.toString().toUpperCase());
}

var server = http.createServer(function(req, res){
    if(req.method === 'POST') {
        req.pipe(tr).pipe(res);
    }
}).listen(process.argv[2]);

For some reason it fails the stream-adventure verify.
Any insight would be much appreciated.
Thanks

websockets: official solution broken in windows

When I run the official solution

var ws = require('websocket-stream');
var stream = ws('ws://localhost:8000');

stream.end("hello\n");

I get this:

PS C:\Users\Benni\Documents\nodejs\nodeschool\stream-adventure1> node .\09websockets.js

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: connect ECONNREFUSED
    at errnoException (net.js:904:11)
    at Object.afterConnect [as oncomplete] (net.js:895:19)

bug in HTML STREAM problem?

  1. Is there a bug in the HTML STREAM solution? I expect the result to be the span's content in caps

     <span class="loud">government love the people, beside the people,
      four of the people, shall not perish from this earth.</span>
    

    but the output i get with the below code is --is "html" the correct expected result?

    ACTUAL:   "GOVERNMENT LOVE THE PEOPLE, BESIDE THE PEOPLE,"
    EXPECTED: "<html>"
    
  2. It seems like trumpet is only grabbing the chunk up to the \n, should I be using concat-stream instead?

my code on node v0.10.12 on win8

    var through = require('through');
    var trumpet = require('trumpet');
    var fs = require('fs');
    var tr = trumpet();

    var th = through(write);
    function write (buf) {
         this.queue(buf.toString()).toUpperCase())
     }

    process.stdin.pipe(tr)
    tr.select('.loud').createStream().pipe(th).pipe(process.stdout);

Solution to `lines` is backwards

From the instructions:

[...]convert even-numbered lines to upper-case and odd-numbered
lines to lower-case. Consider the first line to be odd-numbered. [...]

Your program should output:

    one
    TWO
    three
    FOUR

From verify:

ACTUAL:   "RIVERRUN, PAST EVE AND ADAM'S, FROM SWERVE OF SHORE TO BEND "
EXPECTED: "RIVERRUN, PAST EVE AND ADAM'S, FROM SWERVE OF SHORE TO BEND "

ACTUAL:   "of bay, brings us by a commodius vicus of recirculation back to    "
EXPECTED: "of bay, brings us by a commodius vicus of recirculation back to    "

This can be fixed by initializing lineCount to 1 instead of 0.

'crypt' refers to a module, but solution requires that user *not* export a module

The problems immediately preceding it all involve exporting a module. This one takes a turn and returns to the earlier nodeschool pattern of being a simple script that operates directly on stdin and stdout.

It might be that the request to have the student hardcode those specific streams should be enough of a clue that we aren't building a commonjs module, but the instructions specifically say "module". For me, at least, this was totally confusing and I had to figure out the solution by cheating and looking it up even though the code at the crux of the exercise was all correct.

Solution to LINES expects newlines but doesn't say so

I'm not a newbie, and this was confusing for quite a while. I knew my solution was correct, and could not for the life of me figure out why it wasn't working. The only flaw was the missing + "\n". It seems worthwhile to explicitly mention this in the instructions as a hint.

I think it's more confusing because the example code doesn't show a newline, so I kept looking at that wondering why it wasn't working.

    var split = require('split');
    process.stdin
        .pipe(split())
        .pipe(through(function (line) {
            console.dir(line.toString());  // probably should add a + "\n" here to be helpful?
        }))
    ;

In hindsight, it should be obvious (because I've done streams a thousand times), but remembering those explicit details while learning new concepts from an "incorrect" example can be challenging!

Also this is so awesome.

The WEBSOCKETS test is not verifying anything

As per title, you can send back anything from the client, the test is not actually verifying it.

var ws = require('websocket-stream');
var stream = ws('ws://localhost:8000');

stream.end('HAHAHA\n');
ACTUAL                             EXPECTED
------                             --------
""                                 ""
# PASS

Your solution to WEBSOCKETS passed!

can't select the streams2 exercises

I have stream-adventure installed. But when I run the command and select any of the last ones that begin with 'streams2' I get an error:

  #####################################################################
  ##                   ~~  STREAMS2 TRANSFORM  ~~                    ##
  #####################################################################


events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: ENOENT, open '/usr/lib/node_modules/stream-adventure/problems/streams2_transform/problem.txt'

Upon failure, verification for HTTP SERVER leaves server port open

This causes attempts to test the code to invariably fail until the node process is killed with:

events.js:72
        throw er; // Unhandled error event
              ^
Error: listen EADDRINUSE
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1039:14)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.<anonymous> (/home/harrison/Projects/stream-adventure/server.js:10:8)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

For example, with an incorrect answer which does not close the result stream, or even a correct answer using 8000 instead of 8001 (see #22)

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: connect ECONNREFUSED
    at errnoException (net.js:901:11)
    at Object.afterConnect [as oncomplete] (net.js:892:19)

Afterward, lsof -Pnl +M -i4 produces this:

nodejs  19821     1000   10u  IPv4 2629533      0t0  TCP *:8000 (LISTEN)

TypeError: Object has no method 'tmpdir'

Doesn't work with node v0.8.23:

direvius@direvius-ub:~/learn/node-stream$ stream-adventure verify program.js 

/usr/lib/node_modules/stream-adventure/problems/meet_pipe/setup.js:7
    var file = path.resolve(os.tmpdir(), 'meet-pipe-data.txt');
                               ^
TypeError: Object #<Object> has no method 'tmpdir'
    at module.exports (/usr/lib/node_modules/stream-adventure/problems/meet_pipe/setup.js:7:32)
    at Object.<anonymous> (/usr/lib/node_modules/stream-adventure/bin/cmd.js:43:43)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:245:9)

Workaround: change os.tmpdir() to os.tmpDir() in /usr/lib/node_modules/stream-adventure/problems/meet_pipe/setup.js

Invalid Solution for CONCAT

The test for the CONCAT test is to pipe the reversed, concatenated stream to process.stdout, but in your provided solution you don't even do that. You log it to the console, which has the same net effect.

Granted, I'm new to the stream thing (obviously), and though I did learn a ton from this particular problem, I'm hung up on the fact that I can't get this to work. Maybe it's a matter of not knowing enough, or concat-stream lacking documentation (or features), but I'd love to see the true solution.

Exercise 7 passes without converting to upper case

Exercise 7 HTTP SERVER will pass without converting the text to upper case. Also the test data appears to be generated from the user's code (it was also lowercase).

var http = require('http');
var fs = require('fs');
var through = require('through');

var server = http.createServer(function(req,res){
    if(req.method === 'POST'){
        req.pipe(through(function(buf){ this.queue(buf); })).pipe(res);
    }
});

server.listen(process.argv[2]);

OUTPUT

ACTUAL EXPECTED


"with" "with"
"the" "the"
"original" "original"
"sinse" "sinse"
"we" "we"
"are" "are"
"only" "only"
"yearning" "yearning"
"as" "as"
"yet" "yet"
"how" "how"
"to" "to"
"burgeon." "burgeon."
"It's" "It's"
"meant" "meant"
"milliems" "milliems"
"of" "of"
"centiments" "centiments"
"deadlost" "deadlost"
"or" "or"
"" ""

PASS

Your solution to HTTP SERVER passed!

Here's what the official solution is if you want to compare notes:

var http = require('http');
var through = require('through');

var server = http.createServer(function (req, res) {
    if (req.method === 'POST') {
        req.pipe(through(function (buf) {
            this.queue(buf.toString().toUpperCase());
        })).pipe(res);
    }
    else res.end('send me a POST\n');
});
server.listen(parseInt(process.argv[2]));

You have 12 challenges left.
Type stream-adventure to show the menu.

Unhandled stream error in pipe from http server challenge

I'm getting the following error from both my attempt at and the solution to the HTTP SERVER challenge:

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: connect ECONNREFUSED
    at errnoException (net.js:901:11)
    at Object.afterConnect [as oncomplete] (net.js:892:19)

I'm running node 0.10.18, stream-adventure 1.1.1 on Windows 7 x64.

General Feedback about stream-adventure

My name is Eden, and I completed part of stream-adventure yesterday as a part of NodeSchool Berlin, which was taught by @balupton, @KenanSulayman and @timaschew. Thank you for your excellent guidance and instruction! I had a wonderful time, and NodeSchool is an excellent idea. Thank you @substack for writing this tutorial.

My programming background: I've been coding for about a year in Java/C#, and I'm currently completing a residency at Hacker Retreat. I have been learning JavaScript for ~1 month now using various resources (Eloquent JavaScript, doing katas, refactoring with Ben), and am still new to a lot of programming concepts (callbacks, piping, etc.). I had completed learnyounode prior to doing stream-adventure.

I struggled greatly with completing stream-adventure because I don't feel that a lot of concepts were thoroughly explained to me before I was asked to implement them for each exercise. I experienced this to a lesser degree in learnyounode as well. For example:

  • I didn't actually understand piping until Ben explained it to me as a stream that would get "drained" if I piped it elsewhere, so I can/need to pipe it back to the original stream after I have piped it through some sort of transform. This plumbing analogy helped GREATLY, and I would recommend having a clearer explaining of what piping is exactly during one of the earlier exercises, like Meet Pipe. At present, we are just told to start piping things, without an explanation of what piping is.
  • What is a duplexer? Anton explained a duplexer to me using the analogy of two walkie-talkies, where only one person can be speaking at a time, and the other person is listening. A duplexer is like two phones on a call, where both can speak at the same time. In Duplexer, the exercise simply says a duplexer is a module that exports a duplex stream, but that doesn't actually explain what it is to me.
  • We're asked to use libraries like Trumpet and Through, but I don't feel like they were actually explained to me. How do they work? Why are they useful? When do developers use them? The only reason I was able to make a lot of my exercises work was because of trial and error based on the example code, or cheating by looking at the solutions. Furthermore, it wasn't explicitly stated in Duplexer Redux that we still needed to use the Through library. I know it was used in Duplexer, but having this hint would have helped a lot.
  • In general, the exercises assume a lot about prior knowledge that the student might have. I don't think I actually knew what an HTTP client was.

I think the exercises would be more powerful if all of them directly built on top of the previous one, with the final exercise being a little script that incorporates all of the concepts learned. At present, I feel like I completed all of these exercises, but I don't know what to do with all the concepts I learned. They weren't presented to me in a way where I feel like I can go and apply them to a current project I'm working on. In what context would a duplexer be useful? When should I use these libraries?

These are just some thoughts I had on how to improve stream-adventure and NodeSchool in general. Please keep working on these - they are amazing and I learned so much this weekend! Thank you for all that you do.

Installation issue: "git://github.com/substack/node-browser-resolve.git" unreachable

When trying to install:

npm http 304 https://registry.npmjs.org/combined-stream
npm http 304 https://registry.npmjs.org/async

> [email protected] install /opt/node-v0.10.21-linux-x64/lib/node_modules/stream-adventure/node_modules/ws
> (node-gyp rebuild 2> builderror.log) || (exit 0)

npm http GET https://registry.npmjs.org/delayed-stream/0.0.5
make: Entering directory `/opt/node-v0.10.21-linux-x64/lib/node_modules/stream-adventure/node_modules/ws/build'
  CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
make: Leaving directory `/opt/node-v0.10.21-linux-x64/lib/node_modules/stream-adventure/node_modules/ws/build'
npm http 304 https://registry.npmjs.org/delayed-stream/0.0.5
npm ERR! git clone git://github.com/substack/node-browser-resolve.git Cloning into bare repository '/home/andrew/.npm/_git-remotes/git-github-com-substack-node-browser-resolve-git-baafa423'...
npm ERR! git clone git://github.com/substack/node-browser-resolve.git 
npm ERR! git clone git://github.com/substack/node-browser-resolve.git fatal: unable to connect to github.com:
npm ERR! git clone git://github.com/substack/node-browser-resolve.git github.com[0: 192.30.252.128]: errno=Connection timed out
npm ERR! Error: Command failed: fatal: unable to connect to github.com:
npm ERR! github.com[0: 192.30.252.128]: errno=Connection timed out
npm ERR! 
npm ERR! 
npm ERR!     at ChildProcess.exithandler (child_process.js:637:15)
npm ERR!     at ChildProcess.EventEmitter.emit (events.js:98:17)
npm ERR!     at maybeClose (child_process.js:735:16)
npm ERR!     at Socket.<anonymous> (child_process.js:948:11)
npm ERR!     at Socket.EventEmitter.emit (events.js:95:17)
npm ERR!     at Pipe.close (net.js:466:12)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <[email protected]>

npm ERR! System Linux 3.8.0-19-generic
npm ERR! command "/opt/node-v0.10.21-linux-x64/bin/node" "/opt/node-v0.10.21-linux-x64/bin/npm" "install" "-g" "stream-adventure"
npm ERR! cwd /home/andrew/.npm/_git-remotes
npm ERR! node -v v0.10.21
npm ERR! npm -v 1.3.11
npm ERR! code 128
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/andrew/.npm/_git-remotes/npm-debug.log
npm ERR! not ok code 0

Concat example : extra '\n' in output desireable?

The console.log() adds a '\n' to the output:

var concat = require('concat-stream');

process.stdin.pipe(concat(function (src) {
var s = src.toString().split('').reverse().join('');
console.log(s);
}));

Maybe this should be:

var concat = require('concat-stream');
process.stdin.pipe(concat(function (src) {
var s = src.toString().split('').reverse().join('');
process.stdout.write(s);
}));

Thoughts?

Duplexer confusing example

I'd recommend changing the challenge to use anything else but child_process. Seeing stdin and stdout as the arguments can give people false confidence of duplexer. I just spend an hour trying to figure out the next challenge only to find out that the order of duplexer is Writable, Readable. I know the documentation says that but other people made the same mistake: #55

I'd bet it help other people too if this challenge used process.stdin/stdout instead or something like reading from files.

Document required Node version

I was left stumped trying to find the bug in my solution to the Crypto and Secretz problems, due to a bug (nodejs/node-v0.x-archive#5270) in (at least) the 0.10.3 version of Node which i was running.

Having a documented requirement for Node version would have made finding this out somewhat easier. Now I only started looking elsewhere after "cheating" and finding out that your official solution doesn't work either.

concat : confusing hints

Hello,

If I read the hints and the example it looks like I need to use a http-server.
But if I look at the solution I do not need it.

I find this very confusing in learning how to solve this .

Roelof

question about concat

var concat = require('concat-stream');
var reverse = concat(function (buf) {
var body = buf.toString().split('').reverse().join('');
console.log(body);
});

process.stdin.pipe(reverse).pipe(process.stdout);

the above is my program and I receive this error:
stream.js:94
throw er; // Unhandled stream error in pipe.
^
Error: read ECONNRESET
at errnoException (net.js:901:11)
at Pipe.onread (net.js:556:19)

any idea why and how to fix this?

`through` usage changes test behavior?

On exercise number 7, HTTP SERVER, I'm trying to use through in a slightly different way than the official solution and running into trouble.

The jist of the supplied solution is this code in the server definition:

req.pipe(through(function (buf) {
    this.queue(buf.toString().toUpperCase());
})).pipe(res);

The only difference I'm trying to do is:

//outside server definition
var tr = through(function (buf) {
    this.queue(buf.toString().toUpperCase());
})

...
//inside server definition
req.pipe(tr).pipe(res);

It there any reason why I can't do an assignment like this?

My code will work when I make my posts individually, but when stream-adventure verifies it with a collection of tests I get a handful of actual results duplicated, and the rest of the expected results don't line up :

ACTUAL                             EXPECTED
------                             --------
"CAN"                              "CAN"
"SLOUGHCHANGE"                     "SLOUGHCHANGE"
"IN"                               "IN"
"THE"                              "THE"
"NIP"                              "NIP"
"OF"                               "OF"
"CAN"                          !== "A"
"SLOUGHCHANGE"                 !== "A"
"IN"                           !== "NAPPLE"
"THE"                          !== "NAPPLE"
"NIP"                          !== "SOLONGAS"
"OF"                           !== "WE"
"A"                            !== "SOLONGAS"
"A"                            !== "WE"
"NAPPLE"                       !== "CAN"
"NAPPLE"                       !== "CAN"
"SOLONGAS"                     !== "ALLSEE"
"WE"                           !== "ALLSEE"
"SOLONGAS"                     !== "FOR"
"WE"                           !== "FOR"
"CAN"                          !== "DEEDSETTON"
"CAN"                          !== "DEEDSETTON"
"ALLSEE"                       !== "YOUR"
"ALLSEE"                       !== "YOUR"
"FOR"                          !== "QUICK."
"FOR"                          !== "QUICK."
"DEEDSETTON"                   !== "TARK'S"
"DEEDSETTON"                   !== "TARK'S"
"YOUR"                         !== "BIMBOOWOOD"
"YOUR"                         !== "BIMBOOWOOD"
"QUICK."                       !== "SO"
"QUICK."                       !== "SO"
"TARK'S"                       !== "PLEASEKINDLY"
"TARK'S"                       !== "PLEASEKINDLY"
"BIMBOOWOOD"                   !== ""
"SO"                           !== null
"SO"                           !== null
"PLEASEKINDLY"                 !== null
"PLEASEKINDLY"                 !== null
""                             !== null
# FAIL

I've seen 1-5 results duplicated, sometimes it it's the expected results that are duplicated, not the actual results. Initially I wanted to blame the test runner, but it works fine when the through stream is defined inline so I suspect I'm not understanding something fundamental about the through module.

I've also used this code from an earlier module in stream-adventure that uses through and had the same problem:

var tr = through(write);

function write(buf) { this.queue(buf.toString().toUpperCase())};
function end() {this.queue('')};

//inside server definition
req.pipe(tr).pipe(res);

Doesn't work on windows

Installs fine, then trying to run it I get the following

$ stream-adventure

C:\Users\Mike\AppData\Roaming\npm\node_modules\stream-adventure\node_modules\terminal-menu\index.js:59
    process.stdin.setRawMode(true);
                  ^
TypeError: Object #<Socket> has no method 'setRawMode'
    at new Menu (C:\Users\Mike\AppData\Roaming\npm\node_modules\stream-adventure\node_modules\terminal-menu\index.js:59:19)
    at module.exports (C:\Users\Mike\AppData\Roaming\npm\node_modules\stream-adventure\node_modules\terminal-menu\index.js:7:12)
    at module.exports (C:\Users\Mike\AppData\Roaming\npm\node_modules\stream-adventure\bin\menu.js:9:16)
    at Object.<anonymous> (C:\Users\Mike\AppData\Roaming\npm\node_modules\stream-adventure\bin\cmd.js:125:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)

Secretz create hash stream scope issue

My solution:

var crypto = require('crypto');
var zlib = require('zlib');
var through = require('through');
var tar = require('tar');

var cipher = process.argv[2], pass = process.argv[3];
var decipher = crypto.createDecipher(cipher, pass);
var tarParser = tar.Parse();
var hasher = crypto.createHash('md5', {encoding: 'hex'});
tarParser.on('entry', function(e) {
    if (e.type !== "File") return;
    //e.pipe(tr);

    e.pipe(hasher).pipe(through(null, end)).pipe(process.stdout);
    function end() {
        this.queue(' ' + e.path + '\n');
    }
});

process.stdin.pipe(decipher).pipe(zlib.createGunzip()).pipe(tarParser);

If I run it it gives the following error:

stream.js:94
    throw er; // Unhandled stream error in pipe.

Error: write after end
    at writeAfterEnd (_stream_writable.js:132:12)
    at Hash.Writable.write(_stream_writable.js:180:5)
    at Entry.ondata(stream.js:51:26)
    at Entry.emit(events.js:117:20)

The only difference from official solution is that I put the create hash stream definition in the global scope other than function scope. Can someone explain to me what's going on here? I'm a beginner for node.js and javascript in general.

Many thanks.

secretz proposed solution doesn't look correct

by just removing the encryption and issuing this command:

$ tar cz *.js | node test4.js aes256 12e

The proposed solution results in:

d58a433358aac365cf9775fd720c3877d8511d1533c570132a49ad3a37d40607fafb6b323fea7b405b8692721bfae694ba2d8570a5f7f6a8dc73601441271f2946ba3db932c373a0b9197d044e075ca1 prog.js
 test2.js
 test3.js
 test4.js
 test.js

So the verification is also wrong.
To create a proper result I had to insert the filename into the chunk at the thorugh stream, which is conceptually wrong since the chunk could get splitted (won't happen here since the hash is so small that no implementation will chunk it)

why is this getting mixed up? The proposed solution looks right, but the results don't...

Lines Problem - Official Solution Incorrect

The official solution has the toLowerCase() and toUpperCase() methods on the wrong sides of the ternary expression based on the wording in the challenge. "... convert even-numbered lines to upper-case and odd-numbered lines to lower-case. Consider the first line to be odd-numbered. ..."

Also, the lineCount is defaulted to 0 and the increment is not called until after the output has been queued. This would mean that the first line will be upper case instead of lower case, assuming the above error has been fixed. Either lineCount needs to be defaulted to 1 or the increment call needs to be before the output is queued.

add support for vim bindings

I just finished learnyounode and graduated to stream-adventure. Sad to see that the exercise selector doesn't support j or k for navigating up and down.

Use through2

Should this start using through2 instead of through to teach how to create transform streams?

http server issue

The official answer is

var http = require('http');
var through = require('through');

var server = http.createServer(function (req, res) {
    if (req.method === 'POST') {
        req.pipe(through(function (buf) {
            this.queue(buf.toString().toUpperCase());
        })).pipe(res);
    }
    else res.end('send me a POST\n');
});
server.listen(parseInt(process.argv[2]));

which could pass the http server task. but if I separate the through function like:
var tr = through(write).. like the following code.

var http = require('http');
var through = require('through');
var tr = through(function (buf) {
    this.queue(buf.toString().toUpperCase());
});
var server = http.createServer(function (req, res) {
    if (req.method === 'POST') {
        req.pipe(tr).pipe(res);
    }
    else res.end('send me a POST\n');
});
server.listen(parseInt(process.argv[2]));

It failed, give me the error like:

ACTUAL                             EXPECTED
------                             --------
"ON"                               "ON"                          
"THEM"                             "THEM"                        
"ON"                           !== "BUT,"                        
"THEM"                         !== "MASTER"                      
"BUT,"                         !== "OF"                          
"MASTER"                       !== "BUT,"                        
"OF"                           !== "MASTER"                      
"BUT,"                         !== "OF"                          
"MASTER"                       !== "SNAKES,"                     
"OF"                           !== "WE"                          
"SNAKES,"                          "SNAKES,"                     
"WE"                           !== "CAN"                         
"SNAKES,"                      !== "WE"                          
"CAN"                              "CAN"                         
"WE"                           !== "SLOUGHCHANGE"                
"CAN"                          !== "IN"                          
"SLOUGHCHANGE"                     "SLOUGHCHANGE"                
"IN"                           !== "THE"                         
"SLOUGHCHANGE"                 !== "IN"                          
"THE"                          !== "NIP"                         
"IN"                           !== "THE"                         
"NIP"                          !== "OF"                          
"THE"                          !== "NIP"                         
"OF"                           !== "A"                           
"NIP"                          !== "OF"                          
"A"                            !== "NAPPLE"                      
"OF"                           !== "A"                           
"NAPPLE"                       !== "SOLONGAS"                    
"A"                            !== "NAPPLE"                      
"SOLONGAS"                     !== "WE"                          
"NAPPLE"                       !== "SOLONGAS"                    
"WE"                           !== "CAN"                         
"SOLONGAS"                     !== "WE"                          
"CAN"                          !== "ALLSEE"                      
"WE"                           !== "CAN"                         
"ALLSEE"                       !== "FOR"                         
"CAN"                          !== "ALLSEE"                      
"FOR"                          !== ""                            
""                             !== null                          
# FAIL

Could anybody tell me why?

HTTP Server Q bug, validates incorrectly

I submitted the following for the HTTP Server question and it passed yet didn't return the output I had expected from previous attempts.

var http = require('http');
var through = require('through');

var tr = through(function(buf){
  this.queue(buf.toString().toUpperCase())
});

var server = http.createServer(function(req,res){
  if (req.method === 'POST'){
    req.pipe(tr).pipe(res);
  }
   res.end('bbeeper\n');
});

server.listen(parseInt(process.argv[2]));

passed w/

ACTUAL                             EXPECTED
------                             --------
"bbeeper"                          "bbeeper"                     
""                                 ""                            
# PASS


First node bug reported so feedback would be appreciated.

meet pipe: data.txt not readable by program when installed globally

The data.txt is in a location where it can't easily be read by the node process invoked as a limited user.

You will get a file as the first argument to your program (process.argv[2]).

Use `fs.createReadStream()` to pipe the given file to `process.stdout`.

`fs.createReadStream()` takes a file as an argument and returns a readable
stream that you can call `.pipe()` on. Here's a readable stream that pipes its
data to `process.stderr`:

    var fs = require('fs');
    fs.createReadStream('data.txt').pipe(process.stderr);

Your program is basically the same idea, but instead of `'data.txt'`, the
filename comes from `process.argv[2]` and you should pipe to stdout, not stderr.

To verify your program, run: `stream-adventure verify program.js`.

[diamonds@localhost stream-adventure]$ stream-adventure run meetpipe.js

fs.js:427
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^
Error: EACCES, permission denied '/usr/lib/node_modules/stream-adventure/problems/meet_pipe/data.txt'
    at Object.fs.openSync (fs.js:427:18)
    at Object.fs.writeFileSync (fs.js:966:15)
    at module.exports (/usr/lib/node_modules/stream-adventure/problems/meet_pipe/setup.js:14:8)
    at Object.<anonymous> (/usr/lib/node_modules/stream-adventure/bin/cmd.js:43:43)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)

The offending line;
fs.writeFileSync(file, data);

Problem sets with dependencies require installing these dependencies in script folders

This is not clear from the instructions and the problems emit "# FAIL" and empty lines without any specific error referencing the missing libs.

For examples, in order to pass problems 4 and 5 it is required to run npm install through split in the folder where you are composing your problems.

Thanks for an amazing bit of interactive education, I learned a ton about streams from you.

The rsult is not correct, in problem 7

Here is my solution:

var http = require('http');                                                                                                                                                                                      
var through = require('through');                                                                                                                                                                                                                                                                                                                                                                                         
var th = through(function(buf) {                                                                                                                                                                                 
    this.queue(buf.toString().toUpperCase());                                                                                                                                                                    
})                                                                                                                                                                                                                        
var server = http.createServer(function (req, res) {                                                                                                                                                             
    if (req.method === 'POST') {                                                                                                                                                                                 
    //  req.pipe(through(function(buf) {                                                                                                                                                                         
    //      this.queue(buf.toString().toUpperCase());                                                                                                                                                            
    //  })).pipe(res);                                                                                                                                                                                           
        req.pipe(th).pipe(res);                                                                                                                                                                                  
    }                                                                                                                                                                                                            
    else res.end('send me a POST\n');                                                                                                                                                                            
});                                                                                                                                                                                                              
server.listen(parseInt(process.argv[2]));

Result:

ACTUAL                             EXPECTED                                                                                                                                                                      
------                             --------                                                                                                                                                                      
"OR"                               "OR"                                                                                                                                                                          
"MISLAID"                          "MISLAID"                                                                                                                                                                     
"ON"                               "ON"                                                                                                                                                                          
"THEM"                             "THEM"                                                                                                                                                                        
"BUT,"                             "BUT,"                                                                                                                                                                        
"MASTER"                           "MASTER"                                                                                                                                                                      
"OF"                           !== "SNAKES,"                                                                                                                                                                     
"OR"                           !== "OF"                                                                                                                                                                          
"MISLAID"                      !== "WE"                                                                                                                                                                          
"ON"                           !== "SNAKES,"                                                                                                                                                                     
"THEM"                         !== "CAN"                                                                                                                                                                         
"BUT,"                         !== "WE"                                                                                                                                                                          
"MASTER"                       !== "SLOUGHCHANGE"                                                                                                                                                                
"SNAKES,"                      !== "IN"                                                                                                                                                                          
"OF"                           !== "CAN"                                                                                                                                                                         
"WE"                           !== "SLOUGHCHANGE"                                                                                                                                                                
"SNAKES,"                      !== "THE"                                                                                                                                                                         
"CAN"                          !== "IN"                                                                                                                                                                          
"WE"                           !== "NIP"                                                                                                                                                                         
"SLOUGHCHANGE"                 !== "THE"                                                                                                                                                                         
"IN"                           !== "OF"                                                                                                                                                                          
"CAN"                          !== "NIP"                                                                                                                                                                         
"SLOUGHCHANGE"                 !== "A"                                                                                                                                                                           
"THE"                          !== "OF"                                                                                                                                                                          
"IN"                           !== "A"                                                                                                                                                                           
"NIP"                          !== "NAPPLE"                                                                                                                                                                      
"THE"                          !== "SOLONGAS"                                                                                                                                                                    
"OF"                           !== "NAPPLE"                                                                                                                                                                      
"NIP"                          !== "WE"                                                                                                                                                                          
"A"                            !== "SOLONGAS"                                                                                                                                                                    
"OF"                           !== "CAN"                                                                                                                                                                         
"A"                            !== "WE"                                                                                                                                                                          
"NAPPLE"                       !== ""                                                                                                                                                                            
"NAPPLE"                       !== null                                                                                                                                                                          
"WE"                           !== null                                                                                                                                                                          
"SOLONGAS"                     !== null                                                                                                                                                                          
"CAN"                          !== null                                                                                                                                                                          
"WE"                           !== null                                                                                                                                                                          
""                             !== null                                                                                                                                                                          
# FAIL                                      

Mention \r\n in "lines" lesson

Windows users need to use the split module with \r\n instead of just the default settings. This could throw off some newbie users, so it should probably be mentioned in the lesson text.

Colorful printing

Like learnyounode, colorful printing is much nice looking on the console I think!

issue in installing

[email protected] install /usr/lib/node_modules/stream-adventure/node_modules/ws
(node-gyp rebuild 2> builderror.log) || (exit 0)
what to do here?

UPD Resolved. :)

HTTP SERVER test not working properly

While writing my solution, I first wrote some simple code like

var server = http.createServer(function (req, res) {
    if (req.method === 'POST') { 
        req.pipe(res);
    }
    res.end();
});

and, surprisingly, it did pass the test without complaining

WEBSOCKETS canonical solution errors when run

Running the solution stream-adventure run websockets.js throws an error in the browser:

// CHROME ERROR:
Uncaught TypeError: Invalid non-string/buffer chunk _stream_writable.js:164
validChunk _stream_writable.js:164
Writable.write _stream_writable.js:193
Duplexify.end index.js:218
websocket-stream websockets.js:3
s bundle.js:1
e bundle.js:1(anonymous function)

// FIREFOX ERROR:
TypeError: Invalid non-string/buffer chunk

Using the canonical provided solution:

var ws = require('websocket-stream');
var stream = ws('ws://localhost:8000');
stream.end('hello\n');

Another solution for Duplex Redux

I think for those wondering how to solve the Duplex Redux challenge without using "through", it would be good to add an alternative official solution to compare to.

Here is my solution for the challenge without using "through". I am not sure if the code fulfills latest node and javascript best practices, but it works. It also might be good to point out why solving the challenge with "through" might be preferable to creating a writable stream explicitely on your own.

var spawn = require('child_process').spawn
var Stream = require('stream')
var duplexer = require('duplexer')


module.exports = function (counter) {
  var inwrite = new Stream.Writable({objectMode: true})

  var countryCounts = {}

  inwrite._write = function (chunk, enc, next) {    
    //what to do with the chunk
    if (countryCounts[chunk.country]) {
      countryCounts[chunk.country] = countryCounts[chunk.country] + 1
    } else {
      countryCounts[chunk.country] = 1
    }

    next()
  }

  inwrite.on('finish', function() {
    //in the end: set countryCounts in readable stream
    counter.setCounts(countryCounts)
  })

  return duplexer(inwrite, counter)
}

throw in transform

node v0.10.12,
result of verifying transform solution:

ACTUAL                             EXPECTED
------                             --------

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: read ECONNRESET
    at errnoException (net.js:901:11)
    at Pipe.onread (net.js:556:19)

This occurs even with supplied working solution.

Stream-Adventure, Duplexer Challenge real project example?

Hey!

I finished the Duplexer challenge, however, I'm not sure when to use it in a real life projects.

So, it takes a readable stream process.stdin and a writeable process.stdout, and joins them as a readable/writeable stream, correct? can somebody give me a real project example to demonstrate the use of Duplex streams?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.