daru 0.1.3.1 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -1
  4. data/.rspec_formatter.rb +33 -0
  5. data/.rubocop.yml +26 -2
  6. data/History.md +38 -0
  7. data/README.md +22 -13
  8. data/Rakefile +50 -2
  9. data/benchmarks/csv_reading.rb +22 -0
  10. data/daru.gemspec +9 -2
  11. data/lib/daru.rb +36 -4
  12. data/lib/daru/accessors/array_wrapper.rb +6 -1
  13. data/lib/daru/accessors/dataframe_by_row.rb +10 -2
  14. data/lib/daru/accessors/gsl_wrapper.rb +1 -3
  15. data/lib/daru/accessors/nmatrix_wrapper.rb +9 -0
  16. data/lib/daru/category.rb +935 -0
  17. data/lib/daru/core/group_by.rb +29 -38
  18. data/lib/daru/core/merge.rb +186 -145
  19. data/lib/daru/core/query.rb +22 -11
  20. data/lib/daru/dataframe.rb +976 -885
  21. data/lib/daru/date_time/index.rb +166 -166
  22. data/lib/daru/date_time/offsets.rb +66 -77
  23. data/lib/daru/formatters/table.rb +54 -0
  24. data/lib/daru/helpers/array.rb +40 -0
  25. data/lib/daru/index.rb +476 -73
  26. data/lib/daru/io/io.rb +66 -45
  27. data/lib/daru/io/sql_data_source.rb +33 -62
  28. data/lib/daru/iruby/helpers.rb +38 -0
  29. data/lib/daru/iruby/templates/dataframe.html.erb +52 -0
  30. data/lib/daru/iruby/templates/dataframe_mi.html.erb +58 -0
  31. data/lib/daru/iruby/templates/multi_index.html.erb +12 -0
  32. data/lib/daru/iruby/templates/vector.html.erb +27 -0
  33. data/lib/daru/iruby/templates/vector_mi.html.erb +36 -0
  34. data/lib/daru/maths/arithmetic/dataframe.rb +16 -18
  35. data/lib/daru/maths/arithmetic/vector.rb +4 -6
  36. data/lib/daru/maths/statistics/dataframe.rb +8 -15
  37. data/lib/daru/maths/statistics/vector.rb +120 -98
  38. data/lib/daru/monkeys.rb +12 -40
  39. data/lib/daru/plotting/gruff.rb +3 -0
  40. data/lib/daru/plotting/gruff/category.rb +49 -0
  41. data/lib/daru/plotting/gruff/dataframe.rb +91 -0
  42. data/lib/daru/plotting/gruff/vector.rb +57 -0
  43. data/lib/daru/plotting/nyaplot.rb +3 -0
  44. data/lib/daru/plotting/nyaplot/category.rb +34 -0
  45. data/lib/daru/plotting/nyaplot/dataframe.rb +187 -0
  46. data/lib/daru/plotting/nyaplot/vector.rb +46 -0
  47. data/lib/daru/vector.rb +694 -421
  48. data/lib/daru/version.rb +1 -1
  49. data/profile/_base.rb +23 -0
  50. data/profile/df_to_a.rb +10 -0
  51. data/profile/filter.rb +13 -0
  52. data/profile/joining.rb +13 -0
  53. data/profile/sorting.rb +12 -0
  54. data/profile/vector_each_with_index.rb +9 -0
  55. data/spec/accessors/wrappers_spec.rb +2 -4
  56. data/spec/categorical_spec.rb +1734 -0
  57. data/spec/core/group_by_spec.rb +52 -2
  58. data/spec/core/merge_spec.rb +63 -2
  59. data/spec/core/query_spec.rb +236 -80
  60. data/spec/dataframe_spec.rb +1373 -79
  61. data/spec/date_time/data_spec.rb +3 -5
  62. data/spec/date_time/index_spec.rb +154 -17
  63. data/spec/date_time/offsets_spec.rb +3 -4
  64. data/spec/fixtures/empties.dat +2 -0
  65. data/spec/fixtures/strings.dat +2 -0
  66. data/spec/formatters/table_formatter_spec.rb +99 -0
  67. data/spec/helpers_spec.rb +8 -0
  68. data/spec/index/categorical_index_spec.rb +168 -0
  69. data/spec/index/index_spec.rb +283 -0
  70. data/spec/index/multi_index_spec.rb +570 -0
  71. data/spec/io/io_spec.rb +31 -4
  72. data/spec/io/sql_data_source_spec.rb +0 -1
  73. data/spec/iruby/dataframe_spec.rb +172 -0
  74. data/spec/iruby/helpers_spec.rb +49 -0
  75. data/spec/iruby/multi_index_spec.rb +37 -0
  76. data/spec/iruby/vector_spec.rb +107 -0
  77. data/spec/math/arithmetic/dataframe_spec.rb +71 -13
  78. data/spec/math/arithmetic/vector_spec.rb +8 -10
  79. data/spec/math/statistics/dataframe_spec.rb +3 -5
  80. data/spec/math/statistics/vector_spec.rb +45 -55
  81. data/spec/monkeys_spec.rb +32 -9
  82. data/spec/plotting/dataframe_spec.rb +386 -0
  83. data/spec/plotting/vector_spec.rb +230 -0
  84. data/spec/shared/vector_display_spec.rb +215 -0
  85. data/spec/spec_helper.rb +23 -0
  86. data/spec/vector_spec.rb +905 -138
  87. metadata +143 -11
  88. data/.rubocop_todo.yml +0 -44
  89. data/lib/daru/plotting/dataframe.rb +0 -104
  90. data/lib/daru/plotting/vector.rb +0 -38
  91. data/spec/daru_spec.rb +0 -58
  92. data/spec/index_spec.rb +0 -375
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe Daru::Vector do
4
2
  context "#initialize" do
