LoginSignup
18

More than 5 years have passed since last update.

Riot.jsのtagを非ブラウザ環境で動かす

Last updated at Posted at 2015-02-10

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18