csvops 0.7.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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +61 -21
  3. data/docs/architecture.md +64 -4
  4. data/docs/release-v0.8.0-alpha.md +88 -0
  5. data/lib/csvtool/application/use_cases/run_csv_stats.rb +64 -0
  6. data/lib/csvtool/cli.rb +5 -1
  7. data/lib/csvtool/domain/csv_stats_session/stats_options.rb +11 -0
  8. data/lib/csvtool/domain/csv_stats_session/stats_session.rb +25 -0
  9. data/lib/csvtool/domain/csv_stats_session/stats_source.rb +17 -0
  10. data/lib/csvtool/infrastructure/csv/csv_stats_scanner.rb +67 -0
  11. data/lib/csvtool/infrastructure/output/csv_stats_file_writer.rb +26 -0
  12. data/lib/csvtool/interface/cli/menu_loop.rb +5 -2
  13. data/lib/csvtool/interface/cli/workflows/builders/csv_stats_session_builder.rb +28 -0
  14. data/lib/csvtool/interface/cli/workflows/presenters/csv_stats_presenter.rb +34 -0
  15. data/lib/csvtool/interface/cli/workflows/run_csv_stats_workflow.rb +77 -0
  16. data/lib/csvtool/interface/cli/workflows/steps/csv_stats/build_session_step.rb +25 -0
  17. data/lib/csvtool/interface/cli/workflows/steps/csv_stats/collect_destination_step.rb +27 -0
  18. data/lib/csvtool/interface/cli/workflows/steps/csv_stats/collect_inputs_step.rb +31 -0
  19. data/lib/csvtool/interface/cli/workflows/steps/csv_stats/execute_step.rb +27 -0
  20. data/lib/csvtool/version.rb +1 -1
  21. data/test/csvtool/application/use_cases/run_csv_stats_test.rb +165 -0
  22. data/test/csvtool/cli_test.rb +93 -30
  23. data/test/csvtool/infrastructure/csv/csv_stats_scanner_test.rb +68 -0
  24. data/test/csvtool/infrastructure/output/csv_stats_file_writer_test.rb +38 -0
  25. data/test/csvtool/interface/cli/menu_loop_test.rb +34 -11
  26. data/test/csvtool/interface/cli/workflows/builders/csv_stats_session_builder_test.rb +19 -0
  27. data/test/csvtool/interface/cli/workflows/presenters/csv_stats_presenter_test.rb +37 -0
  28. data/test/csvtool/interface/cli/workflows/run_csv_stats_workflow_test.rb +146 -0
  29. data/test/csvtool/interface/cli/workflows/steps/csv_stats/build_session_step_test.rb +36 -0
  30. data/test/csvtool/interface/cli/workflows/steps/csv_stats/collect_destination_step_test.rb +49 -0
  31. data/test/csvtool/interface/cli/workflows/steps/csv_stats/collect_inputs_step_test.rb +61 -0
  32. data/test/csvtool/interface/cli/workflows/steps/csv_stats/execute_step_test.rb +65 -0
  33. metadata +25 -1
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../../test_helper"
4
+ require "csvtool/interface/cli/workflows/run_csv_stats_workflow"
5
+ require "tmpdir"
6
+
7
+ class RunCsvStatsWorkflowTest < Minitest::Test
8
+ def fixture_path(name)
9
+ File.expand_path("../../../../fixtures/#{name}", __dir__)
10
+ end
11
+
12
+ def test_workflow_prints_core_stats_summary
13
+ out = StringIO.new
14
+ input = [fixture_path("sample_people.csv"), "", ""].join("\n") + "\n"
15
+
16
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
17
+ stdin: StringIO.new(input),
18
+ stdout: out
19
+ ).call
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, "Column completeness:"
26
+ assert_includes out.string, "name: non_blank=3 blank=0"
27
+ assert_includes out.string, "city: non_blank=3 blank=0"
28
+ end
29
+
30
+ def test_workflow_supports_tsv_separator
31
+ out = StringIO.new
32
+ input = [fixture_path("sample_people.tsv"), "2", ""].join("\n") + "\n"
33
+
34
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
35
+ stdin: StringIO.new(input),
36
+ stdout: out
37
+ ).call
38
+
39
+ assert_includes out.string, "Rows: 3"
40
+ assert_includes out.string, "Columns: 2"
41
+ assert_includes out.string, "Headers: name, city"
42
+ end
43
+
44
+ def test_workflow_supports_headerless_mode
45
+ out = StringIO.new
46
+ input = [fixture_path("sample_people_no_headers.csv"), "", "n"].join("\n") + "\n"
47
+
48
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
49
+ stdin: StringIO.new(input),
50
+ stdout: out
51
+ ).call
52
+
53
+ assert_includes out.string, "Rows: 3"
54
+ assert_includes out.string, "Columns: 2"
55
+ refute_includes out.string, "Headers:"
56
+ assert_includes out.string, "column_1: non_blank=3 blank=0"
57
+ assert_includes out.string, "column_2: non_blank=3 blank=0"
58
+ end
59
+
60
+ def test_workflow_supports_custom_separator
61
+ out = StringIO.new
62
+ input = [fixture_path("sample_people_colon.txt"), "5", ":", ""].join("\n") + "\n"
63
+
64
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
65
+ stdin: StringIO.new(input),
66
+ stdout: out
67
+ ).call
68
+
69
+ assert_includes out.string, "Rows: 3"
70
+ assert_includes out.string, "Columns: 2"
71
+ assert_includes out.string, "Headers: name, city"
72
+ end
73
+
74
+ def test_workflow_prints_column_completeness_for_blank_values
75
+ out = StringIO.new
76
+ input = [fixture_path("sample_people_blanks.csv"), "", ""].join("\n") + "\n"
77
+
78
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
79
+ stdin: StringIO.new(input),
80
+ stdout: out
81
+ ).call
82
+
83
+ assert_includes out.string, "name: non_blank=3 blank=2"
84
+ assert_includes out.string, "city: non_blank=4 blank=1"
85
+ end
86
+
87
+ def test_workflow_reports_missing_file
88
+ out = StringIO.new
89
+ input = ["/tmp/does-not-exist.csv", "", ""].join("\n") + "\n"
90
+
91
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
92
+ stdin: StringIO.new(input),
93
+ stdout: out
94
+ ).call
95
+
96
+ assert_includes out.string, "File not found: /tmp/does-not-exist.csv"
97
+ refute_includes out.string, "Traceback"
98
+ end
99
+
100
+ def test_workflow_reports_parse_error
101
+ out = StringIO.new
102
+ input = [fixture_path("sample_people_bad_tail.csv"), "", ""].join("\n") + "\n"
103
+
104
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
105
+ stdin: StringIO.new(input),
106
+ stdout: out
107
+ ).call
108
+
109
+ assert_includes out.string, "Could not parse CSV file."
110
+ refute_includes out.string, "Traceback"
111
+ end
112
+
113
+ def test_workflow_can_write_stats_to_file
114
+ out = StringIO.new
115
+
116
+ Dir.mktmpdir do |dir|
117
+ output_path = File.join(dir, "stats.csv")
118
+ input = [fixture_path("sample_people.csv"), "", "", "2", output_path].join("\n") + "\n"
119
+
120
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
121
+ stdin: StringIO.new(input),
122
+ stdout: out
123
+ ).call
124
+
125
+ assert_includes out.string, "Wrote output to #{output_path}"
126
+ csv_text = File.read(output_path)
127
+ assert_includes csv_text, "metric,value"
128
+ assert_includes csv_text, "row_count,3"
129
+ assert_includes csv_text, "column_count,2"
130
+ end
131
+ end
132
+
133
+ def test_workflow_reports_cannot_write_output_file
134
+ out = StringIO.new
135
+ output_path = "/tmp/does-not-exist-dir/stats.csv"
136
+ input = [fixture_path("sample_people.csv"), "", "", "2", output_path].join("\n") + "\n"
137
+
138
+ Csvtool::Interface::CLI::Workflows::RunCsvStatsWorkflow.new(
139
+ stdin: StringIO.new(input),
140
+ stdout: out
141
+ ).call
142
+
143
+ assert_includes out.string, "Cannot write output file: #{output_path} (Errno::ENOENT)"
144
+ refute_includes out.string, "Traceback"
145
+ end
146
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../../../../test_helper"
4
+ require "csvtool/interface/cli/workflows/steps/csv_stats/build_session_step"
5
+
6
+ class CsvStatsBuildSessionStepTest < Minitest::Test
7
+ class FakeBuilder
8
+ attr_reader :params
9
+
10
+ def call(**params)
11
+ @params = params
12
+ :session
13
+ end
14
+ end
15
+
16
+ def test_builds_session_from_context
17
+ builder = FakeBuilder.new
18
+ step = Csvtool::Interface::CLI::Workflows::Steps::CsvStats::BuildSessionStep.new
19
+ context = {
20
+ session_builder: builder,
21
+ file_path: "/tmp/data.csv",
22
+ col_sep: "\t",
23
+ headers_present: true,
24
+ output_destination: :destination
25
+ }
26
+
27
+ result = step.call(context)
28
+
29
+ assert_nil result
30
+ assert_equal :session, context[:session]
31
+ assert_equal "/tmp/data.csv", builder.params[:file_path]
32
+ assert_equal "\t", builder.params[:col_sep]
33
+ assert_equal true, builder.params[:headers_present]
34
+ assert_equal :destination, builder.params[:destination]
35
+ end
36
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../../../../test_helper"
4
+ require "csvtool/interface/cli/workflows/steps/csv_stats/collect_destination_step"
5
+
6
+ class CsvStatsCollectDestinationStepTest < Minitest::Test
7
+ class FakePrompt
8
+ def initialize(result)
9
+ @result = result
10
+ end
11
+
12
+ def call
13
+ @result
14
+ end
15
+ end
16
+
17
+ class FakeMapper
18
+ attr_reader :input
19
+
20
+ def call(input)
21
+ @input = input
22
+ :mapped_destination
23
+ end
24
+ end
25
+
26
+ def test_collects_and_maps_destination
27
+ mapper = FakeMapper.new
28
+ step = Csvtool::Interface::CLI::Workflows::Steps::CsvStats::CollectDestinationStep.new(
29
+ output_destination_prompt: FakePrompt.new({ mode: :file, path: "/tmp/out.csv" })
30
+ )
31
+ context = { output_destination_mapper: mapper }
32
+
33
+ result = step.call(context)
34
+
35
+ assert_nil result
36
+ assert_equal({ mode: :file, path: "/tmp/out.csv" }, mapper.input)
37
+ assert_equal :mapped_destination, context[:output_destination]
38
+ end
39
+
40
+ def test_halts_when_destination_prompt_returns_nil
41
+ step = Csvtool::Interface::CLI::Workflows::Steps::CsvStats::CollectDestinationStep.new(
42
+ output_destination_prompt: FakePrompt.new(nil)
43
+ )
44
+
45
+ result = step.call(output_destination_mapper: FakeMapper.new)
46
+
47
+ assert_equal :halt, result
48
+ end
49
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../../../../test_helper"
4
+ require "csvtool/interface/cli/workflows/steps/csv_stats/collect_inputs_step"
5
+
6
+ class CsvStatsCollectInputsStepTest < Minitest::Test
7
+ class FakeFilePathPrompt
8
+ attr_reader :label
9
+
10
+ def call(label:)
11
+ @label = label
12
+ "/tmp/input.csv"
13
+ end
14
+ end
15
+
16
+ class FakeSeparatorPrompt
17
+ def initialize(result)
18
+ @result = result
19
+ end
20
+
21
+ def call
22
+ @result
23
+ end
24
+ end
25
+
26
+ class FakeHeadersPresentPrompt
27
+ def call
28
+ false
29
+ end
30
+ end
31
+
32
+ def test_collects_inputs_into_context
33
+ file_prompt = FakeFilePathPrompt.new
34
+ step = Csvtool::Interface::CLI::Workflows::Steps::CsvStats::CollectInputsStep.new(
35
+ file_path_prompt: file_prompt,
36
+ separator_prompt: FakeSeparatorPrompt.new(";"),
37
+ headers_present_prompt: FakeHeadersPresentPrompt.new
38
+ )
39
+ context = {}
40
+
41
+ result = step.call(context)
42
+
43
+ assert_nil result
44
+ assert_equal "CSV file path: ", file_prompt.label
45
+ assert_equal "/tmp/input.csv", context[:file_path]
46
+ assert_equal ";", context[:col_sep]
47
+ assert_equal false, context[:headers_present]
48
+ end
49
+
50
+ def test_halts_when_separator_prompt_returns_nil
51
+ step = Csvtool::Interface::CLI::Workflows::Steps::CsvStats::CollectInputsStep.new(
52
+ file_path_prompt: FakeFilePathPrompt.new,
53
+ separator_prompt: FakeSeparatorPrompt.new(nil),
54
+ headers_present_prompt: FakeHeadersPresentPrompt.new
55
+ )
56
+
57
+ result = step.call({})
58
+
59
+ assert_equal :halt, result
60
+ end
61
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../../../../test_helper"
4
+ require "csvtool/interface/cli/workflows/steps/csv_stats/execute_step"
5
+
6
+ class CsvStatsExecuteStepTest < Minitest::Test
7
+ Result = Struct.new(:ok, :data) do
8
+ def ok? = ok
9
+ end
10
+
11
+ class FakeUseCase
12
+ def initialize(result)
13
+ @result = result
14
+ end
15
+
16
+ def call(session:)
17
+ @result
18
+ end
19
+ end
20
+
21
+ class FakePresenter
22
+ attr_reader :summary_data, :written_path
23
+
24
+ def print_summary(data)
25
+ @summary_data = data
26
+ end
27
+
28
+ def print_file_written(path)
29
+ @written_path = path
30
+ end
31
+ end
32
+
33
+ def test_prints_summary_and_file_path_when_present
34
+ presenter = FakePresenter.new
35
+ result = Result.new(true, { row_count: 2, output_path: "/tmp/stats.csv" })
36
+ step = Csvtool::Interface::CLI::Workflows::Steps::CsvStats::ExecuteStep.new
37
+
38
+ outcome = step.call(
39
+ session: :session,
40
+ use_case: FakeUseCase.new(result),
41
+ presenter: presenter,
42
+ handle_error: ->(_result) { raise "unexpected" }
43
+ )
44
+
45
+ assert_nil outcome
46
+ assert_equal result.data, presenter.summary_data
47
+ assert_equal "/tmp/stats.csv", presenter.written_path
48
+ end
49
+
50
+ def test_halts_on_use_case_failure
51
+ fail_result = Result.new(false, { reason: :bad })
52
+ handled = []
53
+ step = Csvtool::Interface::CLI::Workflows::Steps::CsvStats::ExecuteStep.new
54
+
55
+ outcome = step.call(
56
+ session: :session,
57
+ use_case: FakeUseCase.new(fail_result),
58
+ presenter: FakePresenter.new,
59
+ handle_error: ->(result) { handled << result }
60
+ )
61
+
62
+ assert_equal :halt, outcome
63
+ assert_equal [fail_result], handled
64
+ end
65
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csvops
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0.alpha
4
+ version: 0.8.0.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Hall
@@ -75,10 +75,12 @@ files:
75
75
  - docs/release-v0.5.0-alpha.md
