зеркало из https://github.com/github/ruby.git
* lib/csv.rb: writes lines with "\n" when row separator is not given.
formerly it was "\r\n". * lib/csv.rb: [CAUTION] API change * CSV::Row removed. a row is represented as just an Array. since CSV::Row was a subclass of Array, it won't hurt almost all programs except one which depended CSV::Row#match. * CSV::Cell removed. a cell is represented as just a String or nil(NULL). this change will cause widespread destruction. CSV.open("foo.csv", "r") do |row| row.each do |cell| if cell.is_null # Cell#is_null p "(NULL)" else p cell.data # Cell#data end end end must be just; CSV.open("foo.csv", "r") do |row| row.each do |cell| if cell.nil? p "(NULL)" else p cell end end end * lib/csv.rb: [CAUTION] record separator(CR, LF, CR+LF) behavior change. CSV.open, CSV.parse, and CSV,generate now do not force opened file binmode. formerly it set binmode explicitly. with CSV.open, binmode of opened file depends the given mode parameter "r", "w", "rb", and "wb". CSV.parse and CSV.generate open file with "r" and "w". setting mode properly is user's responsibility now. * lib/csv.rb: accepts String as a fs (field separator/column separator) and rs (record separator/row separator) * lib/csv.rb: added CSV.foreach(path, rs = nil, &block). CSV.foreach now does not handle "| cmd" as a path different from IO.foreach. needed? * test/csv/test_csv.rb: updated. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6359 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
75db654808
Коммит
34a553da2e
55
ChangeLog
55
ChangeLog
|
@ -1,3 +1,58 @@
|
||||||
|
Tue May 18 21:21:43 2004 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
|
||||||
|
|
||||||
|
* lib/csv.rb: writes lines with "\n" when row separator is not given.
|
||||||
|
formerly it was "\r\n".
|
||||||
|
|
||||||
|
* lib/csv.rb: [CAUTION] API change
|
||||||
|
|
||||||
|
* CSV::Row removed. a row is represented as just an Array. since
|
||||||
|
CSV::Row was a subclass of Array, it won't hurt almost all programs
|
||||||
|
except one which depended CSV::Row#match.
|
||||||
|
|
||||||
|
* CSV::Cell removed. a cell is represented as just a String or
|
||||||
|
nil(NULL). this change will cause widespread destruction.
|
||||||
|
|
||||||
|
CSV.open("foo.csv", "r") do |row|
|
||||||
|
row.each do |cell|
|
||||||
|
if cell.is_null # Cell#is_null
|
||||||
|
p "(NULL)"
|
||||||
|
else
|
||||||
|
p cell.data # Cell#data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
must be just;
|
||||||
|
|
||||||
|
CSV.open("foo.csv", "r") do |row|
|
||||||
|
row.each do |cell|
|
||||||
|
if cell.nil?
|
||||||
|
p "(NULL)"
|
||||||
|
else
|
||||||
|
p cell
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
* lib/csv.rb: [CAUTION] record separator(CR, LF, CR+LF) behavior
|
||||||
|
change. CSV.open, CSV.parse, and CSV,generate now do not force
|
||||||
|
opened file binmode. formerly it set binmode explicitly.
|
||||||
|
|
||||||
|
with CSV.open, binmode of opened file depends the given mode
|
||||||
|
parameter "r", "w", "rb", and "wb". CSV.parse and CSV.generate open
|
||||||
|
file with "r" and "w".
|
||||||
|
|
||||||
|
setting mode properly is user's responsibility now.
|
||||||
|
|
||||||
|
* lib/csv.rb: accepts String as a fs (field separator/column separator)
|
||||||
|
and rs (record separator/row separator)
|
||||||
|
|
||||||
|
* lib/csv.rb: added CSV.foreach(path, rs = nil, &block). CSV.foreach
|
||||||
|
now does not handle "| cmd" as a path different from IO.foreach.
|
||||||
|
needed?
|
||||||
|
|
||||||
|
* test/csv/test_csv.rb: updated.
|
||||||
|
|
||||||
Tue May 18 14:24:20 2004 why the lucky stiff <why@ruby-lang.org>
|
Tue May 18 14:24:20 2004 why the lucky stiff <why@ruby-lang.org>
|
||||||
|
|
||||||
* lib/yaml.rb: added rdoc to beginning of lib.
|
* lib/yaml.rb: added rdoc to beginning of lib.
|
||||||
|
|
493
lib/csv.rb
493
lib/csv.rb
|
@ -1,4 +1,5 @@
|
||||||
# CSV -- module for generating/parsing CSV data.
|
# CSV -- module for generating/parsing CSV data.
|
||||||
|
# Copyright (C) 2000-2004 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
|
||||||
|
|
||||||
# $Id$
|
# $Id$
|
||||||
|
|
||||||
|
@ -8,99 +9,22 @@
|
||||||
|
|
||||||
|
|
||||||
class CSV
|
class CSV
|
||||||
|
|
||||||
# Describes a cell of CSV.
|
|
||||||
class Cell
|
|
||||||
# Datum as string.
|
|
||||||
attr_accessor :data
|
|
||||||
|
|
||||||
# Is this datum NULL?
|
|
||||||
attr_accessor :is_null
|
|
||||||
|
|
||||||
# If is_null is true, datum is stored in the instance created but it
|
|
||||||
# should be treated as 'NULL'.
|
|
||||||
def initialize(data = '', is_null = true)
|
|
||||||
@data = data
|
|
||||||
@is_null = is_null
|
|
||||||
end
|
|
||||||
|
|
||||||
# Compares another cell with self. Bear in mind NULL matches with NULL.
|
|
||||||
# Use CSV::Cell#== if you don't want NULL matches with NULL.
|
|
||||||
# rhs: an instance of CSV::Cell to be compared.
|
|
||||||
def match(rhs)
|
|
||||||
if @is_null and rhs.is_null
|
|
||||||
true
|
|
||||||
elsif @is_null or rhs.is_null
|
|
||||||
false
|
|
||||||
else
|
|
||||||
@data == rhs.data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Compares another cell with self. Bear in mind NULL does not match with
|
|
||||||
# NULL. Use CSV::Cell#match if you want NULL matches with NULL.
|
|
||||||
# rhs: an instance of CSV::Cell to be compared.
|
|
||||||
def ==(rhs)
|
|
||||||
if @is_null or rhs.is_null
|
|
||||||
false
|
|
||||||
else
|
|
||||||
@data == rhs.data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_str
|
|
||||||
content.to_str
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
content.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def content
|
|
||||||
@is_null ? nil : data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# Describes a row of CSV. Each element must be a CSV::Cell.
|
|
||||||
class Row < Array
|
|
||||||
|
|
||||||
# Returns the strings contained in the row's cells.
|
|
||||||
def to_a
|
|
||||||
self.collect { |cell| cell.is_null ? nil : cell.data }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Compares another row with self.
|
|
||||||
# rhs: an Array of cells. Each cell should be a CSV::Cell.
|
|
||||||
def match(rhs)
|
|
||||||
if self.size != rhs.size
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
for idx in 0...(self.size)
|
|
||||||
unless self[idx].match(rhs[idx])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
class IllegalFormatError < RuntimeError; end
|
class IllegalFormatError < RuntimeError; end
|
||||||
|
|
||||||
|
def CSV.open(path, mode, fs = ',', rs = nil, &block)
|
||||||
def CSV.open(filename, mode, col_sep = ?,, row_sep = nil, &block)
|
|
||||||
if mode == 'r' or mode == 'rb'
|
if mode == 'r' or mode == 'rb'
|
||||||
open_reader(filename, col_sep, row_sep, &block)
|
open_reader(path, mode, fs, rs, &block)
|
||||||
elsif mode == 'w' or mode == 'wb'
|
elsif mode == 'w' or mode == 'wb'
|
||||||
open_writer(filename, col_sep, row_sep, &block)
|
open_writer(path, mode, fs, rs, &block)
|
||||||
else
|
else
|
||||||
raise ArgumentError.new("'mode' must be 'r', 'rb', 'w', or 'wb'")
|
raise ArgumentError.new("'mode' must be 'r', 'rb', 'w', or 'wb'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def CSV.foreach(path, rs = nil, &block)
|
||||||
|
open_reader(path, 'r', ',', rs, &block)
|
||||||
|
end
|
||||||
|
|
||||||
# Open a CSV formatted file for reading.
|
# Open a CSV formatted file for reading.
|
||||||
#
|
#
|
||||||
# EXAMPLE 1
|
# EXAMPLE 1
|
||||||
|
@ -127,8 +51,8 @@ class CSV
|
||||||
# RETURNS
|
# RETURNS
|
||||||
# reader instance. To get parse result, see CSV::Reader#each.
|
# reader instance. To get parse result, see CSV::Reader#each.
|
||||||
#
|
#
|
||||||
def CSV.parse(filename, col_sep = ?,, row_sep = nil, &block)
|
def CSV.parse(path, fs = ',', rs = nil, &block)
|
||||||
open_reader(filename, col_sep, row_sep, &block)
|
open_reader(path, 'r', fs, rs, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Open a CSV formatted file for writing.
|
# Open a CSV formatted file for writing.
|
||||||
|
@ -156,8 +80,8 @@ class CSV
|
||||||
# writer instance. See CSV::Writer#<< and CSV::Writer#add_row to know how
|
# writer instance. See CSV::Writer#<< and CSV::Writer#add_row to know how
|
||||||
# to generate CSV string.
|
# to generate CSV string.
|
||||||
#
|
#
|
||||||
def CSV.generate(filename, col_sep = ?,, row_sep = nil, &block)
|
def CSV.generate(path, fs = ',', rs = nil, &block)
|
||||||
open_writer(filename, col_sep, row_sep, &block)
|
open_writer(path, 'w', fs, rs, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse a line from given string. Bear in mind it parses ONE LINE. Rest of
|
# Parse a line from given string. Bear in mind it parses ONE LINE. Rest of
|
||||||
|
@ -166,47 +90,52 @@ class CSV
|
||||||
#
|
#
|
||||||
# If you don't know whether a target string to parse is exactly 1 line or
|
# If you don't know whether a target string to parse is exactly 1 line or
|
||||||
# not, use CSV.parse_row instead of this method.
|
# not, use CSV.parse_row instead of this method.
|
||||||
def CSV.parse_line(src, col_sep = ?,, row_sep = nil)
|
def CSV.parse_line(src, fs = ',', rs = nil)
|
||||||
|
if !fs.nil? and fs.is_a?(Fixnum)
|
||||||
|
fs = fs.chr
|
||||||
|
end
|
||||||
|
if !rs.nil? and rs.is_a?(Fixnum)
|
||||||
|
rs = rs.chr
|
||||||
|
end
|
||||||
idx = 0
|
idx = 0
|
||||||
res_type = :DT_COLSEP
|
res_type = :DT_COLSEP
|
||||||
cells = Row.new
|
row = []
|
||||||
begin
|
begin
|
||||||
while (res_type.equal?(:DT_COLSEP))
|
while (res_type.equal?(:DT_COLSEP))
|
||||||
cell = Cell.new
|
res_type, idx, cell = parse_body(src, idx, fs, rs)
|
||||||
res_type, idx = parse_body(src, idx, cell, col_sep, row_sep)
|
row << cell
|
||||||
cells.push(cell.is_null ? nil : cell.data)
|
|
||||||
end
|
end
|
||||||
rescue IllegalFormatError
|
rescue IllegalFormatError
|
||||||
return Row.new
|
return []
|
||||||
end
|
end
|
||||||
cells
|
row
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a line from cells. each cell is stringified by to_s.
|
# Create a line from cells. each cell is stringified by to_s.
|
||||||
def CSV.generate_line(cells, col_sep = ?,, row_sep = nil)
|
def CSV.generate_line(row, fs = ',', rs = nil)
|
||||||
if (cells.size == 0)
|
if (row.size == 0)
|
||||||
return ''
|
return ''
|
||||||
end
|
end
|
||||||
|
if !fs.nil? and fs.is_a?(Fixnum)
|
||||||
|
fs = fs.chr
|
||||||
|
end
|
||||||
|
if !rs.nil? and rs.is_a?(Fixnum)
|
||||||
|
rs = rs.chr
|
||||||
|
end
|
||||||
res_type = :DT_COLSEP
|
res_type = :DT_COLSEP
|
||||||
result_str = ''
|
result_str = ''
|
||||||
idx = 0
|
idx = 0
|
||||||
while true
|
while true
|
||||||
cell = if (cells[idx].nil?)
|
generate_body(row[idx], result_str, fs, rs)
|
||||||
Cell.new('', true)
|
|
||||||
else
|
|
||||||
Cell.new(cells[idx].to_s, false)
|
|
||||||
end
|
|
||||||
generate_body(cell, result_str, col_sep, row_sep)
|
|
||||||
idx += 1
|
idx += 1
|
||||||
if (idx == cells.size)
|
if (idx == row.size)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
generate_separator(:DT_COLSEP, result_str, col_sep, row_sep)
|
generate_separator(:DT_COLSEP, result_str, fs, rs)
|
||||||
end
|
end
|
||||||
result_str
|
result_str
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Parse a line from string. Consider using CSV.parse_line instead.
|
# Parse a line from string. Consider using CSV.parse_line instead.
|
||||||
# To parse lines in CSV string, see EXAMPLE below.
|
# To parse lines in CSV string, see EXAMPLE below.
|
||||||
#
|
#
|
||||||
|
@ -236,16 +165,21 @@ class CSV
|
||||||
# parsed_cells: num of parsed cells.
|
# parsed_cells: num of parsed cells.
|
||||||
# idx: index of next parsing location of 'src'.
|
# idx: index of next parsing location of 'src'.
|
||||||
#
|
#
|
||||||
def CSV.parse_row(src, idx, out_dev, col_sep = ?,, row_sep = nil)
|
def CSV.parse_row(src, idx, out_dev, fs = ',', rs = nil)
|
||||||
|
if !fs.nil? and fs.is_a?(Fixnum)
|
||||||
|
fs = fs.chr
|
||||||
|
end
|
||||||
|
if !rs.nil? and rs.is_a?(Fixnum)
|
||||||
|
rs = rs.chr
|
||||||
|
end
|
||||||
idx_backup = idx
|
idx_backup = idx
|
||||||
parsed_cells = 0
|
parsed_cells = 0
|
||||||
res_type = :DT_COLSEP
|
res_type = :DT_COLSEP
|
||||||
begin
|
begin
|
||||||
while (!res_type.equal?(:DT_ROWSEP))
|
while (!res_type.equal?(:DT_ROWSEP))
|
||||||
cell = Cell.new
|
res_type, idx, cell = parse_body(src, idx, fs, rs)
|
||||||
res_type, idx = parse_body(src, idx, cell, col_sep, row_sep)
|
|
||||||
if res_type.equal?(:DT_EOS)
|
if res_type.equal?(:DT_EOS)
|
||||||
if idx == idx_backup #((parsed_cells == 0) && (cell.is_null))
|
if idx == idx_backup #((parsed_cells == 0) and cell.nil?)
|
||||||
return 0, 0
|
return 0, 0
|
||||||
end
|
end
|
||||||
res_type = :DT_ROWSEP
|
res_type = :DT_ROWSEP
|
||||||
|
@ -259,7 +193,6 @@ class CSV
|
||||||
return parsed_cells, idx
|
return parsed_cells, idx
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Convert a line from cells data to string. Consider using CSV.generate_line
|
# Convert a line from cells data to string. Consider using CSV.generate_line
|
||||||
# instead. To generate multi-row CSV string, see EXAMPLE below.
|
# instead. To generate multi-row CSV string, see EXAMPLE below.
|
||||||
#
|
#
|
||||||
|
@ -292,39 +225,46 @@ class CSV
|
||||||
# RETURNS
|
# RETURNS
|
||||||
# parsed_cells: num of converted cells.
|
# parsed_cells: num of converted cells.
|
||||||
#
|
#
|
||||||
def CSV.generate_row(src, cells, out_dev, col_sep = ?,, row_sep = nil)
|
def CSV.generate_row(src, cells, out_dev, fs = ',', rs = nil)
|
||||||
|
if !fs.nil? and fs.is_a?(Fixnum)
|
||||||
|
fs = fs.chr
|
||||||
|
end
|
||||||
|
if !rs.nil? and rs.is_a?(Fixnum)
|
||||||
|
rs = rs.chr
|
||||||
|
end
|
||||||
src_size = src.size
|
src_size = src.size
|
||||||
if (src_size == 0)
|
if (src_size == 0)
|
||||||
if cells == 0
|
if cells == 0
|
||||||
generate_separator(:DT_ROWSEP, out_dev, col_sep, row_sep)
|
generate_separator(:DT_ROWSEP, out_dev, fs, rs)
|
||||||
end
|
end
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
res_type = :DT_COLSEP
|
res_type = :DT_COLSEP
|
||||||
parsed_cells = 0
|
parsed_cells = 0
|
||||||
generate_body(src[parsed_cells], out_dev, col_sep, row_sep)
|
generate_body(src[parsed_cells], out_dev, fs, rs)
|
||||||
parsed_cells += 1
|
parsed_cells += 1
|
||||||
while ((parsed_cells < cells) && (parsed_cells != src_size))
|
while ((parsed_cells < cells) and (parsed_cells != src_size))
|
||||||
generate_separator(:DT_COLSEP, out_dev, col_sep, row_sep)
|
generate_separator(:DT_COLSEP, out_dev, fs, rs)
|
||||||
generate_body(src[parsed_cells], out_dev, col_sep, row_sep)
|
generate_body(src[parsed_cells], out_dev, fs, rs)
|
||||||
parsed_cells += 1
|
parsed_cells += 1
|
||||||
end
|
end
|
||||||
if (parsed_cells == cells)
|
if (parsed_cells == cells)
|
||||||
generate_separator(:DT_ROWSEP, out_dev, col_sep, row_sep)
|
generate_separator(:DT_ROWSEP, out_dev, fs, rs)
|
||||||
else
|
else
|
||||||
generate_separator(:DT_COLSEP, out_dev, col_sep, row_sep)
|
generate_separator(:DT_COLSEP, out_dev, fs, rs)
|
||||||
end
|
end
|
||||||
parsed_cells
|
parsed_cells
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Private class methods.
|
||||||
class << self
|
class << self
|
||||||
private
|
private
|
||||||
|
|
||||||
def open_reader(filename, col_sep, row_sep, &block)
|
def open_reader(path, mode, fs, rs, &block)
|
||||||
file = File.open(filename, 'rb')
|
file = File.open(path, mode)
|
||||||
if block
|
if block
|
||||||
begin
|
begin
|
||||||
CSV::Reader.parse(file, col_sep, row_sep) do |row|
|
CSV::Reader.parse(file, fs, rs) do |row|
|
||||||
yield(row)
|
yield(row)
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
|
@ -332,17 +272,17 @@ class CSV
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
reader = CSV::Reader.create(file, col_sep, row_sep)
|
reader = CSV::Reader.create(file, fs, rs)
|
||||||
reader.close_on_terminate
|
reader.close_on_terminate
|
||||||
reader
|
reader
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def open_writer(filename, col_sep, row_sep, &block)
|
def open_writer(path, mode, fs, rs, &block)
|
||||||
file = File.open(filename, 'wb')
|
file = File.open(path, mode)
|
||||||
if block
|
if block
|
||||||
begin
|
begin
|
||||||
CSV::Writer.generate(file, col_sep, row_sep) do |writer|
|
CSV::Writer.generate(file, fs, rs) do |writer|
|
||||||
yield(writer)
|
yield(writer)
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
|
@ -350,134 +290,162 @@ class CSV
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
writer = CSV::Writer.create(file, col_sep, row_sep)
|
writer = CSV::Writer.create(file, fs, rs)
|
||||||
writer.close_on_terminate
|
writer.close_on_terminate
|
||||||
writer
|
writer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_body(src, idx, cell, col_sep, row_sep)
|
def parse_body(src, idx, fs, rs)
|
||||||
row_sep_end = row_sep || ?\n
|
fs_str = fs
|
||||||
cell.is_null = false
|
fs_size = fs_str.size
|
||||||
|
fs_idx = 0
|
||||||
|
rs_str = rs || "\n"
|
||||||
|
rs_size = rs_str.size
|
||||||
|
rs_idx = 0
|
||||||
|
cell = ''
|
||||||
state = :ST_START
|
state = :ST_START
|
||||||
quoted = false
|
quoted = false
|
||||||
cr = false
|
cr = false
|
||||||
c = nil
|
c = nil
|
||||||
|
last_idx = idx
|
||||||
while (c = src[idx])
|
while (c = src[idx])
|
||||||
idx += 1
|
if c == ?"
|
||||||
result_state = :DT_UNKNOWN
|
cell << src[last_idx, (idx - last_idx)]
|
||||||
if (c == col_sep)
|
last_idx = idx
|
||||||
|
if cr
|
||||||
|
raise IllegalFormatError
|
||||||
|
end
|
||||||
|
if fs_idx != 0
|
||||||
|
fs_idx = 0
|
||||||
|
end
|
||||||
|
if rs_idx != 0
|
||||||
|
rs_idx = 0
|
||||||
|
end
|
||||||
if state.equal?(:ST_DATA)
|
if state.equal?(:ST_DATA)
|
||||||
if cr
|
|
||||||
raise IllegalFormatError.new
|
|
||||||
end
|
|
||||||
if (!quoted)
|
|
||||||
state = :ST_END
|
|
||||||
result_state = :DT_COLSEP
|
|
||||||
else
|
|
||||||
cell.data << c.chr
|
|
||||||
end
|
|
||||||
elsif state.equal?(:ST_QUOTE)
|
|
||||||
if cr
|
|
||||||
raise IllegalFormatError.new
|
|
||||||
end
|
|
||||||
state = :ST_END
|
|
||||||
result_state = :DT_COLSEP
|
|
||||||
else # :ST_START
|
|
||||||
cell.is_null = true
|
|
||||||
state = :ST_END
|
|
||||||
result_state = :DT_COLSEP
|
|
||||||
end
|
|
||||||
elsif (c == ?") # " for vim syntax hilighting.
|
|
||||||
if state.equal?(:ST_DATA)
|
|
||||||
if cr
|
|
||||||
raise IllegalFormatError.new
|
|
||||||
end
|
|
||||||
if quoted
|
if quoted
|
||||||
|
last_idx += 1
|
||||||
quoted = false
|
quoted = false
|
||||||
state = :ST_QUOTE
|
state = :ST_QUOTE
|
||||||
else
|
else
|
||||||
raise IllegalFormatError.new
|
raise IllegalFormatError
|
||||||
end
|
end
|
||||||
elsif state.equal?(:ST_QUOTE)
|
elsif state.equal?(:ST_QUOTE)
|
||||||
cell.data << c.chr
|
cell << c.chr
|
||||||
|
last_idx += 1
|
||||||
quoted = true
|
quoted = true
|
||||||
state = :ST_DATA
|
state = :ST_DATA
|
||||||
else # :ST_START
|
else # :ST_START
|
||||||
quoted = true
|
quoted = true
|
||||||
|
last_idx += 1
|
||||||
state = :ST_DATA
|
state = :ST_DATA
|
||||||
end
|
end
|
||||||
elsif row_sep.nil? and c == ?\r
|
elsif c == fs_str[fs_idx]
|
||||||
|
fs_idx += 1
|
||||||
|
cell << src[last_idx, (idx - last_idx)]
|
||||||
|
last_idx = idx
|
||||||
|
if rs_idx != 0
|
||||||
|
rs_idx = 0
|
||||||
|
end
|
||||||
|
if fs_idx == fs_size
|
||||||
|
fs_idx = 0
|
||||||
if cr
|
if cr
|
||||||
raise IllegalFormatError.new
|
raise IllegalFormatError
|
||||||
|
end
|
||||||
|
if state.equal?(:ST_DATA)
|
||||||
|
if rs_idx != 0
|
||||||
|
cell << rs_str[0, rs_idx]
|
||||||
|
rs_idx = 0
|
||||||
end
|
end
|
||||||
if quoted
|
if quoted
|
||||||
cell.data << c.chr
|
true # ToDo: delete; dummy line for coverage
|
||||||
|
else
|
||||||
|
return :DT_COLSEP, idx + 1, cell;
|
||||||
|
end
|
||||||
|
elsif state.equal?(:ST_QUOTE)
|
||||||
|
if rs_idx != 0
|
||||||
|
raise IllegalFormatError
|
||||||
|
end
|
||||||
|
return :DT_COLSEP, idx + 1, cell;
|
||||||
|
else # :ST_START
|
||||||
|
return :DT_COLSEP, idx + 1, nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif c == rs_str[rs_idx]
|
||||||
|
rs_idx += 1
|
||||||
|
unless (rs.nil? and cr)
|
||||||
|
cell << src[last_idx, (idx - last_idx)]
|
||||||
|
last_idx = idx
|
||||||
|
end
|
||||||
|
if fs_idx != 0
|
||||||
|
fs_idx = 0
|
||||||
|
end
|
||||||
|
if rs_idx == rs_size
|
||||||
|
rs_idx = 0
|
||||||
|
if state.equal?(:ST_DATA)
|
||||||
|
if quoted
|
||||||
|
true # ToDo: delete; dummy line for coverage
|
||||||
|
else
|
||||||
|
return :DT_ROWSEP, idx + 1, cell
|
||||||
|
end
|
||||||
|
elsif state.equal?(:ST_QUOTE)
|
||||||
|
return :DT_ROWSEP, idx + 1, cell
|
||||||
|
else # :ST_START
|
||||||
|
return :DT_ROWSEP, idx + 1, nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif rs.nil? and c == ?\r
|
||||||
|
# special \r treatment for backward compatibility
|
||||||
|
if cr
|
||||||
|
raise IllegalFormatError
|
||||||
|
end
|
||||||
|
cell << src[last_idx, (idx - last_idx)]
|
||||||
|
last_idx = idx
|
||||||
|
if quoted
|
||||||
state = :ST_DATA
|
state = :ST_DATA
|
||||||
else
|
else
|
||||||
cr = true
|
cr = true
|
||||||
end
|
end
|
||||||
elsif c == row_sep_end
|
|
||||||
if state.equal?(:ST_DATA)
|
|
||||||
if cr
|
|
||||||
state = :ST_END
|
|
||||||
result_state = :DT_ROWSEP
|
|
||||||
cr = false
|
|
||||||
else
|
else
|
||||||
if quoted
|
if fs_idx != 0
|
||||||
cell.data << c.chr
|
fs_idx = 0
|
||||||
state = :ST_DATA
|
|
||||||
else
|
|
||||||
state = :ST_END
|
|
||||||
result_state = :DT_ROWSEP
|
|
||||||
end
|
end
|
||||||
|
if rs_idx != 0
|
||||||
|
rs_idx = 0
|
||||||
end
|
end
|
||||||
elsif state.equal?(:ST_QUOTE)
|
if state.equal?(:ST_DATA) or state.equal?(:ST_START)
|
||||||
state = :ST_END
|
|
||||||
result_state = :DT_ROWSEP
|
|
||||||
if cr
|
if cr
|
||||||
cr = false
|
raise IllegalFormatError
|
||||||
end
|
end
|
||||||
else # :ST_START
|
|
||||||
cell.is_null = true
|
|
||||||
state = :ST_END
|
|
||||||
result_state = :DT_ROWSEP
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if state.equal?(:ST_DATA) || state.equal?(:ST_START)
|
|
||||||
if cr
|
|
||||||
raise IllegalFormatError.new
|
|
||||||
end
|
|
||||||
cell.data << c.chr
|
|
||||||
state = :ST_DATA
|
state = :ST_DATA
|
||||||
else # :ST_QUOTE
|
else # :ST_QUOTE
|
||||||
raise IllegalFormatError.new
|
raise IllegalFormatError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if state.equal?(:ST_END)
|
idx += 1
|
||||||
return result_state, idx;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if state.equal?(:ST_START)
|
if state.equal?(:ST_START)
|
||||||
cell.is_null = true
|
return :DT_EOS, idx, nil
|
||||||
elsif state.equal?(:ST_QUOTE)
|
|
||||||
true # dummy for coverate; only a data
|
|
||||||
elsif quoted
|
elsif quoted
|
||||||
raise IllegalFormatError.new
|
raise IllegalFormatError
|
||||||
elsif cr
|
elsif cr
|
||||||
raise IllegalFormatError.new
|
raise IllegalFormatError
|
||||||
end
|
end
|
||||||
return :DT_EOS, idx
|
cell << src[last_idx, (idx - last_idx)]
|
||||||
|
last_idx = idx
|
||||||
|
return :DT_EOS, idx, cell
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_body(cells, out_dev, col_sep, row_sep)
|
def generate_body(cell, out_dev, fs, rs)
|
||||||
row_data = cells.data.dup
|
if cell.nil?
|
||||||
if (!cells.is_null)
|
# empty
|
||||||
if (row_data.gsub!('"', '""') ||
|
else
|
||||||
row_data.include?(col_sep) ||
|
row_data = cell.dup
|
||||||
(row_sep && row_data.index(row_sep)) ||
|
if (row_data.gsub!('"', '""') or
|
||||||
(/[\r\n]/ =~ row_data) ||
|
row_data.index(fs) or
|
||||||
(cells.data.empty?))
|
(rs and row_data.index(rs)) or
|
||||||
|
(/[\r\n]/ =~ row_data) or
|
||||||
|
(cell.empty?))
|
||||||
out_dev << '"' << row_data << '"'
|
out_dev << '"' << row_data << '"'
|
||||||
else
|
else
|
||||||
out_dev << row_data
|
out_dev << row_data
|
||||||
|
@ -485,12 +453,12 @@ class CSV
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_separator(type, out_dev, col_sep, row_sep)
|
def generate_separator(type, out_dev, fs, rs)
|
||||||
case type
|
case type
|
||||||
when :DT_COLSEP
|
when :DT_COLSEP
|
||||||
out_dev << col_sep.chr
|
out_dev << fs
|
||||||
when :DT_ROWSEP
|
when :DT_ROWSEP
|
||||||
out_dev << (row_sep ? row_sep.chr : "\r\n")
|
out_dev << (rs || "\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -499,7 +467,7 @@ class CSV
|
||||||
# CSV formatted string/stream reader.
|
# CSV formatted string/stream reader.
|
||||||
#
|
#
|
||||||
# EXAMPLE
|
# EXAMPLE
|
||||||
# read CSV lines until the first column is 'stop'.
|
# read CSV lines untill the first column is 'stop'.
|
||||||
#
|
#
|
||||||
# CSV::Reader.parse(File.open('bigdata', 'rb')) do |row|
|
# CSV::Reader.parse(File.open('bigdata', 'rb')) do |row|
|
||||||
# p row
|
# p row
|
||||||
|
@ -511,8 +479,8 @@ class CSV
|
||||||
|
|
||||||
# Parse CSV data and get lines. Given block is called for each parsed row.
|
# Parse CSV data and get lines. Given block is called for each parsed row.
|
||||||
# Block value is always nil. Rows are not cached for performance reason.
|
# Block value is always nil. Rows are not cached for performance reason.
|
||||||
def Reader.parse(str_or_readable, col_sep = ?,, row_sep = nil)
|
def Reader.parse(str_or_readable, fs = ',', rs = nil)
|
||||||
reader = create(str_or_readable, col_sep, row_sep)
|
reader = create(str_or_readable, fs, rs)
|
||||||
reader.each do |row|
|
reader.each do |row|
|
||||||
yield(row)
|
yield(row)
|
||||||
end
|
end
|
||||||
|
@ -521,20 +489,20 @@ class CSV
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns reader instance.
|
# Returns reader instance.
|
||||||
def Reader.create(str_or_readable, col_sep = ?,, row_sep = nil)
|
def Reader.create(str_or_readable, fs = ',', rs = nil)
|
||||||
case str_or_readable
|
case str_or_readable
|
||||||
when IO
|
when IO
|
||||||
IOReader.new(str_or_readable, col_sep, row_sep)
|
IOReader.new(str_or_readable, fs, rs)
|
||||||
when String
|
when String
|
||||||
StringReader.new(str_or_readable, col_sep, row_sep)
|
StringReader.new(str_or_readable, fs, rs)
|
||||||
else
|
else
|
||||||
IOReader.new(str_or_readable, col_sep, row_sep)
|
IOReader.new(str_or_readable, fs, rs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def each
|
def each
|
||||||
while true
|
while true
|
||||||
row = Row.new
|
row = []
|
||||||
parsed_cells = get_row(row)
|
parsed_cells = get_row(row)
|
||||||
if parsed_cells == 0
|
if parsed_cells == 0
|
||||||
break
|
break
|
||||||
|
@ -545,7 +513,7 @@ class CSV
|
||||||
end
|
end
|
||||||
|
|
||||||
def shift
|
def shift
|
||||||
row = Row.new
|
row = []
|
||||||
parsed_cells = get_row(row)
|
parsed_cells = get_row(row)
|
||||||
row
|
row
|
||||||
end
|
end
|
||||||
|
@ -557,12 +525,11 @@ class CSV
|
||||||
private
|
private
|
||||||
|
|
||||||
def initialize(dev)
|
def initialize(dev)
|
||||||
raise RuntimeError.new('do not instantiate this class directly')
|
raise RuntimeError.new('Do not instanciate this class directly.')
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_row(row)
|
def get_row(row)
|
||||||
raise NotImplementedError.new(
|
raise NotImplementedError.new('Method get_row must be defined in a derived class.')
|
||||||
'method get_row must be defined in a derived class')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def terminate
|
def terminate
|
||||||
|
@ -572,10 +539,9 @@ class CSV
|
||||||
|
|
||||||
|
|
||||||
class StringReader < Reader
|
class StringReader < Reader
|
||||||
|
def initialize(string, fs = ',', rs = nil)
|
||||||
def initialize(string, col_sep = ?,, row_sep = nil)
|
@fs = fs
|
||||||
@col_sep = col_sep
|
@rs = rs
|
||||||
@row_sep = row_sep
|
|
||||||
@dev = string
|
@dev = string
|
||||||
@idx = 0
|
@idx = 0
|
||||||
if @dev[0, 3] == "\xef\xbb\xbf"
|
if @dev[0, 3] == "\xef\xbb\xbf"
|
||||||
|
@ -586,9 +552,8 @@ class CSV
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_row(row)
|
def get_row(row)
|
||||||
parsed_cells, next_idx =
|
parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs)
|
||||||
CSV.parse_row(@dev, @idx, row, @col_sep, @row_sep)
|
if parsed_cells == 0 and next_idx == 0 and @idx != @dev.size
|
||||||
if parsed_cells == 0 && next_idx == 0 && @idx != @dev.size
|
|
||||||
raise IllegalFormatError.new
|
raise IllegalFormatError.new
|
||||||
end
|
end
|
||||||
@idx = next_idx
|
@idx = next_idx
|
||||||
|
@ -598,12 +563,10 @@ class CSV
|
||||||
|
|
||||||
|
|
||||||
class IOReader < Reader
|
class IOReader < Reader
|
||||||
|
def initialize(io, fs = ',', rs = nil)
|
||||||
def initialize(io, col_sep = ?,, row_sep = nil)
|
|
||||||
@io = io
|
@io = io
|
||||||
@io.binmode if @io.respond_to?(:binmode)
|
@fs = fs
|
||||||
@col_sep = col_sep
|
@rs = rs
|
||||||
@row_sep = row_sep
|
|
||||||
@dev = CSV::IOBuf.new(@io)
|
@dev = CSV::IOBuf.new(@io)
|
||||||
@idx = 0
|
@idx = 0
|
||||||
if @dev[0] == 0xef and @dev[1] == 0xbb and @dev[2] == 0xbf
|
if @dev[0] == 0xef and @dev[1] == 0xbb and @dev[2] == 0xbf
|
||||||
|
@ -621,9 +584,8 @@ class CSV
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_row(row)
|
def get_row(row)
|
||||||
parsed_cells, next_idx =
|
parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs)
|
||||||
CSV.parse_row(@dev, @idx, row, @col_sep, @row_sep)
|
if parsed_cells == 0 and next_idx == 0 and !@dev.is_eos?
|
||||||
if parsed_cells == 0 && next_idx == 0 && !@dev.is_eos?
|
|
||||||
raise IllegalFormatError.new
|
raise IllegalFormatError.new
|
||||||
end
|
end
|
||||||
dropped = @dev.drop(next_idx)
|
dropped = @dev.drop(next_idx)
|
||||||
|
@ -667,40 +629,25 @@ class CSV
|
||||||
# outfile.close
|
# outfile.close
|
||||||
#
|
#
|
||||||
class Writer
|
class Writer
|
||||||
|
|
||||||
# Generate CSV. Given block is called with the writer instance.
|
# Generate CSV. Given block is called with the writer instance.
|
||||||
def Writer.generate(str_or_writable, col_sep = ?,, row_sep = nil)
|
def Writer.generate(str_or_writable, fs = ',', rs = nil)
|
||||||
writer = Writer.create(str_or_writable, col_sep, row_sep)
|
writer = Writer.create(str_or_writable, fs, rs)
|
||||||
yield(writer)
|
yield(writer)
|
||||||
writer.close
|
writer.close
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# str_or_writable must handle '<<(string)'.
|
# str_or_writable must handle '<<(string)'.
|
||||||
def Writer.create(str_or_writable, col_sep = ?,, row_sep = nil)
|
def Writer.create(str_or_writable, fs = ',', rs = nil)
|
||||||
BasicWriter.new(str_or_writable, col_sep, row_sep)
|
BasicWriter.new(str_or_writable, fs, rs)
|
||||||
end
|
end
|
||||||
|
|
||||||
# dump CSV stream to the device. argument must be an Array of String.
|
# dump CSV stream to the device. argument must be an Array of String.
|
||||||
def <<(ary)
|
def <<(row)
|
||||||
row = ary.collect { |item|
|
CSV.generate_row(row, row.size, @dev, @fs, @rs)
|
||||||
if item.is_a?(Cell)
|
|
||||||
item
|
|
||||||
elsif (item.nil?)
|
|
||||||
Cell.new('', true)
|
|
||||||
else
|
|
||||||
Cell.new(item.to_s, false)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
CSV.generate_row(row, row.size, @dev, @col_sep, @row_sep)
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
# dump CSV stream to the device. argument must be an Array of CSV::Cell.
|
|
||||||
def add_row(row)
|
|
||||||
CSV.generate_row(row, row.size, @dev, @col_sep, @row_sep)
|
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
alias add_row <<
|
||||||
|
|
||||||
def close
|
def close
|
||||||
terminate
|
terminate
|
||||||
|
@ -709,7 +656,7 @@ class CSV
|
||||||
private
|
private
|
||||||
|
|
||||||
def initialize(dev)
|
def initialize(dev)
|
||||||
raise RuntimeError.new('do not instantiate this class directly')
|
raise RuntimeError.new('Do not instanciate this class directly.')
|
||||||
end
|
end
|
||||||
|
|
||||||
def terminate
|
def terminate
|
||||||
|
@ -719,12 +666,10 @@ class CSV
|
||||||
|
|
||||||
|
|
||||||
class BasicWriter < Writer
|
class BasicWriter < Writer
|
||||||
|
def initialize(str_or_writable, fs = ',', rs = nil)
|
||||||
def initialize(str_or_writable, col_sep = ?,, row_sep = nil)
|
@fs = fs
|
||||||
@col_sep = col_sep
|
@rs = rs
|
||||||
@row_sep = row_sep
|
|
||||||
@dev = str_or_writable
|
@dev = str_or_writable
|
||||||
@dev.binmode if @dev.respond_to?(:binmode)
|
|
||||||
@close_on_terminate = false
|
@close_on_terminate = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -743,6 +688,7 @@ class CSV
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
# Buffered stream.
|
# Buffered stream.
|
||||||
#
|
#
|
||||||
|
@ -756,7 +702,7 @@ class CSV
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# # define my own 'read' method.
|
# # define my own 'read' method.
|
||||||
# # CAUTION: Returning nil means EndOfStream.
|
# # CAUTION: Returning nil means EnfOfStream.
|
||||||
# def read(size)
|
# def read(size)
|
||||||
# @s.read(size)
|
# @s.read(size)
|
||||||
# end
|
# end
|
||||||
|
@ -801,8 +747,7 @@ class CSV
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
class StreamBuf # pure virtual. (do not instantiate it directly)
|
class StreamBuf
|
||||||
|
|
||||||
# get a char or a partial string from the stream.
|
# get a char or a partial string from the stream.
|
||||||
# idx: index of a string to specify a start point of a string to get.
|
# idx: index of a string to specify a start point of a string to get.
|
||||||
# unlike String instance, idx < 0 returns nil.
|
# unlike String instance, idx < 0 returns nil.
|
||||||
|
@ -867,7 +812,7 @@ class CSV
|
||||||
end
|
end
|
||||||
size_dropped = 0
|
size_dropped = 0
|
||||||
while (n > 0)
|
while (n > 0)
|
||||||
if (!@is_eos || (@cur_buf != @buf_tail_idx))
|
if !@is_eos or (@cur_buf != @buf_tail_idx)
|
||||||
if (@offset + n < buf_size(@cur_buf))
|
if (@offset + n < buf_size(@cur_buf))
|
||||||
size_dropped += n
|
size_dropped += n
|
||||||
@offset += n
|
@offset += n
|
||||||
|
@ -912,11 +857,10 @@ class CSV
|
||||||
|
|
||||||
# protected method 'read' must be defined in derived classes.
|
# protected method 'read' must be defined in derived classes.
|
||||||
# CAUTION: Returning a string which size is not equal to 'size' means
|
# CAUTION: Returning a string which size is not equal to 'size' means
|
||||||
# EndOfStream. When it is not at EOS, you must block the callee, try to
|
# EnfOfStream. When it is not at EOS, you must block the callee, try to
|
||||||
# read and return the sized string.
|
# read and return the sized string.
|
||||||
def read(size) # raise EOFError
|
def read(size) # raise EOFError
|
||||||
raise NotImplementedError.new(
|
raise NotImplementedError.new('Method read must be defined in a derived class.')
|
||||||
'method read must be defined in a derived class')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -964,13 +908,12 @@ class CSV
|
||||||
end
|
end
|
||||||
|
|
||||||
def idx_is_eos?(idx)
|
def idx_is_eos?(idx)
|
||||||
(@is_eos && ((@cur_buf < 0) || (@cur_buf == @buf_tail_idx)))
|
(@is_eos and ((@cur_buf < 0) or (@cur_buf == @buf_tail_idx)))
|
||||||
end
|
end
|
||||||
|
|
||||||
BufSize = 1024 * 8
|
BufSize = 1024 * 8
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Buffered IO.
|
# Buffered IO.
|
||||||
#
|
#
|
||||||
# EXAMPLE
|
# EXAMPLE
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
require 'test/unit/testsuite'
|
require 'test/unit'
|
||||||
require 'test/unit/testcase'
|
|
||||||
require 'tempfile'
|
require 'tempfile'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
|
|
||||||
|
@ -15,174 +14,20 @@ end
|
||||||
|
|
||||||
|
|
||||||
module CSVTestSupport
|
module CSVTestSupport
|
||||||
def d(data, is_null = false)
|
def d(data)
|
||||||
CSV::Cell.new(data.to_s, is_null)
|
data
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
class TestCSVCell < Test::Unit::TestCase
|
|
||||||
@@colData = ['', nil, true, false, 'foo', '!' * 1000]
|
|
||||||
|
|
||||||
def test_Cell_EQUAL # '=='
|
|
||||||
d1 = CSV::Cell.new('d', false)
|
|
||||||
d2 = CSV::Cell.new('d', false)
|
|
||||||
d3 = CSV::Cell.new('d', true)
|
|
||||||
d4 = CSV::Cell.new('d', true)
|
|
||||||
assert(d1 == d2, "Normal case.")
|
|
||||||
assert(d1 != d3, "RHS is null.")
|
|
||||||
assert(d4 != d1, "LHS is null.")
|
|
||||||
assert(d3 != d4, "Either is null.")
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_Cell_match
|
|
||||||
d1 = CSV::Cell.new('d', false)
|
|
||||||
d2 = CSV::Cell.new('d', false)
|
|
||||||
d3 = CSV::Cell.new('d', true)
|
|
||||||
d4 = CSV::Cell.new('d', true)
|
|
||||||
assert(d1.match(d2), "Normal case.")
|
|
||||||
assert(!d1.match(d3), "RHS is null.")
|
|
||||||
assert(!d4.match(d1), "LHS is null.")
|
|
||||||
assert(d3.match(d4), "Either is null.")
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_Cell_data
|
|
||||||
d = CSV::Cell.new()
|
|
||||||
@@colData.each do |v|
|
|
||||||
d.data = v
|
|
||||||
assert_equal(d.data, v, "Case: #{ v }.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_Cell_data=
|
|
||||||
d = CSV::Cell.new()
|
|
||||||
@@colData.each do |v|
|
|
||||||
d.data = v
|
|
||||||
assert_equal(d.data, v, "Case: #{ v }.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_Cell_is_null
|
|
||||||
d = CSV::Cell.new()
|
|
||||||
d.is_null = true
|
|
||||||
assert_equal(d.is_null, true, "Case: true.")
|
|
||||||
d.is_null = false
|
|
||||||
assert_equal(d.is_null, false, "Case: false.")
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_Cell_is_null=
|
|
||||||
d = CSV::Cell.new()
|
|
||||||
d.is_null = true
|
|
||||||
assert_equal(d.is_null, true, "Case: true.")
|
|
||||||
d.is_null = false
|
|
||||||
assert_equal(d.is_null, false, "Case: false.")
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_Cell_s_new
|
|
||||||
d1 = CSV::Cell.new()
|
|
||||||
assert_equal(d1.data, '', "Default: data.")
|
|
||||||
assert_equal(d1.is_null, true, "Default: is_null.")
|
|
||||||
|
|
||||||
@@colData.each do |v|
|
|
||||||
d = CSV::Cell.new(v)
|
|
||||||
assert_equal(d.data, v, "Data: #{ v }.")
|
|
||||||
end
|
|
||||||
|
|
||||||
d2 = CSV::Cell.new(nil, true)
|
|
||||||
assert_equal(d2.is_null, true, "Data: true.")
|
|
||||||
d3 = CSV::Cell.new(nil, false)
|
|
||||||
assert_equal(d3.is_null, false, "Data: false.")
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_to_str
|
|
||||||
d = CSV::Cell.new("foo", false)
|
|
||||||
assert_equal("foo", d.to_str)
|
|
||||||
assert(/foo/ =~ d)
|
|
||||||
d = CSV::Cell.new("foo", true)
|
|
||||||
begin
|
|
||||||
d.to_str
|
|
||||||
assert(false)
|
|
||||||
rescue
|
|
||||||
# NoMethodError or NameError
|
|
||||||
assert(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_to_s
|
|
||||||
d = CSV::Cell.new("foo", false)
|
|
||||||
assert_equal("foo", d.to_s)
|
|
||||||
assert_equal("foo", "#{d}")
|
|
||||||
d = CSV::Cell.new("foo", true)
|
|
||||||
assert_equal("", d.to_s)
|
|
||||||
assert_equal("", "#{d}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
class TestCSVRow < Test::Unit::TestCase
|
|
||||||
include CSVTestSupport
|
|
||||||
|
|
||||||
def test_Row_s_match
|
|
||||||
c1 = CSV::Row[d(1), d(2), d(3)]
|
|
||||||
c2 = CSV::Row[d(1, false), d(2, false), d(3, false)]
|
|
||||||
assert(c1.match(c2), "Normal case.")
|
|
||||||
|
|
||||||
c1 = CSV::Row[d(1), d('foo', true), d(3)]
|
|
||||||
c2 = CSV::Row[d(1, false), d('bar', true), d(3, false)]
|
|
||||||
assert(c1.match(c2), "Either is null.")
|
|
||||||
|
|
||||||
c1 = CSV::Row[d(1), d('foo', true), d(3)]
|
|
||||||
c2 = CSV::Row[d(1, false), d('bar', false), d(3, false)]
|
|
||||||
assert(!c1.match(c2), "LHS is null.")
|
|
||||||
|
|
||||||
c1 = CSV::Row[d(1), d('foo'), d(3)]
|
|
||||||
c2 = CSV::Row[d(1, false), d('bar', true), d(3, false)]
|
|
||||||
assert(!c1.match(c2), "RHS is null.")
|
|
||||||
|
|
||||||
c1 = CSV::Row[d(1), d('', true), d(3)]
|
|
||||||
c2 = CSV::Row[d(1, false), d('', true), d(3, false)]
|
|
||||||
assert(c1.match(c2), "Either is null(empty data).")
|
|
||||||
|
|
||||||
c1 = CSV::Row[d(1), d('', true), d(3)]
|
|
||||||
c2 = CSV::Row[d(1, false), d('', false), d(3, false)]
|
|
||||||
assert(!c1.match(c2), "LHS is null(empty data).")
|
|
||||||
|
|
||||||
c1 = CSV::Row[d(1), d(''), d(3)]
|
|
||||||
c2 = CSV::Row[d(1, false), d('', true), d(3, false)]
|
|
||||||
assert(!c1.match(c2), "RHS is null(empty data).")
|
|
||||||
|
|
||||||
c1 = CSV::Row[]
|
|
||||||
c2 = CSV::Row[]
|
|
||||||
assert(c1.match(c2))
|
|
||||||
|
|
||||||
c1 = CSV::Row[]
|
|
||||||
c2 = CSV::Row[d(1)]
|
|
||||||
assert(!c1.match(c2))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_Row_to_a
|
|
||||||
r = CSV::Row[d(1), d(2), d(3)]
|
|
||||||
assert_equal(['1', '2', '3'], r.to_a, 'Normal case')
|
|
||||||
|
|
||||||
r = CSV::Row[d(1)]
|
|
||||||
assert_equal(['1'], r.to_a, '1 item')
|
|
||||||
|
|
||||||
r = CSV::Row[d(nil, true), d(2), d(3)]
|
|
||||||
assert_equal([nil, '2', '3'], r.to_a, 'Null in data')
|
|
||||||
|
|
||||||
r = CSV::Row[d(nil, true), d(nil, true), d(nil, true)]
|
|
||||||
assert_equal([nil, nil, nil], r.to_a, 'Nulls')
|
|
||||||
|
|
||||||
r = CSV::Row[d(nil, true)]
|
|
||||||
assert_equal([nil], r.to_a, '1 Null')
|
|
||||||
|
|
||||||
r = CSV::Row[]
|
|
||||||
assert_equal([], r.to_a, 'Empty')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
class TestCSV < Test::Unit::TestCase
|
class TestCSV < Test::Unit::TestCase
|
||||||
|
file = Tempfile.new("crlf")
|
||||||
|
file << "\n"
|
||||||
|
file.open
|
||||||
|
file.binmode
|
||||||
|
RSEP = file.read
|
||||||
|
file.close
|
||||||
|
|
||||||
include CSVTestSupport
|
include CSVTestSupport
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
@ -221,17 +66,17 @@ class TestCSV < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
@@fullCSVData = {
|
@@fullCSVData = {
|
||||||
[d('', true)] => '',
|
[d(nil)] => '',
|
||||||
[d('')] => '""',
|
[d('')] => '""',
|
||||||
[d('', true), d('', true)] => ',',
|
[d(nil), d(nil)] => ',',
|
||||||
[d('', true), d('', true), d('', true)] => ',,',
|
[d(nil), d(nil), d(nil)] => ',,',
|
||||||
[d('foo')] => 'foo',
|
[d('foo')] => 'foo',
|
||||||
[d('foo'), d('bar')] => 'foo,bar',
|
[d('foo'), d('bar')] => 'foo,bar',
|
||||||
[d('foo'), d('"bar"'), d('baz')] => 'foo,"""bar""",baz',
|
[d('foo'), d('"bar"'), d('baz')] => 'foo,"""bar""",baz',
|
||||||
[d('foo'), d('foo,bar'), d('baz')] => 'foo,"foo,bar",baz',
|
[d('foo'), d('foo,bar'), d('baz')] => 'foo,"foo,bar",baz',
|
||||||
[d('foo'), d('""'), d('baz')] => 'foo,"""""",baz',
|
[d('foo'), d('""'), d('baz')] => 'foo,"""""",baz',
|
||||||
[d('foo'), d(''), d('baz')] => 'foo,"",baz',
|
[d('foo'), d(''), d('baz')] => 'foo,"",baz',
|
||||||
[d('foo'), d('', true), d('baz')] => 'foo,,baz',
|
[d('foo'), d(nil), d('baz')] => 'foo,,baz',
|
||||||
[d('foo'), d("\r"), d('baz')] => "foo,\"\r\",baz",
|
[d('foo'), d("\r"), d('baz')] => "foo,\"\r\",baz",
|
||||||
[d('foo'), d("\n"), d('baz')] => "foo,\"\n\",baz",
|
[d('foo'), d("\n"), d('baz')] => "foo,\"\n\",baz",
|
||||||
[d('foo'), d("\r\n"), d('baz')] => "foo,\"\r\n\",baz",
|
[d('foo'), d("\r\n"), d('baz')] => "foo,\"\r\n\",baz",
|
||||||
|
@ -259,7 +104,7 @@ class TestCSV < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def sepConv(srcStr, srcSep, destSep, row_sep = nil)
|
def sepConv(srcStr, srcSep, destSep, row_sep = nil)
|
||||||
rows = CSV::Row.new
|
rows = []
|
||||||
cols, idx = CSV.parse_row(srcStr, 0, rows, srcSep, row_sep)
|
cols, idx = CSV.parse_row(srcStr, 0, rows, srcSep, row_sep)
|
||||||
destStr = ''
|
destStr = ''
|
||||||
cols = CSV.generate_row(rows, rows.size, destStr, destSep, row_sep)
|
cols = CSV.generate_row(rows, rows.size, destStr, destSep, row_sep)
|
||||||
|
@ -278,13 +123,13 @@ public
|
||||||
@bomfile = File.join(@tmpdir, "bom.csv")
|
@bomfile = File.join(@tmpdir, "bom.csv")
|
||||||
@macfile = File.join(@tmpdir, "mac.csv")
|
@macfile = File.join(@tmpdir, "mac.csv")
|
||||||
|
|
||||||
CSV.open(@infile, "w") do |writer|
|
CSV.open(@infile, "wb") do |writer|
|
||||||
@@fullCSVDataArray.each do |row|
|
@@fullCSVDataArray.each do |row|
|
||||||
writer.add_row(row)
|
writer.add_row(row)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
CSV.open(@infiletsv, "w", ?\t) do |writer|
|
CSV.open(@infiletsv, "wb", ?\t) do |writer|
|
||||||
@@fullCSVDataArray.each do |row|
|
@@fullCSVDataArray.each do |row|
|
||||||
writer.add_row(row)
|
writer.add_row(row)
|
||||||
end
|
end
|
||||||
|
@ -317,11 +162,11 @@ public
|
||||||
first = true
|
first = true
|
||||||
ret = reader.each { |row|
|
ret = reader.each { |row|
|
||||||
if first
|
if first
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
first = false
|
first = false
|
||||||
end
|
end
|
||||||
expected = expectedArray.shift
|
expected = expectedArray.shift
|
||||||
assert(row.match(expected))
|
assert_equal(expected, row)
|
||||||
}
|
}
|
||||||
assert_nil(ret, "Return is nil")
|
assert_nil(ret, "Return is nil")
|
||||||
assert(expectedArray.empty?)
|
assert(expectedArray.empty?)
|
||||||
|
@ -352,10 +197,10 @@ public
|
||||||
@@fullCSVDataArray.each do |expected|
|
@@fullCSVDataArray.each do |expected|
|
||||||
actual = reader.shift
|
actual = reader.shift
|
||||||
if first
|
if first
|
||||||
assert_instance_of(CSV::Row, actual)
|
assert_instance_of(Array, actual)
|
||||||
first = false
|
first = false
|
||||||
end
|
end
|
||||||
assert(actual.match(expected))
|
assert_equal(expected, actual)
|
||||||
checked += 1
|
checked += 1
|
||||||
end
|
end
|
||||||
assert(checked == @@fullCSVDataArray.size)
|
assert(checked == @@fullCSVDataArray.size)
|
||||||
|
@ -445,7 +290,7 @@ public
|
||||||
file << "\"\r\n\",\"\r\",\"\n\"\r1,2,3"
|
file << "\"\r\n\",\"\r\",\"\n\"\r1,2,3"
|
||||||
file.close
|
file.close
|
||||||
|
|
||||||
file = File.open(@outfile, "r") # not "rb"
|
file = File.open(@outfile, "rb")
|
||||||
begin
|
begin
|
||||||
reader = CSV::IOReader.new(file, ?,, ?\r)
|
reader = CSV::IOReader.new(file, ?,, ?\r)
|
||||||
assert_equal(["\r\n", "\r", "\n"], reader.shift.to_a)
|
assert_equal(["\r\n", "\r", "\n"], reader.shift.to_a)
|
||||||
|
@ -454,23 +299,34 @@ public
|
||||||
ensure
|
ensure
|
||||||
file.close
|
file.close
|
||||||
end
|
end
|
||||||
|
|
||||||
|
file = File.open(@outfile, "r") # not "rb"
|
||||||
|
begin
|
||||||
|
lfincell = (RSEP == "\n" ? "\r\n" : "\n")
|
||||||
|
reader = CSV::IOReader.new(file, ?,, ?\r)
|
||||||
|
assert_equal([lfincell, "\r", "\n"], reader.shift.to_a)
|
||||||
|
assert_equal(["1", "2", "3"], reader.shift.to_a)
|
||||||
|
reader.close
|
||||||
|
ensure
|
||||||
|
file.close
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_Reader_s_parse
|
def test_Reader_s_parse
|
||||||
ret = CSV::Reader.parse("a,b,c") { |row|
|
ret = CSV::Reader.parse("a,b,c") { |row|
|
||||||
assert_instance_of(CSV::Row, row, "Block parameter")
|
assert_instance_of(Array, row, "Block parameter")
|
||||||
}
|
}
|
||||||
assert_nil(ret, "Return is nil")
|
assert_nil(ret, "Return is nil")
|
||||||
|
|
||||||
ret = CSV::Reader.parse("a;b;c", ?;) { |row|
|
ret = CSV::Reader.parse("a;b;c", ?;) { |row|
|
||||||
assert_instance_of(CSV::Row, row, "Block parameter")
|
assert_instance_of(Array, row, "Block parameter")
|
||||||
}
|
}
|
||||||
|
|
||||||
file = Tempfile.new("in.csv")
|
file = Tempfile.new("in.csv")
|
||||||
file << "a,b,c"
|
file << "a,b,c"
|
||||||
file.open
|
file.open
|
||||||
ret = CSV::Reader.parse(file) { |row|
|
ret = CSV::Reader.parse(file) { |row|
|
||||||
assert_instance_of(CSV::Row, row, "Block parameter")
|
assert_instance_of(Array, row, "Block parameter")
|
||||||
}
|
}
|
||||||
assert_nil(ret, "Return is nil")
|
assert_nil(ret, "Return is nil")
|
||||||
|
|
||||||
|
@ -478,7 +334,7 @@ public
|
||||||
file << "a,b,c"
|
file << "a,b,c"
|
||||||
file.open
|
file.open
|
||||||
ret = CSV::Reader.parse(file, ?,) { |row|
|
ret = CSV::Reader.parse(file, ?,) { |row|
|
||||||
assert_instance_of(CSV::Row, row, "Block parameter")
|
assert_instance_of(Array, row, "Block parameter")
|
||||||
}
|
}
|
||||||
|
|
||||||
# Illegal format.
|
# Illegal format.
|
||||||
|
@ -536,38 +392,38 @@ public
|
||||||
file.open
|
file.open
|
||||||
file.binmode
|
file.binmode
|
||||||
str = file.read
|
str = file.read
|
||||||
assert_equal("a,b,c\r\n,e,f\r\n,,\"\"\r\n", str, 'Normal')
|
assert_equal("a,b,c#{RSEP},e,f#{RSEP},,\"\"#{RSEP}", str, 'Normal')
|
||||||
|
|
||||||
file = Tempfile.new("out2.csv")
|
file = Tempfile.new("out2.csv")
|
||||||
CSV::Writer.generate(file) do |writer|
|
CSV::Writer.generate(file) do |writer|
|
||||||
ret = writer << [d('a'), d('b'), d('c')]
|
ret = writer << [d('a'), d('b'), d('c')]
|
||||||
assert_instance_of(CSV::BasicWriter, ret, 'Return is self')
|
assert_instance_of(CSV::BasicWriter, ret, 'Return is self')
|
||||||
|
|
||||||
writer << [d(nil, true), d('e'), d('f')] << [d(nil, true), d(nil, true), d('')]
|
writer << [d(nil), d('e'), d('f')] << [d(nil), d(nil), d('')]
|
||||||
end
|
end
|
||||||
file.open
|
file.open
|
||||||
file.binmode
|
file.binmode
|
||||||
str = file.read
|
str = file.read
|
||||||
assert_equal("a,b,c\r\n,e,f\r\n,,\"\"\r\n", str, 'Normal')
|
assert_equal("a,b,c#{RSEP},e,f#{RSEP},,\"\"#{RSEP}", str, 'Normal')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_Writer_add_row
|
def test_Writer_add_row
|
||||||
file = Tempfile.new("out.csv")
|
file = Tempfile.new("out.csv")
|
||||||
CSV::Writer.generate(file) do |writer|
|
CSV::Writer.generate(file) do |writer|
|
||||||
ret = writer.add_row(
|
ret = writer.add_row(
|
||||||
[d('a', false), d('b', false), d('c', false)])
|
[d('a'), d('b'), d('c')])
|
||||||
assert_instance_of(CSV::BasicWriter, ret, 'Return is self')
|
assert_instance_of(CSV::BasicWriter, ret, 'Return is self')
|
||||||
|
|
||||||
writer.add_row(
|
writer.add_row(
|
||||||
[d('dummy', true), d('e', false), d('f', false)]
|
[d(nil), d('e'), d('f')]
|
||||||
).add_row(
|
).add_row(
|
||||||
[d('a', true), d('b', true), d('', false)]
|
[d(nil), d(nil), d('')]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
file.open
|
file.open
|
||||||
file.binmode
|
file.binmode
|
||||||
str = file.read
|
str = file.read
|
||||||
assert_equal("a,b,c\r\n,e,f\r\n,,\"\"\r\n", str, 'Normal')
|
assert_equal("a,b,c#{RSEP},e,f#{RSEP},,\"\"#{RSEP}", str, 'Normal')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_Writer_close
|
def test_Writer_close
|
||||||
|
@ -606,7 +462,7 @@ public
|
||||||
file = File.open(@outfile, "rb")
|
file = File.open(@outfile, "rb")
|
||||||
str = file.read
|
str = file.read
|
||||||
file.close
|
file.close
|
||||||
assert_equal("\"\r\n\",\"\r\",\"\n\"\r1,2,3\r", str)
|
assert_equal("\"\r#{RSEP}\",\"\r\",\"#{RSEP}\"\r1,2,3\r", str)
|
||||||
end
|
end
|
||||||
|
|
||||||
#### CSV unit test
|
#### CSV unit test
|
||||||
|
@ -633,12 +489,12 @@ public
|
||||||
reader.close
|
reader.close
|
||||||
|
|
||||||
CSV.open(@infile, "r") do |row|
|
CSV.open(@infile, "r") do |row|
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
CSV.open(@infiletsv, "r", ?\t) do |row|
|
CSV.open(@infiletsv, "r", ?\t) do |row|
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -686,12 +542,12 @@ public
|
||||||
reader.close
|
reader.close
|
||||||
|
|
||||||
CSV.parse(@infile) do |row|
|
CSV.parse(@infile) do |row|
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
CSV.parse(@infiletsv, ?\t) do |row|
|
CSV.parse(@infiletsv, ?\t) do |row|
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -776,12 +632,12 @@ public
|
||||||
|
|
||||||
@@simpleCSVData.each do |col, str|
|
@@simpleCSVData.each do |col, str|
|
||||||
buf = CSV.generate_line(col, ?;)
|
buf = CSV.generate_line(col, ?;)
|
||||||
assert_equal(str + "\r\n", ssv2csv(buf))
|
assert_equal(str + "\n", ssv2csv(buf))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@simpleCSVData.each do |col, str|
|
@@simpleCSVData.each do |col, str|
|
||||||
buf = CSV.generate_line(col, ?\t)
|
buf = CSV.generate_line(col, ?\t)
|
||||||
assert_equal(str + "\r\n", tsv2csv(buf))
|
assert_equal(str + "\n", tsv2csv(buf))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -789,17 +645,17 @@ public
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([], 0, buf)
|
cols = CSV.generate_row([], 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal("\r\n", buf, "Extra boundary check.")
|
assert_equal("\n", buf, "Extra boundary check.")
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([], 0, buf, ?;)
|
cols = CSV.generate_row([], 0, buf, ?;)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal("\r\n", buf, "Extra boundary check.")
|
assert_equal("\n", buf, "Extra boundary check.")
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([], 0, buf, ?\t)
|
cols = CSV.generate_row([], 0, buf, ?\t)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal("\r\n", buf, "Extra boundary check.")
|
assert_equal("\n", buf, "Extra boundary check.")
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([], 0, buf, ?\t, ?|)
|
cols = CSV.generate_row([], 0, buf, ?\t, ?|)
|
||||||
|
@ -807,64 +663,64 @@ public
|
||||||
assert_equal("|", buf, "Extra boundary check.")
|
assert_equal("|", buf, "Extra boundary check.")
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([d(1)], 2, buf)
|
cols = CSV.generate_row([d('1')], 2, buf)
|
||||||
assert_equal('1,', buf)
|
assert_equal('1,', buf)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([d(1)], 2, buf, ?;)
|
cols = CSV.generate_row([d('1')], 2, buf, ?;)
|
||||||
assert_equal('1;', buf)
|
assert_equal('1;', buf)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([d(1)], 2, buf, ?\t)
|
cols = CSV.generate_row([d('1')], 2, buf, ?\t)
|
||||||
assert_equal("1\t", buf)
|
assert_equal("1\t", buf)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([d(1)], 2, buf, ?\t, ?|)
|
cols = CSV.generate_row([d('1')], 2, buf, ?\t, ?|)
|
||||||
assert_equal("1\t", buf)
|
assert_equal("1\t", buf)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([d(1), d(2)], 1, buf)
|
cols = CSV.generate_row([d('1'), d('2')], 1, buf)
|
||||||
assert_equal("1\r\n", buf)
|
|
||||||
|
|
||||||
buf = ''
|
|
||||||
cols = CSV.generate_row([d(1), d(2)], 1, buf, ?;)
|
|
||||||
assert_equal("1\r\n", buf)
|
|
||||||
|
|
||||||
buf = ''
|
|
||||||
cols = CSV.generate_row([d(1), d(2)], 1, buf, ?\t)
|
|
||||||
assert_equal("1\r\n", buf)
|
|
||||||
|
|
||||||
buf = ''
|
|
||||||
cols = CSV.generate_row([d(1), d(2)], 1, buf, ?\t, ?\n)
|
|
||||||
assert_equal("1\n", buf)
|
assert_equal("1\n", buf)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([d(1), d(2)], 1, buf, ?\t, ?\r)
|
cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?;)
|
||||||
|
assert_equal("1\n", buf)
|
||||||
|
|
||||||
|
buf = ''
|
||||||
|
cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\t)
|
||||||
|
assert_equal("1\n", buf)
|
||||||
|
|
||||||
|
buf = ''
|
||||||
|
cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\t, ?\n)
|
||||||
|
assert_equal("1\n", buf)
|
||||||
|
|
||||||
|
buf = ''
|
||||||
|
cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\t, ?\r)
|
||||||
assert_equal("1\r", buf)
|
assert_equal("1\r", buf)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row([d(1), d(2)], 1, buf, ?\t, ?|)
|
cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\t, ?|)
|
||||||
assert_equal("1|", buf)
|
assert_equal("1|", buf)
|
||||||
|
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row(col, col.size, buf)
|
cols = CSV.generate_row(col, col.size, buf)
|
||||||
assert_equal(col.size, cols)
|
assert_equal(col.size, cols)
|
||||||
assert_equal(str + "\r\n", buf)
|
assert_equal(str + "\n", buf)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row(col, col.size, buf, ?;)
|
cols = CSV.generate_row(col, col.size, buf, ?;)
|
||||||
assert_equal(col.size, cols)
|
assert_equal(col.size, cols)
|
||||||
assert_equal(str + "\r\n", ssv2csv(buf))
|
assert_equal(str + "\n", ssv2csv(buf))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
buf = ''
|
buf = ''
|
||||||
cols = CSV.generate_row(col, col.size, buf, ?\t)
|
cols = CSV.generate_row(col, col.size, buf, ?\t)
|
||||||
assert_equal(col.size, cols)
|
assert_equal(col.size, cols)
|
||||||
assert_equal(str + "\r\n", tsv2csv(buf))
|
assert_equal(str + "\n", tsv2csv(buf))
|
||||||
end
|
end
|
||||||
|
|
||||||
# row separator
|
# row separator
|
||||||
|
@ -889,7 +745,7 @@ public
|
||||||
colsToBe = 0
|
colsToBe = 0
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
cols += CSV.generate_row(col, col.size, buf)
|
cols += CSV.generate_row(col, col.size, buf)
|
||||||
toBe << str << "\r\n"
|
toBe << str << "\n"
|
||||||
colsToBe += col.size
|
colsToBe += col.size
|
||||||
end
|
end
|
||||||
assert_equal(colsToBe, cols)
|
assert_equal(colsToBe, cols)
|
||||||
|
@ -902,8 +758,8 @@ public
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
lineBuf = ''
|
lineBuf = ''
|
||||||
cols += CSV.generate_row(col, col.size, lineBuf, ?;)
|
cols += CSV.generate_row(col, col.size, lineBuf, ?;)
|
||||||
buf << ssv2csv(lineBuf) << "\r\n"
|
buf << ssv2csv(lineBuf) << "\n"
|
||||||
toBe << ssv2csv(lineBuf) << "\r\n"
|
toBe << ssv2csv(lineBuf) << "\n"
|
||||||
colsToBe += col.size
|
colsToBe += col.size
|
||||||
end
|
end
|
||||||
assert_equal(colsToBe, cols)
|
assert_equal(colsToBe, cols)
|
||||||
|
@ -916,8 +772,8 @@ public
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
lineBuf = ''
|
lineBuf = ''
|
||||||
cols += CSV.generate_row(col, col.size, lineBuf, ?\t)
|
cols += CSV.generate_row(col, col.size, lineBuf, ?\t)
|
||||||
buf << tsv2csv(lineBuf) << "\r\n"
|
buf << tsv2csv(lineBuf) << "\n"
|
||||||
toBe << tsv2csv(lineBuf) << "\r\n"
|
toBe << tsv2csv(lineBuf) << "\n"
|
||||||
colsToBe += col.size
|
colsToBe += col.size
|
||||||
end
|
end
|
||||||
assert_equal(colsToBe, cols)
|
assert_equal(colsToBe, cols)
|
||||||
|
@ -941,7 +797,7 @@ public
|
||||||
def test_s_parse_line
|
def test_s_parse_line
|
||||||
@@simpleCSVData.each do |col, str|
|
@@simpleCSVData.each do |col, str|
|
||||||
row = CSV.parse_line(str)
|
row = CSV.parse_line(str)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(col.size, row.size)
|
assert_equal(col.size, row.size)
|
||||||
assert_equal(col, row)
|
assert_equal(col, row)
|
||||||
end
|
end
|
||||||
|
@ -949,214 +805,214 @@ public
|
||||||
@@simpleCSVData.each do |col, str|
|
@@simpleCSVData.each do |col, str|
|
||||||
str = csv2ssv(str)
|
str = csv2ssv(str)
|
||||||
row = CSV.parse_line(str, ?;)
|
row = CSV.parse_line(str, ?;)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(col.size, row.size)
|
assert_equal(col.size, row.size, str.inspect)
|
||||||
assert_equal(col, row)
|
assert_equal(col, row, str.inspect)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@simpleCSVData.each do |col, str|
|
@@simpleCSVData.each do |col, str|
|
||||||
str = csv2tsv(str)
|
str = csv2tsv(str)
|
||||||
row = CSV.parse_line(str, ?\t)
|
row = CSV.parse_line(str, ?\t)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(col.size, row.size)
|
assert_equal(col.size, row.size)
|
||||||
assert_equal(col, row)
|
assert_equal(col, row)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Illegal format.
|
# Illegal format.
|
||||||
buf = CSV::Row.new
|
buf = []
|
||||||
row = CSV.parse_line("a,b,\"c\"\ra")
|
row = CSV.parse_line("a,b,\"c\"\ra")
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
row = CSV.parse_line("a;b;\"c\"\ra", ?;)
|
row = CSV.parse_line("a;b;\"c\"\ra", ?;)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
row = CSV.parse_line("a\tb\t\"c\"\ra", ?\t)
|
row = CSV.parse_line("a\tb\t\"c\"\ra", ?\t)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("a,b\"")
|
row = CSV.parse_line("a,b\"")
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("a;b\"", ?;)
|
row = CSV.parse_line("a;b\"", ?;)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("a\tb\"", ?\t)
|
row = CSV.parse_line("a\tb\"", ?\t)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("\"a,b\"\r,")
|
row = CSV.parse_line("\"a,b\"\r,")
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("\"a;b\"\r;", ?;)
|
row = CSV.parse_line("\"a;b\"\r;", ?;)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("\"a\tb\"\r\t", ?\t)
|
row = CSV.parse_line("\"a\tb\"\r\t", ?\t)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("\"a,b\"\r\"")
|
row = CSV.parse_line("\"a,b\"\r\"")
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("\"a;b\"\r\"", ?;)
|
row = CSV.parse_line("\"a;b\"\r\"", ?;)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
|
|
||||||
row = CSV.parse_line("\"a\tb\"\r\"", ?\t)
|
row = CSV.parse_line("\"a\tb\"\r\"", ?\t)
|
||||||
assert_instance_of(CSV::Row, row)
|
assert_instance_of(Array, row)
|
||||||
assert_equal(0, row.size)
|
assert_equal(0, row.size)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_s_parse_row
|
def test_s_parse_row
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str + "\r\n", 0, buf)
|
cols, idx = CSV.parse_row(str + "\r\n", 0, buf)
|
||||||
assert_equal(cols, buf.size, "Reported size.")
|
assert_equal(cols, buf.size, "Reported size.")
|
||||||
assert_equal(col.size, buf.size, "Size.")
|
assert_equal(col.size, buf.size, "Size.")
|
||||||
assert(buf.match(col))
|
assert_equal(col, buf, str.inspect)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str + "\n", 0, buf)
|
cols, idx = CSV.parse_row(str + "\n", 0, buf, ?,, ?\n)
|
||||||
assert_equal(cols, buf.size, "Reported size.")
|
assert_equal(cols, buf.size, "Reported size.")
|
||||||
assert_equal(col.size, buf.size, "Size.")
|
assert_equal(col.size, buf.size, "Size.")
|
||||||
assert(buf.match(col))
|
assert_equal(col, buf, str.inspect)
|
||||||
|
|
||||||
# separator: |
|
# separator: |
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str + "|", 0, buf, ?,)
|
cols, idx = CSV.parse_row(str + "|", 0, buf, ?,)
|
||||||
assert(!buf.match(col))
|
assert_not_equal(col, buf)
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str + "|", 0, buf, ?,, ?|)
|
cols, idx = CSV.parse_row(str + "|", 0, buf, ?,, ?|)
|
||||||
assert_equal(cols, buf.size, "Reported size.")
|
assert_equal(cols, buf.size, "Reported size.")
|
||||||
assert_equal(col.size, buf.size, "Size.")
|
assert_equal(col.size, buf.size, "Size.")
|
||||||
assert(buf.match(col))
|
assert_equal(col, buf, str.inspect)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
str = csv2ssv(str)
|
str = csv2ssv(str)
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str + "\r\n", 0, buf, ?;)
|
cols, idx = CSV.parse_row(str + "\r\n", 0, buf, ?;)
|
||||||
assert_equal(cols, buf.size, "Reported size.")
|
assert_equal(cols, buf.size, "Reported size.")
|
||||||
assert_equal(col.size, buf.size, "Size.")
|
assert_equal(col.size, buf.size, "Size.")
|
||||||
assert(buf.match(col))
|
assert_equal(col, buf, str)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
str = csv2tsv(str)
|
str = csv2tsv(str)
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str + "\r\n", 0, buf, ?\t)
|
cols, idx = CSV.parse_row(str + "\r\n", 0, buf, ?\t)
|
||||||
assert_equal(cols, buf.size, "Reported size.")
|
assert_equal(cols, buf.size, "Reported size.")
|
||||||
assert_equal(col.size, buf.size, "Size.")
|
assert_equal(col.size, buf.size, "Size.")
|
||||||
assert(buf.match(col))
|
assert_equal(col, buf, str)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@fullCSVData.each do |col, str|
|
@@fullCSVData.each do |col, str|
|
||||||
str = csv2tsv(str, ?|)
|
str = csv2tsv(str, ?|)
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str + "|", 0, buf, ?\t, ?|)
|
cols, idx = CSV.parse_row(str + "|", 0, buf, ?\t, ?|)
|
||||||
assert_equal(cols, buf.size, "Reported size.")
|
assert_equal(cols, buf.size, "Reported size.")
|
||||||
assert_equal(col.size, buf.size, "Size.")
|
assert_equal(col.size, buf.size, "Size.")
|
||||||
assert(buf.match(col), str)
|
assert_equal(col, buf, str)
|
||||||
end
|
end
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a,b,\"c\r\"", 0, buf)
|
cols, idx = CSV.parse_row("a,b,\"c\r\"", 0, buf)
|
||||||
assert_equal(["a", "b", "c\r"], buf.to_a)
|
assert_equal(["a", "b", "c\r"], buf.to_a)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a;b;\"c\r\"", 0, buf, ?;)
|
cols, idx = CSV.parse_row("a;b;\"c\r\"", 0, buf, ?;)
|
||||||
assert_equal(["a", "b", "c\r"], buf.to_a)
|
assert_equal(["a", "b", "c\r"], buf.to_a)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a\tb\t\"c\r\"", 0, buf, ?\t)
|
cols, idx = CSV.parse_row("a\tb\t\"c\r\"", 0, buf, ?\t)
|
||||||
assert_equal(["a", "b", "c\r"], buf.to_a)
|
assert_equal(["a", "b", "c\r"], buf.to_a)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a,b,c\n", 0, buf)
|
cols, idx = CSV.parse_row("a,b,c\n", 0, buf, ?,, ?\n)
|
||||||
assert_equal(["a", "b", "c"], buf.to_a)
|
assert_equal(["a", "b", "c"], buf.to_a)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a\tb\tc\n", 0, buf, ?\t)
|
cols, idx = CSV.parse_row("a\tb\tc\n", 0, buf, ?\t, ?\n)
|
||||||
assert_equal(["a", "b", "c"], buf.to_a)
|
assert_equal(["a", "b", "c"], buf.to_a)
|
||||||
|
|
||||||
# Illegal format.
|
# Illegal format.
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a,b,c\"", 0, buf)
|
cols, idx = CSV.parse_row("a,b,c\"", 0, buf)
|
||||||
assert_equal(0, cols, "Illegal format; unbalanced double-quote.")
|
assert_equal(0, cols, "Illegal format; unbalanced double-quote.")
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a;b;c\"", 0, buf, ?;)
|
cols, idx = CSV.parse_row("a;b;c\"", 0, buf, ?;)
|
||||||
assert_equal(0, cols, "Illegal format; unbalanced double-quote.")
|
assert_equal(0, cols, "Illegal format; unbalanced double-quote.")
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a,b,\"c\"\ra", 0, buf)
|
cols, idx = CSV.parse_row("a,b,\"c\"\ra", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a,b,\"c\"\ra", 0, buf, ?;)
|
cols, idx = CSV.parse_row("a,b,\"c\"\ra", 0, buf, ?;)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a,b\"", 0, buf)
|
cols, idx = CSV.parse_row("a,b\"", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a;b\"", 0, buf, ?;)
|
cols, idx = CSV.parse_row("a;b\"", 0, buf, ?;)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("\"a,b\"\r,", 0, buf)
|
cols, idx = CSV.parse_row("\"a,b\"\r,", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a\r,", 0, buf)
|
cols, idx = CSV.parse_row("a\r,", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a\r", 0, buf)
|
cols, idx = CSV.parse_row("a\r", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a\rbc", 0, buf)
|
cols, idx = CSV.parse_row("a\rbc", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a\r\"\"", 0, buf)
|
cols, idx = CSV.parse_row("a\r\"\"", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("a\r\rabc,", 0, buf)
|
cols, idx = CSV.parse_row("a\r\rabc,", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("\"a;b\"\r;", 0, buf, ?;)
|
cols, idx = CSV.parse_row("\"a;b\"\r;", 0, buf, ?;)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("\"a,b\"\r\"", 0, buf)
|
cols, idx = CSV.parse_row("\"a,b\"\r\"", 0, buf)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row("\"a;b\"\r\"", 0, buf, ?;)
|
cols, idx = CSV.parse_row("\"a;b\"\r\"", 0, buf, ?;)
|
||||||
assert_equal(0, cols)
|
assert_equal(0, cols)
|
||||||
assert_equal(0, idx)
|
assert_equal(0, idx)
|
||||||
|
@ -1168,11 +1024,11 @@ public
|
||||||
# String "" is not allowed.
|
# String "" is not allowed.
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
buf = CSV::Row.new
|
buf = Array.new
|
||||||
cols, idx = CSV.parse_row(str, 0, buf)
|
cols, idx = CSV.parse_row(str, 0, buf)
|
||||||
assert_equal(col.size, cols, "Reported size.")
|
assert_equal(col.size, cols, "Reported size.")
|
||||||
assert_equal(col.size, buf.size, "Size.")
|
assert_equal(col.size, buf.size, "Size.")
|
||||||
assert(buf.match(col))
|
assert_equal(col, buf)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1185,7 +1041,7 @@ public
|
||||||
end
|
end
|
||||||
idx = 0
|
idx = 0
|
||||||
cols = 0
|
cols = 0
|
||||||
parsed = CSV::Row.new
|
parsed = Array.new
|
||||||
parsedCols = 0
|
parsedCols = 0
|
||||||
begin
|
begin
|
||||||
cols, idx = CSV.parse_row(buf, idx, parsed)
|
cols, idx = CSV.parse_row(buf, idx, parsed)
|
||||||
|
@ -1193,7 +1049,7 @@ public
|
||||||
end while cols > 0
|
end while cols > 0
|
||||||
assert_equal(toBe.size, parsedCols)
|
assert_equal(toBe.size, parsedCols)
|
||||||
assert_equal(toBe.size, parsed.size)
|
assert_equal(toBe.size, parsed.size)
|
||||||
assert(parsed.match(toBe))
|
assert_equal(toBe, parsed)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
toBe = []
|
toBe = []
|
||||||
|
@ -1203,15 +1059,15 @@ public
|
||||||
end
|
end
|
||||||
idx = 0
|
idx = 0
|
||||||
cols = 0
|
cols = 0
|
||||||
parsed = CSV::Row.new
|
parsed = Array.new
|
||||||
parsedCols = 0
|
parsedCols = 0
|
||||||
begin
|
begin
|
||||||
cols, idx = CSV.parse_row(buf, idx, parsed)
|
cols, idx = CSV.parse_row(buf, idx, parsed, ?,, ?\n)
|
||||||
parsedCols += cols
|
parsedCols += cols
|
||||||
end while cols > 0
|
end while cols > 0
|
||||||
assert_equal(toBe.size, parsedCols)
|
assert_equal(toBe.size, parsedCols)
|
||||||
assert_equal(toBe.size, parsed.size)
|
assert_equal(toBe.size, parsed.size)
|
||||||
assert(parsed.match(toBe))
|
assert_equal(toBe, parsed)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
toBe = []
|
toBe = []
|
||||||
|
@ -1223,15 +1079,15 @@ public
|
||||||
end
|
end
|
||||||
idx = 0
|
idx = 0
|
||||||
cols = 0
|
cols = 0
|
||||||
parsed = CSV::Row.new
|
parsed = Array.new
|
||||||
parsedCols = 0
|
parsedCols = 0
|
||||||
begin
|
begin
|
||||||
cols, idx = CSV.parse_row(buf, idx, parsed)
|
cols, idx = CSV.parse_row(buf, idx, parsed, ?,, ?\n)
|
||||||
parsedCols += cols
|
parsedCols += cols
|
||||||
end while cols > 0
|
end while cols > 0
|
||||||
assert_equal(toBe.size, parsedCols)
|
assert_equal(toBe.size, parsedCols)
|
||||||
assert_equal(toBe.size, parsed.size)
|
assert_equal(toBe.size, parsed.size)
|
||||||
assert(parsed.match(toBe))
|
assert_equal(toBe, parsed)
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
toBe = []
|
toBe = []
|
||||||
|
@ -1241,7 +1097,7 @@ public
|
||||||
end
|
end
|
||||||
idx = 0
|
idx = 0
|
||||||
cols = 0
|
cols = 0
|
||||||
parsed = CSV::Row.new
|
parsed = []
|
||||||
parsedCols = 0
|
parsedCols = 0
|
||||||
begin
|
begin
|
||||||
cols, idx = CSV.parse_row(buf, idx, parsed, ?,, ?|)
|
cols, idx = CSV.parse_row(buf, idx, parsed, ?,, ?|)
|
||||||
|
@ -1249,7 +1105,7 @@ public
|
||||||
end while cols > 0
|
end while cols > 0
|
||||||
assert_equal(toBe.size, parsedCols)
|
assert_equal(toBe.size, parsedCols)
|
||||||
assert_equal(toBe.size, parsed.size)
|
assert_equal(toBe.size, parsed.size)
|
||||||
assert(parsed.match(toBe))
|
assert_equal(toBe, parsed)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_utf8
|
def test_utf8
|
||||||
|
@ -1280,25 +1136,33 @@ public
|
||||||
CSV.open(@macfile, "r") do |row|
|
CSV.open(@macfile, "r") do |row|
|
||||||
rows << row.to_a
|
rows << row.to_a
|
||||||
end
|
end
|
||||||
|
assert_equal([["Avenches", "aus Umgebung\r\"Bad Hersfeld", "Ausgrabung"]], rows)
|
||||||
end
|
end
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
file = File.open(@macfile)
|
file = File.open(@macfile)
|
||||||
|
begin
|
||||||
CSV::Reader.parse(file, ?,, ?\r) do |row|
|
CSV::Reader.parse(file, ?,, ?\r) do |row|
|
||||||
rows << row.to_a
|
rows << row.to_a
|
||||||
end
|
end
|
||||||
assert_equal([["Avenches", "aus Umgebung"], ["Bad Hersfeld", "Ausgrabung"]], rows)
|
assert_equal([["Avenches", "aus Umgebung"], ["Bad Hersfeld", "Ausgrabung"]], rows)
|
||||||
|
ensure
|
||||||
file.close
|
file.close
|
||||||
|
end
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
file = File.open(@macfile)
|
file = File.open(@macfile)
|
||||||
|
begin
|
||||||
assert_raises(CSV::IllegalFormatError) do
|
assert_raises(CSV::IllegalFormatError) do
|
||||||
CSV::Reader.parse(file, ?,) do |row|
|
CSV::Reader.parse(file, ?,) do |row|
|
||||||
rows << row.to_a
|
rows << row.to_a
|
||||||
end
|
end
|
||||||
|
assert_equal([["Avenches", "aus Umgebung\r\"Bad Hersfeld", "Ausgrabung"]], rows)
|
||||||
end
|
end
|
||||||
|
ensure
|
||||||
file.close
|
file.close
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
#### CSV unit test
|
#### CSV unit test
|
||||||
|
@ -1678,8 +1542,8 @@ public
|
||||||
#
|
#
|
||||||
def test_s_parseAndCreate
|
def test_s_parseAndCreate
|
||||||
colSize = 8
|
colSize = 8
|
||||||
csvStr = "foo,!!!foo!!!,!foo,bar!,!!!!!!,!!,,!\r!,!\r\n!\r\nNaHi,!!!Na!!!,!Na,Hi!,!\r.\n!,!\r\n\n!,!!!!,!\n!,!\r\n!".gsub!('!', '"')
|
csvStr = "foo,!!!foo!!!,!foo,bar!,!!!!!!,!!,,!\r!,!\r\n!\nNaHi,!!!Na!!!,!Na,Hi!,!\r.\n!,!\r\n\n!,!!!!,!\n!,!\r\n!".gsub!('!', '"')
|
||||||
csvStrTerminated = csvStr + "\r\n"
|
csvStrTerminated = csvStr + "\n"
|
||||||
|
|
||||||
myStr = csvStr.dup
|
myStr = csvStr.dup
|
||||||
res1 = []; res2 = []
|
res1 = []; res2 = []
|
||||||
|
@ -1708,19 +1572,9 @@ public
|
||||||
buf = ''
|
buf = ''
|
||||||
CSV::Writer.generate(buf) do |writer|
|
CSV::Writer.generate(buf) do |writer|
|
||||||
parsed.each do |row|
|
parsed.each do |row|
|
||||||
writer << row.collect { |e| e.is_null ? nil : e.data }
|
writer << row
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
assert_equal(csvStrTerminated, buf)
|
assert_equal(csvStrTerminated, buf)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if $0 == __FILE__
|
|
||||||
suite = Test::Unit::TestSuite.new('CSV')
|
|
||||||
ObjectSpace.each_object(Class) do |klass|
|
|
||||||
suite << klass.suite if (Test::Unit::TestCase > klass)
|
|
||||||
end
|
|
||||||
require 'test/unit/ui/console/testrunner'
|
|
||||||
Test::Unit::UI::Console::TestRunner.run(suite).passed?
|
|
||||||
end
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче