<commit_before>var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

var gameStates = { "active": 0, "paused": 1, "win": 2, "gameover": 3 };
Object.freeze(gameStates);

var dx = 2;
var dy = -2;

var ballRadius = 10;
var ballColour = "#0095DD";

var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var paddleY = (canvas.height - paddleHeight) - 10;

var ballX = canvas.width / 2;
var ballY = paddleY - (ballRadius * 2);

var rightPressed = false;
var leftPressed = false;

var gameState = gameStates.active;

var destroyedBricksCount = 0;
var score = 0;
var lives = 3;

var pointSound = new sound("assets/sound-effects/beep.mp3", 0.4);
var lifeLostSound = new sound("assets/sound-effects/life-lost.mp3", 0.4);
var gameOverSound = new sound("assets/sound-effects/game-over.mp3");
var winSound = new sound("assets/sound-effects/win.mp3");

var playSound = true;

var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;

var bricks = [];
for (column = 0; column < brickColumnCount; column++) {
    bricks[column] = [];
    for (row = 0; row < brickRowCount; row++) {
        bricks[column][row] = { x: 0, y: 0, status: getRandomBrickStatus() };
    }
}

function getRandomBrickStatus() {
    min = 1;
    max = 3;
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getBrickColour(status) {
    switch (status) {
        case 1:
            return "#4ca33a";
        case 2:
            return "#ffe83a";
        case 3:
            return "#ff3a3a";
    }
}

function keyDownHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = true;
    }
    else if (e.keyCode == 37) {
        leftPressed = true;
    }
    else if (e.keyCode == 32) {
        togglePauseGame();
    }
    else if (e.keyCode == 82) {
        resetGame();
    }
    else if (e.keyCode == 83) {
        toggleAudio();
    }
}
function keyUpHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = false;
    }
    else if (e.keyCode == 37) {
        leftPressed = false;
    }
}
function mouseMoveHandler(e) {
    if (gameState === gameStates.active) {
        movePaddleByClientX(e.clientX);
    }
}

function touchMoveHandler(e) {
    if (gameState === gameStates.active) {
        var touches = e.changedTouches;

        for (var i = 0; i < touches.length; i++) {
            var touch = touches[i];
            movePaddleByClientX(touch.clientX);
        }
    }
}

function movePaddleByClientX(clientX) {
    var relativeX = clientX - canvas.offsetLeft;
    if (relativeX > 0 && (relativeX + (paddleWidth / 2)) < canvas.width) {
        var newX = relativeX - paddleWidth / 2;

        if (newX <= 0) {
            paddleX = 0;
        } else if (newX >= canvas.width) {
            paddleX = canvas.width;
        } else {
            paddleX = newX;
        }
    }
}

function collisionDetection() {
    brickCollisionDetection();
    wallCollisionDetection();
}

function brickCollisionDetection() {
    for (column = 0; column < brickColumnCount; column++) {
        for (row = 0; row < brickRowCount; row++) {
            var b = bricks[column][row];

            if (b.status > 0) {
                if (ballX > b.x && ballX < b.x + brickWidth && ballY > b.y && ballY < b.y + brickHeight) {
                    dy = -dy;
                    b.status--;

                    if (b.status == 0) {
                        destroyedBricksCount++;
                    }

                    score++;

                    if (playSound) {
                        pointSound.play();
                    }
                    if (destroyedBricksCount == brickRowCount * brickColumnCount) {
                        if (playSound) {
                            winSound.play();
                        }
                        gameState = gameStates.win;
                    }
                }
            }
        }
    }
}

function wallCollisionDetection() {
    if (ballX + dx > canvas.width - ballRadius || ballX + dx < ballRadius) {
        dx = -dx;
    }

    if (ballY + dy < ballRadius) {
        dy = -dy;
    } else if (ballY + dy > paddleY - ballRadius) {
        if (ballX > paddleX && ballX < paddleX + paddleWidth) {
            dy = -dy;
            if (playSound) {
                pointSound.play();
            }
        }
        else {
            lives--;

            if (!lives) {
                if (playSound) {
                    gameOverSound.play();
                }
                gameState = gameStates.gameover;
            } else {
                if (playSound) {
                    lifeLostSound.play();
                }
                ballX = canvas.width / 2;
                ballY = canvas.height - 30;
                dx = 2;
                dy = -2;
                paddleX = (canvas.width - paddleWidth) / 2;
            }
        }
    }
}

function drawBall() {
    ctx.beginPath();
    ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
    ctx.fillStyle = ballColour;
    ctx.fill();
    ctx.closePath();
}

function drawPaddle() {
    ctx.beginPath();
    ctx.rect(paddleX, paddleY, paddleWidth, paddleHeight);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
}

function drawMenu() {
    drawOverlay("Game Paused!");
}

function drawGameOver() {
    drawOverlay("Game Over!");
}
function drawWin() {
    drawOverlay("You Win!");
}

function drawBricks() {
    for (column = 0; column < brickColumnCount; column++) {
        for (row = 0; row < brickRowCount; row++) {
            var brick = bricks[column][row];
            if (brick.status > 0) {
                var brickX = (column * (brickWidth + brickPadding)) + brickOffsetLeft;
                var brickY = (row * (brickHeight + brickPadding)) + brickOffsetTop;
                brick.x = brickX;
                brick.y = brickY;

                ctx.beginPath();
                ctx.rect(brickX, brickY, brickWidth, brickHeight);
                ctx.fillStyle = getBrickColour(brick.status);
                ctx.fill();
                ctx.closePath();
            }
        }
    }
}

function drawScore() {
    ctx.beginPath();
    ctx.font = "16px Courier New";
    ctx.fillStyle = "#0095DD";
    ctx.textAlign = "left";
    ctx.fillText("Score: " + score, 10, 20);
    ctx.closePath();
}
function drawLives() {
    ctx.beginPath();
    ctx.font = "16px Courier New";
    ctx.fillStyle = "#0095DD";
    ctx.textAlign = "right";
    ctx.fillText("Lives: " + lives, canvas.width - 10, 20);
    ctx.closePath();
}

function drawSoundState() {
    var state = playSound ? "On" : "Off";

    ctx.beginPath();
    ctx.font = "16px Courier New";
    ctx.fillStyle = "#0095DD";
    ctx.textAlign = "center";
    ctx.fillText("Sound: " + state, canvas.width / 2, 20);
    ctx.closePath();
}

function drawOverlay(text) {
    ctx.beginPath();
    ctx.rect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgba(0,0,0,.2)";
    ctx.fill();
    ctx.closePath();

    ctx.beginPath();
    ctx.font = "30px Courier New";
    ctx.fillStyle = "black";
    ctx.textAlign = "center";
    ctx.fillText(text, canvas.width / 2, canvas.height / 2);
    ctx.closePath();
}

function movePaddle() {
    if (rightPressed && paddleX < canvas.width - paddleWidth) {
        paddleX += 7;
    }
    else if (leftPressed && paddleX > 0) {
        paddleX -= 7;
    }
}

function togglePauseGame() {
    if (gameState === gameStates.active) {
        gameState = gameStates.paused;
    } else if (gameState === gameStates.paused) {
        gameState = gameStates.active;
    }
}

function restartGame() {
    document.location.reload();
}

function toggleAudio() {
    if (gameState === gameStates.active || gameState === gameStates.paused) {
        playSound = !playSound;
    }
}

; (function () {
    function registerInputControls() {
        document.addEventListener("keydown", keyDownHandler, false);
        document.addEventListener("keyup", keyUpHandler, false);
        document.addEventListener("mousemove", mouseMoveHandler, false);
        document.addEventListener("touchmove", touchMoveHandler, false);
    }
    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawBricks();
        drawBall();
        drawPaddle();

        switch (gameState) {
            case gameStates.win:
                drawWin();
                break;
            case gameStates.gameover:
                drawGameOver();
                break;
            case gameStates.paused:
                drawMenu();
                break;
            case gameStates.active:
                collisionDetection();
                movePaddle();

                ballX += dx;
                ballY += dy;
        }

        drawSoundState();
        drawScore();
        drawLives();

        requestAnimationFrame(draw);
    }

    registerInputControls();
    draw();
})();

function sound(src, volume) {
    this.sound = document.createElement("audio");
    this.sound.src = src;

    if (volume && volume > 0) {
        this.sound.volume = volume;
    }

    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function (volume) {

        if (volume && volume > 0) {
            this.sound.volume = volume;
        }

        this.sound.play();
    }
    this.stop = function () {
        this.sound.pause();
    }
}<commit_msg>Anded e.preventDefault() in to stop browser gestures<commit_after>var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

var gameStates = { "active": 0, "paused": 1, "win": 2, "gameover": 3 };
Object.freeze(gameStates);

var dx = 2;
var dy = -2;

var ballRadius = 10;
var ballColour = "#0095DD";

var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var paddleY = (canvas.height - paddleHeight) - 10;

var ballX = canvas.width / 2;
var ballY = paddleY - (ballRadius * 2);

var rightPressed = false;
var leftPressed = false;

var gameState = gameStates.active;

var destroyedBricksCount = 0;
var score = 0;
var lives = 3;

var pointSound = new sound("assets/sound-effects/beep.mp3", 0.4);
var lifeLostSound = new sound("assets/sound-effects/life-lost.mp3", 0.4);
var gameOverSound = new sound("assets/sound-effects/game-over.mp3");
var winSound = new sound("assets/sound-effects/win.mp3");

var playSound = true;

var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;

var bricks = [];
for (column = 0; column < brickColumnCount; column++) {
    bricks[column] = [];
    for (row = 0; row < brickRowCount; row++) {
        bricks[column][row] = { x: 0, y: 0, status: getRandomBrickStatus() };
    }
}

function getRandomBrickStatus() {
    min = 1;
    max = 3;
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getBrickColour(status) {
    switch (status) {
        case 1:
            return "#4ca33a";
        case 2:
            return "#ffe83a";
        case 3:
            return "#ff3a3a";
    }
}

function keyDownHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = true;
    }
    else if (e.keyCode == 37) {
        leftPressed = true;
    }
    else if (e.keyCode == 32) {
        togglePauseGame();
    }
    else if (e.keyCode == 82) {
        resetGame();
    }
    else if (e.keyCode == 83) {
        toggleAudio();
    }
}
function keyUpHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = false;
    }
    else if (e.keyCode == 37) {
        leftPressed = false;
    }
}
function mouseMoveHandler(e) {
    if (gameState === gameStates.active) {
        movePaddleByClientX(e.clientX);
    }
}

function touchMoveHandler(e) {
    if (gameState === gameStates.active) {
        e.preventDefault();

        var touches = e.changedTouches;

        for (var i = 0; i < touches.length; i++) {
            var touch = touches[i];
            movePaddleByClientX(touch.clientX);
        }
    }
}

function movePaddleByClientX(clientX) {
    var relativeX = clientX - canvas.offsetLeft;
    if (relativeX > 0 && (relativeX + (paddleWidth / 2)) < canvas.width) {
        var newX = relativeX - paddleWidth / 2;

        if (newX <= 0) {
            paddleX = 0;
        } else if (newX >= canvas.width) {
            paddleX = canvas.width;
        } else {
            paddleX = newX;
        }
    }
}

function collisionDetection() {
    brickCollisionDetection();
    wallCollisionDetection();
}

function brickCollisionDetection() {
    for (column = 0; column < brickColumnCount; column++) {
        for (row = 0; row < brickRowCount; row++) {
            var b = bricks[column][row];

            if (b.status > 0) {
                if (ballX > b.x && ballX < b.x + brickWidth && ballY > b.y && ballY < b.y + brickHeight) {
                    dy = -dy;
                    b.status--;

                    if (b.status == 0) {
                        destroyedBricksCount++;
                    }

                    score++;

                    if (playSound) {
                        pointSound.play();
                    }
                    if (destroyedBricksCount == brickRowCount * brickColumnCount) {
                        if (playSound) {
                            winSound.play();
                        }
                        gameState = gameStates.win;
                    }
                }
            }
        }
    }
}

function wallCollisionDetection() {
    if (ballX + dx > canvas.width - ballRadius || ballX + dx < ballRadius) {
        dx = -dx;
    }

    if (ballY + dy < ballRadius) {
        dy = -dy;
    } else if (ballY + dy > paddleY - ballRadius) {
        if (ballX > paddleX && ballX < paddleX + paddleWidth) {
            dy = -dy;
            if (playSound) {
                pointSound.play();
            }
        }
        else {
            lives--;

            if (!lives) {
                if (playSound) {
                    gameOverSound.play();
                }
                gameState = gameStates.gameover;
            } else {
                if (playSound) {
                    lifeLostSound.play();
                }
                ballX = canvas.width / 2;
                ballY = canvas.height - 30;
                dx = 2;
                dy = -2;
                paddleX = (canvas.width - paddleWidth) / 2;
            }
        }
    }
}

function drawBall() {
    ctx.beginPath();
    ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
    ctx.fillStyle = ballColour;
    ctx.fill();
    ctx.closePath();
}

function drawPaddle() {
    ctx.beginPath();
    ctx.rect(paddleX, paddleY, paddleWidth, paddleHeight);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
}

function drawMenu() {
    drawOverlay("Game Paused!");
}

function drawGameOver() {
    drawOverlay("Game Over!");
}
function drawWin() {
    drawOverlay("You Win!");
}

function drawBricks() {
    for (column = 0; column < brickColumnCount; column++) {
        for (row = 0; row < brickRowCount; row++) {
            var brick = bricks[column][row];
            if (brick.status > 0) {
                var brickX = (column * (brickWidth + brickPadding)) + brickOffsetLeft;
                var brickY = (row * (brickHeight + brickPadding)) + brickOffsetTop;
                brick.x = brickX;
                brick.y = brickY;

                ctx.beginPath();
                ctx.rect(brickX, brickY, brickWidth, brickHeight);
                ctx.fillStyle = getBrickColour(brick.status);
                ctx.fill();
                ctx.closePath();
            }
        }
    }
}

function drawScore() {
    ctx.beginPath();
    ctx.font = "16px Courier New";
    ctx.fillStyle = "#0095DD";
    ctx.textAlign = "left";
    ctx.fillText("Score: " + score, 10, 20);
    ctx.closePath();
}
function drawLives() {
    ctx.beginPath();
    ctx.font = "16px Courier New";
    ctx.fillStyle = "#0095DD";
    ctx.textAlign = "right";
    ctx.fillText("Lives: " + lives, canvas.width - 10, 20);
    ctx.closePath();
}

function drawSoundState() {
    var state = playSound ? "On" : "Off";

    ctx.beginPath();
    ctx.font = "16px Courier New";
    ctx.fillStyle = "#0095DD";
    ctx.textAlign = "center";
    ctx.fillText("Sound: " + state, canvas.width / 2, 20);
    ctx.closePath();
}

function drawOverlay(text) {
    ctx.beginPath();
    ctx.rect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgba(0,0,0,.2)";
    ctx.fill();
    ctx.closePath();

    ctx.beginPath();
    ctx.font = "30px Courier New";
    ctx.fillStyle = "black";
    ctx.textAlign = "center";
    ctx.fillText(text, canvas.width / 2, canvas.height / 2);
    ctx.closePath();
}

function movePaddle() {
    if (rightPressed && paddleX < canvas.width - paddleWidth) {
        paddleX += 7;
    }
    else if (leftPressed && paddleX > 0) {
        paddleX -= 7;
    }
}

function togglePauseGame() {
    if (gameState === gameStates.active) {
        gameState = gameStates.paused;
    } else if (gameState === gameStates.paused) {
        gameState = gameStates.active;
    }
}

function restartGame() {
    document.location.reload();
}

function toggleAudio() {
    if (gameState === gameStates.active || gameState === gameStates.paused) {
        playSound = !playSound;
    }
}

; (function () {
    function registerInputControls() {
        document.addEventListener("keydown", keyDownHandler, false);
        document.addEventListener("keyup", keyUpHandler, false);
        document.addEventListener("mousemove", mouseMoveHandler, false);
        document.addEventListener("touchmove", touchMoveHandler, false);
    }
    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawBricks();
        drawBall();
        drawPaddle();

        switch (gameState) {
            case gameStates.win:
                drawWin();
                break;
            case gameStates.gameover:
                drawGameOver();
                break;
            case gameStates.paused:
                drawMenu();
                break;
            case gameStates.active:
                collisionDetection();
                movePaddle();

                ballX += dx;
                ballY += dy;
        }

        drawSoundState();
        drawScore();
        drawLives();

        requestAnimationFrame(draw);
    }

    registerInputControls();
    draw();
})();

function sound(src, volume) {
    this.sound = document.createElement("audio");
    this.sound.src = src;

    if (volume && volume > 0) {
        this.sound.volume = volume;
    }

    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function (volume) {

        if (volume && volume > 0) {
            this.sound.volume = volume;
        }

        this.sound.play();
    }
    this.stop = function () {
        this.sound.pause();
    }
}<|endoftext|>


<commit_before>/**
 * Tests for the javascript `Math`
 *
 * Those tests will use a single level of `describe`.
 * We choose `Math` because is a native javascript object
 * that works fine and has a simple API.
 *
 * Here you can see all diferent styles of custom `assetions` the you can use.
 *
 * If you want to learn TDD, the 1k style, just read this file.
 * I am sure that you will get it ;)
 **/

// Allow the tests to run in node
if (typeof module !== "undefined") require("../test.js");

// You can use the describe to group your assertions
describe("Math", function(){
  // #sqrt
  assertSqrt(4, 2);
  assertSqrt(9, 3);
  assertSqrt(16, 4);

  // The assertion function can interpolate a string with an array
  function assertSqrt(n, expectation) {
    assert("Math.sqrt(%0) === %1", [n, expectation]);
  }

  // #flor
  assertFloor(1.4, 1)
  assertFloor(3.41221341234, 3)

  // The assertion function can interpolate a string with an object
  function assertFloor(n, expectation) {
    assert("Math.floor(%n) === %result", {
      n: n, result: expectation
    });
  }

  // #pow
  assertPow(2, 2, 4);
  assertPow(4, 2, 16);
  assertPow(2, 1, 2);

  // you can customize your assertion anyway you like
  function assertPow(n1, n2, expectation) {
    var result = Math.pow(n1, n2)
      , msg = interpolate("#pow(%0, %1): %2 === %3",
        [n1, n2, expectation, result]);

    assert(result === expectation, msg);
  }
});
<commit_msg>make jenkins fail<commit_after>/**
 * Tests for the javascript `Math`
 *
 * Those tests will use a single level of `describe`.
 * We choose `Math` because is a native javascript object
 * that works fine and has a simple API.
 *
 * Here you can see all diferent styles of custom `assetions` the you can use.
 *
 * If you want to learn TDD, the 1k style, just read this file.
 * I am sure that you will get it ;)
 **/

// Allow the tests to run in node
if (typeof module !== "undefined") require("../test.js");

// You can use the describe to group your assertions
describe("Math", function(){
  // #sqrt
  assertSqrt(4, 2);
  assertSqrt(9, 3);
  assertSqrt(16, 4);
  assertSqrt(12, 1);

  // The assertion function can interpolate a string with an array
  function assertSqrt(n, expectation) {
    assert("Math.sqrt(%0) === %1", [n, expectation]);
  }

  // #flor
  assertFloor(1.4, 1)
  assertFloor(3.41221341234, 3)

  // The assertion function can interpolate a string with an object
  function assertFloor(n, expectation) {
    assert("Math.floor(%n) === %result", {
      n: n, result: expectation
    });
  }

  // #pow
  assertPow(2, 2, 4);
  assertPow(4, 2, 16);
  assertPow(2, 1, 2);

  // you can customize your assertion anyway you like
  function assertPow(n1, n2, expectation) {
    var result = Math.pow(n1, n2)
      , msg = interpolate("#pow(%0, %1): %2 === %3",
        [n1, n2, expectation, result]);

    assert(result === expectation, msg);
  }
});
<|endoftext|>


<commit_before>const path = require("path");
const config = require("config");
const express = require("express");
const bodyParser = require("body-parser");
const favicon = require("serve-favicon");

const routes = require("./routes");
const crawler = require("./controllers/crawler");
const dbhelper = require("./controllers/dbhelper");
const assetsMap = require("./public/assets/assets.json");

// init db.
dbhelper.start(() =>
{
    dbhelper.connect((err) =>
    {
        if (err)
        {
            console.error("Database Server not started, some features will be shut down.");
        }
        else
        {
            if (config.crawler.enabled)
            {
                crawler.start();
            }
        }
    });
});

// init express.
const app = express();

// view engine setup.
app.set("views", __dirname + "/views/");
app.set("view engine", "jade");

// favicon setup.
app.use(favicon(__dirname + "/public/favicon.ico"));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// router setup.
app.use("/", routes);

// static file setup.
app.use(express.static(__dirname + "/public/", {
    maxAge: 2592000000
}));

// assets map setup.
app.locals.map = assetsMap;

// catch 404 and forward to global error handler.
app.use((req, res, next) =>
{
    const err = new Error("404 Not Found");
    err.status = 404;
    next(err);
});

// global error handler.
app.use((err, req, res, next) =>
{
    res.status(err.status || 500).render("error_404", { map: app.locals.map });
});

module.exports = app;
<commit_msg>add err handling<commit_after>"use strict";

const path = require("path");
const config = require("config");
const express = require("express");
const bodyParser = require("body-parser");
const favicon = require("serve-favicon");

const routes = require("./routes");
const crawler = require("./controllers/crawler");
const dbhelper = require("./controllers/dbhelper");
const assetsMap = require("./public/assets/assets.json");

// init db.
dbhelper.start((err) =>
{
    let msg = "\nDatabase Server not started, some features will be shut down.";
    if (err)
    {
        console.error(err.message + msg);
    }
    else
    {
        dbhelper.connect((err) =>
        {
            if (err)
            {
                console.error(msg);
            }
            else
            {
                if (config.crawler.enabled)
                {
                    crawler.start();
                }
            }
        });
    }
});

// init express.
const app = express();

// view engine setup.
app.set("views", __dirname + "/views/");
app.set("view engine", "jade");

// favicon setup.
app.use(favicon(__dirname + "/public/favicon.ico"));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// router setup.
app.use("/", routes);

// static file setup.
app.use(express.static(__dirname + "/public/", {
    maxAge: 2592000000
}));

// assets map setup.
app.locals.map = assetsMap;

// catch 404 and forward to global error handler.
app.use((req, res, next) =>
{
    const err = new Error("404 Not Found");
    err.status = 404;
    next(err);
});

// global error handler.
app.use((err, req, res, next) =>
{
    res.status(err.status || 500).render("error_404", { map: app.locals.map });
});

module.exports = app;
<|endoftext|>


<commit_before>var Hapi = require('hapi'),
	config = require('./config.js'),
	server = new Hapi.Server(config.port),
	sc = config.sc;

