totally_lazy 0.0.20 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.idea/.name +1 -0
  3. data/.idea/.rakeTasks +7 -0
  4. data/.idea/compiler.xml +22 -0
  5. data/.idea/encodings.xml +6 -0
  6. data/.idea/misc.xml +19 -0
  7. data/.idea/modules.xml +8 -0
  8. data/.idea/vcs.xml +6 -0
  9. data/.travis.yml +2 -5
  10. data/Gemfile +6 -8
  11. data/Guardfile +2 -17
  12. data/LICENSE +202 -0
  13. data/Rakefile +18 -33
  14. data/VERSION +1 -1
  15. data/contributors.txt +1 -0
  16. data/lib/comparators.rb +9 -0
  17. data/lib/enumerators.rb +74 -0
  18. data/lib/functions.rb +66 -0
  19. data/lib/numbers.rb +38 -0
  20. data/lib/option.rb +38 -268
  21. data/lib/pair.rb +13 -51
  22. data/lib/predicates.rb +5 -0
  23. data/lib/sequence.rb +171 -526
  24. data/lib/strings.rb +13 -0
  25. data/lib/totally_lazy.rb +14 -165
  26. data/readme.md +2 -0
  27. data/spec/option_spec.rb +6 -182
  28. data/spec/sequence_spec.rb +202 -132
  29. data/spec/spec_helper.rb +0 -13
  30. data/totally_lazy.iml +74 -0
  31. metadata +58 -71
  32. data/.document +0 -5
  33. data/.rspec +0 -1
  34. data/LICENSE.txt +0 -20
  35. data/README.md +0 -173
  36. data/lib/any.rb +0 -13
  37. data/lib/functor.rb +0 -92
  38. data/lib/generators.rb +0 -161
  39. data/lib/parallel/parallel.rb +0 -442
  40. data/lib/parallel/processor_count.rb +0 -85
  41. data/lib/predicates/compare.rb +0 -25
  42. data/lib/predicates/conversions.rb +0 -22
  43. data/lib/predicates/numbers.rb +0 -21
  44. data/lib/predicates/predicates.rb +0 -141
  45. data/lib/predicates/where.rb +0 -34
  46. data/lib/predicates/where_processor.rb +0 -13
  47. data/lib/type_check.rb +0 -19
  48. data/lib/utils.rb +0 -9
  49. data/spec/functor_spec.rb +0 -35
  50. data/spec/generators_spec.rb +0 -37
  51. data/spec/pair_spec.rb +0 -44
  52. data/spec/predicate_spec.rb +0 -77
  53. data/spec/serialization_spec.rb +0 -56
  54. data/spec/type_check_spec.rb +0 -20
  55. data/spec/util_spec.rb +0 -10
  56. data/totally_lazy.gemspec +0 -101
@@ -1,230 +1,300 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require_relative 'spec_helper'
2
2
 
3
3
  describe 'Sequence' do
4
-
5
4
  it 'should create empty sequence when iterable is nil' do
6
5
  expect(sequence(nil)).to eq(empty)
7
6
  end
8
7
 
9
- it 'should support transpose' do
10
- expect(sequence(sequence(1, 2), sequence(3, 4), sequence(5, 6)).transpose).to include(sequence(1, 3, 5), sequence(2, 4, 6))
11
- expect { empty.transpose.entries }.to raise_error(NoSuchElementException)
8
+ it 'should support head' do
9
+ expect(sequence(1, 2).head).to eq(1)
12
10
  end
13
11
 
14
- it 'should eagerly return the first element of a sequence, returns NoSuchElementException if empty' do
12
+ it 'should return same result when head called many times' do
13
+ expect(sequence(1, 2).head).to eq(1)
15
14
  expect(sequence(1, 2).head).to eq(1)
16
- expect { empty.head }.to raise_error(NoSuchElementException)
17
15
  end
18
16
 
19
- it 'should eagerly return the first element of a sequence wrapped in a some, returns none if empty' do
20
- expect(sequence(1, 2).head_option).to eq(some(1))
17
+ it 'should support head_option' do
18
+ expect(sequence(1).head_option).to eq(some(1))
21
19
  expect(empty.head_option).to eq(none)
22
20
  end
23
21
 
24
- it 'should eagerly return the last element of a finite sequence, throws NoSuchElementException if empty' do
25
- expect(sequence(1, 2).last).to eq(2)
26
- expect { empty.last }.to raise_error(NoSuchElementException)
22
+ it 'should support reverse' do
23
+ expect(sequence(1, 2, 3).reverse).to eq(sequence(3, 2, 1))
24
+ end
25
+
26
+ it 'should support last' do
27
+ expect(sequence(1, 2, 3).last).to eq(3)
27
28
  end
28
29
 
29
- it 'should eagerly return the last element of a finite sequence wrapped in a some, returns none if empty' do
30
- expect(sequence(1, 2).last_option).to eq(some(2))
30
+ it 'should support last_option' do
31
+ expect(sequence(1, 2, 3).last_option).to eq(some(3))
31
32
  expect(empty.last_option).to eq(none)
32
33
  end
33
34
 
34
- it 'should lazily return the elements except the last one - throws NoSuchElementException if empty. Works with infinite sequences' do
35
+ it 'should support tail' do
35
36
  expect(sequence(1, 2, 3).tail).to eq(sequence(2, 3))
36
- expect { empty.tail.first }.to raise_error(NoSuchElementException)
37
37
  end
38
38
 
39
- it 'should lazily return the elements except the first one - throws NoSuchElementException if empty' do
40
- expect(sequence(1, 2, 3).init).to eq(sequence(1, 2))
41
- expect { empty.init.first }.to raise_error(NoSuchElementException)
39
+ it 'should lazily return tail' do
40
+ expect(Sequence.new((1..Float::INFINITY).lazy).tail.head).to eq(2)
41
+ expect(range_from(100).tail.head).to eq(101)
42
42
  end
43
43
 
44
- it 'should lazily shuffle the elements - throws NoSuchElementException if empty' do
45
- expect(sequence((1..50).to_a).flatten.shuffle.entries).not_to eq(sequence((1..50).to_a).flatten.entries)
46
- expect { empty.shuffle.first }.to raise_error(NoSuchElementException)
44
+ it 'should return empty tail on sequence with 1 item' do
45
+ expect(sequence(1).tail).to eq(empty)
47
46
  end
48
47
 
49
- it 'should flatten the content if possible' do
50
- expect(sequence([1,2,3,[4,5,6]],[7,8,9]).flatten).to eq(sequence(1,2,3,4,5,6,7,8,9))
51
- expect(sequence({:name => 'a', :age => 1},{:up => 2 }).flatten).to eq(sequence(:name,'a',:age,1,:up,2))
48
+ it 'should raise NoSuchElementException when getting a tail of empty' do
49
+ expect { empty.tail }.to raise_error(NoSuchElementException)
52
50
  end
53
51
 
54
- it 'should lazily join sequences together' do
55
- expect(sequence(1, 2, 3).join(sequence(4, 5, 6))).to eq(sequence(1, 2, 3, 4, 5, 6))
56
- expect(empty.join(sequence(1, 2))).to eq(sequence(1, 2))
52
+ it 'should support init' do
53
+ expect(sequence(1, 2, 3).init).to eq(sequence(1, 2))
57
54
  end
58
55
 
59
- it 'should support select' do
60
- expect(sequence(1, 2, 3).filter(even)).to eq(sequence(2))
61
- expect(sequence(1, 2, 3).find_all(even)).to eq(sequence(2))
62
- expect(sequence(1, 2, 3).select(even)).to eq(sequence(2))
63
- expect(sequence(1, 2, 3).filter(&:even?)).to eq(sequence(2))
56
+ it 'should raise NoSuchElementException when getting init of an empty' do
57
+ expect { empty.init }.to raise_error(NoSuchElementException)
64
58
  end
65
59
 
66
60
  it 'should support map' do
67
- expect(sequence(1, 2, 3).map(as_string)).to eq(sequence('1', '2', '3'))
68
- expect(sequence(1, 2, 3).collect(as_string)).to eq(sequence('1', '2', '3'))
69
- expect(sequence(1, 2, 3).map { |x| x.to_s }).to eq(sequence('1', '2', '3'))
61
+ expect(sequence(1, 2, 3).map(->(a) { a*2 })).to eq(sequence(2, 4, 6))
62
+ expect(sequence(1, 2, 3).map { |a| a*2 }).to eq(sequence(2, 4, 6))
70
63
  end
71
64
 
72
- it 'should support reject' do
73
- expect(sequence(1, 2, 3).reject(even)).to eq(sequence(1, 3))
74
- expect(sequence(1, 2, 3).unfilter(even)).to eq(sequence(1, 3))
75
- expect(sequence(1, 2, 3).reject(&:even?)).to eq(sequence(1, 3))
65
+ it 'should ensure map is lazy' do
66
+ result = sequence(returns(1), call_raises(RuntimeError.new)).map(call)
67
+ expect(result.head).to eq(1)
76
68
  end
77
69
 
78
- it 'should support grep' do
79
- expect(sequence('apple', 'pear', 'banana').grep(/p/)).to eq(sequence('apple', 'pear'))
70
+ it 'should support filter' do
71
+ expect(sequence(1, 2, 3, 4).filter(even)).to eq(sequence(2, 4))
72
+ expect(sequence(1, 2, 3, 4).filter { |value| even.(value) }).to eq(sequence(2, 4))
80
73
  end
