tc_features.rb 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #!/usr/local/bin/ruby -w
  2. # tc_features.rb
  3. #
  4. # Created by James Edward Gray II on 2005-11-14.
  5. # Copyright 2012 Gray Productions. All rights reserved.
  6. require "test/unit"
  7. require "zlib"
  8. require "faster_csv"
  9. class TestFasterCSVFeatures < Test::Unit::TestCase
  10. TEST_CASES = [ [%Q{a,b}, ["a", "b"]],
  11. [%Q{a,"""b"""}, ["a", "\"b\""]],
  12. [%Q{a,"""b"}, ["a", "\"b"]],
  13. [%Q{a,"b"""}, ["a", "b\""]],
  14. [%Q{a,"\nb"""}, ["a", "\nb\""]],
  15. [%Q{a,"""\nb"}, ["a", "\"\nb"]],
  16. [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
  17. [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
  18. [%Q{a,,,}, ["a", nil, nil, nil]],
  19. [%Q{,}, [nil, nil]],
  20. [%Q{"",""}, ["", ""]],
  21. [%Q{""""}, ["\""]],
  22. [%Q{"""",""}, ["\"",""]],
  23. [%Q{,""}, [nil,""]],
  24. [%Q{,"\r"}, [nil,"\r"]],
  25. [%Q{"\r\n,"}, ["\r\n,"]],
  26. [%Q{"\r\n,",}, ["\r\n,", nil]] ]
  27. def setup
  28. @sample_data = <<-END_DATA.gsub(/^ +/, "")
  29. line,1,abc
  30. line,2,"def\nghi"
  31. line,4,jkl
  32. END_DATA
  33. @csv = FasterCSV.new(@sample_data)
  34. end
  35. def test_col_sep
  36. [";", "\t"].each do |sep|
  37. TEST_CASES.each do |test_case|
  38. assert_equal( test_case.last.map { |t| t.tr(",", sep) unless t.nil? },
  39. FasterCSV.parse_line( test_case.first.tr(",", sep),
  40. :col_sep => sep ) )
  41. end
  42. end
  43. assert_equal( [",,,", nil],
  44. FasterCSV.parse_line(",,,;", :col_sep => ";") )
  45. end
  46. def test_row_sep
  47. assert_raise(FasterCSV::MalformedCSVError) do
  48. FasterCSV.parse_line("1,2,3\n,4,5\r\n", :row_sep => "\r\n")
  49. end
  50. assert_equal( ["1", "2", "3\n", "4", "5"],
  51. FasterCSV.parse_line( %Q{1,2,"3\n",4,5\r\n},
  52. :row_sep => "\r\n") )
  53. end
  54. def test_quote_char
  55. TEST_CASES.each do |test_case|
  56. assert_equal( test_case.last.map { |t| t.tr('"', "'") unless t.nil? },
  57. FasterCSV.parse_line( test_case.first.tr('"', "'"),
  58. :quote_char => "'" ) )
  59. end
  60. end
  61. def test_row_sep_auto_discovery
  62. ["\r\n", "\n", "\r"].each do |line_end|
  63. data = "1,2,3#{line_end}4,5#{line_end}"
  64. discovered = FasterCSV.new(data).instance_eval { @row_sep }
  65. assert_equal(line_end, discovered)
  66. end
  67. assert_equal("\n", FasterCSV.new("\n\r\n\r").instance_eval { @row_sep })
  68. assert_equal($/, FasterCSV.new("").instance_eval { @row_sep })
  69. assert_equal($/, FasterCSV.new(STDERR).instance_eval { @row_sep })
  70. end
  71. def test_lineno
  72. assert_equal(5, @sample_data.to_a.size)
  73. 4.times do |line_count|
  74. assert_equal(line_count, @csv.lineno)
  75. assert_not_nil(@csv.shift)
  76. assert_equal(line_count + 1, @csv.lineno)
  77. end
  78. assert_nil(@csv.shift)
  79. end
  80. def test_readline
  81. test_lineno
  82. @csv.rewind
  83. test_lineno
  84. end
  85. def test_unknown_options
  86. assert_raise(ArgumentError) do
  87. FasterCSV.new(String.new, :unknown => :error)
  88. end
  89. end
  90. def test_skip_blanks
  91. assert_equal(4, @csv.to_a.size)
  92. @csv = FasterCSV.new(@sample_data, :skip_blanks => true)
  93. count = 0
  94. @csv.each do |row|
  95. count += 1
  96. assert_equal("line", row.first)
  97. end
  98. assert_equal(3, count)
  99. end
  100. # reported by Kev Jackson
  101. def test_failing_to_escape_col_sep_bug_fix
  102. assert_nothing_raised(Exception) do
  103. FasterCSV.new(String.new, :col_sep => "|")
  104. end
  105. end
  106. # reported by Chris Roos
  107. def test_failing_to_reset_headers_in_rewind_bug_fix
  108. csv = FasterCSV.new( "forename,surname", :headers => true,
  109. :return_headers => true )
  110. csv.each { |row| assert row.header_row? }
  111. csv.rewind
  112. csv.each { |row| assert row.header_row? }
  113. end
  114. # reported by Dave Burt
  115. def test_leading_empty_fields_with_multibyte_col_sep_bug_fix
  116. data = <<-END_DATA.gsub(/^\s+/, "")
  117. <=><=>A<=>B<=>C
  118. 1<=>2<=>3
  119. END_DATA
  120. parsed = FasterCSV.parse(data, :col_sep => "<=>")
  121. assert_equal([[nil, nil, "A", "B", "C"], ["1", "2", "3"]], parsed)
  122. end
  123. def test_gzip_reader_bug_fix
  124. zipped = nil
  125. assert_nothing_raised(NoMethodError) do
  126. zipped = FasterCSV.new(
  127. Zlib::GzipReader.open(
  128. File.join(File.dirname(__FILE__), "line_endings.gz")
  129. )
  130. )
  131. end
  132. assert_equal("\r\n", zipped.instance_eval { @row_sep })
  133. end
  134. def test_gzip_writer_bug_fix
  135. file = File.join(File.dirname(__FILE__), "temp.gz")
  136. zipped = nil
  137. assert_nothing_raised(NoMethodError) do
  138. zipped = FasterCSV.new(Zlib::GzipWriter.open(file))
  139. end
  140. zipped << %w[one two three]
  141. zipped << [1, 2, 3]
  142. zipped.close
  143. assert( Zlib::GzipReader.open(file) { |f| f.read }.
  144. include?($INPUT_RECORD_SEPARATOR),
  145. "@row_sep did not default" )
  146. File.unlink(file)
  147. end
  148. def test_inspect_is_smart_about_io_types
  149. str = FasterCSV.new("string,data").inspect
  150. assert(str.include?("io_type:StringIO"), "IO type not detected.")
  151. str = FasterCSV.new($stderr).inspect
  152. assert(str.include?("io_type:$stderr"), "IO type not detected.")
  153. str = FasterCSV.open( File.join( File.dirname(__FILE__),
  154. "test_data.csv" ) ) { |csv| csv.inspect }
  155. assert(str.include?("io_type:File"), "IO type not detected.")
  156. end
  157. def test_inspect_shows_key_attributes
  158. str = @csv.inspect
  159. %w[lineno col_sep row_sep quote_char].each do |attr_name|
  160. assert_match(/\b#{attr_name}:[^\s>]+/, str)
  161. end
  162. end
  163. def test_inspect_shows_headers_when_available
  164. FasterCSV.open( File.join( File.dirname(__FILE__),
  165. "test_data.csv" ),
  166. :headers => true ) do |csv|
  167. assert(csv.inspect.include?("headers:true"), "Header hint not shown.")
  168. csv.shift # load headers
  169. assert_match(/headers:\[[^\]]+\]/, csv.inspect)
  170. end
  171. end
  172. def test_version
  173. assert_not_nil(FasterCSV::VERSION)
  174. assert_instance_of(String, FasterCSV::VERSION)
  175. assert(FasterCSV::VERSION.frozen?)
  176. assert_match(/\A\d\.\d\.\d\Z/, FasterCSV::VERSION)
  177. end
  178. end