totally_lazy 0.0.20 → 0.1.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.
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>