81
74
 
82
- it 'should support drop' do
83
- expect(sequence(1, 2, 3).drop(1)).to eq(sequence(2, 3))
75
+ it 'should ensure filter is lazy' do
76
+ result = sequence(returns(1), returns(2), call_raises(RuntimeError.new)).map(call).filter(even)
77
+ expect(result.head).to eq(2)
84
78
  end
85
79
 
86
- it 'should support drop_while' do
87
- expect(sequence(1, 2, 5, 4, 3).drop_while { |n| n < 5 }).to eq(sequence(5, 4, 3))
80
+ it 'should support composite predicates' do
81
+ expect(sequence(1, 2, 3, 4).filter(Predicates::not(even))).to eq(sequence(1, 3))
88
82
  end
89
83
 
90
- it 'should support take' do
91
- expect(sequence(1, 2, 3).take(2)).to eq(sequence(1, 2))
84
+ it 'should support reject' do
85
+ expect(sequence(1, 2, 3, 4).reject(even)).to eq(sequence(1, 3))
86
+ expect(sequence(1, 2, 3, 4).reject { |value| even.(value) }).to eq(sequence(1, 3))
92
87
  end
93
88
 
94
- it 'should support take_while' do
95
- expect(sequence(1, 2, 5, 4, 3).take_while { |n| n < 5 }).to eq(sequence(1, 2))
89
+ it 'should support fold (aka fold_left)' do
90
+ expect(sequence(1, 2, 3).fold(0, sum)).to eq(6)
91
+ expect(sequence(1, 2, 3).fold(0) { |a, b| a + b }).to eq(6)
92
+ expect(sequence(1, 2, 3).fold_left(0, sum)).to eq(6)
93
+ expect(sequence(1, 2, 3).fold_left(0) { |a, b| a + b }).to eq(6)
94
+ expect(sequence('1', '2', '3').fold(0, join)).to eq('0123')
95
+ expect(sequence('1', '2', '3').fold_left(0, join)).to eq('0123')
96
96
  end
97
97
 
98
- it 'should support flat_map' do
99
- expect(sequence(sequence(1, 2), sequence(3, 4)).flat_map { |s| s+1 }).to eq(sequence(2, 3, 4, 5))
100
- expect(sequence(sequence(1, 2), sequence(3, 4)).flat_map { |s| s }).to eq(sequence(1, 2, 3, 4))
101
- expect(sequence(pair(1, 2), pair(3, 4)).flat_map { |s| s }).to eq(sequence(1, 2, 3, 4))
102
- expect(sequence(some(1),none,some(2)).flat_map { |s| s }).to eq(sequence(1,2))
98
+ it 'should support reduce (aka reduce_left)' do
99
+ expect(sequence(1, 2, 3).reduce(sum)).to eq(6)
100
+ expect(sequence(1, 2, 3).reduce { |a, b| a + b }).to eq(6)
101
+ expect(sequence(1, 2, 3).reduce_left(sum)).to eq(6)
102
+ expect(sequence(1, 2, 3).reduce_left { |a, b| a + b }).to eq(6)
103
+ expect(sequence('1', '2', '3').reduce(join)).to eq('123')
104
+ expect(sequence('1', '2', '3').reduce_left(join)).to eq('123')
103
105
  end
104
106
 
105
- it 'should support zip' do
106
- expect(sequence(1, 2, 3).zip(sequence('a', 'b', 'c'))).to eq(sequence([1, 'a'], [2, 'b'], [3, 'c']))
107
- expect(sequence(1, 2, 3).zip(sequence(4, 5, 6)) { |x| x.reduce(:+) }).to eq(sequence(5, 7, 9))
107
+ it 'should support fold_right' do
108
+ expect(empty.fold_right(4, sum)).to eq(4)
109
+ expect(sequence(1).fold_right(4, sum)).to eq(5)
110
+ expect(sequence(1, 2).fold_right(4, sum)).to eq(7)
111
+ expect(sequence(1, 2, 3).fold_right(4, sum)).to eq(10)
112
+ expect(sequence(1, 2, 3).fold_right(4) { |a, b| a + b }).to eq(10)
113
+ expect(empty.fold_right('4', join)).to eq('4')
114
+ expect(sequence('1').fold_right('4', join)).to eq('14')
115
+ expect(sequence('1', '2').fold_right('4', join)).to eq('124')
116
+ expect(sequence('1', '2', '3').fold_right('4', join)).to eq('1234')
108
117
  end
109
118
 
