torque-postgresql 2.0.4 → 2.1.2

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.
@@ -291,6 +291,20 @@ RSpec.describe 'HasMany' do
291
291
  expect(record.tag_ids).to be_eql([subject.id])
292
292
  end
293
293
 
294
+ it 'can perist after accessed in after_create' do
295
+ other.belongs_to_many(:tags)
296
+ other.after_create { self.tags.to_a }
297
+
298
+ video = FactoryBot.create(:video)
299
+ subject.videos << video
300
+
301
+ expect(subject.reload.videos.size).to eql(1)
302
+ expect(video.reload.tags.size).to eql(1)
303
+
304
+ other.reset_callbacks(:create)
305
+ other._reflections = {}
306
+ end
307
+
294
308
  it 'can concat records' do
295
309
  FactoryBot.create(:video, tag_ids: [subject.id])
296
310
  expect(subject.videos.size).to be_eql(1)
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'InsertAll' do
4
+ context 'on executing' do
5
+ before do
6
+ ActiveRecord::InsertAll.send(:public, :to_sql)
7
+ allow_any_instance_of(ActiveRecord::InsertAll).to receive(:execute, &:to_sql)
8
+ end
9
+
10
+ subject { Tag }
11
+
12
+ let(:entries) { [{ name: 'A' }, { name: 'B' }] }
13
+
14
+ it 'does not mess with insert_all' do
15
+ result = subject.insert_all(entries)
16
+ expect(result.squish).to be_eql(<<~SQL.squish)
17
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
18
+ ON CONFLICT DO NOTHING RETURNING "id"
19
+ SQL
20
+
21
+ result = subject.insert_all(entries, returning: %i[name])
22
+ expect(result.squish).to be_eql(<<~SQL.squish)
23
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
24
+ ON CONFLICT DO NOTHING RETURNING "name"
25
+ SQL
26
+
27
+ result = subject.insert_all(entries, returning: %i[id name])
28
+ expect(result.squish).to be_eql(<<~SQL.squish)
29
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
30
+ ON CONFLICT DO NOTHING RETURNING "id","name"
31
+ SQL
32
+ end
33
+
34
+ it 'does not mess with insert_all!' do
35
+ result = subject.insert_all!(entries)
36
+ expect(result.squish).to be_eql(<<~SQL.squish)
37
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B') RETURNING "id"
38
+ SQL
39
+
40
+ result = subject.insert_all!(entries, returning: %i[name])
41
+ expect(result.squish).to be_eql(<<~SQL.squish)
42
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B') RETURNING "name"
43
+ SQL
44
+ end
45
+
46
+ it 'does not mess with upsert without where' do
47
+ result = subject.upsert_all(entries)
48
+ expect(result.squish).to be_eql(<<~SQL.squish)
49
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
50
+ ON CONFLICT ("id") DO UPDATE SET "name"=excluded."name"
51
+ RETURNING "id"
52
+ SQL
53
+
54
+ result = subject.upsert_all(entries, returning: %i[name])
55
+ expect(result.squish).to be_eql(<<~SQL.squish)
56
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
57
+ ON CONFLICT ("id") DO UPDATE SET "name"=excluded."name"
58
+ RETURNING "name"
59
+ SQL
60
+ end
61
+
62
+ it 'does add the where condition without the returning clause' do
63
+ result = subject.upsert_all(entries, returning: false, where: '1=1')
64
+ expect(result.squish).to be_eql(<<~SQL.squish)
65
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
66
+ ON CONFLICT ("id") DO UPDATE SET "name"=excluded."name"
67
+ WHERE 1=1
68
+ SQL
69
+ end
70
+
71
+ it 'does add the where condition with the returning clause' do
72
+ result = subject.upsert_all(entries, where: '1=1')
73
+ expect(result.squish).to be_eql(<<~SQL.squish)
74
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
75
+ ON CONFLICT ("id") DO UPDATE SET "name"=excluded."name"
76
+ WHERE 1=1 RETURNING "id"
77
+ SQL
78
+ end
79
+
80
+ xit 'dows work with model-based where clause' do
81
+ result = subject.upsert_all(entries, where: Tag.where(name: 'C'))
82
+ expect(result.squish).to be_eql(<<~SQL.squish)
83
+ INSERT INTO "tags" ("name") VALUES ('A'), ('B')
84
+ ON CONFLICT ("id") DO UPDATE SET "name"=excluded."name"
85
+ WHERE "tags"."name" = 'C' RETURNING "id"
86
+ SQL
87
+ end
88
+ end
89
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: torque-postgresql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Silva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-13 00:00:00.000000000 Z
11
+ date: 2021-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -215,12 +215,12 @@ files:
215
215
  - lib/torque/postgresql/auxiliary_statement.rb
