Skip to content
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

Console application for filtering CSV #321

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
26 changes: 26 additions & 0 deletions bin/csv-filter
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
92 changes: 92 additions & 0 deletions test/csv/csv-filter/test_csv_filter.rb
Original file line number Diff line number Diff line change
@@ -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
Loading