Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
knitで学ぶKotlin入門の次 #Kotlin_Sansan
Search
Taro Nagasawa
March 25, 2016
Programming
3
2.1k
knitで学ぶKotlin入門の次 #Kotlin_Sansan
第2回Kotlin勉強会 @ Sansan (
http://connpass.com/event/27583/
)で発表したスライドです。
Taro Nagasawa
March 25, 2016
Tweet
Share
More Decks by Taro Nagasawa
See All by Taro Nagasawa
Android開発者のための Kotlin Multiplatform入門
ntaro
0
720
Kotlin 最新動向2022 #tfcon #techfeed
ntaro
1
2.2k
#Ubie 狂気の認知施策と選考設計
ntaro
13
13k
UbieにおけるサーバサイドKotlin活用事例
ntaro
1
1.1k
KotlinでSpring 完全理解ガイド #jsug
ntaro
6
3.4k
Kotlinでサーバサイドを始めよう!
ntaro
1
990
Androidからサーバーサイドまで!プログラミング言語 Kotlinの魅力 #devboost
ntaro
5
2.8k
Kotlin Contracts #m3kt
ntaro
4
4.1k
How_to_Test_Server-side_Kotlin.pdf
ntaro
1
500
Other Decks in Programming
See All in Programming
構文解析器入門
ydah
7
2k
リッチエディターを安全に開発・運用するために
unachang113
1
330
CEDEC 2025 『ゲームにおけるリアルタイム通信への QUIC導入事例の紹介』
segadevtech
0
480
可変性を制する設計: 構造と振る舞いから考える概念モデリングとその実装
a_suenami
10
1.3k
Understanding Kotlin Multiplatform
l2hyunwoo
0
250
202507_ADKで始めるエージェント開発の基本 〜デモを通じて紹介〜(奥田りさ)The Basics of Agent Development with ADK — A Demo-Focused Introduction
risatube
PRO
6
1.3k
NEWT Backend Evolution
xpromx
1
170
Git Sync を超える!OSS で実現する CDK Pull 型デプロイ / Deploying CDK with PipeCD in Pull-style
tkikuc
4
490
Flutterと Vibe Coding で個人開発!
hyshu
1
190
Workers を定期実行する方法は一つじゃない
rokuosan
0
140
オンコール⼊⾨〜ページャーが鳴る前に、あなたが備えられること〜 / Before The Pager Rings
yktakaha4
2
1.2k
Reactの歴史を振り返る
tutinoko
1
160
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.4k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
A Tale of Four Properties
chriscoyier
160
23k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.9k
Testing 201, or: Great Expectations
jmmastey
44
7.6k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Gamification - CAS2011
davidbonilla
81
5.4k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
770
Building Applications with DynamoDB
mza
95
6.5k
Transcript
knitで学ぶ Kotlin入門の次 2016-03-24 第2回Kotlin勉強会@Sansan 長澤 太郎 @ngsw_taro
自己紹介 • 長澤 太郎 たろーって呼んでね • プログラマー@エムスリー株式会社 ◦ Android, Kotlin,
Java, Scala, Rubyなど • Kotlinエバンジェリスト(JetBrains黙認) ◦ 日本Kotlinユーザグループ代表 ◦ Kotlin入門書 目下執筆中! • やすべえとディズニーが好き
1. knitの紹介
knitとは • JUnitの薄いラッパー • 1ヶ月くらい前につくった • 今すぐダウンロード github.com/ntaro/knit
なぜつくったか // JUnit assertThat(actual, `is`(expected))
なぜつくったか // JUnit assertThat(actual, `is`(expected)) ダサい
knitを使うと // knit actual.should be expected
やってることは単純 actual.should be expected assertThat(actual, `is`(expected))
2. knitの造り
構成要素を分解 actual.should be expected (actual.should).be(expected)
構成要素を分解 actual.should be expected (actual.should).be(expected) オブジェクトへの参照
構成要素を分解 actual.should be expected (actual.should).be(expected) メソッド呼び出し
構成要素を分解 actual.should be expected asserter .be(expected) オブジェクトへの参照 →インタフェース Asserter
Asserter interface Asserter<T> { val target: T infix fun not(matcher:
Matcher<in T>) infix fun be(expected: T) infix fun be(matcher: Matcher<in T>) infix fun be(block: () -> T) infix fun notBe(unexpected: T) infix fun notBe(matcher: Matcher<in T>) infix fun notBe(block: () -> T) }
Asserter interface Asserter<T> { val target: T infix fun not(matcher:
Matcher<in T>) infix fun be(expected: T) infix fun be(matcher: Matcher<in T>) infix fun be(block: () -> T) infix fun notBe(unexpected: T) infix fun notBe(matcher: Matcher<in T>) infix fun notBe(block: () -> T) }
Asserter interface Asserter<T> { val target: T infix fun not(matcher:
Matcher<in T>) infix fun be(expected: T) infix fun be(matcher: Matcher<in T>) infix fun be(block: () -> T) infix fun notBe(unexpected: T) infix fun notBe(matcher: Matcher<in T>) infix fun notBe(block: () -> T) } infix call
infix call asserter.be(expected) asserter be expected • メソッドを中置演算子っぽく呼び出せる • 標準ライブラリだと
and や or がinfix指定されている
Asserterオブジェクトの生成 actual.should be expected
Asserterオブジェクトの生成 actual.should be expected 任意の型のプロパティ
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this)
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) 型パラメータ
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) 拡張プロパティ
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) 型
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) Asserterの実装
オブジェクトを生成
他の表現も可能 fun <T> should(target: T): Asserter<T> = AsserterImpl(target) fun <T>
T.should(): Asserter<T> = AsserterImpl(this)
このコードを実現したいがため // 関数 should(actual) be expected // 拡張関数 actual.should() be
expected // 拡張プロパティ actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 actual.should()
be expected // 拡張プロパティ actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 カッコが邪魔
actual.should() be expected // 拡張プロパティ actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 カッコが邪魔
actual.should() be expected // 拡張プロパティ 英語の文章としてまぁ自然 actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 カッコが邪魔
actual.should() be expected // 拡張プロパティ 英語の文章としてまぁ自然 actual.should be expected ※DSLだから許される?
3. 小ネタ
トップレベルに関数やプロパティをおける package com.taroid.knit val <T> T.should: Asserter<T> get() = AsserterImpl(this)
val <T> (()->T).should: Asserter<T> get() = this().should
ファイル名どうするの問題 • クラスやインタフェースはJavaと同じ ◦ いわゆるpascal-case ◦ 例) AsserterImpl.kt • クラスがないファイルは?
◦ 特に決まりはないっぽい ◦ 試しにcamel-case ◦ 例) matcherAliases.kt ◦ IDEAさんならアイコンでわかる
識別子クォート、テストで便利だった class `be - expected` { @Test fun `does nothing
when target equals expected`() { sut be java.lang.String("Kotlin").toString() } @Test(expected = AssertionError::class) fun `throws error when target does not equal expected`() { sut be "kotlin" } }
Matcherを取るバージョン "knit".should(endWith("it"))
Matcherを取るバージョン "knit".should(endWith("it")) fun endWith(suffix: String): Matcher<String> = CoreMatchers.endsWith(suffix) 三単現のsを除く地味な工夫...
Matcherを取るバージョン "knit".should(endWith("it")) fun <T> T.should(matcher: Matcher(in T>) { assertThat(this, matcher)
} 拡張関数版 should (妥協)
Asserterにinvokeを持たせたかったが... "knit".should(endWith("it")) // NG ("knit".should)(endWith("it")) // OK "knit".should.invoke(endWith("it")) // OK
interface Asserter<T> { operator fun invoke(matcher: Matcher<in T>) ... なぜか型エラー
Thank you Enjoy Kotlin