gist

2012年2月25日土曜日

CoffeeScriptとExpressとMongoDbとMochaでNode.jsするメモ

巷ではCoffeeScriptが流行っているそうで。ExpressとMongoDb、テストにMochaを使った定型文的なメモ。

インストールはこんな感じで。

$ sudo npm install -g coffee-script
$ sudo npm install -g js2coffee
$ express sample
$ cd sample && npm install
$ npm install mocha
$ npm install mongoose

expressで出来たテンプレをcoffeeに変換。


$ js2coffee app.js > app.coffee
$ js2coffee routes/index.js > app.coffee

Mochaのテスト。全文です。本来はコツコツやっていきませう。

test/routes-test.coffee

routes = require "../routes/index"
mongoose = require "mongoose"
Post = require "../models/Post"
require "should"
  
describe "routes", ->
  req = 
    params: {} 
    body: {}
  res =
    redirect: (route) ->
      #do nothing
    render: (view, vars)->
      #do nothing
  before (done) ->
    mongoose.connect 'mongodb://localhost/blog', ->
      Post.remove done

  describe "index", ->
    it "should display index with posts", (done) ->
      res.render = (view, vars) ->
          view.should.equal "index"
          vars.title.should.eql "ぶろぐ"
          vars.posts.should.eql []
          done()
      routes.index(req, res)

  describe "new post", ->
    it "should display the add post page", (done) ->
      res.render = (view, vars) ->
        view.should.equal "add_post"
        vars.title.should.equal "あたらしい投稿"
        done()
      routes.newPost(req, res)
    it "should add a new post when posted to", (done) ->
      req.body.post =
        title: "たいとるです"
        body: "ほんぶんです"

      routes.addPost req, redirect:(route) ->
        route.should.eql "/"
        routes.index req, render: (view, vars) ->
          view.should.equal "index"
          vars.posts[0].title.should.eql "たいとるです"
          vars.posts[0].body.should.eql "ほんぶんです"
          done()

メイン

app.coffee

express = require("express")
routes = require("./routes")
mongoose = require('mongoose')

app = module.exports = express.createServer()
app.configure ->
  app.set "views", __dirname + "/views"
  app.set "view engine", "jade"
  app.use express.bodyParser()
  app.use express.methodOverride()
  app.use app.router
  app.use express.static(__dirname + "/public")

app.configure "development", ->
  mongoose.connect 'mongodb://localhost/blog-dev'
  app.use express.errorHandler(
    dumpExceptions: true
    showStack: true
  )

app.configure "production", ->
  mongoose.connect 'mongodb://localhost/blog-prod'
  app.use express.errorHandler()

app.get "/", routes.index
app.get "/post/new", routes.newPost
app.post "/post/new", routes.addPost
app.get "/post/:id", routes.viewPost
app.listen 3000
console.log "Express server listening on port %d in %s mode", app.address().port, app.settings.env

ルーティング

routes/index.coffee

Post = require '../models/Post'

module.exports =
  index : (req, res) ->
    Post.find {}, (err, posts) ->
      res.render "index",
        title: "ぶろぐ"
        posts: posts
  
  newPost : (req, res) ->
    res.render "add_post", title:"あたらしい投稿"
  
  addPost : (req, res) ->
    new Post(req.body.post).save ->
      res.redirect "/"
  
  viewPost: (req, res) ->
    Post.findById req.params.id, (err, post) ->
      res.render 'post', post: post, title: post.title

モデル

models/Post.coffee

mongoose = require 'mongoose'

Post = new mongoose.Schema(
  title: String,
  body: String
)     
        
module.exports = mongoose.model 'Post', Post

ビュー

views/layout.jade

!!!5  
html    
  head  
    title= title
    link(rel="stylesheet", href="http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css")
    style(type="text/css")
      #content {padding-top: 60px; }
  body    
    .topbar-wrapper
      .topbar
        .topbar-inner
          .container
            h3: a(href="/")= title
            ul.nav
              li: a(href="/post/new") あたらしい投稿
    #content.container!=body

views/index.jade

- each post in posts
  .page-header
    h1  
      a(href="/post/#{post.id}")= post.title
  .content!=post.body

views/add_post.jade

form(method="post", action="/post/new")
  fieldset
    legend=title
    .clearfix
      label(for="title") たいとる
      .input
        input.xlarge#title(type="text", name="post[title]")
    .clearfix
      label(for="post") ないよう
      .input
        textarea#post.xxlarge(name="post[body]", rows="3")
    .actions
      input.btn.primary(type="submit", value="こうかい!")
      |  
      a.btn(href="/") やめた

views/post.jade

.page-header
  h1= post.title
.content!=post.body

実行


$ coffee app.coffee

次はCoffeeKupも使ってみようと思います。Coffeeで統一。

0 件のコメント: