More than 1 year has passed since last update.

Riot.jsについて

Riot.js 2.0 情報まとめを見るととてもよく分かると思う。

ブラウザ以外でもtagを動かしたい

ガイド見る限りブラウザ上でriot.mountを実行することが前提のように書かれていて、tag単位のユニットテストが辛い。ユニットテストやるとして、Node.jsの上で動かしたい。

しかし、ブラウザ上で動いているもの相当のrequire('riot/riot')を単純にNode.js上で実行しても、DOMが存在しない環境なのでブロックされriot.mountriot.tagが生えない。

ということはつまり、Node.js上でもDOM実装さえ適切に与えれば、riot.mountが実行可能になる。Node.jsでDOM操作といえば、jsdomである。jsdomは外部からJavaScript片を注入できるので、以下のような記述が動く。

jsdom = require('jsdom')
fs = require('fs')
riot = fs.readFileSync(require.resolve('riot/riot'), 'utf-8')

jsdom.env
  html: '<div><foo /></div>'
  src: [riot]
  done: (errors, window) ->
    console.log(window.riot.mount)  # => Function

tagファイルはコンパイルするとriot.tagを実行するjsファイルに化けるので、このまま続けて注入できる。

tagをテストする

例えばこんなtagがあるとして、

<foo>
  <h3>{ opts.bar }</h3>
  <p>{ baz }</p>
</foo>

jsdomを使えばこんな感じでテストもできる。今回はtapeを使ったがmochaでも何でも問題ないはず。

jsdom = require('jsdom')
fs = require('fs')
riot = fs.readFileSync(require.resolve('riot/riot'), 'utf-8')
compiler = require('riot')
tag = compiler.compile(fs.readFileSync('./foo.tag', 'utf-8'))
test = require('tape')

test (t) ->
  t.plan(3)

  jsdom.env
    html: '<div><foo /></div>'
    src: [riot, tag]
    done: (errors, window) ->
      [foo] = window.riot.mount('foo', bar: 'baz')

      document = window.document
      t.equal(document.querySelector('h3').innerHTML, 'baz')
      t.equal(document.querySelector('p').innerHTML, '')

      foo.update(baz: 'qux')
      t.equal(document.querySelector('p').innerHTML, 'qux')

これで表示と変更はテストできた。

$ coffee test/foo.tag.test.coffee
TAP version 13
# (anonymous)
ok 1 should be equal
ok 2 should be equal
ok 3 should be equal

1..3
# tests 3
# pass  3

# ok
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.