76
76
  - docs/release-v0.6.0-alpha.md
77
77
  - docs/release-v0.7.0-alpha.md
78
+ - docs/release-v0.8.0-alpha.md
78
79
  - exe/csvtool
79
80
  - lib/csvtool/application/use_cases/run_cross_csv_dedupe.rb
80
81
  - lib/csvtool/application/use_cases/run_csv_parity.rb
81
82
  - lib/csvtool/application/use_cases/run_csv_split.rb
83
+ - lib/csvtool/application/use_cases/run_csv_stats.rb
82
84
  - lib/csvtool/application/use_cases/run_extraction.rb
83
85
  - lib/csvtool/application/use_cases/run_row_extraction.rb
84
86
  - lib/csvtool/application/use_cases/run_row_randomization.rb
@@ -101,6 +103,9 @@ files:
101
103
  - lib/csvtool/domain/csv_split_session/split_options.rb
102
104
  - lib/csvtool/domain/csv_split_session/split_session.rb
103
105
  - lib/csvtool/domain/csv_split_session/split_source.rb
106
+ - lib/csvtool/domain/csv_stats_session/stats_options.rb
107
+ - lib/csvtool/domain/csv_stats_session/stats_session.rb
108
+ - lib/csvtool/domain/csv_stats_session/stats_source.rb
104
109
  - lib/csvtool/domain/row_randomization_session/randomization_options.rb
