src/test/irc_conn.c
author Tero Marttila <terom@fixme.fi>
Mon, 04 May 2009 20:55:04 +0300
branchnew-transport
changeset 168 a58ad50911fc
permissions -rw-r--r--
refactor test.c into tests/*
#include "irc_conn.h"
#include "test.h"

static void _conn_on_registered (struct irc_conn *conn, void *arg)
{
    struct test_conn_ctx *ctx = arg;

    (void) conn;

    if (ctx) ctx->on_registered = true;

    log_debug("registered");
}

static void _conn_on_error (struct irc_conn *conn, struct error_info *err, void *arg)
{
    struct test_conn_ctx *ctx = arg;
    
    (void) conn;
    (void) err;

    if (ctx) ctx->on_error = true;

    log_debug("on_error");
}

static void _conn_on_quit (struct irc_conn *conn, void *arg)
{
    struct test_conn_ctx *ctx = arg;

    (void) conn;

    if (ctx) ctx->on_quit = true;

    log_debug("on_quit");
}

static void _conn_on_TEST (const struct irc_line *line, void *arg)
{
    struct test_conn_ctx *ctx = arg;

    assert(line->source);
    assert(!line->source->nickname && !line->source->username && line->source->hostname);
    assert_strcmp(line->command, "TEST");
    assert_strcmp(line->args[0], "arg0");
    assert_strnull(line->args[1]);

    if (ctx) ctx->on_TEST = true;

    log_debug("on_TEST");
}

static struct irc_conn_callbacks _conn_callbacks = {
    .on_registered      = &_conn_on_registered,
    .on_error           = &_conn_on_error,
    .on_quit            = &_conn_on_quit,
};

static struct irc_cmd_handler _conn_handlers[] = {
    {   "TEST",         &_conn_on_TEST  },
    {   NULL,           NULL            }
};

struct irc_conn* setup_irc_conn (struct transport_test *tp, bool noisy, struct test_conn_ctx *ctx)
{
    struct irc_conn *conn;
    struct error_info err;
    struct irc_conn_register_info register_info = {
        "nick", "user", "realname"
    };

    // init the ctx
    memset(ctx, 0, sizeof(*ctx));

    // create the irc_conn
    assert_success(irc_conn_create(&conn, transport_test_cast(tp), &_conn_callbacks, ctx, &err));

    // test register
    if (noisy) log_info("test irc_conn_register");
    assert_success(irc_conn_register(conn, &register_info));
    assert_transport_data(tp, "NICK nick\r\nUSER user 0 * realname\r\n");
 
    // test on_register callback    
    if (noisy) log_info("test irc_conn_callbacks.on_register");
    transport_test_push_str(tp, "001 mynick :Blaa blaa blaa\r\n");
    if (ctx) assert(ctx->on_registered);
    assert_strcmp(conn->nickname, "mynick");
   
    // ok
    return conn;
}

void test_irc_conn (void)
{
    struct test_conn_ctx ctx;
    struct transport_test *tp = setup_transport_test();
    struct irc_conn *conn = setup_irc_conn(tp, true, &ctx);

    // add our test handlers
    assert_success(irc_conn_add_cmd_handlers(conn, _conn_handlers, &ctx));

    // test on_TEST handler
    // XXX: come up with a better prefix
    log_info("test irc_conn.handlers");
    transport_test_push_str(tp, ":foobar-prefix TEST arg0\r\n");
    assert(ctx.on_TEST);

    // test PING/PONG
    log_info("test PING/PONG");
    transport_test_push_str(tp, "PING foo\r\n");
    assert_transport_data(tp, "PONG foo\r\n");

    // quit nicely
    log_info("test QUIT");
    assert_success(irc_conn_QUIT(conn, "bye now"));
    assert_transport_data(tp, "QUIT :bye now\r\n");
    assert(conn->quitting);

    transport_test_push_str(tp, "ERROR :Closing Link: Quit\r\n");
    transport_test_push_eof(tp);
    assert(conn->quit && !conn->quitting && !conn->registered);
    assert(ctx.on_quit);
    assert(!ctx.on_error);

    // destroy it
    irc_conn_destroy(conn);
}

void test_irc_conn_self_nick (void)
{
    struct test_conn_ctx ctx;
    struct transport_test *tp = setup_transport_test();
    struct irc_conn *conn = setup_irc_conn(tp, false, &ctx);
    
    log_info("test irc_conn_on_NICK");
    transport_test_push_fmt(tp, ":mynick!user@somehost NICK mynick2\r\n");
    assert_strcmp(conn->nickname, "mynick2");

    // cleanup
    irc_conn_destroy(conn);
}