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
810
Kotlin 最新動向2022 #tfcon #techfeed
ntaro
1
2.3k
#Ubie 狂気の認知施策と選考設計
ntaro
13
13k
UbieにおけるサーバサイドKotlin活用事例
ntaro
1
1.1k
KotlinでSpring 完全理解ガイド #jsug
ntaro
6
3.5k
Kotlinでサーバサイドを始めよう!
ntaro
1
1k
Androidからサーバーサイドまで!プログラミング言語 Kotlinの魅力 #devboost
ntaro
5
2.8k
Kotlin Contracts #m3kt
ntaro
4
4.2k
How_to_Test_Server-side_Kotlin.pdf
ntaro
1
520
Other Decks in Programming
See All in Programming
SwiftDataを使って10万件のデータを読み書きする
akidon0000
0
240
pnpm に provenance のダウングレード を検出する PR を出してみた
ryo_manba
1
160
Catch Up: Go Style Guide Update
andpad
0
260
社会人になっても趣味開発を続けたい! / traPavilion
mazrean
1
100
理論と実務のギャップを超える
eycjur
0
180
あなたとKaigi on Rails / Kaigi on Rails + You
shimoju
0
190
Android16 Migration Stories ~Building a Pattern for Android OS upgrades~
reoandroider
0
140
三者三様 宣言的UI
kkagurazaka
0
250
マンガアプリViewerの大画面対応を考える
kk__777
0
310
Introduce Hono CLI
yusukebe
6
3.1k
CSC509 Lecture 07
javiergs
PRO
0
250
スキーマ駆動で、Zod OpenAPI Honoによる、API開発するために、Hono Takibiというライブラリを作っている
nakita628
0
320
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
9.6k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.5k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
Into the Great Unknown - MozCon
thekraken
40
2.1k
How GitHub (no longer) Works
holman
315
140k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
36
6.1k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
116
20k
Git: the NoSQL Database
bkeepers
PRO
431
66k
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