flat_kit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +46 -0
  3. data/HISTORY.md +5 -0
  4. data/LICENSE.txt +21 -0
  5. data/Manifest.txt +66 -0
  6. data/README.md +80 -0
  7. data/Rakefile +20 -0
  8. data/bin/fk +4 -0
  9. data/lib/flat_kit.rb +23 -0
  10. data/lib/flat_kit/cli.rb +80 -0
  11. data/lib/flat_kit/command.rb +53 -0
  12. data/lib/flat_kit/command/cat.rb +93 -0
  13. data/lib/flat_kit/command/merge.rb +88 -0
  14. data/lib/flat_kit/command/sort.rb +88 -0
  15. data/lib/flat_kit/descendant_tracker.rb +27 -0
  16. data/lib/flat_kit/error.rb +5 -0
  17. data/lib/flat_kit/format.rb +34 -0
  18. data/lib/flat_kit/input.rb +32 -0
  19. data/lib/flat_kit/input/file.rb +53 -0
  20. data/lib/flat_kit/input/io.rb +54 -0
  21. data/lib/flat_kit/internal_node.rb +84 -0
  22. data/lib/flat_kit/jsonl.rb +8 -0
  23. data/lib/flat_kit/jsonl/format.rb +25 -0
  24. data/lib/flat_kit/jsonl/reader.rb +30 -0
  25. data/lib/flat_kit/jsonl/record.rb +84 -0
  26. data/lib/flat_kit/jsonl/writer.rb +45 -0
  27. data/lib/flat_kit/leaf_node.rb +71 -0
  28. data/lib/flat_kit/logger.rb +39 -0
  29. data/lib/flat_kit/merge.rb +35 -0
  30. data/lib/flat_kit/merge_tree.rb +104 -0
  31. data/lib/flat_kit/output.rb +32 -0
  32. data/lib/flat_kit/output/file.rb +55 -0
  33. data/lib/flat_kit/output/io.rb +73 -0
  34. data/lib/flat_kit/reader.rb +61 -0
  35. data/lib/flat_kit/record.rb +83 -0
  36. data/lib/flat_kit/sentinel_internal_node.rb +37 -0
  37. data/lib/flat_kit/sentinel_leaf_node.rb +37 -0
  38. data/lib/flat_kit/sort.rb +35 -0
  39. data/lib/flat_kit/writer.rb +38 -0
  40. data/lib/flat_kit/xsv.rb +8 -0
  41. data/lib/flat_kit/xsv/format.rb +25 -0
  42. data/lib/flat_kit/xsv/reader.rb +45 -0
  43. data/lib/flat_kit/xsv/record.rb +90 -0
  44. data/lib/flat_kit/xsv/writer.rb +70 -0
  45. data/tasks/default.rake +242 -0
  46. data/tasks/extension.rake +38 -0
  47. data/tasks/man.rake +7 -0
  48. data/tasks/this.rb +208 -0
  49. data/test/device_dataset.rb +117 -0
  50. data/test/input/test_file.rb +73 -0
  51. data/test/input/test_io.rb +93 -0
  52. data/test/jsonl/test_format.rb +22 -0
  53. data/test/jsonl/test_reader.rb +49 -0
  54. data/test/jsonl/test_record.rb +61 -0
  55. data/test/jsonl/test_writer.rb +68 -0
  56. data/test/output/test_file.rb +60 -0
  57. data/test/output/test_io.rb +104 -0
  58. data/test/test_conversions.rb +45 -0
  59. data/test/test_format.rb +24 -0
  60. data/test/test_helper.rb +26 -0
  61. data/test/test_merge.rb +40 -0
  62. data/test/test_merge_tree.rb +64 -0
  63. data/test/test_version.rb +11 -0
  64. data/test/xsv/test_format.rb +22 -0
  65. data/test/xsv/test_reader.rb +61 -0
  66. data/test/xsv/test_record.rb +69 -0
  67. data/test/xsv/test_writer.rb +68 -0
  68. metadata +237 -0
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class TestMerge < ::Minitest::Test
4
+
5
+ def test_can_use_use_dash_as_output
6
+ merge = ::FlatKit::Merge.new(inputs: [], input_fallback: "json",
7
+ output: "-", output_fallback: "json", compare_fields: [])
8
+ assert_match(/STDOUT/, merge.writer.output.name)
9
+ assert_instance_of(::FlatKit::Output::IO, merge.writer.output)
10
+ end
11
+
12
+ def test_can_use_a_text_path_as_output
13
+ test_path = "tmp/test_can_use_a_text_path_as_output.json"
14
+ begin
15
+ merge = ::FlatKit::Merge.new(output: test_path, inputs: [], input_fallback: "json", compare_fields: [])
16
+ assert_equal(test_path, merge.writer.output.name)
17
+ assert_instance_of(::FlatKit::Output::File, merge.writer.output)
18
+ merge.writer.close
19
+ ensure
20
+ File.unlink(test_path) if File.exist?(test_path)
21
+ end
22
+ end
23
+
24
+ def test_can_use_a_pathname_as_output
25
+ test_path = Pathname.new("tmp/test_can_use_a_pathname_as_output.json")
26
+ begin
27
+ merge = ::FlatKit::Merge.new(output: test_path, inputs: [], input_fallback: "json", compare_fields: [])
28
+ assert_equal(test_path.to_s, merge.writer.output.name)
29
+ assert_instance_of(::FlatKit::Output::File, merge.writer.output)
30
+ merge.writer.close
31
+ ensure
32
+ test_path.unlink if test_path.exist?
33
+ end
34
+ end
35
+
36
+ def test_raises_error_if_unable_to_parse_output
37
+ test_path = Object.new
38
+ assert_raises(FlatKit::Error) { ::FlatKit::Merge.new(output: test_path, inputs: [], compare_fields: []) }
39
+ end
40
+ end
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+
3
+ class TestMergeTree < ::Minitest::Test
4
+ def setup
5
+ @dataset_count = 20
6
+ @records_per_dataset = 100
7
+ @records = []
8
+ @datasets = Array.new.tap do |a|
9
+ @dataset_count.times do
10
+ dd = DeviceDataset.new(count: @records_per_dataset)
11
+ dd.persist_sorted_records_as_jsonl
12
+ @records.concat(dd.records)
13
+ a << dd
14
+ end
15
+ end
16
+ @compare_fields = @datasets.first.compare_fields
17
+ @readers = @datasets.map { |dd|
18
+ ::FlatKit::Jsonl::Reader.new(source: dd.filename_sorted_jsonl, compare_fields: @compare_fields)
19
+ }
20
+ end
21
+
22
+ def teardown
23
+ @datasets.each do |ds|
24
+ ds.cleanup_files
25
+ end
26
+ end
27
+
28
+ def test_init_tree
29
+ tree = ::FlatKit::MergeTree.new(@readers)
30
+ assert_equal(20, tree.leaves.size)
31
+
32
+ assert_equal(5, tree.depth)
33
+
34
+ # 0th level should have 10 nodes - since 20 leaves
35
+ assert_equal(10, tree.levels[0].size)
36
+
37
+ # 1st level should have 5 nodes - since 10 nodes lower
38
+ assert_equal(5, tree.levels[1].size)
39
+
40
+ # 2nd level should have 3 nodes - since 5 above (and we shim in a Sentinel
41
+ # node on the last internal node)
42
+ assert_equal(3, tree.levels[2].size)
43
+ assert_instance_of(::FlatKit::SentinelInternalNode, tree.levels[2].last.right)
44
+
45
+ # 3rd level should have 2 nodes
46
+ assert_equal(2, tree.levels[3].size)
47
+
48
+ # 4th level should have 1 nodes
49
+ assert_equal(1, tree.levels[4].size)
50
+ end
51
+
52
+ def test_merging
53
+ expected_records = @records.sort_by { |r| @compare_fields.map { |f| r[f] } }
54
+ tree = ::FlatKit::MergeTree.new(@readers)
55
+ actual_records = tree.to_a.map { |r| r.to_hash }
56
+
57
+ assert_equal(expected_records.size, actual_records.size)
58
+
59
+ expected_records.each_with_index do |expected, idx|
60
+ actual = actual_records[idx]
61
+ assert_equal(expected, actual)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class TestVersion < ::Minitest::Test
4
+ def test_version_constant_match
5
+ assert_match(/\A\d+\.\d+\.\d+\Z/, FlatKit::VERSION)
6
+ end
7
+
8
+ def test_version_string_match
9
+ assert_match(/\A\d+\.\d+\.\d+\Z/, FlatKit::VERSION.to_s)
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../test_helper'
2
+
3
+ module TestXsv
4
+ class TestFormat < ::Minitest::Test
5
+
6
+ def test_handles_csv
7
+ assert(::FlatKit::Xsv::Format.handles?("csv"))
8
+ end
9
+
10
+ def test_handles_tsv
11
+ assert(::FlatKit::Xsv::Format.handles?("tsv"))
12
+ end
13
+
14
+ def test_handles_txt
15
+ assert(::FlatKit::Xsv::Format.handles?("txt"))
16
+ end
17
+
18
+ def test_does_not_handle_json
19
+ refute(::FlatKit::Xsv::Format.handles?("json"))
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../test_helper'
2
+
3
+ module TestXsv
4
+ class TestReader < ::Minitest::Test
5
+ def setup
6
+ @count = 20
7
+ @dataset = DeviceDataset.new(count: @count)
8
+ @compare_fields = @dataset.compare_fields
9
+ @test_path = "tmp/test_reads_from_io.csv"
10
+
11
+ File.open(@test_path, "wb") do |f|
12
+ f.write(@dataset.records_as_csv)
13
+ end
14
+ end
15
+
16
+ def teardown
17
+ File.unlink(@test_path) if File.exist?(@test_path)
18
+ end
19
+
20
+ def test_fields
21
+ reader = ::FlatKit::Xsv::Reader.new(source: @test_path, compare_fields: @compare_fields)
22
+ reader.to_a
23
+ assert_equal(@dataset.fields, reader.fields)
24
+ end
25
+
26
+ def test_raises_error_on_invalid_source
27
+ assert_raises(::FlatKit::Error) {
28
+ ::FlatKit::Xsv::Reader.new(source: Object.new, compare_fields: nil)
29
+ }
30
+ end
31
+
32
+ def test_automatically_figures_out_fields_if_needed
33
+ reader = ::FlatKit::Xsv::Reader.new(source: @test_path)
34
+ reader.take(1)
35
+ assert_equal(@dataset.fields, reader.fields)
36
+ end
37
+
38
+ def test_reads_from_pathname
39
+ reader = ::FlatKit::Xsv::Reader.new(source: @test_path, compare_fields: @compare_fields)
40
+ all = reader.to_a
41
+ assert_equal(@count, reader.count)
42
+ assert_equal(@count, all.size)
43
+ end
44
+
45
+ def test_reads_from_io
46
+ File.open(@test_path) do |f|
47
+ reader = ::FlatKit::Xsv::Reader.new(source: f, compare_fields: @compare_fields)
48
+ all = reader.to_a
49
+ assert_equal(@count, reader.count)
50
+ assert_equal(@count, all.size)
51
+ end
52
+ end
53
+
54
+ def test_raises_error_on_io_error
55
+ s = StringIO.new
56
+ s.close_read
57
+ reader = ::FlatKit::Xsv::Reader.new(source: s, compare_fields: @compare_fields)
58
+ assert_raises(::FlatKit::Error) { reader.to_a }
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,69 @@
1
+ require 'test_helper'
2
+ require 'faker'
3
+ require 'byebug'
4
+
5
+ module TestXsv
6
+ class TestRecord< ::Minitest::Test
7
+ def setup
8
+ @one_row_dataset = DeviceDataset.new(count: 1)
9
+ @csv_row = @one_row_dataset.records_as_csv_rows.first
10
+ @compare_fields = @one_row_dataset.compare_fields
11
+ end
12
+
13
+ def test_initializes_from_data
14
+ record = FlatKit::Xsv::Record.new(data: @csv_row, compare_fields: @compare_fields)
15
+ original_record = @one_row_dataset.records.first
16
+ @compare_fields.each do |field|
17
+ assert_equal(original_record[field], record[field])
18
+ end
19
+ end
20
+
21
+ def test_ignores_non_compare_fields_values
22
+ record = FlatKit::Xsv::Record.new(data: @csv_row, compare_fields: @compare_fields)
23
+ refute(record["version"])
24
+ end
25
+
26
+ def test_is_sortable
27
+ dataset = DeviceDataset.new(count: 20)
28
+ fk_records = Array.new.tap do |a|
29
+ dataset.records_as_csv_rows.each do |csv_row|
30
+ a << FlatKit::Xsv::Record.new(data: csv_row, compare_fields: @compare_fields)
31
+ end
32
+ end
33
+
34
+ sorted = fk_records.sort
35
+ output_text = CSV.generate('', headers: dataset.fields, write_headers: true) do |csv|
36
+ sorted.each do |row|
37
+ csv << row.data
38
+ end
39
+ end
40
+
41
+ assert_equal(output_text, dataset.sorted_records_as_csv)
42
+ end
43
+
44
+ def test_to_hash
45
+ record = FlatKit::Xsv::Record.new(data: @csv_row, compare_fields: @compare_fields)
46
+ h = record.to_hash
47
+ assert_equal(@one_row_dataset.records.first, h)
48
+ end
49
+
50
+ def test_from_record
51
+ rec1 = FlatKit::Xsv::Record.new(data: @csv_row, compare_fields: @compare_fields)
52
+ rec2 = FlatKit::Xsv::Record.from_record(rec1)
53
+ assert_equal(rec1, rec2)
54
+ end
55
+
56
+ def test_incomplete_initialization
57
+ assert_raises(FlatKit::Error) {
58
+ FlatKit::Xsv::Record.new(data: nil, compare_fields: [])
59
+ }
60
+ end
61
+
62
+ def test_to_s_from_csv_record
63
+ record = FlatKit::Xsv::Record.new(data: @csv_row, compare_fields: @compare_fields)
64
+ line = record.to_s
65
+ expected = @one_row_dataset.records_as_csv_rows[0].to_csv
66
+ assert_equal(expected, line)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,68 @@
1
+ require_relative '../test_helper'
2
+
3
+ module TestXsv
4
+ class TestWriter < ::Minitest::Test
5
+ def setup
6
+ @count = 20
7
+ @dataset = DeviceDataset.new(count: @count)
8
+ @compare_fields = @dataset.compare_fields
9
+ @write_path = "tmp/test_writes_to_io.csv"
10
+ @read_path = "tmp/test_read.csv"
11
+
12
+ File.open(@read_path, "wb") do |f|
13
+ f.write(@dataset.records_as_csv)
14
+ end
15
+
16
+ @reader = ::FlatKit::Xsv::Reader.new(source: @read_path, compare_fields: @compare_fields)
17
+ @records = @reader.to_a
18
+ end
19
+
20
+ def teardown
21
+ File.unlink(@write_path) if File.exist?(@write_path)
22
+ File.unlink(@read_path) if File.exist?(@read_path)
23
+ end
24
+
25
+ def test_raises_error_on_invalid_destination
26
+ assert_raises(::FlatKit::Error) {
27
+ ::FlatKit::Xsv::Writer.new(destination: Object.new, fields: @reader.fields)
28
+ }
29
+ end
30
+
31
+ def test_writes_to_pathname
32
+ writer = ::FlatKit::Xsv::Writer.new(destination: @write_path, fields: @reader.fields)
33
+ @records.each do |r|
34
+ writer.write(r)
35
+ end
36
+ writer.close
37
+ assert_equal(@count, writer.count)
38
+
39
+ expected = @dataset.records_as_csv
40
+ actual = IO.read(@write_path)
41
+ assert_equal(expected, actual)
42
+ end
43
+
44
+ def test_writes_to_io
45
+ File.open(@write_path, "w+") do |f|
46
+ writer = ::FlatKit::Xsv::Writer.new(destination: f,fields: @reader.fields)
47
+
48
+ @records.each do |r|
49
+ writer.write(r)
50
+ end
51
+ writer.close
52
+
53
+ assert_equal(@count, writer.count)
54
+
55
+ expected = @dataset.records_as_csv
56
+ actual = IO.read(@write_path)
57
+ assert_equal(expected, actual)
58
+ end
59
+ end
60
+
61
+ def test_raises_error_on_io_error
62
+ s = StringIO.new
63
+ writer = ::FlatKit::Xsv::Writer.new(destination: s, fields: @reader.fields)
64
+ s.close_write
65
+ assert_raises(::FlatKit::Error) { writer.write(@records.first) }
66
+ end
67
+ end
68
+ end
metadata ADDED
@@ -0,0 +1,237 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flat_kit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Hinegardner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oj
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: optimist
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-focus
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rdoc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '6.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '6.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.21'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.21'
111
+ description: A library and commandline program for reading, writing, indexing, sorting,
112
+ and merging CSV, TSV, JSON and other flat-file formats.
113
+ email: jeremy@copiousfreetime.org
114
+ executables:
115
+ - fk
116
+ extensions: []
117
+ extra_rdoc_files:
118
+ - CONTRIBUTING.md
119
+ - HISTORY.md
120
+ - LICENSE.txt
121
+ - Manifest.txt
122
+ - README.md
123
+ files:
124
+ - CONTRIBUTING.md
125
+ - HISTORY.md
126
+ - LICENSE.txt
127
+ - Manifest.txt
128
+ - README.md
129
+ - Rakefile
130
+ - bin/fk
131
+ - lib/flat_kit.rb
132
+ - lib/flat_kit/cli.rb
133
+ - lib/flat_kit/command.rb
134
+ - lib/flat_kit/command/cat.rb
135
+ - lib/flat_kit/command/merge.rb
136
+ - lib/flat_kit/command/sort.rb
137
+ - lib/flat_kit/descendant_tracker.rb
138
+ - lib/flat_kit/error.rb
139
+ - lib/flat_kit/format.rb
140
+ - lib/flat_kit/input.rb
141
+ - lib/flat_kit/input/file.rb
142
+ - lib/flat_kit/input/io.rb
143
+ - lib/flat_kit/internal_node.rb
144
+ - lib/flat_kit/jsonl.rb
145
+ - lib/flat_kit/jsonl/format.rb
146
+ - lib/flat_kit/jsonl/reader.rb
147
+ - lib/flat_kit/jsonl/record.rb
148
+ - lib/flat_kit/jsonl/writer.rb
149
+ - lib/flat_kit/leaf_node.rb
150
+ - lib/flat_kit/logger.rb
151
+ - lib/flat_kit/merge.rb
152
+ - lib/flat_kit/merge_tree.rb
153
+ - lib/flat_kit/output.rb
154
+ - lib/flat_kit/output/file.rb
155
+ - lib/flat_kit/output/io.rb
156
+ - lib/flat_kit/reader.rb
157
+ - lib/flat_kit/record.rb
158
+ - lib/flat_kit/sentinel_internal_node.rb
159
+ - lib/flat_kit/sentinel_leaf_node.rb
160
+ - lib/flat_kit/sort.rb
161
+ - lib/flat_kit/writer.rb
162
+ - lib/flat_kit/xsv.rb
163
+ - lib/flat_kit/xsv/format.rb
164
+ - lib/flat_kit/xsv/reader.rb
165
+ - lib/flat_kit/xsv/record.rb
166
+ - lib/flat_kit/xsv/writer.rb
167
+ - tasks/default.rake
168
+ - tasks/extension.rake
169
+ - tasks/man.rake
170
+ - tasks/this.rb
171
+ - test/device_dataset.rb
172
+ - test/input/test_file.rb
173
+ - test/input/test_io.rb
174
+ - test/jsonl/test_format.rb
175
+ - test/jsonl/test_reader.rb
176
+ - test/jsonl/test_record.rb
177
+ - test/jsonl/test_writer.rb
178
+ - test/output/test_file.rb
179
+ - test/output/test_io.rb
180
+ - test/test_conversions.rb
181
+ - test/test_format.rb
182
+ - test/test_helper.rb
183
+ - test/test_merge.rb
184
+ - test/test_merge_tree.rb
185
+ - test/test_version.rb
186
+ - test/xsv/test_format.rb
187
+ - test/xsv/test_reader.rb
188
+ - test/xsv/test_record.rb
189
+ - test/xsv/test_writer.rb
190
+ homepage: http://github.com/copiousfreetime/flat_kit
191
+ licenses:
192
+ - MIT
193
+ metadata: {}
194
+ post_install_message:
195
+ rdoc_options:
196
+ - "--main"
197
+ - README.md
198
+ - "--markup"
199
+ - tomdoc
200
+ require_paths:
201
+ - lib
202
+ required_ruby_version: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: 2.2.2
207
+ required_rubygems_version: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ version: '0'
212
+ requirements: []
213
+ rubygems_version: 3.1.2
214
+ signing_key:
215
+ specification_version: 4
216
+ summary: A library and commandline program for reading, writing, indexing, sorting,
217
+ and merging CSV, TSV, JSON and other flat-file formats.
218
+ test_files:
219
+ - test/device_dataset.rb
220
+ - test/input/test_file.rb
221
+ - test/input/test_io.rb
222
+ - test/jsonl/test_format.rb
223
+ - test/jsonl/test_reader.rb
224
+ - test/jsonl/test_record.rb
225
+ - test/jsonl/test_writer.rb
226
+ - test/output/test_file.rb
227
+ - test/output/test_io.rb
228
+ - test/test_conversions.rb
229
+ - test/test_format.rb
230
+ - test/test_helper.rb
231
+ - test/test_merge.rb
232
+ - test/test_merge_tree.rb
233
+ - test/test_version.rb
234
+ - test/xsv/test_format.rb
235
+ - test/xsv/test_reader.rb
236
+ - test/xsv/test_record.rb
237
+ - test/xsv/test_writer.rb