rw_fastercsv 1.5.6
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/CHANGELOG +177 -0
- data/COPYING +340 -0
- data/INSTALL +41 -0
- data/LICENSE +7 -0
- data/README +71 -0
- data/Rakefile +93 -0
- data/TODO +6 -0
- data/examples/csv_converters.rb +28 -0
- data/examples/csv_filter.rb +23 -0
- data/examples/csv_rails_import.task +21 -0
- data/examples/csv_reading.rb +57 -0
- data/examples/csv_table.rb +56 -0
- data/examples/csv_writing.rb +67 -0
- data/examples/purchase.csv +3 -0
- data/examples/shortcut_interface.rb +36 -0
- data/lib/faster_csv.rb +2006 -0
- data/lib/fastercsv.rb +10 -0
- data/setup.rb +1360 -0
- data/test/export.csv +5 -0
- data/test/line_endings.gz +0 -0
- data/test/tc_csv_parsing.rb +194 -0
- data/test/tc_csv_writing.rb +96 -0
- data/test/tc_data_converters.rb +260 -0
- data/test/tc_encodings.rb +23 -0
- data/test/tc_features.rb +212 -0
- data/test/tc_headers.rb +277 -0
- data/test/tc_interface.rb +376 -0
- data/test/tc_row.rb +305 -0
- data/test/tc_rp_cases.rb +45 -0
- data/test/tc_serialization.rb +154 -0
- data/test/tc_speed.rb +65 -0
- data/test/tc_table.rb +408 -0
- data/test/test_data.csv +1000 -0
- data/test/ts_all.rb +21 -0
- metadata +97 -0
data/test/tc_rp_cases.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# tc_interface.rb
|
4
|
+
#
|
5
|
+
# Created by James Edward Gray II on 2005-11-14.
|
6
|
+
# Copyright 2005 Gray Productions. All rights reserved.
|
7
|
+
|
8
|
+
require "test/unit"
|
9
|
+
|
10
|
+
require "faster_csv"
|
11
|
+
|
12
|
+
class TestFasterCSVRPCases < Test::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
@path = File.join(File.dirname(__FILE__), "export.csv")
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
# File.unlink(@path)
|
19
|
+
end
|
20
|
+
|
21
|
+
#RPBS-2760
|
22
|
+
def test_failed_export
|
23
|
+
lines = []
|
24
|
+
csv = FasterCSV.open(@path, :raise_exception => true)
|
25
|
+
assert_raise(FasterCSV::MalformedCSVError) do
|
26
|
+
while line = csv.gets
|
27
|
+
lines<<line
|
28
|
+
end
|
29
|
+
end
|
30
|
+
assert_equal(4,lines.size)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_success_export
|
34
|
+
lines = []
|
35
|
+
csv = FasterCSV.open(@path, :raise_exception => false)
|
36
|
+
assert_nothing_raised do
|
37
|
+
while line = csv.gets
|
38
|
+
lines<<line
|
39
|
+
end
|
40
|
+
end
|
41
|
+
assert_equal(5,lines.size)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# tc_serialization.rb
|
4
|
+
#
|
5
|
+
# Created by James Edward Gray II on 2006-03-28.
|
6
|
+
# Copyright 2006 Gray Productions. All rights reserved.
|
7
|
+
|
8
|
+
require "test/unit"
|
9
|
+
|
10
|
+
require "faster_csv"
|
11
|
+
|
12
|
+
# An example of how to provide custom CSV serialization.
|
13
|
+
class Hash
|
14
|
+
def self.csv_load( meta, headers, fields )
|
15
|
+
self[*headers.zip(fields).flatten.map { |e| eval(e) }]
|
16
|
+
end
|
17
|
+
|
18
|
+
def csv_headers
|
19
|
+
keys.map { |key| key.inspect }
|
20
|
+
end
|
21
|
+
|
22
|
+
def csv_dump( headers )
|
23
|
+
headers.map { |header| fetch(eval(header)).inspect }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class TestSerialization < Test::Unit::TestCase
|
28
|
+
|
29
|
+
### Classes Used to Test Serialization ###
|
30
|
+
|
31
|
+
class ReadOnlyName
|
32
|
+
def initialize( first, last )
|
33
|
+
@first, @last = first, last
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :first, :last
|
37
|
+
|
38
|
+
def ==( other )
|
39
|
+
%w{first last}.all? { |att| send(att) == other.send(att) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Name = Struct.new(:first, :last)
|
44
|
+
|
45
|
+
class FullName < Name
|
46
|
+
def initialize( first, last, suffix = nil )
|
47
|
+
super(first, last)
|
48
|
+
|
49
|
+
@suffix = suffix
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_accessor :suffix
|
53
|
+
|
54
|
+
def ==( other )
|
55
|
+
%w{first last suffix}.all? { |att| send(att) == other.send(att) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
### Tests ###
|
60
|
+
|
61
|
+
def test_class_dump
|
62
|
+
@names = [ %w{James Gray},
|
63
|
+
%w{Dana Gray},
|
64
|
+
%w{Greg Brown} ].map do |first, last|
|
65
|
+
ReadOnlyName.new(first, last)
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_nothing_raised(Exception) do
|
69
|
+
@data = FasterCSV.dump(@names)
|
70
|
+
end
|
71
|
+
assert_equal(<<-END_CLASS_DUMP.gsub(/^\s*/, ""), @data)
|
72
|
+
class,TestSerialization::ReadOnlyName
|
73
|
+
@first,@last
|
74
|
+
James,Gray
|
75
|
+
Dana,Gray
|
76
|
+
Greg,Brown
|
77
|
+
END_CLASS_DUMP
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_struct_dump
|
81
|
+
@names = [ %w{James Gray},
|
82
|
+
%w{Dana Gray},
|
83
|
+
%w{Greg Brown} ].map do |first, last|
|
84
|
+
Name.new(first, last)
|
85
|
+
end
|
86
|
+
|
87
|
+
assert_nothing_raised(Exception) do
|
88
|
+
@data = FasterCSV.dump(@names)
|
89
|
+
end
|
90
|
+
assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
|
91
|
+
class,TestSerialization::Name
|
92
|
+
first=,last=
|
93
|
+
James,Gray
|
94
|
+
Dana,Gray
|
95
|
+
Greg,Brown
|
96
|
+
END_STRUCT_DUMP
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_inherited_struct_dump
|
100
|
+
@names = [ %w{James Gray II},
|
101
|
+
%w{Dana Gray},
|
102
|
+
%w{Greg Brown} ].map do |first, last, suffix|
|
103
|
+
FullName.new(first, last, suffix)
|
104
|
+
end
|
105
|
+
|
106
|
+
assert_nothing_raised(Exception) do
|
107
|
+
@data = FasterCSV.dump(@names)
|
108
|
+
end
|
109
|
+
assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
|
110
|
+
class,TestSerialization::FullName
|
111
|
+
@suffix,first=,last=
|
112
|
+
II,James,Gray
|
113
|
+
,Dana,Gray
|
114
|
+
,Greg,Brown
|
115
|
+
END_STRUCT_DUMP
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_load
|
119
|
+
%w{ test_class_dump
|
120
|
+
test_struct_dump
|
121
|
+
test_inherited_struct_dump }.each do |test|
|
122
|
+
send(test)
|
123
|
+
FasterCSV.load(@data).each do |loaded|
|
124
|
+
assert_instance_of(@names.first.class, loaded)
|
125
|
+
assert_equal(@names.shift, loaded)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_io
|
131
|
+
test_class_dump
|
132
|
+
|
133
|
+
data_file = File.join(File.dirname(__FILE__), "temp_test_data.csv")
|
134
|
+
FasterCSV.dump(@names, File.open(data_file, "w"))
|
135
|
+
|
136
|
+
assert(File.exist?(data_file))
|
137
|
+
assert_equal(<<-END_IO_DUMP.gsub(/^\s*/, ""), File.read(data_file))
|
138
|
+
class,TestSerialization::ReadOnlyName
|
139
|
+
@first,@last
|
140
|
+
James,Gray
|
141
|
+
Dana,Gray
|
142
|
+
Greg,Brown
|
143
|
+
END_IO_DUMP
|
144
|
+
|
145
|
+
assert_equal(@names, FasterCSV.load(File.open(data_file)))
|
146
|
+
|
147
|
+
File.unlink(data_file)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_custom_dump_and_load
|
151
|
+
obj = {1 => "simple", :test => Hash}
|
152
|
+
assert_equal(obj, FasterCSV.load(FasterCSV.dump([obj])).first)
|
153
|
+
end
|
154
|
+
end
|
data/test/tc_speed.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# tc_speed.rb
|
4
|
+
#
|
5
|
+
# Created by James Edward Gray II on 2005-11-14.
|
6
|
+
# Copyright 2005 Gray Productions. All rights reserved.
|
7
|
+
|
8
|
+
require "test/unit"
|
9
|
+
require "timeout"
|
10
|
+
|
11
|
+
require "faster_csv"
|
12
|
+
require "csv"
|
13
|
+
|
14
|
+
class TestFasterCSVSpeed < Test::Unit::TestCase
|
15
|
+
PATH = File.join(File.dirname(__FILE__), "test_data.csv")
|
16
|
+
BIG_DATA = "123456789\n" * 1024
|
17
|
+
|
18
|
+
def test_that_we_are_doing_the_same_work
|
19
|
+
FasterCSV.open(PATH) do |csv|
|
20
|
+
CSV.foreach(PATH) do |row|
|
21
|
+
assert_equal(row, csv.shift)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_speed_vs_csv
|
27
|
+
csv_time = Time.now
|
28
|
+
CSV.foreach(PATH) do |row|
|
29
|
+
# do nothing, we're just timing a read...
|
30
|
+
end
|
31
|
+
csv_time = Time.now - csv_time
|
32
|
+
|
33
|
+
faster_csv_time = Time.now
|
34
|
+
FasterCSV.foreach(PATH) do |row|
|
35
|
+
# do nothing, we're just timing a read...
|
36
|
+
end
|
37
|
+
faster_csv_time = Time.now - faster_csv_time
|
38
|
+
|
39
|
+
assert(faster_csv_time < csv_time / 3)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_the_parse_fails_fast_when_it_can_for_unquoted_fields
|
43
|
+
assert_parse_errors_out('valid,fields,bad start"' + BIG_DATA)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_the_parse_fails_fast_when_it_can_for_unescaped_quotes
|
47
|
+
assert_parse_errors_out('valid,fields,"bad start"unescaped' + BIG_DATA)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_field_size_limit_controls_lookahead
|
51
|
+
assert_parse_errors_out( 'valid,fields,"' + BIG_DATA + '"',
|
52
|
+
:field_size_limit => 2048 )
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def assert_parse_errors_out(*args)
|
58
|
+
assert_raise(FasterCSV::MalformedCSVError) do
|
59
|
+
Timeout.timeout(0.2) do
|
60
|
+
FasterCSV.parse(*args)
|
61
|
+
fail("Parse didn't error out")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/test/tc_table.rb
ADDED
@@ -0,0 +1,408 @@
|
|
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
|
+
assert_equal( csv.to_a[1..-1].join,
|
255
|
+
@table.to_csv(:write_headers => false) )
|
256
|
+
|
257
|
+
# with headers
|
258
|
+
assert_equal(csv, @header_table.to_csv)
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_append
|
262
|
+
# verify that we can chain the call
|
263
|
+
assert_equal(@table, @table << [10, 11, 12])
|
264
|
+
|
265
|
+
# Array append
|
266
|
+
assert_equal(FasterCSV::Row.new(%w[A B C], [10, 11, 12]), @table[-1])
|
267
|
+
|
268
|
+
# Row append
|
269
|
+
assert_equal(@table, @table << FasterCSV::Row.new(%w[A B C], [13, 14, 15]))
|
270
|
+
assert_equal(FasterCSV::Row.new(%w[A B C], [13, 14, 15]), @table[-1])
|
271
|
+
end
|
272
|
+
|
273
|
+
def test_delete
|
274
|
+
##################
|
275
|
+
### Mixed Mode ###
|
276
|
+
##################
|
277
|
+
# delete a row
|
278
|
+
assert_equal(@rows[1], @table.delete(1))
|
279
|
+
|
280
|
+
# delete a col
|
281
|
+
assert_equal(@rows.map { |row| row["A"] }, @table.delete("A"))
|
282
|
+
|
283
|
+
# verify resulting table
|
284
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
285
|
+
B,C
|
286
|
+
2,3
|
287
|
+
8,9
|
288
|
+
END_RESULT
|
289
|
+
|
290
|
+
###################
|
291
|
+
### Column Mode ###
|
292
|
+
###################
|
293
|
+
setup
|
294
|
+
@table.by_col!
|
295
|
+
|
296
|
+
assert_equal(@rows.map { |row| row[0] }, @table.delete(0))
|
297
|
+
assert_equal(@rows.map { |row| row["C"] }, @table.delete("C"))
|
298
|
+
|
299
|
+
# verify resulting table
|
300
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
301
|
+
B
|
302
|
+
2
|
303
|
+
5
|
304
|
+
8
|
305
|
+
END_RESULT
|
306
|
+
|
307
|
+
################
|
308
|
+
### Row Mode ###
|
309
|
+
################
|
310
|
+
setup
|
311
|
+
@table.by_row!
|
312
|
+
|
313
|
+
assert_equal(@rows[1], @table.delete(1))
|
314
|
+
assert_raise(TypeError) { @table.delete("C") }
|
315
|
+
|
316
|
+
# verify resulting table
|
317
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
318
|
+
A,B,C
|
319
|
+
1,2,3
|
320
|
+
7,8,9
|
321
|
+
END_RESULT
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_delete_with_blank_rows
|
325
|
+
data = "col1,col2\nra1,ra2\n\nrb1,rb2"
|
326
|
+
table = FasterCSV.parse(data, :headers => true)
|
327
|
+
assert_equal(["ra2", nil, "rb2"], table.delete("col2"))
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_delete_if
|
331
|
+
######################
|
332
|
+
### Mixed/Row Mode ###
|
333
|
+
######################
|
334
|
+
# verify that we can chain the call
|
335
|
+
assert_equal(@table, @table.delete_if { |row| (row["B"] % 2).zero? })
|
336
|
+
|
337
|
+
# verify resulting table
|
338
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
339
|
+
A,B,C
|
340
|
+
4,5,6
|
341
|
+
END_RESULT
|
342
|
+
|
343
|
+
###################
|
344
|
+
### Column Mode ###
|
345
|
+
###################
|
346
|
+
setup
|
347
|
+
@table.by_col!
|
348
|
+
|
349
|
+
assert_equal(@table, @table.delete_if { |h, v| h > "A" })
|
350
|
+
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
|
351
|
+
A
|
352
|
+
1
|
353
|
+
4
|
354
|
+
7
|
355
|
+
END_RESULT
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_values_at
|
359
|
+
##################
|
360
|
+
### Mixed Mode ###
|
361
|
+
##################
|
362
|
+
# rows
|
363
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
364
|
+
assert_equal(@rows.values_at(1..2), @table.values_at(1..2))
|
365
|
+
|
366
|
+
# cols
|
367
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
|
368
|
+
assert_equal([[2, 3], [5, 6], [8, 9]], @table.values_at("B".."C"))
|
369
|
+
|
370
|
+
###################
|
371
|
+
### Column Mode ###
|
372
|
+
###################
|
373
|
+
@table.by_col!
|
374
|
+
|
375
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at(0, 2))
|
376
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
|
377
|
+
|
378
|
+
################
|
379
|
+
### Row Mode ###
|
380
|
+
################
|
381
|
+
@table.by_row!
|
382
|
+
|
383
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
384
|
+
assert_raise(TypeError) { @table.values_at("A", "C") }
|
385
|
+
|
386
|
+
############################
|
387
|
+
### One Shot Mode Change ###
|
388
|
+
############################
|
389
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
390
|
+
assert_equal([[1, 3], [4, 6], [7, 9]], @table.by_col.values_at(0, 2))
|
391
|
+
assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
|
392
|
+
end
|
393
|
+
|
394
|
+
def test_array_delegation
|
395
|
+
assert(!@table.empty?, "Table was empty.")
|
396
|
+
|
397
|
+
assert_equal(@rows.size, @table.size)
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_inspect_shows_current_mode
|
401
|
+
str = @table.inspect
|
402
|
+
assert(str.include?("mode:#{@table.mode}"), "Mode not shown.")
|
403
|
+
|
404
|
+
@table.by_col!
|
405
|
+
str = @table.inspect
|
406
|
+
assert(str.include?("mode:#{@table.mode}"), "Mode not shown.")
|
407
|
+
end
|
408
|
+
end
|