torque-postgresql 2.1.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f5815c2fe0a3682db3ccb907a29aa171382bfa6d70ffcb58ef7e7bdbb840f65
4
- data.tar.gz: 32ae2c431e089c2c83d6c73be202ae86e79c129f1a79a08ca596ff87ffb231f6
3
+ metadata.gz: 83fb6f6620a916f7ef85af51f4ba4fa6e2a1c6b3597ee5884466e4d46b6544c6
4
+ data.tar.gz: 7503abd9ce29bd38349d88527502abc51182bb5e158e0f1960b71817d65cd559
5
5
  SHA512:
6
- metadata.gz: 78c8d75e7b3534570caa48fe0a607417431813b04d842fb60b292d252d7ab0cb73ac16df488ba71242238f160ad746fe21ea162a988da0e11809c962e988b2d7
7
- data.tar.gz: a9450b4271ddf00be01ef4fb1a45365970310887d0179c457928f8ab36d0be9378e9738befe3797380ace0cbb66181f973f4d966cd39cd3fff7eceef7afb8082
6
+ metadata.gz: 13c371dccc04ee5663e2d249a443f398005a1d2e2cabea904c03f34c379ee4119c5ec5c7edeee52ef009d5223df9b514b6444b1ffeff9fc3231adbba93aebd5a
7
+ data.tar.gz: c8308c9290b8bac1ee2d990ec64e128cdeed903d09dbc391b23eb5867930c41febc1affaf043840c81675642bebd027e1a6bdf7400c4375c23cfe111496ee174
@@ -23,7 +23,6 @@ require 'torque/postgresql/auxiliary_statement'
23
23
  require 'torque/postgresql/base'
24
24
  require 'torque/postgresql/inheritance'
25
25
  require 'torque/postgresql/insert_all'
26
- require 'torque/postgresql/coder'
27
26
  require 'torque/postgresql/migration'
28
27
  require 'torque/postgresql/relation'
29
28
  require 'torque/postgresql/reflection'
@@ -123,7 +123,7 @@ module Torque
123
123
  SQL
124
124
 
125
125
  tables.map do |(table, refs)|
126
- [table, Coder.decode(refs)]
126
+ [table, PG::TextDecoder::Array.new.decode(refs)]
127
127
  end.to_h
128
128
  end
129
129
 
@@ -147,20 +147,6 @@ module Torque
147
147
  SQL
148
148
  end
149
149
 
150
- # Extracts the value from a PostgreSQL column default definition.
151
- def extract_value_from_default(default)
152
- case default
153
- # Array elements
154
- when /\AARRAY\[(.*)\]\z/
155
- # TODO: Improve this since it's not the most safe approach
156
- eval(default.gsub(/ARRAY|::\w+(\[\])?/, ''))
157
- else
158
- super
159
- end
160
- rescue SyntaxError
161
- # If somethin goes wrong with the eval, just return nil
162
- end
163
-
164
150
  end
165
151
  end
166
152
  end
@@ -8,9 +8,6 @@ module Torque
8
8
 
9
9
  attr_reader :name, :klass, :set_klass, :enum_klass
10
10
 
11
- # Delegate all Hash-like methods to the enum class
12
- delegate *(Array.public_instance_methods - Object.public_methods), to: :@klass
13
-
14
11
  def self.create(row, type_map)
15
12
  name = row['typname']
16
13
  oid = row['oid'].to_i
@@ -113,7 +113,7 @@ module Torque
113
113
  end
114
114
 
115
115
  def insert_record(record, *)
116
- super.tap do |saved|
116
+ (record.persisted? || super).tap do |saved|
117
117
  ids_rewriter(record.read_attribute(klass_attr), :<<) if saved
118
118
  end
119
119
  end
@@ -29,7 +29,7 @@ module Torque
29
29
  def include_on(klass, method_name = nil)
30
30
  method_name ||= Torque::PostgreSQL.config.enum.base_method
31
31
  Builder.include_on(klass, method_name, Builder::Enum) do |builder|
32
- defined_enums[builder.attribute.to_s] = builder.subtype
32
+ defined_enums[builder.attribute.to_s] = builder.subtype.klass
33
33
  end
34
34
  end
35
35
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Torque
4
4
  module PostgreSQL
5
- VERSION = '2.1.1'
5
+ VERSION = '2.1.2'
6
6
  end
7
7
  end
@@ -0,0 +1,5 @@
1
+ FactoryBot.define do
2
+ factory :item do
3
+ name { Faker::Lorem.sentence }
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ class Item < ActiveRecord::Base
2
+ belongs_to_many :tags
3
+ end
data/spec/schema.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
13
  begin
14
- version = 63
14
+ version = 70
15
15
 
16
16
  raise SystemExit if ActiveRecord::Migrator.current_version == version
17
17
  ActiveRecord::Schema.define(version: version) do
@@ -102,6 +102,13 @@ begin
102
102
  t.index ["author_id"], name: "index_posts_on_author_id", using: :btree
103
103
  end
104
104
 
105
+ create_table "items", force: :cascade do |t|
106
+ t.string "name"
107
+ t.bigint "tag_ids", array: true, default: "{1}"
108
+ t.datetime "created_at", null: false
109
+ t.datetime "updated_at", null: false
110
+ end
111
+
105
112
  create_table "users", force: :cascade do |t|
106
113
  t.string "name", null: false
107
114
  t.enum "role", subtype: :roles, default: :visitor
@@ -147,6 +147,22 @@ RSpec.describe 'BelongsToMany' do
147
147
  expect(record.tags.count).to be_eql(5)
148
148
  end
149
149
 
150
+ it 'does not trigger after commit on the associated record' do
151
+ called = false
152
+
153
+ tag = FactoryBot.create(:tag)
154
+ Tag.after_commit { called = true }
155
+
156
+ expect(called).to be_falsey
157
+
158
+ subject.tags << tag
159
+
160
+ expect(subject.tag_ids).to be_eql([tag.id])
161
+ expect(called).to be_falsey
162
+
163
+ Tag.reset_callbacks(:commit)
164
+ end
165
+
150
166
  it 'can build an associated record' do
151
167
  record = subject.tags.build(name: 'Test')
152
168
  expect(record).to be_a(other)
@@ -330,17 +346,11 @@ RSpec.describe 'BelongsToMany' do
330
346
  end
331
347
 
332
348
  context 'When the attribute has a default value' do
333
- after(:all) { Video.reset_column_information }
334
- let(:sql) { %{ALTER TABLE "videos" ALTER COLUMN "tag_ids" SET DEFAULT '{}'::bigint[]} }
335
-
336
- before do
337
- Video.connection.execute(sql)
338
- Video.reset_column_information
339
- end
349
+ subject { FactoryBot.create(:item) }
340
350
 
341
351
  it 'will always return the column default value' do
342
352
  expect(subject.tag_ids).to be_a(Array)
343
- expect(subject.tag_ids).to be_empty
353
+ expect(subject.tag_ids).to be_eql([1])
344
354
  end
345
355
 
346
356
  it 'will keep the value as an array even when the association is cleared' do
@@ -349,12 +359,12 @@ RSpec.describe 'BelongsToMany' do
349
359
 
350
360
  subject.reload
351
361
  expect(subject.tag_ids).to be_a(Array)
352
- expect(subject.tag_ids).not_to be_empty
362
+ expect(subject.tag_ids).not_to be_eql([1, *records.map(&:id)])
353
363
 
354
364
  subject.tags.clear
355
365
  subject.reload
356
366
  expect(subject.tag_ids).to be_a(Array)
357
- expect(subject.tag_ids).to be_empty
367
+ expect(subject.tag_ids).to be_eql([1])
358
368
  end
359
369
  end
360
370
 
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.1.1
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: 2021-03-04 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,7 +215,6 @@ 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
@@ -243,6 +242,7 @@ files:
243
242
  - spec/en.yml
244
243
  - spec/factories/authors.rb
245
244
  - spec/factories/comments.rb
245
+ - spec/factories/item.rb
246
246
  - spec/factories/posts.rb
247
247
  - spec/factories/tags.rb
248
248
  - spec/factories/texts.rb
@@ -260,6 +260,7 @@ files:
260
260
  - spec/models/course.rb
261
261
  - spec/models/geometry.rb
262
262
  - spec/models/guest_comment.rb
263
+ - spec/models/item.rb
263
264
  - spec/models/post.rb
264
265
  - spec/models/tag.rb
265
266
  - spec/models/text.rb
@@ -271,7 +272,6 @@ files:
271
272
  - spec/tests/arel_spec.rb
272
273
  - spec/tests/auxiliary_statement_spec.rb
273
274
  - spec/tests/belongs_to_many_spec.rb
274
- - spec/tests/coder_spec.rb
275
275
  - spec/tests/collector_spec.rb
276
276
  - spec/tests/distinct_on_spec.rb
277
277
  - spec/tests/enum_set_spec.rb
@@ -305,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
305
305
  - !ruby/object:Gem::Version
306
306
  version: 1.8.11
307
307
  requirements: []
308
- rubygems_version: 3.1.4
308
+ rubygems_version: 3.2.14
309
309
  signing_key:
310
310
  specification_version: 4
311
311
  summary: ActiveRecord extension to access PostgreSQL advanced resources
@@ -326,6 +326,7 @@ test_files:
326
326
  - spec/models/tag.rb
327
327
  - spec/models/time_keeper.rb
328
328
  - spec/models/video.rb
329
+ - spec/models/item.rb
329
330
  - spec/factories/authors.rb
330
331
  - spec/factories/comments.rb
331
332
  - spec/factories/posts.rb
@@ -333,13 +334,13 @@ test_files:
333
334
  - spec/factories/texts.rb
334
335
  - spec/factories/users.rb
335
336
  - spec/factories/videos.rb
337
+ - spec/factories/item.rb
336
338
  - spec/tests/geometric_builder_spec.rb
337
- - spec/tests/range_spec.rb
338
339
  - spec/tests/arel_spec.rb
339
340
  - spec/tests/insert_all_spec.rb
340
341
  - spec/tests/enum_spec.rb
341
342
  - spec/tests/period_spec.rb
342
- - spec/tests/coder_spec.rb
343
+ - spec/tests/range_spec.rb
343
344
  - spec/tests/collector_spec.rb
344
345
  - spec/tests/distinct_on_spec.rb
345
346
  - spec/tests/interval_spec.rb
@@ -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