123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- #!/usr/local/bin/ruby -w
- # tc_interface.rb
- #
- # Created by James Edward Gray II on 2005-11-14.
- # Copyright 2012 Gray Productions. All rights reserved.
- require "test/unit"
- require "faster_csv"
- class TestFasterCSVInterface < Test::Unit::TestCase
- def setup
- @path = File.join(File.dirname(__FILE__), "temp_test_data.csv")
-
- File.open(@path, "w") do |file|
- file << "1\t2\t3\r\n"
- file << "4\t5\r\n"
- end
- @expected = [%w{1 2 3}, %w{4 5}]
- end
-
- def teardown
- File.unlink(@path)
- end
-
- ### Test Read Interface ###
-
- def test_foreach
- FasterCSV.foreach(@path, :col_sep => "\t", :row_sep => "\r\n") do |row|
- assert_equal(@expected.shift, row)
- end
- end
-
- def test_open_and_close
- csv = FasterCSV.open(@path, "r+", :col_sep => "\t", :row_sep => "\r\n")
- assert_not_nil(csv)
- assert_instance_of(FasterCSV, csv)
- assert_equal(false, csv.closed?)
- csv.close
- assert(csv.closed?)
-
- ret = FasterCSV.open(@path) do |csv|
- assert_instance_of(FasterCSV, csv)
- "Return value."
- end
- assert(csv.closed?)
- assert_equal("Return value.", ret)
- end
-
- def test_parse
- data = File.read(@path)
- assert_equal( @expected,
- FasterCSV.parse(data, :col_sep => "\t", :row_sep => "\r\n") )
- FasterCSV.parse(data, :col_sep => "\t", :row_sep => "\r\n") do |row|
- assert_equal(@expected.shift, row)
- end
- end
-
- def test_parse_line
- row = FasterCSV.parse_line("1;2;3", :col_sep => ";")
- assert_not_nil(row)
- assert_instance_of(Array, row)
- assert_equal(%w{1 2 3}, row)
-
- # shortcut interface
- row = "1;2;3".parse_csv(:col_sep => ";")
- assert_not_nil(row)
- assert_instance_of(Array, row)
- assert_equal(%w{1 2 3}, row)
- end
-
- def test_parse_line_with_empty_lines
- assert_equal(nil, FasterCSV.parse_line("")) # to signal eof
- assert_equal(Array.new, FasterCSV.parse_line("\n1,2,3"))
- end
-
- def test_read_and_readlines
- assert_equal( @expected,
- FasterCSV.read(@path, :col_sep => "\t", :row_sep => "\r\n") )
- assert_equal( @expected,
- FasterCSV.readlines( @path,
- :col_sep => "\t", :row_sep => "\r\n") )
-
-
- data = FasterCSV.open(@path, :col_sep => "\t", :row_sep => "\r\n") do |csv|
- csv.read
- end
- assert_equal(@expected, data)
- data = FasterCSV.open(@path, :col_sep => "\t", :row_sep => "\r\n") do |csv|
- csv.readlines
- end
- assert_equal(@expected, data)
- end
-
- def test_table
- table = FasterCSV.table(@path, :col_sep => "\t", :row_sep => "\r\n")
- assert_instance_of(FasterCSV::Table, table)
- assert_equal([[:"1", :"2", :"3"], [4, 5, nil]], table.to_a)
- end
-
- def test_shift # aliased as gets() and readline()
- FasterCSV.open(@path, "r+", :col_sep => "\t", :row_sep => "\r\n") do |csv|
- assert_equal(@expected.shift, csv.shift)
- assert_equal(@expected.shift, csv.shift)
- assert_equal(nil, csv.shift)
- end
- end
- def test_long_line # ruby's regex parser may have problems with long rows
- File.unlink(@path)
- long_field_length = 2800
- File.open(@path, "w") do |file|
- file << "1\t2\t#{'3' * long_field_length}\r\n"
- end
- @expected = [%w{1 2} + ['3' * long_field_length]]
- test_shift
- end
-
- ### Test Write Interface ###
- def test_generate
- str = FasterCSV.generate do |csv| # default empty String
- assert_instance_of(FasterCSV, csv)
- assert_equal(csv, csv << [1, 2, 3])
- assert_equal(csv, csv << [4, nil, 5])
- end
- assert_not_nil(str)
- assert_instance_of(String, str)
- assert_equal("1,2,3\n4,,5\n", str)
- FasterCSV.generate(str) do |csv| # appending to a String
- assert_equal(csv, csv << ["last", %Q{"row"}])
- end
- assert_equal(%Q{1,2,3\n4,,5\nlast,"""row"""\n}, str)
- end
-
- def test_generate_line
- line = FasterCSV.generate_line(%w{1 2 3}, :col_sep => ";")
- assert_not_nil(line)
- assert_instance_of(String, line)
- assert_equal("1;2;3\n", line)
-
- # shortcut interface
- line = %w{1 2 3}.to_csv(:col_sep => ";")
- assert_not_nil(line)
- assert_instance_of(String, line)
- assert_equal("1;2;3\n", line)
- end
- def test_write_header_detection
- File.unlink(@path)
- headers = %w{a b c}
- FasterCSV.open(@path, "w", :headers => true) do |csv|
- csv << headers
- csv << %w{1 2 3}
- assert_equal(headers, csv.instance_variable_get(:@headers))
- end
- end
- def test_write_lineno
- File.unlink(@path)
- FasterCSV.open(@path, "w") do |csv|
- lines = 20
- lines.times { csv << %w{a b c} }
- assert_equal(lines, csv.lineno)
- end
- end
- def test_write_hash
- File.unlink(@path)
- lines = [{:a => 1, :b => 2, :c => 3}, {:a => 4, :b => 5, :c => 6}]
- FasterCSV.open( @path, "w", :headers => true,
- :header_converters => :symbol ) do |csv|
- csv << lines.first.keys
- lines.each { |line| csv << line }
- end
- FasterCSV.open( @path, "r", :headers => true,
- :converters => :all,
- :header_converters => :symbol ) do |csv|
- csv.each { |line| assert_equal(lines.shift, line.to_hash) }
- end
- end
- def test_write_hash_with_headers_array
- File.unlink(@path)
- lines = [{:a => 1, :b => 2, :c => 3}, {:a => 4, :b => 5, :c => 6}]
- FasterCSV.open(@path, "w", :headers => [:b, :a, :c]) do |csv|
- lines.each { |line| csv << line }
- end
- # test writing fields in the correct order
- File.open(@path, "r") do |f|
- assert_equal("2,1,3", f.gets.strip)
- assert_equal("5,4,6", f.gets.strip)
- end
- # test reading CSV with headers
- FasterCSV.open( @path, "r", :headers => [:b, :a, :c],
- :converters => :all ) do |csv|
- csv.each { |line| assert_equal(lines.shift, line.to_hash) }
- end
- end
- def test_write_hash_with_headers_string
- File.unlink(@path)
- lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}]
- FasterCSV.open( @path, "w", :headers => "b|a|c",
- :col_sep => "|" ) do |csv|
- lines.each { |line| csv << line }
- end
- # test writing fields in the correct order
- File.open(@path, "r") do |f|
- assert_equal("2|1|3", f.gets.strip)
- assert_equal("5|4|6", f.gets.strip)
- end
- # test reading CSV with headers
- FasterCSV.open( @path, "r", :headers => "b|a|c",
- :col_sep => "|",
- :converters => :all ) do |csv|
- csv.each { |line| assert_equal(lines.shift, line.to_hash) }
- end
- end
-
- def test_write_headers
- File.unlink(@path)
- lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}]
- FasterCSV.open( @path, "w", :headers => "b|a|c",
- :write_headers => true,
- :col_sep => "|" ) do |csv|
- lines.each { |line| csv << line }
- end
- # test writing fields in the correct order
- File.open(@path, "r") do |f|
- assert_equal("b|a|c", f.gets.strip)
- assert_equal("2|1|3", f.gets.strip)
- assert_equal("5|4|6", f.gets.strip)
- end
- # test reading CSV with headers
- FasterCSV.open( @path, "r", :headers => true,
- :col_sep => "|",
- :converters => :all ) do |csv|
- csv.each { |line| assert_equal(lines.shift, line.to_hash) }
- end
- end
-
- def test_append # aliased add_row() and puts()
- File.unlink(@path)
-
- FasterCSV.open(@path, "w", :col_sep => "\t", :row_sep => "\r\n") do |csv|
- @expected.each { |row| csv << row }
- end
- test_shift
- # same thing using FasterCSV::Row objects
- File.unlink(@path)
-
- FasterCSV.open(@path, "w", :col_sep => "\t", :row_sep => "\r\n") do |csv|
- @expected.each { |row| csv << FasterCSV::Row.new(Array.new, row) }
- end
- test_shift
- end
-
- ### Test Read and Write Interface ###
-
- def test_filter
- assert_respond_to(FasterCSV, :filter)
-
- expected = [[1, 2, 3], [4, 5]]
- FasterCSV.filter( "1;2;3\n4;5\n", (result = String.new),
- :in_col_sep => ";", :out_col_sep => ",",
- :converters => :all ) do |row|
- assert_equal(row, expected.shift)
- row.map! { |n| n * 2 }
- row << "Added\r"
- end
- assert_equal("2,4,6,\"Added\r\"\n8,10,\"Added\r\"\n", result)
- end
-
- def test_instance
- csv = String.new
-
- first = nil
- assert_nothing_raised(Exception) do
- first = FasterCSV.instance(csv, :col_sep => ";")
- first << %w{a b c}
- end
-
- assert_equal("a;b;c\n", csv)
-
- second = nil
- assert_nothing_raised(Exception) do
- second = FasterCSV.instance(csv, :col_sep => ";")
- second << [1, 2, 3]
- end
-
- assert_equal(first.object_id, second.object_id)
- assert_equal("a;b;c\n1;2;3\n", csv)
-
- # shortcuts
- assert_equal(STDOUT, FasterCSV.instance.instance_eval { @io })
- assert_equal(STDOUT, FasterCSV { |csv| csv.instance_eval { @io } })
- assert_equal(STDOUT, FCSV.instance.instance_eval { @io })
- assert_equal(STDOUT, FCSV { |csv| csv.instance_eval { @io } })
- end
-
- ### Test Alternate Interface ###
-
- def test_csv_interface
- require "csv"
- data = ["Number", 42, "Tricky Field", 'This has embedded "quotes"!']
- data_file = File.join(File.dirname(__FILE__), "temp_csv_data.csv")
- CSV.open(data_file, "w") { |f| 10.times { f << data } }
- csv = CSV.generate_line(data)
- tests = { :foreach => Array.new,
- :generate_line => csv,
- :open => Array.new,
- :parse => CSV.parse(csv),
- :parse_w_block => Array.new,
- :parse_line => CSV.parse_line(csv),
- :readlines => CSV.readlines(data_file) }
- CSV.foreach(data_file) { |row| tests[:foreach] << row }
- CSV.open(data_file, "r") { |row| tests[:open] << row }
- CSV.parse(([csv] * 3).join("\n")) { |row| tests[:parse_w_block] << row }
- Object.send(:remove_const, :CSV)
-
- assert_nothing_raised(Exception) do
- FasterCSV.build_csv_interface
- end
-
- %w{ foreach
- generate_line
- open
- parse
- parse_line
- readlines }.each do |meth|
- assert_respond_to(::CSV, meth)
- end
-
- faster_csv = Array.new
- CSV.foreach(data_file) { |row| faster_csv << row }
- assert_equal(tests[:foreach], faster_csv)
- assert_equal(tests[:generate_line], CSV.generate_line(data))
- faster_csv.clear
- CSV.open(data_file, "r") { |row| faster_csv << row }
- assert_equal(tests[:open], faster_csv)
- comp_file = data_file.sub("_csv_data", "_faster_csv_data")
- CSV.open(comp_file, "w") { |f| 10.times { f << data } }
- assert_equal(File.read(data_file), File.read(comp_file))
- assert_equal(tests[:parse], CSV.parse(csv))
- faster_csv.clear
- CSV.parse(([csv] * 3).join("\n")) { |row| faster_csv << row }
- assert_equal(tests[:parse_w_block], faster_csv)
- assert_equal(tests[:parse_line], CSV.parse_line(csv))
- assert_equal(tests[:readlines], CSV.readlines(data_file))
-
- Object.send(:remove_const, :CSV)
- load "csv.rb"
- [data_file, comp_file].each { |file| File.unlink(file) }
- end
- end
|