daru 0.1.3.1 → 0.1.4
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 +4 -4
- data/.gitignore +2 -0
- data/.rspec +2 -1
- data/.rspec_formatter.rb +33 -0
- data/.rubocop.yml +26 -2
- data/History.md +38 -0
- data/README.md +22 -13
- data/Rakefile +50 -2
- data/benchmarks/csv_reading.rb +22 -0
- data/daru.gemspec +9 -2
- data/lib/daru.rb +36 -4
- data/lib/daru/accessors/array_wrapper.rb +6 -1
- data/lib/daru/accessors/dataframe_by_row.rb +10 -2
- data/lib/daru/accessors/gsl_wrapper.rb +1 -3
- data/lib/daru/accessors/nmatrix_wrapper.rb +9 -0
- data/lib/daru/category.rb +935 -0
- data/lib/daru/core/group_by.rb +29 -38
- data/lib/daru/core/merge.rb +186 -145
- data/lib/daru/core/query.rb +22 -11
- data/lib/daru/dataframe.rb +976 -885
- data/lib/daru/date_time/index.rb +166 -166
- data/lib/daru/date_time/offsets.rb +66 -77
- data/lib/daru/formatters/table.rb +54 -0
- data/lib/daru/helpers/array.rb +40 -0
- data/lib/daru/index.rb +476 -73
- data/lib/daru/io/io.rb +66 -45
- data/lib/daru/io/sql_data_source.rb +33 -62
- data/lib/daru/iruby/helpers.rb +38 -0
- data/lib/daru/iruby/templates/dataframe.html.erb +52 -0
- data/lib/daru/iruby/templates/dataframe_mi.html.erb +58 -0
- data/lib/daru/iruby/templates/multi_index.html.erb +12 -0
- data/lib/daru/iruby/templates/vector.html.erb +27 -0
- data/lib/daru/iruby/templates/vector_mi.html.erb +36 -0
- data/lib/daru/maths/arithmetic/dataframe.rb +16 -18
- data/lib/daru/maths/arithmetic/vector.rb +4 -6
- data/lib/daru/maths/statistics/dataframe.rb +8 -15
- data/lib/daru/maths/statistics/vector.rb +120 -98
- data/lib/daru/monkeys.rb +12 -40
- data/lib/daru/plotting/gruff.rb +3 -0
- data/lib/daru/plotting/gruff/category.rb +49 -0
- data/lib/daru/plotting/gruff/dataframe.rb +91 -0
- data/lib/daru/plotting/gruff/vector.rb +57 -0
- data/lib/daru/plotting/nyaplot.rb +3 -0
- data/lib/daru/plotting/nyaplot/category.rb +34 -0
- data/lib/daru/plotting/nyaplot/dataframe.rb +187 -0
- data/lib/daru/plotting/nyaplot/vector.rb +46 -0
- data/lib/daru/vector.rb +694 -421
- data/lib/daru/version.rb +1 -1
- data/profile/_base.rb +23 -0
- data/profile/df_to_a.rb +10 -0
- data/profile/filter.rb +13 -0
- data/profile/joining.rb +13 -0
- data/profile/sorting.rb +12 -0
- data/profile/vector_each_with_index.rb +9 -0
- data/spec/accessors/wrappers_spec.rb +2 -4
- data/spec/categorical_spec.rb +1734 -0
- data/spec/core/group_by_spec.rb +52 -2
- data/spec/core/merge_spec.rb +63 -2
- data/spec/core/query_spec.rb +236 -80
- data/spec/dataframe_spec.rb +1373 -79
- data/spec/date_time/data_spec.rb +3 -5
- data/spec/date_time/index_spec.rb +154 -17
- data/spec/date_time/offsets_spec.rb +3 -4
- data/spec/fixtures/empties.dat +2 -0
- data/spec/fixtures/strings.dat +2 -0
- data/spec/formatters/table_formatter_spec.rb +99 -0
- data/spec/helpers_spec.rb +8 -0
- data/spec/index/categorical_index_spec.rb +168 -0
- data/spec/index/index_spec.rb +283 -0
- data/spec/index/multi_index_spec.rb +570 -0
- data/spec/io/io_spec.rb +31 -4
- data/spec/io/sql_data_source_spec.rb +0 -1
- data/spec/iruby/dataframe_spec.rb +172 -0
- data/spec/iruby/helpers_spec.rb +49 -0
- data/spec/iruby/multi_index_spec.rb +37 -0
- data/spec/iruby/vector_spec.rb +107 -0
- data/spec/math/arithmetic/dataframe_spec.rb +71 -13
- data/spec/math/arithmetic/vector_spec.rb +8 -10
- data/spec/math/statistics/dataframe_spec.rb +3 -5
- data/spec/math/statistics/vector_spec.rb +45 -55
- data/spec/monkeys_spec.rb +32 -9
- data/spec/plotting/dataframe_spec.rb +386 -0
- data/spec/plotting/vector_spec.rb +230 -0
- data/spec/shared/vector_display_spec.rb +215 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/vector_spec.rb +905 -138
- metadata +143 -11
- data/.rubocop_todo.yml +0 -44
- data/lib/daru/plotting/dataframe.rb +0 -104
- data/lib/daru/plotting/vector.rb +0 -38
- data/spec/daru_spec.rb +0 -58
- data/spec/index_spec.rb +0 -375
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Daru::CategoricalIndex do
|
4
|
+
context "#pos" do
|
5
|
+
context "when the category is non-numeric" do
|
6
|
+
let(:idx) { described_class.new [:a, :b, :a, :a, :c] }
|
7
|
+
|
8
|
+
context "single category" do
|
9
|
+
subject { idx.pos :a }
|
10
|
+
|
11
|
+
it { is_expected.to eq [0, 2, 3] }
|
12
|
+
end
|
13
|
+
|
14
|
+
context "multiple categories" do
|
15
|
+
subject { idx.pos :a, :c }
|
16
|
+
|
17
|
+
it { is_expected.to eq [0, 2, 3, 4] }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "invalid category" do
|
21
|
+
it { expect { idx.pos :e }.to raise_error IndexError }
|
22
|
+
end
|
23
|
+
|
24
|
+
context "positional index" do
|
25
|
+
it { expect(idx.pos 0).to eq 0 }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "invalid positional index" do
|
29
|
+
it { expect { idx.pos 5 }.to raise_error IndexError }
|
30
|
+
end
|
31
|
+
|
32
|
+
context "multiple positional indexes" do
|
33
|
+
subject { idx.pos 0, 1, 2 }
|
34
|
+
|
35
|
+
it { is_expected.to be_a Array }
|
36
|
+
its(:size) { is_expected.to eq 3 }
|
37
|
+
it { is_expected.to eq [0, 1, 2] }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when the category is numeric" do
|
42
|
+
let(:idx) { described_class.new [0, 1, 0, 0, 2] }
|
43
|
+
|
44
|
+
context "first preference to category" do
|
45
|
+
subject { idx.pos 0 }
|
46
|
+
|
47
|
+
it { is_expected.to be_a Array }
|
48
|
+
its(:size) { is_expected.to eq 3 }
|
49
|
+
it { is_expected.to eq [0, 2, 3] }
|
50
|
+
end
|
51
|
+
|
52
|
+
context "second preference to positional index" do
|
53
|
+
subject { idx.pos 3 }
|
54
|
+
|
55
|
+
it { is_expected.to eq 3 }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "#subset" do
|
61
|
+
let(:idx) { described_class.new [:a, 1, :a, 1, :c] }
|
62
|
+
|
63
|
+
context "single index" do
|
64
|
+
context "multiple instances" do
|
65
|
+
subject { idx.subset :a }
|
66
|
+
|
67
|
+
it { is_expected.to be_a described_class }
|
68
|
+
its(:size) { is_expected.to eq 2 }
|
69
|
+
its(:to_a) { is_expected.to eq [:a, :a] }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "multiple indexes" do
|
74
|
+
subject { idx.subset :a, 1 }
|
75
|
+
|
76
|
+
it { is_expected.to be_a described_class }
|
77
|
+
its(:size) { is_expected.to eq 4 }
|
78
|
+
its(:to_a) { is_expected.to eq [:a, 1, :a, 1] }
|
79
|
+
end
|
80
|
+
|
81
|
+
context "multiple positional indexes" do
|
82
|
+
subject { idx.subset 0, 2 }
|
83
|
+
|
84
|
+
it { is_expected.to be_a described_class }
|
85
|
+
its(:size) { is_expected.to eq 2 }
|
86
|
+
its(:to_a) { is_expected.to eq [:a, :a] }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "#at" do
|
91
|
+
let(:idx) { described_class.new [:a, :a, :a, 1, :c] }
|
92
|
+
|
93
|
+
context "single position" do
|
94
|
+
it { expect(idx.at 1).to eq :a }
|
95
|
+
end
|
96
|
+
|
97
|
+
context "multiple positions" do
|
98
|
+
subject { idx.at 0, 2, 3 }
|
99
|
+
|
100
|
+
it { is_expected.to be_a described_class }
|
101
|
+
its(:size) { is_expected.to eq 3 }
|
102
|
+
its(:to_a) { is_expected.to eq [:a, :a, 1] }
|
103
|
+
end
|
104
|
+
|
105
|
+
context "range" do
|
106
|
+
subject { idx.at 2..3 }
|
107
|
+
|
108
|
+
it { is_expected.to be_a described_class }
|
109
|
+
its(:size) { is_expected.to eq 2 }
|
110
|
+
its(:to_a) { is_expected.to eq [:a, 1] }
|
111
|
+
end
|
112
|
+
|
113
|
+
context "range with negative integers" do
|
114
|
+
subject { idx.at 2..-2 }
|
115
|
+
|
116
|
+
it { is_expected.to be_a described_class }
|
117
|
+
its(:size) { is_expected.to eq 2 }
|
118
|
+
its(:to_a) { is_expected.to eq [:a, 1] }
|
119
|
+
end
|
120
|
+
|
121
|
+
context "rangle with single element" do
|
122
|
+
subject { idx.at 2..2 }
|
123
|
+
|
124
|
+
it { is_expected.to be_a described_class }
|
125
|
+
its(:size) { is_expected.to eq 1 }
|
126
|
+
its(:to_a) { is_expected.to eq [:a] }
|
127
|
+
end
|
128
|
+
|
129
|
+
context "invalid position" do
|
130
|
+
it { expect { idx.at 5 }.to raise_error IndexError }
|
131
|
+
end
|
132
|
+
|
133
|
+
context "invalid positions" do
|
134
|
+
it { expect { idx.at 2, 5 }.to raise_error IndexError }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "#add" do
|
139
|
+
let(:idx) { described_class.new [:a, 1, :a, 1] }
|
140
|
+
|
141
|
+
context "single index" do
|
142
|
+
subject { idx.add :c }
|
143
|
+
|
144
|
+
its(:to_a) { is_expected.to eq [:a, 1, :a, 1, :c] }
|
145
|
+
end
|
146
|
+
|
147
|
+
context "multiple indexes" do
|
148
|
+
subject { idx.add :c, :d }
|
149
|
+
|
150
|
+
its(:to_a) { is_expected.to eq [:a, 1, :a, 1, :c, :d] }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "#valid?" do
|
155
|
+
let(:idx) { described_class.new [:a, 1, :a, 1] }
|
156
|
+
|
157
|
+
context "single index" do
|
158
|
+
it { expect(idx.valid? :a).to eq true }
|
159
|
+
it { expect(idx.valid? 2).to eq true }
|
160
|
+
it { expect(idx.valid? 4).to eq false }
|
161
|
+
end
|
162
|
+
|
163
|
+
context "multiple indexes" do
|
164
|
+
it { expect(idx.valid? :a, 1).to eq true }
|
165
|
+
it { expect(idx.valid? :a, 1, 5).to eq false }
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Daru::Index do
|
4
|
+
context ".new" do
|
5
|
+
it "creates an Index object if Index-like data is supplied" do
|
6
|
+
i = Daru::Index.new [:one, 'one', 1, 2, :two]
|
7
|
+
expect(i.class).to eq(Daru::Index)
|
8
|
+
expect(i.to_a) .to eq([:one, 'one', 1, 2, :two])
|
9
|
+
end
|
10
|
+
|
11
|
+
it "creates a MultiIndex if tuples are supplied" do
|
12
|
+
i = Daru::Index.new([
|
13
|
+
[:b,:one,:bar],
|
14
|
+
[:b,:two,:bar],
|
15
|
+
[:b,:two,:baz],
|
16
|
+
[:b,:one,:foo]
|
17
|
+
])
|
18
|
+
|
19
|
+
expect(i.class).to eq(Daru::MultiIndex)
|
20
|
+
expect(i.levels).to eq([[:b], [:one, :two], [:bar, :baz, :foo]])
|
21
|
+
expect(i.labels).to eq([[0,0,0,0],[0,1,1,0],[0,0,1,2]])
|
22
|
+
end
|
23
|
+
|
24
|
+
it "creates DateTimeIndex if date-like objects specified" do
|
25
|
+
i = Daru::Index.new([
|
26
|
+
DateTime.new(2012,2,4), DateTime.new(2012,2,5), DateTime.new(2012,2,6)])
|
27
|
+
expect(i.class).to eq(Daru::DateTimeIndex)
|
28
|
+
expect(i.to_a).to eq([DateTime.new(2012,2,4), DateTime.new(2012,2,5), DateTime.new(2012,2,6)])
|
29
|
+
expect(i.frequency).to eq('D')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "#initialize" do
|
34
|
+
it "creates an Index from Array" do
|
35
|
+
idx = Daru::Index.new ['speaker', 'mic', 'guitar', 'amp']
|
36
|
+
|
37
|
+
expect(idx.to_a).to eq(['speaker', 'mic', 'guitar', 'amp'])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "creates an Index from Range" do
|
41
|
+
idx = Daru::Index.new 1..5
|
42
|
+
|
43
|
+
expect(idx).to eq(Daru::Index.new [1, 2, 3, 4, 5])
|
44
|
+
end
|
45
|
+
|
46
|
+
it "raises ArgumentError on invalid input type" do
|
47
|
+
expect { Daru::Index.new 'foo' }.to raise_error ArgumentError
|
48
|
+
end
|
49
|
+
|
50
|
+
it "accepts all sorts of objects for Indexing" do
|
51
|
+
idx = Daru::Index.new [:a, 'a', :hello, '23', 23]
|
52
|
+
|
53
|
+
expect(idx.to_a).to eq([:a, 'a', :hello, '23', 23])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context '#keys' do
|
58
|
+
subject(:idx) { Daru::Index.new ['speaker', 'mic', 'guitar', 'amp'] }
|
59
|
+
|
60
|
+
it 'returns key by position' do
|
61
|
+
expect(idx.key(2)).to eq 'guitar'
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns nil on too large pos' do
|
65
|
+
expect(idx.key(20)).to be_nil
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns nil on wrong arg type' do
|
69
|
+
expect(idx.key(nil)).to be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "#size" do
|
74
|
+
it "correctly returns the size of the index" do
|
75
|
+
idx = Daru::Index.new ['speaker', 'mic', 'guitar', 'amp']
|
76
|
+
|
77
|
+
expect(idx.size).to eq(4)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "#valid?" do
|
82
|
+
let(:idx) { Daru::Index.new [:a, :b, :c] }
|
83
|
+
|
84
|
+
context "single index" do
|
85
|
+
it { expect(idx.valid? 2).to eq true }
|
86
|
+
it { expect(idx.valid? :d).to eq false }
|
87
|
+
end
|
88
|
+
|
89
|
+
context "multiple indexes" do
|
90
|
+
it { expect(idx.valid? :a, 1).to eq true }
|
91
|
+
it { expect(idx.valid? :a, 3).to eq false }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context '#inspect' do
|
96
|
+
context 'small index' do
|
97
|
+
subject { Daru::Index.new ['one', 'two', 'three'] }
|
98
|
+
its(:inspect) { is_expected.to eq "#<Daru::Index(3): {one, two, three}>" }
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'large index' do
|
102
|
+
subject { Daru::Index.new ('a'..'z').to_a }
|
103
|
+
its(:inspect) { is_expected.to eq "#<Daru::Index(26): {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ... z}>" }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "#&" do
|
108
|
+
before :each do
|
109
|
+
@left = Daru::Index.new [:miles, :geddy, :eric]
|
110
|
+
@right = Daru::Index.new [:geddy, :richie, :miles]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "intersects 2 indexes and returns an Index" do
|
114
|
+
expect(@left & @right).to eq([:miles, :geddy].to_index)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "intersects an Index and an Array to return an Index" do
|
118
|
+
expect(@left & [:bob, :geddy, :richie]).to eq([:geddy].to_index)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "#|" do
|
123
|
+
before :each do
|
124
|
+
@left = Daru::Index.new [:miles, :geddy, :eric]
|
125
|
+
@right = Daru::Index.new [:bob, :jimi, :richie]
|
126
|
+
end
|
127
|
+
|
128
|
+
it "unions 2 indexes and returns an Index" do
|
129
|
+
expect(@left | @right).to eq([:miles, :geddy, :eric, :bob, :jimi, :richie].to_index)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "unions an Index and an Array to return an Index" do
|
133
|
+
expect(@left | [:bob, :jimi, :richie]).to eq([:miles, :geddy, :eric,
|
134
|
+
:bob, :jimi, :richie].to_index)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "#[]" do
|
139
|
+
before do
|
140
|
+
@id = Daru::Index.new [:one, :two, :three, :four, :five, :six, :seven]
|
141
|
+
@mixed_id = Daru::Index.new ['a','b','c',:d,:a,8,3,5]
|
142
|
+
end
|
143
|
+
|
144
|
+
it "works with ranges" do
|
145
|
+
expect(@id[:two..:five]).to eq(Daru::Index.new([:two, :three, :four, :five]))
|
146
|
+
|
147
|
+
expect(@mixed_id['a'..'c']).to eq(Daru::Index.new(['a','b','c']))
|
148
|
+
|
149
|
+
# If both start and end are numbers then refer to numerical indexes
|
150
|
+
expect(@mixed_id[0..2]).to eq(Daru::Index.new(['a','b','c']))
|
151
|
+
|
152
|
+
# If atleast one is a number then refer to actual indexing
|
153
|
+
expect(@mixed_id.slice('b',8)).to eq(Daru::Index.new(['b','c',:d,:a,8]))
|
154
|
+
end
|
155
|
+
|
156
|
+
it "returns multiple keys if specified multiple indices" do
|
157
|
+
expect(@id[0,1,3,4]).to eq(Daru::Index.new([:one, :two, :four, :five]))
|
158
|
+
expect(@mixed_id[0,5,3,2]).to eq(Daru::Index.new(['a', 8, :d, 'c']))
|
159
|
+
end
|
160
|
+
|
161
|
+
it "returns correct index position for non-numeric index" do
|
162
|
+
expect(@id[:four]).to eq(3)
|
163
|
+
expect(@id[3]).to eq(3)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "returns correct index position for mixed index" do
|
167
|
+
expect(@mixed_id[8]).to eq(5)
|
168
|
+
expect(@mixed_id['c']).to eq(2)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "#pos" do
|
173
|
+
let(:idx) { described_class.new [:a, :b, 1, 2] }
|
174
|
+
|
175
|
+
context "single index" do
|
176
|
+
it { expect(idx.pos :a).to eq 0 }
|
177
|
+
end
|
178
|
+
|
179
|
+
context "multiple indexes" do
|
180
|
+
subject { idx.pos :a, 1 }
|
181
|
+
|
182
|
+
it { is_expected.to be_a Array }
|
183
|
+
its(:size) { is_expected.to eq 2 }
|
184
|
+
it { is_expected.to eq [0, 2] }
|
185
|
+
end
|
186
|
+
|
187
|
+
context "single positional index" do
|
188
|
+
it { expect(idx.pos 0).to eq 0 }
|
189
|
+
end
|
190
|
+
|
191
|
+
context "multiple positional index" do
|
192
|
+
subject { idx.pos 0, 3 }
|
193
|
+
|
194
|
+
it { is_expected.to be_a Array }
|
195
|
+
its(:size) { is_expected.to eq 2 }
|
196
|
+
it { is_expected.to eq [0, 3] }
|
197
|
+
end
|
198
|
+
|
199
|
+
context "range" do
|
200
|
+
subject { idx.pos 1..3 }
|
201
|
+
|
202
|
+
it { is_expected.to be_a Array }
|
203
|
+
its(:size) { is_expected.to eq 3 }
|
204
|
+
it { is_expected.to eq [1, 2, 3] }
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "#subset" do
|
209
|
+
let(:idx) { described_class.new [:a, :b, 1, 2] }
|
210
|
+
|
211
|
+
context "multiple indexes" do
|
212
|
+
subject { idx.subset :a, 1 }
|
213
|
+
|
214
|
+
it { is_expected.to be_a described_class }
|
215
|
+
its(:size) { is_expected.to eq 2 }
|
216
|
+
its(:to_a) { is_expected.to eq [:a, 1] }
|
217
|
+
end
|
218
|
+
|
219
|
+
context "multiple positional indexes" do
|
220
|
+
subject { idx.subset 0, 3 }
|
221
|
+
|
222
|
+
it { is_expected.to be_a described_class }
|
223
|
+
its(:size) { is_expected.to eq 2 }
|
224
|
+
its(:to_a) { is_expected.to eq [:a, 2] }
|
225
|
+
end
|
226
|
+
|
227
|
+
context "range" do
|
228
|
+
subject { idx.subset 1..3 }
|
229
|
+
|
230
|
+
it { is_expected.to be_a described_class }
|
231
|
+
its(:size) { is_expected.to eq 3 }
|
232
|
+
its(:to_a) { is_expected.to eq [:b, 1, 2] }
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context "#at" do
|
237
|
+
let(:idx) { described_class.new [:a, :b, 1 ] }
|
238
|
+
|
239
|
+
context "single position" do
|
240
|
+
it { expect(idx.at 1).to eq :b }
|
241
|
+
end
|
242
|
+
|
243
|
+
context "multiple positions" do
|
244
|
+
subject { idx.at 1, 2 }
|
245
|
+
|
246
|
+
it { is_expected.to be_a described_class }
|
247
|
+
its(:size) { is_expected.to eq 2 }
|
248
|
+
its(:to_a) { is_expected.to eq [:b, 1] }
|
249
|
+
end
|
250
|
+
|
251
|
+
context "range" do
|
252
|
+
subject { idx.at 1..2 }
|
253
|
+
|
254
|
+
it { is_expected.to be_a described_class }
|
255
|
+
its(:size) { is_expected.to eq 2 }
|
256
|
+
its(:to_a) { is_expected.to eq [:b, 1] }
|
257
|
+
end
|
258
|
+
|
259
|
+
context "range with negative integer" do
|
260
|
+
subject { idx.at 1..-1 }
|
261
|
+
|
262
|
+
it { is_expected.to be_a described_class }
|
263
|
+
its(:size) { is_expected.to eq 2 }
|
264
|
+
its(:to_a) { is_expected.to eq [:b, 1] }
|
265
|
+
end
|
266
|
+
|
267
|
+
context "rangle with single element" do
|
268
|
+
subject { idx.at 1..1 }
|
269
|
+
|
270
|
+
it { is_expected.to be_a described_class }
|
271
|
+
its(:size) { is_expected.to eq 1 }
|
272
|
+
its(:to_a) { is_expected.to eq [:b] }
|
273
|
+
end
|
274
|
+
|
275
|
+
context "invalid position" do
|
276
|
+
it { expect { idx.at 3 }.to raise_error IndexError }
|
277
|
+
end
|
278
|
+
|
279
|
+
context "invalid positions" do
|
280
|
+
it { expect { idx.at 2, 3 }.to raise_error IndexError }
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|