immutable 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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