110
- it 'should support item access with get' do
111
- expect(sequence(1, 2, 3).get(2)).to eq(3)
112
- expect(sequence(1, 2, 3)[2]).to eq(3)
119
+ it 'should support reduce_right' do
120
+ # expect(sequence().reduce_right(sum)).to eq(0) <-- need a monoid to do this
121
+ expect(sequence(1).reduce_right(sum)).to eq(1)
122
+ expect(sequence(1, 2).reduce_right(sum)).to eq(3)
123
+ expect(sequence(1, 2, 3).reduce_right(sum)).to eq(6)
124
+ expect(sequence(1, 2, 3).reduce_right { |a, b| a+b }).to eq(6)
125
+ # expect(sequence().reduce_right(join)).to eq('') <-- need a monoid to do this
126
+ expect(sequence('1').reduce_right(join)).to eq('1')
127
+ expect(sequence('1', '2').reduce_right(join)).to eq('12')
128
+ expect(sequence('1', '2', '3').reduce_right(join)).to eq('123')
113
129
  end
114
130
 
115
- it 'should join the supplied sequence to the existing sequence' do
116
- expect(sequence(1, 2, 3).join(sequence(4, 5, 6))).to eq(sequence(1, 2, 3, 4, 5, 6))
117
- expect(sequence(1, 2, 3) << sequence(4, 5, 6)).to eq(sequence(1, 2, 3, 4, 5, 6))
131
+ it 'should support find' do
132
+ expect(empty.find(even)).to eq(none)
133
+ expect(sequence(1, 3, 5).find(even)).to eq(none)
134
+ expect(sequence(1, 2, 3).find(even)).to eq(some(2))
135
+ expect(sequence(1, 2, 3).find { |value| even.(value) }).to eq(some(2))
118
136
  end
119
137
 
120
- it 'should append an item to the sequence (creates new sequence)' do
121
- expect(sequence(1, 2, 3).append(4)).to eq(sequence(1, 2, 3, 4))
138
+ it 'should support find_index_of' do
139
+ expect(sequence(1, 3, 5).find_index_of(even)).to eq(none)
140
+ expect(sequence(1, 3, 6).find_index_of(even)).to eq(some(2))
141
+ expect(sequence(1, 3, 6).find_index_of { |value| even.(value) }).to eq(some(2))
122
142
  end
123
143
 
124
- it 'should add any item to the sequence (creates new sequence)' do
125
- expect(sequence(1, 2, 3).add(sequence(4, 5, 6))).to eq(sequence(1, 2, 3, 4, 5, 6))
126
- expect(sequence(1, 2, 3) + sequence(4, 5, 6)).to eq(sequence(1, 2, 3, 4, 5, 6))
144
+ it 'should support finding the first some' do
145
+ expect(sequence(none, some(2), some(3)).flat_map(identity).head_option).to eq(some(2))
127
146
  end
128
147
 
129
- it 'should convert a sequence of sequences into a single flattened sequence' do
130
- expect(sequence(sequence(1,2,3), sequence(4), sequence(5,6,7)).to_seq).to eq(sequence(1, 2, 3, 4, 5, 6,7))
131
- expect{ sequence(1,2,3).to_seq.entries }.to raise_error(UnsupportedTypeException)
148
+ it 'should support zip_with_index' do
149
+ expect(sequence('Dan', 'Kings', 'Raymond').zip_with_index).to eq(sequence(pair(0, 'Dan'), pair(1, 'Kings'), pair(2, 'Raymond')))
132
150
  end
133
151
 
134
- it 'should create a sequence of sequences from a sequence of pairs' do
135
- expect(sequence(pair(1,2),pair(3,4),pair(5,6)).from_pairs).to eq(sequence(1, 2, 3, 4, 5, 6))
136
- expect {sequence({1=>2}).from_pairs.entries}.to raise_error(UnsupportedTypeException)
152
+ it 'should support zip' do
153
+ sequence = sequence(1, 3, 5)
154
+ expect(sequence.zip(sequence(2, 4, 6, 8))).to eq(sequence(pair(1, 2), pair(3, 4), pair(5, 6)))
155
+ expect(sequence.zip(sequence(2, 4, 6))).to eq(sequence(pair(1, 2), pair(3, 4), pair(5, 6)))
156
+ expect(sequence.zip(sequence(2, 4))).to eq(sequence(pair(1, 2), pair(3, 4)))
137
157
  end
138
158
 
139
- it 'should convert a sequence to an array' do
140
- expect(sequence(1, 2, 3).to_a).to eq([1,2,3])
141
- expect(sequence(pair(1,2),pair(3,4)).to_a).to eq([{1=>2},{3=>4}])
142
- expect(empty.to_a).to eq([])
159
+ it 'should support take' do
160
+ sequence = sequence(1, 2, 3).take(2)
161
+ expect(sequence).to eq(sequence(1, 2))
162
+ expect(sequence(1).take(2)).to eq(sequence(1))
163
+ expect(empty.take(2)).to eq(empty)
143
164
  end
