|
require 'tty/prompt' |
|
require 'tmpdir' |
|
require 'active_support/core_ext/object/blank' |
|
|
|
describe 'chmod-alike app' do |
|
let(:app) do |
|
TTY::Testing.app_wrapper do |stdin, stdout| |
|
prompt = TTY::Prompt.new(input: stdin, output: stdout) |
|
filepath = prompt.ask('Type file name:') |
|
unless filepath.blank? |
|
if File.file?(filepath) |
|
if File.stat(filepath).writable? |
|
if File.stat(filepath).executable? |
|
if prompt.yes?('Given file is executable. Remove executable flag?') |
|
FileUtils.chmod 'u-x', filepath |
|
end |
|
else |
|
if prompt.yes?('Given file is not executable. Set executable flag?') |
|
FileUtils.chmod 'u+x', filepath |
|
end |
|
end |
|
else |
|
prompt.say 'Given file is not writable you, cannot proceed' |
|
end |
|
else |
|
prompt.say 'Given file is a directory, cannot proceed' |
|
end |
|
else |
|
prompt.say 'No file name given' |
|
end |
|
end |
|
end |
|
|
|
before { app.run } |
|
|
|
let(:filepath) do |
|
Dir::Tmpname.create('tty-testing-') do |path| |
|
path |
|
end |
|
end |
|
|
|
after do |
|
FileUtils.remove_entry(filepath) if File.exist?(filepath) |
|
end |
|
|
|
before { app.run } |
|
|
|
it 'asks a file name' do |
|
expect(app.output).to end_with("Type file name: ") |
|
end |
|
|
|
context 'when file name is given' do |
|
before do |
|
app.pause_until_further_notice |
|
app.stdin.puts filepath # Important! App won't continue to execute after this line because `app.pause_until_further_notice` was called before |
|
end |
|
|
|
context "when the given file is a directory" do |
|
before { Dir.mkdir(filepath) } # While on pause we can make some preparations for the clause |
|
|
|
before { app.resume_execution } # Now we allow the app to execute and process the input given above |
|
|
|
it do |
|
expect(app.output).to end_with("Given file is a directory, cannot proceed\n") |
|
end |
|
end |
|
|
|
context "when the given file is a regular file" do |
|
before { FileUtils.touch(filepath) } |
|
|
|
context "when the given file is not writable by the user" do |
|
before { FileUtils.chmod 'u-w', filepath } |
|
|
|
before { app.resume_execution } |
|
|
|
it do |
|
expect(app.output).to end_with("Given file is not writable you, cannot proceed\n") |
|
end |
|
end |
|
|
|
context "when the given file is writable by the user" do |
|
before { FileUtils.chmod 'u+w', filepath } |
|
|
|
context "when the given file is executable" do |
|
before { FileUtils.chmod 'u+x', filepath } |
|
|
|
before { app.resume_execution } |
|
|
|
it 'asks whether to remove executable flag' do |
|
expect(app.output).to end_with("Given file is executable. Remove executable flag? (Y/n) ") |
|
end |
|
|
|
context "when the user chooses to remove executable flag" do |
|
before { app.stdin.puts 'y' } # Execution was not paused by now, so the execution continues after a line has been passed to the app input |
|
|
|
it 'removes executable flag' do |
|
expect(File.stat(filepath)).not_to be_executable |
|
end |
|
|
|
it 'exits' do |
|
expect(app).to be_exited |
|
end |
|
end |
|
|
|
context "when the user chooses not to remove executable flag" do |
|
before { app.stdin.puts 'n' } |
|
|
|
it 'does not remove executable flag' do |
|
expect(File.stat(filepath)).to be_executable |
|
end |
|
|
|
it 'exits' do |
|
expect(app).to be_exited |
|
end |
|
end |
|
end |
|
|
|
context "when the given file is not executable" do |
|
before { FileUtils.chmod 'u-x', filepath } |
|
|
|
before { app.resume_execution } |
|
|
|
it 'asks whether to remove executable flag' do |
|
expect(app.output).to end_with("Given file is not executable. Set executable flag? (Y/n) ") |
|
end |
|
|
|
context "when the user chooses to add executable flag" do |
|
before { app.stdin.puts 'y' } |
|
|
|
it 'adds executable flag' do |
|
expect(File.stat(filepath)).to be_executable |
|
end |
|
|
|
it 'exits' do |
|
expect(app).to be_exited |
|
end |
|
end |
|
|
|
context "when the user chooses not to add executable flag" do |
|
before { app.stdin.puts 'n' } |
|
|
|
it 'does not add executable flag' do |
|
expect(File.stat(filepath)).not_to be_executable |
|
end |
|
|
|
it 'exits' do |
|
expect(app).to be_exited |
|
end |
|
end |
|
end |
|
end |
|
end |
|
end |
|
|
|
context 'when file name is not given' do |
|
before { app.stdin.puts } |
|
|
|
it do |
|
expect(app.output).to end_with("No file name given\n") |
|
end |
|
end |
|
end |
Hi Daniel,
Some thoughts on what I am hoping to have in TTY testing helper. I am not sure if this conflicts with your plan, or compliments it, but I thought I will express it in writing here, for reference.
Given CLI that uses TTY that asks these questions:
and at the end prints
#{warrior} wielding #{weapon}
In my view, the most intuitive and testing-framework-agnostic way to test it would be to:
So, translating it to minitest pseudo-code:
and, in rspec: