csv_shaper 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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::Shaper.encode do |csv|
15
- csv.headers :name, :age, :gender, :pet_names
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
@@ -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
  #
@@ -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(column, value = nil)
61
- column = column.to_sym
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 @model && value.nil?
64
- @cells[column] = @model.send(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
- @cells[column] = value
76
+ raise ArgumentError, 'you can pass a column or a column with a value to #cell'
67
77
  end
68
78
 
69
79
  @cells
@@ -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
@@ -1,3 +1,3 @@
1
1
  module CsvShaper
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
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)
@@ -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
@@ -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.1.1
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-11 00:00:00.000000000 Z
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: !ruby/object:Gem::Requirement
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: !ruby/object:Gem::Requirement
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: !ruby/object:Gem::Requirement
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.23
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: