speaky_csv 0.0.3 → 0.0.5

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/spec/base_spec.rb CHANGED
@@ -13,14 +13,18 @@ describe SpeakyCsv::Base do
13
13
  d.has_many :reviews do |r|
14
14
  r.field :tomatoes
15
15
  end
16
+ d.has_one :publisher do |p|
17
+ p.field :id
18
+ end
16
19
  end
17
20
  end
18
21
  end
19
22
 
20
23
  it 'inherits it for child' do
21
- expect(child_klass.csv_field_builder.fields).to eq [:name]
22
- expect(child_klass.csv_field_builder.has_manys.keys).to eq [:reviews]
23
- expect(child_klass.csv_field_builder.has_manys[:reviews].fields).to eq [:tomatoes]
24
+ expect(child_klass.speaky_csv_config.fields).to eq [:name]
25
+ expect(child_klass.speaky_csv_config.has_manys.keys).to eq [:reviews]
26
+ expect(child_klass.speaky_csv_config.has_manys[:reviews].fields).to eq [:tomatoes]
27
+ expect(child_klass.speaky_csv_config.has_ones[:publisher].fields).to eq [:id]
24
28
  end
25
29
 
26
30
  context 'and child adds to it' do
@@ -34,23 +38,42 @@ describe SpeakyCsv::Base do
34
38
  d.has_many :reviews do |r|
35
39
  r.field :publication
36
40
  end
41
+ d.has_one :publisher do |p|
42
+ p.field :name
43
+ end
37
44
  end
38
45
  end
39
46
  end
40
47
 
41
48
  it 'adds it to child' do
42
- expect(child_klass.csv_field_builder.fields).to eq [:name, :author]
43
- expect(child_klass.csv_field_builder.has_manys.keys.sort).to eq [:reviews, :sales].sort
44
- expect(child_klass.csv_field_builder.has_manys[:reviews].fields).to eq [:tomatoes, :publication]
45
- expect(child_klass.csv_field_builder.has_manys[:sales].fields).to eq [:period]
49
+ expect(child_klass.speaky_csv_config.fields).to eq [:name, :author]
50
+ expect(child_klass.speaky_csv_config.has_manys.keys.sort).to eq [:reviews, :sales].sort
51
+ expect(child_klass.speaky_csv_config.has_manys[:reviews].fields).to eq [:tomatoes, :publication]
52
+ expect(child_klass.speaky_csv_config.has_manys[:sales].fields).to eq [:period]
53
+ expect(child_klass.speaky_csv_config.has_ones[:publisher].fields).to eq [:id, :name]
46
54
  end
47
55
 
48
56
  it 'doesnt change parents config' do
49
- expect(parent_klass.csv_field_builder.fields).to_not include :author
50
- expect(parent_klass.csv_field_builder.has_manys.keys).to_not include :sales
51
- expect(parent_klass.csv_field_builder.has_manys[:reviews].fields).to_not include :publication
57
+ expect(parent_klass.speaky_csv_config.fields).to_not include :author
58
+ expect(parent_klass.speaky_csv_config.has_manys.keys).to_not include :sales
59
+ expect(parent_klass.speaky_csv_config.has_manys[:reviews].fields).to_not include :publication
60
+ expect(parent_klass.speaky_csv_config.has_ones[:publisher].fields).to_not include :name
52
61
  end
53
62
  end
54
63
  end
64
+
65
+ it 'raises if association nesting is attempted' do
66
+ expect do
67
+ parent_klass.class_eval do
68
+ define_csv_fields do |d|
69
+ d.has_one :foo do |f|
70
+ f.has_many :bars do |b|
71
+ b.field 'name'
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end.to raise_error(NotImplementedError)
77
+ end
55
78
  end
56
79
  end
data/spec/export_spec.rb CHANGED
@@ -36,6 +36,36 @@ True story,Honest Abe
36
36
  end
37
37
  end
38
38
 
39
+ context 'with _destroy field' do
40
+ before do
41
+ presenter_klass.class_eval do
42
+ define_csv_fields do |d|
43
+ d.field 'id', 'name', '_destroy'
44
+ end
45
+ end
46
+ end
47
+
48
+ let(:records) do
49
+ [
50
+ double('book1', id: 4, name: 'Big Fiction', author: 'Sneed'),
51
+ double('book2', id: 8, name: 'True story', author: 'Honest Abe')
52
+ ]
53
+ end
54
+
55
+ it 'should write to io' do
56
+ expect(output).to eq <<-CSV
57
+ id,name,_destroy
58
+ 4,Big Fiction,
59
+ 8,True story,
60
+ CSV
61
+ end
62
+
63
+ it 'doesnt log that _destroy is an unknown field' do
64
+ subject.to_a
65
+ expect(subject.log).to_not match(/_destroy is not a method/)
66
+ end
67
+ end
68
+
39
69
  context 'with export_only fields' do
40
70
  before do
41
71
  presenter_klass.class_eval do
@@ -171,4 +201,118 @@ id
171
201
  expect(subject.log).to match(/unknowns is not a method/)
172
202
  end
173
203
  end
204
+
205
+ context 'with has_one fields' do
206
+ before do
207
+ presenter_klass.class_eval do
208
+ define_csv_fields do |d|
209
+ d.field 'name', 'author'
210
+ d.has_one 'publisher' do |r|
211
+ r.field :id, :name
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ let(:records) do
218
+ [
219
+ double('book1',
220
+ name: 'Big Fiction',
221
+ author: 'Sneed',
222
+ publisher: double(id: 99, name: 'Post')),
223
+ double('book2',
224
+ name: 'True story',
225
+ author: 'Honest Abe',
226
+ publisher: double(id: 50, name: 'Daily'))
227
+ ]
228
+ end
229
+ it 'should return csv' do
230
+ expect(output).to eq <<-CSV
231
+ name,author,publisher_id,publisher_name
232
+ Big Fiction,Sneed,99,Post
233
+ True story,Honest Abe,50,Daily
234
+ CSV
235
+ end
236
+ end
237
+
238
+ context 'with export_only has_one field' do
239
+ before do
240
+ presenter_klass.class_eval do
241
+ define_csv_fields do |d|
242
+ d.field 'id'
243
+ d.has_one 'publisher' do |r|
244
+ r.field :id
245
+ r.field :name, export_only: true
246
+ end
247
+ end
248
+ end
249
+ end
250
+
251
+ let(:records) do
252
+ [
253
+ double('book1',
254
+ id: 22,
255
+ publisher: double(id: 99, name: 'Post')),
256
+ ]
257
+ end
258
+
259
+ it 'should write field' do
260
+ expect(output).to eq <<-CSV
261
+ id,publisher_id,publisher_name
262
+ 22,99,Post
263
+ CSV
264
+ end
265
+ end
266
+
267
+ context 'with unknown has_many field' do
268
+ before do
269
+ presenter_klass.class_eval do
270
+ define_csv_fields do |d|
271
+ d.field 'id'
272
+ d.has_one 'publisher' do |r|
273
+ r.field :unknown
274
+ end
275
+ end
276
+ end
277
+ end
278
+
279
+ let(:records) do
280
+ [
281
+ double('book1',
282
+ id: 22,
283
+ publisher: double(id: 99, name: 'Post')),
284
+ ]
285
+ end
286
+
287
+ it 'adds an error' do
288
+ subject.to_a
289
+ expect(subject.log).to match(/publisher_unknown is not a method/)
290
+ end
291
+ end
292
+
293
+ context 'with unknown has_many association' do
294
+ before do
295
+ presenter_klass.class_eval do
296
+ define_csv_fields do |d|
297
+ d.field 'id'
298
+ d.has_one 'unknown' do |r|
299
+ r.field :name
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ let(:records) do
306
+ [
307
+ double('book1',
308
+ id: 22,
309
+ publisher: double(id: 99, name: 'Post')),
310
+ ]
311
+ end
312
+
313
+ it 'adds an error' do
314
+ subject.to_a
315
+ expect(subject.log).to match(/unknown is not a method/)
316
+ end
317
+ end
174
318
  end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ require 'support/active_record'