105
110
  - lib/csvtool/domain/row_randomization_session/randomization_session.rb
106
111
  - lib/csvtool/domain/row_randomization_session/randomization_source.rb
@@ -111,6 +116,7 @@ files:
111
116
  - lib/csvtool/infrastructure/csv/cross_csv_deduper.rb
112
117
  - lib/csvtool/infrastructure/csv/csv_parity_comparator.rb
113
118
  - lib/csvtool/infrastructure/csv/csv_splitter.rb
119
+ - lib/csvtool/infrastructure/csv/csv_stats_scanner.rb
114
120
  - lib/csvtool/infrastructure/csv/header_reader.rb
115
121
  - lib/csvtool/infrastructure/csv/row_randomizer.rb
116
122
  - lib/csvtool/infrastructure/csv/row_streamer.rb
@@ -123,6 +129,7 @@ files:
123
129
  - lib/csvtool/infrastructure/output/csv_row_console_writer.rb
124
130
  - lib/csvtool/infrastructure/output/csv_row_file_writer.rb
125
131
  - lib/csvtool/infrastructure/output/csv_split_manifest_writer.rb
132
+ - lib/csvtool/infrastructure/output/csv_stats_file_writer.rb
126
133
  - lib/csvtool/interface/cli/errors/presenter.rb