216
216
  - lib/torque/postgresql/auxiliary_statement/settings.rb
217
217
  - lib/torque/postgresql/base.rb
218
- - lib/torque/postgresql/coder.rb
219
218
  - lib/torque/postgresql/collector.rb
220
219
  - lib/torque/postgresql/config.rb
221
220
  - lib/torque/postgresql/geometry_builder.rb
222
221
  - lib/torque/postgresql/i18n.rb
223
222
  - lib/torque/postgresql/inheritance.rb
223
+ - lib/torque/postgresql/insert_all.rb
224
224
  - lib/torque/postgresql/migration.rb
225
225
  - lib/torque/postgresql/migration/command_recorder.rb
226
226
  - lib/torque/postgresql/railtie.rb
@@ -242,6 +242,7 @@ files:
242
242
  - spec/en.yml
243
243
  - spec/factories/authors.rb
244
244
  - spec/factories/comments.rb
245
+ - spec/factories/item.rb
245
246
  - spec/factories/posts.rb
246
247
  - spec/factories/tags.rb
247
248
  - spec/factories/texts.rb
@@ -259,6 +260,7 @@ files:
259
260
  - spec/models/course.rb
260
261
  - spec/models/geometry.rb
261
262
  - spec/models/guest_comment.rb
263
+ - spec/models/item.rb
262
264
  - spec/models/post.rb
263
265
  - spec/models/tag.rb
264
266
  - spec/models/text.rb
@@ -270,13 +272,13 @@ files:
270
272
  - spec/tests/arel_spec.rb
271
273
  - spec/tests/auxiliary_statement_spec.rb
272
274
  - spec/tests/belongs_to_many_spec.rb
273
- - spec/tests/coder_spec.rb
274
275
  - spec/tests/collector_spec.rb
275
276
  - spec/tests/distinct_on_spec.rb
276
277
  - spec/tests/enum_set_spec.rb
277
278
  - spec/tests/enum_spec.rb
278
279
  - spec/tests/geometric_builder_spec.rb
279
280
  - spec/tests/has_many_spec.rb
281
+ - spec/tests/insert_all_spec.rb
280
282
  - spec/tests/interval_spec.rb
281
283
  - spec/tests/lazy_spec.rb
282
284
  - spec/tests/period_spec.rb
@@ -303,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
303
305
  - !ruby/object:Gem::Version
304
306
  version: 1.8.11
305
307
  requirements: []
306
- rubygems_version: 3.1.4
308
+ rubygems_version: 3.2.14
307
309
  signing_key:
308
310
  specification_version: 4
309
311
  summary: ActiveRecord extension to access PostgreSQL advanced resources
@@ -324,6 +326,7 @@ test_files:
324
326
  - spec/models/tag.rb
325
327
  - spec/models/time_keeper.rb
326
328
  - spec/models/video.rb
329
+ - spec/models/item.rb
327
330
  - spec/factories/authors.rb
328
331
  - spec/factories/comments.rb
329
332
  - spec/factories/posts.rb
@@ -331,23 +334,24 @@ test_files:
331
334
  - spec/factories/texts.rb
332
335
  - spec/factories/users.rb
333
336
  - spec/factories/videos.rb
337
+ - spec/factories/item.rb
334
338
  - spec/tests/geometric_builder_spec.rb
335
- - spec/tests/range_spec.rb
336
- - spec/tests/table_inheritance_spec.rb
339
+ - spec/tests/arel_spec.rb
340
+ - spec/tests/insert_all_spec.rb
337
341
  - spec/tests/enum_spec.rb
338
- - spec/tests/auxiliary_statement_spec.rb
339
- - spec/tests/enum_set_spec.rb
340
- - spec/tests/coder_spec.rb
342
+ - spec/tests/period_spec.rb
343
+ - spec/tests/range_spec.rb
341
344
  - spec/tests/collector_spec.rb
342
345
  - spec/tests/distinct_on_spec.rb
343
346
  - spec/tests/interval_spec.rb
344
347
  - spec/tests/lazy_spec.rb
345
348
  - spec/tests/quoting_spec.rb
346
349
  - spec/tests/relation_spec.rb
347
- - spec/tests/belongs_to_many_spec.rb
348
- - spec/tests/period_spec.rb
349
- - spec/tests/arel_spec.rb
350
+ - spec/tests/auxiliary_statement_spec.rb
351
+ - spec/tests/enum_set_spec.rb
350
352
  - spec/tests/has_many_spec.rb
353
+ - spec/tests/belongs_to_many_spec.rb
354
+ - spec/tests/table_inheritance_spec.rb
351
355
  - spec/mocks/cache_query.rb
352
356
  - spec/mocks/create_table.rb
353
357
  - spec/en.yml
@@ -1,133 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Torque
4
- module PostgreSQL
5
- module Coder
6
-
7
- # This class represents an Record to be encoded, instead of a literal Array
8
- Record = Class.new(Array)
9
-
10
- class << self
11
-
12
- NEED_QUOTE_FOR = /[\\"(){}, \t\n\r\v\f]/m
13
- DELIMITER = ','
14
-
15
- # This method replace the +read_array+ method from PG gem
16
- # See https://github.com/ged/ruby-pg/blob/master/ext/pg_text_decoder.c#L177
17
- # for more information
18
- def decode(value)
19
- # TODO: Use StringScanner
20
- # See http://ruby-doc.org/stdlib-1.9.3/libdoc/strscan/rdoc/StringScanner.html
21
- _decode(::StringIO.new(value))
22
- end
23
-
24
- # This method replace the ++ method from PG gem
25
- # See https://github.com/ged/ruby-pg/blob/master/ext/pg_text_encoder.c#L398
26
- # for more information
27
- def encode(value)
28
- _encode(value)
29
- end
30
-
31
- private
32
-
33
- def _decode(stream)
34
- quoted = 0
35
- escaped = false
36
- result = []
37
- part = String.new
38
-
39
- # Always start getting the non-collection character, the second char
40
- stream.getc if stream.pos == 0
41
-
42
- # Check for an empty list
43
- return result if %w[} )].include?(stream.getc)
44
-
45
- # If it's not an empty list, return one position before iterating
46
- stream.pos -= 1
47
- stream.each_char do |c|
48
-
49
- case
50
- when quoted < 1
51
- case
52
- when c == DELIMITER, c == '}', c == ')'
53
-
54
- unless escaped
55
- # Non-quoted empty string or NULL as extense
56
- part = nil if quoted == 0 && ( part.length == 0 || part == 'NULL' )
57
- result << part
58
- end
59
-
60
- return result unless c == DELIMITER
61
-
62
- escaped = false
63
- quoted = 0
64
- part = String.new
65
-
66
- when c == '"'
67
- quoted = 1
68
- when c == '{', c == '('
69
- result << _decode(stream)
70
- escaped = true
71
- else
72
- part << c
73
- end
74
- when escaped
75
- escaped = false
76
- part << c
77
- when c == '\\'
78
- escaped = true
79
- when c == '"'
80
- if stream.getc == '"'
81
- part << c
82
- else
83
- stream.pos -= 1
84
- quoted = -1
85
- end
86
- else
87
- if ( c == '"' || c == "'" ) && stream.getc != c
88
- stream.pos -= 1
89
- quoted = -1
90
- else
91
- part << c
92
- end
93
- end
94
-
95
- end
96
- end
97
-
98
- def _encode(list)
99
- is_record = list.is_a?(Record)
100
- list.map! do |part|
101
- case part
102
- when NilClass
103
- is_record ? '' : 'NULL'
104
- when Array
105
- _encode(part)
106
- else
107
- _quote(part.to_s)
108
- end
109
- end
110
-
111
- result = is_record ? '(%s)' : '{%s}'
112
- result % list.join(DELIMITER)
113
- end
114
-
115
- def _quote(string)
116
- len = string.length
117
-
118
- # Fast results
119
- return '""' if len == 0
120
- return '"NULL"' if len == 4 && string == 'NULL'
121
-
122
- # Check if the string don't need quotes
123
- return string unless string =~ NEED_QUOTE_FOR
124
-
125
- # Use the original string escape function
126
- PG::Connection.escape_string(string).inspect
127
- end
128
-
129
- end
130
-
131
- end
132
- end
133
- end
@@ -1,367 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe 'Complex coder', type: :helper do
4
- let(:coder) { Torque::PostgreSQL::Coder }
5
-
6
- context 'on decode' do
7
-
8
- context 'one dimensional arrays' do
9
- it 'returns an empty array' do
10
- expect(coder.decode(%[{}])).to eql []
11
- end
12
-
13
- it 'returns an array of strings' do
14
- expect(coder.decode(%[{1,2,3}])).to eql ['1','2','3']
15
- end
16
-
17
- it 'returns an array of strings, with nils replacing NULL characters' do
18
- expect(coder.decode(%[{1,,NULL}])).to eql ['1',nil,nil]
19
- end
20
-
21
- it 'returns an array with the word NULL' do
22
- expect(coder.decode(%[{1,"NULL",3}])).to eql ['1','NULL','3']
23
- end
24
-
25
- it 'returns an array of strings when containing commas in a quoted string' do
26
- expect(coder.decode(%[{1,"2,3",4}])).to eql ['1','2,3','4']
27
- end
28
-
29
- it 'returns an array of strings when containing an escaped quote' do
30
- expect(coder.decode(%[{1,"2\\",3",4}])).to eql ['1','2",3','4']
31
- end
32
-
33
- it 'returns an array of strings when containing an escaped backslash' do
34
- expect(coder.decode(%[{1,"2\\\\",3,4}])).to eql ['1','2\\','3','4']
35
- expect(coder.decode(%[{1,"2\\\\\\",3",4}])).to eql ['1','2\\",3','4']
36
- end
37
-
38
- it 'returns an array containing empty strings' do
39
- expect(coder.decode(%[{1,"",3,""}])).to eql ['1', '', '3', '']
40
- end
41
-
42
- it 'returns an array containing unicode strings' do
43
- expect(coder.decode(%[{"Paragraph 399(b)(i) – “valid leave” – meaning"}])).to eq(['Paragraph 399(b)(i) – “valid leave” – meaning'])
44
- end
45
- end
46
-
47
- context 'two dimensional arrays' do
48
- it 'returns an empty array' do
49
- expect(coder.decode(%[{{}}])).to eql [[]]
50
- expect(coder.decode(%[{{},{}}])).to eql [[],[]]
51
- end
52
-
53
- it 'returns an array of strings with a sub array' do
54
- expect(coder.decode(%[{1,{2,3},4}])).to eql ['1',['2','3'],'4']
55
- end
56
-
57
- it 'returns an array of strings with a sub array' do
58
- expect(coder.decode(%[{1,{"2,3"},4}])).to eql ['1',['2,3'],'4']
59
- end
60
-
61
- it 'returns an array of strings with a sub array and a quoted }' do
62
- expect(coder.decode(%[{1,{"2,}3",,NULL},4}])).to eql ['1',['2,}3',nil,nil],'4']
63
- end
64
-
65
- it 'returns an array of strings with a sub array and a quoted {' do
66
- expect(coder.decode(%[{1,{"2,{3"},4}])).to eql ['1',['2,{3'],'4']
67
- end
68
-
69
- it 'returns an array of strings with a sub array and a quoted { and escaped quote' do
70
- expect(coder.decode(%[{1,{"2\\",{3"},4}])).to eql ['1',['2",{3'],'4']
71
- end
72
-
73
- it 'returns an array of strings with a sub array with empty strings' do
74
- expect(coder.decode(%[{1,{""},4,{""}}])).to eql ['1',[''],'4',['']]
75
- end
76
- end
77
-
78
- context 'three dimensional arrays' do
79
- it 'returns an empty array' do
80
- expect(coder.decode(%[{{{}}}])).to eql [[[]]]
81
- expect(coder.decode(%[{{{},{}},{{},{}}}])).to eql [[[],[]],[[],[]]]
82
- end
83
-
84
- it 'returns an array of strings with sub arrays' do
85
- expect(coder.decode(%[{1,{2,{3,4}},{NULL,,6},7}])).to eql ['1',['2',['3','4']],[nil,nil,'6'],'7']
86
- end
87
- end
88
-
89
- context 'record syntax' do
90
- it 'returns an empty array' do
91
- expect(coder.decode(%[()])).to eql []
92
- end
93
-
94
- it 'returns an array of strings' do
95
- expect(coder.decode(%[(1,2,3)])).to eql ['1','2','3']
96
- end
97
-
98
- it 'returns an array of strings, with nils replacing NULL characters' do
99
- expect(coder.decode(%[(1,,NULL)])).to eql ['1',nil,nil]
100
- end
101
-
102
- it 'returns an array with the word NULL' do
103
- expect(coder.decode(%[(1,"NULL",3)])).to eql ['1','NULL','3']
104
- end
105
-
106
- it 'returns an array of strings when containing commas in a quoted string' do
107
- expect(coder.decode(%[(1,"2,3",4)])).to eql ['1','2,3','4']
108
- end
109
-
110
- it 'returns an array of strings when containing an escaped quote' do
111
- expect(coder.decode(%[(1,"2\\",3",4)])).to eql ['1','2",3','4']
112
- end
113
-
114
- it 'returns an array of strings when containing an escaped backslash' do
115
- expect(coder.decode(%[(1,"2\\\\",3,4)])).to eql ['1','2\\','3','4']
116
- expect(coder.decode(%[(1,"2\\\\\\",3",4)])).to eql ['1','2\\",3','4']
117
- end
118
-
119
- it 'returns an array containing empty strings' do
120
- expect(coder.decode(%[(1,"",3,"")])).to eql ['1', '', '3', '']
121
- end
122
-
123
- it 'returns an array containing unicode strings' do
124
- expect(coder.decode(%[("Paragraph 399(b)(i) – “valid leave” – meaning")])).to eq(['Paragraph 399(b)(i) – “valid leave” – meaning'])
125
- end
126
- end
127
-
128
- context 'array of records' do
129
- it 'returns an empty array' do
130
- expect(coder.decode(%[{()}])).to eql [[]]
131
- expect(coder.decode(%[{(),()}])).to eql [[],[]]
132
- end
133
-
134
- it 'returns an array of strings with a sub array' do
135
- expect(coder.decode(%[{1,(2,3),4}])).to eql ['1',['2','3'],'4']
136
- end
137
-
138
- it 'returns an array of strings with a sub array' do
139
- expect(coder.decode(%[{1,("2,3"),4}])).to eql ['1',['2,3'],'4']
140
- end
141
-
142
- it 'returns an array of strings with a sub array and a quoted }' do
143
- expect(coder.decode(%[{1,("2,}3",,NULL),4}])).to eql ['1',['2,}3',nil,nil],'4']
144
- end
145
-
146
- it 'returns an array of strings with a sub array and a quoted {' do
147
- expect(coder.decode(%[{1,("2,{3"),4}])).to eql ['1',['2,{3'],'4']
148
- end
149
-
150
- it 'returns an array of strings with a sub array and a quoted { and escaped quote' do
151
- expect(coder.decode(%[{1,("2\\",{3"),4}])).to eql ['1',['2",{3'],'4']
152
- end
153
-
154
- it 'returns an array of strings with a sub array with empty strings' do
155
- expect(coder.decode(%[{1,(""),4,("")}])).to eql ['1',[''],'4',['']]
156
- end
157
- end
158
-
159
- context 'mix of record and array' do
160
- it 'returns an empty array' do
161
- expect(coder.decode(%[({()})])).to eql [[[]]]
162
- expect(coder.decode(%[{({},{}),{(),{}}}])).to eql [[[],[]],[[],[]]]
163
- end
164
-
165
- it 'returns an array of strings with sub arrays' do
166
- expect(coder.decode(%[{1,(2,{3,4}),(NULL,,6),7}])).to eql ['1',['2',['3','4']],[nil,nil,'6'],'7']
167
- end
168
- end
169
-
170
- context 'record complex sample' do
171
- it 'may have double double quotes translate to single double quotes' do
172
- expect(coder.decode(%[("Test with double "" quoutes")])).to eql ['Test with double " quoutes']
173
- end
174
-
175
- it 'double double quotes may occur any number of times' do
176
- expect(coder.decode(%[("Only one ""","Now "" two "".",""",""{""}","""""")])).to eql ['Only one "', 'Now " two ".', '","{"}', '""']
177
- end
178
-
179
- it 'may have any kind of value' do
180
- expect(coder.decode(%[(String,123456,false,true,"2016-01-01 12:00:00",{1,2,3})])).to eql ['String', '123456', 'false', 'true', '2016-01-01 12:00:00', ['1', '2', '3']]
181
- end
182
- end
183
-
184
- end
185
-
186
- context 'on encode' do
187
- let(:record) { Torque::PostgreSQL::Coder::Record }
188
-
189
- context 'one dimensional arrays' do
190
- it 'receives an empty array' do
191
- expect(coder.encode([])).to eql %[{}]
192
- end
193
-
194
- it 'receives an array of strings' do
195
- expect(coder.encode(['1','2','3'])).to eql %[{1,2,3}]
196
- end
197
-
198
- it 'receives an array of strings, with nils replacing NULL characters' do
199
- expect(coder.encode(['1',nil,nil])).to eql %[{1,NULL,NULL}]
200
- end
201
-
202
- it 'receives an array with the word NULL' do
203
- expect(coder.encode(['1','NULL','3'])).to eql %[{1,"NULL",3}]
204
- end
205
-
206
- it 'receives an array of strings when containing commas in a quoted string' do
207
- expect(coder.encode(['1','2,3','4'])).to eql %[{1,"2,3",4}]
208
- end
209
-
210
- it 'receives an array of strings when containing an escaped quote' do
211
- expect(coder.encode(['1','2",3','4'])).to eql %[{1,"2\\",3",4}]
212
- end
213
-
214
- it 'receives an array of strings when containing an escaped backslash' do
215
- expect(coder.encode(['1','2\\','3','4'])).to eql %[{1,"2\\\\",3,4}]
216
- expect(coder.encode(['1','2\\",3','4'])).to eql %[{1,"2\\\\\\",3",4}]
217
- end
218
-
219
- it 'receives an array containing empty strings' do
220
- expect(coder.encode(['1', '', '3', ''])).to eql %[{1,"",3,""}]
221
- end
222
-
223
- it 'receives an array containing unicode strings' do
224
- expect(coder.encode(['Paragraph 399(b)(i) – “valid leave” – meaning'])).to eql %[{"Paragraph 399(b)(i) – “valid leave” – meaning"}]
225
- end
226
- end
227
-
228
- context 'two dimensional arrays' do
229
- it 'receives an empty array' do
230
- expect(coder.encode([[]])).to eql %[{{}}]
231
- expect(coder.encode([[],[]])).to eql %[{{},{}}]
232
- end
233
-
234
- it 'receives an array of strings with a sub array' do
235
- expect(coder.encode(['1',['2','3'],'4'])).to eql %[{1,{2,3},4}]
236
- end
237
-
238
- it 'receives an array of strings with a sub array' do
239
- expect(coder.encode(['1',['2,3'],'4'])).to eql %[{1,{"2,3"},4}]
240
- end
241
-
242
- it 'receives an array of strings with a sub array and a quoted }' do
243
- expect(coder.encode(['1',['2,}3',nil,nil],'4'])).to eql %[{1,{"2,}3",NULL,NULL},4}]
244
- end
245
-
246
- it 'receives an array of strings with a sub array and a quoted {' do
247
- expect(coder.encode(['1',['2,{3'],'4'])).to eql %[{1,{"2,{3"},4}]
248
- end
249
-
250
- it 'receives an array of strings with a sub array and a quoted { and escaped quote' do
251
- expect(coder.encode(['1',['2",{3'],'4'])).to eql %[{1,{"2\\",{3"},4}]
252
- end
253
-
254
- it 'receives an array of strings with a sub array with empty strings' do
255
- expect(coder.encode(['1',[''],'4',['']])).to eql %[{1,{""},4,{""}}]
256
- end
257
- end
258
-
259
- context 'three dimensional arrays' do
260
- it 'receives an empty array' do
261
- expect(coder.encode([[[]]])).to eql %[{{{}}}]
262
- expect(coder.encode([[[],[]],[[],[]]])).to eql %[{{{},{}},{{},{}}}]
263
- end
264
-
265
- it 'receives an array of strings with sub arrays' do
266
- expect(coder.encode(['1',['2',['3','4']],[nil,nil,'6'],'7'])).to eql %[{1,{2,{3,4}},{NULL,NULL,6},7}]
267
- end
268
- end
269
-
270
- context 'record syntax' do
271
- it 'receives an empty array' do
272
- expect(coder.encode( record.new )).to eql %[()]
273
- end
274
-
275
- it 'receives an array of strings' do
276
- expect(coder.encode( record.new(['1','2','3']) )).to eql %[(1,2,3)]
277
- end
278
-
279
- it 'receives an array of strings, with nils replacing NULL characters' do
280
- expect(coder.encode( record.new(['1',nil,nil]) )).to eql %[(1,,)]
281
- end
282
-
283
- it 'receives an array with the word NULL' do
284
- expect(coder.encode( record.new(['1','NULL','3']) )).to eql %[(1,"NULL",3)]
285
- end
286
-
287
- it 'receives an array of strings when containing commas in a quoted string' do
288
- expect(coder.encode( record.new(['1','2,3','4']) )).to eql %[(1,"2,3",4)]
289
- end
290
-
291
- it 'receives an array of strings when containing an escaped quote' do
292
- expect(coder.encode( record.new(['1','2",3','4']) )).to eql %[(1,"2\\",3",4)]
293
- end
294
-
295
- it 'receives an array of strings when containing an escaped backslash' do
296
- expect(coder.encode( record.new(['1','2\\','3','4']) )).to eql %[(1,"2\\\\",3,4)]
297
- expect(coder.encode( record.new(['1','2\\",3','4']) )).to eql %[(1,"2\\\\\\",3",4)]
298
- end
299
-
300
- it 'receives an array containing empty strings' do
301
- expect(coder.encode( record.new(['1', '', '3', '']) )).to eql %[(1,"",3,"")]
302
- end
303
-
304
- it 'receives an array containing unicode strings' do
305
- expect(coder.encode( record.new(['Paragraph 399(b)(i) – “valid leave” – meaning']) )).to eql %[("Paragraph 399(b)(i) – “valid leave” – meaning")]
306
- end
307
- end
308
-
309
- context 'array of records' do
310
- it 'receives an empty array' do
311
- expect(coder.encode([record.new])).to eql %[{()}]
312
- expect(coder.encode([record.new,record.new])).to eql %[{(),()}]
313
- end
314
-
315
- it 'receives an array of strings with a sub array' do
316
- expect(coder.encode(['1',record.new(['2','3']),'4'])).to eql %[{1,(2,3),4}]
317
- end
318
-
319
- it 'receives an array of strings with a sub array' do
320
- expect(coder.encode(['1',record.new(['2,3']),'4'])).to eql %[{1,("2,3"),4}]
321
- end
322
-
323
- it 'receives an array of strings with a sub array and a quoted }' do
324
- expect(coder.encode(['1',record.new(['2,}3',nil,nil]),'4'])).to eql %[{1,("2,}3",,),4}]
325
- end
326
-
327
- it 'receives an array of strings with a sub array and a quoted {' do
328
- expect(coder.encode(['1',record.new(['2,{3']),'4'])).to eql %[{1,("2,{3"),4}]
329
- end
330
-
331
- it 'receives an array of strings with a sub array and a quoted { and escaped quote' do
332
- expect(coder.encode(['1',record.new(['2",{3']),'4'])).to eql %[{1,("2\\",{3"),4}]
333
- end
334
-
335
- it 'receives an array of strings with a sub array with empty strings' do
336
- expect(coder.encode(['1',record.new(['']),'4',record.new([''])])).to eql %[{1,(""),4,("")}]
337
- end
338
- end
339
-
340
- context 'mix of record and array' do
341
- it 'receives an empty array' do
342
- expect(coder.encode( record.new([[record.new,nil]]) )).to eql %[({(),NULL})]
343
- expect(coder.encode( [record.new([[], []]),[record.new,[]]] )).to eql %[{({},{}),{(),{}}}]
344
- end
345
-
346
- it 'receives an array of strings with sub arrays' do
347
- expect(coder.encode(['1',record.new(['2',['3','4']]),record.new([nil,nil,'6']),'7'])).to eql %[{1,(2,{3,4}),(,,6),7}]
348
- end
349
- end
350
-
351
- context 'record complex sample' do
352
- it 'may have double double quotes translate to single double quotes' do
353
- expect(coder.encode( record.new(['Test with double " quoutes']) )).to eql %[("Test with double \\" quoutes")]
354
- end
355
-
356
- it 'double double quotes may occur any number of times' do
357
- expect(coder.encode( record.new(['Only one "', 'Now " two ".', '","{"}', '""']) )).to eql %[("Only one \\"","Now \\" two \\".","\\",\\"{\\"}","\\"\\"")]
358
- end
359
-
360
- it 'may have any kind of value' do
361
- expect(coder.encode( record.new(['String', '123456', 'false', 'true', '2016-01-01 12:00:00', ['1', '2', '3']]) )).to eql %[(String,123456,false,true,"2016-01-01 12:00:00",{1,2,3})]
362
- end
363
- end
364
-
365
- end
366
-
367
- end