rubyexcel 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/README.md CHANGED
@@ -3,13 +3,19 @@ RubyExcel
3
3
 
4
4
  Designed for Ruby on Windows with MS Excel
5
5
 
6
- Please feel free to log any bugs you find [here](https://github.com/VirtuosoJoel/RubyExcel/issues "Bug Tracker").
7
-
8
6
  Introduction
9
7
  ------------
10
8
 
11
9
  A Data-analysis tool for Ruby, with an Excel-style API.
12
10
 
11
+ You can find the gem [here](https://rubygems.org/gems/rubyexcel "Rubygems").
12
+
13
+ Main Documentation is [here](rubydoc.info/gems/rubyexcel "Rubydoc")
14
+
15
+ For any requests, comments, etc. I keep an eye on [This forum](http://www.ruby-forum.com/forum/ruby "Ruby Mailing List"). If you have "RubyExcel" in the title I should see it.
16
+
17
+ Please feel free to log any bugs you find [here](https://github.com/VirtuosoJoel/RubyExcel/issues "Bug Tracker").
18
+
13
19
  Details
14
20
  -----
15
21
 
@@ -36,7 +42,7 @@ As this works directly on the data, processing is faster than using Excel itself
36
42
  This was written out of the frustration of editing tabular data using Ruby's multidimensional arrays,
37
43
  without affecting headers and while maintaining code readability.
38
44
  Its API is designed to simplify moving code across from VBA into Ruby format when processing spreadsheet data.
39
- The combination of Ruby, WIN32OLE Excel, and extracting HTML table data is probably quite rare; but I thought I'd share what I came up with.
45
+ The combination of Ruby, WIN32OLE Excel, and analysing table data is probably quite rare; but I thought I'd share what I came up with.
40
46
 
41
47
  Examples
42
48
  ========
@@ -5,6 +5,8 @@ require_relative 'address.rb'
5
5
  #
6
6
  # The class which holds a Sheet's data
7
7
  #
8
+ # @note This class is exposed to the API purely for debugging.
9
+ #
8
10
 
9
11
  class Data
10
12
  include Address
@@ -71,24 +73,15 @@ require_relative 'address.rb'
71
73
  #
72
74
  # Returns a copy of the data
73
75
  #
76
+ # @return [Array<Array>]
77
+ #
74
78
 
75
79
  def all
76
80
  @data.dup
77
81
  end
78
-
79
- #
80
- # Appends a multidimensional Array to the end of the data
81
- #
82
- # @param [Array<Array>] multi_array the multidimensional Array to add to the data
83
- #
84
-
85
- def append( multi_array )
86
- @data << multi_array
87
- calc_dimensions
88
- end
89
-
82
+
90
83
  #
91
- # Finds a Column reference bu a header
84
+ # Finds a Column reference by a header
92
85
  #
93
86
  # @param [String] header the header to search for
94
87
  # @return [String] the Column reference
@@ -162,7 +155,6 @@ require_relative 'address.rb'
162
155
 
163
156
  def delete_column( ref )
164
157
  delete( Column.new( sheet, ref ) )
165
- calc_dimensions
166
158
  end
167
159
 
168
160
  #
@@ -171,7 +163,6 @@ require_relative 'address.rb'
171
163
 
172
164
  def delete_row( ref )
173
165
  delete( Row.new( sheet, ref ) )
174
- calc_dimensions
175
166
  end
176
167
 
177
168
  #
@@ -180,7 +171,6 @@ require_relative 'address.rb'
180
171
 
181
172
  def delete_range( ref )
182
173
  delete( Element.new( sheet, ref ) )
183
- calc_dimensions
184
174
  end
185
175
 
186
176
  #
@@ -194,7 +184,7 @@ require_relative 'address.rb'
194
184
  end
195
185
 
196
186
  #
197
- # Check whether the data is empty
187
+ # Check whether the data (without headers) is empty
198
188
  #
199
189
  # @return [Boolean]
200
190
  #
@@ -208,6 +198,7 @@ require_relative 'address.rb'
208
198
  #
209
199
 
210
200
  def each
201
+ return to_enum( :each ) unless block_given?
211
202
  @data.each { |ar| yield ar }
212
203
  end
213
204
 
@@ -230,6 +221,7 @@ require_relative 'address.rb'
230
221
  # Select and re-order Columns by a list of headers
231
222
  #
232
223
  # @param [Array<String>] headers the ordered list of headers to keep
224
+ # @note This method can accept either a list of arguments or an Array
233
225
  # @note Invalid headers will be skipped
234
226
  #
235
227
 
@@ -258,7 +250,8 @@ require_relative 'address.rb'
258
250
  #
259
251
 
260
252
  def index_by_header( header )
261
- col_index( sheet.header_rows > 0 ? colref_by_header( header ) : header )
253
+ sheet.header_rows > 0 or fail NoMethodError, 'No header rows present'
254
+ col_index( colref_by_header( header ) )
262
255
  end
263
256
 
264
257
  #
@@ -365,7 +358,7 @@ require_relative 'address.rb'
365
358
  #
366
359
 
367
360
  def sort_by!( &block )
368
- @data = skip_headers { |d| d.sort_by( &block ) }
361
+ @data = skip_headers { |d| d.sort_by( &block ) }; self
369
362
  end
370
363
 
371
364
  #
@@ -391,6 +384,7 @@ require_relative 'address.rb'
391
384
  ( row_idx - rows ).times { @data << [] }
392
385
  @data[ row_idx-1 ][ col_idx-1 ] = val
393
386
  calc_dimensions
387
+ val
394
388
  end
395
389
  alias []= write
396
390
 
@@ -65,15 +65,35 @@ module RubyExcel
65
65
  #
66
66
 
67
67
  def value=( val )
68
+
69
+ #Range
68
70
  if address.include? ':'
71
+
72
+ addresses = expand( address )
73
+
74
+ # 2D Array of Values
69
75
  if multi_array?( val )
70
- expand( address ).each_with_index { |row,idx| row.each_with_index { |el,i| data[ el ] = val[idx][i] } }
76
+
77
+ #Check the dimensions
78
+ val_rows, val_cols, range_rows, range_cols = val.length, val.max_by(&:length).length, addresses.length, addresses.max_by(&:length).length
79
+ val_rows == range_rows && val_cols == range_cols or fail ArgumentError, "Dimension mismatch! Value rows, columns: #{ val_rows }, #{ val_cols }. Range rows, columns: #{ range_rows }, #{ range_cols }"
80
+
81
+ #Write the values in order
82
+ addresses.each_with_index { |row,idx| row.each_with_index { |el,i| data[ el ] = val[idx][i] } }
83
+
84
+ # Single Value
71
85
  else
72
- expand( address ).each { |ar| ar.each { |addr| data[ addr ] = val } }
86
+
87
+ #Write the same value to every cell in the Range
88
+ addresses.each { |ar| ar.each { |addr| data[ addr ] = val } }
89
+
73
90
  end
91
+
92
+ #Cell
74
93
  else
75
94
  data[ address ] = val
76
95
  end
96
+
77
97
  self
78
98
  end
79
99
 
@@ -28,16 +28,16 @@ module RubyExcel
28
28
 
29
29
  #
30
30
  # Append a value to the Section.
31
- # This only adds an extra cell if it is the first Row / Column.
32
- # This prevents a loop through Rows or Columns from extending diagonally away from the main data.
33
31
  #
34
32
  # @param [Object] value the object to append
33
+ # @note This only adds an extra cell if it is the first Row / Column.
34
+ # This prevents a loop through Rows or Columns from extending diagonally away from the main data.
35
35
  #
36
36
 
37
37
  def <<( value )
38
38
  case self
39
- when Row ; lastone = ( col_index( idx ) == 1 ? data.cols + 1 : data.cols )
40
- else ; lastone = ( col_index( idx ) == 1 ? data.rows + 1 : data.rows )
39
+ when Row ; lastone = ( idx == 1 ? data.cols + 1 : data.cols )
40
+ else ; lastone = ( idx == 'A' ? data.rows + 1 : data.rows )
41
41
  end
42
42
  data[ translate_address( lastone ) ] = value
43
43
  end
@@ -58,6 +58,44 @@ module RubyExcel
58
58
  data.delete( self ); self
59
59
  end
60
60
 
61
+ #
62
+ # Yields each value
63
+ #
64
+
65
+ def each
66
+ return to_enum(:each) unless block_given?
67
+ each_address { |addr| yield data[ addr ] }
68
+ end
69
+
70
+ #
71
+ # Yields each value, skipping headers
72
+ #
73
+
74
+ def each_without_headers
75
+ return to_enum( :each_without_headers ) unless block_given?
76
+ each_address_without_headers { |addr| yield data[ addr ] }
77
+ end
78
+ alias each_wh each_without_headers
79
+
80
+ #
81
+ # Yields each cell
82
+ #
83
+
84
+ def each_cell
85
+ return to_enum( :each_cell ) unless block_given?
86
+ each_address { |addr| yield Element.new( sheet, addr ) }
87
+ end
88
+
89
+ #
90
+ # Yields each cell, skipping headers
91
+ #
92
+
93
+ def each_cell_without_headers
94
+ return to_enum( :each_cell_without_headers ) unless block_given?
95
+ each_address_without_headers { |addr| yield Element.new( sheet, addr ) }
96
+ end
97
+ alias each_cell_wh each_cell_without_headers
98
+
61
99
  #
62
100
  # Check whether the data in self is empty
63
101
  #
@@ -86,6 +124,15 @@ module RubyExcel
86
124
  "#{ self.class }:0x#{ '%x' % (object_id << 1) }: #{ idx }"
87
125
  end
88
126
 
127
+ #
128
+ # Replaces each value with the result of the block
129
+ #
130
+
131
+ def map!
132
+ return to_enum( :map! ) unless block_given?
133
+ each_address { |addr| data[addr] = ( yield data[addr] ) }
134
+ end
135
+
89
136
  #
90
137
  # Read a value by address
91
138
  #
@@ -128,53 +175,6 @@ module RubyExcel
128
175
  end
129
176
  alias []= write
130
177
 
131
- #
132
- # Yields each value
133
- #
134
-
135
- def each
136
- return to_enum(:each) unless block_given?
137
- each_address { |addr| yield data[ addr ] }
138
- end
139
-
140
- #
141
- # Yields each value, skipping headers
142
- #
143
-
144
- def each_without_headers
145
- return to_enum( :each_without_headers ) unless block_given?
146
- each_address_without_headers { |addr| yield data[ addr ] }
147
- end
148
- alias each_wh each_without_headers
149
-
150
- #
151
- # Yields each cell
152
- #
153
-
154
- def each_cell
155
- return to_enum( :each_cell ) unless block_given?
156
- each_address { |addr| yield Element.new( sheet, addr ) }
157
- end
158
-
159
- #
160
- # Yields each cell, skipping headers
161
- #
162
-
163
- def each_cell_without_headers
164
- return to_enum( :each_cell_without_headers ) unless block_given?
165
- each_address_without_headers { |addr| yield Element.new( sheet, addr ) }
166
- end
167
- alias each_cell_wh each_cell_without_headers
168
-
169
- #
170
- # Replaces each value with the result of the block
171
- #
172
-
173
- def map!
174
- return to_enum( :map! ) unless block_given?
175
- each_address { |addr| data[addr] = ( yield data[addr] ) }
176
- end
177
-
178
178
  private
179
179
 
180
180
  def translate_address( addr )
@@ -192,11 +192,12 @@ module RubyExcel
192
192
 
193
193
  #
194
194
  # A Row in the Sheet
195
+ # @attr_reader [Fixnum] idx the Row index
196
+ # @attr_reader [Fixnum] length the Row length
195
197
  #
196
198
 
197
199
  class Row < Section
198
200
 
199
- # The Row index
200
201
  attr_reader :idx
201
202
 
202
203
  #
@@ -238,6 +239,10 @@ module RubyExcel
238
239
  fail ArgumentError, 'Invalid header: ' + header.to_s
239
240
  end
240
241
 
242
+ def length
243
+ data.cols
244
+ end
245
+
241
246
  #
242
247
  # Find a value in this Row by its header
243
248
  #
@@ -255,20 +260,19 @@ module RubyExcel
255
260
  def each_address
256
261
  ( 'A'..col_letter( data.cols ) ).each { |col_id| yield "#{col_id}#{idx}" }
257
262
  end
258
-
259
- def each_address_without_headers
260
- ( 'A'..col_letter( data.cols ) ).each { |col_id| yield "#{col_id}#{idx}" }
261
- end
263
+ alias each_address_without_headers each_address
262
264
 
263
265
  end
264
266
 
265
267
  #
266
268
  # A Column in the Sheet
267
269
  #
270
+ # @attr_reader [String] idx the Column index
271
+ # @attr_reader [Fixnum] length the Column length
272
+ #
268
273
 
269
274
  class Column < Section
270
275
 
271
- # The Row index
272
276
  attr_reader :idx
273
277
 
274
278
  #
@@ -282,6 +286,10 @@ module RubyExcel
282
286
  @idx = idx
283
287
  super( sheet )
284
288
  end
289
+
290
+ def length
291
+ data.rows
292
+ end
285
293
 
286
294
  private
287
295
 
data/lib/rubyexcel.rb CHANGED
@@ -293,7 +293,7 @@ module RubyExcel
293
293
  def <<( other )
294
294
  case other
295
295
  when Array ; load( data.all + other, header_rows )
296
- when Hash ; load( data.all + _convert_hash( other ) )
296
+ when Hash ; load( data.all + _convert_hash( other ), header_rows )
297
297
  when Sheet ; load( data.all + other.data.no_headers, header_rows )
298
298
  else ; fail ArgumentError, "Unsupported class: #{ other.class }"
299
299
  end
@@ -308,10 +308,8 @@ module RubyExcel
308
308
 
309
309
  # @overload advanced_filter!( header, comparison_operator, search_criteria, ... )
310
310
  # Filter on multiple criteria
311
- #
312
311
  # @example Filter to 'Part': 'Type1' and 'Type3', with Qty greater than 1
313
312
  # s.advanced_filter!( 'Part', :=~, /Type[13]/, 'Qty', :>, 1 )
314
- #
315
313
  # @example Filter to 'Part': 'Type1', with 'Ref1' containing 'X'
316
314
  # s.advanced_filter!( 'Part', :==, 'Type1', 'Ref1', :include?, 'X' )
317
315
  #
@@ -474,6 +472,7 @@ module RubyExcel
474
472
  # Select and re-order Columns by a list of headers
475
473
  #
476
474
  # @param [Array<String>] headers the ordered list of headers to keep
475
+ # @note This method can accept either a list of arguments or an Array
477
476
  # @note Invalid headers will be skipped
478
477
  #
479
478
 
@@ -0,0 +1,81 @@
1
+ require_relative '../../rubyexcel'
2
+ require 'test/unit'
3
+
4
+
5
+ class TestAddress < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @s = RubyExcel.sample_sheet
9
+ end
10
+
11
+ def teardown
12
+ @s = nil
13
+ end
14
+
15
+ def test_address_to_col_index
16
+
17
+ assert( @s.address_to_col_index( 'A1' ) == 1 )
18
+
19
+ end
20
+
21
+ def test_address_to_indices
22
+
23
+ assert_equal( [ 1, 1 ], @s.address_to_indices( 'A1' ) )
24
+
25
+ end
26
+
27
+ def test_col_index
28
+
29
+ assert_equal( 1, @s.col_index( 'A' ) )
30
+
31
+ end
32
+
33
+ def test_col_letter
34
+
35
+ assert_equal( 'A', @s.col_letter( 1 ) )
36
+
37
+ end
38
+
39
+ def test_column_id
40
+
41
+ assert_equal( 'A', @s.column_id( 'A1' ) )
42
+
43
+ end
44
+
45
+ def test_expand
46
+
47
+ assert_equal( [['A1','B1'],['A2', 'B2']], @s.expand( 'A1:B2' ) )
48
+
49
+ end
50
+
51
+ def test_indices_to_address
52
+
53
+ assert_equal( 'A1', @s.indices_to_address( 1, 1 ) )
54
+
55
+ end
56
+
57
+ def test_multi_array?
58
+
59
+ assert( @s.multi_array? RubyExcel.sample_data )
60
+
61
+ end
62
+
63
+ def test_offset
64
+
65
+ assert_equal( 'B2', @s.offset( 'A1', 1, 1 ) )
66
+
67
+ end
68
+
69
+ def test_to_range_address
70
+
71
+ assert_equal( 'A1:B2', @s.to_range_address( @s.cell(1,1), @s.cell(2,2) ) )
72
+
73
+ end
74
+
75
+ def test_row_id
76
+
77
+ assert_equal( 2, @s.row_id( 'A2' ) )
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,153 @@
1
+ require_relative '../../rubyexcel'
2
+ require 'test/unit'
3
+
4
+ class TestData < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @s = RubyExcel.sample_sheet
8
+ end
9
+
10
+ def teardown
11
+ @s = nil
12
+ end
13
+
14
+ def test_advanced_filter!
15
+
16
+ assert_equal( 3, @s.data.advanced_filter!( 'Part', :=~, /Type[13]/, 'Qty', :>, 1 ).rows )
17
+
18
+ end
19
+
20
+ def test_colref_by_header
21
+
22
+ assert_equal( 'B', @s.data.colref_by_header( 'Ref1' ) )
23
+
24
+ end
25
+
26
+ def test_compact
27
+
28
+ @s << [[1,2,3], [4,5,6]]
29
+ assert( @s.data.cols == 5 && @s.data.rows == 10 )
30
+
31
+ @s.rows( 9 ) { |r| r.map! { nil } }
32
+ @s.data.compact!
33
+ assert_equal( 8, @s.data.rows )
34
+
35
+ end
36
+
37
+ def test_delete
38
+
39
+ @s.data.delete( @s.row(1) )
40
+ assert_equal( 7, @s.data.rows )
41
+
42
+ @s.data.delete( @s.column(1) )
43
+ assert_equal( 4, @s.data.cols )
44
+
45
+ @s.data.delete( @s.range('A:A') )
46
+ assert_equal( 3, @s.data.cols )
47
+
48
+ assert_raise( NoMethodError ) { @s.data.delete( [[]] ) }
49
+
50
+ end
51
+
52
+ def test_each
53
+
54
+ assert_equal( 8, @s.data.each.count )
55
+
56
+ end
57
+
58
+ def test_filter!
59
+
60
+ assert_equal( 3, @s.data.filter!( 'Part', &/Type2/ ).rows )
61
+
62
+ end
63
+
64
+ def test_get_columns!
65
+
66
+ assert_equal( [ 'Ref2', 'Part' ], @s.data.get_columns!( 'Ref2', 'Part' ).sheet.row(1).to_a )
67
+
68
+ end
69
+
70
+ def test_headers
71
+
72
+ assert_equal( 1, @s.data.headers.length )
73
+
74
+ @s.headers = 0
75
+ assert_equal( nil, @s.data.headers )
76
+
77
+ end
78
+
79
+ def test_index_by_header
80
+
81
+ assert_equal( 1, @s.data.index_by_header( 'Part' ) )
82
+
83
+ @s.headers = 0
84
+ assert_raise( NoMethodError ) { @s.data.index_by_header( 'Part' ) }
85
+
86
+ end
87
+
88
+ def test_insert
89
+
90
+ @s.data.insert_columns( 'A', 2 )
91
+ assert_equal( 7, @s.maxcol )
92
+ assert_equal( nil, @s['B2'] )
93
+
94
+ @s.data.insert_rows( 2, 2 )
95
+ assert_equal( 10, @s.maxrow )
96
+ assert_equal( nil, @s['B4'] )
97
+
98
+ end
99
+
100
+ def test_no_headers
101
+
102
+ assert_equal( 7, @s.data.no_headers.length )
103
+
104
+ end
105
+
106
+ def test_partition
107
+
108
+ ar1, ar2 = @s.data.partition( 'Part', &/Type[13]/ )
109
+ assert_equal( 5, ar1.length )
110
+ assert_equal( 'Type1', ar1[1][0] )
111
+ assert_equal( 4, ar2.length )
112
+
113
+ end
114
+
115
+ def test_read_write
116
+
117
+ assert_equal( '123', @s.data.read( 'C3' ) )
118
+
119
+ @s.data.write( 'C3', '321' )
120
+ assert_equal( '321', @s.data.read( 'C3' ) )
121
+
122
+ end
123
+
124
+ def test_reverse
125
+
126
+ @s.data.reverse_columns!
127
+ assert_equal( 'Cost', @s.A1 )
128
+
129
+ @s.data.reverse_rows!
130
+ assert_equal( 'QT1', @s.d8 )
131
+
132
+ @s.headers = 0
133
+ @s.data.reverse_rows!
134
+ assert_equal( 'Ref1', @s.d8 )
135
+
136
+ end
137
+
138
+ def test_skip_headers
139
+
140
+ @s.load( @s.data.skip_headers { |data| data.map { |row| row.map { nil } } } )
141
+ assert_equal( 'Part', @s.a1 )
142
+ assert_equal( nil, @s.a2 )
143
+
144
+ end
145
+
146
+ def test_uniq!
147
+
148
+ @s.data.uniq!( 'Part' )
149
+ assert_equal( 5, @s.maxrow )
150
+
151
+ end
152
+
153
+ end
@@ -0,0 +1,42 @@
1
+ require_relative '../../rubyexcel'
2
+ require 'test/unit'
3
+
4
+ class TestElement < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @s = RubyExcel.sample_sheet
8
+ end
9
+
10
+ def teardown
11
+ @s = nil
12
+ end
13
+
14
+ def test_initialize
15
+
16
+ r = @s.range( 'A1:B2' )
17
+ assert_equal( @s, r.sheet )
18
+ assert_equal( 'A1:B2', r.address )
19
+ assert_equal( 'A', r.column )
20
+ assert_equal( 1, r.row )
21
+
22
+ end
23
+
24
+ def test_value
25
+
26
+ r = @s.range( 'A1' )
27
+ assert_equal( 'Part', r.value )
28
+
29
+ r = @s.range( 'A1:B2' )
30
+ assert_equal( [['Part', 'Ref1'], ['Type1', 'QT1']], r.value )
31
+
32
+ assert_raise( ArgumentError ) { r.value = [[1, 2]] }
33
+
34
+ end
35
+
36
+ def test_each
37
+
38
+ assert_equal( 6, @s.range( 'A1:C2' ).each.count )
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,59 @@
1
+ require_relative '../../rubyexcel'
2
+ require 'test/unit'
3
+
4
+ class TestRowColumn < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @s = RubyExcel.sample_sheet
8
+ @r = @s.row(2)
9
+ @c = @s.column(2)
10
+ end
11
+
12
+ def teardown
13
+ @s = nil
14
+ @r = nil
15
+ end
16
+
17
+ def test_shovel
18
+
19
+ @r << 1
20
+ assert_equal( 5, @r.length )
21
+
22
+ @r = @s.row(1)
23
+ @r << 1
24
+ assert_equal( 6, @r.length )
25
+
26
+ end
27
+
28
+ def test_cell
29
+
30
+ assert_equal( @r.cell(2).address, @c.cell(2).address )
31
+
32
+ end
33
+
34
+ def test_find
35
+
36
+ assert_equal( 'B2', @r.find( &/QT1/ ) )
37
+
38
+ end
39
+
40
+ def test_summarise
41
+
42
+ h = { 'Type1' => 3, 'Type2' => 2, 'Type3' => 1, 'Type4' => 1 }
43
+ assert_equal( h, @s.column(1).summarise )
44
+
45
+ end
46
+
47
+ def test_getref
48
+
49
+ assert_equal( 'A', @r.getref( 'Part' ) )
50
+
51
+ end
52
+
53
+ def test_value_by_header
54
+
55
+ assert_equal( 'Type1', @r.val( 'Part' ) )
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,272 @@
1
+ require_relative '../rubyexcel'
2
+ require 'test/unit'
3
+
4
+ class TestRegexp < Test::Unit::TestCase
5
+
6
+ def test_to_proc
7
+ assert_equal(0, /a/.to_proc.call('a') )
8
+ end
9
+
10
+ end
11
+
12
+ class TestWorkbook < Test::Unit::TestCase
13
+
14
+ def setup
15
+ @wb = RubyExcel::Workbook.new
16
+ 3.times { @wb.add.load RubyExcel.sample_data }
17
+ end
18
+
19
+ def teardown
20
+ @wb = nil
21
+ end
22
+
23
+ def test_shovel
24
+
25
+ @wb << @wb.dup
26
+ assert_equal( 6, @wb.sheets.count )
27
+
28
+ @wb << @wb.sheets(1)
29
+ assert_equal( 7, @wb.sheets.count )
30
+
31
+ @wb << @wb.sheets(1).data.all
32
+ assert_equal( 8, @wb.sheets.count )
33
+
34
+ end
35
+
36
+ def test_add
37
+
38
+ @wb.add 'Sheet4'
39
+ assert_equal( 4, @wb.sheets.count )
40
+
41
+ @wb.add
42
+ assert_equal( 5, @wb.sheets.count )
43
+
44
+ @wb.add @wb.sheets(1)
45
+ assert_equal( 6, @wb.sheets.count )
46
+
47
+ assert_raise( TypeError ) { @wb.add 1 }
48
+
49
+ end
50
+
51
+ def test_clear_all
52
+
53
+ assert_equal( 0, @wb.clear_all.sheets.count )
54
+
55
+ end
56
+
57
+ def test_delete
58
+
59
+ assert_equal( 2, @wb.delete(1).sheets.count )
60
+
61
+ assert_equal( 1, @wb.delete( 'Sheet2' ).sheets.count )
62
+
63
+ assert_equal( 0, @wb.delete( /Sheet/ ).sheets.count )
64
+
65
+ assert_equal( 0, @wb.delete( @wb.add ).sheets.count )
66
+
67
+ end
68
+
69
+ def test_dup
70
+
71
+ dup_wb = @wb.dup
72
+
73
+ assert_equal( @wb.sheets(1).to_a, dup_wb.sheets(1).to_a )
74
+
75
+ assert_not_equal( @wb.object_id, dup_wb.object_id )
76
+
77
+ end
78
+
79
+ def test_empty?
80
+
81
+ assert( !@wb.empty? )
82
+
83
+ assert( @wb.clear_all.empty? )
84
+
85
+ end
86
+
87
+ def test_load
88
+
89
+ assert( @wb.load( [[]] ).class == RubyExcel::Sheet )
90
+
91
+ assert( @wb.load( RubyExcel.sample_data )['A1'] == 'Part' )
92
+
93
+ end
94
+
95
+ def test_sheets
96
+
97
+ assert( @wb.sheets.class == Enumerator )
98
+
99
+ assert( @wb.sheets(2) == @wb.sheets('Sheet2') )
100
+
101
+ end
102
+
103
+ end
104
+
105
+ class TestSheet < Test::Unit::TestCase
106
+
107
+ def setup
108
+ @s = RubyExcel.sample_sheet
109
+ end
110
+
111
+ def teardown
112
+ @s = nil
113
+ end
114
+
115
+ def test_basics
116
+
117
+ assert( @s['A1'] == @s.A1 )
118
+
119
+ @s << RubyExcel.sample_hash
120
+ assert( @s.maxrow == 20 && @s.maxcol == 5 )
121
+
122
+ @s << RubyExcel.sample_data
123
+ assert( @s.maxrow == 28 && @s.maxcol == 5 )
124
+
125
+ @s << @s
126
+ assert( @s.maxrow == 55 && @s.maxcol == 5 )
127
+
128
+ end
129
+
130
+ def test_advanced_filter
131
+
132
+ @s.advanced_filter!( 'Part', :=~, /Type[13]/, 'Qty', :>, 1 )
133
+ assert( @s.maxrow == 3 )
134
+
135
+ setup
136
+ @s.advanced_filter!( 'Part', :==, 'Type1', 'Ref1', :include?, 'X' )
137
+ assert( @s.maxrow == 2 )
138
+
139
+ end
140
+
141
+ def test_cell
142
+
143
+ assert( @s.cell(1,1).value == 'Part' && @s.cell(1,1).address == 'A1' )
144
+
145
+ end
146
+
147
+ def test_column
148
+
149
+ assert( @s.column('A')[1] == 'Part' )
150
+
151
+ end
152
+
153
+ def test_column_by_header
154
+
155
+ assert( @s.ch( 'Part' )[1] == @s.ch( @s.column(1) )[1] )
156
+
157
+ end
158
+
159
+ def test_columns
160
+
161
+ assert( @s.columns.class == Enumerator )
162
+
163
+ assert( @s.columns( 'B' ).count == 4 )
164
+
165
+ assert( @s.columns( 'B', 'D' ).to_a[0][1] == 'Ref1' )
166
+
167
+ end
168
+
169
+ def test_filter
170
+
171
+ assert( @s.filter( 'Part', &/Type[13]/ ).maxrow == 5 )
172
+
173
+ end
174
+
175
+ def test_get_columns
176
+
177
+ assert_equal( @s.get_columns( 'Ref2', 'Part' ).row(1).to_a, [ 'Ref2', 'Part' ] )
178
+
179
+ end
180
+
181
+ def test_insert_columns
182
+
183
+ assert( @s.insert_columns( 2, 2 ).columns.count == 7 )
184
+
185
+ end
186
+
187
+ def test_insert_rows
188
+
189
+ assert( @s.insert_rows( 2, 2 ).rows.count == 10 )
190
+
191
+ end
192
+
193
+ def test_match
194
+
195
+ assert( @s.match( 'Part', &/Type2/ ) == 3 )
196
+
197
+ end
198
+
199
+ def test_method_missing
200
+
201
+ assert( @s.a1 == 'Part' )
202
+
203
+ assert_raise( NoMethodError ) { @s.abcd123 }
204
+
205
+ end
206
+
207
+ def test_respond_to?
208
+
209
+ assert( @s.respond_to?(:A1) )
210
+
211
+ end
212
+
213
+ def test_partition
214
+
215
+ s1, s2 = @s.partition( 'Qty' ) { |v| v > 1 }
216
+ assert_equal( s1.maxrow + 1, s2.maxrow )
217
+
218
+ end
219
+
220
+ def test_range
221
+
222
+ assert( @s.range( 'A1:A1' ).value == @s.range( @s.cell(1,1), @s.cell( 1,1 ) ).value )
223
+
224
+ assert( @s.range( 'A1' ).value == @s.range( @s.cell(1,1) ).value )
225
+
226
+ end
227
+
228
+ def test_reverse
229
+
230
+ assert( @s.reverse_columns!['A1'] == 'Cost' )
231
+
232
+ assert( @s.reverse_rows!['A2'] == 104 )
233
+
234
+ end
235
+
236
+ def test_row
237
+
238
+ assert( @s.row(1)['A'] == 'Part' )
239
+
240
+ end
241
+
242
+ def test_rows
243
+
244
+ assert( @s.rows.class == Enumerator )
245
+
246
+ assert( @s.rows( 2 ).count == 7 )
247
+
248
+ assert( @s.rows( 2, 4 ).to_a[0]['A'] == 'Type1' )
249
+
250
+ end
251
+
252
+ def test_sumif
253
+
254
+ assert( @s.sumif( 'Part', 'Cost', &/Type1/ ) == 169.15 )
255
+
256
+ end
257
+
258
+ def test_uniq
259
+
260
+ assert( @s.uniq( 'Part' ).maxrow == 5 )
261
+
262
+ end
263
+
264
+ def test_
265
+
266
+ assert( @s.vlookup( 'Part', 'Ref2', &/Type1/ ) == '231' )
267
+
268
+ end
269
+
270
+
271
+
272
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'tc_rubyexcel'
2
+ require_relative 'rubyexcel/tc_address'
3
+ require_relative 'rubyexcel/tc_data'
4
+ require_relative 'rubyexcel/tc_element'
5
+ require_relative 'rubyexcel/tc_section'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyexcel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-30 00:00:00.000000000 Z
12
+ date: 2013-05-01 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A tabular data structure, mixing Ruby with some of Excel's API style.
15
15
  email: VirtuosoJoel@gmail.com
@@ -24,6 +24,12 @@ files:
24
24
  - lib/rubyexcel/rubyexcel_components.rb
25
25
  - lib/rubyexcel/section.rb
26
26
  - lib/rubyexcel.rb
27
+ - lib/test/rubyexcel/tc_address.rb
28
+ - lib/test/rubyexcel/tc_data.rb
29
+ - lib/test/rubyexcel/tc_element.rb
30
+ - lib/test/rubyexcel/tc_section.rb
31
+ - lib/test/tc_rubyexcel.rb
32
+ - lib/test/test_all.rb
27
33
  - lib/README.md
28
34
  homepage: https://github.com/VirtuosoJoel
29
35
  licenses: []