この記事はもう古くなってしまいました。
Jest v28 以降では、下記のように JSDOM のオプションを指定することができるようになっています。

/**
 * @jest-environment jsdom
 * @jest-environment-options {"url": "https://example.com/"}
 */
it('detects PC', () => {
  expect(location.hostname).toBe('example.com');
});

目的

Node.js におけるテストで Jest を使用する場合、DOM API が関連するテストは JSDOM の実装によって実行されます。この JSDOM はブラウザーと完全に同じ実装を持っているわけではなく、location.href への代入ができないなどの制約があります。そのため Jest でもこれに合わせて JSDOM の API を使用したテストコードを記述する必要があります。

準備

Jest では JSDOM の API を直接参照することができないため、jest-environment-jsdom-global をインストールします。

$ npm i jest-environment-jsdom-global jest-environment-jsdom

package.jsonjest の項目にも追加しておきます。

{
  "jest": {
    "testEnvironment": "jest-environment-jsdom-global"
  }
}

CI などの環境で Node.js の Intl API をはじめとする国際化サポート1が想定した挙動にならない場合があります。たとえば Travis CI の Node.js 環境で以下のコマンドを実行すると ja を指定していても en-US 相当の出力になっています。

$ node -p '(new Intl.DateTimeFormat("ja")).format(new Date())'
3/26/2019

Node.js の i18n は ICU を必要としており2、スクリプト実行の前に full-icu をインストールして環境変数に出しておけば正常に動作します。

$ npm i -g full-icu
export NODE_ICU_DATA=$(node-full-icu-path)

$ node -p '(new Intl.DateTimeFormat("ja")).format(new Date())'
2019/3/26

Travis CI の場合は .travis.ymlbefore_install などに指定しておくと期待した出力が得られます3

環境

Node.js v11.10.0
Travis CI Worker v6.2.0

脚注

2019/02 まで WordPress で管理していた chitoku.jp ですがこの度 Gatsby に移行しました!

TL;DR

  1. Gatsby で TypeScript なら gatsby-plugin-ts-loader + tsconfig-paths-webpack-plugin
  2. Algolia で日本語の検索をするときは Keep diacritics on characters に注意
  3. babel-plugin-react-intl-auto に出した PR がマージされた1
  4. gatsby-transformer-remark に出した PR がマージされた2
  5. remark-grid-tables に出した PR がマージされた3
  6. Gatsby の IE サポートは半分嘘なので残り半分は自分でやる

Gatsby とは

Gatsby は React 製の静的サイトジェネレーターです。Markdown や画像、YAML、テキストファイルなどを透過的に扱うサーバーをローカルに建てて、それらを React のコンポーネントから GraphQL クエリーを通じて組み込めるという特徴があります。豊富なプラグインによって動作を拡張できるほか、細かいカスタマイズは自分でローカルにプラグインとして切り出して管理することができます。

コアの基本的に見える機能もプラグインとして切り出されており、ビルド時のフックに比較的柔軟に介入できます。たとえば Markdown をソースとすると、gatsby-source-filesystem がファイルを読み込んで gatsby-transformer-remark に処理を委譲し、さらに下位のプラグインが Markdown パーサーの処理をカスタマイズできます。今回は以下のようなプラグインを入れてみました。

SystemInfo について

もはやブラウザーを判定する必要がないので更新されていません。

JavaScript で書かれた Web ブラウザーの判定スクリプトです。最近ではほとんどの環境がレンダリング結果の差異が小さいモダンブラウザーに置き換わりつつあり、ブラウザーを判定する必要は薄れてきていますが、アクセス解析なんかでは未だ使えると思います。

UserAgent 以外にもブラウザーが持つ固有のオブジェクトも含めて判定しているため、いくつかの UserAgent 偽装を検出することができます。また、PlayStation Portable の独自拡張にも対応しており、UserAgent に含まれていない情報も追加で取得することができます。