-
Notifications
You must be signed in to change notification settings - Fork 128
Add bare bones console application for filtering CSV #321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
02a733d
c23e371
f6a7b29
e929d19
c6f9dd6
6a01bbf
8fee505
c354176
97444e7
7102e61
cdc2b47
119e98c
ebb8f48
1776b21
c3e960e
0658a05
b5cdca6
ae72bb6
a63628d
b176c63
60ff670
31c2f2f
2d67ff1
ecd77d6
4befc44
cf86328
0dc6777
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #!/usr/bin/env ruby | ||
|
|
||
| require 'optparse' | ||
| require 'csv' | ||
|
|
||
| options = {} | ||
|
|
||
| parser = OptionParser.new | ||
|
|
||
| parser.version = CSV::VERSION | ||
| parser.banner = <<-BANNER | ||
| Usage: #{parser.program_name} [options] | ||
|
|
||
| Reads and parses the CSV text content of the standard input per the given input options. | ||
| From that content, generates CSV text per the given output options | ||
| and writes that text to the standard output. | ||
|
|
||
| BANNER | ||
|
|
||
| parser.separator('Generic Options') | ||
| parser.separator(nil) | ||
|
|
||
| parser.parse! | ||
|
|
||
| CSV.filter(**options) do |row| | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # frozen_string_literal: false | ||
|
|
||
| require_relative '../helper' | ||
|
|
||
| require 'csv' | ||
|
|
||
| class TestFilter < Test::Unit::TestCase | ||
|
|
||
|
BurdetteLamar marked this conversation as resolved.
Outdated
|
||
| # Some rows data (useful as default). | ||
| Rows = [ | ||
| %w[aaa bbb ccc], | ||
| %w[ddd eee fff], | ||
| ] | ||
|
BurdetteLamar marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Return CSV string generated from rows array and options. | ||
| def make_csv_s(rows: Rows, **options) | ||
| CSV.generate(**options) do|csv| | ||
| rows.each do |row| | ||
| csv << row | ||
| end | ||
| end | ||
| end | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this? How about keeping all CSV data as
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
|
||
| # Return filepath of file containing CSV data. | ||
| def csv_filepath(csv_in_s, dirpath, option_sym) | ||
| filename = "#{option_sym}.csv" | ||
| filepath = File.join(dirpath, filename) | ||
| File.write(filepath, csv_in_s) | ||
| filepath | ||
| end | ||
|
|
||
| # Return stdout and stderr from CLI execution. | ||
| def run_csv_filter(filepath, cli_option_names = []) | ||
|
BurdetteLamar marked this conversation as resolved.
Outdated
|
||
| top_dir = File.join(__dir__, "..", "..", "..") | ||
| command_line_s = [ | ||
| Gem.ruby, | ||
| "-I", | ||
| File.join(top_dir, "lib"), | ||
| File.join(top_dir, "bin", "csv-filter"), | ||
| * cli_option_names, | ||
|
BurdetteLamar marked this conversation as resolved.
Outdated
|
||
| filepath, | ||
| ].join(' ') | ||
| Tempfile.create("stdout", mode: File::RDWR) do |stdout| | ||
| Tempfile.create("stderr", mode: File::RDWR) do |stderr| | ||
| status = system(command_line_s, {1 => stdout, 2 => stderr}) | ||
| stdout.rewind | ||
| stderr.rewind | ||
| [stdout.read, stderr.read] | ||
| end | ||
| end | ||
| end | ||
|
|
||
| # Return results for CLI-only option (or invalid option). | ||
| def results_for_cli_option(option_name) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use better name? This executes |
||
| cli_out_s = '' | ||
| cli_err_s = '' | ||
| Dir.mktmpdir do |dirpath| | ||
| sym = option_name.to_sym | ||
| filepath = csv_filepath('', dirpath, sym) | ||
| cli_out_s, cli_err_s = run_csv_filter(filepath, [option_name]) | ||
| end | ||
| [cli_out_s, cli_err_s] | ||
| end | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove this? Can
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tests that use this have CLI-only options (-v -h etc.) that can't be passed to the API. I think we need to keep this. |
||
|
|
||
| # Get and return the actual output from the API. | ||
| def get_via_api(csv_in_s, **api_options) | ||
| cli_out_s = '' | ||
| CSV.filter(csv_in_s, cli_out_s, **api_options) {|row| } | ||
| cli_out_s | ||
| end | ||
|
|
||
| # Test for invalid option. | ||
|
|
||
| def test_invalid_option | ||
| cli_out_s, cli_err_s = results_for_cli_option('-Z') | ||
| assert_equal("", cli_out_s) | ||
| assert_match(/OptionParser::InvalidOption/, cli_err_s) | ||
| end | ||
|
|
||
| # Test for no options. | ||
|
|
||
| def test_no_options | ||
| csv_in_s = make_csv_s | ||
| cli_out_s = get_via_api(csv_in_s) | ||
| assert_equal(csv_in_s, cli_out_s) | ||
| end | ||
|
|
||
| # Tests for general options. | ||
|
|
||
| def test_option_h | ||
| cli_out_s, cli_err_s = results_for_cli_option('-h') | ||
|
BurdetteLamar marked this conversation as resolved.
Outdated
|
||
| assert_equal("Usage: csv-filter [options]\n", cli_out_s.lines.first) | ||
| assert_equal('', cli_err_s) | ||
| end | ||
|
|
||
| def test_option_v | ||
| cli_out_s, cli_err_s = results_for_cli_option('-v') | ||
| assert_match(/\d+\.\d+\.\d+/, cli_out_s) | ||
| assert_equal('', cli_err_s) | ||
| end | ||
|
|
||
|
BurdetteLamar marked this conversation as resolved.
Outdated
|
||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this because
../helperhas this?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.