3
+
4
+ describe "Examples in README.md", :db do
5
+ it "has working examples" do
6
+ # For example ...
7
+
8
+ # in app/models/book.rb
9
+ class Book < ActiveRecord::Base
10
+ # ...
11
+ end
12
+
13
+ # in app/csvs/book_csv.rb
14
+ class BookCsv < SpeakyCsv::Base
15
+ define_csv_fields do |config|
16
+ config.field :id, :author
17
+ end
18
+ end
19
+
20
+ # Importing - create
21
+
22
+ csv_io = StringIO.new <<-CSV
23
+ id,author
24
+ ,Sneed
25
+ CSV
26
+
27
+ importer = BookCsv.active_record_importer csv_io, Book
28
+ importer.each { |book| book.save }
29
+
30
+ expect(Book.last.author).to eq 'Sneed'
31
+
32
+ # Importing - update
33
+
34
+ csv_io = StringIO.new <<-CSV
35
+ id,author
36
+ 1,Simon Sneed
37
+ CSV
38
+
39
+ importer = BookCsv.active_record_importer csv_io, Book
40
+ importer.each { |book| book.save }
41
+ expect(Book.last.author).to eq 'Simon Sneed'
42
+
43
+ # Importing - record not found
44
+
45
+ csv_io = StringIO.new <<-CSV
46
+ id,author
47
+ 234,I dont exist
48
+ CSV
49
+
50
+ importer = BookCsv.active_record_importer csv_io, Book
51
+ expect(importer.to_a).to eq [nil]
52
+ expect(importer.log).to include '[row 1] record not found with primary key: "234"'
53
+
54
+ # Importing - destroy
55
+
56
+ # in app/csvs/book_csv.rb
57
+ class BookCsv < SpeakyCsv::Base
58
+ define_csv_fields do |config|
59
+ config.field :id, :author, :_destroy
60
+ end
61
+ end
62
+
63
+ csv_io = StringIO.new <<-CSV
64
+ id,_destroy
65
+ 1,true
66
+ CSV
67
+
68
+ importer = BookCsv.active_record_importer csv_io, Book
69
+ book = importer.to_a.first
70
+ expect(book).to be_marked_for_destruction
71
+ if book.marked_for_destruction?
72
+ book.destroy
73
+ end
74
+
75
+ # Exporting
76
+
77
+ books = [
78
+ Book.create!(author: 'Stevenson'),
79
+ Book.create!(author: 'Melville'),
80
+ Book.create!(author: 'Macaulay'),
81
+ ]
82
+ exporter = BookCsv.exporter books
83
+
84
+ io = StringIO.new
85
+ exporter.each { |row| io.write row }
86
+ io.rewind
87
+ expect(io.read).to eq <<-OUTPUT
88
+ id,author,_destroy
89
+ 2,Stevenson,false
90
+ 3,Melville,false
91
+ 4,Macaulay,false
92
+ OUTPUT
93
+ end
94
+ end
95
+
@@ -30,6 +30,7 @@ class Book < ActiveRecord::Base
30
30
  has_many :reviews, inverse_of: :book
31
31
  belongs_to :publisher, inverse_of: :books
32
32
  accepts_nested_attributes_for :reviews, allow_destroy: true
33
+ accepts_nested_attributes_for :publisher, allow_destroy: true
33
34
  end
34
35
 
35
36
  class Review < ActiveRecord::Base
metadata CHANGED
@@ -1,209 +1,209 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: speaky_csv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Hartford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-04 00:00:00.000000000 Z
11
+ date: 2016-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '4.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '4.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '4.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.10'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.10'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: database_cleaner
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ~>
74
74
  - !ruby/object:Gem::Version
75
75
  version: '1.5'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.5'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ~>
88
88
  - !ruby/object:Gem::Version
