Ryo | Web developer blog

Web開発者のブログです。

TypeScript と Jest で単体テストの環境構築

f:id:ryogift:20210925195755j:plain
Freepik - jp.freepik.com によって作成された background ベクトル

目次

  1. 概要
  2. TypeScript とは
  3. Jest とは
  4. 環境
  5. プロジェクト作成
  6. コード例

1. 概要

TypeScript を使ってみたくなりましたが、単体テストを実行するまでの環境構築に手間取ったので、手順を残します。

2. TypeScript とは

まず初めに TypeScript とは何かについて、公式サイトに説明がありますので、そのまま引用します。

TypeScript は、型の構文を備えた JavaScript です。 TypeScript は、JavaScript に基づいて構築された強い型を持つプログラミング言語であり、 あらゆる規模で優れたツールを提供します。

www.typescriptlang.org

3. Jest とは

TypeScript に標準で組み込まれているテスティングフレームワークが無さそうなため、個人的に好きな Jest を使います。他にもテスティングフレームワークはありますが、最近は Jest の人気が高いので特にこだわりがなければ Jest 一択だと思っています。こちらも公式サイトに説明がありますので、そのまま引用します。

Jest はシンプルさを重視した、快適な JavaScript テスティングフレームワークです。

jestjs.io

4. 環境

今回は以下の環境で作成しました。

$ node -v
v16.3.0
$ npm -v
7.19.1

5. プロジェクト作成

フォルダ作成後に作成したフォルダに移動して、新規に npm パッケージをセットアップします。

$ mkdir ts-study && cd ts-study
$ npm init

実行に必要なパッケージをインストールします。

$ npm install --save-dev typescript jest ts-jest ts-node @types/jest @types/node

大まかなライブラリの説明

- ts-jest は、 Jest を使用して TypeScript で記述されたプロジェクトをテストできるソースマップをサポートする Jest トランスフォーマーです。
- ts-node は、 TypeScript の実行エンジンであり、 Node.js の REPL です。
- @types/jest は、 Jest の型定義が含まれています。
- @types/node は、 Node.js の型定義が含まれています。

TypeScript の設定ファイルと Jest の設定ファイルを作成します。 (npx は npm の v5.2.0 より同梱されているコマンドです。npm パッケージを簡単に実行できるコマンドです。)

$ npx tsc --init
$ npx jest --init

jest.config.js に以下の内容を設定します。

export default {
  // その他の設定内容は省略しています。

  // A list of paths to directories that Jest should use to search for files in
  roots: [
    "<rootDir>/src"
  ],

  // __tests__ディレクトリ以下にあるファイル または *.test.ts ファイルを探す
  testMatch: [
    "**/__tests__/**/*.+(ts)",
    "**/?(*.)+(test).+(ts)",
  ],

  // A map from regular expressions to paths to transformers
  transform: {"^.+\\.(ts)$": "ts-jest"},
};

今回は、以下のディレクトリ構成で作成しました。

├── src
    └── calc
        ├── calc.ts
        └── calc.test.ts
├── .gitignore
├── README.md
├── jest.config.ts
├── package-lock.json
├── package.json
└── tsconfig.json

今回作成したサンプルコードです。GitHubホスティングするにあたって、各種設定を追加しています。

github.com

6. コード例

簡単な四則演算のコードを書きました。

// src/calc/calc.ts
class Calc {
  readonly left: number;
  readonly right: number;

  constructor(left: number, right: number) {
    this.left = left;
    this.right = right;
  }

  add(): number {
    return this.left + this.right;
  }

  minus(): number {
    return this.left - this.right;
  }

  multiply(): number {
    return this.left * this.right;
  }

  divide(): number {
    return this.left / this.right;
  }
}

export default Calc;

先ほど作成した四則演算のテストコードです。

// src/calc/calc.test.ts
import Calc from "./calc";

test("add", () => {
  const calc = new Calc(1, 2);
  expect(calc.add()).toBe(3);
});

test("minus", () => {
  const calc = new Calc(2, 1);
  expect(calc.minus()).toBe(1);
});

test("multiply", () => {
  const calc = new Calc(2, 2);
  expect(calc.multiply()).toBe(4);
});

test("divide", () => {
  const calc = new Calc(4, 2);
  expect(calc.divide()).toBe(2);
});

テストの実行内容です。

$ npm test

> ts-study@1.0.0 test
> jest

 PASS  src/calc/calc.test.ts
  ✓ add (1 ms)
  ✓ minus
  ✓ multiply
  ✓ divide

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        0.704 s, estimated 1 s
Ran all test suites.

railsでwebpackerのみ使う方法

f:id:ryogift:20210715010757j:plain
Macrovector - jp.freepik.com によって作成された design ベクトル

目次

  1. 事前に
  2. 概要
  3. Sprocketsを除外したアプリケーション
  4. Sprocketsの除外方法

1. 事前に

今回、作成したアプリケーションは以下のバージョンのrubyrailsを事前にインストールしています。

version:
  ruby: 3.0.2
  rails: 6.1.4

2. 概要

rails6で新規にアプリケーションを作成するとアセットパイプラインは、SprocketsとWebpackerが同梱されています。 主にCSSファイルと画像ファイルはSprockets、JavaScriptファイルはWebpackerで管理されています。 新規にアプリケーションを作成する場合に限ってですが、二つのアセットパイプラインが共存しているのは紛らわしいためWebpackerでCSSファイル、画像ファイル、JavaScriptファイルを管理出来るようにしていきたいと思います。

アセットパイプラインやWebpackerについては以下のRailsガイドに詳しく記載されていますので、ご参照ください。

railsguides.jp

railsguides.jp

単純に新規作成ではSprocketsを除外するオプションもありますが、既存のアプリケーションからSprocketsを除外していく方法の参考にもなるかと思いますので、今回はデフォルトの状態から手作業でSprocketsを除外していきます。

rails new appname --skip-sprockets

3. Sprocketsを除外したアプリケーション

Sprocketsを除外したアプリケーションの最終的なコードは以下のリポジトリをご参照ください。

github.com

4. Sprocketsの除外方法
1. Sprocketsを除外します。

変更点は以下をご参照ください。

github.com

変更内容は、sass-railsライブラリの削除、assetsフォルダの削除や各種assetsの設定削除、webpackerにCSSファイルと画像ファイルを管理するように変更しています。

デフォルトでアプリケーションを新規作成すると、require "rails/all"の指定のみになりますので、require "sprockets/railtie"を除いた各種ライブラリを個別に呼び出すように追加しています。

# config/application.rb
- require "rails/all"
+ require "rails"
+ # Pick the frameworks you want:
+ require "active_model/railtie"
+ require "active_job/railtie"
+ require "active_record/railtie"
+ require "active_storage/engine"
+ require "action_controller/railtie"
+ require "action_mailer/railtie"
+ require "action_view/railtie"
+ require "action_cable/engine"
+ require "rails/test_unit/railtie"
2. Generatorからassetsファイルの生成を除外します。

変更点は以下をご参照ください。

github.com

3. 動作確認

最後にアプリケーションのテスト実行や起動確認、また、assets:precompileでpublicディレクトリにpacksディレクトリのみが作成されていると、Sprocketsの除外が出来ていることを確認することが出来ます。

「白鳥とコウモリ」の感想

目次

  1. 購入者したきっかけ
  2. 加害者家族の生活が一変
  3. 加害者家族と被害者家族の協力プレー
  4. まとめ

1. 購入者したきっかけ

久しぶりに本屋に立ち寄って、東野圭吾さんの新作を目にしてしまったら買うしかない。 普段は電子書籍でしか本を購入しないが、どうやら東野圭吾さんの作品は電子書籍化されていないらしい。 私は紙の本でも、電子の本でも読めればいいので早速、「白鳥とコウモリ」を購入して読んでみた。

2. 加害者家族の生活が一変

弁護士が遺体で見つかって、とある容疑者の1人が自供するところから物語が始まる。 容疑者の息子は、突然、加害者側の家族になりネットで特定されてしまう。その影響で会社からは休職扱いにされてしまい、生活環境が一変する。

容疑者の1人が割と序盤に自供してしまうので、物語の後半に確実に別の真相が明らかになっていくんだろうなという推測が出来てしまうぐらいに本作は少しボリュームがある。現代に良くあるネットでの特定から加害者側の生活が一変してしまうところに妙にリアリティを感じます。

3. 加害者家族と被害者家族の協力プレー

容疑者の供述に違和感があると感じた。同じ目的で加害者家族と被害者家族がそれぞれ真相を明らかにしようと行動していた。そしたら、偶然出会うことになる。加害者家族と被害者家族は協力して真相を明らかにしようとする。

容疑者は過去の事件をきっかけに新たに事件を起こしてしまうのだけれど、そのために過去の事件に遡って当時の関係者に話を聞きにいく。 2017年の東京で起きた事件と1984年の愛知で起きた過去の事件を関連付けるために33年前の当時の関係者に話を聞きに行くのだが、このあたりは少し話が強引に進むなと感じる。30年以上前に起きた事件の記憶を鮮明に覚えていられるだろうか。覚えていたとしても記憶が曖昧にならないのだろうか。そんな疑問を持ってしまった。

やがて、真相が明らかになり、被害者と容疑者の関係が判明する。33年の時を超えても繰り返してしまう罪と罰の因果関係が少々、強引でもあり結末は少し悲しい。

5. まとめ