server.route({
	method: 'GET',
	path: '/',
	handler: function(request, reply){
		return reply(JSON.stringify({response: sc})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/{query}',
	handler: function(request, reply){
		return reply(JSON.stringify({query: encodeURIComponent(request.params.query) + '?', response: sc})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/caps',
	handler: function(request, reply){
		return reply(JSON.stringify({response: sc.toUpperCase()})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/caps/{query}',
	handler: function(request, reply){
		return reply(JSON.stringify({query: encodeURIComponent(request.params.query) + '?', response: sc.toUpperCase()})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/camel',
	handler: function(request, reply){
		return reply(JSON.stringify({response: sc})).type('application/json');
	}
});

server.start(function () {
	console.log('A stocazzo provider is running at:', server.info.uri);
});
<commit_msg>camelcase fixed<commit_after>var Hapi = require('hapi'),
	config = require('./config.js'),
	server = new Hapi.Server(config.port),
	sc = config.sc;

server.route({
	method: 'GET',
	path: '/',
	handler: function(request, reply){
		return reply(JSON.stringify({response: sc})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/{query}',
	handler: function(request, reply){
		return reply(JSON.stringify({query: encodeURIComponent(request.params.query) + '?', response: sc})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/caps',
	handler: function(request, reply){
		return reply(JSON.stringify({response: sc.toUpperCase()})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/caps/{query}',
	handler: function(request, reply){
		return reply(JSON.stringify({query: encodeURIComponent(request.params.query) + '?', response: sc.toUpperCase()})).type('application/json');
	}
});

server.route({
	method: 'GET',
	path: '/camel',
	handler: function(request, reply){
		return reply(JSON.stringify({response: 'StoCazzo'})).type('application/json');
	}
});

server.start(function () {
	console.log('A stocazzo provider is running at:', server.info.uri);
});
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

 var express = require('express'),
     routes = require('./routes'),
     http = require('http'),
     path = require('path'),
     _ = require('underscore'),
     nodemailer = require('nodemailer'),
     emailTemplates = require('email-templates'),
     templatesDir = path.resolve(__dirname, '.', 'templates'),
     emailExistence = require('email-existence'),
     q = require('q'),
     app, ga;

 app = express();

process.on('uncaughtException', function (err) {
  console.error(err.stack);
  console.log("Node NOT Exiting...");
});

ga = {
  code: process.env.GA_CODE,
  url: process.env.GA_URL
};

app.configure(function(){
  app.set('port', process.env.PORT || 3005);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon(path.join(__dirname, 'app/img/favicon.ico')));
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'app')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index(app.get('env'), ga));

secretSanta = function(data) {
  var givers = data,
  takers = _.clone(givers),
  matches = [],
  i;

  for(i = 0; i < data.length; i++) {
    // can probably be done way better but hey, quick hack for now..
    var tmpGivers, tmpTakers, giver, taker;
    tmpGivers = _.clone(givers);
    tmpTakers = _.clone(takers);
    giver = _.sample(tmpGivers);
    tmpTakers = _.without(tmpTakers, giver);
    taker = _.sample(tmpTakers);
    takers = _.without(takers, taker);
    givers = _.without(givers, giver);
    takers.push(giver);

    matches.push({
      from: giver,
      to: taker
    });
  }

  return matches;
};

app.post('/checkEmail', function(req, res) {
  var data = req.body,
      _err = {
        errors: [],
        success: false
      },
      _res = res,
      checkEmail;

  checkEmail = function(email) {
    var deferred = q.defer();
    emailExistence.check(email, function(err, res) {
        deferred.resolve(err, res);
    });
    return deferred.promise;
  }

  checkEmail(data.email)
    .then(
      function(err, res) {
        console.log(err, res);
        if(err) {
          _err.success = false;
          _err.errors.push({
            error: err,
            message: 'E-mail address does not exist: ' + data.email
          });
        } else {
          _err.success = true;
          _res.json(_err);
        }
        _res.json(_err);
      }
    );
});

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
<commit_msg>status<commit_after>
/**
 * Module dependencies.
 */

 var express = require('express'),
     routes = require('./routes'),
     http = require('http'),
     path = require('path'),
     _ = require('underscore'),
     nodemailer = require('nodemailer'),
     emailTemplates = require('email-templates'),
     templatesDir = path.resolve(__dirname, '.', 'templates'),
     emailExistence = require('email-existence'),
     q = require('q'),
     app, ga;

 app = express();

process.on('uncaughtException', function (err) {
  console.error(err.stack);
  console.log("Node NOT Exiting...");
});

ga = {
  code: process.env.GA_CODE,
  url: process.env.GA_URL
};

app.configure(function(){
  app.set('port', process.env.PORT || 3005);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon(path.join(__dirname, 'app/img/favicon.ico')));
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'app')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index(app.get('env'), ga));

secretSanta = function(data) {
  var givers = data,
  takers = _.clone(givers),
  matches = [],
  i;

  for(i = 0; i < data.length; i++) {
    // can probably be done way better but hey, quick hack for now..
    var tmpGivers, tmpTakers, giver, taker;
    tmpGivers = _.clone(givers);
    tmpTakers = _.clone(takers);
    giver = _.sample(tmpGivers);
    tmpTakers = _.without(tmpTakers, giver);
    taker = _.sample(tmpTakers);
    takers = _.without(takers, taker);
    givers = _.without(givers, giver);
    takers.push(giver);

    matches.push({
      from: giver,
      to: taker
    });
  }

  return matches;
};

app.post('/checkEmail', function(req, res) {
  var data = req.body,
      _err = {
        errors: [],
        success: false
      },
      _res = res,
      checkEmail;

  checkEmail = function(email) {
    var deferred = q.defer();
    emailExistence.check(email, function(err, res) {
        deferred.resolve(err, res);
    });
    return deferred.promise;
  }

  checkEmail(data.email)
    .then(
      function(err, status) {
        console.log(err, status);
        if(err) {
          _err.success = false;
          _err.errors.push({
            error: err,
            message: 'E-mail address does not exist: ' + data.email
          });
        } else {
          _err.success = true;
          _res.json(_err);
        }
        _res.json(_err);
      }
    );
});

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

// you might want to change this :)
var track = "#c4l15";

var fs = require('fs');
var http = require('http');
var path = require('path');
var async = require('async');
var redis = require('redis');
var _ = require('underscore');
var cheerio = require('cheerio');
var express = require('express');
var Twitter = require('twitter');
var request = require('request');
var sockio = require('socket.io');
var readline = require('readline');

var db = redis.createClient();
var queue = async.queue(lookupUrl, 1);

function main() {
  listenForTweets(track);
  runWeb();
}

function runWeb() {
  var app = express();
  var server = http.Server(app);
  var io = sockio(server);

  app.use(express.static('public'));
  app.enable('trust proxy');
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'hbs');

  app.get('/', function(req, res) {
    getStats(function (stats) {
      res.render('index.hbs', {track: track, stats: stats});
    });
  });

  app.get('/stats.json', function(req, res) {
    getStats(function (stats) {
      res.json(stats);
    });
  });

  app.listen(3000);
}

function addTitle(score, callback) {
  db.hget(score.url, 'title', function(err, result) {
    score.title = result;
    callback(null, score);
  });
}

function addTweets(score, callback) {
  db.lrange('tweets:' + score.url, 0, -1, function (err, tweets) {
    async.mapSeries(tweets, addTweetInfo, function (err, results) {
      score.tweets = results;
      callback(null, score);
    });
  });
}

function addTweetInfo(tweetId, callback) {
  db.hgetall(tweetId, function (err, tweet) {
    callback(null, tweet);
  });
}

function listenForTweets() {
  console.log('listening for new tweets');
  var twtr = new Twitter({
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
  });
  twtr.stream('statuses/filter', {track: track}, function(stream) {
    stream.on('data', checkTweet);
    stream.on('error', function(error) {
      console.log(error);
    });
  });
}

function checkTweet(tweet) {
  console.log('processing tweet: ' + tweet.id_str);
  _.each(tweet.entities.urls, function(urlEntity) {
    var url = urlEntity.expanded_url;
    console.log('queueing lookup for ' + url);
    queue.push({url: url, tweet: tweet}, function (err) {
      if (! err) {
        console.log("finished processing url: " + url);
      } else {
        console.log("error while processing url: " + err);
      }
    });
  });
}

function lookupUrl(job, done) {
  console.log('looking up url: ' + job.url);
  request(job.url, function (error, response, body) {
    if (! error) {
      var $ = cheerio.load(body);
      addResource({
        url: response.request.uri.href,
        title: $("head title").text(),
        tweet: job.tweet
      });
      done();
      $ = null;
    } else {
      done(error);
    }
  });
}

function addResource(r) {
  var tweetId = 'tweet:' + r.tweet.id_str;
  var avatar = r.tweet.user.profile_image_url;
  var name = r.tweet.user.screen_name;
  var tweetUrl = "https://twitter.com/" + r.tweet.user.screen_name + "/statuses/" + r.tweet.id_str;

  console.log("tallying: ", r.url, r.title, name, tweetUrl);

  db.hset(r.url, "title", r.title);
  db.zincrby('urls', 1, r.url);
  db.lpush('tweets:' + r.url, tweetId);
  db.hset(tweetId, "url", tweetUrl)
  db.hset(tweetId, "name", name);
  db.hset(tweetId, "avatar", avatar);
}

function getStats(callback) {
  db.zrevrange('urls', 0, 100, 'withscores', function(err, results) {
    scores = [];
    for (var i = 0; i < results.length; i+=2) {
      scores.push({
        url: results[i],
        count: results[i + 1]
      });
    }
    async.mapSeries(scores, addTitle, function(err, results) {
      async.mapSeries(scores, addTweets, function(err, results) {
        callback(results);
      });
    });
  });
}

function loadExisting(filename) {
  var rd = readline.createInterface({
    input: fs.createReadStream(filename),
    output: process.stdout,
    terminal: false
  });
  rd.on('line', function(line) {
    var tweet = JSON.parse(line);
    checkTweet(tweet);
  });
}

if (require.main === module) {
  //loadExisting('tweets.json');
  main();
}
<commit_msg>can only look for titles in html<commit_after>#!/usr/bin/env node

// you might want to change this :)
var track = "#c4l15";

var fs = require('fs');
var http = require('http');
var path = require('path');
var async = require('async');
var redis = require('redis');
var _ = require('underscore');
var cheerio = require('cheerio');
var express = require('express');
var Twitter = require('twitter');
var request = require('request');
var sockio = require('socket.io');
var readline = require('readline');

var db = redis.createClient();
var queue = async.queue(lookupUrl, 1);

function main() {
  listenForTweets(track);
  runWeb();
}

function runWeb() {
  var app = express();
  var server = http.Server(app);
  var io = sockio(server);

  app.use(express.static('public'));
  app.enable('trust proxy');
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'hbs');

  app.get('/', function(req, res) {
    getStats(function (stats) {
      res.render('index.hbs', {track: track, stats: stats});
    });
  });

  app.get('/stats.json', function(req, res) {
    getStats(function (stats) {
      res.json(stats);
    });
  });

  app.listen(3000);
}

function addTitle(score, callback) {
  db.hget(score.url, 'title', function(err, result) {
    score.title = result;
    callback(null, score);
  });
}

function addTweets(score, callback) {
  db.lrange('tweets:' + score.url, 0, -1, function (err, tweets) {
    async.mapSeries(tweets, addTweetInfo, function (err, results) {
      score.tweets = results;
      callback(null, score);
    });
  });
}

function addTweetInfo(tweetId, callback) {
  db.hgetall(tweetId, function (err, tweet) {
    callback(null, tweet);
  });
}

function listenForTweets() {
  console.log('listening for new tweets');
  var twtr = new Twitter({
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
  });
  twtr.stream('statuses/filter', {track: track}, function(stream) {
    stream.on('data', checkTweet);
    stream.on('error', function(error) {
      console.log(error);
    });
  });
}

function checkTweet(tweet) {
  console.log('processing tweet: ' + tweet.id_str);
  _.each(tweet.entities.urls, function(urlEntity) {
    var url = urlEntity.expanded_url;
    console.log('queueing lookup for ' + url);
    queue.push({url: url, tweet: tweet}, function (err) {
      if (! err) {
        console.log("finished processing url: " + url);
      } else {
        console.log("error while processing url: " + err);
      }
    });
  });
}

function lookupUrl(job, done) {
  console.log('looking up url: ' + job.url);
  request(job.url, function (error, response, body) {
    if (! error) {
      var mimetype = response.headers['content-type'];
      if (mimetype && mimetype.match(/html/)) {
        var $ = cheerio.load(body);
        var title = $("head title").text();
      } else {
        var title = response.request.uri.href;
      }

      addResource({
        url: response.request.uri.href,
        title: title,
        tweet: job.tweet
      });
      done();
      $ = null;
    } else {
      done(error);
    }
  });
}

function addResource(r) {
  var tweetId = 'tweet:' + r.tweet.id_str;
  var avatar = r.tweet.user.profile_image_url;
  var name = r.tweet.user.screen_name;
  var tweetUrl = "https://twitter.com/" + r.tweet.user.screen_name + "/statuses/" + r.tweet.id_str;

  console.log("tallying: ", r.url, r.title, name, tweetUrl);

  db.hset(r.url, "title", r.title);
  db.zincrby('urls', 1, r.url);
  db.lpush('tweets:' + r.url, tweetId);
  db.hset(tweetId, "url", tweetUrl)
  db.hset(tweetId, "name", name);
  db.hset(tweetId, "avatar", avatar);
}

function getStats(callback) {
  db.zrevrange('urls', 0, 100, 'withscores', function(err, results) {
    scores = [];
    for (var i = 0; i < results.length; i+=2) {
      scores.push({
        url: results[i],
        count: results[i + 1]
      });
    }
    async.mapSeries(scores, addTitle, function(err, results) {
      async.mapSeries(scores, addTweets, function(err, results) {
        callback(results);
      });
    });
  });
}

function loadExisting(filename) {
  var rd = readline.createInterface({
    input: fs.createReadStream(filename),
    output: process.stdout,
    terminal: false
  });
  rd.on('line', function(line) {
    var tweet = JSON.parse(line);
    checkTweet(tweet);
  });
}

if (require.main === module) {
  //loadExisting('tweets.json');
  main();
}
<|endoftext|>


<commit_before>'use strict';

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const messagingManager = require('./src/messaging-manager');

const PORT = process.env.PORT || 5555;
const VALIDATION_TOKEN = process.env.POKEDEX_VALIDATION_TOKEN || '';

// body parser middleware
app.use(bodyParser.urlencoded({
	extended: true
}));

// base route
app.get('/', (req, res) => {
	res.status(200).send('works! 💪👌💯🙌');
});

app.get('/page-subscription', (req, res) => {
	if (req.query['hub.mode'] === 'subscribe' &&
			req.query['hub.verify_token'] === VALIDATION_TOKEN) {
		console.log('validating webhook');
		res.status(200).send(req.query['hub.challenge']);
	} else {
		console.log('failed validation.');
		res.sendStatus(403);
	}
});

app.post('/page-subscription', (req, res) => {
	const data = req.body;

	console.log(req.body);

	if (data.object === 'page') {
		data.entry.forEach(function(pageEntry) {
			var pageID = pageEntry.id;
			var timeOfEvent = pageEntry.time;

			// Iterate over each messaging event
			pageEntry.messaging.forEach((messagingEvent) => {
				if (messagingEvent.optin) {
					// receivedAuthentication(messagingEvent);
					console.log('receivedAuthentication');
				} else if (messagingEvent.message) {
					messagingManager.receivedMessage(messagingEvent);
				} else if (messagingEvent.delivery) {
					// receivedDeliveryConfirmation(messagingEvent);
					console.log('receivedDeliveryConfirmation');
				} else if (messagingEvent.postback) {
					// receivedPostback(messagingEvent);
					console.log('receivedPostback');
				} else {
					console.log(`Webhook received unknown messagingEvent: ${messagingEvent}`);
				}
			});
		});

		// Assume all went well.
		res.sendStatus(200);
	} else {
		res.sendStatus(400);
	}
});

app.listen(PORT, () => {
    console.log('listening on port', PORT);
});
<commit_msg>changed to /webhook<commit_after>'use strict';

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const messagingManager = require('./src/messaging-manager');

const PORT = process.env.PORT || 5555;
const VALIDATION_TOKEN = process.env.POKEDEX_VALIDATION_TOKEN || '';

// body parser middleware
app.use(bodyParser.urlencoded({
	extended: true
}));

// base route
app.get('/', (req, res) => {
	res.status(200).send('works! 💪👌💯🙌');
});

app.get('/page-subscription', (req, res) => {
	if (req.query['hub.mode'] === 'subscribe' &&
			req.query['hub.verify_token'] === VALIDATION_TOKEN) {
		console.log('validating webhook');
		res.status(200).send(req.query['hub.challenge']);
	} else {
		console.log('failed validation.');
		res.sendStatus(403);
	}
});

app.post('/webhook', (req, res) => {
	const data = req.body;

	console.log(req.body);

	if (data.object === 'page') {
		data.entry.forEach(function(pageEntry) {
			var pageID = pageEntry.id;
			var timeOfEvent = pageEntry.time;

			// Iterate over each messaging event
			pageEntry.messaging.forEach((messagingEvent) => {
				if (messagingEvent.optin) {
					// receivedAuthentication(messagingEvent);
					console.log('receivedAuthentication');
				} else if (messagingEvent.message) {
					messagingManager.receivedMessage(messagingEvent);
				} else if (messagingEvent.delivery) {
					// receivedDeliveryConfirmation(messagingEvent);
					console.log('receivedDeliveryConfirmation');
				} else if (messagingEvent.postback) {
					// receivedPostback(messagingEvent);
					console.log('receivedPostback');
				} else {
					console.log(`Webhook received unknown messagingEvent: ${messagingEvent}`);
				}
			});
		});

		// Assume all went well.
		res.sendStatus(200);
	} else {
		res.sendStatus(400);
	}
});

app.listen(PORT, () => {
    console.log('listening on port', PORT);
});
<|endoftext|>


<commit_before>var fs = require('fs')
  , express = module.exports = require('express')
  , path = require('path')
  , hogan = require('hogan.js')
  , soynode = require('soynode')
  , klass = global.klass = require('klass')
  , v = global.v = require('valentine')
  , router = require('./router')
  , argv = module.exports.argv = require('optimist').argv
  , minifyViews = process.env.minify || false
  , paths = {
      SERVICES: 'services'
    , HELPERS: 'helpers'
    , MODELS: 'models'
    , CONTROLLERS: 'controllers'
  }
  , filenameSuffixes = {
      SERVICES: 'Service'
    , HELPERS: 'Helper'
    , MODELS: 'Model'
    , CONTROLLERS: 'Controller'
  }

var minify = function () {
  var r = /(<script[^>]*>[\s\S]+?<\/script>)/
    , scr = /^<script([^>]*)>([\s\S]+?)<\/script>/
    , white = /\s+/g
    , closeTags = />\s+</g
    , jsp = require('uglify-js').parser
    , pro = require('uglify-js').uglify
    , uglify = function (src) {
        try {
          var ast = jsp.parse(src)
          ast = pro.ast_squeeze(ast)
          return pro.gen_code(ast)
        }
        catch (ex) {
          return src
        }
      }
  return function (doc) {
    if (!minifyViews) return doc
    return doc.trim().replace(/ +/g, ' ').split(r).map(function (p, i, m) {
      return (m = p.match(scr)) ? '<script' + m[1] + '>' + uglify(m[2]) + '</script>' : p.replace(white, ' ')
    }).join('').replace(closeTags, '><')
  }
}()

function isDirectory(p) {
  try {
    return fs.statSync(p).isDirectory()
  }
  catch (ex) {
    return false
  }
}

module.exports.createApp = function (baseDir, configuration, options) {
  configuration = configuration || {}
  options = options || {}

  var appDir = path.join(baseDir, '/app')
    , fileCache = {}
    , objCache = {}
    , pathCache = {}
    , updateCaches = v(paths).each(function (key, val) {
        fileCache[val] = {}
        objCache[val] = {}
        pathCache[val] = {}
      })
    , partialCache = {}
    , listingCache = {}
    , appDirs = [appDir].concat(v(function () {
        var dir = appDir + '/modules'
        return path.existsSync(dir) ? fs.readdirSync(dir) : []
      }()).map(function (dir) {
        return appDir + '/modules/' + dir
      }))
    , app = express.createServer()
    , fileExists = function (filename) {
        // We check for file existence this way so that our lookups are case sensitive regardless of the underlying filesystem.
        var dir = path.dirname(filename)
          , base = path.basename(filename)
        if (!listingCache[dir]) listingCache[dir] = path.existsSync(dir) ? fs.readdirSync(dir) : []
        return listingCache[dir].indexOf(base) !== -1
      }
    , loadFile = function (subdir, name, p) {
        if (typeof(fileCache[subdir][name]) !== 'undefined') return fileCache[subdir][name]
        var pathname = name.replace(/\./g, '/')
        var dir = v.find((p ? [p] : appDirs), function (dir) {
          var filename = dir + '/' + subdir + '/' + pathname + '.js'
          if (!fileExists(filename)) return false
          fileCache[subdir][name] = require(filename)(app, (configuration[subdir] && configuration[subdir][name] ? configuration[subdir][name] : {}))
          pathCache[subdir][name] = dir === appDir ? [appDir] : [dir, appDir]
          return true
        })
        if (!dir) throw new Error('Unable to find ' + subdir + '/' + pathname)

        return fileCache[subdir][name]
      }
    , loadClass = function (subdir, name, localName, definitionOnly) {
        if (definitionOnly) return loadFile(subdir, name)
        if (!objCache[subdir][name]) {
          var File = loadFile(subdir, name)
          objCache[subdir][name] = new File(localName, pathCache[subdir][name])
          objCache[subdir][name]._paths = pathCache[subdir][name]

          if (subdir === paths.MODELS) app.emit('createModel', localName, objCache[subdir][name])
          else if (subdir === paths.SERVICES) app.emit('createService', localName, objCache[subdir][name])
          else if (subdir === paths.CONTROLLERS) app.emit('createController', localName, objCache[subdir][name])
          //not emitting an event for helpers here as we never actually instantiate a helper
        }
        return objCache[subdir][name]
      }
    , mountPublicDir = function (dir) {
      var directory = dir + '/public'
      fileExists(directory) && app.use(express.static(directory))
    }

  app.set('base_dir', appDir)
  app.set('public', appDir + '/public')
  v(appDirs).each(mountPublicDir)

  app.controllers = {
    Base: require('./BaseController')(app)
  }

  app.addModulePath = function (dir) {
    appDirs.push(dir)
    mountPublicDir(dir)
  }

  app.getModulePaths = function () {
    return appDirs
  }

  app.mount = function () {
    var router = require('./router')
      , self = this

    v.each(appDirs, function (dir) {
      var filename = dir + '/config/routes.js'
      if (!fileExists(filename)) return
      router.init(self, require(filename)(self))
    })
    // static directory server

    router.init(this, {
      root: [['get', /(.+)/, 'Static']]
    })
  }

  app.prefetch = function (options) {
    var self = this

    v(paths).each(function (key, type) {
      v.each(appDirs, function (dir) {
        var d = dir + '/' + type
        if (!isDirectory(d)) return
        v.each(fs.readdirSync(d), function (file) {
          if (isDirectory(d + "/" + file)) return
          if (file.charAt(0) == '.') return
          if (file.substr(file.length - 3) === '.js') file = file.substr(0, file.length - 3)
          loadFile(type, file, dir)
        })
      })
    })

    var soyOptions = {
      allowDynamicRecompile: app.enabled('soy allowDynamicRecompile')
    }
    soynode.setOptions(soyOptions)

    // Precompile all Closure templates.
    v.each(appDirs, function (dir) {
      dir = dir + '/views'
      if (!isDirectory(dir)) return

      soynode.compileTemplates(d, function (err) {
        if (err) {
          throw err
        }
      })
    })
  }

  /**
   * Finds all partial templates relative to the provided view directory, stopping once the root
   * directory has been reached.
   *
   * All templates are added from the /partials/ folder within the current view directory.  We then
   * move to the parent directory and add any partials from it's /partials/ folder that don't conflict
   * with ones already added. We then move to the next parent directory and so on until we reach the
   * application root.
   *
   * This allows views to use common templates, and be able to override sub-templates.
   *
   * Example: consider the following directory structure:
   *   app/
   *       views/
   *           partials/
   *               user-details.html  - contains {{> user-link}})
   *               user-link.html
   *           search/
   *               results.html - contains {{> user-details}}
   *               partials/
   *                   user-link.html
   *           post/
   *               post.html  - contains {{> user-details}}
   *
   * The partials for app/views/search will contain:
   *   app/views/search/partial/user-link.html
   *   app/views/partial/user-details.html
   *
   * The partials for app/views/post will only contain app/views/partials/%
   *
   *
   * TODO: This uses synchronous filesystem APIs. It should either be performed at start up
   * for all controllers or else switched to use async APIs.
   */
  app.getPartials = function (viewDir) {
    var rootDir = app.set('base_dir')
    var viewSuffix = '.' + app.set('view engine')

    if (!partialCache[viewDir]) {

      if (path.relative(rootDir, viewDir).indexOf('../') != -1) {
        throw new Error('View directories must live beneath the application root.')
      }

      var partials = {}
      while (viewDir != rootDir) {
        var partialDir = path.resolve(viewDir, 'partials')
        try {
          fs.readdirSync(partialDir).forEach(function (file) {
            // Ignore hidden files and files that don't have the right extension.
            if (file.charAt(0) == '.') return
            if (file.substr(-viewSuffix.length) != viewSuffix) return

            // Remove the suffix, such that /partials/something.html can be used as {{> something}}
            var partialName = file.substr(0, file.length - viewSuffix.length)

            // If the map already contains this partial it means it has already been specified higher
            // up the view hierarchy.
            if (!partials[partialName]) {
              var partialFilename = path.resolve(partialDir, file)
              try {
                var partialContent = fs.readFileSync(partialFilename, 'utf8')
                partials[partialName] = hogan.compile(minify(partialContent))
              } catch (e) {
                console.log('Unable to compile partial', partialFilename, e)
              }
            }
          })
        } catch (e) {
          // Only log errors if they are not a "no such file or directory" error, since we expect
          // those to happen. (Saves us an fs.statSync.)
          if (e.code != 'ENOENT') console.log('Unable to read partials directory', partialDir, e)
        }
        viewDir = path.resolve(viewDir, '../')
      }
      partialCache[viewDir] = partials
    }

    // Note: This does more work than is necessary, since common parents of views will
    // be hit once for each view. If this turns out to be problematic we can cache at
    // intermediate folders as well.

    return partialCache[viewDir]
  }

  /**
   * Get a service instance or class
   *
   * @param {String} name the name of the service
   * @param {Boolean} definitionOnly whether to just grab the class or to grab an actual
   *     instance
   * @return {Object} a service class or instance
   */
  app.getService = function (name, definitionOnly) {
    return loadClass(paths.SERVICES, name + filenameSuffixes.SERVICES, name, definitionOnly)
  }

  /**
   * Get a controller instance or class
   *
   * @param {String} name the name of the controller
   * @param {Boolean} definitionOnly whether to just grab the class or to grab an actual
   *     instance
   * @return {Object} a controller class or instance
   */
  app.getController = function (name, definitionOnly) {
    if (app.controllers[name]) {
      return definitionOnly ? app.controllers[name] : new app.controllers[name](name, [])
    }
    else {
      return loadClass(paths.CONTROLLERS, name + filenameSuffixes.CONTROLLERS, name, definitionOnly)
    }
  }

  /**
   * Get a model instance or class
   *
   * @param {String} name the name of the model
   * @param {Boolean} definitionOnly whether to just grab the class or to grab an actual
   *     instance
   * @return {Object} a model class or instance
   */
  app.getModel = function (name, definitionOnly) {
    return loadClass(paths.MODELS, name + filenameSuffixes.MODELS, name, definitionOnly)
  }

  /**
   * Get a helper
   *
   * @param {String} name of the helper
   * @return {Object} a helper instance
   */
  app.getHelper = function (name) {
    return loadFile(paths.HELPERS, name + filenameSuffixes.HELPERS)
  }

  /**
   * Override the existing cached version of a service
   *
   * @param {String} name the name of the service
   * @param {Object} instance the service instance
   */
  app.setService = function (name, instance) {
    objCache[paths.SERVICES][name + filenameSuffixes.SERVICES] = instance
  }

  /**
   * Override the existing cached version of a controller
   *
   * @param {String} name the name of the controller
   * @param {Object} instance the controller instance
   */
  app.setController = function (name, instance) {
    objCache[paths.CONTROLLERS][name + filenameSuffixes.CONTROLLERS] = instance
  }

  /**
   * Override the existing cached version of a model
   *
   * @param {String} name the name of the model
   * @param {Object} instance the model instance
   */
  app.setModel = function (name, instance) {
    objCache[paths.MODELS][name + filenameSuffixes.MODELS] = instance
  }

  app.controllers.Static = require('./StaticController')(app)

  return app
}

module.exports.engine = {
  compile: function (source, options) {
    if (typeof source !== 'string') return source
    source = minify(source)
    return function (options) {
      options.locals = options.locals || {}
      options.partials = options.partials || {}
      if (options.body) options.locals.body = options.body
      for (var i in options.partials) {
        if (v.is.fun(options.partials[i].r)) continue
        try {
          options.partials[i] = hogan.compile(options.partials[i])
        } catch (e) {
          console.log("Unable to compile partial", i, e)
        }
      }
      return hogan.compile(source, options).render(options.locals, options.partials)
    }
  }
}
<commit_msg>fixed compile error<commit_after>var fs = require('fs')
  , express = module.exports = require('express')
  , path = require('path')
  , hogan = require('hogan.js')
  , soynode = require('soynode')
  , klass = global.klass = require('klass')
  , v = global.v = require('valentine')
  , router = require('./router')
  , argv = module.exports.argv = require('optimist').argv
  , minifyViews = process.env.minify || false
  , paths = {
      SERVICES: 'services'
    , HELPERS: 'helpers'
    , MODELS: 'models'
    , CONTROLLERS: 'controllers'
  }
  , filenameSuffixes = {
      SERVICES: 'Service'
    , HELPERS: 'Helper'
    , MODELS: 'Model'
    , CONTROLLERS: 'Controller'
  }

var minify = function () {
  var r = /(<script[^>]*>[\s\S]+?<\/script>)/
    , scr = /^<script([^>]*)>([\s\S]+?)<\/script>/
    , white = /\s+/g
    , closeTags = />\s+</g
    , jsp = require('uglify-js').parser
    , pro = require('uglify-js').uglify
    , uglify = function (src) {
        try {
          var ast = jsp.parse(src)
          ast = pro.ast_squeeze(ast)
          return pro.gen_code(ast)
        }
        catch (ex) {
          return src
        }
      }
  return function (doc) {
    if (!minifyViews) return doc
    return doc.trim().replace(/ +/g, ' ').split(r).map(function (p, i, m) {
      return (m = p.match(scr)) ? '<script' + m[1] + '>' + uglify(m[2]) + '</script>' : p.replace(white, ' ')
    }).join('').replace(closeTags, '><')
  }
}()

function isDirectory(p) {
  try {
    return fs.statSync(p).isDirectory()
  }
  catch (ex) {
    return false
  }
}

module.exports.createApp = function (baseDir, configuration, options) {
  configuration = configuration || {}
  options = options || {}

  var appDir = path.join(baseDir, '/app')
    , fileCache = {}
    , objCache = {}
    , pathCache = {}
    , updateCaches = v(paths).each(function (key, val) {
        fileCache[val] = {}
        objCache[val] = {}
        pathCache[val] = {}
      })
    , partialCache = {}
    , listingCache = {}
    , appDirs = [appDir].concat(v(function () {
        var dir = appDir + '/modules'
        return path.existsSync(dir) ? fs.readdirSync(dir) : []
      }()).map(function (dir) {
        return appDir + '/modules/' + dir
      }))
    , app = express.createServer()
    , fileExists = function (filename) {
        // We check for file existence this way so that our lookups are case sensitive regardless of the underlying filesystem.
        var dir = path.dirname(filename)
          , base = path.basename(filename)
        if (!listingCache[dir]) listingCache[dir] = path.existsSync(dir) ? fs.readdirSync(dir) : []
        return listingCache[dir].indexOf(base) !== -1
      }
    , loadFile = function (subdir, name, p) {
        if (typeof(fileCache[subdir][name]) !== 'undefined') return fileCache[subdir][name]
        var pathname = name.replace(/\./g, '/')
        var dir = v.find((p ? [p] : appDirs), function (dir) {
          var filename = dir + '/' + subdir + '/' + pathname + '.js'
          if (!fileExists(filename)) return false
          fileCache[subdir][name] = require(filename)(app, (configuration[subdir] && configuration[subdir][name] ? configuration[subdir][name] : {}))
          pathCache[subdir][name] = dir === appDir ? [appDir] : [dir, appDir]
          return true
        })
        if (!dir) throw new Error('Unable to find ' + subdir + '/' + pathname)

        return fileCache[subdir][name]
      }
    , loadClass = function (subdir, name, localName, definitionOnly) {
        if (definitionOnly) return loadFile(subdir, name)
        if (!objCache[subdir][name]) {
          var File = loadFile(subdir, name)
          objCache[subdir][name] = new File(localName, pathCache[subdir][name])
          objCache[subdir][name]._paths = pathCache[subdir][name]

          if (subdir === paths.MODELS) app.emit('createModel', localName, objCache[subdir][name])
          else if (subdir === paths.SERVICES) app.emit('createService', localName, objCache[subdir][name])
          else if (subdir === paths.CONTROLLERS) app.emit('createController', localName, objCache[subdir][name])
          //not emitting an event for helpers here as we never actually instantiate a helper
        }
        return objCache[subdir][name]
      }
    , mountPublicDir = function (dir) {
      var directory = dir + '/public'
      fileExists(directory) && app.use(express.static(directory))
    }

  app.set('base_dir', appDir)
  app.set('public', appDir + '/public')
  v(appDirs).each(mountPublicDir)

  app.controllers = {
    Base: require('./BaseController')(app)
  }

  app.addModulePath = function (dir) {
    appDirs.push(dir)
    mountPublicDir(dir)
  }

  app.getModulePaths = function () {
    return appDirs
  }

  app.mount = function () {
    var router = require('./router')
      , self = this

    v.each(appDirs, function (dir) {
      var filename = dir + '/config/routes.js'
      if (!fileExists(filename)) return
      router.init(self, require(filename)(self))
    })
    // static directory server

    router.init(this, {
      root: [['get', /(.+)/, 'Static']]
    })
  }

  app.prefetch = function (options) {
    var self = this

    v(paths).each(function (key, type) {
      v.each(appDirs, function (dir) {
        var d = dir + '/' + type
        if (!isDirectory(d)) return
        v.each(fs.readdirSync(d), function (file) {
          if (isDirectory(d + "/" + file)) return
          if (file.charAt(0) == '.') return
          if (file.substr(file.length - 3) === '.js') file = file.substr(0, file.length - 3)
          loadFile(type, file, dir)
        })
      })
    })

    var soyOptions = {
      allowDynamicRecompile: app.enabled('soy allowDynamicRecompile')
    }
    soynode.setOptions(soyOptions)

    // Precompile all Closure templates.
    v.each(appDirs, function (dir) {
      dir = dir + '/views'
      if (!isDirectory(dir)) return

      soynode.compileTemplates(dir, function (err) {
        if (err) {
          throw err
        }
      })
    })
  }

  /**
   * Finds all partial templates relative to the provided view directory, stopping once the root
   * directory has been reached.
   *
   * All templates are added from the /partials/ folder within the current view directory.  We then
   * move to the parent directory and add any partials from it's /partials/ folder that don't conflict
   * with ones already added. We then move to the next parent directory and so on until we reach the
   * application root.
   *
   * This allows views to use common templates, and be able to override sub-templates.
   *
   * Example: consider the following directory structure:
   *   app/
   *       views/
   *           partials/
   *               user-details.html  - contains {{> user-link}})
   *               user-link.html
   *           search/
   *               results.html - contains {{> user-details}}
   *               partials/
   *                   user-link.html
   *           post/
   *               post.html  - contains {{> user-details}}
   *
   * The partials for app/views/search will contain:
   *   app/views/search/partial/user-link.html
   *   app/views/partial/user-details.html
   *
   * The partials for app/views/post will only contain app/views/partials/%
   *
   *
   * TODO: This uses synchronous filesystem APIs. It should either be performed at start up
   * for all controllers or else switched to use async APIs.
   */
  app.getPartials = function (viewDir) {
    var rootDir = app.set('base_dir')
    var viewSuffix = '.' + app.set('view engine')

    if (!partialCache[viewDir]) {

      if (path.relative(rootDir, viewDir).indexOf('../') != -1) {
        throw new Error('View directories must live beneath the application root.')
      }

      var partials = {}
      while (viewDir != rootDir) {
        var partialDir = path.resolve(viewDir, 'partials')
        try {
          fs.readdirSync(partialDir).forEach(function (file) {
            // Ignore hidden files and files that don't have the right extension.
            if (file.charAt(0) == '.') return
            if (file.substr(-viewSuffix.length) != viewSuffix) return

            // Remove the suffix, such that /partials/something.html can be used as {{> something}}
            var partialName = file.substr(0, file.length - viewSuffix.length)

            // If the map already contains this partial it means it has already been specified higher
            // up the view hierarchy.
            if (!partials[partialName]) {
              var partialFilename = path.resolve(partialDir, file)
              try {
                var partialContent = fs.readFileSync(partialFilename, 'utf8')
                partials[partialName] = hogan.compile(minify(partialContent))
              } catch (e) {
                console.log('Unable to compile partial', partialFilename, e)
              }
            }
          })
        } catch (e) {
          // Only log errors if they are not a "no such file or directory" error, since we expect
          // those to happen. (Saves us an fs.statSync.)
          if (e.code != 'ENOENT') console.log('Unable to read partials directory', partialDir, e)
        }
        viewDir = path.resolve(viewDir, '../')
      }
      partialCache[viewDir] = partials
    }

    // Note: This does more work than is necessary, since common parents of views will
    // be hit once for each view. If this turns out to be problematic we can cache at
    // intermediate folders as well.

    return partialCache[viewDir]
  }

  /**
   * Get a service instance or class
   *
   * @param {String} name the name of the service
   * @param {Boolean} definitionOnly whether to just grab the class or to grab an actual
   *     instance
   * @return {Object} a service class or instance
   */
  app.getService = function (name, definitionOnly) {
    return loadClass(paths.SERVICES, name + filenameSuffixes.SERVICES, name, definitionOnly)
  }

  /**
   * Get a controller instance or class
   *
   * @param {String} name the name of the controller
   * @param {Boolean} definitionOnly whether to just grab the class or to grab an actual
   *     instance
   * @return {Object} a controller class or instance
   */
  app.getController = function (name, definitionOnly) {
    if (app.controllers[name]) {
      return definitionOnly ? app.controllers[name] : new app.controllers[name](name, [])
    }
    else {
      return loadClass(paths.CONTROLLERS, name + filenameSuffixes.CONTROLLERS, name, definitionOnly)
    }
  }

  /**
   * Get a model instance or class
   *
   * @param {String} name the name of the model
   * @param {Boolean} definitionOnly whether to just grab the class or to grab an actual
   *     instance
   * @return {Object} a model class or instance
   */
  app.getModel = function (name, definitionOnly) {
    return loadClass(paths.MODELS, name + filenameSuffixes.MODELS, name, definitionOnly)
  }

  /**
   * Get a helper
   *
   * @param {String} name of the helper
   * @return {Object} a helper instance
   */
  app.getHelper = function (name) {
    return loadFile(paths.HELPERS, name + filenameSuffixes.HELPERS)
  }

  /**
   * Override the existing cached version of a service
   *
   * @param {String} name the name of the service
   * @param {Object} instance the service instance
   */
  app.setService = function (name, instance) {
    objCache[paths.SERVICES][name + filenameSuffixes.SERVICES] = instance
  }

  /**
   * Override the existing cached version of a controller
   *
   * @param {String} name the name of the controller
   * @param {Object} instance the controller instance
   */
  app.setController = function (name, instance) {
    objCache[paths.CONTROLLERS][name + filenameSuffixes.CONTROLLERS] = instance
  }

  /**
   * Override the existing cached version of a model
   *
   * @param {String} name the name of the model
   * @param {Object} instance the model instance
   */
  app.setModel = function (name, instance) {
    objCache[paths.MODELS][name + filenameSuffixes.MODELS] = instance
  }

  app.controllers.Static = require('./StaticController')(app)

  return app
}

module.exports.engine = {
  compile: function (source, options) {
    if (typeof source !== 'string') return source
    source = minify(source)
    return function (options) {
      options.locals = options.locals || {}
      options.partials = options.partials || {}
      if (options.body) options.locals.body = options.body
      for (var i in options.partials) {
        if (v.is.fun(options.partials[i].r)) continue
        try {
          options.partials[i] = hogan.compile(options.partials[i])
        } catch (e) {
          console.log("Unable to compile partial", i, e)
        }
      }
      return hogan.compile(source, options).render(options.locals, options.partials)
    }
  }
}
<|endoftext|>


<commit_before>var expect, formatter;

if (typeof module !== 'undefined') {
  expect = require('expect.js');
  formatter = require('../').formatter_;
} else {
  expect = this.expect;
  formatter = this.ltsv.formatter_;
}

describe('formatter', function() {

  describe('#format()', function() {

    it('should generate LTSV from object', function() {
      expect(
          formatter.format({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should generate LTSV from object in array', function() {
      expect(
          formatter.format([
            { l1: 'v1', l2: 'v2' },
            { l3: 'v3', l4: 'v4' }
          ])
      ).to.be('l1:v1\tl2:v2\nl3:v3\tl4:v4');
    });

    it('should throw error if parameter is not an object or array', function() {
      function f(v) {
        return function() {
          formatter.format(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

  });

  describe('#formatStrict()', function() {

    it('should generate LTSV from object', function() {
      expect(
          formatter.formatStrict({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should generate LTSV from object in array', function() {
      expect(
          formatter.formatStrict([
            { l1: 'v1', l2: 'v2' },
            { l3: 'v3', l4: 'v4' }
          ])
      ).to.be('l1:v1\tl2:v2\nl3:v3\tl4:v4');
    });

    it('should throw error if parameter is not an object or array', function() {
      function f(v) {
        return function() {
          formatter.formatStrict(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

  });

  describe('#objectToRecord_()', function() {

    it('should generate record from object', function() {
      expect(
          formatter.objectToRecord_({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should generate record if label has unexpected character', function() {
      expect(
          formatter.objectToRecord_({
            '\x00\x2C': ''
          })
      ).to.be('\x00\x2C:');

      expect(
          formatter.objectToRecord_({
            '\x2F': ''
          })
      ).to.be('\x2F:');

      // \x3A is ":"
      expect(
          formatter.objectToRecord_({
            '\x3B\x40': ''
          })
      ).to.be('\x3B\x40:');

      expect(
          formatter.objectToRecord_({
            '\x5B\x5E': ''
          })
      ).to.be('\x5B\x5E:');

      expect(
          formatter.objectToRecord_({
            '\x60': ''
          })
      ).to.be('\x60:');

      expect(
          formatter.objectToRecord_({
            '\x7B\xFF': ''
          })
      ).to.be('\x7B\xFF:');
    });

    it('should generate record if value has unexpected character', function() {
      expect(
          formatter.objectToRecord_({
            label: '\x00\x09\x0A\x0D'
          })
      ).to.be('label:\x00\x09\x0A\x0D');
    });

    it('should throw error if parameter is not an object', function() {
      function f(v) {
        return function() {
          formatter.objectToRecord_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

  });

  describe('#objectToRecordStrict_()', function() {

    it('should generate record from object', function() {
      expect(
          formatter.objectToRecordStrict_({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should throw error if parameter is not an object', function() {
      function f(v) {
        return function() {
          formatter.objectToRecordStrict_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

    it('should throw error if label has unexpected character', function() {
      function f(v) {
        return function() {
          formatter.objectToRecordStrict_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(SyntaxError);
      }

      expect(f({ '\x00\x2C': '' })).to.throwError(fn);
      expect(f({ '\x2F': '' })).to.throwError(fn);
      expect(f({ '\x3B\x40': '' })).to.throwError(fn);
      expect(f({ '\x5B\x5E': '' })).to.throwError(fn);
      expect(f({ '\x60': '' })).to.throwError(fn);
      expect(f({ '\x7B\xFF': '' })).to.throwError(fn);
    });

    it('should throw error if value has unexpected character', function() {
      function f(v) {
        return function() {
          formatter.objectToRecordStrict_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(SyntaxError);
      }

      expect(f({ label: '\x00' })).to.throwError(fn);
      expect(f({ label: '\x09' })).to.throwError(fn);
      expect(f({ label: '\x0A' })).to.throwError(fn);
      expect(f({ label: '\x0D' })).to.throwError(fn);
    });

  });

  describe('#getType_()', function() {

    it('should return typeof value', function() {
      expect(formatter.getType_(1)).to.be('number');
      expect(formatter.getType_('a')).to.be('string');
      expect(formatter.getType_(true)).to.be('boolean');
      expect(formatter.getType_(void 0)).to.be('undefined');
      expect(formatter.getType_(function() {})).to.be('function');
      expect(formatter.getType_({})).to.be('object');
    });

    it('should return "null" if parameter is null', function() {
      expect(formatter.getType_(null)).to.be('null');
    });

  });

});
<commit_msg>appended unit test of getObjectKeys_<commit_after>var expect, formatter;

if (typeof module !== 'undefined') {
  expect = require('expect.js');
  formatter = require('../').formatter_;
} else {
  expect = this.expect;
  formatter = this.ltsv.formatter_;
}

describe('formatter', function() {

  describe('#format()', function() {

    it('should generate LTSV from object', function() {
      expect(
          formatter.format({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should generate LTSV from object in array', function() {
      expect(
          formatter.format([
            { l1: 'v1', l2: 'v2' },
            { l3: 'v3', l4: 'v4' }
          ])
      ).to.be('l1:v1\tl2:v2\nl3:v3\tl4:v4');
    });

    it('should throw error if parameter is not an object or array', function() {
      function f(v) {
        return function() {
          formatter.format(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

  });

  describe('#formatStrict()', function() {

    it('should generate LTSV from object', function() {
      expect(
          formatter.formatStrict({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should generate LTSV from object in array', function() {
      expect(
          formatter.formatStrict([
            { l1: 'v1', l2: 'v2' },
            { l3: 'v3', l4: 'v4' }
          ])
      ).to.be('l1:v1\tl2:v2\nl3:v3\tl4:v4');
    });

    it('should throw error if parameter is not an object or array', function() {
      function f(v) {
        return function() {
          formatter.formatStrict(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

  });

  describe('#objectToRecord_()', function() {

    it('should generate record from object', function() {
      expect(
          formatter.objectToRecord_({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should generate record if label has unexpected character', function() {
      expect(
          formatter.objectToRecord_({
            '\x00\x2C': ''
          })
      ).to.be('\x00\x2C:');

      expect(
          formatter.objectToRecord_({
            '\x2F': ''
          })
      ).to.be('\x2F:');

      // \x3A is ":"
      expect(
          formatter.objectToRecord_({
            '\x3B\x40': ''
          })
      ).to.be('\x3B\x40:');

      expect(
          formatter.objectToRecord_({
            '\x5B\x5E': ''
          })
      ).to.be('\x5B\x5E:');

      expect(
          formatter.objectToRecord_({
            '\x60': ''
          })
      ).to.be('\x60:');

      expect(
          formatter.objectToRecord_({
            '\x7B\xFF': ''
          })
      ).to.be('\x7B\xFF:');
    });

    it('should generate record if value has unexpected character', function() {
      expect(
          formatter.objectToRecord_({
            label: '\x00\x09\x0A\x0D'
          })
      ).to.be('label:\x00\x09\x0A\x0D');
    });

    it('should throw error if parameter is not an object', function() {
      function f(v) {
        return function() {
          formatter.objectToRecord_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

  });

  describe('#objectToRecordStrict_()', function() {

    it('should generate record from object', function() {
      expect(
          formatter.objectToRecordStrict_({
            label1: 'value1',
            label2: 'value2'
          })
      ).to.be('label1:value1\tlabel2:value2');
    });

    it('should throw error if parameter is not an object', function() {
      function f(v) {
        return function() {
          formatter.objectToRecordStrict_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

    it('should throw error if label has unexpected character', function() {
      function f(v) {
        return function() {
          formatter.objectToRecordStrict_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(SyntaxError);
      }

      expect(f({ '\x00\x2C': '' })).to.throwError(fn);
      expect(f({ '\x2F': '' })).to.throwError(fn);
      expect(f({ '\x3B\x40': '' })).to.throwError(fn);
      expect(f({ '\x5B\x5E': '' })).to.throwError(fn);
      expect(f({ '\x60': '' })).to.throwError(fn);
      expect(f({ '\x7B\xFF': '' })).to.throwError(fn);
    });

    it('should throw error if value has unexpected character', function() {
      function f(v) {
        return function() {
          formatter.objectToRecordStrict_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(SyntaxError);
      }

      expect(f({ label: '\x00' })).to.throwError(fn);
      expect(f({ label: '\x09' })).to.throwError(fn);
      expect(f({ label: '\x0A' })).to.throwError(fn);
      expect(f({ label: '\x0D' })).to.throwError(fn);
    });

  });

  describe('#getType_()', function() {

    it('should return typeof value', function() {
      expect(formatter.getType_(1)).to.be('number');
      expect(formatter.getType_('a')).to.be('string');
      expect(formatter.getType_(true)).to.be('boolean');
      expect(formatter.getType_(void 0)).to.be('undefined');
      expect(formatter.getType_(function() {})).to.be('function');
      expect(formatter.getType_({})).to.be('object');
    });

    it('should return "null" if parameter is null', function() {
      expect(formatter.getType_(null)).to.be('null');
    });

  });

  describe('#getObjectKeys_()', function() {

    it('should throw error if parameter is not an Object', function() {
      function f(v) {
        return function() {
          formatter.getObjectKeys_(v);
        };
      }

      function fn(e) {
        expect(e).to.be.a(TypeError);
      }

      expect(f(1)).to.throwError(fn);
      expect(f('a')).to.throwError(fn);
      expect(f(true)).to.throwError(fn);
      expect(f(null)).to.throwError(fn);
      expect(f(void 0)).to.throwError(fn);
      expect(f(function() {})).to.throwError(fn);
    });

    it('should return array in parameter\'s keys', function() {
      expect(
          formatter.getObjectKeys_({
            i: 1, ro: 'ro', ha: true
          })
      ).to.eql([
          'i', 'ro', 'ha'
      ]);
    });

  });

});
<|endoftext|>


<commit_before>describe('ax5.info TEST', function() {

    it('ax5.info.eventKeys expect {BACKSPACE: 8, ...}', function() {
        var expect = {
            "BACKSPACE": 8,
            "TAB": 9,
            "RETURN": 13,
            "ESC": 27,
            "LEFT": 37,
            "UP": 38,
            "RIGHT": 39,
            "DOWN": 40,
            "DELETE": 46,
            "HOME": 36,
            "END": 35,
            "PAGEUP": 33,
            "PAGEDOWN": 34,
            "INSERT": 45,
            "SPACE": 32
        };
        should.deepEqual(ax5.info.eventKeys, expect);
    });

    it('ax5.info.browser expect {name: "xxx", version: "xx", mobile: Boolean}', function() {
        should.deepEqual(Object.keys(ax5.info.browser), ["name", "version", "mobile"]);
    });

    it('ax5.info.urlUtil() expect ["href", "param", ...]', function() {
        should.deepEqual(Object.keys(ax5.info.urlUtil()), ["href", "param", "referrer", "pathname", "hostname", "port", "url", "baseUrl"]);
    });

    it('ax5.info.errorMsg.ax5dialog["501"] expect "Duplicate call error"', function() {
        should.equal(ax5.info.errorMsg.ax5dialog["501"], 'Duplicate call error');
    });

    it('ax5.info.isBrowser expect true', function() {
        should(ax5.info.isBrowser).Boolean();
    });

    it('ax5.info.wheelEnm expect "mousewheel"', function() {
        should.equal(ax5.info.wheelEnm === "mousewheel" || ax5.info.wheelEnm === "DOMMouseScroll", true);
    });

    it('ax5.info.weekNames expect [{label: "SUN"},{label: "MON"}...]', function() {
        var expect = [
            { "label": "SUN" },
            { "label": "MON" },
            { "label": "TUE" },
            { "label": "WED" },
            { "label": "THU" },
            { "label": "FRI" },
            { "label": "SAT" }
        ];
        should.deepEqual(ax5.info.weekNames, expect);
    });

    it('ax5.info.supportTouch expect Boolean', function() {
        should(ax5.info.supportTouch).Boolean();
    });

    it('ax5.info.getError', function (done) {
        var expect = {
            className: "ax5dialog",
            errorCode: "501",
            methodName: "methodName",
            msg: "Duplicate call error"
        };
        done(ae.equalAll(expect, ax5.info.getError("ax5dialog", "501", "methodName")));
    });

    it('ax5.info.getError not in ax5.info.errorMsg ', function (done) {
        var expect = {
            className: "ax5custom",
            errorCode: "501",
            methodName: "methodName"
        };
        done(ae.equalAll(expect, ax5.info.getError("ax5custom", "501", "methodName")));
    });
});
<commit_msg>update test code<commit_after>describe('ax5.info TEST', function() {

    it('ax5.info.eventKeys expect {BACKSPACE: 8, ...}', function() {
        var expect = {
            "BACKSPACE": 8,
            "TAB": 9,
            "RETURN": 13,
            "ESC": 27,
            "LEFT": 37,
            "UP": 38,
            "RIGHT": 39,
            "DOWN": 40,
            "DELETE": 46,
            "HOME": 36,
            "END": 35,
            "PAGEUP": 33,
            "PAGEDOWN": 34,
            "INSERT": 45,
            "SPACE": 32
        };
        should.deepEqual(ax5.info.eventKeys, expect);
    });

    it('ax5.info.browser expect {name: "xxx", version: "xx", mobile: Boolean}', function() {
        should.deepEqual(Object.keys(ax5.info.browser), ["name", "version", "mobile"]);
    });

    it('ax5.info.urlUtil() expect ["href", "param", ...]', function() {
        should.deepEqual(Object.keys(ax5.info.urlUtil()), ["href", "param", "referrer", "pathname", "hostname", "port", "url", "baseUrl"]);
    });

    it('ax5.info.errorMsg.ax5dialog["501"] expect "Duplicate call error"', function() {
        should.equal(ax5.info.errorMsg.ax5dialog["501"], 'Duplicate call error');
    });

    it('ax5.info.isBrowser expect true', function() {
        should(ax5.info.isBrowser).Boolean();
    });

    it('ax5.info.wheelEnm expect "mousewheel"', function() {
        should.equal(ax5.info.wheelEnm === "mousewheel" || ax5.info.wheelEnm === "DOMMouseScroll", true);
    });

    it('ax5.info.weekNames expect [{label: "SUN"},{label: "MON"}...]', function() {
        var expect = [
            { "label": "SUN" },
            { "label": "MON" },
            { "label": "TUE" },
            { "label": "WED" },
            { "label": "THU" },
            { "label": "FRI" },
            { "label": "SAT" }
        ];
        should.deepEqual(ax5.info.weekNames, expect);
    });

    it('ax5.info.supportTouch expect Boolean', function() {
        should(ax5.info.supportTouch).Boolean();
    });

    it('ax5.info.getError expect {className: "ax5dialog", ...}', function (done) {
        var expect = {
            className: "ax5dialog",
            errorCode: "501",
            methodName: "methodName",
            msg: "Duplicate call error"
        };
        done(ae.equalAll(expect, ax5.info.getError("ax5dialog", "501", "methodName")));
    });

    it('ax5.info.getError not in ax5.info.errorMsg expect {className: "ax5custom", ...}', function (done) {
        var expect = {
            className: "ax5custom",
            errorCode: "501",
            methodName: "methodName"
        };
        done(ae.equalAll(expect, ax5.info.getError("ax5custom", "501", "methodName")));
    });

    it('ax5.info.errorMsg expect ["ax5dialog", "ax5picker" ...]', function (done) {
        var expect = [
            "ax5dialog",
            "ax5picker",
            "single-uploader",
            "ax5calendar",
            "ax5formatter",
            "ax5menu",
            "ax5select",
            "ax5combobox"
        ];
        done(ae.equalAll(expect, Object.keys(ax5.info.errorMsg)));
    });
});
<|endoftext|>