diff --git a/bin/csv-filter b/bin/csv-filter new file mode 100644 index 00000000..1a9326d7 --- /dev/null +++ b/bin/csv-filter @@ -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 diff --git a/test/csv/csv-filter/test_csv_filter.rb b/test/csv/csv-filter/test_csv_filter.rb new file mode 100644 index 00000000..0d931f06 --- /dev/null +++ b/test/csv/csv-filter/test_csv_filter.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: false + +require_relative "../helper" + +class TestFilter < Test::Unit::TestCase + + def setup + @input = [ + %w[aaa bbb ccc].join(","), + %w[ddd eee fff].join(","), + "" # Force trailing newline. + ].join("\n") + end + + # Return filepath of file containing CSV data. + def csv_filepath(input, dirpath, option) + filename = "#{option}.csv" + filepath = File.join(dirpath, filename) + File.write(filepath, input) + filepath + end + + # Return stdout and stderr from CLI execution. + def run_csv_filter(filepath, *cli_option_names) + top_dir = File.join(__dir__, "..", "..", "..") + command_line = [ + Gem.ruby, + "-I", + File.join(top_dir, "lib"), + File.join(top_dir, "bin", "csv-filter"), + *cli_option_names, + filepath, + ].join(" ") + Tempfile.create("stdout", mode: File::RDWR) do |stdout| + Tempfile.create("stderr", mode: File::RDWR) do |stderr| + system(command_line, {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) + output = "" + error = "" + Dir.mktmpdir do |dirpath| + sym = option_name.to_sym + filepath = csv_filepath("", dirpath, sym) + output, error = run_csv_filter(filepath, [option_name]) + end + [output, error] + end + + # Get and return the actual output from the API. + def api_output(input, **api_options) + output = "" + CSV.filter(input, output, **api_options) {|row| } + output + end + + # Test for invalid option. + + def test_invalid_option + output, error = results_for_cli_option("-Z") + assert_equal("", output) + assert_match(/OptionParser::InvalidOption/, error) + end + + # Test for no options. + + def test_no_options + output = api_output(@input) + assert_equal(@input, output) + end + + # Tests for general options. + + def test_option_h + output, error = results_for_cli_option("-h") + assert_equal("Usage: csv-filter [options]\n", output.lines.first) + assert_equal("", error) + end + + def test_option_v + output, error = results_for_cli_option("-v") + assert_match(/\d+\.\d+\.\d+/, output) + assert_equal("", error) + end + +end