Implement basic CLI usage help

This commit is contained in:
Thibault Jouan 2015-04-07 17:34:16 +00:00
parent f38a5761be
commit 422a940eae
6 changed files with 184 additions and 10 deletions

View File

@ -2,4 +2,5 @@
require 'uh/wm'
Uh::WM::CLI.run!(ARGV)
Uh::WM::CLI.run(ARGV)
sleep 8

View File

@ -0,0 +1,11 @@
Feature: CLI usage
Scenario: prints the usage when unknown option switch is given
When I run uhwm with option --unknown-option
Then the exit status must be 64
And the output must contain exactly the usage
Scenario: prints the help when -h option is given
When I run uhwm with option -h
Then the exit status must be 0
And the output must contain exactly the usage

View File

@ -0,0 +1,8 @@
Then /^the output must contain exactly the usage$/ do
assert_exact_output <<-eoh, all_output
Usage: uhwm [options]
options:
-h, --help print this message
eoh
end

View File

@ -1,4 +1,17 @@
When /^I start uhwm$/ do
@process = run 'uhwm'
@interactive = @process
def uhwm_run options = nil
command = %w[uhwm]
command << options if options
@interactive = @process = run command.join ' '
end
When /^I start uhwm$/ do
uhwm_run
end
When /^I run uhwm with options? (-.+)$/ do |options|
uhwm_run options
end
Then /^the exit status must be (\d+)$/ do |exit_status|
assert_exit_status exit_status.to_i
end

View File

@ -1,13 +1,56 @@
module Uh
module WM
class CLI
ArgumentError = Class.new(ArgumentError)
USAGE = "Usage: #{File.basename $0} [options]".freeze
EX_USAGE = 64
class << self
def run! arguments
$stdout.sync = true
@display = Display.new
@display.open
puts "Connected to X server on `#{display}'"
sleep 8
def run arguments, **options
cli = new arguments, **options
cli.parse_arguments!
cli.run
rescue ArgumentError => e
$stderr.puts e
exit EX_USAGE
end
end
def initialize args, stdin: $stdin, stdout: $stdout, stderr: $stderr
@arguments = args
@stdin = stdin
@stdout = stdout
@stderr = stderr
end
def parse_arguments!
option_parser.parse! @arguments
rescue OptionParser::InvalidOption => e
fail ArgumentError, option_parser
end
def run
@stdout.sync = true
@display = Display.new
@display.open
@stdout.puts "Connected to X server on `#{@display}'"
end
private
def option_parser
OptionParser.new do |opts|
opts.banner = USAGE
opts.separator ''
opts.separator 'options:'
opts.on '-h', '--help', 'print this message' do
@stdout.print opts
exit
end
end
end
end

98
spec/uh/wm/cli_spec.rb Normal file
View File

@ -0,0 +1,98 @@
require 'support/exit_helpers'
module Uh
module WM
RSpec.describe CLI do
include ExitHelpers
let(:stdout) { StringIO.new }
let(:stderr) { StringIO.new }
let(:arguments) { [] }
let(:options) { { stdout: stdout, stderr: stderr } }
subject(:cli) { described_class.new arguments, **options }
describe '.run' do
subject(:run) { described_class.run arguments, **options }
it 'builds a new CLI with given arguments' do
expect(described_class)
.to receive(:new).with(arguments, options).and_call_original
run
end
it 'parses new CLI arguments' do
cli = instance_spy CLI
allow(described_class).to receive(:new) { cli }
expect(cli).to receive :parse_arguments!
run
end
it 'runs new CLI' do
cli = instance_spy CLI
allow(described_class).to receive(:new) { cli }
expect(cli).to receive :run
run
end
context 'with invalid arguments' do
let(:arguments) { %w[--unknown-option] }
it 'prints the usage' do
expect { trap_exit { run } }.to output(/\AUsage: .+/).to_stderr
end
it 'exits with a return status of 64' do
stderr_original = $stderr
$stderr = stderr
expect { run }.to raise_error(SystemExit) do |e|
expect(e.status).to eq 64
end
$stderr = stderr_original
end
end
end
describe '#run' do
let(:display) { instance_spy Display }
before { allow(Display).to receive(:new) { display } }
it 'opens a new X display' do
expect(display).to receive :open
cli.run
end
it 'prints a message on standard output when connected' do
cli.run
expect(stdout.string).to match /connected/i
end
end
describe '#parse_arguments!' do
context 'with help option' do
let(:arguments) { %w[-h] }
it 'prints the usage banner on standard output' do
trap_exit { cli.parse_arguments! }
expect(stdout.string).to match /\AUsage: .+/
end
it 'prints options usage on standard output' do
trap_exit { cli.parse_arguments! }
expect(stdout.string).to match /\n^options:\n\s+-/
end
end
context 'with invalid option' do
let(:arguments) { %w[--unknown-option] }
it 'raises a CLI::ArgumentError' do
expect { cli.parse_arguments! }
.to raise_error CLI::ArgumentError
end
end
end
end
end
end