1#!/usr/bin/env ruby -w 2# encoding: UTF-8 3 4# tc_interface.rb 5# 6# Created by James Edward Gray II on 2005-10-31. 7# Copyright 2005 James Edward Gray II. You can redistribute or modify this code 8# under the terms of Ruby's license. 9 10require_relative "base" 11require "tempfile" 12 13class TestCSV::Interface < TestCSV 14 extend DifferentOFS 15 16 def setup 17 super 18 @tempfile = Tempfile.new(%w"temp .csv") 19 @tempfile.close 20 @path = @tempfile.path 21 22 File.open(@path, "wb") do |file| 23 file << "1\t2\t3\r\n" 24 file << "4\t5\r\n" 25 end 26 27 @expected = [%w{1 2 3}, %w{4 5}] 28 end 29 30 def teardown 31 @tempfile.close(true) 32 super 33 end 34 35 ### Test Read Interface ### 36 37 def test_foreach 38 CSV.foreach(@path, col_sep: "\t", row_sep: "\r\n") do |row| 39 assert_equal(@expected.shift, row) 40 end 41 end 42 43 def test_open_and_close 44 csv = CSV.open(@path, "r+", col_sep: "\t", row_sep: "\r\n") 45 assert_not_nil(csv) 46 assert_instance_of(CSV, csv) 47 assert_equal(false, csv.closed?) 48 csv.close 49 assert(csv.closed?) 50 51 ret = CSV.open(@path) do |new_csv| 52 csv = new_csv 53 assert_instance_of(CSV, new_csv) 54 "Return value." 55 end 56 assert(csv.closed?) 57 assert_equal("Return value.", ret) 58 end 59 60 def test_parse 61 data = File.binread(@path) 62 assert_equal( @expected, 63 CSV.parse(data, col_sep: "\t", row_sep: "\r\n") ) 64 65 CSV.parse(data, col_sep: "\t", row_sep: "\r\n") do |row| 66 assert_equal(@expected.shift, row) 67 end 68 end 69 70 def test_parse_line 71 row = CSV.parse_line("1;2;3", col_sep: ";") 72 assert_not_nil(row) 73 assert_instance_of(Array, row) 74 assert_equal(%w{1 2 3}, row) 75 76 # shortcut interface 77 row = "1;2;3".parse_csv(col_sep: ";") 78 assert_not_nil(row) 79 assert_instance_of(Array, row) 80 assert_equal(%w{1 2 3}, row) 81 end 82 83 def test_parse_line_with_empty_lines 84 assert_equal(nil, CSV.parse_line("")) # to signal eof 85 assert_equal(Array.new, CSV.parse_line("\n1,2,3")) 86 end 87 88 def test_read_and_readlines 89 assert_equal( @expected, 90 CSV.read(@path, col_sep: "\t", row_sep: "\r\n") ) 91 assert_equal( @expected, 92 CSV.readlines(@path, col_sep: "\t", row_sep: "\r\n") ) 93 94 95 data = CSV.open(@path, col_sep: "\t", row_sep: "\r\n") do |csv| 96 csv.read 97 end 98 assert_equal(@expected, data) 99 data = CSV.open(@path, col_sep: "\t", row_sep: "\r\n") do |csv| 100 csv.readlines 101 end 102 assert_equal(@expected, data) 103 end 104 105 def test_table 106 table = CSV.table(@path, col_sep: "\t", row_sep: "\r\n") 107 assert_instance_of(CSV::Table, table) 108 assert_equal([[:"1", :"2", :"3"], [4, 5, nil]], table.to_a) 109 end 110 111 def test_shift # aliased as gets() and readline() 112 CSV.open(@path, "rb+", col_sep: "\t", row_sep: "\r\n") do |csv| 113 assert_equal(@expected.shift, csv.shift) 114 assert_equal(@expected.shift, csv.shift) 115 assert_equal(nil, csv.shift) 116 end 117 end 118 119 def test_enumerators_are_supported 120 CSV.open(@path, col_sep: "\t", row_sep: "\r\n") do |csv| 121 enum = csv.each 122 assert_instance_of(Enumerator, enum) 123 assert_equal(@expected.shift, enum.next) 124 end 125 end 126 127 ### Test Write Interface ### 128 129 def test_generate 130 str = CSV.generate do |csv| # default empty String 131 assert_instance_of(CSV, csv) 132 assert_equal(csv, csv << [1, 2, 3]) 133 assert_equal(csv, csv << [4, nil, 5]) 134 end 135 assert_not_nil(str) 136 assert_instance_of(String, str) 137 assert_equal("1,2,3\n4,,5\n", str) 138 139 CSV.generate(str) do |csv| # appending to a String 140 assert_equal(csv, csv << ["last", %Q{"row"}]) 141 end 142 assert_equal(%Q{1,2,3\n4,,5\nlast,"""row"""\n}, str) 143 end 144 145 def test_generate_line 146 line = CSV.generate_line(%w{1 2 3}, col_sep: ";") 147 assert_not_nil(line) 148 assert_instance_of(String, line) 149 assert_equal("1;2;3\n", line) 150 151 # shortcut interface 152 line = %w{1 2 3}.to_csv(col_sep: ";") 153 assert_not_nil(line) 154 assert_instance_of(String, line) 155 assert_equal("1;2;3\n", line) 156 end 157 158 def test_write_header_detection 159 File.unlink(@path) 160 161 headers = %w{a b c} 162 CSV.open(@path, "w", headers: true) do |csv| 163 csv << headers 164 csv << %w{1 2 3} 165 assert_equal(headers, csv.instance_variable_get(:@headers)) 166 end 167 end 168 169 def test_write_lineno 170 File.unlink(@path) 171 172 CSV.open(@path, "w") do |csv| 173 lines = 20 174 lines.times { csv << %w{a b c} } 175 assert_equal(lines, csv.lineno) 176 end 177 end 178 179 def test_write_hash 180 File.unlink(@path) 181 182 lines = [{a: 1, b: 2, c: 3}, {a: 4, b: 5, c: 6}] 183 CSV.open( @path, "wb", headers: true, 184 header_converters: :symbol ) do |csv| 185 csv << lines.first.keys 186 lines.each { |line| csv << line } 187 end 188 CSV.open( @path, "rb", headers: true, 189 converters: :all, 190 header_converters: :symbol ) do |csv| 191 csv.each { |line| assert_equal(lines.shift, line.to_hash) } 192 end 193 end 194 195 def test_write_hash_with_headers_array 196 File.unlink(@path) 197 198 lines = [{a: 1, b: 2, c: 3}, {a: 4, b: 5, c: 6}] 199 CSV.open(@path, "wb", headers: [:b, :a, :c]) do |csv| 200 lines.each { |line| csv << line } 201 end 202 203 # test writing fields in the correct order 204 File.open(@path, "rb") do |f| 205 assert_equal("2,1,3", f.gets.strip) 206 assert_equal("5,4,6", f.gets.strip) 207 end 208 209 # test reading CSV with headers 210 CSV.open( @path, "rb", headers: [:b, :a, :c], 211 converters: :all ) do |csv| 212 csv.each { |line| assert_equal(lines.shift, line.to_hash) } 213 end 214 end 215 216 def test_write_hash_with_headers_string 217 File.unlink(@path) 218 219 lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}] 220 CSV.open(@path, "wb", headers: "b|a|c", col_sep: "|") do |csv| 221 lines.each { |line| csv << line } 222 end 223 224 # test writing fields in the correct order 225 File.open(@path, "rb") do |f| 226 assert_equal("2|1|3", f.gets.strip) 227 assert_equal("5|4|6", f.gets.strip) 228 end 229 230 # test reading CSV with headers 231 CSV.open( @path, "rb", headers: "b|a|c", 232 col_sep: "|", 233 converters: :all ) do |csv| 234 csv.each { |line| assert_equal(lines.shift, line.to_hash) } 235 end 236 end 237 238 def test_write_headers 239 File.unlink(@path) 240 241 lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}] 242 CSV.open( @path, "wb", headers: "b|a|c", 243 write_headers: true, 244 col_sep: "|" ) do |csv| 245 lines.each { |line| csv << line } 246 end 247 248 # test writing fields in the correct order 249 File.open(@path, "rb") do |f| 250 assert_equal("b|a|c", f.gets.strip) 251 assert_equal("2|1|3", f.gets.strip) 252 assert_equal("5|4|6", f.gets.strip) 253 end 254 255 # test reading CSV with headers 256 CSV.open( @path, "rb", headers: true, 257 col_sep: "|", 258 converters: :all ) do |csv| 259 csv.each { |line| assert_equal(lines.shift, line.to_hash) } 260 end 261 end 262 263 def test_append # aliased add_row() and puts() 264 File.unlink(@path) 265 266 CSV.open(@path, "wb", col_sep: "\t", row_sep: "\r\n") do |csv| 267 @expected.each { |row| csv << row } 268 end 269 270 test_shift 271 272 # same thing using CSV::Row objects 273 File.unlink(@path) 274 275 CSV.open(@path, "wb", col_sep: "\t", row_sep: "\r\n") do |csv| 276 @expected.each { |row| csv << CSV::Row.new(Array.new, row) } 277 end 278 279 test_shift 280 end 281 282 ### Test Read and Write Interface ### 283 284 def test_filter 285 assert_respond_to(CSV, :filter) 286 287 expected = [[1, 2, 3], [4, 5]] 288 CSV.filter( "1;2;3\n4;5\n", (result = String.new), 289 in_col_sep: ";", out_col_sep: ",", 290 converters: :all ) do |row| 291 assert_equal(row, expected.shift) 292 row.map! { |n| n * 2 } 293 row << "Added\r" 294 end 295 assert_equal("2,4,6,\"Added\r\"\n8,10,\"Added\r\"\n", result) 296 end 297 298 def test_instance 299 csv = String.new 300 301 first = nil 302 assert_nothing_raised(Exception) do 303 first = CSV.instance(csv, col_sep: ";") 304 first << %w{a b c} 305 end 306 307 assert_equal("a;b;c\n", csv) 308 309 second = nil 310 assert_nothing_raised(Exception) do 311 second = CSV.instance(csv, col_sep: ";") 312 second << [1, 2, 3] 313 end 314 315 assert_equal(first.object_id, second.object_id) 316 assert_equal("a;b;c\n1;2;3\n", csv) 317 318 # shortcuts 319 assert_equal(STDOUT, CSV.instance.instance_eval { @io }) 320 assert_equal(STDOUT, CSV { |new_csv| new_csv.instance_eval { @io } }) 321 end 322 323 def test_options_are_not_modified 324 opt = {}.freeze 325 assert_nothing_raised { CSV.foreach(@path, opt) } 326 assert_nothing_raised { CSV.open(@path, opt){} } 327 assert_nothing_raised { CSV.parse("", opt) } 328 assert_nothing_raised { CSV.parse_line("", opt) } 329 assert_nothing_raised { CSV.read(@path, opt) } 330 assert_nothing_raised { CSV.readlines(@path, opt) } 331 assert_nothing_raised { CSV.table(@path, opt) } 332 assert_nothing_raised { CSV.generate(opt){} } 333 assert_nothing_raised { CSV.generate_line([], opt) } 334 assert_nothing_raised { CSV.filter("", "", opt){} } 335 assert_nothing_raised { CSV.instance("", opt) } 336 end 337end 338