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
Rui Peres: Testing FRP Code
Search
Realm
July 08, 2016
Technology
80
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rui Peres: Testing FRP Code
Realm
July 08, 2016
More Decks by Realm
See All by Realm
WWDC 2017 Review
realm
0
2.2k
Xcode shortcuts
realm
0
4.7k
Self Branding with GitHub
realm
0
4.3k
Realm Mobile Platform overview and demo
realm
0
2.1k
Realm advanced topics and demo
realm
0
2k
Realm introduction Seoul meetup 10
realm
0
2.2k
Stuart Hall: How I got 2.3 Million App Downloads
realm
0
2k
James Majors: What the Swiftly Func?
realm
1
4.3k
Simina Pasat: Continuous everything for iOS apps
realm
0
670
Other Decks in Technology
See All in Technology
ヘルスケア領域における AI 活用と その安全性担保のための取り組み (Leveraging AI in Healthcare and Our Efforts to Ensure Its Safety) - Google I/O Extended Tokyo 2026, July 11, 2026
zettaittenani
0
280
10年目を迎えた「ABEMA」がどのように AI 活用を推進して、AI 駆動開発にシフトしているのか / How ABEMA, entering its 10th year, is promoting the use of AI and shifting toward AI-driven development
miyukki
0
130
最適な自走を最小限の支援で — M&Aで拡大する組織で少人数SREが挑んだ1年 / SRE NEXT 2026
genda
0
1.1k
AI時代の EM への処方箋
staka121
PRO
0
140
Mastraエージェント、どのクラウドにデプロイする?
minorun365
PRO
2
180
「早く出す」より「事業に効く」 ── 顧客の業務サイクルから逆算するAI時代の二重ループ開発と「変化の設計者」 / devsumi2026
rakus_dev
1
230
Gen3R: 3D Scene Generation Meets Feed-Forward Reconstruction
spatial_ai_network
0
120
Compose 新機能総まとめ / What's New in Jetpack Compose
yanzm
0
170
Road to SRE NEXTの今までとこれから
hiroyaonoe
0
310
AI時代のエンジニアキャリアについて今一度考える
sakamoto_582
2
1.5k
なぜ私たちのSREプラクティスはなかなか機能しないのか 〜システムより先に組織を見る〜 / Why our SRE practices aren't really working
vtryo
3
3.7k
ボーイスカウトルールでメモリやスキルを改善しよう
azukiazusa1
2
960
Featured
See All Featured
A designer walks into a library…
pauljervisheath
211
24k
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Un-Boring Meetings
codingconduct
0
340
GitHub's CSS Performance
jonrohan
1033
470k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1k
GraphQLとの向き合い方2022年版
quramy
50
15k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
180
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
370
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
190
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
410
Transcript
1
BUENOS DÍAS BARCELONA !☀# 2
FRP && TESTING 3
But before we start... 4
SMALL STORY... ! 5
WAY BACK IN 2013... ⏰ 6
FRP + RAC + OBJC ! 7
8
9
10
11
12
13
FRP 101 ! 14
FAMILIAR CONCEPTS... ! 15
KVO + NSOperation + ✨ 16
KVO 17
MutableProperty<T> 18
let foo = MutableProperty(1) // 1. observe foo foo.signalProducer.startWithNext {
newFooValue in print(newFooValue) // prints "1" } // 2. modifiy foo's value foo.value = 2 // 3. prints "2" 19
NSOperation 20
SignalProducer<T, E: ErrorType> 21
let networkCall: SignalProducer<NSData, NSError> = ... let parser: NSData ->
[Painting] = ... let paintingsProducer = networkCall.map(parser) .startOn(QueueScheduler()) 22
paintingsProducer.startWithNext { paintings in print(paintings) // [!, "] } paintingsProducer.on(
failure: { error in // handle error }, next: { paintings in print(paintings) // [!, "] }) .start() 23
✨ 24
25
EXAMPLES... ! 26
Form Validation 27
28
let email: MutableProperty<String> = emailTextField.rex_text let password: MutableProperty<String> = passwordTextField.rex_text
let isValid: (String, String) -> Bool = ... let areCredentialsValid = combineLatest(email.producer, password.producer).map(isValid) loginButton.rex_enabled <~ areCredentialsValid 29
30
Puzzle ! 31
32
33
A plan... ! 34
35
let drinks = SignalProducer<[String], NoError>(value: ["!","!"]) let areSober: [String] ->
Bool = ... let gamePlan = drinks .concat(drinks.delay(7.5)) .concat(timer(5).flatMapLatest { _ in drinks }.takeWhile(areSober)) 36
TESTING FRP ! 37
Discrete 38
func testNumberPaintings() { let expectation = self.expectationWithDescription("Expect to have 2
paintings") defer { self.waitForExpectationsWithTimeout(1.0, handler: nil) } paintingsViewModel.paintingsProducer.startWithNext { paintings in XCTAssertEqual(paintings.count, 2) expectation.fulfill() } } 39
func testNumberPaintings() { let result: Result<[Painting], Error>? = paintingsViewModel.paintingsProducer.first() XCTAssertEqual(result?.value?.count,
2) } 40
Continuous 41
final class StubbedNextValues<T: Equatable> { private var nextValues: [T] private
let expectation: XCTestExpectation init(nextValues: [T] , expectation: XCTestExpectation) { self.nextValues = nextValues self.expectation = expectation } func handleNextValue(nextValue: T) -> Void { guard !nextValues.isEmpty else { fatalError("Can't handle \(nextValue)") } let stubbedValue = nextValues.removeFirst() XCTAssertEqual(stubbedValue, nextValue) if nextValues.isEmpty { expectation.fulfill() } } } 42
let producer: SignalProducer<Int, NoError> = ... let stubbedNextValues = StubbedNextValues(nextValues:
[1, 2, 3, 4], expectation: expectation) producer.startWithNext(stubbed.handleNextValue) 43
FRP takes a while to get used to... ! 44
...testing FRP code is as difficult as you want it
to be ! 45
THANKS @peres 46
47