fastercsv 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,121 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_csv_parsing.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-10-31.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ #
13
+ # Following tests are my interpretation of the
14
+ # {CSV RCF}[http://www.ietf.org/rfc/rfc4180.txt]. I only deviate from that
15
+ # document in one place (intentionally) and that is to make the default row
16
+ # separator <tt>$/</tt>.
17
+ #
18
+ class TestCSVParsing < Test::Unit::TestCase
19
+ def test_mastering_regex_example
20
+ ex = %Q{Ten Thousand,10000, 2710 ,,"10,000","It's ""10 Grand"", baby",10K}
21
+ assert_equal( [ "Ten Thousand", "10000", " 2710 ", nil, "10,000",
22
+ "It's \"10 Grand\", baby", "10K" ],
23
+ FasterCSV.parse_line(ex) )
24
+ end
25
+
26
+ # Pulled from: http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/test/csv/test_csv.rb?rev=1.12.2.2;content-type=text%2Fplain
27
+ def test_std_lib_csv
28
+ [ ["\t", ["\t"]],
29
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
30
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
31
+ ["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
32
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
33
+ ["\"\"", [""]],
34
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
35
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
36
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
37
+ ["foo,\"\",baz", ["foo", "", "baz"]],
38
+ ["\",\"", [","]],
39
+ ["foo", ["foo"]],
40
+ [",,", [nil, nil, nil]],
41
+ [",", [nil, nil]],
42
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
43
+ ["foo,,baz", ["foo", nil, "baz"]],
44
+ ["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
45
+ ["\",\",\",\"", [",", ","]],
46
+ ["foo,bar,", ["foo", "bar", nil]],
47
+ [",foo,bar", [nil, "foo", "bar"]],
48
+ ["foo,bar", ["foo", "bar"]],
49
+ [";", [";"]],
50
+ ["\t,\t", ["\t", "\t"]],
51
+ ["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
52
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
53
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
54
+ [";,;", [";", ";"]] ].each do |csv_test|
55
+ assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first))
56
+ end
57
+
58
+ [ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
59
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
60
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
61
+ ["\"\"", [""]],
62
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
63
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
64
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
65
+ ["foo,\"\",baz", ["foo", "", "baz"]],
66
+ ["foo", ["foo"]],
67
+ [",,", [nil, nil, nil]],
68
+ [",", [nil, nil]],
69
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
70
+ ["foo,,baz", ["foo", nil, "baz"]],
71
+ ["foo,bar", ["foo", "bar"]],
72
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
73
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]] ].each do |csv_test|
74
+ assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first))
75
+ end
76
+ end
77
+
78
+ # From: http://ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-core/6496
79
+ def test_aras_edge_cases
80
+ [ [%Q{a,b}, ["a", "b"]],
81
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
82
+ [%Q{a,"""b"}, ["a", "\"b"]],
83
+ [%Q{a,"b"""}, ["a", "b\""]],
84
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
85
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
86
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
87
+ [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
88
+ [%Q{a,,,}, ["a", nil, nil, nil]],
89
+ [%Q{,}, [nil, nil]],
90
+ [%Q{"",""}, ["", ""]],
91
+ [%Q{""""}, ["\""]],
92
+ [%Q{"""",""}, ["\"",""]],
93
+ [%Q{,""}, [nil,""]],
94
+ [%Q{,"\r"}, [nil,"\r"]],
95
+ [%Q{"\r\n,"}, ["\r\n,"]],
96
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |edge_case|
97
+ assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
98
+ end
99
+ end
100
+
101
+ def test_james_edge_cases
102
+ # A read at eof? should return nil.
103
+ assert_equal(nil, FasterCSV.parse_line(""))
104
+ #
105
+ # With CSV it's impossible to tell an empty line from a line containing a
106
+ # single +nil+ field. The standard CSV library returns <tt>[nil]</tt>
107
+ # in these cases, but <tt>Array.new</tt> makes more sense to me.
108
+ #
109
+ assert_equal(Array.new, FasterCSV.parse_line("\n1,2,3\n"))
110
+ end
111
+
112
+ def test_malformed_csv
113
+ assert_raise(FasterCSV::MalformedCSVError) do
114
+ FasterCSV.parse_line("1,2\r,3")
115
+ end
116
+
117
+ assert_raise(FasterCSV::MalformedCSVError) do
118
+ FasterCSV.parse_line('1,2,"3...')
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,90 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_csv_writing.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 TestFasterCSVWriting < Test::Unit::TestCase
13
+ def test_writing
14
+ [ ["\t", ["\t"]],
15
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
16
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
17
+ ["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
18
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
19
+ ["\"\"", [""]],
20
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
21
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
22
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
23
+ ["foo,\"\",baz", ["foo", "", "baz"]],
24
+ ["\",\"", [","]],
25
+ ["foo", ["foo"]],
26
+ [",,", [nil, nil, nil]],
27
+ [",", [nil, nil]],
28
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
29
+ ["foo,,baz", ["foo", nil, "baz"]],
30
+ ["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
31
+ ["\",\",\",\"", [",", ","]],
32
+ ["foo,bar,", ["foo", "bar", nil]],
33
+ [",foo,bar", [nil, "foo", "bar"]],
34
+ ["foo,bar", ["foo", "bar"]],
35
+ [";", [";"]],
36
+ ["\t,\t", ["\t", "\t"]],
37
+ ["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
38
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
39
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
40
+ [";,;", [";", ";"]],
41
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
42
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
43
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
44
+ ["\"\"", [""]],
45
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
46
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
47
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
48
+ ["foo,\"\",baz", ["foo", "", "baz"]],
49
+ ["foo", ["foo"]],
50
+ [",,", [nil, nil, nil]],
51
+ [",", [nil, nil]],
52
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
53
+ ["foo,,baz", ["foo", nil, "baz"]],
54
+ ["foo,bar", ["foo", "bar"]],
55
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
56
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
57
+ [%Q{a,b}, ["a", "b"]],
58
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
59
+ [%Q{a,"""b"}, ["a", "\"b"]],
60
+ [%Q{a,"b"""}, ["a", "b\""]],
61
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
62
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
63
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
64
+ [%Q{a,"""\nb\n""",}, ["a", "\"\nb\n\"", nil]],
65
+ [%Q{a,,,}, ["a", nil, nil, nil]],
66
+ [%Q{,}, [nil, nil]],
67
+ [%Q{"",""}, ["", ""]],
68
+ [%Q{""""}, ["\""]],
69
+ [%Q{"""",""}, ["\"",""]],
70
+ [%Q{,""}, [nil,""]],
71
+ [%Q{,"\r"}, [nil,"\r"]],
72
+ [%Q{"\r\n,"}, ["\r\n,"]],
73
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |test_case|
74
+ assert_equal( test_case.first + $/,
75
+ FasterCSV.generate_line(test_case.last) )
76
+ end
77
+ end
78
+
79
+ def test_col_sep
80
+ assert_equal( "a;b;;c\n", FasterCSV.generate_line( ["a", "b", nil, "c"],
81
+ :col_sep => ";" ) )
82
+ assert_equal( "a\tb\t\tc\n", FasterCSV.generate_line( ["a", "b", nil, "c"],
83
+ :col_sep => "\t" ) )
84
+ end
85
+
86
+ def test_row_sep
87
+ assert_equal( "a,b,,c\r\n", FasterCSV.generate_line( ["a", "b", nil, "c"],
88
+ :row_sep => "\r\n" ) )
89
+ end
90
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_features.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 TestFasterCSVFeatures < Test::Unit::TestCase
13
+ TEST_CASES = [ [%Q{a,b}, ["a", "b"]],
14
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
15
+ [%Q{a,"""b"}, ["a", "\"b"]],
16
+ [%Q{a,"b"""}, ["a", "b\""]],
17
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
18
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
19
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
20
+ [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
21
+ [%Q{a,,,}, ["a", nil, nil, nil]],
22
+ [%Q{,}, [nil, nil]],
23
+ [%Q{"",""}, ["", ""]],
24
+ [%Q{""""}, ["\""]],
25
+ [%Q{"""",""}, ["\"",""]],
26
+ [%Q{,""}, [nil,""]],
27
+ [%Q{,"\r"}, [nil,"\r"]],
28
+ [%Q{"\r\n,"}, ["\r\n,"]],
29
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ]
30
+
31
+ def test_col_sep
32
+ [";", "\t"].each do |sep|
33
+ TEST_CASES.each do |test_case|
34
+ assert_equal( test_case.last.map { |t| t.tr(",", sep) unless t.nil? },
35
+ FasterCSV.parse_line( test_case.first.tr(",", sep),
36
+ :col_sep => sep ) )
37
+ end
38
+ end
39
+ assert_equal( [",,,", nil],
40
+ FasterCSV.parse_line(",,,;", :col_sep => ";") )
41
+ end
42
+
43
+ def test_row_sep
44
+ assert_raise(FasterCSV::MalformedCSVError) do
45
+ FasterCSV.parse_line("1,2,3\n,4,5\r\n", :row_sep => "\r\n")
46
+ end
47
+ assert_equal( ["1", "2", "3\n", "4", "5"],
48
+ FasterCSV.parse_line( %Q{1,2,"3\n",4,5\r\n},
49
+ :row_sep => "\r\n") )
50
+ end
51
+ end
@@ -0,0 +1,124 @@
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 TestFasterCSVInterface < Test::Unit::TestCase
13
+ def setup
14
+ @path = File.join(File.dirname(__FILE__), "temp_test_data.csv")
15
+
16
+ File.open(@path, "w") do |file|
17
+ file << "1\t2\t3\r\n"
18
+ file << "4\t5\r\n"
19
+ end
20
+
21
+ @expected = [%w{1 2 3}, %w{4 5}]
22
+ end
23
+
24
+ def teardown
25
+ File.unlink(@path)
26
+ end
27
+
28
+ ### Test Read Interface ###
29
+
30
+ def test_foreach
31
+ FasterCSV.foreach(@path, :col_sep => "\t", :row_sep => "\r\n") do |row|
32
+ assert_equal(@expected.shift, row)
33
+ end
34
+ end
35
+
36
+ def test_open_and_close
37
+ csv = FasterCSV.open(@path, "r+", :col_sep => "\t", :row_sep => "\r\n")
38
+ assert_not_nil(csv)
39
+ assert_instance_of(FasterCSV, csv)
40
+ assert_equal(false, csv.closed?)
41
+ csv.close
42
+ assert(csv.closed?)
43
+
44
+ ret = FasterCSV.open(@path) do |csv|
45
+ assert_instance_of(FasterCSV, csv)
46
+ "Return value."
47
+ end
48
+ assert(csv.closed?)
49
+ assert_equal("Return value.", ret)
50
+ end
51
+
52
+ def test_parse
53
+ data = File.read(@path)
54
+ assert_equal( @expected,
55
+ FasterCSV.parse(data, :col_sep => "\t", :row_sep => "\r\n") )
56
+
57
+ FasterCSV.parse(data, :col_sep => "\t", :row_sep => "\r\n") do |row|
58
+ assert_equal(@expected.shift, row)
59
+ end
60
+ end
61
+
62
+ def test_parse_line
63
+ row = FasterCSV.parse_line("1;2;3", :col_sep => ";")
64
+ assert_not_nil(row)
65
+ assert_instance_of(Array, row)
66
+ assert_equal(%w{1 2 3}, row)
67
+ end
68
+
69
+ def test_read_and_readlines
70
+ assert_equal( @expected,
71
+ FasterCSV.read(@path, :col_sep => "\t", :row_sep => "\r\n") )
72
+ assert_equal( @expected,
73
+ FasterCSV.readlines( @path,
74
+ :col_sep => "\t", :row_sep => "\r\n") )
75
+
76
+
77
+ data = FasterCSV.open(@path, :col_sep => "\t", :row_sep => "\r\n") do |csv|
78
+ csv.read
79
+ end
80
+ assert_equal(@expected, data)
81
+ data = FasterCSV.open(@path, :col_sep => "\t", :row_sep => "\r\n") do |csv|
82
+ csv.readlines
83
+ end
84
+ assert_equal(@expected, data)
85
+ end
86
+
87
+ def test_shift # aliased as gets() and readline()
88
+ FasterCSV.open(@path, "r+", :col_sep => "\t", :row_sep => "\r\n") do |csv|
89
+ assert_equal(@expected.shift, csv.shift)
90
+ assert_equal(@expected.shift, csv.shift)
91
+ assert_equal(nil, csv.shift)
92
+ end
93
+ end
94
+
95
+ ### Test Write Interface ###
96
+
97
+ def test_generate
98
+ str = FasterCSV.generate do |csv|
99
+ assert_instance_of(FasterCSV, csv)
100
+ assert_equal(csv, csv << [1, 2, 3])
101
+ assert_equal(csv, csv << [4, nil, 5])
102
+ end
103
+ assert_not_nil(str)
104
+ assert_instance_of(String, str)
105
+ assert_equal("1,2,3\n4,,5\n", str)
106
+ end
107
+
108
+ def test_generate_line
109
+ line = FasterCSV.generate_line(%w{1 2 3}, :col_sep => ";")
110
+ assert_not_nil(line)
111
+ assert_instance_of(String, line)
112
+ assert_equal("1;2;3\n", line)
113
+ end
114
+
115
+ def test_append # aliased add_row() and puts()
116
+ File.unlink(@path)
117
+
118
+ FasterCSV.open(@path, "w", :col_sep => "\t", :row_sep => "\r\n") do |csv|
119
+ @expected.each { |row| csv << row }
120
+ end
121
+
122
+ test_shift
123
+ end
124
+ end
@@ -0,0 +1,39 @@
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
+
10
+ require "faster_csv"
11
+ require "csv"
12
+
13
+ class TestFasterCSVSpeed < Test::Unit::TestCase
14
+ PATH = File.join(File.dirname(__FILE__), "test_data.csv")
15
+
16
+ def test_that_we_are_doing_the_same_work
17
+ FasterCSV.open(PATH) do |csv|
18
+ CSV.foreach(PATH) do |row|
19
+ assert_equal(row, csv.shift)
20
+ end
21
+ end
22
+ end
23
+
24
+ def test_speed_vs_csv
25
+ csv_time = Time.now
26
+ CSV.foreach(PATH) do |row|
27
+ # do nothing, we're just timing a read...
28
+ end
29
+ csv_time = Time.now - csv_time
30
+
31
+ faster_csv_time = Time.now
32
+ FasterCSV.foreach(PATH) do |row|
33
+ # do nothing, we're just timing a read...
34
+ end
35
+ faster_csv_time = Time.now - faster_csv_time
36
+
37
+ assert(faster_csv_time < csv_time / 3)
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # ts_all.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 "tc_csv_parsing"
11
+ require "tc_features"
12
+ require "tc_interface"
13
+ require "tc_csv_writing"
14
+ require "tc_speed"
metadata ADDED
@@ -0,0 +1,65 @@
1
+ !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: fastercsv
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2005-11-15 00:00:00 -06:00
8
+ summary: FasterCSV is CSV, but faster, smaller, and cleaner.
9
+ require_paths:
10
+ - lib
11
+ email: james@grayproductions.net
12
+ homepage: http://fastercsv.rubyforge.org
13
+ rubyforge_project: fastercsv
14
+ description: FasterCSV is intended as a complete replacement to the CSV standard library. It is significantly faster and smaller while still being pure Ruby code. It also strives for a better interface.
15
+ autorequire: fastercsv
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - James Edward Gray II
30
+ files:
31
+ - lib/faster_csv.rb
32
+ - test/tc_csv_parsing.rb
33
+ - test/tc_csv_writing.rb
34
+ - test/tc_features.rb
35
+ - test/tc_interface.rb
36
+ - test/tc_speed.rb
37
+ - test/ts_all.rb
38
+ - Rakefile
39
+ - setup.rb
40
+ - README
41
+ - INSTALL
42
+ - TODO
43
+ - CHANGELOG
44
+ - LICENSE
45
+ test_files:
46
+ - test/ts_all.rb
47
+ rdoc_options:
48
+ - --title
49
+ - FasterCSV Documentation
50
+ - --main
51
+ - README
52
+ extra_rdoc_files:
53
+ - README
54
+ - INSTALL
55
+ - TODO
56
+ - CHANGELOG
57
+ - LICENSE
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ requirements: []
63
+
64
+ dependencies: []
65
+