127
134
  - lib/csvtool/interface/cli/menu_loop.rb
128
135
  - lib/csvtool/interface/cli/prompts/chunk_size_prompt.rb
@@ -142,17 +149,20 @@ files:
142
149
  - lib/csvtool/interface/cli/workflows/builders/cross_csv_dedupe_session_builder.rb
143
150
  - lib/csvtool/interface/cli/workflows/builders/csv_parity_session_builder.rb
144
151
  - lib/csvtool/interface/cli/workflows/builders/csv_split_session_builder.rb
152
+ - lib/csvtool/interface/cli/workflows/builders/csv_stats_session_builder.rb
145
153
  - lib/csvtool/interface/cli/workflows/builders/row_extraction_session_builder.rb
146
154
  - lib/csvtool/interface/cli/workflows/builders/row_randomization_session_builder.rb
147
155
  - lib/csvtool/interface/cli/workflows/presenters/column_extraction_presenter.rb
148
156
  - lib/csvtool/interface/cli/workflows/presenters/cross_csv_dedupe_presenter.rb
149
157
  - lib/csvtool/interface/cli/workflows/presenters/csv_parity_presenter.rb
150
158
  - lib/csvtool/interface/cli/workflows/presenters/csv_split_presenter.rb
159
+ - lib/csvtool/interface/cli/workflows/presenters/csv_stats_presenter.rb
151
160
  - lib/csvtool/interface/cli/workflows/presenters/row_extraction_presenter.rb
