immutable 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,8 @@
1
- require "test/unit"
2
- require "immutable/list"
1
+ require_relative "../test_helper"
2
+
3
+ with_tailcall_optimization {
4
+ require "immutable/list"
5
+ }
3
6
 
4
7
  module Immutable
5
8
  class TestList < Test::Unit::TestCase
@@ -52,6 +55,16 @@ module Immutable
52
55
  assert(!List[1, 2, 3].empty?)
53
56
  end
54
57
 
58
+ def test_each
59
+ a = []
60
+ List[].each { |x| a << x }
61
+ assert_equal([], a)
62
+
63
+ a = []
64
+ List[1, 2, 3].each { |x| a << x }
65
+ assert_equal([1, 2, 3], a)
66
+ end
67
+
55
68
  def test_foldr
56
69
  assert_equal(0, List[].foldr(0, &:+))
57
70
  assert_equal(123, List[].foldr(123, &:+))
@@ -96,6 +109,7 @@ module Immutable
96
109
  assert(List[1] != List[])
97
110
  assert(List[1] == List[1])
98
111
  assert(List[1] != List[2])
112
+ assert(List[1] != [1])
99
113
  assert(List["foo"] == List["foo"])
100
114
  assert(List["foo"] != List["bar"])
101
115
  assert(List[1, 2, 3] == List[1, 2, 3])
@@ -159,6 +173,15 @@ module Immutable
159
173
  assert_equal(List[2, 4], List[1, 2, 3, 4, 5].filter(&:even?))
160
174
  end
161
175
 
176
+ def test_aref
177
+ assert_equal(nil, List[][0])
178
+ assert_equal(1, List[1, 2, 3][0])
179
+ assert_equal(nil, List[1, 2, 3][-1])
180
+ assert_equal(2, List[1, 2, 3][1])
181
+ assert_equal(3, List[1, 2, 3][2])
182
+ assert_equal(nil, List[1, 2, 3][3])
183
+ end
184
+
162
185
  def test_take
163
186
  assert_equal(List[], List[].take(1))
164
187
  assert_equal(List[], List[1, 2, 3].take(0))
@@ -226,6 +249,13 @@ module Immutable
226
249
  List[List[1, 2, 3], List[4, 5]].transpose)
227
250
  end
228
251
 
252
+ def test_subsequences
253
+ assert_equal(List[List[]], List[].subsequences)
254
+ assert_equal(List[List[], List[1], List[2], List[1, 2],
255
+ List[3], List[1, 3], List[2, 3], List[1, 2, 3]],
256
+ List[1, 2, 3].subsequences)
257
+ end
258
+
229
259
  def test_sum
230
260
  assert_equal(0, List[].sum)
231
261
  assert_equal(1, List[1].sum)
@@ -251,5 +281,23 @@ module Immutable
251
281
  }
252
282
  assert_equal(List["foo", "bar", "baz"], xs)
253
283
  end
284
+
285
+ def test_zip
286
+ xs = List[0, 1, 2]
287
+ ys = List[0, 2, 4]
288
+ zs = List[0, 3, 6]
289
+ assert_equal(List[[0, 0, 0], [1, 2, 3], [2, 4, 6]],
290
+ xs.zip(ys, zs))
291
+ end
292
+
293
+ def test_zip_with
294
+ xs = List[0, 1, 2]
295
+ ys = List[0, 2, 4]
296
+ zs = List[0, 3, 6]
297
+ l = xs.zip_with(ys, zs) { |x, y, z|
298
+ x + y + z
299
+ }
300
+ assert_equal(List[0, 6, 12], l)
301
+ end
254
302
  end
255
303
  end
@@ -1,5 +1,8 @@
1
- require "test/unit"
2
- require "immutable/map"
1
+ require_relative "../test_helper"
2
+
3
+ with_tailcall_optimization {
4
+ require "immutable/map"
5
+ }
3
6
 
4
7
  module Immutable
5
8
  class TestMap < Test::Unit::TestCase
@@ -48,6 +51,16 @@ module Immutable
48
51
  end
49
52
  end
50
53
 
54
+ def test_each
55
+ a = []
56
+ Map[].each { |x| a << x }
57
+ assert_equal([], a)
58
+
59
+ a = []
60
+ Map[a: 1, c: 3, b: 2].each { |x| a << x }
61
+ assert_equal([[:a, 1], [:b, 2], [:c, 3]], a)
62
+ end
63
+
51
64
  def test_foldr
