to-csv 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +3 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +188 -0
- data/Rakefile +36 -0
- data/init.rb +1 -0
- data/lib/to_csv.rb +59 -0
- data/lib/to_csv/csv_converter.rb +169 -0
- data/test/database.yml +4 -0
- data/test/fixtures/movie.rb +2 -0
- data/test/fixtures/movies.yml +19 -0
- data/test/fixtures/people.yml +7 -0
- data/test/fixtures/person.rb +3 -0
- data/test/fixtures/schema.rb +12 -0
- data/test/lib/activerecord_test_case.rb +20 -0
- data/test/lib/activerecord_test_connector.rb +32 -0
- data/test/lib/load_fixtures.rb +9 -0
- data/test/locales/en-US.yml +28 -0
- data/test/locales/pt-BR.yml +147 -0
- data/test/tasks.rake +8 -0
- data/test/to_csv_test.rb +148 -0
- metadata +94 -0
data/CHANGELOG.rdoc
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Ícaro Leopoldino da Motta
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
= ToCSV
|
2
|
+
|
3
|
+
|
4
|
+
ToCSV is a gem for converting arrays to CSV by calling +to_csv+.
|
5
|
+
These arrays can contain different data structures, as long as they are homogeneous, like the ones
|
6
|
+
described below:
|
7
|
+
|
8
|
+
* A simple array of anything that responds to <tt>to_s</tt>: <tt>['Date', Time.now].to_csv</tt>
|
9
|
+
* An array of hashes: <tt>[ {'Name' => 'Icaro', 'Age' => 23}, {'Name' => 'Gabriel', 'Age' => 16} ].to_csv</tt>
|
10
|
+
* A matrix: <tt>[['Name', 'Age'], ['Icaro', 23], ['Gabriel', 16]].to_csv</tt>
|
11
|
+
* A hash like array: <tt>[ [['Name', 'Icaro'], ['Age', 23]], [['Name', 'Gabriel'], ['Age', 16]] ].to_csv</tt>
|
12
|
+
* An array of ActiveRecord objects: <tt>@users.to_csv(:except => [:password, :phone], :timestamps => true)</tt>
|
13
|
+
|
14
|
+
|
15
|
+
=== Requirements
|
16
|
+
|
17
|
+
You must have FasterCSV installed:
|
18
|
+
$ sudo gem install fastercsv
|
19
|
+
|
20
|
+
And also ActiveSupport:
|
21
|
+
$ sudo gem install active_support
|
22
|
+
|
23
|
+
ToCSV has been tested with Ruby 1.8.6/1.8.7.
|
24
|
+
|
25
|
+
|
26
|
+
=== Configuration
|
27
|
+
|
28
|
+
If you want to use this gem with Rails, put the following requirement in your environment.rb:
|
29
|
+
|
30
|
+
config.gem 'to-csv', :lib => 'to_csv', :source => 'http://gemcutter.org'
|
31
|
+
|
32
|
+
After that, if you need to globally configure the gem, just create a <i>to_csv.rb</i> file in <i>initializers</i>.
|
33
|
+
|
34
|
+
ToCSV.byte_order_marker = true
|
35
|
+
ToCSV.timestamps = true
|
36
|
+
ToCSV.locale = 'en-US'
|
37
|
+
ToCSV.primary_key = false
|
38
|
+
ToCSV.csv_options = { :col_sep => ',', :row_sep => "\r\n" }
|
39
|
+
|
40
|
+
|
41
|
+
== Examples
|
42
|
+
|
43
|
+
Let's start with the most simple example.
|
44
|
+
|
45
|
+
['Alfred Hitchcock', 'Robert Mitchum', 'Lucille Ball'].to_csv
|
46
|
+
#=> "Alfred Hitchcock;Robert Mitchum;Lucille Ball\n"
|
47
|
+
|
48
|
+
|
49
|
+
Or, if we have an array of arrays (i.e. a matrix) we can create tabular data.
|
50
|
+
[
|
51
|
+
['Name', 'Gender'],
|
52
|
+
['Alfred', 'M'],
|
53
|
+
['Robert', 'M'],
|
54
|
+
['Lucille', 'F']
|
55
|
+
].to_csv #=> "Name;Gender\nAlfred;M\nRobert;M\nLucille;F\n"
|
56
|
+
|
57
|
+
|
58
|
+
Almost always, when we generate CSV files, we want it to have appropriate
|
59
|
+
headers, so a better approach might be to use an array of hashes.
|
60
|
+
|
61
|
+
[
|
62
|
+
{ 'Name' => 'Alfred', 'Gender' => 'M' },
|
63
|
+
{ 'Name' => 'Robert', 'Gender' => 'M' },
|
64
|
+
{ 'Name' => 'Lucille', 'Gender' => 'F' }
|
65
|
+
].to_csv #=> "Gender;Name\nM;Alfred\nM;Robert\nF;Lucille\n"
|
66
|
+
|
67
|
+
|
68
|
+
Look carefully to the above output. You can see that when we use hashes we can
|
69
|
+
no longer be sure of the headers' order. When we are working with tabular data
|
70
|
+
the headers' order can be very important, thus we can use a somewhat similar
|
71
|
+
data structure:
|
72
|
+
|
73
|
+
[
|
74
|
+
[ ['Name', 'Alfred'], ['Gender', 'M'] ],
|
75
|
+
[ ['Name', 'Robert'], ['Gender', 'M'] ],
|
76
|
+
[ ['Name', 'Lucille'], ['Gender', 'F'] ]
|
77
|
+
].to_csv #=> "Name;Gender\nAlfred;M\nRobert;M\nLucille;F\n"
|
78
|
+
|
79
|
+
That's a lot to type... The first example was much simpler...
|
80
|
+
|
81
|
+
There is the <tt>headers</tt> option. You can use it in all the examples above
|
82
|
+
to enable/disable headers from the output. Default is to show (true).
|
83
|
+
|
84
|
+
users = [{ 'Name' => 'Alfred', 'Gender' => 'M' }]
|
85
|
+
users.to_csv(:headers => false)
|
86
|
+
|
87
|
+
|
88
|
+
==== Active Record Objects
|
89
|
+
|
90
|
+
When we're building our data like the previous examples we have very few options
|
91
|
+
compared to what can be passed when converting an array of AR objects. Again,
|
92
|
+
the easiest way:
|
93
|
+
|
94
|
+
# Anywhere in your app.
|
95
|
+
# By default, all available model attributes (DB columns) are going to be used
|
96
|
+
# except timestamps and the primary key of the record
|
97
|
+
@users = User.all
|
98
|
+
File.open('path/to/file.csv', 'w') { |io| io.puts @users.to_csv }
|
99
|
+
|
100
|
+
|
101
|
+
==== Headers
|
102
|
+
|
103
|
+
You can control the order and the text of any header. You can accomplish that
|
104
|
+
in various ways.
|
105
|
+
|
106
|
+
By default all attribute/method names will be sorted in alphabetical order. So
|
107
|
+
imagine a person model have +name+, +age+ and +email+ as attributes, and you
|
108
|
+
want to get the following output:
|
109
|
+
|
110
|
+
Name | E-mail | Age
|
111
|
+
... | ... | ..
|
112
|
+
... | ... | ..
|
113
|
+
|
114
|
+
You can tell <i>to-csv</i> to use a specific locale. If you don't, it uses
|
115
|
+
your app current locale. It will try to translate attributes to a
|
116
|
+
more friendly text by using the scope <tt>[:activerecord, :attributes, <model name>]</tt>.
|
117
|
+
If the translation doesn't exist the header's text is going to be humanized.
|
118
|
+
|
119
|
+
The order of columns can be changed with the option +headers+. The way this
|
120
|
+
option works is very similar to the <tt>plugins</tt> method in your Rails
|
121
|
+
<i>environment.rb</i> file.
|
122
|
+
|
123
|
+
* If you pass +nil+ (default) then headers/columns will be in alphabetical order.
|
124
|
+
* If you pass an empty array or +false+, no headers will be shown.
|
125
|
+
* Instead, if you pass a non empty array, headers will be sorted in the order specified. <tt>:all</tt> can be used as a placeholder for all attributes not explicitly named.
|
126
|
+
|
127
|
+
So, in our example above, we can say:
|
128
|
+
|
129
|
+
@users.to_csv(:headers => [:name, :email, :age])
|
130
|
+
|
131
|
+
Or, using the placeholder +all+, which is not very useful here:
|
132
|
+
|
133
|
+
@users.to_csv(:headers => [:name, :email, :all])
|
134
|
+
|
135
|
+
If you want a completely different result you could, for instance, map all
|
136
|
+
users to a hash. Example:
|
137
|
+
|
138
|
+
# This makes use of a hash to completely change the CSV output.
|
139
|
+
@users.map do |user|
|
140
|
+
{
|
141
|
+
'Name' => user.name,
|
142
|
+
'Age' => user.age,
|
143
|
+
'Total Comments' => user.comments.count
|
144
|
+
}
|
145
|
+
end.to_csv
|
146
|
+
|
147
|
+
|
148
|
+
===== Passing a Block
|
149
|
+
|
150
|
+
Sometimes you may want to change just one value out of six for example. The best
|
151
|
+
way to go is to pass a block so that you don't have to repeat yourself writing
|
152
|
+
five headers and it's obvious values and also loosing I18n translations.
|
153
|
+
|
154
|
+
# The block yields a new OpenStruct for each object in the list. By calling
|
155
|
+
# methods on this struct you can change their default values.
|
156
|
+
@users.to_csv do |csv, user|
|
157
|
+
csv.date_of_birth = user.date_of_birth.to_s(:long)
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
===== A More Complete Example
|
162
|
+
|
163
|
+
# index.html.haml
|
164
|
+
= link_to 'export (CSV)', users_url(:csv)
|
165
|
+
|
166
|
+
# index action in users controller
|
167
|
+
def index
|
168
|
+
@users = User.all
|
169
|
+
respond_to do |format|
|
170
|
+
format.html
|
171
|
+
format.csv { send_data @users.to_csv, :filename => 'users_report.csv' }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
==== Full Customization
|
177
|
+
|
178
|
+
You can always customize the output if you wish by building arrays of hashes,
|
179
|
+
arrays of arrays of bidimensional arrays etc :). Or you can obviously mix
|
180
|
+
anything you want and even use FasterCSV directly.
|
181
|
+
|
182
|
+
@user.to_csv { :only => [:name, :email] }, :col_sep => ','
|
183
|
+
|
184
|
+
There are other options for you to customize the output. Take a look at the
|
185
|
+
<tt>to_csv</tt> method documentation.
|
186
|
+
|
187
|
+
Copyright (c) 2009 Ícaro Leopoldino da Motta, released under the MIT license.
|
188
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/clean'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
load 'test/tasks.rake'
|
7
|
+
|
8
|
+
TO_CSV_VERSION = '1.0.0'
|
9
|
+
CLEAN.include('pkg')
|
10
|
+
|
11
|
+
spec = Gem::Specification.new do |s|
|
12
|
+
s.author = "Ícaro Leopoldino da Motta"
|
13
|
+
s.email = "icaro.ldm@gmail.com"
|
14
|
+
s.platform = Gem::Platform::RUBY
|
15
|
+
s.name = "to-csv"
|
16
|
+
s.summary = s.description = "Convert arrays to CSV (array of hashes, matrixes, ActiveRecord objects etc)."
|
17
|
+
s.homepage = "http://github.com/ilmotta/to-csv"
|
18
|
+
s.version = TO_CSV_VERSION
|
19
|
+
|
20
|
+
s.add_dependency 'fastercsv', '>= 1.5.0'
|
21
|
+
s.add_dependency 'activesupport', '>= 2.3.5'
|
22
|
+
|
23
|
+
s.has_rdoc = true
|
24
|
+
s.require_path = "lib"
|
25
|
+
s.extra_rdoc_files = FileList['*.rdoc']
|
26
|
+
s.files = FileList['init.rb', 'MIT-LICENSE', 'Rakefile', 'lib/**/*', 'test/**/*']
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
30
|
+
pkg.define
|
31
|
+
end
|
32
|
+
|
33
|
+
task :build => [:clean, :repackage]
|
34
|
+
|
35
|
+
task :default => :test
|
36
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'to_csv'
|
data/lib/to_csv.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'fastercsv'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'active_support'
|
4
|
+
require 'to_csv/csv_converter'
|
5
|
+
|
6
|
+
module ToCSV
|
7
|
+
mattr_accessor :byte_order_marker, :locale, :primary_key, :timestamps
|
8
|
+
mattr_accessor :csv_options
|
9
|
+
self.csv_options = { :col_sep => ';' }
|
10
|
+
end
|
11
|
+
|
12
|
+
class Array
|
13
|
+
|
14
|
+
#
|
15
|
+
# Returns a CSV string.
|
16
|
+
#
|
17
|
+
# ==== Available Options:
|
18
|
+
#
|
19
|
+
# 1. *options*
|
20
|
+
# +byte_order_marker+::
|
21
|
+
# If true, a Byte Order Maker (BOM) will be inserted at
|
22
|
+
# the beginning of the output. It's useful if you want to force
|
23
|
+
# MS Excel to read UTF-8 encoded files, otherwise it will just
|
24
|
+
# decode them as Latin1 (ISO-8859-1). Default: +false+.
|
25
|
+
# +only+::
|
26
|
+
# Same behavior as with the +to_json+ method.
|
27
|
+
# +except+::
|
28
|
+
# Same as +only+ option.
|
29
|
+
# +methods+::
|
30
|
+
# Accepts a symbol or an array with additional methods to be included.
|
31
|
+
# +timestamps+::
|
32
|
+
# Include timestamps +created_at+, +created_on+, +updated_at+ and
|
33
|
+
# +updated_on+. If false Default: +false+.
|
34
|
+
# +primary_key+::
|
35
|
+
# If +true+ the object's primary key will be added as an attribute,
|
36
|
+
# which in turn will be mapped to a CSV column. Default: +false+.
|
37
|
+
# +headers+::
|
38
|
+
# If this list is <tt>nil</tt> then headers will be in alphabetical order.
|
39
|
+
# If it is an empty array or <tt>false</tt>, no headers will be shown.
|
40
|
+
# If it is non empty, headers will be sorted in the order specified.
|
41
|
+
# <tt>:all</tt> can be used as a placeholder for all attributes not
|
42
|
+
# explicitly named.
|
43
|
+
# +locale+::
|
44
|
+
# In a Rails environment, it will automatically take the current locale
|
45
|
+
# and will use it to translate the columns to friendly headers.
|
46
|
+
# Methods will be translated from
|
47
|
+
# <tt>[:activerecord, :attributes, <model>]</tt>. If the translation
|
48
|
+
# is missing, then a simple humanize will be called.
|
49
|
+
#
|
50
|
+
# 2. *csv_options*
|
51
|
+
# Accepts all options listed in <tt>FasterCSV::DEFAULT_OPTIONS</tt>.
|
52
|
+
#
|
53
|
+
def to_csv(options = {}, csv_options = {}, &block)
|
54
|
+
return '' if empty?
|
55
|
+
csv_converter = ToCSV::Converter.new(self, options, csv_options, &block)
|
56
|
+
csv_converter.to_csv
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module ToCSV
|
2
|
+
class Converter
|
3
|
+
|
4
|
+
def initialize(data, options = {}, csv_options = {}, &block)
|
5
|
+
@opts = options.to_options.reverse_merge({
|
6
|
+
:byte_order_marker => ToCSV.byte_order_marker,
|
7
|
+
:locale => ToCSV.locale || ::I18n.locale,
|
8
|
+
:primary_key => ToCSV.primary_key,
|
9
|
+
:timestamps => ToCSV.timestamps
|
10
|
+
})
|
11
|
+
|
12
|
+
@opts[:only] = Array(@opts[:only]).map(&:to_s)
|
13
|
+
@opts[:except] = Array(@opts[:except]).map(&:to_s)
|
14
|
+
@opts[:methods] = Array(@opts[:methods]).map(&:to_s)
|
15
|
+
|
16
|
+
@data = data
|
17
|
+
@block = block
|
18
|
+
@csv_options = csv_options.to_options.reverse_merge(ToCSV.csv_options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_csv
|
22
|
+
build_headers_and_rows
|
23
|
+
|
24
|
+
output = ::FasterCSV.generate(@csv_options) do |csv|
|
25
|
+
csv << @header_row if @header_row.try(:any?)
|
26
|
+
@rows.each { |row| csv << row }
|
27
|
+
end
|
28
|
+
|
29
|
+
@opts[:byte_order_marker] ? "\xEF\xBB\xBF#{output}" : output
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def build_headers_and_rows
|
35
|
+
send "headers_and_rows_from_#{ discover_data_type }"
|
36
|
+
end
|
37
|
+
|
38
|
+
def discover_data_type
|
39
|
+
test_data = @data.first
|
40
|
+
return 'ar_object' if instance_of_active_record? test_data
|
41
|
+
return 'hash' if test_data.is_a? Hash
|
42
|
+
return 'unidimensional_array' if test_data.is_a?(Array) && !test_data.first.is_a?(Array)
|
43
|
+
return 'bidimensional_array' if test_data.is_a?(Array) && test_data.first.is_a?(Array) && test_data.first.size == 2
|
44
|
+
'simple_data'
|
45
|
+
end
|
46
|
+
|
47
|
+
def instance_of_active_record?(obj)
|
48
|
+
obj.class.base_class.superclass == ActiveRecord::Base
|
49
|
+
rescue Exception
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
def headers_and_rows_from_simple_data
|
54
|
+
@header_row = nil
|
55
|
+
@rows = [@data.dup]
|
56
|
+
end
|
57
|
+
|
58
|
+
def headers_and_rows_from_hash
|
59
|
+
@header_row = @data.first.keys if display_headers?
|
60
|
+
@rows = @data.map(&:values)
|
61
|
+
end
|
62
|
+
|
63
|
+
def headers_and_rows_from_unidimensional_array
|
64
|
+
@header_row = @data.first if display_headers?
|
65
|
+
@rows = @data[1..-1]
|
66
|
+
end
|
67
|
+
|
68
|
+
def headers_and_rows_from_bidimensional_array
|
69
|
+
@header_row = @data.first.map(&:first) if display_headers?
|
70
|
+
@rows = @data.map { |array| array.map(&:last) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def headers_and_rows_from_ar_object
|
74
|
+
attributes = sort_attributes(filter_attributes(attribute_names))
|
75
|
+
@header_row = human_attribute_names(attributes) if display_headers?
|
76
|
+
|
77
|
+
@rows = if @block
|
78
|
+
@data.map do |item|
|
79
|
+
os = OpenStruct.new
|
80
|
+
@block.call(os, item)
|
81
|
+
marshal_dump = os.marshal_dump
|
82
|
+
attributes.map { |attribute| marshal_dump[attribute.to_sym] || try_formatting_date(item.send(attribute)) }
|
83
|
+
end
|
84
|
+
else
|
85
|
+
@data.map do |item|
|
86
|
+
attributes.map { |attribute| try_formatting_date item.send(attribute) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def display_headers?
|
92
|
+
@opts[:headers].nil? || (Array(@opts[:headers]).any? && Array(@opts[:headers]).all? { |h| h != false })
|
93
|
+
end
|
94
|
+
|
95
|
+
def human_attribute_names(attributes)
|
96
|
+
@opts[:locale] ? translate(attributes) : humanize(attributes)
|
97
|
+
end
|
98
|
+
|
99
|
+
def humanize(attributes)
|
100
|
+
attributes.map(&:humanize)
|
101
|
+
end
|
102
|
+
|
103
|
+
def translate(attributes)
|
104
|
+
::I18n.with_options :locale => @opts[:locale], :scope => [:activerecord, :attributes, @data.first.class.to_s.underscore] do |locale|
|
105
|
+
attributes.map { |attribute| locale.t(attribute, :default => attribute.humanize) }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def try_formatting_date(value)
|
110
|
+
is_a_date?(value) ? value.to_s : value
|
111
|
+
end
|
112
|
+
|
113
|
+
def is_a_date?(value)
|
114
|
+
value.is_a?(Time) || value.is_a?(Date) || value.is_a?(DateTime)
|
115
|
+
end
|
116
|
+
|
117
|
+
def primary_key_filter(attributes)
|
118
|
+
return attributes if @opts[:primary_key]
|
119
|
+
attributes - Array(@data.first.class.primary_key.to_s)
|
120
|
+
end
|
121
|
+
|
122
|
+
def timestamps_filter(attributes)
|
123
|
+
return attributes if @opts[:timestamps]
|
124
|
+
return attributes if (@opts[:only] + @opts[:except]).any? { |attribute| timestamps.include? attribute }
|
125
|
+
attributes - timestamps
|
126
|
+
end
|
127
|
+
|
128
|
+
def timestamps
|
129
|
+
%w[ created_at updated_at created_on updated_on ]
|
130
|
+
end
|
131
|
+
|
132
|
+
def methods_filter(attributes)
|
133
|
+
attributes | @opts[:methods]
|
134
|
+
end
|
135
|
+
|
136
|
+
def only_filter(attributes)
|
137
|
+
return attributes if @opts[:only].empty?
|
138
|
+
attributes & @opts[:only]
|
139
|
+
end
|
140
|
+
|
141
|
+
def except_filter(attributes)
|
142
|
+
attributes - @opts[:except]
|
143
|
+
end
|
144
|
+
|
145
|
+
def attribute_names
|
146
|
+
@data.first.attribute_names.map(&:to_s)
|
147
|
+
end
|
148
|
+
|
149
|
+
def filter_attributes(attributes)
|
150
|
+
attributes = methods_filter(attributes)
|
151
|
+
attributes = primary_key_filter(attributes)
|
152
|
+
attributes = timestamps_filter(attributes)
|
153
|
+
attributes = @opts[:only].any?? only_filter(attributes) : except_filter(attributes)
|
154
|
+
attributes
|
155
|
+
end
|
156
|
+
|
157
|
+
def sort_attributes(attributes)
|
158
|
+
attributes = attributes.map(&:to_s).sort
|
159
|
+
return attributes if @opts[:headers].nil?
|
160
|
+
headers = Array(@opts[:headers]).map(&:to_s)
|
161
|
+
headers.delete_if { |attribute| attribute == 'false' }
|
162
|
+
if index = headers.index('all')
|
163
|
+
(headers & attributes).insert(index, (attributes - headers)).flatten
|
164
|
+
else
|
165
|
+
headers + (attributes - headers)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
data/test/database.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
the_dark_knight:
|
2
|
+
id: 1
|
3
|
+
title: The Dark Knight
|
4
|
+
subtitles: English, French, Spanish
|
5
|
+
studio: Warner Home Video
|
6
|
+
number_of_discs: 2
|
7
|
+
dvd_release_date: <%= DateTime.new 2008, 12, 9 %>
|
8
|
+
created_at: <%= Date.new 2009, 12, 12 %>
|
9
|
+
updated_at: <%= Date.new 2009, 12, 12 %>
|
10
|
+
|
11
|
+
2001_space_odyssey:
|
12
|
+
id: 2
|
13
|
+
title: 2001 - A Space Odyssey
|
14
|
+
subtitles: English, Spanish, French
|
15
|
+
studio: Warner Home Video
|
16
|
+
number_of_discs: 1
|
17
|
+
dvd_release_date: <%= DateTime.new 2007, 10, 23 %>
|
18
|
+
created_at: <%= Date.new 2009, 11, 11 %>
|
19
|
+
updated_at: <%= Date.new 2009, 11, 11 %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
create_table :movies, :force => true do |t|
|
3
|
+
t.string :title, :subtitles, :studio
|
4
|
+
t.integer :number_of_discs
|
5
|
+
t.datetime :dvd_release_date
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
create_table :people, :primary_key => :cod, :force => true do |t|
|
10
|
+
t.string :name
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'lib/activerecord_test_connector'
|
2
|
+
|
3
|
+
class ActiveRecordTestCase < Test::Unit::TestCase
|
4
|
+
if defined? ActiveSupport::Testing::SetupAndTeardown
|
5
|
+
include ActiveSupport::Testing::SetupAndTeardown
|
6
|
+
end
|
7
|
+
|
8
|
+
if defined? ActiveRecord::TestFixtures
|
9
|
+
include ActiveRecord::TestFixtures
|
10
|
+
end
|
11
|
+
|
12
|
+
self.fixture_path = ActiveRecordTestConnector::FIXTURES_PATH
|
13
|
+
self.use_transactional_fixtures = true
|
14
|
+
|
15
|
+
def self.fixtures(*args)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
ActiveRecordTestConnector.setup
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'active_record/fixtures'
|
4
|
+
|
5
|
+
class ActiveRecordTestConnector
|
6
|
+
FIXTURES_PATH = File.join(File.dirname(__FILE__), '..', 'fixtures')
|
7
|
+
|
8
|
+
def self.setup
|
9
|
+
setup_connection
|
10
|
+
load_schema
|
11
|
+
add_load_path FIXTURES_PATH
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def self.add_load_path(path)
|
17
|
+
dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
|
18
|
+
dep.load_paths.unshift path
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load_schema
|
22
|
+
ActiveRecord::Base.silence do
|
23
|
+
ActiveRecord::Migration.verbose = false
|
24
|
+
load File.join(FIXTURES_PATH, 'schema.rb')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.setup_connection
|
29
|
+
configurations = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'database.yml'))
|
30
|
+
ActiveRecord::Base.establish_connection configurations['sqlite3']
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
"en-US":
|
2
|
+
date:
|
3
|
+
formats:
|
4
|
+
default: "%Y-%m-%d"
|
5
|
+
short: "%e %b"
|
6
|
+
long: "%B %e, %Y"
|
7
|
+
only_day: "%e"
|
8
|
+
|
9
|
+
day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
|
10
|
+
abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
|
11
|
+
month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
|
12
|
+
abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
|
13
|
+
order: [ :year, :month, :day ]
|
14
|
+
|
15
|
+
time:
|
16
|
+
formats:
|
17
|
+
default: "%a %b %d %H:%M:%S %Z %Y"
|
18
|
+
time: "%H:%M"
|
19
|
+
short: "%d %b %H:%M"
|
20
|
+
long: "%B %d, %Y %H:%M"
|
21
|
+
only_second: "%S"
|
22
|
+
|
23
|
+
datetime:
|
24
|
+
formats:
|
25
|
+
default: "%Y-%m-%dT%H:%M:%S%Z"
|
26
|
+
|
27
|
+
am: 'am'
|
28
|
+
pm: 'pm'
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# formatos de data e hora
|
2
|
+
date:
|
3
|
+
formats:
|
4
|
+
default: "%d/%m/%Y"
|
5
|
+
short: "%d de %B"
|
6
|
+
long: "%d de %B de %Y"
|
7
|
+
|
8
|
+
day_names: [Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sábado]
|
9
|
+
abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sáb]
|
10
|
+
month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
|
11
|
+
abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
|
12
|
+
order: [ :day, :month, :year ]
|
13
|
+
|
14
|
+
time:
|
15
|
+
formats:
|
16
|
+
default: "%A, %d de %B de %Y, %H:%M h"
|
17
|
+
short: "%d/%m, %H:%M h"
|
18
|
+
long: "%A, %d de %B de %Y, %H:%M h"
|
19
|
+
am: ''
|
20
|
+
pm: ''
|
21
|
+
|
22
|
+
# date helper distanci em palavras
|
23
|
+
datetime:
|
24
|
+
distance_in_words:
|
25
|
+
half_a_minute: 'meio minuto'
|
26
|
+
less_than_x_seconds:
|
27
|
+
one: 'menos de 1 segundo'
|
28
|
+
other: 'menos de {{count}} segundos'
|
29
|
+
|
30
|
+
x_seconds:
|
31
|
+
one: '1 segundo'
|
32
|
+
other: '{{count}} segundos'
|
33
|
+
|
34
|
+
less_than_x_minutes:
|
35
|
+
one: 'menos de um minuto'
|
36
|
+
other: 'menos de {{count}} minutos'
|
37
|
+
|
38
|
+
x_minutes:
|
39
|
+
one: '1 minuto'
|
40
|
+
other: '{{count}} minutos'
|
41
|
+
|
42
|
+
about_x_hours:
|
43
|
+
one: 'aproximadamente 1 hora'
|
44
|
+
other: 'aproximadamente {{count}} horas'
|
45
|
+
|
46
|
+
x_days:
|
47
|
+
one: '1 dia'
|
48
|
+
other: '{{count}} dias'
|
49
|
+
|
50
|
+
about_x_months:
|
51
|
+
one: 'aproximadamente 1 mês'
|
52
|
+
other: 'aproximadamente {{count}} meses'
|
53
|
+
|
54
|
+
x_months:
|
55
|
+
one: '1 mês'
|
56
|
+
other: '{{count}} meses'
|
57
|
+
|
58
|
+
about_x_years:
|
59
|
+
one: 'aproximadamente 1 ano'
|
60
|
+
other: 'aproximadamente {{count}} anos'
|
61
|
+
|
62
|
+
over_x_years:
|
63
|
+
one: 'mais de 1 ano'
|
64
|
+
other: 'mais de {{count}} anos'
|
65
|
+
prompts:
|
66
|
+
year: "Ano"
|
67
|
+
month: "Mês"
|
68
|
+
day: "Dia"
|
69
|
+
hour: "Hora"
|
70
|
+
minute: "Minuto"
|
71
|
+
second: "Segundos"
|
72
|
+
|
73
|
+
# numeros
|
74
|
+
number:
|
75
|
+
format:
|
76
|
+
precision: 3
|
77
|
+
separator: ','
|
78
|
+
delimiter: '.'
|
79
|
+
currency:
|
80
|
+
format:
|
81
|
+
unit: 'R$'
|
82
|
+
precision: 2
|
83
|
+
format: '%u %n'
|
84
|
+
separator: ','
|
85
|
+
delimiter: '.'
|
86
|
+
percentage:
|
87
|
+
format:
|
88
|
+
delimiter: '.'
|
89
|
+
precision:
|
90
|
+
format:
|
91
|
+
delimiter: '.'
|
92
|
+
human:
|
93
|
+
format:
|
94
|
+
precision: 1
|
95
|
+
delimiter: '.'
|
96
|
+
storage_units:
|
97
|
+
format: "%n %u"
|
98
|
+
units:
|
99
|
+
byte:
|
100
|
+
one: "Byte"
|
101
|
+
other: "Bytes"
|
102
|
+
kb: "KB"
|
103
|
+
mb: "MB"
|
104
|
+
gb: "GB"
|
105
|
+
tb: "TB"
|
106
|
+
|
107
|
+
# Used in array.to_sentence.
|
108
|
+
support:
|
109
|
+
array:
|
110
|
+
words_connector: ", "
|
111
|
+
two_words_connector: " e "
|
112
|
+
last_word_connector: " e "
|
113
|
+
|
114
|
+
# Active Record
|
115
|
+
activerecord:
|
116
|
+
errors:
|
117
|
+
template:
|
118
|
+
header:
|
119
|
+
one: "Não foi possível gravar {{model}}: 1 erro"
|
120
|
+
other: "Não foi possível gravar {{model}}: {{count}} erros."
|
121
|
+
body: "Por favor, verifique o(s) seguinte(s) campo(s):"
|
122
|
+
messages:
|
123
|
+
inclusion: "não está incluído na lista"
|
124
|
+
exclusion: "não está disponível"
|
125
|
+
invalid: "não é válido"
|
126
|
+
confirmation: "não está de acordo com a confirmação"
|
127
|
+
accepted: "deve ser aceito"
|
128
|
+
empty: "não pode ficar vazio"
|
129
|
+
blank: "não pode ficar em branco"
|
130
|
+
too_long: "é muito longo (máximo: {{count}} caracteres)"
|
131
|
+
too_short: "é muito curto (mínimo: {{count}} caracteres)"
|
132
|
+
wrong_length: "não possui o tamanho esperado ({{count}} caracteres)"
|
133
|
+
taken: "já está em uso"
|
134
|
+
not_a_number: "não é um número"
|
135
|
+
greater_than: "deve ser maior do que {{count}}"
|
136
|
+
greater_than_or_equal_to: "deve ser maior ou igual a {{count}}"
|
137
|
+
equal_to: "deve ser igual a {{count}}"
|
138
|
+
less_than: "deve ser menor do que {{count}}"
|
139
|
+
less_than_or_equal_to: "deve ser menor ou igual a {{count}}"
|
140
|
+
odd: "deve ser ímpar"
|
141
|
+
even: "deve ser par"
|
142
|
+
attributes:
|
143
|
+
movie:
|
144
|
+
title: Título
|
145
|
+
subtitles: Legendas
|
146
|
+
number_of_discs: Número de Discos
|
147
|
+
dvd_release_date: Data de Lançamento do DVD
|
data/test/tasks.rake
ADDED
data/test/to_csv_test.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'test/lib/activerecord_test_case'
|
3
|
+
require 'test/lib/load_fixtures'
|
4
|
+
|
5
|
+
class ToCsvTest < ActiveRecordTestCase
|
6
|
+
fixtures :movies
|
7
|
+
|
8
|
+
def setup
|
9
|
+
ToCSV.byte_order_marker = ToCSV.locale = ToCSV.primary_key = ToCSV.timestamps = false
|
10
|
+
ToCSV.csv_options = { :col_sep => ';' }
|
11
|
+
@movies = Movie.all
|
12
|
+
@people = Person.all(:order => :name)
|
13
|
+
store_translations('en-US', 'pt-BR')
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_simple_array
|
17
|
+
csv = ['Alfred Hitchcock', 'Robert Mitchum', 'Lucille Ball'].to_csv
|
18
|
+
assert_equal "Alfred Hitchcock;Robert Mitchum;Lucille Ball\n", csv
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_matrix
|
22
|
+
csv = [
|
23
|
+
['Name', 'Age'],
|
24
|
+
['Icaro', 22],
|
25
|
+
['Gabriel', 16]
|
26
|
+
].to_csv
|
27
|
+
|
28
|
+
assert_equal "Name;Age\nIcaro;22\nGabriel;16\n", csv
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_array_of_matrixes
|
32
|
+
csv = [
|
33
|
+
[
|
34
|
+
['Name', 'Alfred'],
|
35
|
+
['Gender', 'M']
|
36
|
+
],
|
37
|
+
[
|
38
|
+
['Name', 'Robert'],
|
39
|
+
['Gender', 'M']
|
40
|
+
],
|
41
|
+
[
|
42
|
+
['Name', 'Lucille'],
|
43
|
+
['Gender', 'F']
|
44
|
+
]
|
45
|
+
].to_csv
|
46
|
+
|
47
|
+
assert_equal "Name;Gender\nAlfred;M\nRobert;M\nLucille;F\n", csv
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_array_of_hashes
|
51
|
+
csv = [
|
52
|
+
{
|
53
|
+
'Name' => 'Icaro',
|
54
|
+
'E-mail' => 'icaro.ldm@gmail.com'
|
55
|
+
},
|
56
|
+
{
|
57
|
+
'Name' => 'Gabriel',
|
58
|
+
'E-mail' => 'gaby@gmail.com'
|
59
|
+
}
|
60
|
+
].to_csv
|
61
|
+
|
62
|
+
order_01 = "Name;E-mail\nIcaro;icaro.ldm@gmail.com\nGabriel;gaby@gmail.com\n"
|
63
|
+
order_02 = "E-mail;Name\nicaro.ldm@gmail.com;Icaro\ngaby@gmail.com;Gabriel\n"
|
64
|
+
|
65
|
+
|
66
|
+
assert order_01 == csv || order_02 == csv
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_without_options
|
70
|
+
assert_equal "Dvd release date;Number of discs;Studio;Subtitles;Title\nMon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_only_option
|
74
|
+
assert_equal "Title\nThe Dark Knight\n2001 - A Space Odyssey\n", @movies.to_csv(:only => :title)
|
75
|
+
assert_equal @movies.to_csv(:only => :title), @movies.to_csv(:only => [:title])
|
76
|
+
assert_equal "Studio;Title\nWarner Home Video;The Dark Knight\nWarner Home Video;2001 - A Space Odyssey\n", @movies.to_csv(:only => [:title, :studio])
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_except_option
|
80
|
+
assert_equal "Dvd release date;Number of discs;Subtitles;Title\nMon Dec 08 22:00:00 -0200 2008;2;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:except => :studio)
|
81
|
+
assert_equal @movies.to_csv(:except => :studio), @movies.to_csv(:except => [:studio])
|
82
|
+
assert_equal "Dvd release date;Number of discs;Studio\nMon Dec 08 22:00:00 -0200 2008;2;Warner Home Video\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video\n", @movies.to_csv(:except => [:title, :subtitles])
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_timestamps_option
|
86
|
+
assert_equal "Created at;Number of discs\nSat Dec 12 00:00:00 -0200 2009;2\nWed Nov 11 00:00:00 -0200 2009;1\n", @movies.to_csv(:except => [:title, :subtitles, :studio, :dvd_release_date, :updated_at])
|
87
|
+
assert_equal "Created at;Number of discs\nSat Dec 12 00:00:00 -0200 2009;2\nWed Nov 11 00:00:00 -0200 2009;1\n", @movies.to_csv(:except => [:title, :subtitles, :studio, :dvd_release_date, :updated_at], :timestamps => false)
|
88
|
+
assert_equal "Created at;Number of discs\nSat Dec 12 00:00:00 -0200 2009;2\nWed Nov 11 00:00:00 -0200 2009;1\n", @movies.to_csv(:except => [:title, :subtitles, :studio, :dvd_release_date, :updated_at], :timestamps => true)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_headers_option
|
92
|
+
assert_equal "Icaro;23\n", ['Icaro', 23].to_csv(:headers => false)
|
93
|
+
assert_equal "Icaro;23\n", [ [:name, :age], ['Icaro', 23] ].to_csv(:headers => false)
|
94
|
+
assert_equal "Icaro;23\n", [ [[:name, 'Icaro'], [:age, 23]] ].to_csv(:headers => false)
|
95
|
+
assert_equal "Subtitles;Dvd release date;Number of discs;Studio;Title\nEnglish, French, Spanish;Mon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;The Dark Knight\nEnglish, Spanish, French;Mon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;2001 - A Space Odyssey\n", @movies.to_csv(:headers => :subtitles)
|
96
|
+
assert_equal "Mon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:headers => false)
|
97
|
+
assert_equal "Mon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:headers => [false])
|
98
|
+
assert_equal "Mon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:headers => [])
|
99
|
+
assert_equal "Title;Number of discs\nThe Dark Knight;2\n2001 - A Space Odyssey;1\n", @movies.to_csv(:headers => [:title, :number_of_discs], :only => [:number_of_discs, :title])
|
100
|
+
assert_equal "Title;Number of discs\nThe Dark Knight;2\n2001 - A Space Odyssey;1\n", @movies.to_csv(:headers => [:title, :all], :only => [:number_of_discs, :title])
|
101
|
+
assert_equal "Title;Number of discs\nThe Dark Knight;2\n2001 - A Space Odyssey;1\n", @movies.to_csv(:headers => :title, :only => [:number_of_discs, :title])
|
102
|
+
assert_equal "Dvd release date;Number of discs;Studio;Subtitles;Title\nMon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:headers => :all)
|
103
|
+
assert_equal "Dvd release date;Number of discs;Studio;Subtitles;Title\nMon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:headers => [:all])
|
104
|
+
assert_equal "Dvd release date;Studio;Subtitles;Title;Number of discs\nMon Dec 08 22:00:00 -0200 2008;Warner Home Video;English, French, Spanish;The Dark Knight;2\nMon Oct 22 22:00:00 -0200 2007;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey;1\n", @movies.to_csv(:headers => [:all, :subtitles, :title, :number_of_discs])
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_locale_option
|
108
|
+
assert_equal "Data de Lançamento do DVD;Número de Discos;Studio;Legendas;Título\nMon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:locale => 'pt-BR')
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_primary_key_option
|
112
|
+
assert_equal "Name\nGabriel\nIcaro\n", @people.to_csv
|
113
|
+
assert_equal "Name\nGabriel\nIcaro\n", @people.to_csv(:primary_key => false)
|
114
|
+
assert_equal "Name\nGabriel\nIcaro\n", @people.to_csv(:primary_key => nil)
|
115
|
+
assert_equal "Cod;Name\n2;Gabriel\n1;Icaro\n", @people.to_csv(:primary_key => true)
|
116
|
+
assert_equal "Number of discs\n2\n1\n", @movies.to_csv(:primary_key => true, :only => [:number_of_discs])
|
117
|
+
assert_equal "Number of discs\n2\n1\n", @movies.to_csv(:only => [:number_of_discs, :id])
|
118
|
+
assert_equal "Dvd release date;Number of discs;Studio;Subtitles;Title\nMon Dec 08 22:00:00 -0200 2008;2;Warner Home Video;English, French, Spanish;The Dark Knight\nMon Oct 22 22:00:00 -0200 2007;1;Warner Home Video;English, Spanish, French;2001 - A Space Odyssey\n", @movies.to_csv(:primary_key => true, :except => :id)
|
119
|
+
assert_equal "Name\nGabriel\nIcaro\n", @people.to_csv(:methods => :cod)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_block_passed
|
123
|
+
csv = @movies.to_csv do |csv, movie|
|
124
|
+
csv.title = movie.title.upcase
|
125
|
+
csv.number_of_discs = "%02d" % movie.number_of_discs
|
126
|
+
end
|
127
|
+
assert_equal "Dvd release date;Number of discs;Studio;Subtitles;Title\nMon Dec 08 22:00:00 -0200 2008;02;Warner Home Video;English, French, Spanish;THE DARK KNIGHT\nMon Oct 22 22:00:00 -0200 2007;01;Warner Home Video;English, Spanish, French;2001 - A SPACE ODYSSEY\n", csv
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_default_settings
|
131
|
+
ToCSV.byte_order_marker = true
|
132
|
+
ToCSV.locale = 'pt-BR'
|
133
|
+
ToCSV.primary_key = true
|
134
|
+
ToCSV.timestamps = true
|
135
|
+
ToCSV.csv_options = { :col_sep => ',' }
|
136
|
+
assert_equal "\xEF\xBB\xBFCreated at,Data de Lançamento do DVD,Id,Número de Discos,Studio,Legendas,Título,Updated at\nSat Dec 12 00:00:00 -0200 2009,Mon Dec 08 22:00:00 -0200 2008,1,2,Warner Home Video,\"English, French, Spanish\",The Dark Knight,Sat Dec 12 00:00:00 -0200 2009\n", Array(@movies.first).to_csv
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def store_translations(*locales)
|
142
|
+
locale_path = File.join(File.dirname(__FILE__), 'locales')
|
143
|
+
locales.each do |locale|
|
144
|
+
I18n.backend.store_translations locale, YAML.load_file(File.join(locale_path, "#{ locale }.yml"))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: to-csv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "\xC3\x8Dcaro Leopoldino da Motta"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-23 00:00:00 -02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: fastercsv
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.5.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.3.5
|
34
|
+
version:
|
35
|
+
description: Convert arrays to CSV (array of hashes, matrixes, ActiveRecord objects etc).
|
36
|
+
email: icaro.ldm@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- CHANGELOG.rdoc
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- init.rb
|
46
|
+
- MIT-LICENSE
|
47
|
+
- Rakefile
|
48
|
+
- lib/to_csv/csv_converter.rb
|
49
|
+
- lib/to_csv.rb
|
50
|
+
- test/database.yml
|
51
|
+
- test/fixtures/movie.rb
|
52
|
+
- test/fixtures/movies.yml
|
53
|
+
- test/fixtures/people.yml
|
54
|
+
- test/fixtures/person.rb
|
55
|
+
- test/fixtures/schema.rb
|
56
|
+
- test/lib/activerecord_test_case.rb
|
57
|
+
- test/lib/activerecord_test_connector.rb
|
58
|
+
- test/lib/load_fixtures.rb
|
59
|
+
- test/locales/en-US.yml
|
60
|
+
- test/locales/pt-BR.yml
|
61
|
+
- test/tasks.rake
|
62
|
+
- test/to_csv_test.rb
|
63
|
+
- CHANGELOG.rdoc
|
64
|
+
- README.rdoc
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: http://github.com/ilmotta/to-csv
|
67
|
+
licenses: []
|
68
|
+
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.3.5
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Convert arrays to CSV (array of hashes, matrixes, ActiveRecord objects etc).
|
93
|
+
test_files: []
|
94
|
+
|