csvops 0.6.0.alpha → 0.8.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 +103 -24
- data/docs/architecture.md +121 -4
- data/docs/release-v0.7.0-alpha.md +87 -0
- data/docs/release-v0.8.0-alpha.md +88 -0
- data/lib/csvtool/application/use_cases/run_csv_split.rb +97 -0
- data/lib/csvtool/application/use_cases/run_csv_stats.rb +64 -0
- data/lib/csvtool/cli.rb +9 -1
- data/lib/csvtool/domain/csv_split_session/split_options.rb +27 -0
- data/lib/csvtool/domain/csv_split_session/split_session.rb +20 -0
- data/lib/csvtool/domain/csv_split_session/split_source.rb +17 -0
- data/lib/csvtool/domain/csv_stats_session/stats_options.rb +11 -0
- data/lib/csvtool/domain/csv_stats_session/stats_session.rb +25 -0
- data/lib/csvtool/domain/csv_stats_session/stats_source.rb +17 -0
- data/lib/csvtool/infrastructure/csv/csv_splitter.rb +64 -0
- data/lib/csvtool/infrastructure/csv/csv_stats_scanner.rb +67 -0
- data/lib/csvtool/infrastructure/output/csv_split_manifest_writer.rb +20 -0
- data/lib/csvtool/infrastructure/output/csv_stats_file_writer.rb +26 -0
- data/lib/csvtool/interface/cli/errors/presenter.rb +8 -0
- data/lib/csvtool/interface/cli/menu_loop.rb +8 -2
- data/lib/csvtool/interface/cli/prompts/chunk_size_prompt.rb +21 -0
- data/lib/csvtool/interface/cli/prompts/split_manifest_prompt.rb +30 -0
- data/lib/csvtool/interface/cli/prompts/split_output_prompt.rb +38 -0
- data/lib/csvtool/interface/cli/workflows/builders/csv_split_session_builder.rb +44 -0
- data/lib/csvtool/interface/cli/workflows/builders/csv_stats_session_builder.rb +28 -0
- data/lib/csvtool/interface/cli/workflows/presenters/csv_split_presenter.rb +26 -0
- data/lib/csvtool/interface/cli/workflows/presenters/csv_stats_presenter.rb +34 -0
- data/lib/csvtool/interface/cli/workflows/run_csv_split_workflow.rb +89 -0
- data/lib/csvtool/interface/cli/workflows/run_csv_stats_workflow.rb +77 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_split/build_session_step.rb +30 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_split/collect_inputs_step.rb +43 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_split/collect_manifest_step.rb +30 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_split/collect_output_step.rb +31 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_split/execute_step.rb +36 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_stats/build_session_step.rb +25 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_stats/collect_destination_step.rb +27 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_stats/collect_inputs_step.rb +31 -0
- data/lib/csvtool/interface/cli/workflows/steps/csv_stats/execute_step.rb +27 -0
- data/lib/csvtool/version.rb +1 -1
- data/test/csvtool/application/use_cases/run_csv_split_test.rb +124 -0
- data/test/csvtool/application/use_cases/run_csv_stats_test.rb +165 -0
- data/test/csvtool/cli_test.rb +139 -29
- data/test/csvtool/infrastructure/csv/csv_splitter_test.rb +68 -0
- data/test/csvtool/infrastructure/csv/csv_stats_scanner_test.rb +68 -0
- data/test/csvtool/infrastructure/output/csv_split_manifest_writer_test.rb +25 -0
- data/test/csvtool/infrastructure/output/csv_stats_file_writer_test.rb +38 -0
- data/test/csvtool/interface/cli/menu_loop_test.rb +104 -130
- data/test/csvtool/interface/cli/prompts/chunk_size_prompt_test.rb +17 -0
- data/test/csvtool/interface/cli/prompts/split_manifest_prompt_test.rb +42 -0
- data/test/csvtool/interface/cli/prompts/split_output_prompt_test.rb +22 -0
- data/test/csvtool/interface/cli/workflows/builders/csv_split_session_builder_test.rb +30 -0
- data/test/csvtool/interface/cli/workflows/builders/csv_stats_session_builder_test.rb +19 -0
- data/test/csvtool/interface/cli/workflows/presenters/csv_split_presenter_test.rb +26 -0
- data/test/csvtool/interface/cli/workflows/presenters/csv_stats_presenter_test.rb +37 -0
- data/test/csvtool/interface/cli/workflows/run_csv_split_workflow_test.rb +200 -0
- data/test/csvtool/interface/cli/workflows/run_csv_stats_workflow_test.rb +146 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_split/build_session_step_test.rb +40 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_split/collect_inputs_step_test.rb +64 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_split/collect_manifest_step_test.rb +30 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_split/collect_output_step_test.rb +32 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_split/execute_step_test.rb +83 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_stats/build_session_step_test.rb +36 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_stats/collect_destination_step_test.rb +49 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_stats/collect_inputs_step_test.rb +61 -0
- data/test/csvtool/interface/cli/workflows/steps/csv_stats/execute_step_test.rb +65 -0
- data/test/fixtures/split_people_25.csv +26 -0
- metadata +58 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../test_helper"
|
|
4
|
+
require "csvtool/infrastructure/output/csv_stats_file_writer"
|
|
5
|
+
require "tmpdir"
|
|
6
|
+
|
|
7
|
+
class InfrastructureCsvStatsFileWriterTest < Minitest::Test
|
|
8
|
+
def test_writes_stats_as_metric_value_csv
|
|
9
|
+
writer = Csvtool::Infrastructure::Output::CsvStatsFileWriter.new
|
|
10
|
+
|
|
11
|
+
Dir.mktmpdir do |dir|
|
|
12
|
+
path = File.join(dir, "stats.csv")
|
|
13
|
+
writer.call(
|
|
14
|
+
path: path,
|
|
15
|
+
data: {
|
|
16
|
+
row_count: 3,
|
|
17
|
+
column_count: 2,
|
|
18
|
+
headers: ["name", "city"],
|
|
19
|
+
column_stats: [
|
|
20
|
+
{ name: "name", non_blank_count: 3, blank_count: 0 },
|
|
21
|
+
{ name: "city", non_blank_count: 2, blank_count: 1 }
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
assert_equal [
|
|
27
|
+
"metric,value",
|
|
28
|
+
"row_count,3",
|
|
29
|
+
"column_count,2",
|
|
30
|
+
"headers,name|city",
|
|
31
|
+
"column.name.non_blank,3",
|
|
32
|
+
"column.name.blank,0",
|
|
33
|
+
"column.city.non_blank,2",
|
|
34
|
+
"column.city.blank,1"
|
|
35
|
+
], File.read(path).lines.map(&:strip)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -17,171 +17,145 @@ class MenuLoopTest < Minitest::Test
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def test_routes_extract_column_then_exit
|
|
20
|
-
|
|
21
|
-
rows_action = FakeAction.new
|
|
22
|
-
randomize_rows_action = FakeAction.new
|
|
23
|
-
dedupe_action = FakeAction.new
|
|
24
|
-
parity_action = FakeAction.new
|
|
25
|
-
stdout = StringIO.new
|
|
26
|
-
menu = Csvtool::Interface::CLI::MenuLoop.new(
|
|
27
|
-
stdin: StringIO.new("1\n6\n"),
|
|
28
|
-
stdout: stdout,
|
|
29
|
-
menu_options: ["Extract column", "Extract rows (range)", "Randomize rows", "Dedupe using another CSV", "Validate parity", "Exit"],
|
|
30
|
-
extract_column_action: column_action,
|
|
31
|
-
extract_rows_action: rows_action,
|
|
32
|
-
randomize_rows_action: randomize_rows_action,
|
|
33
|
-
dedupe_action: dedupe_action,
|
|
34
|
-
parity_action: parity_action
|
|
35
|
-
)
|
|
36
|
-
|
|
20
|
+
menu, actions, = build_menu("1\n8\n")
|
|
37
21
|
status = menu.run
|
|
38
22
|
|
|
39
23
|
assert_equal 0, status
|
|
40
|
-
assert_equal 1,
|
|
41
|
-
assert_equal 0,
|
|
42
|
-
assert_equal 0,
|
|
43
|
-
assert_equal 0,
|
|
44
|
-
assert_equal 0,
|
|
45
|
-
|
|
24
|
+
assert_equal 1, actions[:column].runs
|
|
25
|
+
assert_equal 0, actions[:rows].runs
|
|
26
|
+
assert_equal 0, actions[:randomize].runs
|
|
27
|
+
assert_equal 0, actions[:dedupe].runs
|
|
28
|
+
assert_equal 0, actions[:parity].runs
|
|
29
|
+
assert_equal 0, actions[:split].runs
|
|
30
|
+
assert_equal 0, actions[:stats].runs
|
|
46
31
|
end
|
|
47
32
|
|
|
48
33
|
def test_routes_extract_rows_then_exit
|
|
49
|
-
|
|
50
|
-
rows_action = FakeAction.new
|
|
51
|
-
randomize_rows_action = FakeAction.new
|
|
52
|
-
dedupe_action = FakeAction.new
|
|
53
|
-
parity_action = FakeAction.new
|
|
54
|
-
stdout = StringIO.new
|
|
55
|
-
menu = Csvtool::Interface::CLI::MenuLoop.new(
|
|
56
|
-
stdin: StringIO.new("2\n6\n"),
|
|
57
|
-
stdout: stdout,
|
|
58
|
-
menu_options: ["Extract column", "Extract rows (range)", "Randomize rows", "Dedupe using another CSV", "Validate parity", "Exit"],
|
|
59
|
-
extract_column_action: column_action,
|
|
60
|
-
extract_rows_action: rows_action,
|
|
61
|
-
randomize_rows_action: randomize_rows_action,
|
|
62
|
-
dedupe_action: dedupe_action,
|
|
63
|
-
parity_action: parity_action
|
|
64
|
-
)
|
|
65
|
-
|
|
34
|
+
menu, actions, = build_menu("2\n8\n")
|
|
66
35
|
status = menu.run
|
|
67
36
|
|
|
68
37
|
assert_equal 0, status
|
|
69
|
-
assert_equal 0,
|
|
70
|
-
assert_equal 1,
|
|
71
|
-
assert_equal 0,
|
|
72
|
-
assert_equal 0,
|
|
73
|
-
assert_equal 0,
|
|
38
|
+
assert_equal 0, actions[:column].runs
|
|
39
|
+
assert_equal 1, actions[:rows].runs
|
|
40
|
+
assert_equal 0, actions[:randomize].runs
|
|
41
|
+
assert_equal 0, actions[:dedupe].runs
|
|
42
|
+
assert_equal 0, actions[:parity].runs
|
|
43
|
+
assert_equal 0, actions[:split].runs
|
|
44
|
+
assert_equal 0, actions[:stats].runs
|
|
74
45
|
end
|
|
75
46
|
|
|
76
47
|
def test_routes_randomize_rows_then_exit
|
|
77
|
-
|
|
78
|
-
rows_action = FakeAction.new
|
|
79
|
-
randomize_rows_action = FakeAction.new
|
|
80
|
-
dedupe_action = FakeAction.new
|
|
81
|
-
parity_action = FakeAction.new
|
|
82
|
-
stdout = StringIO.new
|
|
83
|
-
menu = Csvtool::Interface::CLI::MenuLoop.new(
|
|
84
|
-
stdin: StringIO.new("3\n6\n"),
|
|
85
|
-
stdout: stdout,
|
|
86
|
-
menu_options: ["Extract column", "Extract rows (range)", "Randomize rows", "Dedupe using another CSV", "Validate parity", "Exit"],
|
|
87
|
-
extract_column_action: column_action,
|
|
88
|
-
extract_rows_action: rows_action,
|
|
89
|
-
randomize_rows_action: randomize_rows_action,
|
|
90
|
-
dedupe_action: dedupe_action,
|
|
91
|
-
parity_action: parity_action
|
|
92
|
-
)
|
|
93
|
-
|
|
48
|
+
menu, actions, = build_menu("3\n8\n")
|
|
94
49
|
status = menu.run
|
|
95
50
|
|
|
96
51
|
assert_equal 0, status
|
|
97
|
-
assert_equal 0,
|
|
98
|
-
assert_equal 0,
|
|
99
|
-
assert_equal 1,
|
|
100
|
-
assert_equal 0,
|
|
101
|
-
assert_equal 0,
|
|
52
|
+
assert_equal 0, actions[:column].runs
|
|
53
|
+
assert_equal 0, actions[:rows].runs
|
|
54
|
+
assert_equal 1, actions[:randomize].runs
|
|
55
|
+
assert_equal 0, actions[:dedupe].runs
|
|
56
|
+
assert_equal 0, actions[:parity].runs
|
|
57
|
+
assert_equal 0, actions[:split].runs
|
|
58
|
+
assert_equal 0, actions[:stats].runs
|
|
102
59
|
end
|
|
103
60
|
|
|
104
61
|
def test_routes_dedupe_then_exit
|
|
105
|
-
|
|
106
|
-
rows_action = FakeAction.new
|
|
107
|
-
randomize_rows_action = FakeAction.new
|
|
108
|
-
dedupe_action = FakeAction.new
|
|
109
|
-
parity_action = FakeAction.new
|
|
110
|
-
stdout = StringIO.new
|
|
111
|
-
menu = Csvtool::Interface::CLI::MenuLoop.new(
|
|
112
|
-
stdin: StringIO.new("4\n6\n"),
|
|
113
|
-
stdout: stdout,
|
|
114
|
-
menu_options: ["Extract column", "Extract rows (range)", "Randomize rows", "Dedupe using another CSV", "Validate parity", "Exit"],
|
|
115
|
-
extract_column_action: column_action,
|
|
116
|
-
extract_rows_action: rows_action,
|
|
117
|
-
randomize_rows_action: randomize_rows_action,
|
|
118
|
-
dedupe_action: dedupe_action,
|
|
119
|
-
parity_action: parity_action
|
|
120
|
-
)
|
|
121
|
-
|
|
62
|
+
menu, actions, = build_menu("4\n8\n")
|
|
122
63
|
status = menu.run
|
|
123
64
|
|
|
124
65
|
assert_equal 0, status
|
|
125
|
-
assert_equal 0,
|
|
126
|
-
assert_equal 0,
|
|
127
|
-
assert_equal 0,
|
|
128
|
-
assert_equal 1,
|
|
129
|
-
assert_equal 0,
|
|
66
|
+
assert_equal 0, actions[:column].runs
|
|
67
|
+
assert_equal 0, actions[:rows].runs
|
|
68
|
+
assert_equal 0, actions[:randomize].runs
|
|
69
|
+
assert_equal 1, actions[:dedupe].runs
|
|
70
|
+
assert_equal 0, actions[:parity].runs
|
|
71
|
+
assert_equal 0, actions[:split].runs
|
|
72
|
+
assert_equal 0, actions[:stats].runs
|
|
130
73
|
end
|
|
131
74
|
|
|
132
75
|
def test_routes_parity_then_exit
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
randomize_rows_action = FakeAction.new
|
|
136
|
-
dedupe_action = FakeAction.new
|
|
137
|
-
parity_action = FakeAction.new
|
|
138
|
-
stdout = StringIO.new
|
|
139
|
-
menu = Csvtool::Interface::CLI::MenuLoop.new(
|
|
140
|
-
stdin: StringIO.new("5\n6\n"),
|
|
141
|
-
stdout: stdout,
|
|
142
|
-
menu_options: ["Extract column", "Extract rows (range)", "Randomize rows", "Dedupe using another CSV", "Validate parity", "Exit"],
|
|
143
|
-
extract_column_action: column_action,
|
|
144
|
-
extract_rows_action: rows_action,
|
|
145
|
-
randomize_rows_action: randomize_rows_action,
|
|
146
|
-
dedupe_action: dedupe_action,
|
|
147
|
-
parity_action: parity_action
|
|
148
|
-
)
|
|
76
|
+
menu, actions, = build_menu("5\n8\n")
|
|
77
|
+
status = menu.run
|
|
149
78
|
|
|
79
|
+
assert_equal 0, status
|
|
80
|
+
assert_equal 0, actions[:column].runs
|
|
81
|
+
assert_equal 0, actions[:rows].runs
|
|
82
|
+
assert_equal 0, actions[:randomize].runs
|
|
83
|
+
assert_equal 0, actions[:dedupe].runs
|
|
84
|
+
assert_equal 1, actions[:parity].runs
|
|
85
|
+
assert_equal 0, actions[:split].runs
|
|
86
|
+
assert_equal 0, actions[:stats].runs
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_routes_split_then_exit
|
|
90
|
+
menu, actions, stdout = build_menu("6\n8\n")
|
|
150
91
|
status = menu.run
|
|
151
92
|
|
|
152
93
|
assert_equal 0, status
|
|
153
|
-
assert_equal 0,
|
|
154
|
-
assert_equal 0,
|
|
155
|
-
assert_equal 0,
|
|
156
|
-
assert_equal 0,
|
|
157
|
-
assert_equal
|
|
94
|
+
assert_equal 0, actions[:column].runs
|
|
95
|
+
assert_equal 0, actions[:rows].runs
|
|
96
|
+
assert_equal 0, actions[:randomize].runs
|
|
97
|
+
assert_equal 0, actions[:dedupe].runs
|
|
98
|
+
assert_equal 0, actions[:parity].runs
|
|
99
|
+
assert_equal 1, actions[:split].runs
|
|
100
|
+
assert_equal 0, actions[:stats].runs
|
|
101
|
+
assert_includes stdout.string, "CSV Tool Menu"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_routes_stats_then_exit
|
|
105
|
+
menu, actions, = build_menu("7\n8\n")
|
|
106
|
+
status = menu.run
|
|
107
|
+
|
|
108
|
+
assert_equal 0, status
|
|
109
|
+
assert_equal 0, actions[:column].runs
|
|
110
|
+
assert_equal 0, actions[:rows].runs
|
|
111
|
+
assert_equal 0, actions[:randomize].runs
|
|
112
|
+
assert_equal 0, actions[:dedupe].runs
|
|
113
|
+
assert_equal 0, actions[:parity].runs
|
|
114
|
+
assert_equal 0, actions[:split].runs
|
|
115
|
+
assert_equal 1, actions[:stats].runs
|
|
158
116
|
end
|
|
159
117
|
|
|
160
118
|
def test_invalid_choice_shows_prompt
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
119
|
+
menu, actions, stdout = build_menu("x\n8\n")
|
|
120
|
+
menu.run
|
|
121
|
+
|
|
122
|
+
assert_includes stdout.string, "Please choose 1, 2, 3, 4, 5, 6, 7, or 8."
|
|
123
|
+
assert_equal 0, actions[:column].runs
|
|
124
|
+
assert_equal 0, actions[:rows].runs
|
|
125
|
+
assert_equal 0, actions[:randomize].runs
|
|
126
|
+
assert_equal 0, actions[:dedupe].runs
|
|
127
|
+
assert_equal 0, actions[:parity].runs
|
|
128
|
+
assert_equal 0, actions[:split].runs
|
|
129
|
+
assert_equal 0, actions[:stats].runs
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
private
|
|
133
|
+
|
|
134
|
+
def build_menu(input)
|
|
135
|
+
actions = {
|
|
136
|
+
column: FakeAction.new,
|
|
137
|
+
rows: FakeAction.new,
|
|
138
|
+
randomize: FakeAction.new,
|
|
139
|
+
dedupe: FakeAction.new,
|
|
140
|
+
parity: FakeAction.new,
|
|
141
|
+
split: FakeAction.new,
|
|
142
|
+
stats: FakeAction.new
|
|
143
|
+
}
|
|
166
144
|
stdout = StringIO.new
|
|
145
|
+
|
|
167
146
|
menu = Csvtool::Interface::CLI::MenuLoop.new(
|
|
168
|
-
stdin: StringIO.new(
|
|
147
|
+
stdin: StringIO.new(input),
|
|
169
148
|
stdout: stdout,
|
|
170
|
-
menu_options: ["Extract column", "Extract rows (range)", "Randomize rows", "Dedupe using another CSV", "Validate parity", "Exit"],
|
|
171
|
-
extract_column_action:
|
|
172
|
-
extract_rows_action:
|
|
173
|
-
randomize_rows_action:
|
|
174
|
-
dedupe_action:
|
|
175
|
-
parity_action:
|
|
149
|
+
menu_options: ["Extract column", "Extract rows (range)", "Randomize rows", "Dedupe using another CSV", "Validate parity", "Split CSV into chunks", "CSV stats summary", "Exit"],
|
|
150
|
+
extract_column_action: actions[:column],
|
|
151
|
+
extract_rows_action: actions[:rows],
|
|
152
|
+
randomize_rows_action: actions[:randomize],
|
|
153
|
+
dedupe_action: actions[:dedupe],
|
|
154
|
+
parity_action: actions[:parity],
|
|
155
|
+
split_action: actions[:split],
|
|
156
|
+
stats_action: actions[:stats]
|
|
176
157
|
)
|
|
177
158
|
|
|
178
|
-
menu
|
|
179
|
-
|
|
180
|
-
assert_includes stdout.string, "Please choose 1, 2, 3, 4, 5, or 6."
|
|
181
|
-
assert_equal 0, column_action.runs
|
|
182
|
-
assert_equal 0, rows_action.runs
|
|
183
|
-
assert_equal 0, randomize_rows_action.runs
|
|
184
|
-
assert_equal 0, dedupe_action.runs
|
|
185
|
-
assert_equal 0, parity_action.runs
|
|
159
|
+
[menu, actions, stdout]
|
|
186
160
|
end
|
|
187
161
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/prompts/chunk_size_prompt"
|
|
5
|
+
|
|
6
|
+
class ChunkSizePromptTest < Minitest::Test
|
|
7
|
+
def test_returns_entered_value
|
|
8
|
+
out = StringIO.new
|
|
9
|
+
prompt = Csvtool::Interface::CLI::Prompts::ChunkSizePrompt.new(
|
|
10
|
+
stdin: StringIO.new("25\n"),
|
|
11
|
+
stdout: out
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
assert_equal "25", prompt.call
|
|
15
|
+
assert_includes out.string, "Rows per chunk: "
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/prompts/split_manifest_prompt"
|
|
5
|
+
|
|
6
|
+
class SplitManifestPromptTest < Minitest::Test
|
|
7
|
+
class FakeYesNoPrompt
|
|
8
|
+
def initialize(value)
|
|
9
|
+
@value = value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(label:, default:)
|
|
13
|
+
@value.nil? ? default : @value
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_returns_disabled_when_user_declines_manifest
|
|
18
|
+
prompt = Csvtool::Interface::CLI::Prompts::SplitManifestPrompt.new(
|
|
19
|
+
stdin: StringIO.new,
|
|
20
|
+
stdout: StringIO.new,
|
|
21
|
+
yes_no_prompt: FakeYesNoPrompt.new(false)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
result = prompt.call(default_path: "/tmp/manifest.csv")
|
|
25
|
+
|
|
26
|
+
assert_equal false, result[:write_manifest]
|
|
27
|
+
assert_nil result[:manifest_path]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_uses_default_manifest_path_when_blank
|
|
31
|
+
prompt = Csvtool::Interface::CLI::Prompts::SplitManifestPrompt.new(
|
|
32
|
+
stdin: StringIO.new("\n"),
|
|
33
|
+
stdout: StringIO.new,
|
|
34
|
+
yes_no_prompt: FakeYesNoPrompt.new(true)
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
result = prompt.call(default_path: "/tmp/manifest.csv")
|
|
38
|
+
|
|
39
|
+
assert_equal true, result[:write_manifest]
|
|
40
|
+
assert_equal "/tmp/manifest.csv", result[:manifest_path]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/prompts/split_output_prompt"
|
|
5
|
+
require "csvtool/interface/cli/prompts/yes_no_prompt"
|
|
6
|
+
|
|
7
|
+
class SplitOutputPromptTest < Minitest::Test
|
|
8
|
+
def test_uses_defaults_for_blank_values
|
|
9
|
+
out = StringIO.new
|
|
10
|
+
prompt = Csvtool::Interface::CLI::Prompts::SplitOutputPrompt.new(
|
|
11
|
+
stdin: StringIO.new("\n\n\n"),
|
|
12
|
+
stdout: out,
|
|
13
|
+
yes_no_prompt: Csvtool::Interface::CLI::Prompts::YesNoPrompt.new(stdin: StringIO.new("\n"), stdout: StringIO.new)
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
result = prompt.call(default_directory: "/tmp/out", default_prefix: "people")
|
|
17
|
+
|
|
18
|
+
assert_equal "/tmp/out", result[:output_directory]
|
|
19
|
+
assert_equal "people", result[:file_prefix]
|
|
20
|
+
assert_equal false, result[:overwrite_existing]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/workflows/builders/csv_split_session_builder"
|
|
5
|
+
|
|
6
|
+
class CsvSplitSessionBuilderTest < Minitest::Test
|
|
7
|
+
def test_builds_split_session
|
|
8
|
+
session = Csvtool::Interface::CLI::Workflows::Builders::CsvSplitSessionBuilder.new.call(
|
|
9
|
+
file_path: "/tmp/people.csv",
|
|
10
|
+
col_sep: ",",
|
|
11
|
+
headers_present: true,
|
|
12
|
+
chunk_size: 10,
|
|
13
|
+
output_directory: "/tmp/out",
|
|
14
|
+
file_prefix: "batch",
|
|
15
|
+
overwrite_existing: true,
|
|
16
|
+
write_manifest: true,
|
|
17
|
+
manifest_path: "/tmp/out/manifest.csv"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
assert_equal "/tmp/people.csv", session.source.path
|
|
21
|
+
assert_equal ",", session.source.separator
|
|
22
|
+
assert_equal true, session.source.headers_present
|
|
23
|
+
assert_equal 10, session.options.chunk_size
|
|
24
|
+
assert_equal "/tmp/out", session.options.output_directory
|
|
25
|
+
assert_equal "batch", session.options.file_prefix
|
|
26
|
+
assert_equal true, session.options.overwrite_existing
|
|
27
|
+
assert_equal true, session.options.write_manifest
|
|
28
|
+
assert_equal "/tmp/out/manifest.csv", session.options.manifest_path
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/workflows/builders/csv_stats_session_builder"
|
|
5
|
+
require "csvtool/domain/shared/output_destination"
|
|
6
|
+
|
|
7
|
+
class CsvStatsSessionBuilderTest < Minitest::Test
|
|
8
|
+
def test_builds_stats_session
|
|
9
|
+
builder = Csvtool::Interface::CLI::Workflows::Builders::CsvStatsSessionBuilder.new
|
|
10
|
+
destination = Csvtool::Domain::Shared::OutputDestination.console
|
|
11
|
+
|
|
12
|
+
session = builder.call(file_path: "/tmp/data.csv", col_sep: ";", headers_present: false, destination: destination)
|
|
13
|
+
|
|
14
|
+
assert_equal "/tmp/data.csv", session.source.path
|
|
15
|
+
assert_equal ";", session.source.separator
|
|
16
|
+
assert_equal false, session.source.headers_present
|
|
17
|
+
assert_equal true, session.output_destination.console?
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/workflows/presenters/csv_split_presenter"
|
|
5
|
+
|
|
6
|
+
class CsvSplitPresenterTest < Minitest::Test
|
|
7
|
+
def test_prints_summary_and_chunk_paths
|
|
8
|
+
out = StringIO.new
|
|
9
|
+
presenter = Csvtool::Interface::CLI::Workflows::Presenters::CsvSplitPresenter.new(stdout: out)
|
|
10
|
+
|
|
11
|
+
presenter.print_summary(
|
|
12
|
+
chunk_size: 10,
|
|
13
|
+
data_rows: 25,
|
|
14
|
+
chunk_count: 3,
|
|
15
|
+
manifest_path: "/tmp/manifest.csv",
|
|
16
|
+
chunk_paths: ["/tmp/people_part_001.csv", "/tmp/people_part_002.csv", "/tmp/people_part_003.csv"]
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
assert_includes out.string, "Split complete."
|
|
20
|
+
assert_includes out.string, "Chunk size: 10"
|
|
21
|
+
assert_includes out.string, "Data rows: 25"
|
|
22
|
+
assert_includes out.string, "Chunks written: 3"
|
|
23
|
+
assert_includes out.string, "Manifest: /tmp/manifest.csv"
|
|
24
|
+
assert_includes out.string, "/tmp/people_part_001.csv"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../../../test_helper"
|
|
4
|
+
require "csvtool/interface/cli/workflows/presenters/csv_stats_presenter"
|
|
5
|
+
|
|
6
|
+
class CsvStatsPresenterTest < Minitest::Test
|
|
7
|
+
def test_prints_summary_with_headers_and_column_stats
|
|
8
|
+
out = StringIO.new
|
|
9
|
+
presenter = Csvtool::Interface::CLI::Workflows::Presenters::CsvStatsPresenter.new(stdout: out)
|
|
10
|
+
|
|
11
|
+
presenter.print_summary(
|
|
12
|
+
row_count: 3,
|
|
13
|
+
column_count: 2,
|
|
14
|
+
headers: ["name", "city"],
|
|
15
|
+
column_stats: [
|
|
16
|
+
{ name: "name", non_blank_count: 3, blank_count: 0 },
|
|
17
|
+
{ name: "city", non_blank_count: 2, blank_count: 1 }
|
|
18
|
+
]
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
assert_includes out.string, "CSV Stats Summary"
|
|
22
|
+
assert_includes out.string, "Rows: 3"
|
|
23
|
+
assert_includes out.string, "Columns: 2"
|
|
24
|
+
assert_includes out.string, "Headers: name, city"
|
|
25
|
+
assert_includes out.string, "name: non_blank=3 blank=0"
|
|
26
|
+
assert_includes out.string, "city: non_blank=2 blank=1"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_prints_file_written_message
|
|
30
|
+
out = StringIO.new
|
|
31
|
+
presenter = Csvtool::Interface::CLI::Workflows::Presenters::CsvStatsPresenter.new(stdout: out)
|
|
32
|
+
|
|
33
|
+
presenter.print_file_written("/tmp/stats.csv")
|
|
34
|
+
|
|
35
|
+
assert_includes out.string, "Wrote output to /tmp/stats.csv"
|
|
36
|
+
end
|
|
37
|
+
end
|