array_to_csv 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1a14acec1c38d14bc166fcc2e3c885a00664747
4
- data.tar.gz: fb3982fb10d8bec759d05fa61de02ed2a9bad320
3
+ metadata.gz: 6a35e265bf29320eaad3cc7455ba66882a062347
4
+ data.tar.gz: 07ccceb8f2ee1868f1de8c812a98b0b5d126799a
5
5
  SHA512:
6
- metadata.gz: 54da663d1c117d226a8f616ef198a6e899f2bad3fa9e2f039482966f189286e90df7869077961db12e00f6b39f448e152cfeefda82c2709c618238d188163dbd
7
- data.tar.gz: f781a7c56fc1bb835649113d704c1efe71e47c361bd692d0efb383047d94b94f0bc368df5af9092b5b04e2fac103879e7e4c16671ad2031e8cb4d56e018a5c27
6
+ metadata.gz: 10d9744daa78f20ab1c7c42a1777f69866339c773f4e7d08b73b361a69a97ae452f5533446c68c66cd4d839adfdd9774859a2ef889808d51a5f836ea2ad31f4e
7
+ data.tar.gz: 68bbacbd8721eb81b4b04c19867a682aa782c4cbf35e10da6fc3d018ceb3e69ac2f1a8b9d7615001381c9f387cbd91ce3ce78d962b53dde372f5e328cae716a2
@@ -0,0 +1,102 @@
1
+ # array_to_csv
2
+
3
+ Simple convenience library for converting an array of hashes to CSV
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'array_to_csv'
11
+ ```
12
+
13
+ OR
14
+
15
+ ```ruby
16
+ gem 'array_to_csv', :require => 'array_to_csv/core_ext'
17
+ ```
18
+
19
+ if you want the to_csv method to be added to the Array class.
20
+
21
+ Then execute:
22
+
23
+ ```sh
24
+ $ bundle install
25
+ ```
26
+
27
+ Or install it yourself as:
28
+
29
+ ```sh
30
+ $ gem install array_to_csv
31
+ ```
32
+
33
+ ## Example Usage
34
+
35
+ ### Using Array#to_csv (re-opening the Array class)
36
+
37
+ If you require array_to_csv/core_ext,
38
+
39
+ ```ruby
40
+ require 'array_to_csv/core_ext'
41
+ ```
42
+
43
+ (or require it from within your Gemfile)
44
+ you can call to_csv directly on an array.
45
+
46
+ ```ruby
47
+ puts [
48
+ {:first_name => 'Rob', :last_name => 'Bobber'},
49
+ {:first_name => 'Bob', :age => 103}
50
+ ].to_csv
51
+ ```
52
+
53
+ This outputs:
54
+
55
+ first_name,last_name,age
56
+ Rob,Bobber,
57
+ Rob,,103
58
+
59
+ Which would look something like this in your favourite spreadsheet editor
60
+
61
+ | first_name | last_name | age |
62
+ |------------|-----------|-----|
63
+ | Rob | Bobber | |
64
+ | Bob | | 103 |
65
+
66
+ When no arguments are given to to_csv, the CSV data is returned as a string.
67
+
68
+ You can pass in a file path, and the CSV data will be written directly to file,
69
+ instead of being returned as a string.
70
+
71
+ ```ruby
72
+ [
73
+ {:first_name => 'Rob', :last_name => 'Bobber'},
74
+ {:first_name => 'Bob', :age => 103}
75
+ ].to_csv("/tmp/people.csv")
76
+ ```
77
+
78
+ You can also pass in a File object as the first argument, or any other
79
+ IO/IO-like object (anything that implements #write(string) and #close).
80
+
81
+ ### Without reopening Array class
82
+
83
+ If you don't want to being reopening core classes, you can convert an array to CSV
84
+ like this:
85
+
86
+ ```ruby
87
+ data = [
88
+ {:first_name => 'Rob', :last_name => 'Bobber'},
89
+ {:first_name => 'Bob', :age => 103}
90
+ ]
91
+ puts ArrayToCsv.new(data).to_csv
92
+ ```
93
+
94
+ Which produces the same output as above
95
+
96
+ first_name,last_name,age
97
+ Rob,Bobber,
98
+ Rob,,103
99
+
100
+ The interface for ArrayToCsv#to_csv is the same as that for Array#to_csv.
101
+
102
+ You can pass in a file path, File, or IO/IO-like object.
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "array_to_csv"
7
- spec.version = "0.0.1"
7
+ spec.version = "0.1.0"
8
8
  spec.authors = ["Joel Plane"]
9
9
  spec.email = ["joel.plane@gmail.com"]
10
10
  spec.description = %q{Adds convenience method Array#to_csv for converting an array of hashes to CSV.}
@@ -1,52 +1,41 @@
1
1
  class ArrayToCsv
2
2
 
3
- def initialize array, csv_lib=choose_csv_lib
3
+ require 'array_to_csv/csv_writer'
4
+
5
+ def initialize array, csv_lib=nil
4
6
  @array = array
5
- @csv = csv_lib
7
+ @csv_lib = csv_lib
6
8
  end
7
9
 
8
- def to_csv
9
- @csv.generate do |csv|
10
- each_row do |row|
11
- csv << row
12
- end
10
+ # @return [String, nil]
11
+ def to_csv io_or_file_path=nil
12
+ case io_or_file_path
13
+ when nil
14
+ to_csv_string
15
+ when String
16
+ to_csv_file io_or_file_path
17
+ else
18
+ to_csv_io io_or_file_path
13
19
  end
14
20
  end
15
21
 
16
22
  private
17
23
 
18
- def each_row
19
- yield head
20
- @array.each do |hash|
21
- yield row_from_hash hash
22
- end
23
- end
24
-
25
- def head
26
- @head_from_array ||= [].tap do |keys|
27
- seen_keys = {}
28
- @array.each do |hash|
29
- hash.keys.each do |key|
30
- unless seen_keys[key]
31
- seen_keys[key] = true
32
- keys << key
33
- end
34
- end
35
- end
36
- end
24
+ # @return [String]
25
+ def to_csv_string
26
+ StringIO.new.tap do |string_io|
27
+ self.to_csv string_io
28
+ end.string
37
29
  end
38
30
 
39
- def row_from_hash hash
40
- hash.values_at(*head)
31
+ def to_csv_file file_path
32
+ file_io = File.open(file_path, 'w')
33
+ self.to_csv file_io
41
34
  end
42
35
 
43
- # TODO: return FasterCSV in old ruby
44
- def choose_csv_lib
45
- if RUBY_VERSION =~ /^1\.8/
46
- FasterCSV
47
- else
48
- CSV
49
- end
36
+ # @return [nil]
37
+ def to_csv_io io
38
+ CsvWriter.new(@array, io, @csv_lib).write
50
39
  end
51
40
 
52
41
  end
@@ -1,9 +1,14 @@
1
1
  require 'array_to_csv'
2
+ if RUBY_VERSION =~ /^1\.8/
3
+ require 'fastercsv'
4
+ else
5
+ require 'csv'
6
+ end
2
7
 
3
8
  class Array
4
9
 
5
- def to_csv
6
- ArrayToCsv.new(self).to_csv
10
+ def to_csv *args
11
+ ArrayToCsv.new(self).to_csv *args
7
12
  end
8
13
 
9
14
  end
@@ -0,0 +1,53 @@
1
+ class ArrayToCsv::CsvWriter
2
+
3
+ def initialize array, io, csv_lib
4
+ @array, @io = array, io
5
+ @csv = csv_lib || choose_csv_lib
6
+ end
7
+
8
+ def write
9
+ each_row do |row|
10
+ write_line row
11
+ end
12
+ @io.close
13
+ nil
14
+ end
15
+
16
+ def write_line row
17
+ @io.write @csv.generate_line row
18
+ end
19
+
20
+ def each_row
21
+ yield head
22
+ @array.each do |hash|
23
+ yield row_from_hash hash
24
+ end
25
+ end
26
+
27
+ def head
28
+ @head_from_array ||= [].tap do |keys|
29
+ seen_keys = {}
30
+ @array.each do |hash|
31
+ hash.keys.each do |key|
32
+ unless seen_keys[key]
33
+ seen_keys[key] = true
34
+ keys << key
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def row_from_hash hash
42
+ hash.values_at(*head)
43
+ end
44
+
45
+ def choose_csv_lib
46
+ if RUBY_VERSION =~ /^1\.8/
47
+ FasterCSV
48
+ else
49
+ CSV
50
+ end
51
+ end
52
+
53
+ end
@@ -41,4 +41,37 @@ describe ArrayToCsv do
41
41
 
42
42
  end
43
43
 
44
+ describe ".to_csv(io)" do
45
+
46
+ subject { ArrayToCsv.new([{:key1 => 'value1'}, {:key2 => 'value2'}]) }
47
+
48
+ it "should stream output to provided io object" do
49
+ io = double
50
+ expect(io).to receive(:write).with("key1,key2\n")
51
+ expect(io).to receive(:write).with("value1,\n")
52
+ expect(io).to receive(:write).with(",value2\n")
53
+ expect(io).to receive(:close)
54
+ subject.to_csv(io)
55
+ end
56
+
57
+ it "should return nil" do
58
+ io = double :write => nil, :close => nil
59
+ expect(subject.to_csv(io)).to be_nil
60
+ end
61
+
62
+ end
63
+
64
+ describe ".to_csv(file_path)" do
65
+
66
+ subject { ArrayToCsv.new([{:key1 => 'value1'}, {:key2 => 'value2'}]) }
67
+ let(:csv_output) { "key1,key2\nvalue1,\n,value2\n" }
68
+ let(:test_path) { "/tmp/array_to_csv_test_output.csv" }
69
+
70
+ it "should write CSV to file" do
71
+ subject.to_csv test_path
72
+ expect(File.read(test_path)).to eq(csv_output)
73
+ end
74
+
75
+ end
76
+
44
77
  end
@@ -16,4 +16,12 @@ describe "array_to_csv/core_ext" do
16
16
  expect(array.to_csv).to eq(ArrayToCsv.new(array).to_csv)
17
17
  end
18
18
 
19
+ it "should delegate with arguments" do
20
+ array = []
21
+ fake_io, inst = double, double
22
+ expect(ArrayToCsv).to receive(:new).and_return(inst)
23
+ expect(inst).to receive(:to_csv).with(fake_io)
24
+ array.to_csv fake_io
25
+ end
26
+
19
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: array_to_csv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Plane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-08 00:00:00.000000000 Z
11
+ date: 2014-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -63,10 +63,12 @@ files:
63
63
  - .gitignore
64
64
  - Gemfile
65
65
  - LICENSE.txt
66
+ - README.md
66
67
  - Rakefile
67
68
  - array_to_csv.gemspec
68
69
  - lib/array_to_csv.rb
69
70
  - lib/array_to_csv/core_ext.rb
71
+ - lib/array_to_csv/csv_writer.rb
70
72
  - spec/array_to_csv_spec.rb
71
73
  - spec/core_ext_spec.rb
72
74
  - test_helper.rb