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.
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