152
161
  - lib/csvtool/interface/cli/workflows/presenters/row_randomization_presenter.rb
153
162
  - lib/csvtool/interface/cli/workflows/run_cross_csv_dedupe_workflow.rb
154
163
  - lib/csvtool/interface/cli/workflows/run_csv_parity_workflow.rb
155
164
  - lib/csvtool/interface/cli/workflows/run_csv_split_workflow.rb
165
+ - lib/csvtool/interface/cli/workflows/run_csv_stats_workflow.rb
156
166
  - lib/csvtool/interface/cli/workflows/run_extraction_workflow.rb
157
167
  - lib/csvtool/interface/cli/workflows/run_row_extraction_workflow.rb
158
168
  - lib/csvtool/interface/cli/workflows/run_row_randomization_workflow.rb
@@ -164,6 +174,10 @@ files:
164
174
  - lib/csvtool/interface/cli/workflows/steps/csv_split/collect_manifest_step.rb
165
175
  - lib/csvtool/interface/cli/workflows/steps/csv_split/collect_output_step.rb
166
176
  - lib/csvtool/interface/cli/workflows/steps/csv_split/execute_step.rb
177
+ - lib/csvtool/interface/cli/workflows/steps/csv_stats/build_session_step.rb
178
+ - lib/csvtool/interface/cli/workflows/steps/csv_stats/collect_destination_step.rb
179
+ - lib/csvtool/interface/cli/workflows/steps/csv_stats/collect_inputs_step.rb
180
+ - lib/csvtool/interface/cli/workflows/steps/csv_stats/execute_step.rb
167
181
  - lib/csvtool/interface/cli/workflows/steps/extraction/build_preview_step.rb
168
182
  - lib/csvtool/interface/cli/workflows/steps/extraction/collect_destination_step.rb
169
183
  - lib/csvtool/interface/cli/workflows/steps/extraction/collect_inputs_step.rb
@@ -188,6 +202,7 @@ files:
188
202
  - test/csvtool/application/use_cases/run_cross_csv_dedupe_test.rb
189
203
  - test/csvtool/application/use_cases/run_csv_parity_test.rb
190
204
  - test/csvtool/application/use_cases/run_csv_split_test.rb
205
+ - test/csvtool/application/use_cases/run_csv_stats_test.rb
191
206
  - test/csvtool/application/use_cases/run_extraction_test.rb
192
207
  - test/csvtool/application/use_cases/run_row_extraction_test.rb
193
208
  - test/csvtool/application/use_cases/run_row_randomization_test.rb
@@ -218,6 +233,7 @@ files:
218
233
  - test/csvtool/infrastructure/csv/cross_csv_deduper_test.rb
