comma 4.2.0 → 4.5.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -1
- data/.rubocop_todo.yml +3 -364
- data/.travis.yml +26 -57
- data/Appraisals +31 -1
- data/Gemfile +5 -1
- data/Gemfile.lock +54 -36
- data/README.md +3 -3
- data/Rakefile +2 -0
- data/comma.gemspec +13 -14
- data/gemfiles/active5.0.7.2.gemfile +12 -0
- data/gemfiles/active5.0.7.2.gemfile.lock +113 -0
- data/gemfiles/active5.1.7.gemfile +12 -0
- data/gemfiles/active5.1.7.gemfile.lock +113 -0
- data/gemfiles/active5.2.4.3.gemfile +12 -0
- data/gemfiles/{active5.2.0.gemfile.lock → active5.2.4.3.gemfile.lock} +48 -41
- data/gemfiles/active6.0.3.1.gemfile +12 -0
- data/gemfiles/active6.0.3.1.gemfile.lock +113 -0
- data/gemfiles/active6.1.0.gemfile +12 -0
- data/gemfiles/active6.1.0.gemfile.lock +112 -0
- data/gemfiles/{rails5.0.1.gemfile → rails5.0.7.2.gemfile} +5 -2
- data/gemfiles/rails5.0.7.2.gemfile.lock +204 -0
- data/gemfiles/{rails4.2.8.gemfile → rails5.1.7.gemfile} +5 -2
- data/gemfiles/{rails5.2.0.gemfile.lock → rails5.1.7.gemfile.lock} +97 -97
- data/gemfiles/rails5.2.4.3.gemfile +14 -0
- data/gemfiles/rails5.2.4.3.gemfile.lock +212 -0
- data/gemfiles/{rails4.1.16.gemfile → rails6.0.3.1.gemfile} +4 -2
- data/gemfiles/rails6.0.3.1.gemfile.lock +227 -0
- data/gemfiles/{rails4.0.13.gemfile → rails6.1.0.gemfile} +4 -2
- data/gemfiles/rails6.1.0.gemfile.lock +230 -0
- data/init.rb +2 -0
- data/lib/comma.rb +26 -35
- data/lib/comma/array.rb +2 -0
- data/lib/comma/data_extractor.rb +5 -5
- data/lib/comma/data_mapper_collection.rb +9 -3
- data/lib/comma/extractor.rb +3 -5
- data/lib/comma/generator.rb +11 -11
- data/lib/comma/header_extractor.rb +19 -14
- data/lib/comma/mongoid.rb +10 -7
- data/lib/comma/object.rb +5 -1
- data/lib/comma/relation.rb +16 -10
- data/lib/comma/version.rb +3 -1
- data/spec/comma/comma_spec.rb +71 -50
- data/spec/comma/data_extractor_spec.rb +13 -17
- data/spec/comma/header_extractor_spec.rb +7 -13
- data/spec/comma/rails/active_record_spec.rb +34 -33
- data/spec/comma/rails/data_mapper_collection_spec.rb +4 -3
- data/spec/comma/rails/mongoid_spec.rb +8 -7
- data/spec/controllers/users_controller_spec.rb +83 -70
- data/spec/non_rails_app/ruby_classes.rb +13 -6
- data/spec/rails_app/active_record/config.rb +3 -1
- data/spec/rails_app/active_record/models.rb +4 -2
- data/spec/rails_app/data_mapper/config.rb +2 -0
- data/spec/rails_app/mongoid/config.rb +4 -2
- data/spec/rails_app/rails_app.rb +12 -11
- data/spec/rails_app/tmp/.gitkeep +0 -0
- data/spec/spec_helper.rb +21 -4
- metadata +31 -48
- data/gemfiles/active4.0.13.gemfile +0 -10
- data/gemfiles/active4.0.13.gemfile.lock +0 -107
- data/gemfiles/active4.1.16.gemfile +0 -10
- data/gemfiles/active4.1.16.gemfile.lock +0 -106
- data/gemfiles/active4.2.8.gemfile +0 -10
- data/gemfiles/active4.2.8.gemfile.lock +0 -105
- data/gemfiles/active5.0.1.gemfile +0 -10
- data/gemfiles/active5.0.1.gemfile.lock +0 -104
- data/gemfiles/active5.1.0.gemfile +0 -10
- data/gemfiles/active5.1.0.gemfile.lock +0 -104
- data/gemfiles/active5.2.0.gemfile +0 -10
- data/gemfiles/rails4.0.13.gemfile.lock +0 -158
- data/gemfiles/rails4.1.16.gemfile.lock +0 -162
- data/gemfiles/rails4.2.8.gemfile.lock +0 -187
- data/gemfiles/rails5.0.1.gemfile.lock +0 -194
- data/gemfiles/rails5.1.0.gemfile +0 -11
- data/gemfiles/rails5.1.0.gemfile.lock +0 -194
- data/gemfiles/rails5.2.0.gemfile +0 -11
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
# comma do
|
@@ -8,7 +10,6 @@ require 'spec_helper'
|
|
8
10
|
# end
|
9
11
|
|
10
12
|
describe Comma::DataExtractor do # rubocop:disable Metrics/BlockLength
|
11
|
-
|
12
13
|
before do
|
13
14
|
@isbn = Isbn.new('123123123', '321321321')
|
14
15
|
@book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
|
@@ -17,47 +18,42 @@ describe Comma::DataExtractor do # rubocop:disable Metrics/BlockLength
|
|
17
18
|
end
|
18
19
|
|
19
20
|
describe 'when no parameters are provided' do
|
20
|
-
|
21
21
|
it 'should use the string value returned by sending the method name on the object' do
|
22
|
-
@data.
|
22
|
+
expect(@data).to include('Language and Implementation')
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe 'when given a string description as a parameter' do
|
27
|
-
|
28
27
|
it 'should use the string value returned by sending the method name on the object' do
|
29
|
-
@data.
|
28
|
+
expect(@data).to include('Smalltalk-80')
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
32
|
describe 'when an hash is passed as a parameter' do
|
34
|
-
|
35
33
|
describe 'with a string value' do
|
36
|
-
|
37
34
|
it 'should use the string value, returned by sending the hash key to the object' do
|
38
|
-
@data.
|
39
|
-
@data.
|
35
|
+
expect(@data).to include('123123123')
|
36
|
+
expect(@data).to include('321321321')
|
40
37
|
end
|
41
38
|
|
42
39
|
it 'should not fail when an associated object is nil' do
|
43
|
-
|
40
|
+
expect { Book.new('Smalltalk-80', 'Language and Implementation', nil).to_comma }.not_to raise_error
|
44
41
|
end
|
45
42
|
end
|
46
43
|
end
|
47
|
-
|
48
44
|
end
|
49
45
|
|
50
46
|
describe Comma::DataExtractor, 'id attribute' do
|
51
47
|
before do
|
52
48
|
@data = Class.new(Struct.new(:id)) do
|
53
49
|
comma do
|
54
|
-
id 'ID' do |
|
50
|
+
id 'ID' do |_id| '42' end
|
55
51
|
end
|
56
52
|
end.new(1).to_comma
|
57
53
|
end
|
58
54
|
|
59
55
|
it 'id attribute should yield block' do
|
60
|
-
@data.
|
56
|
+
expect(@data).to include('42')
|
61
57
|
end
|
62
58
|
end
|
63
59
|
|
@@ -68,13 +64,13 @@ describe Comma::DataExtractor, 'with static column method' do
|
|
68
64
|
__static_column__
|
69
65
|
__static_column__ 'STATIC'
|
70
66
|
__static_column__ 'STATIC' do '' end
|
71
|
-
__static_column__ 'STATIC'
|
67
|
+
__static_column__ 'STATIC', &:name
|
72
68
|
end
|
73
69
|
end.new(1, 'John Doe').to_comma
|
74
70
|
end
|
75
71
|
|
76
72
|
it 'should extract headers' do
|
77
|
-
@data.
|
73
|
+
expect(@data).to eq([nil, nil, '', 'John Doe'])
|
78
74
|
end
|
79
75
|
end
|
80
76
|
|
@@ -84,12 +80,12 @@ describe Comma::DataExtractor, 'nil value' do
|
|
84
80
|
comma do
|
85
81
|
name
|
86
82
|
name 'Name'
|
87
|
-
name 'Name' do |
|
83
|
+
name 'Name' do |_name| nil end
|
88
84
|
end
|
89
85
|
end.new(1, nil).to_comma
|
90
86
|
end
|
91
87
|
|
92
88
|
it 'should extract nil' do
|
93
|
-
@data.
|
89
|
+
expect(@data).to eq([nil, nil, nil])
|
94
90
|
end
|
95
91
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
# comma do
|
@@ -8,7 +10,6 @@ require 'spec_helper'
|
|
8
10
|
# end
|
9
11
|
|
10
12
|
describe Comma::HeaderExtractor do # rubocop:disable Metrics/BlockLength
|
11
|
-
|
12
13
|
before do
|
13
14
|
@isbn = Isbn.new('123123123', '321321321')
|
14
15
|
@book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
|
@@ -17,37 +18,30 @@ describe Comma::HeaderExtractor do # rubocop:disable Metrics/BlockLength
|
|
17
18
|
end
|
18
19
|
|
19
20
|
describe 'when no parameters are provided' do
|
20
|
-
|
21
21
|
it 'should use the method name as the header name, humanized' do
|
22
|
-
@headers.
|
22
|
+
expect(@headers).to include('Description')
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe 'when given a string description as a parameter' do
|
27
|
-
|
28
27
|
it 'should use the string value, unmodified' do
|
29
|
-
@headers.
|
28
|
+
expect(@headers).to include('Title')
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
32
|
describe 'when an hash is passed as a parameter' do
|
34
|
-
|
35
33
|
describe 'with a string value' do
|
36
|
-
|
37
34
|
it 'should use the string value, unmodified' do
|
38
|
-
@headers.
|
35
|
+
expect(@headers).to include('ISBN-10')
|
39
36
|
end
|
40
37
|
end
|
41
38
|
|
42
39
|
describe 'with a non-string value' do
|
43
|
-
|
44
40
|
it 'should use the non string value converted to a string, humanized' do
|
45
|
-
@headers.
|
41
|
+
expect(@headers).to include('Issuer')
|
46
42
|
end
|
47
43
|
end
|
48
|
-
|
49
44
|
end
|
50
|
-
|
51
45
|
end
|
52
46
|
|
53
47
|
describe Comma::HeaderExtractor, 'with static column method' do
|
@@ -62,6 +56,6 @@ describe Comma::HeaderExtractor, 'with static column method' do
|
|
62
56
|
end
|
63
57
|
|
64
58
|
it 'should extract headers' do
|
65
|
-
@headers.
|
59
|
+
expect(@headers).to eq(['', 'STATIC', 'STATIC'])
|
66
60
|
end
|
67
61
|
end
|
@@ -1,19 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
if defined? ActiveRecord
|
4
6
|
|
5
7
|
describe Comma, 'generating CSV from an ActiveRecord object' do # rubocop:disable Metrics/BlockLength
|
6
|
-
|
7
8
|
class Picture < ActiveRecord::Base
|
8
|
-
belongs_to :imageable, :
|
9
|
+
belongs_to :imageable, polymorphic: true
|
9
10
|
|
10
11
|
comma :pr_83 do
|
11
|
-
imageable :
|
12
|
+
imageable name: 'Picture'
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
class Person < ActiveRecord::Base
|
16
|
-
scope(:teenagers,
|
17
|
+
scope(:teenagers, -> { where(age: 13..19) })
|
17
18
|
|
18
19
|
comma do
|
19
20
|
name
|
@@ -26,18 +27,18 @@ if defined? ActiveRecord
|
|
26
27
|
job :title
|
27
28
|
end
|
28
29
|
|
29
|
-
has_many :pictures, :
|
30
|
+
has_many :pictures, as: :imageable
|
30
31
|
end
|
31
32
|
|
32
33
|
class Job < ActiveRecord::Base
|
33
34
|
belongs_to :person
|
34
35
|
|
35
36
|
comma do
|
36
|
-
person_formatter :
|
37
|
+
person_formatter name: 'Name'
|
37
38
|
end
|
38
39
|
|
39
40
|
def person_formatter
|
40
|
-
@person_formatter ||= PersonFormatter.new(
|
41
|
+
@person_formatter ||= PersonFormatter.new(person)
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -52,51 +53,51 @@ if defined? ActiveRecord
|
|
52
53
|
end
|
53
54
|
|
54
55
|
before(:all) do
|
55
|
-
#Setup AR model in memory
|
56
|
-
ActiveRecord::Base.connection.create_table :pictures, :
|
56
|
+
# Setup AR model in memory
|
57
|
+
ActiveRecord::Base.connection.create_table :pictures, force: true do |table|
|
57
58
|
table.column :name, :string
|
58
59
|
table.column :imageable_id, :integer
|
59
60
|
table.column :imageable_type, :string
|
60
61
|
end
|
61
62
|
|
62
|
-
ActiveRecord::Base.connection.create_table :people, :
|
63
|
+
ActiveRecord::Base.connection.create_table :people, force: true do |table|
|
63
64
|
table.column :name, :string
|
64
65
|
table.column :age, :integer
|
65
66
|
end
|
66
67
|
Person.reset_column_information
|
67
68
|
|
68
|
-
ActiveRecord::Base.connection.create_table :jobs, :
|
69
|
+
ActiveRecord::Base.connection.create_table :jobs, force: true do |table|
|
69
70
|
table.column :person_id, :integer
|
70
71
|
table.column :title, :string
|
71
72
|
end
|
72
73
|
Job.reset_column_information
|
73
74
|
|
74
|
-
@person = Person.new(:
|
75
|
-
@person.build_job(:
|
75
|
+
@person = Person.new(age: 18, name: 'Junior')
|
76
|
+
@person.build_job(title: 'Nice job')
|
76
77
|
@person.save!
|
77
|
-
Picture.create(:
|
78
|
+
Picture.create(name: 'photo.jpg', imageable_id: @person.id, imageable_type: 'Person')
|
78
79
|
end
|
79
80
|
|
80
|
-
describe
|
81
|
-
it 'should extend ActiveRecord::NamedScope::Scope to add a #to_comma method which will return CSV content for objects within the scope' do
|
82
|
-
Person.teenagers.to_comma.
|
81
|
+
describe '#to_comma on scopes' do
|
82
|
+
it 'should extend ActiveRecord::NamedScope::Scope to add a #to_comma method which will return CSV content for objects within the scope' do # rubocop:disable Metrics/LineLength
|
83
|
+
expect(Person.teenagers.to_comma).to eq "Name,Age\nJunior,18\n"
|
83
84
|
end
|
84
85
|
|
85
86
|
it 'should find in batches' do
|
86
87
|
scope = Person.teenagers
|
87
|
-
scope.
|
88
|
+
expect(scope).to receive(:find_each).and_yield @person
|
88
89
|
scope.to_comma
|
89
90
|
end
|
90
91
|
|
91
92
|
it 'should fall back to iterating with each when scope has limit clause' do
|
92
93
|
scope = Person.limit(1)
|
93
|
-
scope.
|
94
|
+
expect(scope).to receive(:each).and_yield @person
|
94
95
|
scope.to_comma
|
95
96
|
end
|
96
97
|
|
97
98
|
it 'should fall back to iterating with each when scope has order clause' do
|
98
99
|
scope = Person.order(:age)
|
99
|
-
scope.
|
100
|
+
expect(scope).to receive(:each).and_yield @person
|
100
101
|
scope.to_comma
|
101
102
|
end
|
102
103
|
end
|
@@ -112,7 +113,7 @@ if defined? ActiveRecord
|
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
115
|
-
I18n.config.backend.store_translations(:ja,
|
116
|
+
I18n.config.backend.store_translations(:ja, activerecord: { attributes: { person: { age: '年齢', name: '名前' } } })
|
116
117
|
@original_locale = I18n.locale
|
117
118
|
I18n.locale = :ja
|
118
119
|
end
|
@@ -125,25 +126,25 @@ if defined? ActiveRecord
|
|
125
126
|
end
|
126
127
|
|
127
128
|
it 'should i18n-ize header values' do
|
128
|
-
Person.teenagers.to_comma.
|
129
|
+
expect(Person.teenagers.to_comma).to match(/^名前,年齢/)
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
132
133
|
describe 'github issue 75' do
|
133
134
|
it 'should find association' do
|
134
|
-
|
135
|
+
expect { Person.all.to_comma(:issue_75) }.not_to raise_error
|
135
136
|
end
|
136
137
|
end
|
137
138
|
|
138
139
|
describe 'with accessor' do
|
139
140
|
it 'should not raise exception' do
|
140
|
-
Job.all.to_comma.
|
141
|
+
expect(Job.all.to_comma).to eq("Name\nJunior\n")
|
141
142
|
end
|
142
143
|
end
|
143
144
|
|
144
145
|
describe 'github pull-request 83' do
|
145
146
|
it 'should not raise NameError' do
|
146
|
-
|
147
|
+
expect { Picture.all.to_comma(:pr_83) }.not_to raise_error
|
147
148
|
end
|
148
149
|
end
|
149
150
|
end
|
@@ -174,29 +175,29 @@ if defined? ActiveRecord
|
|
174
175
|
end
|
175
176
|
|
176
177
|
before(:all) do
|
177
|
-
#Setup AR model in memory
|
178
|
-
ActiveRecord::Base.connection.create_table :animals, :
|
178
|
+
# Setup AR model in memory
|
179
|
+
ActiveRecord::Base.connection.create_table :animals, force: true do |table|
|
179
180
|
table.column :name, :string
|
180
181
|
table.column :type, :string
|
181
182
|
end
|
182
183
|
|
183
|
-
@dog = Dog.new(:
|
184
|
+
@dog = Dog.new(name: 'Rex')
|
184
185
|
@dog.save!
|
185
|
-
@cat = Cat.new(:
|
186
|
+
@cat = Cat.new(name: 'Kitty')
|
186
187
|
@cat.save!
|
187
188
|
end
|
188
189
|
|
189
190
|
it 'should return and array of data content, as defined in comma block in child class' do
|
190
|
-
@dog.to_comma.
|
191
|
+
expect(@dog.to_comma).to eq %w[Dog-Rex]
|
191
192
|
end
|
192
193
|
|
193
|
-
#FIXME: this one is failing - the comma block from Dog is executed instead of the one from the super class
|
194
|
+
# FIXME: this one is failing - the comma block from Dog is executed instead of the one from the super class
|
194
195
|
it 'should return and array of data content, as defined in comma block in super class, if not present in child' do
|
195
|
-
@cat.to_comma.
|
196
|
+
expect(@cat.to_comma).to eq %w[Super-Kitty]
|
196
197
|
end
|
197
198
|
|
198
199
|
it 'should call definion in parent class' do
|
199
|
-
|
200
|
+
expect { @dog.to_comma(:with_type) }.not_to raise_error
|
200
201
|
end
|
201
202
|
end
|
202
203
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
if defined? DataMapper
|
4
6
|
|
5
7
|
describe Comma, 'generating CSV from an DataMapper object' do # rubocop:disable Metrics/BlockLength
|
6
|
-
|
7
8
|
class Person
|
8
9
|
include DataMapper::Resource
|
9
10
|
|
@@ -30,9 +31,9 @@ if defined? DataMapper
|
|
30
31
|
after(:all) do
|
31
32
|
end
|
32
33
|
|
33
|
-
describe
|
34
|
+
describe 'case' do
|
34
35
|
before do
|
35
|
-
@person = Person.new(:
|
36
|
+
@person = Person.new(age: 18, name: 'Junior')
|
36
37
|
@person.save
|
37
38
|
end
|
38
39
|
|
@@ -1,16 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
if defined? Mongoid
|
4
6
|
|
5
7
|
describe Comma, 'generating CSV from an Mongoid object' do
|
6
|
-
|
7
8
|
class Person
|
8
9
|
include Mongoid::Document
|
9
10
|
|
10
|
-
field :name, :
|
11
|
-
field :age, :
|
11
|
+
field :name, type: String
|
12
|
+
field :age, type: Integer
|
12
13
|
|
13
|
-
scope :teenagers, between(:
|
14
|
+
scope :teenagers, between(age: 13..19)
|
14
15
|
|
15
16
|
comma do
|
16
17
|
name
|
@@ -22,13 +23,13 @@ if defined? Mongoid
|
|
22
23
|
Mongoid.purge!
|
23
24
|
end
|
24
25
|
|
25
|
-
describe
|
26
|
+
describe 'case' do
|
26
27
|
before do
|
27
|
-
@person = Person.new(:
|
28
|
+
@person = Person.new(age: 18, name: 'Junior')
|
28
29
|
@person.save
|
29
30
|
end
|
30
31
|
|
31
|
-
it 'should extend ActiveRecord::NamedScope::Scope to add a #to_comma method which will return CSV content for objects within the scope' do
|
32
|
+
it 'should extend ActiveRecord::NamedScope::Scope to add a #to_comma method which will return CSV content for objects within the scope' do # rubocop:disable Metrics/LineLength
|
32
33
|
Person.teenagers.to_comma.should == "Name,Age\nJunior,18\n"
|
33
34
|
end
|
34
35
|
|
@@ -1,69 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
if defined?(Rails)
|
4
6
|
|
5
7
|
RSpec.describe UsersController, type: :controller do # rubocop:disable Metrics/BlockLength
|
6
|
-
|
7
|
-
describe "rails setup" do
|
8
|
-
|
8
|
+
describe 'rails setup' do
|
9
9
|
it 'should capture the CSV renderer provided by Rails' do
|
10
10
|
mock_users = [mock_model(User), mock_model(User)]
|
11
11
|
allow(User).to receive(:all).and_return(mock_users)
|
12
12
|
|
13
|
-
mock_users.
|
13
|
+
expect(mock_users).to receive(:to_comma).once
|
14
14
|
|
15
|
-
get :index, :
|
15
|
+
get :index, format: :csv
|
16
16
|
end
|
17
|
-
|
18
17
|
end
|
19
18
|
|
20
|
-
describe
|
19
|
+
describe 'controller' do # rubocop:disable Metrics/BlockLength
|
21
20
|
before(:all) do
|
22
|
-
@user_1 = User.create!(:
|
23
|
-
@user_2 = User.create!(:
|
21
|
+
@user_1 = User.create!(first_name: 'Fred', last_name: 'Flintstone')
|
22
|
+
@user_2 = User.create!(first_name: 'Wilma', last_name: 'Flintstone')
|
24
23
|
end
|
25
24
|
|
26
25
|
it 'should not affect html requested' do
|
27
26
|
get :index
|
28
27
|
|
29
|
-
response.status.
|
30
|
-
response.
|
31
|
-
response.body.
|
28
|
+
expect(response.status).to eq 200
|
29
|
+
expect(response.media_type).to eq 'text/html'
|
30
|
+
expect(response.body).to eq 'Users!'
|
32
31
|
end
|
33
32
|
|
34
|
-
it
|
35
|
-
get :index, :
|
33
|
+
it 'should return a csv when requested' do
|
34
|
+
get :index, format: :csv
|
36
35
|
|
37
|
-
response.status.
|
38
|
-
response.
|
39
|
-
response.header[
|
36
|
+
expect(response.status).to eq 200
|
37
|
+
expect(response.media_type).to eq 'text/csv'
|
38
|
+
expect(response.header['Content-Disposition']).to include('filename="data.csv"')
|
40
39
|
|
41
|
-
expected_content
|
40
|
+
expected_content = <<-CSV.gsub(/^\s+/, '')
|
42
41
|
First name,Last name,Name
|
43
42
|
Fred,Flintstone,Fred Flintstone
|
44
43
|
Wilma,Flintstone,Wilma Flintstone
|
45
44
|
CSV
|
46
45
|
|
47
|
-
response.body.
|
46
|
+
expect(response.body).to eq expected_content
|
48
47
|
end
|
49
48
|
|
50
49
|
describe 'with comma options' do
|
51
|
-
|
52
50
|
it 'should allow the style to be chosen from the renderer' do
|
53
|
-
#Must be passed in same format (string/symbol) eg:
|
51
|
+
# Must be passed in same format (string/symbol) eg:
|
54
52
|
# format.csv { render User.all, :style => :shortened }
|
55
53
|
|
56
|
-
get :with_custom_style, :
|
54
|
+
get :with_custom_style, format: :csv
|
57
55
|
|
58
|
-
expected_content
|
56
|
+
expected_content = <<-CSV.gsub(/^\s+/, '')
|
59
57
|
First name,Last name
|
60
58
|
Fred,Flintstone
|
61
59
|
Wilma,Flintstone
|
62
60
|
CSV
|
63
61
|
|
64
|
-
response.body.
|
62
|
+
expect(response.body).to eq expected_content
|
65
63
|
end
|
66
|
-
|
67
64
|
end
|
68
65
|
|
69
66
|
describe 'with custom options' do # rubocop:disable Metrics/BlockLength
|
@@ -80,105 +77,121 @@ if defined?(Rails)
|
|
80
77
|
end
|
81
78
|
|
82
79
|
it 'should allow a filename to be set' do
|
83
|
-
get_ :with_custom_options, :
|
80
|
+
get_ :with_custom_options, format: :csv, params: { custom_options: { filename: 'my_custom_name' } }
|
84
81
|
|
85
|
-
response.status.
|
86
|
-
response.
|
87
|
-
response.header[
|
82
|
+
expect(response.status).to eq 200
|
83
|
+
expect(response.media_type).to eq 'text/csv'
|
84
|
+
expect(response.header['Content-Disposition']).to include('filename="my_custom_name.csv"')
|
88
85
|
end
|
89
86
|
|
90
|
-
it
|
87
|
+
it 'should allow a custom filename with spaces' do
|
91
88
|
require 'shellwords'
|
92
|
-
|
89
|
+
params = { custom_options: { filename: 'filename with a lot of spaces' } }
|
90
|
+
get_ :with_custom_options, format: :csv, params: params
|
93
91
|
|
94
|
-
response.status.
|
95
|
-
response.
|
96
|
-
response.header[
|
92
|
+
expect(response.status).to eq 200
|
93
|
+
expect(response.media_type).to eq 'text/csv'
|
94
|
+
expect(response.header['Content-Disposition']).to include('filename="filename with a lot of spaces.csv"')
|
97
95
|
|
98
|
-
filename_string = response.header[
|
96
|
+
filename_string = response.header['Content-Disposition'].split('=').last
|
99
97
|
# shellsplit honors quoted strings
|
100
|
-
filename_string.shellsplit.length.
|
98
|
+
expect(filename_string.shellsplit.length).to eq 1
|
101
99
|
end
|
102
100
|
|
103
101
|
it 'should allow a file extension to be set' do
|
104
|
-
get_ :with_custom_options, :
|
102
|
+
get_ :with_custom_options, format: :csv, params: { custom_options: { extension: :txt } }
|
105
103
|
|
106
|
-
response.status.
|
107
|
-
response.
|
108
|
-
response.header[
|
104
|
+
expect(response.status).to eq 200
|
105
|
+
expect(response.media_type).to eq 'text/csv'
|
106
|
+
expect(response.header['Content-Disposition']).to include('filename="data.txt"')
|
109
107
|
end
|
110
108
|
|
111
109
|
it 'should allow mime type to be set' do
|
112
|
-
get_ :with_custom_options, :
|
113
|
-
response.status.
|
114
|
-
response.
|
110
|
+
get_ :with_custom_options, format: :csv, params: { custom_options: { mime_type: 'text/plain' } }
|
111
|
+
expect(response.status).to eq 200
|
112
|
+
expect(response.media_type).to eq 'text/plain'
|
115
113
|
end
|
116
114
|
|
117
|
-
|
115
|
+
it 'should allow bom to be set' do
|
116
|
+
get_ :with_custom_options, format: :csv, params: { custom_options: { with_bom: true } }
|
117
|
+
|
118
|
+
expected_content = <<-CSV.gsub(/^\s+/, '')
|
119
|
+
\xEF\xBB\xBFFirst name,Last name,Name
|
120
|
+
Fred,Flintstone,Fred Flintstone
|
121
|
+
Wilma,Flintstone,Wilma Flintstone
|
122
|
+
CSV
|
118
123
|
|
124
|
+
expect(response.body). to eq expected_content
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'headers' do
|
119
128
|
it 'should allow toggling on' do
|
120
|
-
get_ :with_custom_options, :
|
129
|
+
get_ :with_custom_options, format: :csv, params: { custom_options: { write_headers: 'true' } }
|
121
130
|
|
122
|
-
response.status.
|
123
|
-
response.
|
131
|
+
expect(response.status).to eq 200
|
132
|
+
expect(response.media_type).to eq 'text/csv'
|
124
133
|
|
125
|
-
expected_content
|
134
|
+
expected_content = <<-CSV.gsub(/^\s+/, '')
|
126
135
|
First name,Last name,Name
|
127
136
|
Fred,Flintstone,Fred Flintstone
|
128
137
|
Wilma,Flintstone,Wilma Flintstone
|
129
138
|
CSV
|
130
139
|
|
131
|
-
response.body.
|
140
|
+
expect(response.body).to eq expected_content
|
132
141
|
end
|
133
142
|
|
134
143
|
it 'should allow toggling off' do
|
135
|
-
get_ :with_custom_options, :
|
144
|
+
get_ :with_custom_options, format: :csv, params: { custom_options: { write_headers: false } }
|
136
145
|
|
137
|
-
response.status.
|
138
|
-
response.
|
146
|
+
expect(response.status).to eq 200
|
147
|
+
expect(response.media_type).to eq 'text/csv'
|
139
148
|
|
140
|
-
expected_content
|
149
|
+
expected_content = <<-CSV.gsub(/^\s+/, '')
|
141
150
|
Fred,Flintstone,Fred Flintstone
|
142
151
|
Wilma,Flintstone,Wilma Flintstone
|
143
152
|
CSV
|
144
153
|
|
145
|
-
response.body.
|
154
|
+
expect(response.body).to eq expected_content
|
146
155
|
end
|
147
|
-
|
148
156
|
end
|
149
157
|
|
150
158
|
it 'should allow forcing of quotes' do
|
151
|
-
get_ :with_custom_options, :
|
159
|
+
get_ :with_custom_options, format: :csv, params: { custom_options: { force_quotes: true } }
|
152
160
|
|
153
|
-
response.status.
|
154
|
-
response.
|
161
|
+
expect(response.status).to eq 200
|
162
|
+
expect(response.media_type).to eq 'text/csv'
|
155
163
|
|
156
|
-
expected_content
|
164
|
+
expected_content = <<-CSV.gsub(/^\s+/, '')
|
157
165
|
"First name","Last name","Name"
|
158
166
|
"Fred","Flintstone","Fred Flintstone"
|
159
167
|
"Wilma","Flintstone","Wilma Flintstone"
|
160
168
|
CSV
|
161
169
|
|
162
|
-
response.body.
|
170
|
+
expect(response.body).to eq expected_content
|
163
171
|
end
|
164
172
|
|
165
173
|
it 'should allow combinations of options' do
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
174
|
+
params = {
|
175
|
+
custom_options: {
|
176
|
+
write_headers: false,
|
177
|
+
force_quotes: true,
|
178
|
+
col_sep: '||',
|
179
|
+
row_sep: "ENDOFLINE\n"
|
180
|
+
}
|
181
|
+
}
|
182
|
+
get_ :with_custom_options, format: :csv, params: params
|
183
|
+
|
184
|
+
expect(response.status).to eq 200
|
185
|
+
expect(response.media_type).to eq 'text/csv'
|
186
|
+
|
187
|
+
expected_content = <<-CSV.gsub(/^\s+/, '')
|
172
188
|
"Fred"||"Flintstone"||"Fred Flintstone"ENDOFLINE
|
173
189
|
"Wilma"||"Flintstone"||"Wilma Flintstone"ENDOFLINE
|
174
190
|
CSV
|
175
191
|
|
176
|
-
response.body.
|
192
|
+
expect(response.body).to eq expected_content
|
177
193
|
end
|
178
|
-
|
179
194
|
end
|
180
|
-
|
181
195
|
end
|
182
|
-
|
183
196
|
end
|
184
197
|
end
|