huge_enumerable 0.0.2 → 0.1.1
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.
- checksums.yaml +5 -5
- data/lib/huge_enumerable/version.rb +3 -4
- data/lib/huge_enumerable.rb +31 -19
- metadata +48 -69
- data/.gitignore +0 -21
- data/huge_enumerable.gemspec +0 -28
- data/spec/lib/huge_enumerable/huge_collection_spec.rb +0 -33
- data/spec/lib/huge_enumerable/huge_combination_spec.rb +0 -39
- data/spec/lib/huge_enumerable/huge_permutation_spec.rb +0 -39
- data/spec/lib/huge_enumerable/huge_product_spec.rb +0 -35
- data/spec/lib/huge_enumerable_spec.rb +0 -642
- data/spec/spec_helper.rb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a31b89b4c2cdd80273c579549e27b093fa1723f737dcb5dcf67c8609a930ebc9
|
4
|
+
data.tar.gz: 8de5ac7d85dd81a51349b763768e3d44dba188590c61802b6fb1d8182a5894c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06d6d73e2c3c2218f0b820a64ee9ee8714cfbdff0350fefcb061b9f965692eab828ec38a1dc159d6b7c38027cb40475525e47491a4adad4dd1770a93919935e6
|
7
|
+
data.tar.gz: 4a1e0cbde30ab90bf71c9da8a1d3a180062205ec37e85c21bddbd594401d62ed68c15f4aecb570c60bd5ec385ff14ce0f1ad570adb4b810eb524228c665b4119
|
@@ -1,4 +1,3 @@
|
|
1
|
-
class HugeEnumerable
|
2
|
-
|
3
|
-
|
4
|
-
end
|
1
|
+
class HugeEnumerable
|
2
|
+
VERSION = "0.1.1"
|
3
|
+
end
|
data/lib/huge_enumerable.rb
CHANGED
@@ -106,11 +106,13 @@ class HugeEnumerable
|
|
106
106
|
# If no block is given, an HugeCombination is returned instead.
|
107
107
|
# === Caveat
|
108
108
|
# max_array_size is currently inherited by the generated HugeCombination. This may change in the future.
|
109
|
-
def combination(n) # :yields: element
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
109
|
+
def combination(n, &block) # :yields: element
|
110
|
+
# Check to see if we have a specific random number generator to use.
|
111
|
+
# Using hash comparison as dups, clones, and other actions can make == and eql? return false when it is actually the same method
|
112
|
+
random_number_generator = rng.hash != method(:rand).hash ? rng : nil
|
113
|
+
combo = HugeCombination.new(self.clone.reset!, n, max_array_size, random_number_generator)
|
114
|
+
if block
|
115
|
+
combo.each(&block)
|
114
116
|
self
|
115
117
|
else
|
116
118
|
combo
|
@@ -118,9 +120,15 @@ class HugeEnumerable
|
|
118
120
|
end
|
119
121
|
|
120
122
|
# Calls the given block once for each element in the next array of the collection, passing that element as a parameter.
|
121
|
-
def each # :yields: element
|
123
|
+
def each(&block) # :yields: element
|
122
124
|
# TODO: Return an Enumerator if no block is given
|
123
|
-
remaining_or(max_array_size).times
|
125
|
+
remaining_or(max_array_size).times(&(block << method(:_fetch)))
|
126
|
+
# remaining_or(max_array_size).times { |i| yield _fetch(i) }
|
127
|
+
end
|
128
|
+
|
129
|
+
def initialize_copy(orig)
|
130
|
+
super
|
131
|
+
@rng = @rng.unbind.bind(self) if @rng.respond_to?(:unbind) # Make sure this is bound to self if it is a method
|
124
132
|
end
|
125
133
|
|
126
134
|
def max_array_size #:nodoc:
|
@@ -142,11 +150,13 @@ class HugeEnumerable
|
|
142
150
|
# If no block is given, a HugePermutation is returned instead.
|
143
151
|
# === Caveat
|
144
152
|
# max_array_size is currently inherited by the generated HugePermutation. This may change in the future.
|
145
|
-
def permutation(n) # :yields: element
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
153
|
+
def permutation(n, &block) # :yields: element
|
154
|
+
# Check to see if we have a specific random number generator to use.
|
155
|
+
# Using hash comparison as dups, clones, and other actions can make == and eql? return false when it is actually the same method
|
156
|
+
random_number_generator = rng.hash != method(:rand).hash ? rng : nil
|
157
|
+
perm = HugePermutation.new(self.clone.reset!, n, max_array_size, random_number_generator)
|
158
|
+
if block
|
159
|
+
perm.each(&block)
|
150
160
|
self
|
151
161
|
else
|
152
162
|
perm
|
@@ -165,12 +175,14 @@ class HugeEnumerable
|
|
165
175
|
# === Caveat
|
166
176
|
# max_array_size is currently inherited by the generated HugeProduct. This may change in the future.
|
167
177
|
# other_enumerable is duped and reset if it is a HugeEnumerable. This may change in the future.
|
168
|
-
def product(other_enumerable) # :yields: element
|
169
|
-
other_enumerable = other_enumerable.
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
178
|
+
def product(other_enumerable, &block) # :yields: element
|
179
|
+
other_enumerable = other_enumerable.clone.reset! if other_enumerable.is_a?(HugeEnumerable)
|
180
|
+
# Check to see if we have a specific random number generator to use.
|
181
|
+
# Using hash comparison as dups, clones, and other actions can make == and eql? return false when it is actually the same method
|
182
|
+
random_number_generator = rng.hash != method(:rand).hash ? rng : nil
|
183
|
+
prod = HugeProduct.new(self.clone.reset!, other_enumerable, max_array_size, random_number_generator)
|
184
|
+
if block
|
185
|
+
prod.each(&block)
|
174
186
|
self
|
175
187
|
else
|
176
188
|
prod
|
@@ -221,7 +233,7 @@ class HugeEnumerable
|
|
221
233
|
# ==== Side Effects
|
222
234
|
# The new collection is reset to the current collection's original size and elements before shuffling.
|
223
235
|
def shuffle(rng=nil)
|
224
|
-
self.
|
236
|
+
self.clone.shuffle!(rng)
|
225
237
|
end
|
226
238
|
|
227
239
|
# Randomly reorders the elements of the collection.
|
metadata
CHANGED
@@ -1,99 +1,91 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: huge_enumerable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Hall
|
8
|
-
autorequire:
|
9
|
-
bindir:
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: prime_miller_rabin
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1
|
20
|
-
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ~>
|
19
|
+
version: '0.1'
|
20
|
+
- - ">="
|
25
21
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
-
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
22
|
+
version: 0.1.0
|
23
|
+
type: :runtime
|
35
24
|
prerelease: false
|
36
25
|
version_requirements: !ruby/object:Gem::Requirement
|
37
26
|
requirements:
|
38
|
-
- -
|
27
|
+
- - "~>"
|
39
28
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
29
|
+
version: '0.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.1.0
|
41
33
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
34
|
+
name: bundler
|
43
35
|
requirement: !ruby/object:Gem::Requirement
|
44
36
|
requirements:
|
45
|
-
- - ~>
|
37
|
+
- - "~>"
|
46
38
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2.
|
39
|
+
version: '2.3'
|
48
40
|
type: :development
|
49
41
|
prerelease: false
|
50
42
|
version_requirements: !ruby/object:Gem::Requirement
|
51
43
|
requirements:
|
52
|
-
- - ~>
|
44
|
+
- - "~>"
|
53
45
|
- !ruby/object:Gem::Version
|
54
|
-
version: '2.
|
46
|
+
version: '2.3'
|
55
47
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
48
|
+
name: rake
|
57
49
|
requirement: !ruby/object:Gem::Requirement
|
58
50
|
requirements:
|
59
|
-
- -
|
51
|
+
- - "~>"
|
60
52
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
53
|
+
version: '13'
|
62
54
|
type: :development
|
63
55
|
prerelease: false
|
64
56
|
version_requirements: !ruby/object:Gem::Requirement
|
65
57
|
requirements:
|
66
|
-
- -
|
58
|
+
- - "~>"
|
67
59
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
60
|
+
version: '13'
|
69
61
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
62
|
+
name: rspec
|
71
63
|
requirement: !ruby/object:Gem::Requirement
|
72
64
|
requirements:
|
73
|
-
- -
|
65
|
+
- - "~>"
|
74
66
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
76
|
-
type: :
|
67
|
+
version: '3'
|
68
|
+
type: :development
|
77
69
|
prerelease: false
|
78
70
|
version_requirements: !ruby/object:Gem::Requirement
|
79
71
|
requirements:
|
80
|
-
- -
|
72
|
+
- - "~>"
|
81
73
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
74
|
+
version: '3'
|
83
75
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
76
|
+
name: rdoc
|
85
77
|
requirement: !ruby/object:Gem::Requirement
|
86
78
|
requirements:
|
87
|
-
- -
|
79
|
+
- - "~>"
|
88
80
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
90
|
-
type: :
|
81
|
+
version: '6.4'
|
82
|
+
type: :development
|
91
83
|
prerelease: false
|
92
84
|
version_requirements: !ruby/object:Gem::Requirement
|
93
85
|
requirements:
|
94
|
-
- -
|
86
|
+
- - "~>"
|
95
87
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
88
|
+
version: '6.4'
|
97
89
|
description: Enumerate, sample, shuffle, combine, permutate, and create products of
|
98
90
|
massive data sets using minimal memory
|
99
91
|
email:
|
@@ -102,53 +94,40 @@ executables: []
|
|
102
94
|
extensions: []
|
103
95
|
extra_rdoc_files: []
|
104
96
|
files:
|
105
|
-
- .gitignore
|
106
97
|
- Gemfile
|
107
98
|
- LICENSE.txt
|
108
99
|
- README.md
|
109
100
|
- Rakefile
|
110
|
-
- huge_enumerable.gemspec
|
111
101
|
- lib/huge_enumerable.rb
|
112
102
|
- lib/huge_enumerable/huge_collection.rb
|
113
103
|
- lib/huge_enumerable/huge_combination.rb
|
114
104
|
- lib/huge_enumerable/huge_permutation.rb
|
115
105
|
- lib/huge_enumerable/huge_product.rb
|
116
106
|
- lib/huge_enumerable/version.rb
|
117
|
-
|
118
|
-
- spec/lib/huge_enumerable/huge_combination_spec.rb
|
119
|
-
- spec/lib/huge_enumerable/huge_permutation_spec.rb
|
120
|
-
- spec/lib/huge_enumerable/huge_product_spec.rb
|
121
|
-
- spec/lib/huge_enumerable_spec.rb
|
122
|
-
- spec/spec_helper.rb
|
123
|
-
homepage: https://github.com/ChapterHouse/huge_enumerable.git
|
107
|
+
homepage: https://github.com/ChapterHouse/huge_enumerable
|
124
108
|
licenses:
|
125
109
|
- MIT
|
126
|
-
metadata:
|
127
|
-
|
110
|
+
metadata:
|
111
|
+
homepage_uri: https://github.com/ChapterHouse/huge_enumerable
|
112
|
+
source_code_uri: https://github.com/ChapterHouse/huge_enumerable/tree/v0.1.1
|
113
|
+
post_install_message:
|
128
114
|
rdoc_options: []
|
129
115
|
require_paths:
|
130
116
|
- lib
|
131
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
132
118
|
requirements:
|
133
|
-
- -
|
119
|
+
- - ">="
|
134
120
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
121
|
+
version: 3.0.0
|
136
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
123
|
requirements:
|
138
|
-
- -
|
124
|
+
- - ">="
|
139
125
|
- !ruby/object:Gem::Version
|
140
126
|
version: '0'
|
141
127
|
requirements: []
|
142
|
-
|
143
|
-
|
144
|
-
signing_key:
|
128
|
+
rubygems_version: 3.2.33
|
129
|
+
signing_key:
|
145
130
|
specification_version: 4
|
146
131
|
summary: Enumerate, sample, shuffle, combine, permutate, and create products of massive
|
147
132
|
data sets using minimal memory
|
148
|
-
test_files:
|
149
|
-
- spec/lib/huge_enumerable/huge_collection_spec.rb
|
150
|
-
- spec/lib/huge_enumerable/huge_combination_spec.rb
|
151
|
-
- spec/lib/huge_enumerable/huge_permutation_spec.rb
|
152
|
-
- spec/lib/huge_enumerable/huge_product_spec.rb
|
153
|
-
- spec/lib/huge_enumerable_spec.rb
|
154
|
-
- spec/spec_helper.rb
|
133
|
+
test_files: []
|
data/.gitignore
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
*.gem
|
2
|
-
*.rbc
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
Gemfile.lock
|
6
|
-
InstalledFiles
|
7
|
-
coverage
|
8
|
-
InstalledFiles
|
9
|
-
lib/bundler/man
|
10
|
-
pkg
|
11
|
-
rdoc
|
12
|
-
spec/reports
|
13
|
-
test/tmp
|
14
|
-
test/version_tmp
|
15
|
-
tmp
|
16
|
-
|
17
|
-
# YARD artifacts
|
18
|
-
.yardoc
|
19
|
-
_yardoc
|
20
|
-
doc/
|
21
|
-
.idea
|
data/huge_enumerable.gemspec
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'huge_enumerable/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "huge_enumerable"
|
8
|
-
spec.version = HugeEnumerable::VERSION
|
9
|
-
spec.authors = ["Frank Hall"]
|
10
|
-
spec.email = ["ChapterHouse.Dune@gmail.com"]
|
11
|
-
spec.description = %q{Enumerate, sample, shuffle, combine, permutate, and create products of massive data sets using minimal memory}
|
12
|
-
spec.summary = %q{Enumerate, sample, shuffle, combine, permutate, and create products of massive data sets using minimal memory}
|
13
|
-
spec.homepage = "https://github.com/ChapterHouse/huge_enumerable.git"
|
14
|
-
spec.license = "MIT"
|
15
|
-
|
16
|
-
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
-
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency 'rspec', '~> 2.13'
|
24
|
-
spec.add_development_dependency 'rdoc'
|
25
|
-
spec.add_runtime_dependency "backports" # Wish this could be conditional. It is only used for ruby 1.8 for as long as I support it.
|
26
|
-
spec.add_runtime_dependency "prime_miller_rabin", ">= 0.0.2"
|
27
|
-
|
28
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugeCollection do
|
4
|
-
|
5
|
-
let(:enumerable) { ('a'..'z').to_a }
|
6
|
-
|
7
|
-
subject(:collection) do
|
8
|
-
HugeCollection.send(:public, :collection_size)
|
9
|
-
HugeCollection.send(:public, :fetch)
|
10
|
-
HugeCollection.new(enumerable)
|
11
|
-
end
|
12
|
-
|
13
|
-
context "#collection_size" do
|
14
|
-
|
15
|
-
it "is equal to the original enumerable size" do
|
16
|
-
collection.collection_size.should eql(enumerable.size)
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
context "#fetch" do
|
22
|
-
|
23
|
-
it "returns values in the same order as enumerable[]" do
|
24
|
-
enumerable_fetches = []
|
25
|
-
collection_fetches = []
|
26
|
-
enumerable.size.times { |i| enumerable_fetches << enumerable[i] }
|
27
|
-
collection.collection_size.times { |i| collection_fetches << collection.fetch(i) }
|
28
|
-
collection_fetches.should eql(enumerable_fetches)
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugeCombination do
|
4
|
-
|
5
|
-
let(:enumerable) { ('a'..'z').to_a }
|
6
|
-
let(:combination_size) { 3 }
|
7
|
-
|
8
|
-
subject(:combination) do
|
9
|
-
HugeCombination.send(:public, :collection_size)
|
10
|
-
HugeCombination.send(:public, :fetch)
|
11
|
-
HugeCombination.new(enumerable, combination_size)
|
12
|
-
end
|
13
|
-
|
14
|
-
def enum_combo(x)
|
15
|
-
@cache ||= {}
|
16
|
-
@cache[x.to_i] ||= enumerable.combination(x).to_a
|
17
|
-
end
|
18
|
-
|
19
|
-
context "#collection_size" do
|
20
|
-
|
21
|
-
it "is equal to array#combination.to_a.size" do
|
22
|
-
combination.collection_size.should eql(enum_combo(combination_size).size)
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
context "#fetch" do
|
28
|
-
|
29
|
-
it "returns values in the same order as array#combination.to_a[]" do
|
30
|
-
enum_combo_fetches = []
|
31
|
-
combination_fetches = []
|
32
|
-
enum_combo(combination_size).size.times { |i| enum_combo_fetches << enum_combo(combination_size)[i] }
|
33
|
-
combination.collection_size.times { |i| combination_fetches << combination.fetch(i) }
|
34
|
-
combination_fetches.should eql(enum_combo_fetches)
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugePermutation do
|
4
|
-
|
5
|
-
let(:enumerable) { ('a'..'z').to_a }
|
6
|
-
let(:permutation_size) { 3 }
|
7
|
-
|
8
|
-
subject(:permutation) do
|
9
|
-
HugePermutation.send(:public, :collection_size)
|
10
|
-
HugePermutation.send(:public, :fetch)
|
11
|
-
HugePermutation.new(enumerable, permutation_size)
|
12
|
-
end
|
13
|
-
|
14
|
-
def enum_perm(x)
|
15
|
-
@cache ||= {}
|
16
|
-
@cache[x.to_i] ||= enumerable.permutation(x).to_a
|
17
|
-
end
|
18
|
-
|
19
|
-
context "#collection_size" do
|
20
|
-
|
21
|
-
it "is equal to array#permutation.to_a.size" do
|
22
|
-
permutation.collection_size.should eql(enum_perm(permutation_size).size)
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
context "#fetch" do
|
28
|
-
|
29
|
-
it "returns values in the same order as array#permutation.to_a[]" do
|
30
|
-
enum_perm_fetches = []
|
31
|
-
permutation_fetches = []
|
32
|
-
enum_perm(permutation_size).size.times { |i| enum_perm_fetches << enum_perm(permutation_size)[i] }
|
33
|
-
permutation.collection_size.times { |i| permutation_fetches << permutation.fetch(i) }
|
34
|
-
permutation_fetches.should eql(enum_perm_fetches)
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugeProduct do
|
4
|
-
|
5
|
-
let(:enumerable_a) { ('a'..'z').to_a }
|
6
|
-
let(:enumerable_b) { ('A'..'Z').to_a }
|
7
|
-
let(:enum_prod) { enumerable_a.product(enumerable_b) }
|
8
|
-
|
9
|
-
subject(:product) do
|
10
|
-
HugeProduct.send(:public, :collection_size)
|
11
|
-
HugeProduct.send(:public, :fetch)
|
12
|
-
HugeProduct.new(enumerable_a, enumerable_b)
|
13
|
-
end
|
14
|
-
|
15
|
-
context "#collection_size" do
|
16
|
-
|
17
|
-
it "is equal to array#product(other_ary).size" do
|
18
|
-
product.collection_size.should eql(enum_prod.size)
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
context "#fetch" do
|
24
|
-
|
25
|
-
it "returns values in the same order as array#product(other_ary)[]" do
|
26
|
-
enum_prod_fetches = []
|
27
|
-
product_fetches = []
|
28
|
-
enum_prod.size.times { |i| enum_prod_fetches << enum_prod[i] }
|
29
|
-
product.collection_size.times { |i| product_fetches << product.fetch(i) }
|
30
|
-
product_fetches.should eql(enum_prod_fetches)
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
@@ -1,642 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugeEnumerable do
|
4
|
-
|
5
|
-
let(:collection) { ('a'..'z').to_a }
|
6
|
-
|
7
|
-
subject(:enumerable) do
|
8
|
-
klass = Class.new(HugeEnumerable)
|
9
|
-
enum_collection = collection.sort
|
10
|
-
klass.send(:define_method, :collection_size) { enum_collection.size }
|
11
|
-
klass.send(:define_method, :fetch) { |x| enum_collection[x] }
|
12
|
-
klass.send(:public, :next_prime)
|
13
|
-
klass.send(:public, :_fetch)
|
14
|
-
klass.send(:public, :element_or_array)
|
15
|
-
klass.send(:public, :full_cycle_increment)
|
16
|
-
klass.new
|
17
|
-
end
|
18
|
-
|
19
|
-
subject(:emptied_enumerable) do
|
20
|
-
enumerable.tap do |enum|
|
21
|
-
enum.max_array_size = enum.size
|
22
|
-
enum.next_array
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context ".new" do
|
27
|
-
|
28
|
-
context "with no arguments" do
|
29
|
-
|
30
|
-
it "defaults max_array_size to a Numeric" do
|
31
|
-
enumerable.max_array_size.should be_kind_of(Numeric)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "defaults rng to #rand" do
|
35
|
-
enumerable.rng.should eq(enumerable.method(:rand))
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
context "#[]" do
|
43
|
-
|
44
|
-
context "with a positive index" do
|
45
|
-
it "returns the element from the beginning of the collection at the specified index" do
|
46
|
-
enumerable[3].should eql(collection[3])
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
context "with a negative index" do
|
51
|
-
it "returns the element from the end of the collection at the specified index" do
|
52
|
-
enumerable[-3].should eql(collection[-3])
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context "with an out of bounds index" do
|
57
|
-
it "returns nil" do
|
58
|
-
enumerable[enumerable.size + 1].should be_nil
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context "with a range" do
|
63
|
-
it "returns an array of elements corresponding to indexes within the range" do
|
64
|
-
size = collection.size + 1
|
65
|
-
test_range = (-size..size).to_a
|
66
|
-
ranges = test_range.product(test_range).map { |x| (x.first..x.last) }
|
67
|
-
arrays = ranges.map { |range| [enumerable[range], collection[range]] }
|
68
|
-
arrays.each { |x| x.first.should eq(x.last) }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
context "with a length" do
|
73
|
-
it "returns an array of elements corresponding to starting with index and containing a maximum of length items" do
|
74
|
-
size = collection.size + 1
|
75
|
-
test_range = (-size..size).to_a
|
76
|
-
index_lengths = test_range.product(test_range).map { |x| [x.first, x.last] }
|
77
|
-
arrays = index_lengths.map do |idx_len|
|
78
|
-
index = idx_len.first
|
79
|
-
length = idx_len.last
|
80
|
-
[enumerable[index, length], collection[index, length]]
|
81
|
-
end
|
82
|
-
arrays.each { |x| x.first.should eq(x.last) }
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
|
87
|
-
it "relays to #_fetch for index mapping" do
|
88
|
-
enumerable.should_receive(:_fetch).at_least(:once)
|
89
|
-
enumerable[0]
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
|
94
|
-
context "#each" do
|
95
|
-
|
96
|
-
it "yields #max_array_size items" do
|
97
|
-
items = []
|
98
|
-
total_items = collection.size / 5
|
99
|
-
enumerable.max_array_size = total_items
|
100
|
-
enumerable.each { |x| items << x }
|
101
|
-
items.size.should eql(total_items)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "yields only the remaining items if there are fewer than #max_array_size" do
|
105
|
-
items = []
|
106
|
-
enumerable.max_array_size = collection.size + 1
|
107
|
-
enumerable.each { |x| items << x }
|
108
|
-
items.size.should eql(collection.size)
|
109
|
-
end
|
110
|
-
|
111
|
-
it "relays to #_fetch for index mapping" do
|
112
|
-
enumerable.should_receive(:_fetch).at_least(:once)
|
113
|
-
enumerable.each {}
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
context "#combination" do
|
119
|
-
|
120
|
-
context "with no block" do
|
121
|
-
|
122
|
-
it "returns a new HugeCombination" do
|
123
|
-
enumerable.combination(2).should be_instance_of(HugeCombination)
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
context "with a block" do
|
129
|
-
|
130
|
-
# This should really be calls the block from the combination since there is testing duplication here.
|
131
|
-
# However, knowing where the block is called from would need stack investigation or similar.
|
132
|
-
it "calls the block for each combination element" do
|
133
|
-
combo = enumerable.combination(2)
|
134
|
-
enumerable.max_array_size = combo.size # Hrm. Perhaps having to do this is a reason to have it call collection_each
|
135
|
-
index = 0
|
136
|
-
enumerable.combination(2) do |x|
|
137
|
-
x.should eql(combo[index])
|
138
|
-
index += 1
|
139
|
-
end
|
140
|
-
index.should eql(combo.size)
|
141
|
-
end
|
142
|
-
|
143
|
-
it "returns self" do
|
144
|
-
enumerable.combination(2) {}.should equal(enumerable)
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
it "uses self a dup of itself as the enumerable" do
|
150
|
-
dupped_enumerable = enumerable.dup
|
151
|
-
enumerable.stub(:dup).and_return(dupped_enumerable)
|
152
|
-
HugeCombination.should_receive(:new).with(dupped_enumerable, 2, enumerable.max_array_size, nil)
|
153
|
-
enumerable.combination(2)
|
154
|
-
end
|
155
|
-
|
156
|
-
it "uses the same max array size" do
|
157
|
-
enumerable.combination(2).max_array_size.should eql(enumerable.max_array_size)
|
158
|
-
end
|
159
|
-
|
160
|
-
it "uses the same random number generator" do
|
161
|
-
enumerable.rng = Proc.new { 1 }
|
162
|
-
enumerable.combination(2).rng.should eq(enumerable.rng)
|
163
|
-
end
|
164
|
-
|
165
|
-
it "calls reset! on the dup" do
|
166
|
-
HugeEnumerable.send(:public, :reset!)
|
167
|
-
dupped_enumerable = enumerable.dup
|
168
|
-
enumerable.stub(:dup).and_return(dupped_enumerable)
|
169
|
-
dupped_enumerable.should_receive(:reset!).and_call_original
|
170
|
-
enumerable.combination(2)
|
171
|
-
end
|
172
|
-
|
173
|
-
end
|
174
|
-
|
175
|
-
|
176
|
-
context "#max_array_size" do
|
177
|
-
|
178
|
-
context "not explicitly set" do
|
179
|
-
|
180
|
-
it "defaults to DEFAULT_MAX_ARRAY_SIZE if smaller than #collection_size" do
|
181
|
-
enumerable.stub(:collection_size).and_return(HugeEnumerable::DEFAULT_MAX_ARRAY_SIZE + 1)
|
182
|
-
enumerable.max_array_size.should eql(HugeEnumerable::DEFAULT_MAX_ARRAY_SIZE)
|
183
|
-
end
|
184
|
-
|
185
|
-
it "defaults to #collection_size if smaller than DEFAULT_MAX_ARRAY_SIZE" do
|
186
|
-
enumerable.stub(:collection_size).and_return(HugeEnumerable::DEFAULT_MAX_ARRAY_SIZE - 1)
|
187
|
-
enumerable.max_array_size.should eql(HugeEnumerable::DEFAULT_MAX_ARRAY_SIZE - 1)
|
188
|
-
end
|
189
|
-
|
190
|
-
end
|
191
|
-
|
192
|
-
end
|
193
|
-
|
194
|
-
context "#next_array" do
|
195
|
-
|
196
|
-
it "advances to the next array in the collection" do
|
197
|
-
size = collection.size / 5
|
198
|
-
enumerable.max_array_size = size
|
199
|
-
enumerable.next_array.should eql(collection[size...size*2])
|
200
|
-
end
|
201
|
-
|
202
|
-
it "changes #size" do
|
203
|
-
size = collection.size / 5
|
204
|
-
enumerable.max_array_size = size
|
205
|
-
enumerable.next_array
|
206
|
-
enumerable.size.should eql(collection.size - size)
|
207
|
-
end
|
208
|
-
|
209
|
-
end
|
210
|
-
|
211
|
-
context "#empty?" do
|
212
|
-
|
213
|
-
it "returns true if the collection has been entirely emptied by #pop, #shift, or #next_array" do
|
214
|
-
enumerable.max_array_size = collection.size
|
215
|
-
enumerable.next_array
|
216
|
-
enumerable.empty?.should be_true
|
217
|
-
end
|
218
|
-
|
219
|
-
it "returns false if the collection has been not entirely emptied by #pop, #shift, or #next_array" do
|
220
|
-
enumerable.max_array_size = collection.size - 1
|
221
|
-
enumerable.next_array
|
222
|
-
enumerable.empty?.should be_false
|
223
|
-
end
|
224
|
-
|
225
|
-
end
|
226
|
-
|
227
|
-
context "#permutation" do
|
228
|
-
|
229
|
-
context "with no block" do
|
230
|
-
|
231
|
-
it "returns a new HugePermutation" do
|
232
|
-
enumerable.permutation(2).should be_instance_of(HugePermutation)
|
233
|
-
end
|
234
|
-
|
235
|
-
end
|
236
|
-
|
237
|
-
context "with a block" do
|
238
|
-
|
239
|
-
# This should really be calls the block from the combination since there is testing duplication here.
|
240
|
-
# However, knowing where the block is called from would need stack investigation or similar.
|
241
|
-
it "calls the block for each permutation element" do
|
242
|
-
perm = enumerable.permutation(2)
|
243
|
-
enumerable.max_array_size = perm.size # Hrm. Perhaps having to do this is a reason to have it call collection_each
|
244
|
-
index = 0
|
245
|
-
enumerable.permutation(2) do |x|
|
246
|
-
x.should eql(perm[index])
|
247
|
-
index += 1
|
248
|
-
end
|
249
|
-
index.should eql(perm.size)
|
250
|
-
end
|
251
|
-
|
252
|
-
it "returns self" do
|
253
|
-
enumerable.permutation(2) {}.should equal(enumerable)
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
it "uses self a dup of itself as the enumerable" do
|
259
|
-
dupped_enumerable = enumerable.dup
|
260
|
-
enumerable.stub(:dup).and_return(dupped_enumerable)
|
261
|
-
HugePermutation.should_receive(:new).with(dupped_enumerable, 2, enumerable.max_array_size, nil)
|
262
|
-
enumerable.permutation(2)
|
263
|
-
end
|
264
|
-
|
265
|
-
it "uses the same max array size" do
|
266
|
-
enumerable.permutation(2).max_array_size.should eql(enumerable.max_array_size)
|
267
|
-
end
|
268
|
-
|
269
|
-
it "uses the same random number generator" do
|
270
|
-
enumerable.rng = Proc.new { 1 }
|
271
|
-
enumerable.permutation(2).rng.should eq(enumerable.rng)
|
272
|
-
end
|
273
|
-
|
274
|
-
it "calls reset! on the dup" do
|
275
|
-
HugeEnumerable.send(:public, :reset!)
|
276
|
-
dupped_enumerable = enumerable.dup
|
277
|
-
enumerable.stub(:dup).and_return(dupped_enumerable)
|
278
|
-
dupped_enumerable.should_receive(:reset!).and_call_original
|
279
|
-
enumerable.permutation(2)
|
280
|
-
end
|
281
|
-
|
282
|
-
end
|
283
|
-
|
284
|
-
|
285
|
-
context "#pop" do
|
286
|
-
|
287
|
-
context "on a non empty collection" do
|
288
|
-
context "with no parameter" do
|
289
|
-
it "returns the next element from the end of the collection" do
|
290
|
-
enumerable.pop.should eql(collection.pop)
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
context "with a parameter" do
|
295
|
-
it "returns an array of the next N elements from the end of the collection" do
|
296
|
-
enumerable.pop(3).should eql(collection.pop(3))
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
it "removes the elements from the end of the collection" do
|
301
|
-
enumerable.pop
|
302
|
-
enumerable.pop(3)
|
303
|
-
enumerable.to_a.should eql(collection[0..-5])
|
304
|
-
end
|
305
|
-
|
306
|
-
it "changes #size" do
|
307
|
-
enumerable.pop
|
308
|
-
enumerable.pop(3)
|
309
|
-
enumerable.size.should eql(collection.size - 4)
|
310
|
-
end
|
311
|
-
|
312
|
-
it "does not harm the original collection" do
|
313
|
-
original = collection.dup
|
314
|
-
enumerable.pop
|
315
|
-
enumerable.pop(3)
|
316
|
-
collection.should eql(original)
|
317
|
-
end
|
318
|
-
|
319
|
-
end
|
320
|
-
|
321
|
-
it "depends on #(private)element_or_array" do
|
322
|
-
enumerable.should_receive(:element_or_array).twice.and_call_original
|
323
|
-
enumerable.pop
|
324
|
-
enumerable.pop(3)
|
325
|
-
end
|
326
|
-
|
327
|
-
end
|
328
|
-
|
329
|
-
context "#product" do
|
330
|
-
|
331
|
-
context "with no block" do
|
332
|
-
|
333
|
-
it "returns a new HugeProduct" do
|
334
|
-
enumerable.product([]).should be_instance_of(HugeProduct)
|
335
|
-
end
|
336
|
-
|
337
|
-
end
|
338
|
-
|
339
|
-
context "with a block" do
|
340
|
-
|
341
|
-
# This should really be calls the block from the combination since there is testing duplication here.
|
342
|
-
# However, knowing where the block is called from would need stack investigation or similar.
|
343
|
-
it "calls the block for each product element" do
|
344
|
-
other_enumerable = [1, 2, 3]
|
345
|
-
prod = enumerable.product(other_enumerable)
|
346
|
-
enumerable.max_array_size = prod.size # Hrm. Perhaps having to do this is a reason to have it call collection_each
|
347
|
-
index = 0
|
348
|
-
enumerable.product(other_enumerable) do |x|
|
349
|
-
x.should eql(prod[index])
|
350
|
-
index += 1
|
351
|
-
end
|
352
|
-
index.should eql(prod.size)
|
353
|
-
end
|
354
|
-
|
355
|
-
it "returns self" do
|
356
|
-
enumerable.product([]) {}.should equal(enumerable)
|
357
|
-
end
|
358
|
-
|
359
|
-
end
|
360
|
-
|
361
|
-
it "uses self a dup of itself as the enumerable" do
|
362
|
-
dupped_enumerable = enumerable.dup
|
363
|
-
enumerable.stub(:dup).and_return(dupped_enumerable)
|
364
|
-
other_enumerable = []
|
365
|
-
HugeProduct.should_receive(:new).with(dupped_enumerable, other_enumerable, enumerable.max_array_size, nil)
|
366
|
-
enumerable.product(other_enumerable)
|
367
|
-
end
|
368
|
-
|
369
|
-
it "calls dup on the other enumerable if it is a HugeEnumerable" do
|
370
|
-
other_enumerable = HugeCollection.new([])
|
371
|
-
other_enumerable.should_receive(:dup).and_call_original
|
372
|
-
enumerable.product(other_enumerable)
|
373
|
-
end
|
374
|
-
|
375
|
-
it "calls reset on the other enumerable if it is a HugeEnumerable" do
|
376
|
-
HugeEnumerable.send(:public, :reset!)
|
377
|
-
other_enumerable = HugeCollection.new([])
|
378
|
-
dupped_enumerable = other_enumerable.dup
|
379
|
-
other_enumerable.stub(:dup).and_return(dupped_enumerable)
|
380
|
-
dupped_enumerable.should_receive(:reset!).and_call_original
|
381
|
-
enumerable.product(other_enumerable)
|
382
|
-
end
|
383
|
-
|
384
|
-
it "does not call dup on the other enumerable if it is a HugeEnumerable" do
|
385
|
-
other_enumerable = []
|
386
|
-
other_enumerable.should_not_receive(:dup)
|
387
|
-
enumerable.product(other_enumerable)
|
388
|
-
end
|
389
|
-
|
390
|
-
it "uses the same max array size" do
|
391
|
-
enumerable.product([]).max_array_size.should eql(enumerable.max_array_size)
|
392
|
-
end
|
393
|
-
|
394
|
-
it "uses the same random number generator" do
|
395
|
-
enumerable.rng = Proc.new { 1 }
|
396
|
-
enumerable.product([]).rng.should eq(enumerable.rng)
|
397
|
-
end
|
398
|
-
|
399
|
-
it "calls reset! on the dup" do
|
400
|
-
HugeEnumerable.send(:public, :reset!)
|
401
|
-
dupped_enumerable = enumerable.dup
|
402
|
-
enumerable.stub(:dup).and_return(dupped_enumerable)
|
403
|
-
dupped_enumerable.should_receive(:reset!).and_call_original
|
404
|
-
enumerable.product([])
|
405
|
-
end
|
406
|
-
|
407
|
-
end
|
408
|
-
|
409
|
-
context "#sample" do
|
410
|
-
|
411
|
-
context "on an non empty collection" do
|
412
|
-
context "with no arguments" do
|
413
|
-
it "returns a single element from the collection" do
|
414
|
-
collection.include?(enumerable.sample).should be_true
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
context "with size argument" do
|
419
|
-
it "returns N elements from the collection" do
|
420
|
-
samples = enumerable.sample(3)
|
421
|
-
samples.should have(3).items
|
422
|
-
samples.all? { |item| collection.include?(item) }.should be_true
|
423
|
-
end
|
424
|
-
end
|
425
|
-
|
426
|
-
it "returns elements from the collection in a pseudo random pattern" do
|
427
|
-
enumerable.sample(enumerable.size).should_not eq(collection)
|
428
|
-
end
|
429
|
-
|
430
|
-
it "visits each element exactly once before repeating" do
|
431
|
-
samples = []
|
432
|
-
enumerable.size.times { samples << enumerable.sample }
|
433
|
-
samples.uniq.should have(collection.size).items
|
434
|
-
end
|
435
|
-
|
436
|
-
it "does not reorder the original collection" do
|
437
|
-
original = collection.dup
|
438
|
-
enumerable.sample
|
439
|
-
enumerable.sample(3)
|
440
|
-
collection.should eql(original)
|
441
|
-
end
|
442
|
-
|
443
|
-
end
|
444
|
-
|
445
|
-
it "depends on #(private)element_or_array" do
|
446
|
-
enumerable.should_receive(:element_or_array).twice.and_call_original
|
447
|
-
enumerable.sample
|
448
|
-
enumerable.sample(3)
|
449
|
-
end
|
450
|
-
|
451
|
-
end
|
452
|
-
|
453
|
-
context "#shift" do
|
454
|
-
|
455
|
-
context "on a non empty collection" do
|
456
|
-
context "with no parameter" do
|
457
|
-
it "returns the next element from the beginning of the collection" do
|
458
|
-
enumerable.shift.should eql(collection.shift)
|
459
|
-
end
|
460
|
-
end
|
461
|
-
|
462
|
-
context "with a parameter" do
|
463
|
-
it "returns an array of the next N elements from the beginning of the collection" do
|
464
|
-
enumerable.shift(3).should eql(collection.shift(3))
|
465
|
-
end
|
466
|
-
end
|
467
|
-
|
468
|
-
it "removes the elements from the beginning of the collection" do
|
469
|
-
enumerable.shift
|
470
|
-
enumerable.shift(3)
|
471
|
-
enumerable.to_a.should eql(collection[4..-1])
|
472
|
-
end
|
473
|
-
|
474
|
-
it "changes #size" do
|
475
|
-
enumerable.shift
|
476
|
-
enumerable.shift(3)
|
477
|
-
enumerable.size.should eql(collection.size - 4)
|
478
|
-
end
|
479
|
-
|
480
|
-
it "does not harm the original collection" do
|
481
|
-
original = collection.dup
|
482
|
-
enumerable.shift
|
483
|
-
enumerable.shift(3)
|
484
|
-
collection.should eql(original)
|
485
|
-
end
|
486
|
-
|
487
|
-
end
|
488
|
-
|
489
|
-
it "depends on #(private)element_or_array" do
|
490
|
-
enumerable.should_receive(:element_or_array).twice.and_call_original
|
491
|
-
enumerable.shift
|
492
|
-
enumerable.shift(3)
|
493
|
-
end
|
494
|
-
|
495
|
-
end
|
496
|
-
|
497
|
-
context "#shuffle" do
|
498
|
-
|
499
|
-
it "returns a new HugeEnumerable" do
|
500
|
-
enumerable.shuffle.should_not equal(enumerable)
|
501
|
-
end
|
502
|
-
|
503
|
-
end
|
504
|
-
|
505
|
-
context "#shuffle!" do
|
506
|
-
|
507
|
-
it "randomly alters the order of the sequence" do
|
508
|
-
fake_random = Proc.new { |x| 2 % x }
|
509
|
-
enumerable.max_array_size = enumerable.size
|
510
|
-
original = enumerable.to_a
|
511
|
-
enumerable.shuffle!(fake_random)
|
512
|
-
shuffle1 = enumerable.to_a
|
513
|
-
fake_random = Proc.new { |x| 3 % x }
|
514
|
-
enumerable.shuffle!(fake_random)
|
515
|
-
shuffle2 = enumerable.to_a
|
516
|
-
original.should_not eq(shuffle1)
|
517
|
-
original.should_not eq(shuffle2)
|
518
|
-
shuffle1.should_not eq(shuffle2)
|
519
|
-
end
|
520
|
-
|
521
|
-
it "contains all of the original elements" do
|
522
|
-
enumerable.shuffle!.to_a.sort.should eq(collection)
|
523
|
-
end
|
524
|
-
|
525
|
-
it "does noy alter the original collection" do
|
526
|
-
original = collection.dup
|
527
|
-
enumerable.max_array_size = enumerable.size
|
528
|
-
enumerable.shuffle!
|
529
|
-
enumerable.to_a.should_not eq(original)
|
530
|
-
original.should eq(collection)
|
531
|
-
end
|
532
|
-
|
533
|
-
end
|
534
|
-
|
535
|
-
context "#size" do
|
536
|
-
|
537
|
-
it "returns the current size of the collection" do
|
538
|
-
enumerable.size.should eql(collection.size)
|
539
|
-
end
|
540
|
-
|
541
|
-
end
|
542
|
-
|
543
|
-
context "#(private)next_prime" do
|
544
|
-
|
545
|
-
it "should return the next prime following any integer" do
|
546
|
-
primes = Prime.first(100)
|
547
|
-
x = 0
|
548
|
-
until primes.empty?
|
549
|
-
enumerable.next_prime(x).should eq(primes.first)
|
550
|
-
x += 1
|
551
|
-
primes.shift if x.prime?
|
552
|
-
end
|
553
|
-
end
|
554
|
-
|
555
|
-
end
|
556
|
-
|
557
|
-
context "#(private)_fetch" do
|
558
|
-
|
559
|
-
context "with an index outside the range of (sequence_start..sequence_end)" do
|
560
|
-
it "should never relay to fetch" do
|
561
|
-
enumerable.should_not_receive(:fetch)
|
562
|
-
enumerable._fetch(-1 * enumerable.size - 1)
|
563
|
-
enumerable._fetch(enumerable.size)
|
564
|
-
end
|
565
|
-
end
|
566
|
-
|
567
|
-
context "with an index inside the range of (sequence_start..sequence_end)" do
|
568
|
-
it "should relay to fetch" do
|
569
|
-
enumerable.should_receive(:fetch).twice
|
570
|
-
enumerable._fetch(0)
|
571
|
-
enumerable._fetch(enumerable.size - 1)
|
572
|
-
end
|
573
|
-
|
574
|
-
it "should map the relative index to an absolute index before calling fetch" do
|
575
|
-
enumerable.shift(3)
|
576
|
-
enumerable.stub(:shuffle_index) { |index| index + 2 }
|
577
|
-
enumerable.should_receive(:fetch).with(5)
|
578
|
-
enumerable._fetch(0)
|
579
|
-
end
|
580
|
-
|
581
|
-
end
|
582
|
-
|
583
|
-
end
|
584
|
-
|
585
|
-
context "#(private)element_or_array" do
|
586
|
-
|
587
|
-
let(:block) { Proc.new { 1 } }
|
588
|
-
|
589
|
-
context "on a non empty collection" do
|
590
|
-
context "with no parameter" do
|
591
|
-
it "returns a single element" do
|
592
|
-
enumerable.element_or_array { block.call }.should eql(1)
|
593
|
-
end
|
594
|
-
end
|
595
|
-
|
596
|
-
context "with a nil parameter" do
|
597
|
-
it "returns a single element" do
|
598
|
-
enumerable.element_or_array(nil, &block).should eql(1)
|
599
|
-
end
|
600
|
-
end
|
601
|
-
|
602
|
-
context "with a non nil parameter" do
|
603
|
-
it "returns an array of N elements" do
|
604
|
-
enumerable.element_or_array(3, &block).should eql([1, 1, 1])
|
605
|
-
end
|
606
|
-
|
607
|
-
it "will not return more items than remain in the collection" do
|
608
|
-
size = enumerable.size
|
609
|
-
enumerable.element_or_array(size + 1, &block).should have(size).items
|
610
|
-
end
|
611
|
-
end
|
612
|
-
end
|
613
|
-
|
614
|
-
context "on an empty collection" do
|
615
|
-
context "with no parameter" do
|
616
|
-
it "returns nil" do
|
617
|
-
emptied_enumerable.element_or_array(&:block).should be_nil
|
618
|
-
end
|
619
|
-
end
|
620
|
-
|
621
|
-
context "with a parameter" do
|
622
|
-
it "returns an empty array" do
|
623
|
-
emptied_enumerable.element_or_array(3, &block).should eql([])
|
624
|
-
end
|
625
|
-
end
|
626
|
-
end
|
627
|
-
|
628
|
-
it "raises an exception if the parameter is negative" do
|
629
|
-
expect { enumerable.element_or_array(-1, &block) }.to raise_error(ArgumentError, 'negative array size')
|
630
|
-
end
|
631
|
-
|
632
|
-
end
|
633
|
-
|
634
|
-
context "#(private)full_cycle_increment" do
|
635
|
-
|
636
|
-
it "must never return a value equal to the domain size" do
|
637
|
-
(0...100).to_a.all? { |x| enumerable.full_cycle_increment(x) != x }.should be_true
|
638
|
-
end
|
639
|
-
|
640
|
-
end
|
641
|
-
|
642
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'huge_enumerable'
|