219
234
  - test/csvtool/infrastructure/csv/csv_parity_comparator_test.rb
220
235
  - test/csvtool/infrastructure/csv/csv_splitter_test.rb
236
+ - test/csvtool/infrastructure/csv/csv_stats_scanner_test.rb
221
237
  - test/csvtool/infrastructure/csv/header_reader_test.rb
222
238
  - test/csvtool/infrastructure/csv/row_randomizer_test.rb
223
239
  - test/csvtool/infrastructure/csv/row_streamer_test.rb
@@ -230,6 +246,7 @@ files:
230
246
  - test/csvtool/infrastructure/output/csv_row_console_writer_test.rb
231
247
  - test/csvtool/infrastructure/output/csv_row_file_writer_test.rb
232
248
  - test/csvtool/infrastructure/output/csv_split_manifest_writer_test.rb
249
+ - test/csvtool/infrastructure/output/csv_stats_file_writer_test.rb
233
250
  - test/csvtool/interface/cli/errors/presenter_test.rb
234
251
  - test/csvtool/interface/cli/menu_loop_test.rb
235
252
  - test/csvtool/interface/cli/prompts/chunk_size_prompt_test.rb
@@ -249,17 +266,20 @@ files:
249
266
  - test/csvtool/interface/cli/workflows/builders/cross_csv_dedupe_session_builder_test.rb
250
267
  - test/csvtool/interface/cli/workflows/builders/csv_parity_session_builder_test.rb
251
268
  - test/csvtool/interface/cli/workflows/builders/csv_split_session_builder_test.rb
269
+ - test/csvtool/interface/cli/workflows/builders/csv_stats_session_builder_test.rb
252
270
  - test/csvtool/interface/cli/workflows/builders/row_extraction_session_builder_test.rb
253
271
  - test/csvtool/interface/cli/workflows/builders/row_randomization_session_builder_test.rb
254
272
  - test/csvtool/interface/cli/workflows/presenters/column_extraction_presenter_test.rb
255
273
  - test/csvtool/interface/cli/workflows/presenters/cross_csv_dedupe_presenter_test.rb
256
274
  - test/csvtool/interface/cli/workflows/presenters/csv_parity_presenter_test.rb
257
275
  - test/csvtool/interface/cli/workflows/presenters/csv_split_presenter_test.rb
276
+ - test/csvtool/interface/cli/workflows/presenters/csv_stats_presenter_test.rb
258
277
  - test/csvtool/interface/cli/workflows/presenters/row_extraction_presenter_test.rb
259
278
  - test/csvtool/interface/cli/workflows/presenters/row_randomization_presenter_test.rb
260
279
  - test/csvtool/interface/cli/workflows/run_cross_csv_dedupe_workflow_test.rb
261
280
  - test/csvtool/interface/cli/workflows/run_csv_parity_workflow_test.rb
262
281
  - test/csvtool/interface/cli/workflows/run_csv_split_workflow_test.rb
282
+ - test/csvtool/interface/cli/workflows/run_csv_stats_workflow_test.rb
263
283
  - test/csvtool/interface/cli/workflows/run_extraction_workflow_test.rb
264
284
  - test/csvtool/interface/cli/workflows/run_row_extraction_workflow_test.rb
265
285
  - test/csvtool/interface/cli/workflows/run_row_randomization_workflow_test.rb
@@ -269,6 +289,10 @@ files:
269
289
  - test/csvtool/interface/cli/workflows/steps/csv_split/collect_manifest_step_test.rb
270
290
  - test/csvtool/interface/cli/workflows/steps/csv_split/collect_output_step_test.rb
271
291
  - test/csvtool/interface/cli/workflows/steps/csv_split/execute_step_test.rb
292
+ - test/csvtool/interface/cli/workflows/steps/csv_stats/build_session_step_test.rb
293
+ - test/csvtool/interface/cli/workflows/steps/csv_stats/collect_destination_step_test.rb
294
+ - test/csvtool/interface/cli/workflows/steps/csv_stats/collect_inputs_step_test.rb
295
+ - test/csvtool/interface/cli/workflows/steps/csv_stats/execute_step_test.rb
272
296
  - test/csvtool/interface/cli/workflows/steps/extraction/collect_inputs_step_test.rb
273
297
  - test/csvtool/interface/cli/workflows/steps/parity/build_session_step_test.rb
274
298
  - test/csvtool/interface/cli/workflows/steps/parity/collect_inputs_step_test.rb