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
650
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
970
Androidからサーバーサイドまで!プログラミング言語 Kotlinの魅力 #devboost
ntaro
5
2.7k
Kotlin Contracts #m3kt
ntaro
4
4.1k
How_to_Test_Server-side_Kotlin.pdf
ntaro
1
490
Other Decks in Programming
See All in Programming
なぜHono×GraphQLを選んだのか?
junichi_fukushima
0
830
Language Server と喋ろう – TSKaigi 2025
pizzacat83
2
510
型安全なDrag and Dropの設計を考える
yudppp
5
620
複雑なフォームを継続的に開発していくための技術選定・設計・実装 #tskaigi / #tskaigi2025
izumin5210
12
5.6k
Digging into the Matrix: Practicing Code Archaeology
arthurdoler
PRO
0
200
データベースの技術選定を突き詰める ~複数事例から考える最適なデータベースの選び方~
nnaka2992
3
3.9k
TypeScript だけを書いて Tauri でデスクトップアプリを作ろう / Tauri with only TypeScript
tris5572
2
470
TVer iOSチームの共通認識の作り方 - Findy Job LT iOSアプリ開発の裏側 開発組織が向き合う課題とこれから
techtver
PRO
0
600
AIエージェントによるテストフレームワーク Arbigent
takahirom
0
120
事業KPIを基に価値の解像度を上げる
nealle
0
180
當開發遇上包裝:AI 如何讓產品從想法變成商品
clonn
0
110
tsconfigのオプションで変わる型世界
keisukeikeda
1
110
Featured
See All Featured
Designing for Performance
lara
608
69k
Scaling GitHub
holman
459
140k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Designing for humans not robots
tammielis
253
25k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
Into the Great Unknown - MozCon
thekraken
38
1.8k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
228
22k
Music & Morning Musume
bryan
47
6.5k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.7k
Embracing the Ebb and Flow
colly
85
4.7k
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