89
89
  version: '10.0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: '10.0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ~>
102
102
  - !ruby/object:Gem::Version
103
103
  version: '3'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ~>
109
109
  - !ruby/object:Gem::Version
110
110
  version: '3'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rspec-its
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ~>
116
116
  - !ruby/object:Gem::Version
117
117
  version: '1'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ~>
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rubocop
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ~>
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0.35'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ~>
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0.35'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: sqlite3
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - ~>
144
144
  - !ruby/object:Gem::Version
145
145
  version: '1.3'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - "~>"
150
+ - - ~>
151
151
  - !ruby/object:Gem::Version
152
152
  version: '1.3'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: guard-rspec
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - "~>"
157
+ - - ~>
158
158
  - !ruby/object:Gem::Version
159
159
  version: '4.6'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - "~>"
164
+ - - ~>
165
165
  - !ruby/object:Gem::Version
166
166
  version: '4.6'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rb-fsevent
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - "~>"
171
+ - - ~>
172
172
  - !ruby/object:Gem::Version
173
173
  version: '0.9'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - "~>"
178
+ - - ~>
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0.9'
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: rb-inotify
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - "~>"
185
+ - - ~>
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0.9'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
- - - "~>"
192
+ - - ~>
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0.9'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: ruby_gntp
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
- - - "~>"
199
+ - - ~>
200
200
  - !ruby/object:Gem::Version
201
201
  version: '0.3'
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
- - - "~>"
206
+ - - ~>
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0.3'
209
209
  description: CSV importing and exporting for ActiveRecord and ActiveModel with a Enumerator
@@ -216,9 +216,9 @@ executables:
216
216
  extensions: []
217
217
  extra_rdoc_files: []
218
218
  files:
219
- - ".gitignore"
220
- - ".rubocop.yml"
221
- - ".travis.yml"
219
+ - .gitignore
220
+ - .rubocop.yml
221
+ - .travis.yml
222
222
  - Gemfile
223
223
  - Guardfile
224
224
  - LICENSE.txt
@@ -230,6 +230,8 @@ files:
230
230
  - lib/speaky_csv/active_record_import.rb
231
231
  - lib/speaky_csv/attr_import.rb
232
232
  - lib/speaky_csv/base.rb
233
+ - lib/speaky_csv/config.rb
234
+ - lib/speaky_csv/config_builder.rb
233
235
  - lib/speaky_csv/export.rb
234
236
  - lib/speaky_csv/version.rb
235
237
  - log/.gitkeep
@@ -238,6 +240,7 @@ files:
238
240
  - spec/attr_import_spec.rb
239
241
  - spec/base_spec.rb
240
242
  - spec/export_spec.rb
243
+ - spec/readme_spec.rb
241
244
  - spec/spec_helper.rb
242
245
  - spec/support/active_record.rb
243
246
  homepage: https://github.com/ajh/speaky_csv
@@ -250,17 +253,17 @@ require_paths:
250
253
  - lib
251
254
  required_ruby_version: !ruby/object:Gem::Requirement
252
255
  requirements:
253
- - - ">="
256
+ - - '>='
254
257
  - !ruby/object:Gem::Version
255
258
  version: '0'
256
259
  required_rubygems_version: !ruby/object:Gem::Requirement
257
260
  requirements:
258
- - - ">="
261
+ - - '>='
259
262
  - !ruby/object:Gem::Version
260
263
  version: '0'
261
264
  requirements: []
262
265
  rubyforge_project:
263
- rubygems_version: 2.4.3
266
+ rubygems_version: 2.0.14.1
264
267
  signing_key:
265
268
  specification_version: 4
266
269
  summary: CSV importing and exporting for ActiveRecord and ActiveModel
@@ -269,5 +272,6 @@ test_files:
269
272
  - spec/attr_import_spec.rb
270
273
  - spec/base_spec.rb
271
274
  - spec/export_spec.rb
275
+ - spec/readme_spec.rb
272
276
  - spec/spec_helper.rb
273
277
  - spec/support/active_record.rb