/
future.fy
105 lines (93 loc) · 2.27 KB
/
future.fy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
FancySpec describe: FutureSend with: {
it: "returns a FutureSend" when: {
def future_send_method {
"hello, future world!"
}
f = self @ future_send_method
f is_a?: FutureSend . is: true
f value is: future_send_method
}
it: "returns nil for async sends" when: {
def async_send_method {
"hello, async world!"
}
a = self @@ async_send_method
a is: nil
}
it: "accesses the same future from multiple threads and blocks them until the value is computed" when: {
def another_method {
Thread sleep: 0.1
42
}
future = self @ another_method
threads = (0..10) map: {
Thread new: {
future completed? is: false
future value is: 42
}
}
threads each: 'join
}
it: "deals as expected with failures" when: {
def a_failing_method {
"error!" raise!
}
f = self @ a_failing_method
f value # wait for completion
f failure message is: "error!"
f failed? is: true
}
it: "calls a block when done" with: 'when_done: when: {
called? = false
failed? = false
val = 0
f = { Thread sleep: 0.01; 2 } @ call
f when_done: |v| {
val = v
called? = true
}
f when_failed: |err| {
val = err
failed? = true
}
f value
called? is: true
val is: 2
}
it: "calls a block when failed" with: 'when_failed: when: {
called? = false
failed? = false
val = 0
f = { Thread sleep: 0.01; "Fail!" raise! } @ call . tap: @{
when_done: |v| {
val = v
called? = true
}
when_failed: |err| {
val = err
failed? = true
}
}
f value
called? is: false
failed? is: true
val message is: "Fail!"
val is_a?: Exception
}
}
FancySpec describe: FutureCollection with: {
it: "iterates over each future's value" with: 'each: when: {
futures = ("a".."z") map: |l| { l @ inspect }
FutureCollection[futures] each: |val| {
val =~ /[a-z]/ . is_not: nil
}
}
it: "awaits all futures to complete" with: 'await_all when: {
futures = (0..100) map: |i| {
{ Thread sleep: 0.01; i * 2 } @ call
}
futures all?: @{ completed? } . is: false
FutureCollection[futures] await_all
futures all?: @{ completed? } . is: true
}
}