to-csv 1.0.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/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
|
+
|