相変わらず東野圭吾さんの作品は読みやすくて、あっと言う間に読み終えてしまいます。個人的には本作は、サイエンス要素が弱いのがちょっと残念でした。 人間模様が中心で、事件に関わる人々の生活について考えさせられる作品ですね。 昨今のどんな話題でも面白可笑しく騒ぐ状況が少しでも緩和すれば良いのにと感じました。

Hash#transform_keysを利用する

目次

  1. Hash#transform_keysを利用する
  2. 変更前
  3. 変更後
  4. まとめ

1. Hash#transform_keysを利用する

f:id:ryogift:20210620234135j:plain
先日行った知床峠の写真です。本記事とは無関係です。

久しぶりにRuby on Rails APIモードのアプリを確認していたら、rubocop さんからの警告が表示されていました。 Class: RuboCop::Cop::Style::HashTransformKeys の警告でハッシュのキーを変換するだけで to_h などのメソッドは利用せずに transform_keys を利用することによって、単純で高速な呼び出しに変更できるそうです。

2. 変更前
def lower_camelize_keys(object)
  if object.is_a?(Array)
    object.map { |item| item.to_h { |k, v| [k.to_s.camelize(:lower).to_sym, v] } }
  else
    object.to_h { |k, v| [k.to_s.camelize(:lower).to_sym, v] }
  end
end

3 変更後
def lower_camelize_keys(object)
  if object.is_a?(Array)
    object.map { |item| item.transform_keys { |k| k.to_s.camelize(:lower).to_sym } }
  else
    object.transform_keys { |k| k.to_s.camelize(:lower).to_sym }
  end
end

4 まとめ

キーバリューのバリューを省略できて、可読性が高くなりましたね。習慣的に RubyRuby on Rails の動向を確認していないと便利なメソッドが追加されても気づかないままです。少しづつ確認し始めようかなと思いました。

佐藤可士和展の感想と都会の緑を楽しむ

f:id:ryogift:20210411191624j:plain
国立新美術館

目次

  1. 佐藤可士和展(国立新美術館)を楽しむ
  2. 初めての代々木公園
  3. 初めての新宿御苑
  4. まとめ

1. 佐藤可士和展(国立新美術館)を楽しむ

f:id:ryogift:20210411191722j:plain
佐藤可士和展(ユニクロ

f:id:ryogift:20210411191753j:plain
佐藤可士和展(セブンイレブン

私は、アートが幼少期から好きでクラスの中では絵が上手い方であったという程度の子供時代でした。 将来は芸術家かアニメーターか漫画家になりたいという時期もありましたが、いつの間にかプログラマーとして働いています。 アートを仕事にしているのが羨ましいなと思い、「佐藤可士和展」に行って見ましたが、正直これはアートではなくデザインの世界であると驚愕しました。 一見、単純なロゴではありますが、そのロゴは実は緻密に設計されていました。また、そのロゴを依頼者にプレゼンして採用してもらうというプロセスを考えると恐ろしく難易度が高く感じます。デザインの世界には詳しくありませんが、Webのシステムを開発している側としてはWebのフロントデザインのコンセプトや根拠を説明して採用してもらうというだけでも大変なため、どのようにロゴをプレゼンして採用してもらっているのかというプロセスがとても気になり、ワクワクしました。

2. 初めての代々木公園

代々木公園に行った記憶が無く、暇なので行ってみることにしました。渋谷は何度か行ってますが、狭い空間にビルが並んでいて土地の高さが予想できます。そんな空間に緑一面の公園が広がっているという感覚が不思議な気持ちになりました。さらに、明治神宮にも行ってみましたが、都会とは思えない空間ですね。(写真を撮り忘れました😞)

3. 初めての新宿御苑

f:id:ryogift:20210411191935j:plain
新宿御苑
f:id:ryogift:20210411191952j:plain
新宿御苑(さくら)

新宿御苑にも行った記憶がなく、折角、暇なので行ってみることにしました。新宿御苑は現在、事前予約制になっており、慌てて現地で予約してみましたが、次の時間帯しか予約できないため一時間待ってから入園しました。こちらも新宿とは思えないほどに緑が広がっており、心が癒されました。桜は少し散っていましたが、この場所でお花見が出来ると思うと、さぞかし楽しいのではないかと感じました。

4. まとめ

f:id:ryogift:20210411192049j:plain
ザッハトルテ

今回は国立新美術館、代々木公園、明治神宮新宿御苑を周ってみましたが、一日で周るには疲れますね。今までは、都内を散策する行動をしていなかったので、これからは積極的に色々な名所を周ってみたいと思います。 帰りにあまりにも疲れたので、チョコレートケーキを買いました。ザッハトルテという名前を聞いたことがありましたが、今まで食べたことがなかったのですが、食べてみると美味しいですね。