fastercsv 0.1.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.
@@ -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
+