csv_shaper 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +18 -2
- data/lib/csv_shaper/config.rb +53 -0
- data/lib/csv_shaper/encoder.rb +6 -2
- data/lib/csv_shaper/row.rb +15 -5
- data/lib/csv_shaper/shaper.rb +10 -0
- data/lib/csv_shaper/version.rb +1 -1
- data/lib/csv_shaper.rb +10 -0
- data/spec/config_spec.rb +30 -0
- data/spec/csv_shaper_spec.rb +9 -0
- data/spec/encoder_spec.rb +7 -0
- data/spec/row_spec.rb +33 -0
- metadata +13 -24
data/README.md
CHANGED
@@ -11,8 +11,8 @@ Annotated source: http://paulspringett.github.com/csv_shaper/
|
|
11
11
|
### Example Usage
|
12
12
|
|
13
13
|
```ruby
|
14
|
-
csv_string = CsvShaper
|
15
|
-
csv.
|
14
|
+
csv_string = CsvShaper.encode do |csv|
|
15
|
+
csv.header :name, :age, :gender, :pet_names
|
16
16
|
|
17
17
|
csv.rows @users do |csv, user|
|
18
18
|
csv.cells :name, :age, :gender
|
@@ -219,6 +219,22 @@ def index
|
|
219
219
|
end
|
220
220
|
```
|
221
221
|
|
222
|
+
### CSV configuration
|
223
|
+
|
224
|
+
To configure how the CSV output is formatted you can define a configure block, like so:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
CsvShaper.configure do |config|
|
228
|
+
config.col_sep = "\t"
|
229
|
+
config.write_headers = false
|
230
|
+
end
|
231
|
+
```
|
232
|
+
|
233
|
+
Inside the block you can pass any of the standard library [CSV DEFAULT_OPTIONS](http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html#DEFAULT_OPTIONS), as well as a `write_headers` option (default: `true`).
|
234
|
+
Setting this to `false` will exclude the headers from the final CSV output.
|
235
|
+
|
236
|
+
If you're using Rails you can put this in an initializer.
|
237
|
+
|
222
238
|
### Contributing
|
223
239
|
|
224
240
|
1. Fork it
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module CsvShaper
|
4
|
+
# Config
|
5
|
+
# Configure the standard CSV default options
|
6
|
+
# as well the option to output the header row
|
7
|
+
class Config
|
8
|
+
attr_reader :options
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@options = {}
|
12
|
+
yield self if block_given?
|
13
|
+
end
|
14
|
+
|
15
|
+
# Public: set options where the method name
|
16
|
+
# matches a key
|
17
|
+
def method_missing(meth, value)
|
18
|
+
meth = sanitize_setter_method(meth)
|
19
|
+
|
20
|
+
if defaults.key?(meth)
|
21
|
+
@options[meth] = value
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def respond_to?(meth)
|
28
|
+
meth = sanitize_setter_method(meth)
|
29
|
+
defaults.key?(meth)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Internal: removes the equals from the end of the
|
35
|
+
# method name
|
36
|
+
#
|
37
|
+
# `meth` - Symbol of the method of sanitize
|
38
|
+
#
|
39
|
+
# Returns a Symbol
|
40
|
+
def sanitize_setter_method(meth)
|
41
|
+
meth = meth.to_s.gsub('=', '')
|
42
|
+
meth.to_sym
|
43
|
+
end
|
44
|
+
|
45
|
+
# Internal: default CSV options, plus a write headers
|
46
|
+
# option, to pass to #to_csv
|
47
|
+
#
|
48
|
+
# Returns a Hash
|
49
|
+
def defaults
|
50
|
+
@defaults ||= CSV::DEFAULT_OPTIONS.dup.merge(write_headers: true)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/csv_shaper/encoder.rb
CHANGED
@@ -27,11 +27,15 @@ module CsvShaper
|
|
27
27
|
end
|
28
28
|
|
29
29
|
table = CSV::Table.new(rows)
|
30
|
-
table.to_csv
|
30
|
+
table.to_csv(options)
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
|
-
|
34
|
+
|
35
|
+
def options
|
36
|
+
CsvShaper::Shaper.config && CsvShaper::Shaper.config.options || {}
|
37
|
+
end
|
38
|
+
|
35
39
|
# Internal: make use of `CSV#values_at` to pad out the
|
36
40
|
# cells into the correct columns for the headers
|
37
41
|
#
|
data/lib/csv_shaper/row.rb
CHANGED
@@ -57,13 +57,23 @@ module CsvShaper
|
|
57
57
|
# `value` - data to assign to the cell (default: nil)
|
58
58
|
#
|
59
59
|
# Returns an Array of the Row's cells
|
60
|
-
def cell(
|
61
|
-
|
60
|
+
def cell(*args)
|
61
|
+
if args.empty?
|
62
|
+
raise ArgumentError, 'no args passed to #cell, you must pass at least a column name'
|
63
|
+
end
|
64
|
+
|
65
|
+
column = args.first.to_sym
|
62
66
|
|
63
|
-
if
|
64
|
-
@cells[column] =
|
67
|
+
if args.size == 2
|
68
|
+
@cells[column] = args.last
|
69
|
+
elsif args.size == 1
|
70
|
+
if @model && @model.respond_to?(column)
|
71
|
+
@cells[column] = @model.send(column)
|
72
|
+
else
|
73
|
+
raise ArgumentError, "##{column} is not a method on #{@model.class.to_s}, call `csv.cell #{column}, value` instead"
|
74
|
+
end
|
65
75
|
else
|
66
|
-
|
76
|
+
raise ArgumentError, 'you can pass a column or a column with a value to #cell'
|
67
77
|
end
|
68
78
|
|
69
79
|
@cells
|
data/lib/csv_shaper/shaper.rb
CHANGED
@@ -4,6 +4,10 @@ module CsvShaper
|
|
4
4
|
class Shaper
|
5
5
|
attr_reader :header, :rows
|
6
6
|
|
7
|
+
class << self
|
8
|
+
attr_accessor :config
|
9
|
+
end
|
10
|
+
|
7
11
|
def initialize
|
8
12
|
@rows = []
|
9
13
|
yield self if block_given?
|
@@ -72,5 +76,11 @@ module CsvShaper
|
|
72
76
|
def to_csv
|
73
77
|
Encoder.new(@header, @rows).to_csv
|
74
78
|
end
|
79
|
+
|
80
|
+
# Public: Create an instance of the config and cache it
|
81
|
+
# for reference by the Encoder later
|
82
|
+
def self.configure(&block)
|
83
|
+
@config ||= CsvShaper::Config.new(&block)
|
84
|
+
end
|
75
85
|
end
|
76
86
|
end
|
data/lib/csv_shaper/version.rb
CHANGED
data/lib/csv_shaper.rb
CHANGED
@@ -5,10 +5,20 @@ require 'csv_shaper/version'
|
|
5
5
|
require 'csv_shaper/header'
|
6
6
|
require 'csv_shaper/row'
|
7
7
|
require 'csv_shaper/encoder'
|
8
|
+
require 'csv_shaper/config'
|
8
9
|
require 'csv_shaper/shaper'
|
9
10
|
|
10
11
|
module CsvShaper
|
11
12
|
class MissingHeadersError < StandardError; end
|
13
|
+
|
14
|
+
# Shortcut the encode method
|
15
|
+
def self.encode(&block)
|
16
|
+
CsvShaper::Shaper.encode(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.configure(&block)
|
20
|
+
CsvShaper::Shaper.configure(&block)
|
21
|
+
end
|
12
22
|
end
|
13
23
|
|
14
24
|
require "csv_shaper_template" if defined?(ActionView::Template)
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CsvShaper::Config do
|
4
|
+
let(:config) {
|
5
|
+
CsvShaper::Config.new do |c|
|
6
|
+
c.write_headers = false
|
7
|
+
c.col_sep = "\t"
|
8
|
+
end
|
9
|
+
}
|
10
|
+
|
11
|
+
it "should assign options to config" do
|
12
|
+
config.options.should eq({ write_headers: false, col_sep: "\t" })
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should exclude the headers if specified" do
|
16
|
+
CsvShaper::Shaper.config = config
|
17
|
+
|
18
|
+
shaper = CsvShaper::Shaper.new do |csv|
|
19
|
+
csv.headers :name, :age, :gender
|
20
|
+
|
21
|
+
csv.row do |csv|
|
22
|
+
csv.cell :name, 'Paul'
|
23
|
+
csv.cell :age, '27'
|
24
|
+
csv.cell :gender, 'Male'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
shaper.to_csv.should eq "Paul\t27\tMale\n"
|
29
|
+
end
|
30
|
+
end
|
data/spec/csv_shaper_spec.rb
CHANGED
@@ -16,4 +16,13 @@ describe CsvShaper::Shaper do
|
|
16
16
|
csv = CsvShaper::Shaper.new
|
17
17
|
csv.should respond_to(:to_csv)
|
18
18
|
end
|
19
|
+
|
20
|
+
it "should provide a shortcut to the encode method" do
|
21
|
+
CsvShaper.should respond_to(:encode)
|
22
|
+
|
23
|
+
CsvShaper.encode do |csv|
|
24
|
+
csv.headers :foo
|
25
|
+
csv.should be_instance_of(CsvShaper::Shaper)
|
26
|
+
end
|
27
|
+
end
|
19
28
|
end
|
data/spec/encoder_spec.rb
CHANGED
@@ -4,6 +4,12 @@ require 'fixtures/user'
|
|
4
4
|
describe CsvShaper::Encoder do
|
5
5
|
let(:user) { User.new(name: 'Paul', age: 27, gender: 'Male') }
|
6
6
|
|
7
|
+
let(:config) {
|
8
|
+
CsvShaper::Config.new do |c|
|
9
|
+
c.write_headers = true
|
10
|
+
end
|
11
|
+
}
|
12
|
+
|
7
13
|
it "should raise an exception if the headers are missing" do
|
8
14
|
expect {
|
9
15
|
CsvShaper::Encoder.new(nil)
|
@@ -30,6 +36,7 @@ describe CsvShaper::Encoder do
|
|
30
36
|
}
|
31
37
|
|
32
38
|
it "should encode a Shaper instance to a CSV string" do
|
39
|
+
CsvShaper::Shaper.config = config
|
33
40
|
encoder = CsvShaper::Encoder.new(csv.header, csv.rows)
|
34
41
|
encoder.to_csv.should eq("Full name,Sex,Age\nPaul,Male,27\nBob,Male,31\nJane,Female,23\n,,81\n")
|
35
42
|
end
|
data/spec/row_spec.rb
CHANGED
@@ -22,4 +22,37 @@ describe CsvShaper::Row do
|
|
22
22
|
csv.should be_kind_of(CsvShaper::Row)
|
23
23
|
}
|
24
24
|
end
|
25
|
+
|
26
|
+
describe "cells" do
|
27
|
+
it "should send parse an attribute of the model" do
|
28
|
+
row = CsvShaper::Row.new(user, :gender)
|
29
|
+
row.cell :name
|
30
|
+
row.cells.should eq({ name: 'Paul', gender: 'Male' })
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should send assign an unrelated value" do
|
34
|
+
row = CsvShaper::Row.new(user, :gender)
|
35
|
+
row.cell :foo, 'bar'
|
36
|
+
row.cells.should eq({ foo: 'bar', gender: 'Male' })
|
37
|
+
end
|
38
|
+
|
39
|
+
it "ignore nil values passed" do
|
40
|
+
row = CsvShaper::Row.new(user, :gender)
|
41
|
+
row.cell :foo, nil
|
42
|
+
row.cells.should eq({ foo: nil, gender: 'Male' })
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not send column to model if two args are passed" do
|
46
|
+
row = CsvShaper::Row.new(user, :gender)
|
47
|
+
row.cell :name, 'Another name'
|
48
|
+
row.cells.should eq({ name: 'Another name', gender: 'Male' })
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should raise an exception of the model does not respond to column, and no value is passed" do
|
52
|
+
row = CsvShaper::Row.new(user, :gender)
|
53
|
+
expect {
|
54
|
+
row.cell :foo
|
55
|
+
}.to raise_error(ArgumentError)
|
56
|
+
end
|
57
|
+
end
|
25
58
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_shaper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirement: &2232251900 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,15 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 3.0.0
|
24
|
+
version_requirements: *2232251900
|
30
25
|
- !ruby/object:Gem::Dependency
|
31
26
|
name: rspec
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
27
|
+
requirement: &2232251240 !ruby/object:Gem::Requirement
|
33
28
|
none: false
|
34
29
|
requirements:
|
35
30
|
- - ! '>='
|
@@ -37,15 +32,10 @@ dependencies:
|
|
37
32
|
version: '0'
|
38
33
|
type: :development
|
39
34
|
prerelease: false
|
40
|
-
version_requirements:
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
35
|
+
version_requirements: *2232251240
|
46
36
|
- !ruby/object:Gem::Dependency
|
47
37
|
name: rake
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirement: &2232250580 !ruby/object:Gem::Requirement
|
49
39
|
none: false
|
50
40
|
requirements:
|
51
41
|
- - ! '>='
|
@@ -53,12 +43,7 @@ dependencies:
|
|
53
43
|
version: '0'
|
54
44
|
type: :development
|
55
45
|
prerelease: false
|
56
|
-
version_requirements:
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
46
|
+
version_requirements: *2232250580
|
62
47
|
description: ! "\n Creating CSV files in Ruby is painful! CSV Shaper makes life
|
63
48
|
easier! It's\n ideal for converting database backed models with attrbiutes into
|
64
49
|
CSV output.\n It can be used without Rails, but works great with ActiveRecord
|
@@ -78,12 +63,14 @@ files:
|
|
78
63
|
- Rakefile
|
79
64
|
- csv_shaper.gemspec
|
80
65
|
- lib/csv_shaper.rb
|
66
|
+
- lib/csv_shaper/config.rb
|
81
67
|
- lib/csv_shaper/encoder.rb
|
82
68
|
- lib/csv_shaper/header.rb
|
83
69
|
- lib/csv_shaper/row.rb
|
84
70
|
- lib/csv_shaper/shaper.rb
|
85
71
|
- lib/csv_shaper/version.rb
|
86
72
|
- lib/csv_shaper_template.rb
|
73
|
+
- spec/config_spec.rb
|
87
74
|
- spec/csv_shaper_spec.rb
|
88
75
|
- spec/encoder_spec.rb
|
89
76
|
- spec/fixtures/user.rb
|
@@ -110,14 +97,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
97
|
version: '0'
|
111
98
|
requirements: []
|
112
99
|
rubyforge_project:
|
113
|
-
rubygems_version: 1.8.
|
100
|
+
rubygems_version: 1.8.16
|
114
101
|
signing_key:
|
115
102
|
specification_version: 3
|
116
103
|
summary: Beautiful DSL for creating CSV output in Ruby & Rails
|
117
104
|
test_files:
|
105
|
+
- spec/config_spec.rb
|
118
106
|
- spec/csv_shaper_spec.rb
|
119
107
|
- spec/encoder_spec.rb
|
120
108
|
- spec/fixtures/user.rb
|
121
109
|
- spec/header_spec.rb
|
122
110
|
- spec/row_spec.rb
|
123
111
|
- spec/spec_helper.rb
|
112
|
+
has_rdoc:
|