52
65
  xs = Map[].foldr(List[]) { |v, ys| Cons[v, ys] }
53
66
  assert_equal(List[], xs)
@@ -0,0 +1,202 @@
1
+ require_relative "../test_helper"
2
+
3
+ with_tailcall_optimization {
4
+ require "immutable/promise"
5
+ require "immutable/list"
6
+ }
7
+
8
+ module Immutable
9
+ class TestPromise < Test::Unit::TestCase
10
+ COUNT = 10000
11
+
12
+ def test_eager
13
+ assert_equal(123, Promise.eager(123).force)
14
+ end
15
+
16
+ def test_delay
17
+ assert_equal(123, Promise.delay { 123 }.force)
18
+ count = 0
19
+ x = Promise.delay { count += 1; 123 }
20
+ assert_equal(0, count)
21
+ assert_equal(123, x.force)
22
+ assert_equal(1, count)
23
+ end
24
+
25
+ def test_memoization1
26
+ count = 0
27
+ s = Promise.delay { count += 1; 1 }
28
+ assert_equal(1, s.force)
29
+ assert_equal(1, s.force)
30
+ assert_equal(1, count)
31
+ end
32
+
33
+ def test_memoization2
34
+ count = 0
35
+ s = Promise.delay { count += 1; 2 }
36
+ assert_equal(4, s.force + s.force)
37
+ assert_equal(1, count)
38
+ end
39
+
40
+ def test_memoization3
41
+ count = 0
42
+ r = Promise.delay { count += 1; 1 }
43
+ s = Promise.lazy { r }
44
+ t = Promise.lazy { s }
45
+ assert_equal(1, t.force)
46
+ assert_equal(1, s.force)
47
+ assert_equal(1, count)
48
+ end
49
+
50
+ def test_memoization4
51
+ stream_drop = ->(s, index) {
52
+ Promise.lazy {
53
+ if index.zero?
54
+ s
55
+ else
56
+ stream_drop[s.force.tail, index - 1]
57
+ end
58
+ }
59
+ }
60
+ count = 0
61
+ ones = -> {
62
+ Promise.delay {
63
+ count += 1
64
+ Cons[1, ones[]]
65
+ }
66
+ }
67
+ s = ones[]
68
+ assert_equal(1, stream_drop[s, 4].force.head)
69
+ assert_equal(1, stream_drop[s, 4].force.head)
70
+ assert_equal(5, count)
71
+ end
72
+
73
+ def test_reentrancy1
74
+ count = 0
75
+ x = 5
76
+ p = Promise.delay {
77
+ count += 1
78
+ if count > x
79
+ count
80
+ else
81
+ p.force
82
+ end
83
+ }
84
+ assert_equal(6, p.force)
85
+ x = 10
86
+ assert_equal(6, p.force)
87
+ end
88
+
89
+ def test_reentrancy2
90
+ first = true
91
+ f = Promise.delay {
92
+ if first
93
+ first = false
94
+ f.force
95
+ else
96
+ :second
97
+ end
98
+ }
99
+ assert_equal(:second, f.force)
100
+ end
101
+
102
+ def test_reentrancy3
103
+ q = -> {
104
+ count = 5
105
+ get_count = -> { count }
106
+ p = Promise.delay {
107
+ if count <= 0
108
+ count
109
+ else
110
+ count -= 1
111
+ p.force
112
+ count += 2
113
+ count
114
+ end
115
+ }
116
+ [get_count, p]
117
+ }[]
118
+ get_count, p = q
119
+ assert_equal(5, get_count[])
120
+ assert_equal(0, p.force)
121
+ assert_equal(10, get_count[])
122
+ end
123
+
124
+ def nloop(n)
125
+ Promise.lazy { n <= 0 ? Promise.eager(0) : nloop(n - 1) }
126
+ end
127
+
128
+ def test_leak1
129
+ assert_equal(0, nloop(COUNT).force)
130
+ end
131
+
132
+ def test_leak2
133
+ s = nloop(COUNT)
134
+ assert_equal(0, s.force)
135
+ end
136
+
137
+ def from(n)
138
+ Promise.delay {
139
+ Cons[n, from(n + 1)]
140
+ }
141
+ end
142
+
143
+ def traverse(s, n)
144
+ Promise.lazy {
145
+ if n <= 0
146
+ s
147
+ else
148
+ traverse(s.force.tail, n - 1)
149
+ end
150
+ }
151
+ end
152
+
153
+ def test_leak3
154
+ assert_equal(COUNT, traverse(from(0), COUNT).force.head)
155
+ end
156
+
157
+ def test_leak4
158
+ s = traverse(from(0), COUNT)
159
+ assert_equal(COUNT, s.force.head)
160
+ end
161
+
162
+ def stream_filter(s, &block)
163
+ Promise.lazy {
164
+ xs = s.force
165
+ if xs.empty?
166
+ Promise.delay { List[] }
167
+ else
168
+ if yield(xs.head)
169
+ Promise.delay { Cons[xs.head, stream_filter(xs.tail, &block)] }
170
+ else
171
+ stream_filter(xs.tail, &block)
172
+ end
173
+ end
174
+ }
175
+ end
176
+
177
+ def test_leak5
178
+ stream_filter(from(0)) { |n| n == COUNT }.force
179
+ end
180
+
181
+ def stream_ref(s, index)
182
+ Promise.lazy {
183
+ xs = s.force
184
+ if xs.empty?
185
+ :error
186
+ else
187
+ if index.zero?
188
+ Promise.delay { xs.head }
189
+ else
190
+ stream_ref(xs.tail, index - 1)
191
+ end
192
+ end
193
+ }
194
+ end
195
+
196
+ def test_leak6
197
+ assert_equal(0, stream_ref(stream_filter(from(0), &:zero?), 0).force)
198
+ s = stream_ref(from(0), COUNT)
199
+ assert_equal(COUNT, s.force)
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,43 @@
1
+ require_relative "../test_helper"
2
+
3
+ with_tailcall_optimization {
4
+ require "immutable/queue"
5
+ }
6
+
7
+ module Immutable
8
+ class TestList < Test::Unit::TestCase
9
+ def test_head
10
+ assert_raise(List::EmptyError) do
11
+ Queue[].head
12
+ end
13
+ assert_equal(1, Queue[1].head)
14
+ assert_equal(1, Queue[1, 2, 3].head)
15
+ end
16
+
17
+ def test_tail
18
+ assert_raise(List::EmptyError) do
19
+ Queue[].tail
20
+ end
21
+ assert(Queue[1].tail.empty?)
22
+ assert_equal(2, Queue[1, 2].tail.head)
23
+ assert_equal(2, Queue[1, 2, 3].tail.head)
24
+ assert_equal(3, Queue[1, 2, 3].tail.tail.head)
25
+ end
26
+
27
+ def test_snoc
28
+ q1 = Queue.empty.snoc(1)
29
+ assert_equal(1, q1.head)
30
+ assert(q1.tail.empty?)
31
+ q2 = q1.snoc(2)
32
+ assert_equal(1, q2.head)
33
+ assert_equal(2, q2.tail.head)
34
+ assert(q2.tail.tail.empty?)
35
+ assert_equal(1, q1.head)
36
+ assert(q1.tail.empty?)
37
+
38
+ a = (1..1000).to_a.shuffle
39
+ q = a.inject(Queue.empty, :snoc)
40
+ assert_equal(a, q.to_a)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,359 @@
1
+ require_relative "../test_helper"
2
+
3
+ with_tailcall_optimization {
4
+ require "immutable/stream"
5
+ }
6
+
7
+ module Immutable
8
+ class TestStream < Test::Unit::TestCase
9
+ def test_s_from_enum
10
+ assert_equal([], Stream.from_enum([]).to_a)
11
+ assert_equal([1, 2, 3], Stream.from_enum([1, 2, 3]).to_a)
12
+ assert_equal(["a", "b", "c"],
13
+ Stream.from_enum("abc".chars).to_a)
14
+ end
15
+
16
+ def test_s_from_enumerator
17
+ e = [1, 2, 3, 4, 5].each
18
+ s1 = Stream.from_enumerator(e)
19
+ s2 = Stream.from_enumerator(e)
20
+ assert_equal(1, s1.head)
21
+ assert_equal(2, s2.head)
22
+ assert_equal(1, s1.head)
23
+ assert_equal([1, 3], s1.take(2).to_a)
24
+ assert_equal(4, s2.drop(1).head)
25
+ assert_equal([1, 3, 5], s1.to_a)
26
+ assert_equal([2, 4], s2.to_a)
27
+ end
28
+
29
+ def test_s_from
30
+ s = Stream.from(1)
31
+ assert_equal(Stream[1], s.take(1))
32
+ assert_equal(Stream[1, 2, 3], s.take(3))
33
+ assert_equal(Stream[1, 3, 5], Stream.from(1, 2).take(3))
34
+ end
35
+
36
+ def test_prepend
37
+ assert_equal(Stream[1], Stream.null.prepend { 1 })
38
+ assert_equal(Stream[1, 2], Stream.null.prepend { 2 }.prepend { 1 })
39
+ end
40
+
41
+ def test_head
42
+ assert_raise(List::EmptyError) do
43
+ Stream.null.head
44
+ end
45
+ assert_equal(1, Stream[1].head)
46
+ assert_equal(1, Stream[1, 2, 3].head)
47
+ end
48
+
49
+ def test_tail
50
+ assert_raise(List::EmptyError) do
51
+ Stream.null.tail
52
+ end
53
+ assert(Stream[1].tail.null?)
54
+ assert_equal([2, 3], Stream[1, 2, 3].tail.to_a)
55
+ end
56
+
57
+ def test_last
58
+ assert_raise(List::EmptyError) do
59
+ Stream.null.last
60
+ end
61
+ assert_equal(1, Stream[1].last)
62
+ assert_equal(3, Stream[1, 2, 3].last)
63
+ end
64
+
65
+ def test_init
66
+ assert_raise(List::EmptyError) do
67
+ Stream.null.init.force
68
+ end
69
+ assert_equal(Stream[], Stream[1].init)
70
+ assert_equal(Stream[1], Stream[1, 2].init)
71
+ assert_equal(Stream[1, 2], Stream[1, 2, 3].init)
72
+ end
73
+
74
+ def test_aref
75
+ s = Stream[1, 2, 3, 4, 5]
76
+ 2.times do
77
+ assert_equal(nil, s[-1])
78
+ assert_equal(1, s[0])
79
+ assert_equal(5, s[4])
80
+ assert_equal(nil, s[5])
81
+ assert_equal(4, s[3])
82
+ end
83
+ end
84
+
85
+ def test_empty?
86
+ assert(Stream[].empty?)
87
+ assert(!Stream[1].empty?)
88
+ assert(!Stream[1, 2, 3].empty?)
89
+ end
90
+
91
+ def test_each
92
+ a = []
93
+ Stream[].each { |x| a << x }
94
+ assert_equal([], a)
95
+
96
+ a = []
97
+ Stream[1, 2, 3].each { |x| a << x }
98
+ assert_equal([1, 2, 3], a)
99
+ end
100
+
101
+ def test_foldr
102
+ assert_equal(0, Stream[].foldr(0, &:+))
103
+ assert_equal(123, Stream[].foldr(123, &:+))
104
+
105
+ assert_equal(6, Stream[1, 2, 3].foldr(0, &:+))
106
+ # 1 - (2 - (3 - 10))
107
+ assert_equal(-8, Stream[1, 2, 3].foldr(10, &:-))
108
+ end
109
+
110
+ def test_foldr1
111
+ assert_raise(List::EmptyError) do
112
+ Stream[].foldr1(&:+)
113
+ end
114
+ assert_equal(1, Stream[1].foldr1(&:+))
115
+ assert_equal(3, Stream[1, 2].foldr1(&:+))
116
+ assert_equal(6, Stream[1, 2, 3].foldr1(&:+))
117
+ assert_equal(2, Stream[1, 2, 3].foldr1(&:-))
118
+ end
119
+
120
+ def test_foldl
121
+ assert_equal(0, Stream[].foldl(0, &:+))
122
+ assert_equal(123, Stream[].foldl(123, &:+))
123
+
124
+ assert_equal(6, Stream[1, 2, 3].foldl(0, &:+))
125
+ # ((10 - 1) - 2) - 3
126
+ assert_equal(4, Stream[1, 2, 3].foldl(10, &:-))
127
+ end
128
+
129
+ def test_foldl1
130
+ assert_raise(List::EmptyError) do
131
+ Stream[].foldl1(&:+)
132
+ end
133
+ assert_equal(1, Stream[1].foldl1(&:+))
134
+ assert_equal(3, Stream[1, 2].foldl1(&:+))
135
+ assert_equal(6, Stream[1, 2, 3].foldl1(&:+))
136
+ assert_equal(-4, Stream[1, 2, 3].foldl1(&:-))
137
+ end
138
+
139
+ def test_eq
140
+ assert(Stream[] == Stream[])
141
+ assert(Stream[] != Stream[1])
142
+ assert(Stream[1] != Stream[])
143
+ assert(Stream[1] == Stream[1])
144
+ assert(Stream[1] != Stream[2])
145
+ assert(Stream["foo"] == Stream["foo"])
146
+ assert(Stream["foo"] != Stream["bar"])
147
+ assert(Stream[1, 2, 3] == Stream[1, 2, 3])
148
+ assert(Stream[1, 2, 3] != Stream[1, 2])
149
+ assert(Stream[1, 2, 3] != Stream[1, 2, 3, 4])
150
+ assert(Stream[Stream[1, 2], Stream[3, 4]] ==
151
+ Stream[Stream[1, 2], Stream[3, 4]])
152
+ assert(Stream[Stream[1, 2], Stream[3, 4]] !=
153
+ Stream[Stream[1, 2], Stream[3]])
154
+ assert(Stream[] != Stream.from(1))
155
+ assert(Stream.from(1) != Stream[])
156
+ assert(Stream[1] != Stream.from(1))
157
+ assert(Stream.from(1) != Stream[1])
158
+ end
159
+
160
+ def test_inspect
161
+ s = Stream[]
162
+ assert_equal('Stream[...]', s.inspect)
163
+ assert_equal(nil, s[0])
164
+ assert_equal('Stream[]', s.inspect)
165
+ s = Stream[1]
166
+ assert_equal('Stream[...]', s.inspect)
167
+ assert_equal(1, s[0])
168
+ assert_equal('Stream[1, ...]', s.inspect)
169
+ assert_equal(nil, s[1])
170
+ assert_equal('Stream[1]', s.inspect)
171
+ s = Stream["foo"]
172
+ assert_equal("foo", s[0])
173
+ assert_equal('Stream["foo", ...]', s.inspect)
174
+ assert_equal(nil, s[1])
175
+ assert_equal('Stream["foo"]', s.inspect)
176
+ s = Stream[1, 2, 3]
177
+ assert_equal('Stream[...]', s.inspect)
178
+ assert_equal(1, s[0])
179
+ assert_equal('Stream[1, ...]', s.inspect)
180
+ assert_equal(2, s[1])
181
+ assert_equal('Stream[1, 2, ...]', s.inspect)
182
+ assert_equal(3, s[2])
183
+ assert_equal('Stream[1, 2, 3, ...]', s.inspect)
184
+ assert_equal(nil, s[3])
185
+ assert_equal('Stream[1, 2, 3]', s.inspect)
186
+ s = Stream[1, 2, 3]
187
+ assert_equal(2, s[1])
188
+ assert_equal('Stream[?, 2, ...]', s.inspect)
189
+ s = Stream[Stream[1, 2], Stream[3, 4]]
190
+ assert_equal(Stream[1, 2], s[0])
191
+ assert_equal(Stream[3, 4], s[1])
192
+ assert_equal(nil, s[2])
193
+ assert_equal('Stream[Stream[1, 2], Stream[3, 4]]',
194
+ s.inspect)
195
+ end
196
+
197
+ def test_length
198
+ assert_equal(0, Stream[].length)
199
+ assert_equal(1, Stream[1].length)
200
+ assert_equal(3, Stream[1, 2, 3].length)
201
+ assert_equal(100, Stream.from(1).take(100).length)
202
+ end
203
+
204
+ def test_plus
205
+ assert_equal(Stream[], Stream[] + Stream[])
206
+ assert_equal(Stream[1, 2, 3], Stream[] + Stream[1, 2, 3])
207
+ assert_equal(Stream[1, 2, 3], Stream[1, 2, 3] + Stream[])
208
+ assert_equal(Stream[1, 2, 3], Stream[1] + Stream[2, 3])
209
+ assert_equal(Stream[1, 2, 3], Stream[1, 2] + Stream[3])
210
+ end
211
+
212
+ def test_flatten
213
+ assert_equal(Stream[], Stream[].flatten)
214
+ assert_equal(Stream[1], Stream[Stream[1]].flatten)
215
+ assert_equal(Stream[Stream[1]],
216
+ Stream[Stream[Stream[1]]].flatten)
217
+ assert_equal(Stream[1, 2, 3], Stream[Stream[1, 2], Stream[3]].flatten)
218
+ assert_equal(Stream[1, 2, 3],
219
+ Stream[Stream[1], Stream[2], Stream[3]].flatten)
220
+ end
221
+
222
+ def test_map
223
+ assert_equal(Stream[], Stream[].map(&:to_s))
224
+ assert_equal(Stream["1", "2", "3"], Stream[1, 2, 3].map(&:to_s))
225
+ end
226
+
227
+ def test_reverse
228
+ assert_equal(Stream[], Stream[].reverse)
229
+ assert_equal(Stream[1], Stream[1].reverse)
230
+ assert_equal(Stream[2, 1], Stream[1, 2].reverse)
231
+ assert_equal(Stream[3, 2, 1], Stream[1, 2, 3].reverse)
232
+ end
233
+
234
+ def test_intersperse
235
+ assert_equal(Stream[], Stream[].intersperse(0))
236
+ assert_equal(Stream[1], Stream[1].intersperse(0))
237
+ assert_equal(Stream[1, 0, 2], Stream[1, 2].intersperse(0))
238
+ assert_equal(Stream[1, 0, 2, 0, 3], Stream[1, 2, 3].intersperse(0))
239
+ assert_equal(Stream[1, 0, 2, 0, 3],
240
+ Stream.from(1).intersperse(0).take(5))
241
+ end
242
+
243
+ def test_intercalate
244
+ assert_equal(Stream[], Stream[].intercalate(Stream[0]))
245
+ assert_equal(Stream[1], Stream[Stream[1]].intercalate(Stream[0]))
246
+ xs = Stream[Stream[1, 2], Stream[3, 4], Stream[5, 6]].
247
+ intercalate(Stream[0])
248
+ assert_equal(Stream[1, 2, 0, 3, 4, 0, 5, 6], xs)
249
+ xs = Stream.from(1, 2).map { |x| Stream[x, x + 1] }.
250
+ intercalate(Stream[0]).take(8)
251
+ assert_equal(Stream[1, 2, 0, 3, 4, 0, 5, 6], xs)
252
+ end
253
+
254
+ def test_find
255
+ assert_equal(nil, Stream[].find(&:odd?))
256
+ assert_equal(1, Stream[1, 2, 3, 4, 5].find(&:odd?))
257
+ assert_equal(2, Stream[1, 2, 3, 4, 5].find(&:even?))
258
+ assert_equal(1, Stream.from(1).find(&:odd?))
259
+ assert_equal(2, Stream.from(1).find(&:even?))
260
+ end
261
+
262
+ def test_filter
263
+ assert_equal(Stream[], Stream[].filter(&:odd?))
264
+ assert_equal(Stream[1, 3, 5], Stream[1, 2, 3, 4, 5].filter(&:odd?))
265
+ assert_equal(Stream[2, 4], Stream[1, 2, 3, 4, 5].filter(&:even?))
266
+ end
267
+
268
+ def test_take
269
+ assert_equal(Stream[], Stream[].take(1))
270
+ assert_equal(Stream[], Stream[1, 2, 3].take(0))
271
+ assert_equal(Stream[], Stream[1, 2, 3].take(-1))
272
+ assert_equal(Stream[1], Stream[1, 2, 3].take(1))
273
+ assert_equal(Stream[1, 2], Stream[1, 2, 3].take(2))
274
+ assert_equal(Stream[1, 2, 3], Stream[1, 2, 3].take(3))
275
+ assert_equal(Stream[1, 2, 3], Stream[1, 2, 3].take(4))
276
+ assert_equal(Stream[], Stream.from(1).take(0))
277
+ assert_equal(Stream[1, 2, 3], Stream.from(1).take(3))
278
+ assert_equal(Stream[0, 2, 4], Stream.from(0, 2).take(3))
279
+ end
280
+
281
+ def test_take_while
282
+ assert_equal(Stream[], Stream[].take_while { true })
283
+ assert_equal(Stream[], Stream[1, 2, 3].take_while { |x| x < 1 })
284
+ assert_equal(Stream[1], Stream[1, 2, 3].take_while { |x| x < 2 })
285
+ assert_equal(Stream[1, 2], Stream[1, 2, 3].take_while { |x| x < 3 })
286
+ assert_equal(Stream[1, 2, 3],
287
+ Stream[1, 2, 3].take_while { |x| x < 4 })
288
+ end
289
+
290
+ def test_drop
291
+ assert_equal(Stream[], Stream[].drop(1))
292
+ assert_equal(Stream[1, 2, 3], Stream[1, 2, 3].drop(0))
293
+ assert_equal(Stream[1, 2, 3], Stream[1, 2, 3].drop(-1))
294
+ assert_equal(Stream[2, 3], Stream[1, 2, 3].drop(1))
295
+ assert_equal(Stream[3], Stream[1, 2, 3].drop(2))
296
+ assert_equal(Stream[], Stream[1, 2, 3].drop(3))
297
+ assert_equal(Stream[], Stream[1, 2, 3].drop(4))
298
+ assert_equal(Stream[6, 7, 8], Stream.from(1).drop(5).take(3))
299
+ end
300
+
301
+ def test_drop_while
302
+ assert_equal(Stream[], Stream[].drop_while { false })
303
+ assert_equal(Stream[1, 2, 3],
304
+ Stream[1, 2, 3].drop_while { |x| x < 1 })
305
+ assert_equal(Stream[2, 3], Stream[1, 2, 3].drop_while { |x| x < 2 })
306
+ assert_equal(Stream[3], Stream[1, 2, 3].drop_while { |x| x < 3 })
307
+ assert_equal(Stream[], Stream[1, 2, 3].drop_while { |x| x < 4 })
308
+ end
309
+
310
+ def test_s_unfoldr
311
+ xs = Stream.unfoldr(3) { |x| x == 0 ? nil : [x, x - 1] }
312
+ assert_equal(Stream[3, 2, 1], xs)
313
+ xs = Stream.unfoldr("foo,bar,baz") { |x|
314
+ if x.empty?
315
+ nil
316
+ else
317
+ y = x.slice(/([^,]*),?/, 1)
318
+ [y, $']
319
+ end
320
+ }
321
+ assert_equal(Stream["foo", "bar", "baz"], xs)
322
+ nats = Stream.unfoldr(0) { |x| [x, x + 1] }
323
+ assert_equal(Stream[0, 1, 2], nats.take(3))
324
+ assert_equal(Stream[0, 1, 2, 3, 4], nats.take(5))
325
+ end
326
+
327
+ def test_zip
328
+ s1 = Stream.from(0)
329
+ s2 = Stream.from(0, 2)
330
+ s3 = Stream.from(0, 3)
331
+ assert_equal(Stream[[0, 0, 0], [1, 2, 3], [2, 4, 6]],
332
+ s1.zip(s2, s3).take(3))
333
+
334
+ s1 = Stream[0, 1, 2]
335
+ s2 = Stream.from(0, 2)
336
+ s3 = Stream.from(0, 3)
337
+ assert_equal(Stream[[0, 0, 0], [1, 2, 3], [2, 4, 6]],
338
+ s1.zip(s2, s3))
339
+ end
340
+
341
+ def test_zip_with
342
+ s1 = Stream.from(0)
343
+ s2 = Stream.from(0, 2)
344
+ s3 = Stream.from(0, 3)
345
+ s = s1.zip_with(s2, s3) { |x, y, z|
346
+ x + y + z
347
+ }
348
+ assert_equal(Stream[0, 6, 12, 18], s.take(4))
349
+
350
+ s1 = Stream[0, 1, 2, 3]
351
+ s2 = Stream.from(0, 2)
352
+ s3 = Stream.from(0, 3)
353
+ s = s1.zip_with(s2, s3) { |x, y, z|
354
+ x + y + z
355
+ }
356
+ assert_equal(Stream[0, 6, 12, 18], s)
357
+ end
358
+ end
359
+ end