gf3 / IRC-js

The best IRC library for node.js
http://irc-js.com
The Unlicense
179 stars 33 forks source link

Make IRC mockable. #53

Closed emberian closed 12 years ago

emberian commented 12 years ago

Mostly the addition of IRC#emit, as well as something for things like IRC#privmsg et al to log somewhere. I've forked and will work on this. Feedback? Advice?

gf3 commented 12 years ago

Good call! I actually have some mock stuff under /spec in the feature/twopointoh branch. IRC#emit is a neat idea, if you're using the 2.0.0-beta or feature/twopointoh branch you can hack it with instance._internals.emitter.emit("dix").

emberian commented 12 years ago

MockInternals looks like it should be ready for drop-in replacement of instance._internals, anything unfinished? I think I have a fairly good idea of the changes I want to make.

If you were writing tests for a bot or a client, what would you want? At first I thought something like IRC#emit would be a good idea but I just realized that then I'd probably be giving it an object like I'd be given in the event listener, but that's not a good source of data because that might change or be something I don't expect. I could give it raw IRC lines and have it parse it and such, but that's not really good because it's a pain in the ass to write. So what I'm thinking I'll end up writing is a convenience library for building IRC protocol strings. But pretty much every method of IRC is already doing that for its own thing, so my thought is to hotswap instance._internals.socket with a simple object that I can pull the string from afterwards, replace the socket object, and then send that string back through with instance._internals.socket.emit(that_string).

Thoughts?

gf3 commented 12 years ago

I honestly think the simplest solution is using actual, raw IRC messages. Less room for error. Also allows you to copy paste failing IRC messages and use them in tests.

emberian commented 12 years ago

On that note, I've been thinking that something like expect(1) would be good. You'd have something like this:

expect NICK foobar
expect USER js-irc 0 * :Javascript Bot
send "intro_and_motd.irc"

# This is a comment. Up there is how you'd include a file, it's just a bunch of raw irc lines
# Comments are lines that start with # and nothing else. Different syntax?
expect JOIN #test
send "join_channel.irc"
send :tester!tester@example.com PRIVMSG #test :foobar: ping
expect PRIVMSG #test :tester: pong

# Maybe some programmatic tests?
function (prev) { 
    return (prev.params[1] == 'foobar: ping')
}

Or something along those lines. Would be fairly simple to write, basically just a script that the bot should be following. For the programmatic tests, the argument passed would be like the objects event handlers get in IRC#on. A simple parser could just look for 'function', then count curly braces till the number of { is the number of }, and pass the body off to new Function. Expected to return true/false, or a string indicating what the error was.

Thoughts?

gf3 commented 12 years ago

I think most of this we get for free from existing testing frameworks, albeit a tad more verbose. I'm not sure the benefits of using this system would outweigh the burden of maintaining it. Would be cool, perhaps, as a generalized network testing framework.

emberian commented 12 years ago

I'll sleep on it and write some tests with an existing framework (probably node-tap) and see if it'd be worth my time. Do you know of anything using irc-js that has tests?

gf3 commented 12 years ago

Nothing other than IRC-js itself.