5
3
  it "accepts DateTimeIndex in index option" do
@@ -70,7 +68,7 @@ describe Daru::Vector do
70
68
  end
71
69
 
72
70
  it "assigns multiple elements when index incomplete" do
73
- index = Daru::DateTimeIndex.date_range(:start => '2012', :periods => 100,
71
+ index = Daru::DateTimeIndex.date_range(:start => '2012', :periods => 100,
74
72
  :freq => 'MB')
75
73
  vector = Daru::Vector.new([1,2,3,4,5,6,7,8,9,10]*10, index: index)
76
74
  vector['2012'] = 666
@@ -88,7 +86,7 @@ describe Daru::DataFrame do
88
86
  @a = [1,2,3,4,5]*20
89
87
  @b = @a.map { |e| e*3 }
90
88
  @c = @a.map(&:to_s)
91
- @df = Daru::DataFrame.new([@a, @b, @c], index: @index, order: @order)
89
+ @df = Daru::DataFrame.new([@a, @b, @c], index: @index, order: @order)
92
90
  end
93
91
 
94
92
  context "#initialize" do
@@ -111,7 +109,7 @@ describe Daru::DataFrame do
111
109
 
112
110
  it "returns DataFrame when incomplete index" do
113
111
  answer = Daru::DataFrame.new(
114
- [@a, @c], index: @index, order: Daru::DateTimeIndex.new([
112
+ [@a, @c], index: @index, order: Daru::DateTimeIndex.new([
115
113
  DateTime.new(2012,1,3),DateTime.new(2012,3,3)]))
116
114
  expect(@df['2012']).to eq(answer)
117
115
  end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  include Daru
4
2
 
5
3
  describe DateTimeIndex do
@@ -32,6 +30,20 @@ describe DateTimeIndex do
32
30
  end
33
31
  end
34
32
 
33
+ context '.try_create' do
34
+ it 'creates index from array of dates' do
35
+ index = DateTimeIndex.try_create([
36
+ DateTime.new(2014,7,1),DateTime.new(2014,7,2),
37
+ DateTime.new(2014,7,3),DateTime.new(2014,7,4)])
38
+ expect(index.class).to eq(DateTimeIndex)
39
+ end
40
+
41
+ it 'does not creates index from anything else' do
42
+ index = DateTimeIndex.try_create([:a, :b, :c])
43
+ expect(index).to be_nil
44
+ end
45
+ end
46
+
35
47
  context ".date_range" do
36
48
  it "creates DateTimeIndex with default options" do
37
49
  index = DateTimeIndex.date_range(:start => DateTime.new(2014,5,3),
@@ -54,6 +66,11 @@ describe DateTimeIndex do
54
66
  expect(index.frequency).to eq('D')
55
67
  end
56
68
 
69
+ it 'fails on wrong string format' do
70
+ expect{DateTimeIndex.date_range(start: '2014/5/3', end: '2014/5/10')}
71
+ .to raise_error(ArgumentError, /Unacceptable date string/)
72
+ end
73
+
57
74
  it "creates DateTimeIndex of per minute frequency between start and end" do
58
75
  index = DateTimeIndex.date_range(start: '2015-7-1',freq: 'M', periods: 10)
59
76
 
@@ -88,7 +105,7 @@ describe DateTimeIndex do
88
105
  end
89
106
 
90
107
  it "creates a DateTimeIndex of (sunday) weekly frequency" do
91
- index = DateTimeIndex.date_range(start: '2014-8-2', end: '2014-9-8',
108
+ index = DateTimeIndex.date_range(start: '2014-8-2', end: '2014-9-8',
92
109
  freq: 'W')
93
110
 
94
111
  expect(index).to eq(DateTimeIndex.new([
@@ -98,7 +115,7 @@ describe DateTimeIndex do
98
115
  end
99
116
 
100
117
  it "creates a DateTimeIndex of (monday) weekly frequency" do
101
- index = DateTimeIndex.date_range(:start => '2015-7-6', :periods => 5,
118
+ index = DateTimeIndex.date_range(:start => '2015-7-6', :periods => 5,
102
119
  :freq => 'W-MON')
103
120
  expect(index).to eq(DateTimeIndex.new([
104
121
  DateTime.new(2015,7,6), DateTime.new(2015,7,13), DateTime.new(2015,7,20),
@@ -110,7 +127,7 @@ describe DateTimeIndex do
110
127
  index = DateTimeIndex.date_range(
111
128
  :start => '2017-4-14', :freq => 'MB', :periods => 5)
112
129
  expect(index).to eq(DateTimeIndex.new([
113
- DateTime.new(2017,5,1), DateTime.new(2017,6,1),
130
+ DateTime.new(2017,5,1), DateTime.new(2017,6,1),
114
131
  DateTime.new(2017,7,1), DateTime.new(2017,8,1),DateTime.new(2017,9,1)]))
115
132
  end
116
133
 
@@ -132,13 +149,13 @@ describe DateTimeIndex do
132
149
  index = DateTimeIndex.date_range(start: '2014-9',end: '2018-1',freq: 'YE')
133
150
 
134
151
  expect(index).to eq(DateTimeIndex.new([
135
- DateTime.new(2014,12,31), DateTime.new(2015,12,31),DateTime.new(2016,12,31),
152
+ DateTime.new(2014,12,31), DateTime.new(2015,12,31),DateTime.new(2016,12,31),
136
153
  DateTime.new(2017,12,31)]))
137
154
  expect(index.frequency).to eq('YE')
138
155
  end
139
156
 
140
157
  it "creates only specfied number of periods taking precendence over end" do
141
- index = DateTimeIndex.date_range(start: '2014-5-5', end: '2015-3',
158
+ index = DateTimeIndex.date_range(start: '2014-5-5', end: '2015-3',
142
159
  periods: 5, freq: 'YB')
143
160
  expect(index).to eq(DateTimeIndex.new([
144
161
  DateTime.new(2015,1,1),DateTime.new(2016,1,1),DateTime.new(2017,1,1),
@@ -148,19 +165,45 @@ describe DateTimeIndex do
148
165
  it "does not increment start date if it satisifies the anchor" do
149
166
  index = DateTimeIndex.date_range(:start => '2012-1-1', freq: 'MB', periods: 4)
150
167
  expect(index).to eq(DateTimeIndex.new(
151
- [DateTime.new(2012,1,1), DateTime.new(2012,2,1),
168
+ [DateTime.new(2012,1,1), DateTime.new(2012,2,1),
152
169
  DateTime.new(2012,3,1), DateTime.new(2012,4,1)]))
153
170
  end
154
171
 
155
172
  it "raises error for different start and end timezones" do
156
173
  expect {
157
174
  DateTimeIndex.date_range(
158
- :start => DateTime.new(2012,3,4,12,5,4,"+5:30"),
175
+ :start => DateTime.new(2012,3,4,12,5,4,"+5:30"),
159
176
  :end => DateTime.new(2013,3,4,12,5,4,"+7:30"), freq: 'M')
160
177
  }.to raise_error(ArgumentError)
161
178
  end
162
179
  end
163
180
 
181
+ context '#inspect' do
182
+ subject { index.inspect }
183
+
184
+ context 'with known frequency' do
185
+ let(:index){
186
+ DateTimeIndex.new([
187
+ DateTime.new(2014,7,1),DateTime.new(2014,7,2),DateTime.new(2014,7,3),
188
+ DateTime.new(2014,7,4)], freq: :infer)
189
+ }
190
+ it { is_expected.to eq \
191
+ "#<Daru::DateTimeIndex(4, frequency=D) 2014-07-01T00:00:00+00:00...2014-07-04T00:00:00+00:00>"
192
+ }
193
+ end
194
+
195
+ context 'with unknown frequency' do
196
+ let(:index){
197
+ DateTimeIndex.new([
198
+ DateTime.new(2014,7,1),DateTime.new(2014,7,2),DateTime.new(2014,7,3),
199
+ DateTime.new(2014,7,4)])
200
+ }
201
+ it { is_expected.to eq \
202
+ "#<Daru::DateTimeIndex(4) 2014-07-01T00:00:00+00:00...2014-07-04T00:00:00+00:00>"
203
+ }
204
+ end
205
+ end
206
+
164
207
  context "#frequency" do
165
208
  it "reports the frequency of when a period index is specified" do
166
209
  index = DateTimeIndex.new([
@@ -180,7 +223,7 @@ describe DateTimeIndex do
180
223
  context "#[]" do
181
224
  it "accepts complete time as a string" do
182
225
  index = DateTimeIndex.new([
183
- DateTime.new(2014,3,3),DateTime.new(2014,3,4),DateTime.new(2014,3,5),DateTime.new(2014,3,6)],
226
+ DateTime.new(2014,3,3),DateTime.new(2014,3,4),DateTime.new(2014,3,5),DateTime.new(2014,3,6)],
184
227
  freq: :infer)
185
228
  expect(index.frequency).to eq('D')
186
229
  expect(index['2014-3-5']).to eq(2)
@@ -188,7 +231,7 @@ describe DateTimeIndex do
188
231
 
189
232
  it "accepts complete time as a DateTime object" do
190
233
  index = DateTimeIndex.new([
191
- DateTime.new(2014,3,3),DateTime.new(2014,3,4),DateTime.new(2014,3,5),DateTime.new(2014,3,6)],
234
+ DateTime.new(2014,3,3),DateTime.new(2014,3,4),DateTime.new(2014,3,5),DateTime.new(2014,3,6)],
192
235
  freq: :infer)
193
236
  expect(index[DateTime.new(2014,3,6)]).to eq(3)
194
237
  end
@@ -202,7 +245,7 @@ describe DateTimeIndex do
202
245
  end
203
246
 
204
247
  it "accepts only year for frequency data" do
205
- index = DateTimeIndex.date_range(:start => DateTime.new(2012,3,2),
248
+ index = DateTimeIndex.date_range(:start => DateTime.new(2012,3,2),
206
249
  periods: 1000, freq: '5D')
207
250
  expect(index['2012']).to eq(DateTimeIndex.date_range(
208
251
  :start => DateTime.new(2012,3,2), :end => DateTime.new(2012,12,27), freq: '5D'))
@@ -233,10 +276,10 @@ describe DateTimeIndex do
233
276
  end
234
277
 
235
278
  it "accepts year, month, date for frequency data" do
236
- index = DateTimeIndex.date_range(:start => DateTime.new(2012,2,29),
279
+ index = DateTimeIndex.date_range(:start => DateTime.new(2012,2,29),
237
280
  periods: 1000, freq: 'M')
238
281
  expect(index['2012-2-29']).to eq(DateTimeIndex.date_range(
239
- :start => DateTime.new(2012,2,29),
282
+ :start => DateTime.new(2012,2,29),
240
283
  :end => DateTime.new(2012,2,29,16,39,00), freq: 'M'))
241
284
  end
242
285
 
@@ -291,7 +334,7 @@ describe DateTimeIndex do
291
334
  end
292
335
 
293
336
  it "returns slice upto last element if overshoot in range" do
294
- index = DateTimeIndex.date_range(:start => '2012-2-2', :periods => 50,
337
+ index = DateTimeIndex.date_range(:start => '2012-2-2', :periods => 50,
295
338
  freq: 'M')
296
339
  expect(index['2012'..'2013']).to eq(DateTimeIndex.date_range(
297
340
  :start => '2012-2-2',:periods => 50, freq: 'M'))
@@ -332,10 +375,75 @@ describe DateTimeIndex do
332
375
  }.to raise_error(ArgumentError)
333
376
  end
334
377
  end
378
+
379
+ context "#pos" do
380
+ let(:idx) do
381
+ described_class.new([
382
+ DateTime.new(2014,3,3),
383
+ DateTime.new(2014,3,4),
384
+ DateTime.new(2014,3,5),
385
+ DateTime.new(2014,3,6)
386
+ ], freq: :infer
387
+ )
388
+ end
389
+
390
+ context "single index" do
391
+ it { expect(idx.pos '2014-3-4').to eq 1 }
392
+ end
393
+
394
+ context "multiple indexes" do
395
+ subject { idx.pos '2014' }
396
+
397
+ it { is_expected.to be_a Array }
398
+ its(:size) { is_expected.to eq 4 }
399
+ it { is_expected.to eq [0, 1, 2, 3] }
400
+ end
401
+
402
+ context "single positional index" do
403
+ it { expect(idx.pos 1).to eq 1 }
404
+ end
405
+
406
+ context "multiple positional indexes" do
407
+ subject { idx.pos 0, 2 }
408
+
409
+ it { is_expected.to be_a Array }
410
+ its(:size) { is_expected.to eq 3 }
411
+ it { is_expected.to eq [0, 1, 2] }
412
+ end
413
+ end
414
+
415
+ context "#subset" do
416
+ let(:idx) do
417
+ described_class.new([
418
+ DateTime.new(2014,3,3),
419
+ DateTime.new(2014,3,4),
420
+ DateTime.new(2014,3,5),
421
+ DateTime.new(2014,3,6)
422
+ ], freq: :infer
423
+ )
424
+ end
425
+
426
+ context "multiple indexes" do
427
+ subject { idx.subset '2014' }
428
+
429
+ it { is_expected.to be_a described_class }
430
+ its(:size) { is_expected.to eq 4 }
431
+ it { is_expected.to eq idx }
432
+ end
433
+
434
+ context "multiple positional indexes" do
435
+ subject { idx.subset 0, 2 }
436
+
437
+ it { is_expected.to be_a described_class }
438
+ its(:size) { is_expected.to eq 3 }
439
+ its(:to_a) { is_expected.to eq [DateTime.new(2014, 3, 3),
440
+ DateTime.new(2014, 3, 4), DateTime.new(2014, 3, 5)] }
441
+ end
442
+ end
335
443
 
336
444
  context "#slice" do
337
445
  it "supports both DateTime objects" do
338
- index = DateTimeIndex.date_range(:start => '2012', :periods => 50,
446
+ index = DateTimeIndex.date_range(:start => '2012', :periods => 50,
339
447
  :freq => 'M')
340
448
  expect(index.slice(DateTime.new(2012,1,1), DateTime.new(2012,1,1,0,6))).to eq(
341
449
  DateTimeIndex.date_range(:start => '2012', :periods => 7, :freq => 'M'))
@@ -352,6 +460,16 @@ describe DateTimeIndex do
352
460
  expect(index.slice(DateTime.new(2012), '2013')).to eq(
353
461
  DateTimeIndex.date_range(:start => '2012', :periods => 24, :freq => 'MONTH'))
354
462
  end
463
+
464
+ it "supports two strings" do
465
+ index = DateTimeIndex.date_range(:start => '2012', :periods => 40, :freq => 'MONTH')
466
+ expect(index.slice('2012', '2013')).to eq(
467
+ DateTimeIndex.date_range(:start => '2012', :periods => 24, :freq => 'MONTH'))
468
+
469
+ # FIXME: It works this way now, yet I'm faithfully not sure that is most
470
+ # reasonable behavior. At least MY expectation is "slice(2012, 2013)" returns
471
+ # "from start of 2012 to start of 2013"... Or am I missing something?.. - zverok
472
+ end
355
473
  end
356
474
 
357
475
  context "#size" do
@@ -360,6 +478,25 @@ describe DateTimeIndex do
360
478
  expect(index.size).to eq(100)
361
479
  end
362
480
  end
481
+
482
+ context "#add" do
483
+ before { skip }
484
+ let(:idx) { Daru::Index.new [:a, :b, :c] }
485
+
486
+ context "single index" do
487
+ subject { idx }
488
+ before { idx.add :d }
489
+
490
+ its(:to_a) { is_expected.to eq [:a, :b, :c, :d] }
491
+ end
492
+
493
+ context "mulitple indexes" do
494
+ subject { idx }
495
+ before { idx.add :d, :e }
496
+
497
+ its(:to_a) { is_expected.to eq [:a, :b, :c, :d, :e] }
498
+ end
499
+ end
363
500
 
364
501
  context "#to_a" do
365
502
  it "returns an Array of ruby Time objects" do
@@ -430,4 +567,4 @@ describe DateTimeIndex do
430
567
  expect(index.include?(DateTime.new(2011,4,2))).to eq(false)
431
568
  end
432
569
  end
433
- end
570
+ end
@@ -1,4 +1,3 @@
1
- require 'spec_helper'
2
1
  include Daru
3
2
 
4
3
  describe DateOffset do
@@ -63,7 +62,7 @@ describe Offsets do
63
62
  end
64
63
 
65
64
  context "#initialize" do
66
- it "creates a seconds offset" do
65
+ it "creates a seconds offset" do
67
66
  expect(@offset + DateTime.new(2012,3,4,23,4,00)).to eq(
68
67
  DateTime.new(2012,3,4,23,4,05))
69
68
  end
@@ -200,7 +199,7 @@ describe Offsets do
200
199
  end
201
200
 
202
201
  context "#+" do
203
- it "offsets to beginning of next month" do
202
+ it "offsets to beginning of next month" do
204
203
  expect(@offset + DateTime.new(2012,3,25)).to eq(
205
204
  DateTime.new(2012,4,1))
206
205
 
@@ -296,7 +295,7 @@ describe Offsets do
296
295
  end
297
296
 
298
297
  context "#+" do
299
- it "offsets date to future" do
298
+ it "offsets date to future" do
300
299
  expect(@n_offset + DateTime.new(2012,3,25)).to eq(
301
300
  DateTime.new(2014,1,1))
302
301
  end
@@ -0,0 +1,2 @@
1
+ 1 2 3
2
+ 4 6
@@ -0,0 +1,2 @@
1
+ test 1 2
2
+ foo 3 4
@@ -0,0 +1,99 @@
1
+ describe Daru::Formatters::Table do
2
+ let(:options) { {} }
3
+ subject {
4
+ Daru::Formatters::Table
5
+ .format(data, options.merge(headers: headers, row_headers: row_headers))
6
+ }
7
+
8
+ let(:data) { [[1,2,3], [4,5,6], [7,8,9]] }
9
+ let(:headers) { [:col1, :col2, :col3] }
10
+ let(:row_headers) { [:row1, :row2, :row3] }
11
+
12
+ context 'simple table' do
13
+ it { is_expected.to eq %Q{
14
+ | col1 col2 col3
15
+ | row1 1 2 3
16
+ | row2 4 5 6
17
+ | row3 7 8 9
18
+ }.unindent}
19
+ end
20
+
21
+ context 'with nils' do
22
+ let(:data) { [[1,nil,3], [4,5,nil], [7,8,9]] }
23
+ let(:headers) { [:col1, :col2, nil] }
24
+ let(:row_headers) { [:row1, nil, :row3] }
25
+
26
+ it { is_expected.to eq %Q{
27
+ | col1 col2 |
28
+ | row1 1 nil 3|
29
+ | 4 5 nil|
30
+ | row3 7 8 9|
31
+ }.unindent}
32
+ end
33
+
34
+ context 'with multivalue row headers' do
35
+ let(:row_headers) { [[:row,1], [:row,2], [:row,3]] }
36
+ it { is_expected.to eq %Q{
37
+ | col1 col2 col3
38
+ | row 1 1 2 3
39
+ | row 2 4 5 6
40
+ | row 3 7 8 9
41
+ }.unindent}
42
+ end
43
+
44
+ context 'with multivalue column headers' do
45
+ let(:headers) { [[:col,1], [:col,2], [:col,3]] }
46
+ end
47
+
48
+ context 'rows only' do
49
+ let(:data) { [] }
50
+ let(:headers) { nil }
51
+ it { is_expected.to eq %Q{
52
+ | row1
53
+ | row2
54
+ | row3
55
+ }.unindent}
56
+ end
57
+
58
+ context 'columns only' do
59
+ let(:data) { [] }
60
+ let(:row_headers) { nil }
61
+ it { is_expected.to eq %Q{
62
+ | col1 col2 col3
63
+ }.unindent}
64
+ end
65
+
66
+ context 'wide values' do
67
+ let(:options) { {spacing: 2} }
68
+
69
+ it { is_expected.to eq %Q{
70
+ | co co co
71
+ | ro 1 2 3
72
+ | ro 4 5 6
73
+ | ro 7 8 9
74
+ }.unindent}
75
+ end
76
+
77
+ context '<more> threshold' do
78
+ let(:options) { {threshold: threshold} }
79
+ context 'lower than data size' do
80
+ let(:threshold) { 2 }
81
+ it { is_expected.to eq %Q{
82
+ | col1 col2 col3
83
+ | row1 1 2 3
84
+ | row2 4 5 6
85
+ | ... ... ... ...
86
+ }.unindent}
87
+ end
88
+
89
+ context 'greater than data size' do
90
+ let(:threshold) { 5 }
91
+ it { is_expected.to eq %Q{
92
+ | col1 col2 col3
93
+ | row1 1 2 3
94
+ | row2 4 5 6
95
+ | row3 7 8 9
96
+ }.unindent}
97
+ end
98
+ end
99
+ end