csvops 0.3.0.alpha → 0.4.0.alpha
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 +56 -142
- data/docs/architecture.md +266 -0
- data/docs/release-v0.4.0-alpha.md +87 -0
- data/lib/csvtool/application/use_cases/run_cross_csv_dedupe.rb +93 -0
- data/lib/csvtool/application/use_cases/run_extraction.rb +3 -3
- data/lib/csvtool/application/use_cases/run_row_extraction.rb +3 -3
- data/lib/csvtool/application/use_cases/run_row_randomization.rb +3 -3
- data/lib/csvtool/cli.rb +5 -1
- data/lib/csvtool/domain/cross_csv_dedupe_session/column_selector.rb +44 -0
- data/lib/csvtool/domain/cross_csv_dedupe_session/cross_csv_dedupe_session.rb +46 -0
- data/lib/csvtool/domain/cross_csv_dedupe_session/csv_profile.rb +24 -0
- data/lib/csvtool/domain/cross_csv_dedupe_session/key_mapping.rb +22 -0
- data/lib/csvtool/domain/cross_csv_dedupe_session/match_options.rb +29 -0
- data/lib/csvtool/domain/row_randomization_session/randomization_source.rb +1 -0
- data/lib/csvtool/domain/row_session/row_source.rb +3 -0
- data/lib/csvtool/domain/{column_session → shared}/output_destination.rb +1 -1
- data/lib/csvtool/infrastructure/csv/cross_csv_deduper.rb +85 -0
- data/lib/csvtool/infrastructure/csv/selector_validator.rb +30 -0
- data/lib/csvtool/interface/cli/menu_loop.rb +5 -2
- data/lib/csvtool/interface/cli/workflows/run_cross_csv_dedupe_workflow.rb +163 -0
- data/lib/csvtool/version.rb +1 -1
- data/test/csvtool/application/use_cases/run_cross_csv_dedupe_test.rb +113 -0
- data/test/csvtool/cli_test.rb +130 -16
- data/test/csvtool/cli_unit_test.rb +16 -3
- data/test/csvtool/domain/column_session/column_session_test.rb +2 -2
- data/test/csvtool/domain/column_session/csv_source_test.rb +10 -0
- data/test/csvtool/domain/cross_csv_dedupe_session/column_selector_test.rb +42 -0
- data/test/csvtool/domain/cross_csv_dedupe_session/cross_csv_dedupe_session_test.rb +75 -0
- data/test/csvtool/domain/cross_csv_dedupe_session/csv_profile_test.rb +26 -0
- data/test/csvtool/domain/cross_csv_dedupe_session/key_mapping_test.rb +31 -0
- data/test/csvtool/domain/cross_csv_dedupe_session/match_options_test.rb +52 -0
- data/test/csvtool/domain/row_randomization_session/randomization_session_test.rb +2 -2
- data/test/csvtool/domain/row_randomization_session/randomization_source_test.rb +15 -1
- data/test/csvtool/domain/row_session/row_session_test.rb +2 -2
- data/test/csvtool/domain/row_session/row_source_test.rb +16 -0
- data/test/csvtool/domain/shared/output_destination_test.rb +24 -0
- data/test/csvtool/infrastructure/csv/cross_csv_deduper_test.rb +155 -0
- data/test/csvtool/infrastructure/csv/selector_validator_test.rb +72 -0
- data/test/csvtool/interface/cli/menu_loop_test.rb +50 -13
- data/test/csvtool/interface/cli/workflows/run_cross_csv_dedupe_workflow_test.rb +246 -0
- data/test/fixtures/dedupe_reference.csv +3 -0
- data/test/fixtures/dedupe_reference.tsv +3 -0
- data/test/fixtures/dedupe_reference_all.csv +5 -0
- data/test/fixtures/dedupe_reference_no_headers.csv +2 -0
- data/test/fixtures/dedupe_reference_none.csv +2 -0
- data/test/fixtures/dedupe_reference_normalization.csv +3 -0
- data/test/fixtures/dedupe_source.csv +6 -0
- data/test/fixtures/dedupe_source.tsv +6 -0
- data/test/fixtures/dedupe_source_no_headers.csv +5 -0
- data/test/fixtures/dedupe_source_normalization.csv +4 -0
- metadata +34 -8
- data/lib/csvtool/domain/row_randomization_session/randomization_output_destination.rb +0 -31
- data/lib/csvtool/domain/row_session/row_output_destination.rb +0 -31
- data/test/csvtool/domain/column_session/output_destination_test.rb +0 -18
- data/test/csvtool/domain/row_randomization_session/randomization_output_destination_test.rb +0 -21
- data/test/csvtool/domain/row_session/row_output_destination_test.rb +0 -23
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/workflows/run_cross_csv_dedupe_workflow"
|
|
5
|
+
require "tmpdir"
|
|
6
|
+
|
|
7
|
+
class RunCrossCsvDedupeWorkflowTest < Minitest::Test
|
|
8
|
+
def fixture_path(name)
|
|
9
|
+
File.expand_path("../../../../fixtures/#{name}", __dir__)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_dedupes_source_rows_by_reference_column
|
|
13
|
+
output = StringIO.new
|
|
14
|
+
input = [
|
|
15
|
+
fixture_path("dedupe_source.csv"),
|
|
16
|
+
"",
|
|
17
|
+
"",
|
|
18
|
+
fixture_path("dedupe_reference.csv"),
|
|
19
|
+
"",
|
|
20
|
+
"",
|
|
21
|
+
"customer_id",
|
|
22
|
+
"external_id",
|
|
23
|
+
"",
|
|
24
|
+
"",
|
|
25
|
+
""
|
|
26
|
+
].join("\n") + "\n"
|
|
27
|
+
|
|
28
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
29
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
30
|
+
.call
|
|
31
|
+
|
|
32
|
+
assert_includes output.string, "CSV file path:"
|
|
33
|
+
assert_includes output.string, "Reference CSV file path:"
|
|
34
|
+
assert_includes output.string, "Source key column name:"
|
|
35
|
+
assert_includes output.string, "Reference key column name:"
|
|
36
|
+
assert_includes output.string, "customer_id,name"
|
|
37
|
+
assert_includes output.string, "1,Alice"
|
|
38
|
+
assert_includes output.string, "3,Cara"
|
|
39
|
+
refute_includes output.string, "2,Bob"
|
|
40
|
+
refute_includes output.string, "4,Dan"
|
|
41
|
+
assert_includes output.string, "Summary: source_rows=5 removed_rows=3 kept_rows=2"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_can_write_deduped_rows_to_file
|
|
45
|
+
output = StringIO.new
|
|
46
|
+
|
|
47
|
+
Dir.mktmpdir do |dir|
|
|
48
|
+
output_path = File.join(dir, "deduped.csv")
|
|
49
|
+
input = [
|
|
50
|
+
fixture_path("dedupe_source.csv"),
|
|
51
|
+
"",
|
|
52
|
+
"",
|
|
53
|
+
fixture_path("dedupe_reference.csv"),
|
|
54
|
+
"",
|
|
55
|
+
"",
|
|
56
|
+
"customer_id",
|
|
57
|
+
"external_id",
|
|
58
|
+
"",
|
|
59
|
+
"",
|
|
60
|
+
"2",
|
|
61
|
+
output_path
|
|
62
|
+
].join("\n") + "\n"
|
|
63
|
+
|
|
64
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
65
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
66
|
+
.call
|
|
67
|
+
|
|
68
|
+
assert_includes output.string, "Wrote output to #{output_path}"
|
|
69
|
+
assert_equal "customer_id,name\n1,Alice\n3,Cara\n", File.read(output_path)
|
|
70
|
+
assert_includes output.string, "Summary: source_rows=5 removed_rows=3 kept_rows=2"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_supports_tsv_separators
|
|
75
|
+
output = StringIO.new
|
|
76
|
+
input = [
|
|
77
|
+
fixture_path("dedupe_source.tsv"),
|
|
78
|
+
"2",
|
|
79
|
+
"",
|
|
80
|
+
fixture_path("dedupe_reference.tsv"),
|
|
81
|
+
"2",
|
|
82
|
+
"",
|
|
83
|
+
"customer_id",
|
|
84
|
+
"external_id",
|
|
85
|
+
"",
|
|
86
|
+
"",
|
|
87
|
+
""
|
|
88
|
+
].join("\n") + "\n"
|
|
89
|
+
|
|
90
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
91
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
92
|
+
.call
|
|
93
|
+
|
|
94
|
+
assert_includes output.string, "customer_id\tname"
|
|
95
|
+
assert_includes output.string, "1\tAlice"
|
|
96
|
+
assert_includes output.string, "3\tCara"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_headerless_mode_supports_column_index
|
|
100
|
+
output = StringIO.new
|
|
101
|
+
input = [
|
|
102
|
+
fixture_path("dedupe_source_no_headers.csv"),
|
|
103
|
+
"",
|
|
104
|
+
"n",
|
|
105
|
+
fixture_path("dedupe_reference_no_headers.csv"),
|
|
106
|
+
"",
|
|
107
|
+
"n",
|
|
108
|
+
"1",
|
|
109
|
+
"1",
|
|
110
|
+
"",
|
|
111
|
+
"",
|
|
112
|
+
""
|
|
113
|
+
].join("\n") + "\n"
|
|
114
|
+
|
|
115
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
116
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
117
|
+
.call
|
|
118
|
+
|
|
119
|
+
refute_includes output.string, "customer_id,name"
|
|
120
|
+
assert_includes output.string, "1,Alice"
|
|
121
|
+
assert_includes output.string, "3,Cara"
|
|
122
|
+
assert_includes output.string, "Summary: source_rows=5 removed_rows=3 kept_rows=2"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_reports_column_not_found_when_missing
|
|
126
|
+
output = StringIO.new
|
|
127
|
+
input = [
|
|
128
|
+
fixture_path("dedupe_source.csv"),
|
|
129
|
+
"",
|
|
130
|
+
"",
|
|
131
|
+
fixture_path("dedupe_reference.csv"),
|
|
132
|
+
"",
|
|
133
|
+
"",
|
|
134
|
+
"missing",
|
|
135
|
+
"external_id",
|
|
136
|
+
"",
|
|
137
|
+
""
|
|
138
|
+
].join("\n") + "\n"
|
|
139
|
+
|
|
140
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
141
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
142
|
+
.call
|
|
143
|
+
|
|
144
|
+
assert_includes output.string, "Column not found."
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_reports_when_no_rows_were_removed
|
|
148
|
+
output = StringIO.new
|
|
149
|
+
input = [
|
|
150
|
+
fixture_path("dedupe_source.csv"),
|
|
151
|
+
"",
|
|
152
|
+
"",
|
|
153
|
+
fixture_path("dedupe_reference_none.csv"),
|
|
154
|
+
"",
|
|
155
|
+
"",
|
|
156
|
+
"customer_id",
|
|
157
|
+
"external_id",
|
|
158
|
+
"",
|
|
159
|
+
"",
|
|
160
|
+
""
|
|
161
|
+
].join("\n") + "\n"
|
|
162
|
+
|
|
163
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
164
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
165
|
+
.call
|
|
166
|
+
|
|
167
|
+
assert_includes output.string, "Summary: source_rows=5 removed_rows=0 kept_rows=5"
|
|
168
|
+
assert_includes output.string, "No rows removed; no matching keys found."
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_reports_when_all_rows_were_removed
|
|
172
|
+
output = StringIO.new
|
|
173
|
+
input = [
|
|
174
|
+
fixture_path("dedupe_source.csv"),
|
|
175
|
+
"",
|
|
176
|
+
"",
|
|
177
|
+
fixture_path("dedupe_reference_all.csv"),
|
|
178
|
+
"",
|
|
179
|
+
"",
|
|
180
|
+
"customer_id",
|
|
181
|
+
"external_id",
|
|
182
|
+
"",
|
|
183
|
+
"",
|
|
184
|
+
""
|
|
185
|
+
].join("\n") + "\n"
|
|
186
|
+
|
|
187
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
188
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
189
|
+
.call
|
|
190
|
+
|
|
191
|
+
assert_includes output.string, "Summary: source_rows=5 removed_rows=5 kept_rows=0"
|
|
192
|
+
assert_includes output.string, "All source rows were removed by dedupe."
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def test_normalization_trim_on_and_case_insensitive_on_matches_equivalent_keys
|
|
196
|
+
output = StringIO.new
|
|
197
|
+
input = [
|
|
198
|
+
fixture_path("dedupe_source_normalization.csv"),
|
|
199
|
+
"",
|
|
200
|
+
"",
|
|
201
|
+
fixture_path("dedupe_reference_normalization.csv"),
|
|
202
|
+
"",
|
|
203
|
+
"",
|
|
204
|
+
"customer_id",
|
|
205
|
+
"external_id",
|
|
206
|
+
"",
|
|
207
|
+
"y",
|
|
208
|
+
""
|
|
209
|
+
].join("\n") + "\n"
|
|
210
|
+
|
|
211
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
212
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
213
|
+
.call
|
|
214
|
+
|
|
215
|
+
refute_includes output.string, " A1 ,Alice"
|
|
216
|
+
refute_includes output.string, "c3,Cara"
|
|
217
|
+
assert_includes output.string, "B2,Bob"
|
|
218
|
+
assert_includes output.string, "Summary: source_rows=3 removed_rows=2 kept_rows=1"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def test_normalization_disabled_preserves_exact_match_behavior
|
|
222
|
+
output = StringIO.new
|
|
223
|
+
input = [
|
|
224
|
+
fixture_path("dedupe_source_normalization.csv"),
|
|
225
|
+
"",
|
|
226
|
+
"",
|
|
227
|
+
fixture_path("dedupe_reference_normalization.csv"),
|
|
228
|
+
"",
|
|
229
|
+
"",
|
|
230
|
+
"customer_id",
|
|
231
|
+
"external_id",
|
|
232
|
+
"n",
|
|
233
|
+
"n",
|
|
234
|
+
""
|
|
235
|
+
].join("\n") + "\n"
|
|
236
|
+
|
|
237
|
+
Csvtool::Interface::CLI::Workflows::RunCrossCsvDedupeWorkflow
|
|
238
|
+
.new(stdin: StringIO.new(input), stdout: output)
|
|
239
|
+
.call
|
|
240
|
+
|
|
241
|
+
assert_includes output.string, " A1 ,Alice"
|
|
242
|
+
assert_includes output.string, "B2,Bob"
|
|
243
|
+
assert_includes output.string, "c3,Cara"
|
|
244
|
+
assert_includes output.string, "Summary: source_rows=3 removed_rows=0 kept_rows=3"
|
|
245
|
+
end
|
|
246
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: csvops
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0.alpha
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robert Hall
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-02-
|
|
11
|
+
date: 2026-02-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: csv
|
|
@@ -67,10 +67,13 @@ files:
|
|
|
67
67
|
- bin/csvtool
|
|
68
68
|
- bin/tool
|
|
69
69
|
- csvops.gemspec
|
|
70
|
+
- docs/architecture.md
|
|
70
71
|
- docs/release-v0.1.0-alpha.md
|
|
71
72
|
- docs/release-v0.2.0-alpha.md
|
|
72
73
|
- docs/release-v0.3.0-alpha.md
|
|
74
|
+
- docs/release-v0.4.0-alpha.md
|
|
73
75
|
- exe/csvtool
|
|
76
|
+
- lib/csvtool/application/use_cases/run_cross_csv_dedupe.rb
|
|
74
77
|
- lib/csvtool/application/use_cases/run_extraction.rb
|
|
75
78
|
- lib/csvtool/application/use_cases/run_row_extraction.rb
|
|
76
79
|
- lib/csvtool/application/use_cases/run_row_randomization.rb
|
|
@@ -80,20 +83,25 @@ files:
|
|
|
80
83
|
- lib/csvtool/domain/column_session/csv_source.rb
|
|
81
84
|
- lib/csvtool/domain/column_session/extraction_options.rb
|
|
82
85
|
- lib/csvtool/domain/column_session/extraction_value.rb
|
|
83
|
-
- lib/csvtool/domain/column_session/output_destination.rb
|
|
84
86
|
- lib/csvtool/domain/column_session/preview.rb
|
|
85
87
|
- lib/csvtool/domain/column_session/separator.rb
|
|
88
|
+
- lib/csvtool/domain/cross_csv_dedupe_session/column_selector.rb
|
|
89
|
+
- lib/csvtool/domain/cross_csv_dedupe_session/cross_csv_dedupe_session.rb
|
|
90
|
+
- lib/csvtool/domain/cross_csv_dedupe_session/csv_profile.rb
|
|
91
|
+
- lib/csvtool/domain/cross_csv_dedupe_session/key_mapping.rb
|
|
92
|
+
- lib/csvtool/domain/cross_csv_dedupe_session/match_options.rb
|
|
86
93
|
- lib/csvtool/domain/row_randomization_session/randomization_options.rb
|
|
87
|
-
- lib/csvtool/domain/row_randomization_session/randomization_output_destination.rb
|
|
88
94
|
- lib/csvtool/domain/row_randomization_session/randomization_session.rb
|
|
89
95
|
- lib/csvtool/domain/row_randomization_session/randomization_source.rb
|
|
90
|
-
- lib/csvtool/domain/row_session/row_output_destination.rb
|
|
91
96
|
- lib/csvtool/domain/row_session/row_range.rb
|
|
92
97
|
- lib/csvtool/domain/row_session/row_session.rb
|
|
93
98
|
- lib/csvtool/domain/row_session/row_source.rb
|
|
99
|
+
- lib/csvtool/domain/shared/output_destination.rb
|
|
100
|
+
- lib/csvtool/infrastructure/csv/cross_csv_deduper.rb
|
|
94
101
|
- lib/csvtool/infrastructure/csv/header_reader.rb
|
|
95
102
|
- lib/csvtool/infrastructure/csv/row_randomizer.rb
|
|
96
103
|
- lib/csvtool/infrastructure/csv/row_streamer.rb
|
|
104
|
+
- lib/csvtool/infrastructure/csv/selector_validator.rb
|
|
97
105
|
- lib/csvtool/infrastructure/csv/value_streamer.rb
|
|
98
106
|
- lib/csvtool/infrastructure/output/console_writer.rb
|
|
99
107
|
- lib/csvtool/infrastructure/output/csv_file_writer.rb
|
|
@@ -109,8 +117,10 @@ files:
|
|
|
109
117
|
- lib/csvtool/interface/cli/prompts/seed_prompt.rb
|
|
110
118
|
- lib/csvtool/interface/cli/prompts/separator_prompt.rb
|
|
111
119
|
- lib/csvtool/interface/cli/prompts/skip_blanks_prompt.rb
|
|
120
|
+
- lib/csvtool/interface/cli/workflows/run_cross_csv_dedupe_workflow.rb
|
|
112
121
|
- lib/csvtool/services/preview_builder.rb
|
|
113
122
|
- lib/csvtool/version.rb
|
|
123
|
+
- test/csvtool/application/use_cases/run_cross_csv_dedupe_test.rb
|
|
114
124
|
- test/csvtool/application/use_cases/run_extraction_test.rb
|
|
115
125
|
- test/csvtool/application/use_cases/run_row_extraction_test.rb
|
|
116
126
|
- test/csvtool/application/use_cases/run_row_randomization_test.rb
|
|
@@ -121,20 +131,25 @@ files:
|
|
|
121
131
|
- test/csvtool/domain/column_session/csv_source_test.rb
|
|
122
132
|
- test/csvtool/domain/column_session/extraction_options_test.rb
|
|
123
133
|
- test/csvtool/domain/column_session/extraction_value_test.rb
|
|
124
|
-
- test/csvtool/domain/column_session/output_destination_test.rb
|
|
125
134
|
- test/csvtool/domain/column_session/preview_test.rb
|
|
126
135
|
- test/csvtool/domain/column_session/separator_test.rb
|
|
136
|
+
- test/csvtool/domain/cross_csv_dedupe_session/column_selector_test.rb
|
|
137
|
+
- test/csvtool/domain/cross_csv_dedupe_session/cross_csv_dedupe_session_test.rb
|
|
138
|
+
- test/csvtool/domain/cross_csv_dedupe_session/csv_profile_test.rb
|
|
139
|
+
- test/csvtool/domain/cross_csv_dedupe_session/key_mapping_test.rb
|
|
140
|
+
- test/csvtool/domain/cross_csv_dedupe_session/match_options_test.rb
|
|
127
141
|
- test/csvtool/domain/row_randomization_session/randomization_options_test.rb
|
|
128
|
-
- test/csvtool/domain/row_randomization_session/randomization_output_destination_test.rb
|
|
129
142
|
- test/csvtool/domain/row_randomization_session/randomization_session_test.rb
|
|
130
143
|
- test/csvtool/domain/row_randomization_session/randomization_source_test.rb
|
|
131
|
-
- test/csvtool/domain/row_session/row_output_destination_test.rb
|
|
132
144
|
- test/csvtool/domain/row_session/row_range_test.rb
|
|
133
145
|
- test/csvtool/domain/row_session/row_session_test.rb
|
|
134
146
|
- test/csvtool/domain/row_session/row_source_test.rb
|
|
147
|
+
- test/csvtool/domain/shared/output_destination_test.rb
|
|
148
|
+
- test/csvtool/infrastructure/csv/cross_csv_deduper_test.rb
|
|
135
149
|
- test/csvtool/infrastructure/csv/header_reader_test.rb
|
|
136
150
|
- test/csvtool/infrastructure/csv/row_randomizer_test.rb
|
|
137
151
|
- test/csvtool/infrastructure/csv/row_streamer_test.rb
|
|
152
|
+
- test/csvtool/infrastructure/csv/selector_validator_test.rb
|
|
138
153
|
- test/csvtool/infrastructure/csv/value_streamer_test.rb
|
|
139
154
|
- test/csvtool/infrastructure/output/console_writer_test.rb
|
|
140
155
|
- test/csvtool/infrastructure/output/csv_file_writer_test.rb
|
|
@@ -150,7 +165,18 @@ files:
|
|
|
150
165
|
- test/csvtool/interface/cli/prompts/seed_prompt_test.rb
|
|
151
166
|
- test/csvtool/interface/cli/prompts/separator_prompt_test.rb
|
|
152
167
|
- test/csvtool/interface/cli/prompts/skip_blanks_prompt_test.rb
|
|
168
|
+
- test/csvtool/interface/cli/workflows/run_cross_csv_dedupe_workflow_test.rb
|
|
153
169
|
- test/csvtool/services/preview_builder_test.rb
|
|
170
|
+
- test/fixtures/dedupe_reference.csv
|
|
171
|
+
- test/fixtures/dedupe_reference.tsv
|
|
172
|
+
- test/fixtures/dedupe_reference_all.csv
|
|
173
|
+
- test/fixtures/dedupe_reference_no_headers.csv
|
|
174
|
+
- test/fixtures/dedupe_reference_none.csv
|
|
175
|
+
- test/fixtures/dedupe_reference_normalization.csv
|
|
176
|
+
- test/fixtures/dedupe_source.csv
|
|
177
|
+
- test/fixtures/dedupe_source.tsv
|
|
178
|
+
- test/fixtures/dedupe_source_no_headers.csv
|
|
179
|
+
- test/fixtures/dedupe_source_normalization.csv
|
|
154
180
|
- test/fixtures/empty.csv
|
|
155
181
|
- test/fixtures/sample_people.csv
|
|
156
182
|
- test/fixtures/sample_people.tsv
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Csvtool
|
|
4
|
-
module Domain
|
|
5
|
-
module RowRandomizationSession
|
|
6
|
-
class RandomizationOutputDestination
|
|
7
|
-
attr_reader :mode, :path
|
|
8
|
-
|
|
9
|
-
def self.console
|
|
10
|
-
new(mode: :console)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.file(path:)
|
|
14
|
-
new(mode: :file, path: path)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def initialize(mode:, path: nil)
|
|
18
|
-
raise ArgumentError, "invalid output mode" unless %i[console file].include?(mode)
|
|
19
|
-
raise ArgumentError, "file output path cannot be empty" if mode == :file && path.to_s.empty?
|
|
20
|
-
|
|
21
|
-
@mode = mode
|
|
22
|
-
@path = path
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def file?
|
|
26
|
-
@mode == :file
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Csvtool
|
|
4
|
-
module Domain
|
|
5
|
-
module RowSession
|
|
6
|
-
class RowOutputDestination
|
|
7
|
-
attr_reader :mode, :path
|
|
8
|
-
|
|
9
|
-
def self.console
|
|
10
|
-
new(mode: :console)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.file(path:)
|
|
14
|
-
new(mode: :file, path: path)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def initialize(mode:, path: nil)
|
|
18
|
-
raise ArgumentError, "invalid output mode" unless %i[console file].include?(mode)
|
|
19
|
-
raise ArgumentError, "file output path cannot be empty" if mode == :file && path.to_s.empty?
|
|
20
|
-
|
|
21
|
-
@mode = mode
|
|
22
|
-
@path = path
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def file?
|
|
26
|
-
@mode == :file
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../../test_helper"
|
|
4
|
-
require "csvtool/domain/column_session/output_destination"
|
|
5
|
-
|
|
6
|
-
class OutputDestinationTest < Minitest::Test
|
|
7
|
-
def test_console_factory
|
|
8
|
-
destination = Csvtool::Domain::ColumnSession::OutputDestination.console
|
|
9
|
-
assert_equal true, destination.console?
|
|
10
|
-
assert_equal false, destination.file?
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def test_file_factory
|
|
14
|
-
destination = Csvtool::Domain::ColumnSession::OutputDestination.file(path: "/tmp/out.csv")
|
|
15
|
-
assert_equal true, destination.file?
|
|
16
|
-
assert_equal "/tmp/out.csv", destination.path
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../../test_helper"
|
|
4
|
-
require "csvtool/domain/row_randomization_session/randomization_output_destination"
|
|
5
|
-
|
|
6
|
-
class RandomizationOutputDestinationTest < Minitest::Test
|
|
7
|
-
def test_console_and_file_modes
|
|
8
|
-
console = Csvtool::Domain::RowRandomizationSession::RandomizationOutputDestination.console
|
|
9
|
-
file = Csvtool::Domain::RowRandomizationSession::RandomizationOutputDestination.file(path: "/tmp/out.csv")
|
|
10
|
-
|
|
11
|
-
assert_equal false, console.file?
|
|
12
|
-
assert_equal true, file.file?
|
|
13
|
-
assert_equal "/tmp/out.csv", file.path
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def test_rejects_empty_file_path
|
|
17
|
-
assert_raises(ArgumentError) do
|
|
18
|
-
Csvtool::Domain::RowRandomizationSession::RandomizationOutputDestination.file(path: "")
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../../test_helper"
|
|
4
|
-
require "csvtool/domain/row_session/row_output_destination"
|
|
5
|
-
|
|
6
|
-
class RowRangeOutputDestinationTest < Minitest::Test
|
|
7
|
-
def test_console_destination
|
|
8
|
-
destination = Csvtool::Domain::RowSession::RowOutputDestination.console
|
|
9
|
-
refute destination.file?
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_file_destination
|
|
13
|
-
destination = Csvtool::Domain::RowSession::RowOutputDestination.file(path: "/tmp/out.csv")
|
|
14
|
-
assert destination.file?
|
|
15
|
-
assert_equal "/tmp/out.csv", destination.path
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def test_rejects_empty_file_path
|
|
19
|
-
assert_raises(ArgumentError) do
|
|
20
|
-
Csvtool::Domain::RowSession::RowOutputDestination.file(path: "")
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|