144
165
 
145
- it 'should get or else the value at an index' do
146
- expect(sequence(1, 2, 3).get_or_else(0,99)).to eq(1)
147
- expect(sequence(1, 2, 3).get_or_else(99,1)).to eq(1)
166
+ it 'should not take more than it needs' do
167
+ sequence = repeat_fn(-> { raise RuntimeError }).take(0)
168
+ expect(sequence.is_empty?).to eq(true)
169
+ expect(sequence.size).to eq(0)
148
170
  end
149
171
 
150
- it 'should get or else the value at an index' do
151
- expect(sequence(1, 2, 3).get_or_throw(1,Exception,'oops')).to eq(2)
152
- expect {sequence(1, 2, 3).get_or_throw(99,Exception,'oops')}.to raise_error(Exception)
153
- end
154
-
155
- it 'should get an option at an index' do
156
- expect(sequence(1, 2, 3).get_option(1)).to eq(some(2))
157
- expect(sequence(1, 2, 3).get_option(99)).to eq(none)
172
+ it 'should support take_while' do
173
+ sequence = sequence(1, 3, 5, 6, 8, 1, 3)
174
+ expect(sequence.take_while(odd)).to eq(sequence(1, 3, 5))
175
+ expect(sequence.take_while { |value| odd.(value) }).to eq(sequence(1, 3, 5))
176
+ expect(sequence(1).take_while(odd)).to eq(sequence(1))
177
+ expect(empty.take_while(odd)).to eq(empty)
158
178
  end
159
179
 
160
- it 'should return all as flattened array' do
161
- expect(sequence(sequence(1, 2, 3),sequence(4,5,6)).all).to eq([1,2,3,4,5,6])
180
+
181
+ it 'should support size' do
182
+ expect(range(10000000000, 10000000099).size).to eq(100)
162
183
  end
163
184
 
164
- it 'should iterate empty' do
165
- expect(empty.each{|i| i}).to eq([])
166
- expect(Empty.new([1,2]).each{|i| i}).to eq([1,2])
167
- expect(Empty.new([1,2]){|a| a}).to eq(empty)
185
+ it 'should support repeat' do
186
+ expect(Sequences.repeat(10).take(5)).to eq(sequence(10, 10, 10, 10, 10))
187
+ expect(Sequences.repeat_fn(returns(20)).take(5)).to eq(sequence(20, 20, 20, 20, 20))
168
188
  end
169
189
 
170
- it 'should support from_arrays' do
171
- expect(sequence([1,2,3,4,5],[6,7]).from_arrays).to eq(sequence(1,2,3,4,5,6,7))
190
+ it 'should support is_empty?' do
191
+ expect(empty.is_empty?).to be(true)
192
+ expect(sequence(1).is_empty?).to be(false)
172
193
  end
173
194
 
174
- it 'should support from_sets' do
175
- expect(sequence(Set.new([1,2,3,4,5]),Set.new([6,7])).from_sets.entries).to eq(sequence(1,2,3,4,5,6,7).entries)
195
+ it 'should support flat_map' do
196
+ expect(sequence('Hello').flat_map(to_characters)).to eq(sequence('H', 'e', 'l', 'l', 'o'))
197
+ expect(sequence(sequence(1, 2), sequence(3, 4)).flat_map { |s| s.map { |v| v+1 } }).to eq(sequence(2, 3, 4, 5))
198
+ expect(sequence(sequence(1, 2), sequence(3, 4)).flat_map { |s| s }).to eq(sequence(1, 2, 3, 4))
199
+ expect(sequence(pair(1, 2), pair(3, 4)).flat_map { |s| s }).to eq(sequence(1, 2, 3, 4))
200
+ expect(sequence(some(1), none, some(2)).flat_map { |s| s }).to eq(sequence(1, 2))
201
+ end
202
+
203
+ it 'should raise exception if you try to use both lambda and block' do
204
+ expect { empty.map(->(a) { a+1 }) { |b| b+2 } }.to raise_error(RuntimeError)
205
+ expect { empty.map_concurrently(->(a) { a+1 }) { |b| b+2 } }.to raise_error(RuntimeError)
206
+ expect { empty.flat_map(->(a) { a+1 }) { |b| b+2 } }.to raise_error(RuntimeError)
207
+ expect { empty.fold(0, ->(a, b) { a+b }) { |a, b| a+b } }.to raise_error(RuntimeError)
208
+ expect { empty.fold_left(0, ->(a, b) { a+b }) { |a, b| a+b } }.to raise_error(RuntimeError)
209
+ expect { empty.fold_right(0, ->(a, b) { a+b }) { |a, b| a+b } }.to raise_error(RuntimeError)
210
+ expect { empty.reduce(->(a, b) { a+b }) { |a, b| a+b } }.to raise_error(RuntimeError)
211
+ expect { empty.reduce_left(->(a, b) { a+b }) { |a, b| a+b } }.to raise_error(RuntimeError)
212
+ expect { empty.reduce_right(->(a, b) { a+b }) { |a, b| a+b } }.to raise_error(RuntimeError)
213
+ expect { empty.find(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
214
+ expect { empty.find_index_of(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
215
+ expect { empty.take_while(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
216
+ expect { empty.drop_while(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
217
+ expect { empty.exists?(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
218
+ expect { empty.for_all?(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
219
+ expect { empty.filter(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
220
+ expect { empty.reject(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
221
+ expect { empty.group_by(->(_) { true }) { |_| true } }.to raise_error(RuntimeError)
222
+ expect { empty.each(->(v) { puts(v) }) { |v| puts(v) } }.to raise_error(RuntimeError)
223
+ end
224
+
225
+ it 'should support flatten' do
226
+ expect(sequence('Hello').map(to_characters).flatten).to eq(sequence('H', 'e', 'l', 'l', 'o'))
227
+ expect(sequence(some(1), none, some(3)).flatten).to eq(sequence(1, 3))
176
228
  end
177
229
 
178
- it 'should map concurrently' do
179
- expect(sequence(1,2,3,4,5).map_concurrently(even)).to eq(sequence(2,4))
180
- expect(sequence(1,2,3,4,5).map_concurrently{|i| i+1}).to eq(sequence(2,3,4,5,6))
181
- expect(sequence(1,2,3,4,5).map_concurrently(even,in_threads:2)).to eq(sequence(2,4))
182
- expect(sequence(1,2,3,4,5).map_concurrently(where(is even),in_processes:2)).to eq(sequence(2,4))
183
- expect(sequence(1,2,3,4,5).map_concurrently(nil,in_threads:2){|i| i+1}).to eq(sequence(2,3,4,5,6))
230
+ it 'should support drop' do
231
+ expect(sequence(1, 2, 3).drop(2)).to eq(sequence(3))
232
+ expect(sequence(1).drop(2)).to eq(empty)
233
+ expect(empty.drop(1)).to eq(empty)
184
234
  end
185
235
 
186
- it 'should each concurrently' do
187
- expect(sequence(1,2,3).each_concurrently{|i| i }).to eq([1,2,3])
236
+ it 'should support drop_while' do
237
+ sequence = sequence(1, 3, 5, 6, 8, 1, 3)
238
+ expect(sequence.drop_while(odd)).to eq(sequence(6, 8, 1, 3))
239
+ expect(sequence.drop_while { |value| odd.(value) }).to eq(sequence(6, 8, 1, 3))
240
+ expect(sequence(1).drop_while(odd)).to eq(empty)
241
+ expect(empty.drop_while(odd)).to eq(empty)
188
242
  end
189
243
 
190
- it 'should drop nils' do
191
- expect(sequence(1,nil,2,nil,3).drop_nil).to eq(sequence(1,2,3))
244
+ it 'should support sort' do
245
+ expect(sort(sequence(5, 6, 1, 3, 4, 2))).to eq(sequence(1, 2, 3, 4, 5, 6))
246
+ expect(sort(sequence('Matt', 'Dan', 'Bob'))).to eq(sequence('Bob', 'Dan', 'Matt'))
192
247
  end
193
248
 
194
- it 'should cycle' do
195
- expect(sequence(1,2,3).cycle.take(6)).to eq(sequence(1,2,3,1,2,3))
249
+ it 'should support sort descending' do
250
+ expect(sort(sequence(5, 6, 1, 3, 4, 2), descending)).to eq(sequence(6, 5, 4, 3, 2, 1))
251
+ expect(sequence(5, 6, 1, 3, 4, 2).sort_by(descending)).to eq(sequence(6, 5, 4, 3, 2, 1))
252
+ expect(sort(sequence('Bob', 'Dan', 'Matt'), descending)).to eq(sequence('Matt', 'Dan', 'Bob'))
253
+ expect(sequence('Bob', 'Dan', 'Matt').sort_by(descending)).to eq(sequence('Matt', 'Dan', 'Bob'))
196
254
  end
197
255
 
198
- it 'should get pairs from sequence' do
199
- expect(sequence(:name,'kings',:age,39).in_pairs.to_a).to eq(sequence(pair(:name,'kings'),pair(:age,39)).to_a)
256
+ it 'should support contains' do
257
+ expect(sequence(1, 3, 5).contains?(2)).to eq(false)
258
+ expect(sequence(1, 2, 3).contains?(2)).to eq(true)
200
259
  end
201
260
 
202
- it 'should update items in a sequence' do
203
- expect(Seq.repeat(->{OpenStruct.new(name:Any.string(5),age:Any.int(2))}).take(100000).update(age:11,name:'woops').take(10).map{|s| [s.name,s.age]}.head).to eq(['woops',11])
204
- expect(Seq.range(1,10).filter(odd).update(2)).to eq(sequence(2,2,2,2,2))
261
+ it 'should support exists' do
262
+ expect(sequence(1, 3, 5).exists?(even)).to eq(false)
263
+ expect(sequence(1, 3, 5).exists? { |value| even.(value) }).to eq(false)
264
+ expect(sequence(1, 2, 3).exists?(even)).to eq(true)
205
265
  end
206
266
 
207
- it 'should sort by attributes' do
208
- expect(sequence(pair(:a,1),pair(:d,4),pair(:c,3),pair(:b,2)).sorting_by{|e| e.value }.to_a).to eq([{:a=>1}, {:b=>2}, {:c=>3}, {:d=>4}])
209
- expect(sequence(pair(:a,1),pair(:d,4),pair(:c,3),pair(:b,2)).sorting_by(:value).to_a).to eq([{:a=>1}, {:b=>2}, {:c=>3}, {:d=>4}])
210
- expect(sequence(
211
- OpenStruct.new(first_name:'David',age:19,job:'computers'),
212
- OpenStruct.new(first_name:'Chris',age:19,job:'art'),
213
- OpenStruct.new(first_name:'Andrew',age:32,job:'dancing'),
214
- OpenStruct.new(first_name:'Andrew',age:18,job:'dancing'),
215
- ).sorting_by{|e| [e.first_name,e.age] }.map{|e| [e.first_name,e.age,e.job]}.to_a).to eq([['Andrew', 18, 'dancing'], ['Andrew', 32, 'dancing'], ['Chris', 19, 'art'], ['David', 19, 'computers']])
267
+ it 'should support for_all' do
268
+ expect(sequence(1, 3, 5).for_all?(odd)).to eq(true)
269
+ expect(sequence(1, 3, 5).for_all? { |value| odd.(value) }).to eq(true)
270
+ expect(sequence(1, 2, 3).for_all?(odd)).to eq(false)
216
271
  end
217
272
 
218
- it 'should sort' do
219
- expect(sequence(5,2,3,1,4).sorting).to eq(sequence(1,2,3,4,5))
273
+ it 'should support group_by and preserve order' do
274
+ groups_fn = sequence(1, 2, 3, 4).group_by(mod(2))
275
+ expect(groups_fn.first).to eq(group(1, sequence(1, 3).enumerator))
276
+ expect(groups_fn.second).to eq(group(0, sequence(2, 4).enumerator))
277
+
278
+ groups_block = sequence(1, 2, 3, 4).group_by { |value| mod(2).(value) }
279
+ expect(groups_block.first).to eq(group(1, sequence(1, 3).enumerator))
280
+ expect(groups_block.second).to eq(group(0, sequence(2, 4).enumerator))
220
281
  end
221
282
 
222
- it 'should convert sequence to a map' do
223
- expect(sequence('apple',1,'pear',2).to_map).to eq({apple:1,pear:2})
283
+ it 'should support each' do
284
+ sum = 0
285
+ sequence(1, 2).each(->(value) { sum = sum + value })
286
+ expect(sum).to eq(3)
287
+
288
+ sequence(3, 4).each { |value| sum = sum + value }
289
+ expect(sum).to eq(10)
224
290
  end
225
291
 
226
- it 'should convert from an array to a seq' do
227
- expect([1,2,3].to_seq).to eq(sequence(1,2,3))
292
+ it 'should support map_concurrently' do
293
+ strings = sequence(1, 2).map_concurrently(to_string)
294
+ expect(strings).to eq(sequence('1', '2'))
295
+
296
+ strings_block = sequence(1, 2).map_concurrently { |value| to_string.(value) }
297
+ expect(strings_block).to eq(sequence('1', '2'))
228
298
  end
229
299
 
230
300
 
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,3 @@
1
- require 'coveralls'
2
- Coveralls.wear!
3
-
4
- require 'simplecov'
5
-
6
- SimpleCov.configure do
7
- load_profile 'test_frameworks'
8
- end
9
-
10
- ENV["COVERAGE"] && SimpleCov.start do
11
- add_filter "/.rvm/"
12
- add_filter "parallel"
13
- end
14
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
16
3
 
data/totally_lazy.iml ADDED
@@ -0,0 +1,74 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="FacetManager">
4
+ <facet type="gem" name="Ruby Gem">
5
+ <configuration>
6
+ <option name="GEM_APP_ROOT_PATH" value="" />
7
+ <option name="GEM_APP_TEST_PATH" value="" />
8
+ <option name="GEM_APP_LIB_PATH" value="" />
9
+ </configuration>
10
+ </facet>
11
+ </component>
12
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
13
+ <exclude-output />
14
+ <content url="file://$MODULE_DIR$">
15
+ <sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
16
+ <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
17
+ </content>
18
+ <orderEntry type="jdk" jdkName="RVM: ruby-2.1.4 [global]" jdkType="RUBY_SDK" />
19
+ <orderEntry type="sourceFolder" forTests="false" />
20
+ <orderEntry type="library" scope="PROVIDED" name="activesupport (v4.2.5.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="addressable (v2.4.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
23
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v1.11.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
24
+ <orderEntry type="library" scope="PROVIDED" name="coderay (v1.1.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
25
+ <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.0.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
26
+ <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby-edge (v0.2.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
27
+ <orderEntry type="library" scope="PROVIDED" name="descendants_tracker (v0.0.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
28
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
29
+ <orderEntry type="library" scope="PROVIDED" name="faraday (v0.9.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
30
+ <orderEntry type="library" scope="PROVIDED" name="ffi (v1.9.10, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
31
+ <orderEntry type="library" scope="PROVIDED" name="formatador (v0.2.5, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
32
+ <orderEntry type="library" scope="PROVIDED" name="git (v1.2.9.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
33
+ <orderEntry type="library" scope="PROVIDED" name="github_api (v0.13.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
34
+ <orderEntry type="library" scope="PROVIDED" name="guard (v2.13.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
35
+ <orderEntry type="library" scope="PROVIDED" name="guard-compat (v1.2.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
36
+ <orderEntry type="library" scope="PROVIDED" name="guard-rspec (v4.6.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
37
+ <orderEntry type="library" scope="PROVIDED" name="hashie (v3.4.3, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
38
+ <orderEntry type="library" scope="PROVIDED" name="highline (v1.7.8, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
39
+ <orderEntry type="library" scope="PROVIDED" name="i18n (v0.7.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
40
+ <orderEntry type="library" scope="PROVIDED" name="jeweler (v2.0.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
41
+ <orderEntry type="library" scope="PROVIDED" name="json (v1.8.3, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
42
+ <orderEntry type="library" scope="PROVIDED" name="jwt (v1.5.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
43
+ <orderEntry type="library" scope="PROVIDED" name="listen (v3.0.6, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
44
+ <orderEntry type="library" scope="PROVIDED" name="lumberjack (v1.0.10, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
45
+ <orderEntry type="library" scope="PROVIDED" name="method_source (v0.8.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
46
+ <orderEntry type="library" scope="PROVIDED" name="mini_portile2 (v2.0.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
47
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.8.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
48
+ <orderEntry type="library" scope="PROVIDED" name="multi_json (v1.11.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
49
+ <orderEntry type="library" scope="PROVIDED" name="multi_xml (v0.5.5, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
50
+ <orderEntry type="library" scope="PROVIDED" name="multipart-post (v2.0.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
51
+ <orderEntry type="library" scope="PROVIDED" name="nenv (v0.3.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
52
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.6.7.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
53
+ <orderEntry type="library" scope="PROVIDED" name="notiffany (v0.0.8, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
54
+ <orderEntry type="library" scope="PROVIDED" name="oauth2 (v1.1.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
55
+ <orderEntry type="library" scope="PROVIDED" name="pry (v0.10.3, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
56
+ <orderEntry type="library" scope="PROVIDED" name="rack (v1.6.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
57
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.3.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
58
+ <orderEntry type="library" scope="PROVIDED" name="rb-fsevent (v0.9.7, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
59
+ <orderEntry type="library" scope="PROVIDED" name="rb-inotify (v0.9.7, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
60
+ <orderEntry type="library" scope="PROVIDED" name="rdoc (v4.2.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
61
+ <orderEntry type="library" scope="PROVIDED" name="rouge (v1.10.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
62
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v3.0.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
63
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.0.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
64
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.0.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
65
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.0.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
66
+ <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.0.4, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
67
+ <orderEntry type="library" scope="PROVIDED" name="rspec_html_formatter (v0.3.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
68
+ <orderEntry type="library" scope="PROVIDED" name="shellany (v0.0.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
69
+ <orderEntry type="library" scope="PROVIDED" name="slop (v3.6.0, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
70
+ <orderEntry type="library" scope="PROVIDED" name="thor (v0.19.1, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
71
+ <orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.5, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
72
+ <orderEntry type="library" scope="PROVIDED" name="tzinfo (v1.2.2, RVM: ruby-2.1.4 [global]) [gem]" level="application" />
73
+ </component>
74
+ </module>