fastercsv 0.2.1 → 1.0.0
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.
- data/CHANGELOG +15 -3
- data/README +2 -2
- data/TODO +1 -26
- data/examples/csv_filter.rb +8 -0
- data/examples/csv_reading.rb +57 -0
- data/examples/csv_table.rb +56 -0
- data/examples/csv_writing.rb +67 -0
- data/examples/shortcut_interface.rb +4 -0
- data/lib/faster_csv.rb +432 -74
- data/test/tc_features.rb +41 -13
- data/test/tc_headers.rb +35 -26
- data/test/tc_row.rb +3 -0
- data/test/tc_table.rb +385 -0
- data/test/ts_all.rb +1 -0
- metadata +6 -2
data/test/tc_features.rb
CHANGED
@@ -28,6 +28,16 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
28
28
|
[%Q{"\r\n,"}, ["\r\n,"]],
|
29
29
|
[%Q{"\r\n,",}, ["\r\n,", nil]] ]
|
30
30
|
|
31
|
+
def setup
|
32
|
+
@sample_data = <<-END_DATA.gsub(/^ +/, "")
|
33
|
+
line,1,abc
|
34
|
+
line,2,"def\nghi"
|
35
|
+
|
36
|
+
line,4,jkl
|
37
|
+
END_DATA
|
38
|
+
@csv = FasterCSV.new(@sample_data)
|
39
|
+
end
|
40
|
+
|
31
41
|
def test_col_sep
|
32
42
|
[";", "\t"].each do |sep|
|
33
43
|
TEST_CASES.each do |test_case|
|
@@ -64,22 +74,22 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
64
74
|
end
|
65
75
|
|
66
76
|
def test_lineno
|
67
|
-
sample_data
|
68
|
-
line,1,abc
|
69
|
-
line,2,"def\nghi"
|
77
|
+
assert_equal(5, @sample_data.to_a.size)
|
70
78
|
|
71
|
-
line,4,jkl
|
72
|
-
END_DATA
|
73
|
-
assert_equal(5, sample_data.to_a.size)
|
74
|
-
|
75
|
-
csv = FasterCSV.new(sample_data)
|
76
79
|
4.times do |line_count|
|
77
|
-
assert_equal(line_count, csv.lineno)
|
78
|
-
assert_not_nil(csv.shift)
|
79
|
-
assert_equal(line_count + 1, csv.lineno)
|
80
|
+
assert_equal(line_count, @csv.lineno)
|
81
|
+
assert_not_nil(@csv.shift)
|
82
|
+
assert_equal(line_count + 1, @csv.lineno)
|
80
83
|
end
|
81
|
-
assert_nil(csv.shift)
|
82
|
-
|
84
|
+
assert_nil(@csv.shift)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_readline
|
88
|
+
test_lineno
|
89
|
+
|
90
|
+
@csv.rewind
|
91
|
+
|
92
|
+
test_lineno
|
83
93
|
end
|
84
94
|
|
85
95
|
def test_unknown_options
|
@@ -93,6 +103,24 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
93
103
|
assert_nothing_raised(Exception) do
|
94
104
|
FasterCSV.new(String.new, :col_sep => "|")
|
95
105
|
end
|
106
|
+
|
107
|
+
# failing to reset header behavior on rewind() (reported by Chris Roos)
|
108
|
+
csv = FasterCSV.new( "forename,surname", :headers => true,
|
109
|
+
:return_headers => true )
|
110
|
+
csv.each { |row| assert row.header_row? }
|
111
|
+
csv.rewind
|
112
|
+
csv.each { |row| assert row.header_row? }
|
113
|
+
|
114
|
+
#
|
115
|
+
# leading empty fields with multibyte col_sep raises MalformedCSVError
|
116
|
+
# (reported by Dave Burt)
|
117
|
+
#
|
118
|
+
data = <<-END_DATA.gsub(/^\s+/, "")
|
119
|
+
<=><=>A<=>B<=>C
|
120
|
+
1<=>2<=>3
|
121
|
+
END_DATA
|
122
|
+
parsed = FasterCSV.parse(data, :col_sep => "<=>")
|
123
|
+
assert_equal([[nil, nil, "A", "B", "C"], ["1", "2", "3"]], parsed)
|
96
124
|
end
|
97
125
|
|
98
126
|
def test_version
|
data/test/tc_headers.rb
CHANGED
@@ -27,19 +27,19 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# first data row - skipping headers
|
30
|
-
row = csv
|
30
|
+
row = csv[0]
|
31
31
|
assert_not_nil(row)
|
32
32
|
assert_instance_of(FasterCSV::Row, row)
|
33
33
|
assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
|
34
34
|
|
35
35
|
# second data row
|
36
|
-
row = csv
|
36
|
+
row = csv[1]
|
37
37
|
assert_not_nil(row)
|
38
38
|
assert_instance_of(FasterCSV::Row, row)
|
39
39
|
assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
|
40
40
|
|
41
41
|
# empty
|
42
|
-
assert_nil(csv
|
42
|
+
assert_nil(csv[2])
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -51,26 +51,26 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# first data row - skipping headers
|
54
|
-
row = csv
|
54
|
+
row = csv[0]
|
55
55
|
assert_not_nil(row)
|
56
56
|
assert_instance_of(FasterCSV::Row, row)
|
57
57
|
assert_equal( [[:my, "first"], [:new, "second"], [:headers, "third"]],
|
58
58
|
row.to_a )
|
59
59
|
|
60
60
|
# second data row
|
61
|
-
row = csv
|
61
|
+
row = csv[1]
|
62
62
|
assert_not_nil(row)
|
63
63
|
assert_instance_of(FasterCSV::Row, row)
|
64
64
|
assert_equal([[:my, "A"], [:new, "B"], [:headers, "C"]], row.to_a)
|
65
65
|
|
66
66
|
# third data row
|
67
|
-
row = csv
|
67
|
+
row = csv[2]
|
68
68
|
assert_not_nil(row)
|
69
69
|
assert_instance_of(FasterCSV::Row, row)
|
70
70
|
assert_equal([[:my, "1"], [:new, "2"], [:headers, "3"]], row.to_a)
|
71
71
|
|
72
72
|
# empty
|
73
|
-
assert_nil(csv
|
73
|
+
assert_nil(csv[3])
|
74
74
|
|
75
75
|
# with return and convert
|
76
76
|
assert_nothing_raised(Exception) do
|
@@ -78,7 +78,7 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
78
78
|
:return_headers => true,
|
79
79
|
:header_converters => lambda { |h| h.to_s } )
|
80
80
|
end
|
81
|
-
row = csv
|
81
|
+
row = csv[0]
|
82
82
|
assert_not_nil(row)
|
83
83
|
assert_instance_of(FasterCSV::Row, row)
|
84
84
|
assert_equal( [["my", :my], ["new", :new], ["headers", :headers]],
|
@@ -95,25 +95,25 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
95
95
|
end
|
96
96
|
|
97
97
|
# first data row - skipping headers
|
98
|
-
row = csv
|
98
|
+
row = csv[0]
|
99
99
|
assert_not_nil(row)
|
100
100
|
assert_instance_of(FasterCSV::Row, row)
|
101
101
|
assert_equal([%w{my first}, %w{new second}, %w{headers third}], row.to_a)
|
102
102
|
|
103
103
|
# second data row
|
104
|
-
row = csv
|
104
|
+
row = csv[1]
|
105
105
|
assert_not_nil(row)
|
106
106
|
assert_instance_of(FasterCSV::Row, row)
|
107
107
|
assert_equal([%w{my A}, %w{new B}, %w{headers C}], row.to_a)
|
108
108
|
|
109
109
|
# third data row
|
110
|
-
row = csv
|
110
|
+
row = csv[2]
|
111
111
|
assert_not_nil(row)
|
112
112
|
assert_instance_of(FasterCSV::Row, row)
|
113
113
|
assert_equal([%w{my 1}, %w{new 2}, %w{headers 3}], row.to_a)
|
114
114
|
|
115
115
|
# empty
|
116
|
-
assert_nil(csv
|
116
|
+
assert_nil(csv[3])
|
117
117
|
|
118
118
|
# with return and convert
|
119
119
|
assert_nothing_raised(Exception) do
|
@@ -121,7 +121,7 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
121
121
|
:return_headers => true,
|
122
122
|
:header_converters => :symbol )
|
123
123
|
end
|
124
|
-
row = csv
|
124
|
+
row = csv[0]
|
125
125
|
assert_not_nil(row)
|
126
126
|
assert_instance_of(FasterCSV::Row, row)
|
127
127
|
assert_equal( [[:my, "my"], [:new, "new"], [:headers, "headers"]],
|
@@ -138,7 +138,7 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
138
138
|
end
|
139
139
|
|
140
140
|
# header row
|
141
|
-
row = csv
|
141
|
+
row = csv[0]
|
142
142
|
assert_not_nil(row)
|
143
143
|
assert_instance_of(FasterCSV::Row, row)
|
144
144
|
assert_equal( [%w{first first}, %w{second second}, %w{third third}],
|
@@ -147,7 +147,7 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
147
147
|
assert(!row.field_row?)
|
148
148
|
|
149
149
|
# first data row - skipping headers
|
150
|
-
row = csv
|
150
|
+
row = csv[1]
|
151
151
|
assert_not_nil(row)
|
152
152
|
assert_instance_of(FasterCSV::Row, row)
|
153
153
|
assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
|
@@ -155,7 +155,7 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
155
155
|
assert(row.field_row?)
|
156
156
|
|
157
157
|
# second data row
|
158
|
-
row = csv
|
158
|
+
row = csv[2]
|
159
159
|
assert_not_nil(row)
|
160
160
|
assert_instance_of(FasterCSV::Row, row)
|
161
161
|
assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
|
@@ -163,7 +163,7 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
163
163
|
assert(row.field_row?)
|
164
164
|
|
165
165
|
# empty
|
166
|
-
assert_nil(csv
|
166
|
+
assert_nil(csv[3])
|
167
167
|
end
|
168
168
|
|
169
169
|
def test_converters
|
@@ -177,9 +177,9 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
177
177
|
csv = FasterCSV.parse( data, :headers => true,
|
178
178
|
:return_headers => true,
|
179
179
|
:converters => :numeric )
|
180
|
-
assert_equal([%w{1 1}, %w{2 2}, %w{3 3}], csv.
|
181
|
-
assert_equal([["1", 1], ["2", 2], ["3", 3]], csv.
|
182
|
-
assert_nil(csv
|
180
|
+
assert_equal([%w{1 1}, %w{2 2}, %w{3 3}], csv[0].to_a)
|
181
|
+
assert_equal([["1", 1], ["2", 2], ["3", 3]], csv[1].to_a)
|
182
|
+
assert_nil(csv[2])
|
183
183
|
|
184
184
|
# header converters do affect headers (only)
|
185
185
|
assert_nothing_raised(Exception) do
|
@@ -188,23 +188,23 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
188
188
|
:converters => :numeric,
|
189
189
|
:header_converters => :symbol )
|
190
190
|
end
|
191
|
-
assert_equal([[:"1", "1"], [:"2", "2"], [:"3", "3"]], csv.
|
192
|
-
assert_equal([[:"1", 1], [:"2", 2], [:"3", 3]], csv.
|
193
|
-
assert_nil(csv
|
191
|
+
assert_equal([[:"1", "1"], [:"2", "2"], [:"3", "3"]], csv[0].to_a)
|
192
|
+
assert_equal([[:"1", 1], [:"2", 2], [:"3", 3]], csv[1].to_a)
|
193
|
+
assert_nil(csv[2])
|
194
194
|
end
|
195
195
|
|
196
196
|
def test_builtin_downcase_converter
|
197
197
|
csv = FasterCSV.parse( "One,TWO Three", :headers => true,
|
198
198
|
:return_headers => true,
|
199
199
|
:header_converters => :downcase )
|
200
|
-
assert_equal(%w{one two\ three}, csv.
|
200
|
+
assert_equal(%w{one two\ three}, csv.headers)
|
201
201
|
end
|
202
202
|
|
203
203
|
def test_builtin_symbol_converter
|
204
204
|
csv = FasterCSV.parse( "One,TWO Three", :headers => true,
|
205
205
|
:return_headers => true,
|
206
206
|
:header_converters => :symbol )
|
207
|
-
assert_equal([:one, :two_three], csv.
|
207
|
+
assert_equal([:one, :two_three], csv.headers)
|
208
208
|
end
|
209
209
|
|
210
210
|
def test_custom_converter
|
@@ -213,6 +213,15 @@ class TestFasterCSVHeaders < Test::Unit::TestCase
|
|
213
213
|
:headers => true,
|
214
214
|
:return_headers => true,
|
215
215
|
:header_converters => converter )
|
216
|
-
assert_equal(%w{One TWO_Three}, csv.
|
216
|
+
assert_equal(%w{One TWO_Three}, csv.headers)
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_table_support
|
220
|
+
csv = nil
|
221
|
+
assert_nothing_raised(Exception) do
|
222
|
+
csv = FasterCSV.parse(@data, :headers => true)
|
223
|
+
end
|
224
|
+
|
225
|
+
assert_instance_of(FasterCSV::Table, csv)
|
217
226
|
end
|
218
227
|
end
|
data/test/tc_row.rb
CHANGED
data/test/tc_table.rb
ADDED
@@ -0,0 +1,385 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# tc_table.rb
|
4
|
+
#
|
5
|
+
# Created by James Edward Gray II on 2006-02-24.
|
6
|
+
# Copyright 2006 Gray Productions. All rights reserved.
|
7
|
+
|
8
|
+
require "test/unit"
|
9
|
+
|
10
|
+
require "faster_csv"
|
11
|
+
|
12
|
+
class TestFasterCSVTable < Test::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
@rows = [ FasterCSV::Row.new(%w{A B C}, [1, 2, 3]),
|
15
|
+
FasterCSV::Row.new(%w{A B C}, [4, 5, 6]),
|
16
|
+
FasterCSV::Row.new(%w{A B C}, [7, 8, 9]) ]
|
17
|
+
@table = FasterCSV::Table.new(@rows)
|
18
|
+
|
19
|
+
@header_table = FasterCSV::Table.new(
|
20
|
+
[FasterCSV::Row.new(%w{A B C}, %w{A B C}, true)] + @rows
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_initialze
|
25
|
+
assert_not_nil(@table)
|
26
|
+
assert_instance_of(FasterCSV::Table, @table)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_modes
|
30
|
+
assert_equal(:col_or_row, @table.mode)
|
31
|
+
|
32
|
+
# non-destructive changes, intended for one shot calls
|
33
|
+
cols = @table.by_col
|
34
|
+
assert_equal(:col_or_row, @table.mode)
|
35
|
+
assert_equal(:col, cols.mode)
|
36
|
+
assert_equal(@table, cols)
|
37
|
+
|
38
|
+
rows = @table.by_row
|
39
|
+
assert_equal(:col_or_row, @table.mode)
|
40
|
+
assert_equal(:row, rows.mode)
|
41
|
+
assert_equal(@table, rows)
|
42
|
+
|
43
|
+
# destructive mode changing calls
|
44
|
+
assert_equal(@table, @table.by_row!)
|
45
|
+
assert_equal(:row, @table.mode)
|
46
|
+
assert_equal(@table, @table.by_col_or_row!)
|
47
|
+
assert_equal(:col_or_row, @table.mode)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_headers
|
51
|
+
assert_equal(@rows.first.headers, @table.headers)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_index
|
55
|
+
##################
|
56
|
+
### Mixed Mode ###
|
57
|
+
##################
|
58
|
+
# by row
|
59
|
+
@rows.each_index { |i| assert_equal(@rows[i], @table[i]) }
|
60
|
+
assert_equal(nil, @table[100]) # empty row
|
61
|
+
|
62
|
+
# by col
|
63
|
+
@rows.first.headers.each do |header|
|
64
|
+
assert_equal(@rows.map { |row| row[header] }, @table[header])
|
65
|
+
end
|
66
|
+
assert_equal([nil] * @rows.size, @table["Z"]) # empty col
|
67
|
+
|
68
|
+
# by cell, row then col
|
69
|
+
assert_equal(2, @table[0][1])
|
70
|
+
assert_equal(6, @table[1]["C"])
|
71
|
+
|
72
|
+
# by cell, col then row
|
73
|
+
assert_equal(5, @table["B"][1])
|
74
|
+
assert_equal(9, @table["C"][2])
|
75
|
+
|
76
|
+
# with headers (by col)
|
77
|
+
assert_equal(["B", 2, 5, 8], @header_table["B"])
|
78
|
+
|
79
|
+
###################
|
80
|
+
### Column Mode ###
|
81
|
+
###################
|
82
|
+
@table.by_col!
|
83
|
+
|
84
|
+
assert_equal([2, 5, 8], @table[1])
|
85
|
+
assert_equal([2, 5, 8], @table["B"])
|
86
|
+
|
87
|
+
################
|
88
|
+
### Row Mode ###
|
89
|
+
################
|
90
|
+
@table.by_row!
|
91
|
+
|
92
|
+
assert_equal(@rows[1], @table[1])
|
93
|
+
assert_raise(TypeError) { @table["B"] }
|
94
|
+
|
95
|
+
############################
|
96
|
+
### One Shot Mode Change ###
|
97
|
+
############################
|
98
|
+
assert_equal(@rows[1], @table[1])
|
99
|
+
assert_equal([2, 5, 8], @table.by_col[1])
|
100
|
+
assert_equal(@rows[1], @table[1])
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_set_row_or_column
|
104
|
+
##################
|
105
|
+
### Mixed Mode ###
|
106
|
+
##################
|
107
|
+
# set row
|
108
|
+
@table[2] = [10, 11, 12]
|
109
|
+
assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12]], @table.to_a)
|
110
|
+
|
111
|
+
@table[3] = FasterCSV::Row.new(%w[A B C], [13, 14, 15])
|
112
|
+
assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12], [13, 14, 15]],
|
113
|
+
@table.to_a )
|
114
|
+
|
115
|
+
# set col
|
116
|
+
@table["Type"] = "data"
|
117
|
+
assert_equal( [ %w[A B C Type],
|
118
|
+
[1, 2, 3, "data"],
|
119
|
+
[4, 5, 6, "data"],
|
120
|
+
[10, 11, 12, "data"],
|
121
|
+
[13, 14, 15, "data"] ],
|
122
|
+
@table.to_a )
|
123
|
+
|
124
|
+
@table["Index"] = [1, 2, 3]
|
125
|
+
assert_equal( [ %w[A B C Type Index],
|
126
|
+
[1, 2, 3, "data", 1],
|
127
|
+
[4, 5, 6, "data", 2],
|
128
|
+
[10, 11, 12, "data", 3],
|
129
|
+
[13, 14, 15, "data", nil] ],
|
130
|
+
@table.to_a )
|
131
|
+
|
132
|
+
@table["B"] = [100, 200]
|
133
|
+
assert_equal( [ %w[A B C Type Index],
|
134
|
+
[1, 100, 3, "data", 1],
|
135
|
+
[4, 200, 6, "data", 2],
|
136
|
+
[10, nil, 12, "data", 3],
|
137
|
+
[13, nil, 15, "data", nil] ],
|
138
|
+
@table.to_a )
|
139
|
+
|
140
|
+
# verify resulting table
|
141
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
142
|
+
A,B,C,Type,Index
|
143
|
+
1,100,3,data,1
|
144
|
+
4,200,6,data,2
|
145
|
+
10,,12,data,3
|
146
|
+
13,,15,data,
|
147
|
+
END_RESULT
|
148
|
+
|
149
|
+
# with headers
|
150
|
+
@header_table["Type"] = "data"
|
151
|
+
assert_equal(%w[Type data data data], @header_table["Type"])
|
152
|
+
|
153
|
+
###################
|
154
|
+
### Column Mode ###
|
155
|
+
###################
|
156
|
+
@table.by_col!
|
157
|
+
|
158
|
+
@table[1] = [2, 5, 11, 14]
|
159
|
+
assert_equal( [ %w[A B C Type Index],
|
160
|
+
[1, 2, 3, "data", 1],
|
161
|
+
[4, 5, 6, "data", 2],
|
162
|
+
[10, 11, 12, "data", 3],
|
163
|
+
[13, 14, 15, "data", nil] ],
|
164
|
+
@table.to_a )
|
165
|
+
|
166
|
+
@table["Extra"] = "new stuff"
|
167
|
+
assert_equal( [ %w[A B C Type Index Extra],
|
168
|
+
[1, 2, 3, "data", 1, "new stuff"],
|
169
|
+
[4, 5, 6, "data", 2, "new stuff"],
|
170
|
+
[10, 11, 12, "data", 3, "new stuff"],
|
171
|
+
[13, 14, 15, "data", nil, "new stuff"] ],
|
172
|
+
@table.to_a )
|
173
|
+
|
174
|
+
################
|
175
|
+
### Row Mode ###
|
176
|
+
################
|
177
|
+
@table.by_row!
|
178
|
+
|
179
|
+
@table[1] = (1..6).to_a
|
180
|
+
assert_equal( [ %w[A B C Type Index Extra],
|
181
|
+
[1, 2, 3, "data", 1, "new stuff"],
|
182
|
+
[1, 2, 3, 4, 5, 6],
|
183
|
+
[10, 11, 12, "data", 3, "new stuff"],
|
184
|
+
[13, 14, 15, "data", nil, "new stuff"] ],
|
185
|
+
@table.to_a )
|
186
|
+
|
187
|
+
assert_raise(TypeError) { @table["Extra"] = nil }
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_each
|
191
|
+
######################
|
192
|
+
### Mixed/Row Mode ###
|
193
|
+
######################
|
194
|
+
i = 0
|
195
|
+
@table.each do |row|
|
196
|
+
assert_equal(@rows[i], row)
|
197
|
+
i += 1
|
198
|
+
end
|
199
|
+
|
200
|
+
# verify that we can chain the call
|
201
|
+
assert_equal(@table, @table.each { })
|
202
|
+
|
203
|
+
###################
|
204
|
+
### Column Mode ###
|
205
|
+
###################
|
206
|
+
@table.by_col!
|
207
|
+
|
208
|
+
headers = @table.headers
|
209
|
+
@table.each do |header, column|
|
210
|
+
assert_equal(headers.shift, header)
|
211
|
+
assert_equal(@table[header], column)
|
212
|
+
end
|
213
|
+
|
214
|
+
############################
|
215
|
+
### One Shot Mode Change ###
|
216
|
+
############################
|
217
|
+
@table.by_col_or_row!
|
218
|
+
|
219
|
+
@table.each { |row| assert_instance_of(FasterCSV::Row, row) }
|
220
|
+
@table.by_col.each { |tuple| assert_instance_of(Array, tuple) }
|
221
|
+
@table.each { |row| assert_instance_of(FasterCSV::Row, row) }
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_enumerable
|
225
|
+
assert_equal( @rows.values_at(0, 2),
|
226
|
+
@table.select { |row| (row["B"] % 2).zero? } )
|
227
|
+
|
228
|
+
assert_equal(@rows[1], @table.find { |row| row["C"] > 5 })
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_to_a
|
232
|
+
assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]], @table.to_a)
|
233
|
+
|
234
|
+
# with headers
|
235
|
+
assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]],
|
236
|
+
@header_table.to_a )
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_to_csv
|
240
|
+
csv = <<-END_CSV.gsub(/^\s+/, "")
|
241
|
+
A,B,C
|
242
|
+
1,2,3
|
243
|
+
4,5,6
|
244
|
+
7,8,9
|
245
|
+
END_CSV
|
246
|
+
|
247
|
+
# normal conversion
|
248
|
+
assert_equal(csv, @table.to_csv)
|
249
|
+
assert_equal(csv, @table.to_s) # alias
|
250
|
+
|
251
|
+
# with options
|
252
|
+
assert_equal( csv.gsub(",", "|").gsub("\n", "\r\n"),
|
253
|
+
@table.to_csv(:col_sep => "|", :row_sep => "\r\n") )
|
254
|
+
|
255
|
+
# with headers
|
256
|
+
assert_equal(csv, @header_table.to_csv)
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_append
|
260
|
+
# verify that we can chain the call
|
261
|
+
assert_equal(@table, @table << [10, 11, 12])
|
262
|
+
|
263
|
+
# Array append
|
264
|
+
assert_equal(FasterCSV::Row.new(%w[A B C], [10, 11, 12]), @table[-1])
|
265
|
+
|
266
|
+
# Row append
|
267
|
+
assert_equal(@table, @table << FasterCSV::Row.new(%w[A B C], [13, 14, 15]))
|
268
|
+
assert_equal(FasterCSV::Row.new(%w[A B C], [13, 14, 15]), @table[-1])
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_delete
|
272
|
+
##################
|
273
|
+
### Mixed Mode ###
|
274
|
+
##################
|
275
|
+
# delete a row
|
276
|
+
assert_equal(@rows[1], @table.delete(1))
|
277
|
+
|
278
|
+
# delete a col
|
279
|
+
assert_equal(@rows.map { |row| row["A"] }, @table.delete("A"))
|
280
|
+
|
281
|
+
# verify resulting table
|
282
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
283
|
+
B,C
|
284
|
+
2,3
|
285
|
+
8,9
|
286
|
+
END_RESULT
|
287
|
+
|
288
|
+
###################
|
289
|
+
### Column Mode ###
|
290
|
+
###################
|
291
|
+
setup
|
292
|
+
@table.by_col!
|
293
|
+
|
294
|
+
assert_equal(@rows.map { |row| row[0] }, @table.delete(0))
|
295
|
+
assert_equal(@rows.map { |row| row["C"] }, @table.delete("C"))
|
296
|
+
|
297
|
+
# verify resulting table
|
298
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
299
|
+
B
|
300
|
+
2
|
301
|
+
5
|
302
|
+
8
|
303
|
+
END_RESULT
|
304
|
+
|
305
|
+
################
|
306
|
+
### Row Mode ###
|
307
|
+
################
|
308
|
+
setup
|
309
|
+
@table.by_row!
|
310
|
+
|
311
|
+
assert_equal(@rows[1], @table.delete(1))
|
312
|
+
assert_raise(TypeError) { @table.delete("C") }
|
313
|
+
|
314
|
+
# verify resulting table
|
315
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
316
|
+
A,B,C
|
317
|
+
1,2,3
|
318
|
+
7,8,9
|
319
|
+
END_RESULT
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_delete_if
|
323
|
+
######################
|
324
|
+
### Mixed/Row Mode ###
|
325
|
+
######################
|
326
|
+
# verify that we can chain the call
|
327
|
+
assert_equal(@table, @table.delete_if { |row| (row["B"] % 2).zero? })
|
328
|
+
|
329
|
+
# verify resulting table
|
330
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
331
|
+
A,B,C
|
332
|
+
4,5,6
|
333
|
+
END_RESULT
|
334
|
+
|
335
|
+
###################
|
336
|
+
### Column Mode ###
|
337
|
+
###################
|
338
|
+
setup
|
339
|
+
@table.by_col!
|
340
|
+
|
341
|
+
assert_equal(@table, @table.delete_if { |h, v| h > "A" })
|
342
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
343
|
+
A
|
344
|
+
1
|
345
|
+
4
|
346
|
+
7
|
347
|
+
END_RESULT
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_values_at
|
351
|
+
##################
|
352
|
+
### Mixed Mode ###
|
353
|
+
##################
|
354
|
+
# rows
|
355
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
356
|
+
assert_equal(@rows.values_at(1..2), @table.values_at(1..2))
|
357
|
+
|
358
|
+
# cols
|
359
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
|
360
|
+
assert_equal([[2, 3], [5, 6], [8, 9]], @table.values_at("B".."C"))
|
361
|
+
|
362
|
+
###################
|
363
|
+
### Column Mode ###
|
364
|
+
###################
|
365
|
+
@table.by_col!
|
366
|
+
|
367
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at(0, 2))
|
368
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
|
369
|
+
|
370
|
+
################
|
371
|
+
### Row Mode ###
|
372
|
+
################
|
373
|
+
@table.by_row!
|
374
|
+
|
375
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
376
|
+
assert_raise(TypeError) { @table.values_at("A", "C") }
|
377
|
+
|
378
|
+
############################
|
379
|
+
### One Shot Mode Change ###
|
380
|
+
############################
|
381
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
382
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.by_col.values_at(0, 2))
|
383
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
384
|
+
end
|
385
|
+
end
|