この記事はand factory.inc Advent Calendar 2022 21日目の記事です。
昨日は @k_shinn さんの 【Jetpack Compose】WearOSで簡単なアプリを作ってみる でした。
はじめに
テストを書くときによく構造体の比較をしたいときがあるのですが、毎回Equatableに準拠させるために==
の実装をするのが面倒だと感じてました。
そこで今回は、Sourceryというツールを使ってEquatableの実装を自動化してみました。
Sourceryとは
Sourceryとはボイラーテンプレートを自動生成してくれるSwift製のツールです。
環境
- MacBook Pro Apple M1 Max
- Xcode14.1(14B47b)
- Swift:5.7.1
- Mint:0.17.4
セットアップ
今回はMintを使ってインストールします。
krzysztofzablocki/Sourcery@1.9.2
$ mint bootstrap
.sourcery.ymlを作成する
コマンドラインから実行するときに指定するオプションをあらかじめ設定ファイルに記述しておきます。
sources:
# ソースとなるファイルやディレクトリのパス
- Sample-Sourcery
templates:
# テンプレートが格納されているパス
- Sample-Sourcery/Templates
output:
# 自動生成したファイルを格納するパス
Sample-Sourcery/Generated
Templateを配置する
自動生成するときに元となるテンプレートを配置します。
// AutoEquatable
{% for type in types.implementing.AutoEquatable|struct %}
extension {{type.name}}: Equatable {
static func == (lhs: {{type.name}}, rhs: {{type.name}}) -> Bool {
{% for variable in type.storedVariables|!annotated:"skipEquality" %}guard lhs.{{variable.name}} == rhs.{{variable.name}} else { return false }
{% endfor %}
return true
}
}
{% endfor %}
プロトコルの実装
Equatable
の実装を自動生成したい構造体は、AutoEquatable
に準拠させる必要があるので、AutoEquatable
プロトコルを定義しておきます。
protocol AutoEquatable {}
AutoEquatableに準拠させる
Equatable
の実装を自動生成したい構造体にAutoEquatable
を準拠させます。
import Foundation
struct User: AutoEquatable {
let id: Int
let name: String
let iconUrlStr: String
}
Sourceryを実行
ここまで準備ができたら、コマンドラインからSourceryを実行してEquatable
の実装を自動生成します。
$ mint run krzysztofzablocki/Sourcery
自動生成されたファイル
実行が成功すると、.sourcery.yml
のoutput:
に定義したパスに自動生成されたコードが出力されます。
// Generated using Sourcery 1.9.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// AutoEquatable
extension User: Equatable {
static func == (lhs: User, rhs: User) -> Bool {
guard lhs.id == rhs.id else { return false }
guard lhs.name == rhs.name else { return false }
guard lhs.iconUrlStr == rhs.iconUrlStr else { return false }
return true
}
}
おわりに
Sourceryを使うことでEquatable
の実装を簡単に行うことができるようになりました。
Sourceryは他にもMock
なども自動生成できるので、それらも活用してテストの実装コストを下げていければと思います。
明日のAdvent Calendarの記事もお楽しみに
参考リンク
https://github.com/krzysztofzablocki/Sourcery
https://github.com/krzysztofzablocki/SourceryWorkshops/tree/steps
https://enmtknt.hateblo.jp/entry/2018/03/13/153344