rcsv 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rcsv (0.0.8)
4
+ rcsv (0.0.9)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/RELNOTES CHANGED
@@ -1,3 +1,6 @@
1
+ Version 0.0.9
2
+ * preliminary write support
3
+
1
4
  Version 0.0.8
2
5
  * libcsv upgraded to 3.0.3
3
6
  * :parse_empty_fields_as option added
@@ -4,6 +4,11 @@ require "rcsv/version"
4
4
  require "stringio"
5
5
 
6
6
  class Rcsv
7
+
8
+ attr_reader :write_options
9
+
10
+ BOOLEAN_FALSE = [nil, false, 0, 'f', 'false']
11
+
7
12
  def self.parse(csv_data, options = {}, &block)
8
13
  #options = {
9
14
  #:column_separator => "\t",
@@ -102,4 +107,56 @@ class Rcsv
102
107
  csv_data.pos = initial_position
103
108
  return self.raw_parse(csv_data, raw_options, &block)
104
109
  end
110
+
111
+ def initialize(write_options = {})
112
+ @write_options = write_options
113
+ @write_options[:column_separator] ||= ','
114
+ @write_options[:newline_delimiter] ||= "\r\n" # Making Excel happy...
115
+ @write_options[:header] ||= false
116
+ end
117
+
118
+ def write(io, &block)
119
+ io.write generate_header if @write_options[:header]
120
+ while row = yield
121
+ io.write generate_row(row)
122
+ end
123
+ end
124
+
125
+ def generate_header
126
+ return @write_options[:columns].map { |c|
127
+ c[:name].to_s
128
+ }.join(@write_options[:column_separator]) << @write_options[:newline_delimiter]
129
+ end
130
+
131
+ def generate_row(row)
132
+ column_separator = @write_options[:column_separator]
133
+ csv_row = ''
134
+ max_index = row.size - 1
135
+
136
+ row.each_with_index do |field, index|
137
+ unquoted_field = process(field, @write_options[:columns][index])
138
+ # TODO: a better quoting
139
+ csv_row << (unquoted_field.match(/,/) ? "\"#{unquoted_field}\"" : unquoted_field)
140
+ csv_row << column_separator unless index == max_index
141
+ end
142
+
143
+ return csv_row << @write_options[:newline_delimiter]
144
+ end
145
+
146
+ protected
147
+
148
+ def process(field, column_options)
149
+ return case column_options[:formatter]
150
+ when :strftime
151
+ format = column_options[:format] || "%Y-%m-%d %H:%M:%S %z"
152
+ field.strftime(format)
153
+ when :printf
154
+ format = column_options[:format] || "%s"
155
+ sprintf(format, field)
156
+ when :boolean
157
+ BOOLEAN_FALSE.include?(field.respond_to?(:downcase) ? field.downcase : field) ? 'false' : 'true'
158
+ else
159
+ field.to_s
160
+ end
161
+ end
105
162
  end
@@ -1,3 +1,3 @@
1
1
  class Rcsv
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require 'test/unit'
2
2
  require 'rcsv'
3
3
 
4
- class RcsvTest < Test::Unit::TestCase
4
+ class RcsvRawParseTest < Test::Unit::TestCase
5
5
  def setup
6
6
  @csv_data = File.open('test/test_rcsv.csv')
7
7
  end
@@ -0,0 +1,79 @@
1
+ require 'test/unit'
2
+ require 'rcsv'
3
+
4
+ class RcsvWriteTest < Test::Unit::TestCase
5
+ def setup
6
+ @options = {
7
+ :header => true,
8
+ :columns => [
9
+ {
10
+ :name => 'ID'
11
+ },
12
+ {
13
+ :name => 'Date',
14
+ :formatter => :strftime,
15
+ :format => '%Y-%m-%d'
16
+ },
17
+ {
18
+ :name => 'Money',
19
+ :formatter => :printf,
20
+ :format => '$%2.2f'
21
+ },
22
+ {
23
+ :name => 'Banana IDDQD'
24
+ },
25
+ {
26
+ :name => nil,
27
+ :formatter => :boolean
28
+ }
29
+ ]
30
+ }
31
+
32
+ @data = [
33
+ [1, Date.parse('2012-11-11'), 100.234, true, nil],
34
+ [nil, Date.parse('1970-01-02'), -0.1, :nyancat, 0],
35
+ [3, Date.parse('2012-12-12'), 0, 'sepulka', 'zoop']
36
+ ]
37
+
38
+ @writer = Rcsv.new(@options)
39
+ end
40
+
41
+ def test_rcsv_generate_header
42
+ assert_equal(
43
+ "ID,Date,Money,Banana IDDQD,\r\n", @writer.generate_header
44
+ )
45
+ end
46
+
47
+ def test_rscv_generate_row
48
+ assert_equal("1,2012-11-11,$100.23,true,false\r\n", @writer.generate_row(@data.first))
49
+ end
50
+
51
+ def test_rcsv_write
52
+ io = StringIO.new
53
+
54
+ @writer.write(io) do
55
+ @data.shift
56
+ end
57
+
58
+ io.rewind
59
+
60
+ assert_equal(
61
+ "ID,Date,Money,Banana IDDQD,\r\n1,2012-11-11,$100.23,true,false\r\n,1970-01-02,$-0.10,nyancat,false\r\n3,2012-12-12,$0.00,sepulka,true\r\n", io.read
62
+ )
63
+ end
64
+
65
+ def test_rcsv_write_no_headers
66
+ io = StringIO.new
67
+ @writer.write_options[:header] = false
68
+
69
+ @writer.write(io) do
70
+ @data.shift
71
+ end
72
+
73
+ io.rewind
74
+
75
+ assert_equal(
76
+ "1,2012-11-11,$100.23,true,false\r\n,1970-01-02,$-0.10,nyancat,false\r\n3,2012-12-12,$0.00,sepulka,true\r\n", io.read
77
+ )
78
+ end
79
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rcsv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-11 00:00:00.000000000 Z
12
+ date: 2013-01-22 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A libcsv-based CSV parser for Ruby
15
15
  email:
@@ -40,6 +40,7 @@ files:
40
40
  - rcsv.gemspec
41
41
  - test/test_rcsv.csv
42
42
  - test/test_rcsv_raw_parse.rb
43
+ - test/test_rcsv_write.rb
43
44
  homepage: http://github.com/fiksu/rcsv
44
45
  licenses: []
45
46
  post_install_message:
@@ -69,4 +70,5 @@ summary: Fast CSV parsing library for MRI based on libcsv. Supports type convers
69
70
  test_files:
70
71
  - test/test_rcsv.csv
71
72
  - test/test_rcsv_raw_parse.rb
73
+ - test/test_rcsv_write.rb
72
74
  has_rdoc: