iostreams 1.2.1 → 1.6.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.
- checksums.yaml +4 -4
- data/README.md +19 -4
- data/lib/io_streams/builder.rb +27 -10
- data/lib/io_streams/bzip2/reader.rb +3 -3
- data/lib/io_streams/bzip2/writer.rb +3 -3
- data/lib/io_streams/deprecated.rb +1 -1
- data/lib/io_streams/encode/reader.rb +1 -3
- data/lib/io_streams/encode/writer.rb +1 -1
- data/lib/io_streams/errors.rb +22 -0
- data/lib/io_streams/io_streams.rb +1 -5
- data/lib/io_streams/line/reader.rb +28 -16
- data/lib/io_streams/path.rb +3 -1
- data/lib/io_streams/paths/file.rb +4 -4
- data/lib/io_streams/paths/http.rb +6 -3
- data/lib/io_streams/paths/s3.rb +30 -8
- data/lib/io_streams/paths/sftp.rb +34 -13
- data/lib/io_streams/pgp.rb +84 -71
- data/lib/io_streams/stream.rb +78 -12
- data/lib/io_streams/tabular.rb +28 -27
- data/lib/io_streams/tabular/header.rb +14 -12
- data/lib/io_streams/tabular/parser/csv.rb +4 -2
- data/lib/io_streams/tabular/parser/fixed.rb +166 -26
- data/lib/io_streams/tabular/utility/csv_row.rb +1 -4
- data/lib/io_streams/utils.rb +4 -4
- data/lib/io_streams/version.rb +1 -1
- data/lib/io_streams/zip/reader.rb +1 -1
- data/test/builder_test.rb +29 -0
- data/test/bzip2_writer_test.rb +6 -4
- data/test/deprecated_test.rb +2 -0
- data/test/files/test.psv +4 -0
- data/test/files/unclosed_quote_large_test.csv +1658 -0
- data/test/files/unclosed_quote_test2.csv +3 -0
- data/test/io_streams_test.rb +2 -2
- data/test/line_reader_test.rb +30 -4
- data/test/paths/file_test.rb +1 -1
- data/test/paths/s3_test.rb +3 -3
- data/test/paths/sftp_test.rb +4 -4
- data/test/pgp_test.rb +54 -4
- data/test/pgp_writer_test.rb +3 -3
- data/test/stream_test.rb +174 -8
- data/test/tabular_test.rb +100 -40
- data/test/test_helper.rb +1 -1
- metadata +47 -42
data/test/io_streams_test.rb
CHANGED
@@ -16,7 +16,7 @@ module IOStreams
|
|
16
16
|
end
|
17
17
|
|
18
18
|
let :json_file_name do
|
19
|
-
"/tmp/
|
19
|
+
"/tmp/iostreams_abc.json"
|
20
20
|
end
|
21
21
|
|
22
22
|
describe ".root" do
|
@@ -90,7 +90,7 @@ module IOStreams
|
|
90
90
|
it "hash reader detects json format from file name" do
|
91
91
|
::File.open(json_file_name, "wb") { |file| file.write(expected_json) }
|
92
92
|
rows = []
|
93
|
-
path = IOStreams.path(
|
93
|
+
path = IOStreams.path(json_file_name)
|
94
94
|
path.each(:hash) do |row|
|
95
95
|
rows << row
|
96
96
|
end
|
data/test/line_reader_test.rb
CHANGED
@@ -14,6 +14,14 @@ class LineReaderTest < Minitest::Test
|
|
14
14
|
File.join(File.dirname(__FILE__), "files", "unclosed_quote_test.csv")
|
15
15
|
end
|
16
16
|
|
17
|
+
let :unclosed_quote_file2 do
|
18
|
+
File.join(File.dirname(__FILE__), "files", "unclosed_quote_test2.csv")
|
19
|
+
end
|
20
|
+
|
21
|
+
let :unclosed_quote_large_file do
|
22
|
+
File.join(File.dirname(__FILE__), "files", "unclosed_quote_large_test.csv")
|
23
|
+
end
|
24
|
+
|
17
25
|
let :data do
|
18
26
|
data = []
|
19
27
|
File.open(file_name, "rt") do |file|
|
@@ -51,13 +59,31 @@ class LineReaderTest < Minitest::Test
|
|
51
59
|
assert_equal 4, lines.count
|
52
60
|
end
|
53
61
|
|
54
|
-
it "raises error for
|
55
|
-
assert_raises(
|
62
|
+
it "raises error for unbalanced quotes" do
|
63
|
+
exc = assert_raises(IOStreams::Errors::MalformedDataError) do
|
56
64
|
IOStreams::Line::Reader.file(unclosed_quote_file, embedded_within: '"') do |io|
|
57
|
-
io.each
|
58
|
-
|
65
|
+
io.each { |line| }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
assert_includes exc.message, "Unbalanced delimited field, delimiter:"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "raises error for unclosed quote" do
|
72
|
+
exc = assert_raises(IOStreams::Errors::MalformedDataError) do
|
73
|
+
IOStreams::Line::Reader.file(unclosed_quote_file2, embedded_within: '"') do |io|
|
74
|
+
io.each { |line| }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
assert_includes exc.message, "Unbalanced delimited field, delimiter:"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "raises error for unclosed quote before eof" do
|
81
|
+
exc = assert_raises(IOStreams::Errors::MalformedDataError) do
|
82
|
+
IOStreams::Line::Reader.file(unclosed_quote_large_file, embedded_within: '"', buffer_size: 20) do |io|
|
83
|
+
io.each { |line| }
|
59
84
|
end
|
60
85
|
end
|
86
|
+
assert_includes exc.message, "Unbalanced delimited field, delimiter:"
|
61
87
|
end
|
62
88
|
end
|
63
89
|
end
|
data/test/paths/file_test.rb
CHANGED
data/test/paths/s3_test.rb
CHANGED
@@ -73,7 +73,7 @@ module Paths
|
|
73
73
|
|
74
74
|
describe "#reader" do
|
75
75
|
it "reads" do
|
76
|
-
assert_equal raw, existing_path.
|
76
|
+
assert_equal raw, existing_path.read
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -89,7 +89,7 @@ module Paths
|
|
89
89
|
|
90
90
|
describe "#writer" do
|
91
91
|
it "writes" do
|
92
|
-
assert_equal
|
92
|
+
assert_equal(raw.size, write_path.writer { |io| io.write(raw) })
|
93
93
|
assert write_path.exist?
|
94
94
|
assert_equal raw, write_path.read
|
95
95
|
end
|
@@ -138,7 +138,7 @@ module Paths
|
|
138
138
|
|
139
139
|
it "returns all the children under a sub-dir" do
|
140
140
|
write_raw_data
|
141
|
-
expected =
|
141
|
+
expected = %w[abd/test1.txt abd/test5.file].collect { |file_name| each_root.join(file_name) }
|
142
142
|
assert_equal expected.collect(&:to_s).sort, each_root.children("abd/*").collect(&:to_s).sort
|
143
143
|
end
|
144
144
|
|
data/test/paths/sftp_test.rb
CHANGED
@@ -42,7 +42,7 @@ module Paths
|
|
42
42
|
|
43
43
|
describe "#reader" do
|
44
44
|
it "reads" do
|
45
|
-
assert_equal raw, existing_path.
|
45
|
+
assert_equal raw, existing_path.read
|
46
46
|
end
|
47
47
|
|
48
48
|
it "fails when the file does not exist" do
|
@@ -60,7 +60,7 @@ module Paths
|
|
60
60
|
|
61
61
|
describe "#writer" do
|
62
62
|
it "writes" do
|
63
|
-
assert_equal
|
63
|
+
assert_equal(raw.size, write_path.writer { |io| io.write(raw) })
|
64
64
|
assert_equal raw, write_path.read
|
65
65
|
end
|
66
66
|
|
@@ -77,7 +77,7 @@ module Paths
|
|
77
77
|
|
78
78
|
it "writes" do
|
79
79
|
skip "No identity file env var set: SFTP_IDENTITY_FILE" unless ENV["SFTP_IDENTITY_FILE"]
|
80
|
-
assert_equal
|
80
|
+
assert_equal(raw.size, write_path.writer { |io| io.write(raw) })
|
81
81
|
assert_equal raw, write_path.read
|
82
82
|
end
|
83
83
|
end
|
@@ -90,7 +90,7 @@ module Paths
|
|
90
90
|
|
91
91
|
it "writes" do
|
92
92
|
skip "No identity file env var set: SFTP_IDENTITY_FILE" unless ENV["SFTP_IDENTITY_FILE"]
|
93
|
-
assert_equal
|
93
|
+
assert_equal(raw.size, write_path.writer { |io| io.write(raw) })
|
94
94
|
assert_equal raw, write_path.read
|
95
95
|
end
|
96
96
|
end
|
data/test/pgp_test.rb
CHANGED
@@ -70,7 +70,7 @@ class PgpTest < Minitest::Test
|
|
70
70
|
refute IOStreams::Pgp.delete_keys(email: "random@iostreams.net", public: true, private: true)
|
71
71
|
end
|
72
72
|
|
73
|
-
it "deletes existing keys" do
|
73
|
+
it "deletes existing keys with specified email" do
|
74
74
|
generated_key_id
|
75
75
|
# There is a timing issue with creating and then deleting keys.
|
76
76
|
# Call list_keys again to give GnuPGP time.
|
@@ -78,7 +78,16 @@ class PgpTest < Minitest::Test
|
|
78
78
|
assert IOStreams::Pgp.delete_keys(email: email, public: true, private: true)
|
79
79
|
end
|
80
80
|
|
81
|
-
it "deletes
|
81
|
+
it "deletes existing keys with specified key_id" do
|
82
|
+
generated_key_id
|
83
|
+
|
84
|
+
# There is a timing issue with creating and then deleting keys.
|
85
|
+
# Call list_keys again to give GnuPGP time.
|
86
|
+
IOStreams::Pgp.list_keys(key_id: generated_key_id, private: true)
|
87
|
+
assert IOStreams::Pgp.delete_keys(key_id: generated_key_id, public: true, private: true)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "deletes just the private key with specified email" do
|
82
91
|
generated_key_id
|
83
92
|
# There is a timing issue with creating and then deleting keys.
|
84
93
|
# Call list_keys again to give GnuPGP time.
|
@@ -87,6 +96,16 @@ class PgpTest < Minitest::Test
|
|
87
96
|
refute IOStreams::Pgp.key?(key_id: generated_key_id, private: true)
|
88
97
|
assert IOStreams::Pgp.key?(key_id: generated_key_id, private: false)
|
89
98
|
end
|
99
|
+
|
100
|
+
it "deletes just the private key with specified key_id" do
|
101
|
+
generated_key_id
|
102
|
+
# There is a timing issue with creating and then deleting keys.
|
103
|
+
# Call list_keys again to give GnuPGP time.
|
104
|
+
IOStreams::Pgp.list_keys(key_id: generated_key_id, private: true)
|
105
|
+
assert IOStreams::Pgp.delete_keys(key_id: generated_key_id, public: false, private: true)
|
106
|
+
refute IOStreams::Pgp.key?(key_id: generated_key_id, private: true)
|
107
|
+
assert IOStreams::Pgp.key?(key_id: generated_key_id, private: false)
|
108
|
+
end
|
90
109
|
end
|
91
110
|
|
92
111
|
describe ".export" do
|
@@ -113,7 +132,7 @@ class PgpTest < Minitest::Test
|
|
113
132
|
IOStreams::Pgp.list_keys(email: email)
|
114
133
|
end
|
115
134
|
|
116
|
-
it "lists public keys" do
|
135
|
+
it "lists public keys for email" do
|
117
136
|
assert keys = IOStreams::Pgp.list_keys(email: email)
|
118
137
|
assert_equal 1, keys.size
|
119
138
|
assert key = keys.first
|
@@ -130,7 +149,24 @@ class PgpTest < Minitest::Test
|
|
130
149
|
assert_equal "ultimate", key[:trust] if (ver.to_f >= 2) && (maint >= 30)
|
131
150
|
end
|
132
151
|
|
133
|
-
it "lists
|
152
|
+
it "lists public keys for key_id" do
|
153
|
+
assert keys = IOStreams::Pgp.list_keys(key_id: generated_key_id)
|
154
|
+
assert_equal 1, keys.size
|
155
|
+
assert key = keys.first
|
156
|
+
|
157
|
+
assert_equal Date.today, key[:date]
|
158
|
+
assert_equal email, key[:email]
|
159
|
+
assert_includes key[:key_id], generated_key_id
|
160
|
+
assert_equal 1024, key[:key_length]
|
161
|
+
assert_includes %w[R rsa], key[:key_type]
|
162
|
+
assert_equal user_name, key[:name]
|
163
|
+
refute key[:private], key
|
164
|
+
ver = IOStreams::Pgp.pgp_version
|
165
|
+
maint = ver.split(".").last.to_i
|
166
|
+
assert_equal "ultimate", key[:trust] if (ver.to_f >= 2) && (maint >= 30)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "lists private keys for email" do
|
134
170
|
assert keys = IOStreams::Pgp.list_keys(email: email, private: true)
|
135
171
|
assert_equal 1, keys.size
|
136
172
|
assert key = keys.first
|
@@ -143,6 +179,20 @@ class PgpTest < Minitest::Test
|
|
143
179
|
assert_equal user_name, key[:name]
|
144
180
|
assert key[:private], key
|
145
181
|
end
|
182
|
+
|
183
|
+
it "lists private keys for key_id" do
|
184
|
+
assert keys = IOStreams::Pgp.list_keys(key_id: generated_key_id, private: true)
|
185
|
+
assert_equal 1, keys.size
|
186
|
+
assert key = keys.first
|
187
|
+
|
188
|
+
assert_equal Date.today, key[:date]
|
189
|
+
assert_equal email, key[:email]
|
190
|
+
assert_includes key[:key_id], generated_key_id
|
191
|
+
assert_equal 1024, key[:key_length]
|
192
|
+
assert_includes %w[R rsa], key[:key_type]
|
193
|
+
assert_equal user_name, key[:name]
|
194
|
+
assert key[:private], key
|
195
|
+
end
|
146
196
|
end
|
147
197
|
|
148
198
|
describe ".key_info" do
|
data/test/pgp_writer_test.rb
CHANGED
@@ -53,9 +53,9 @@ class PgpWriterTest < Minitest::Test
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it "supports multiple recipients" do
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
IOStreams::Pgp::Writer.file(file_name, recipient: %w[receiver@example.org receiver2@example.org], signer: "sender@example.org", signer_passphrase: "sender_passphrase") do |io|
|
57
|
+
io.write(decrypted)
|
58
|
+
end
|
59
59
|
|
60
60
|
result = IOStreams::Pgp::Reader.file(file_name, passphrase: "receiver_passphrase", &:read)
|
61
61
|
assert_equal decrypted, result
|
data/test/stream_test.rb
CHANGED
@@ -45,9 +45,9 @@ class StreamTest < Minitest::Test
|
|
45
45
|
it "reads a zip file" do
|
46
46
|
File.open(multiple_zip_file_name, "rb") do |io|
|
47
47
|
result = IOStreams::Stream.new(io).
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
file_name(multiple_zip_file_name).
|
49
|
+
option(:zip, entry_file_name: "test.json").
|
50
|
+
read
|
51
51
|
assert_equal contents_test_json, result
|
52
52
|
end
|
53
53
|
end
|
@@ -55,8 +55,8 @@ class StreamTest < Minitest::Test
|
|
55
55
|
it "reads a zip file from within a gz file" do
|
56
56
|
File.open(zip_gz_file_name, "rb") do |io|
|
57
57
|
result = IOStreams::Stream.new(io).
|
58
|
-
|
59
|
-
|
58
|
+
file_name(zip_gz_file_name).
|
59
|
+
read
|
60
60
|
assert_equal contents_test_txt, result
|
61
61
|
end
|
62
62
|
end
|
@@ -71,7 +71,7 @@ class StreamTest < Minitest::Test
|
|
71
71
|
describe ".record_reader" do
|
72
72
|
end
|
73
73
|
|
74
|
-
describe "
|
74
|
+
describe "#each(:line)" do
|
75
75
|
it "returns a line at a time" do
|
76
76
|
lines = []
|
77
77
|
stream.stream(:none)
|
@@ -91,10 +91,114 @@ class StreamTest < Minitest::Test
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
describe "
|
94
|
+
describe "#each(:array)" do
|
95
|
+
describe "csv" do
|
96
|
+
let :source_file_name do
|
97
|
+
File.join(__dir__, "files", "test.csv")
|
98
|
+
end
|
99
|
+
|
100
|
+
let :expected_rows do
|
101
|
+
rows = []
|
102
|
+
CSV.open(source_file_name).each { |row| rows << row }
|
103
|
+
rows
|
104
|
+
end
|
105
|
+
|
106
|
+
it "detects format from file_name" do
|
107
|
+
output = []
|
108
|
+
stream.file_name = source_file_name
|
109
|
+
stream.each(:array) { |record| output << record }
|
110
|
+
assert_equal expected_rows, output
|
111
|
+
end
|
112
|
+
|
113
|
+
it "honors format" do
|
114
|
+
output = []
|
115
|
+
stream.file_name = "blah"
|
116
|
+
stream.format = :csv
|
117
|
+
stream.each(:array) { |record| output << record }
|
118
|
+
assert_equal expected_rows, output
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "psv" do
|
123
|
+
let :source_file_name do
|
124
|
+
File.join(__dir__, "files", "test.psv")
|
125
|
+
end
|
126
|
+
|
127
|
+
let :expected_rows do
|
128
|
+
File.readlines(source_file_name).collect { |line| line.chomp.split("|") }
|
129
|
+
end
|
130
|
+
|
131
|
+
it "detects format from file_name" do
|
132
|
+
output = []
|
133
|
+
stream.file_name = source_file_name
|
134
|
+
stream.each(:array) { |record| output << record }
|
135
|
+
assert_equal expected_rows, output
|
136
|
+
end
|
137
|
+
|
138
|
+
it "honors format" do
|
139
|
+
output = []
|
140
|
+
stream.file_name = "blah"
|
141
|
+
stream.format = :psv
|
142
|
+
stream.each(:array) { |record| output << record }
|
143
|
+
assert_equal expected_rows, output
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "json" do
|
148
|
+
let :source_file_name do
|
149
|
+
File.join(__dir__, "files", "test.json")
|
150
|
+
end
|
151
|
+
|
152
|
+
let :expected_rows do
|
153
|
+
hash_rows = File.readlines(source_file_name).collect { |line| JSON.load(line) }
|
154
|
+
rows = []
|
155
|
+
rows << hash_rows.first.keys
|
156
|
+
hash_rows.each { |hash| rows << hash.values }
|
157
|
+
rows
|
158
|
+
end
|
159
|
+
|
160
|
+
it "detects format from file_name" do
|
161
|
+
skip "TODO: Support reading json files as arrays"
|
162
|
+
output = []
|
163
|
+
stream.file_name = source_file_name
|
164
|
+
stream.each(:array) { |record| output << record }
|
165
|
+
assert_equal expected_rows, output
|
166
|
+
end
|
167
|
+
|
168
|
+
it "honors format" do
|
169
|
+
skip "TODO: Support reading json files as arrays"
|
170
|
+
output = []
|
171
|
+
stream.file_name = "blah"
|
172
|
+
stream.format = :json
|
173
|
+
stream.each(:array) { |record| output << record }
|
174
|
+
assert_equal expected_rows, output
|
175
|
+
end
|
176
|
+
end
|
95
177
|
end
|
96
178
|
|
97
|
-
describe ".each
|
179
|
+
describe ".each hash" do
|
180
|
+
let :source_file_name do
|
181
|
+
File.join(__dir__, "files", "test.json")
|
182
|
+
end
|
183
|
+
|
184
|
+
let :expected_json do
|
185
|
+
File.readlines(source_file_name).collect { |line| JSON.load(line) }
|
186
|
+
end
|
187
|
+
|
188
|
+
it "detects format from file_name" do
|
189
|
+
output = []
|
190
|
+
stream.file_name = source_file_name
|
191
|
+
stream.each(:hash) { |record| output << record }
|
192
|
+
assert_equal expected_json, output
|
193
|
+
end
|
194
|
+
|
195
|
+
it "honors format" do
|
196
|
+
output = []
|
197
|
+
stream.file_name = "blah"
|
198
|
+
stream.format = :json
|
199
|
+
stream.each(:hash) { |record| output << record }
|
200
|
+
assert_equal expected_json, output
|
201
|
+
end
|
98
202
|
end
|
99
203
|
|
100
204
|
describe "#writer" do
|
@@ -359,6 +463,24 @@ class StreamTest < Minitest::Test
|
|
359
463
|
end
|
360
464
|
assert_equal "\nHe\n\nl\n\nlo \nWorld\n\n", io.string, io.string.inspect
|
361
465
|
end
|
466
|
+
|
467
|
+
it "honors format" do
|
468
|
+
io = StringIO.new
|
469
|
+
IOStreams::Stream.new(io).format(:psv).writer(:array) do |stream|
|
470
|
+
stream << %w[first_name last_name]
|
471
|
+
stream << %w[Jack Johnson]
|
472
|
+
end
|
473
|
+
assert_equal "first_name|last_name\nJack|Johnson\n", io.string, io.string.inspect
|
474
|
+
end
|
475
|
+
|
476
|
+
it "auto detects format" do
|
477
|
+
io = StringIO.new
|
478
|
+
IOStreams::Stream.new(io).file_name("abc.psv").writer(:array) do |stream|
|
479
|
+
stream << %w[first_name last_name]
|
480
|
+
stream << %w[Jack Johnson]
|
481
|
+
end
|
482
|
+
assert_equal "first_name|last_name\nJack|Johnson\n", io.string, io.string.inspect
|
483
|
+
end
|
362
484
|
end
|
363
485
|
end
|
364
486
|
|
@@ -402,6 +524,50 @@ class StreamTest < Minitest::Test
|
|
402
524
|
end
|
403
525
|
assert_equal "first_name,last_name\nJack,Johnson\n\n{:first_name=>\"Able\", :last_name=>\"Smith\"}\n\n", io.string, io.string.inspect
|
404
526
|
end
|
527
|
+
|
528
|
+
it "honors format" do
|
529
|
+
io = StringIO.new
|
530
|
+
IOStreams::Stream.new(io).format(:json).writer(:hash) do |stream|
|
531
|
+
stream << {first_name: "Jack", last_name: "Johnson"}
|
532
|
+
end
|
533
|
+
assert_equal "{\"first_name\":\"Jack\",\"last_name\":\"Johnson\"}\n", io.string, io.string.inspect
|
534
|
+
end
|
535
|
+
|
536
|
+
it "auto detects format" do
|
537
|
+
io = StringIO.new
|
538
|
+
IOStreams::Stream.new(io).file_name("abc.json").writer(:hash) do |stream|
|
539
|
+
stream << {first_name: "Jack", last_name: "Johnson"}
|
540
|
+
end
|
541
|
+
assert_equal "{\"first_name\":\"Jack\",\"last_name\":\"Johnson\"}\n", io.string, io.string.inspect
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
describe "#format" do
|
547
|
+
it "detects the format from the file name" do
|
548
|
+
stream.file_name = "abc.json"
|
549
|
+
assert_equal :json, stream.format
|
550
|
+
end
|
551
|
+
|
552
|
+
it "is nil if the file name has no meaningful format" do
|
553
|
+
assert_nil stream.format
|
554
|
+
end
|
555
|
+
|
556
|
+
it "returns set format with no file_name" do
|
557
|
+
stream.format = :csv
|
558
|
+
assert_equal :csv, stream.format
|
559
|
+
end
|
560
|
+
|
561
|
+
it "returns set format with file_name" do
|
562
|
+
stream.file_name = "abc.json"
|
563
|
+
stream.format = :csv
|
564
|
+
assert_equal :csv, stream.format
|
565
|
+
end
|
566
|
+
|
567
|
+
it "validates bad format" do
|
568
|
+
assert_raises ArgumentError do
|
569
|
+
stream.format = :blah
|
570
|
+
end
|
405
571
|
end
|
406
572
|
end
|
407
573
|
end
|