require 'spec_helper' require 'support/heredoc_helper' RSpec.describe SLOCCountScanner, type: :process do # For safety and speed: disable the system calls by default before do stub_const('SystemSLOCCount', double) end describe ".scan" do it "returns a SLOCCount object when sloccount is successful" do stub_dir_exists system_sloccount = fake_system_sloccount( result: "The thing worked. Your sloccount was lots", process_status: successful_process_status ) expect(SLOCCountScanner.new(system_sloccount).scan("my_directory")).to be_a(SLOCCount) end it "returns a null SLOCCount object when sloccount gives a zero sloc result" do stub_dir_exists system_sloccount = fake_system_sloccount( result: ZERO_SLOCCOUNT_OUTPUT, process_status: failed_process_status ) expect(SLOCCountScanner.new(system_sloccount).scan("my_directory")).to be_a(NullSLOCCount) end # EXCEPTION HANDLING: ##################### it "raises an error when no directory is passed" do expect{ SLOCCountScanner.new(anything).scan(nil) } .to raise_error SLOCCountScanner::ArgumentError end it "raises an error when the directory doesn't exist" do system_sloccount = fake_system_sloccount(available: true) expect{ SLOCCountScanner.new(system_sloccount).scan("my_directory") } .to raise_error SLOCCountScanner::NoDirectory end it "raises an error when sloccount was not available" do stub_dir_exists system_sloccount = fake_system_sloccount(available: false) expect{ SLOCCountScanner.new(system_sloccount).scan("my_directory") } .to raise_error SLOCCountScanner::Unavailable end it 'raises an error when sloccount returns an unrecognised error' do stub_dir_exists system_sloccount = fake_system_sloccount( result: "Some nonsense", process_status: failed_process_status ) expect{ SLOCCountScanner.new(system_sloccount).scan("my_directory") } .to raise_error SLOCCountScanner::Exception end it 'raises an error when sloccount returns a `no input` error' do stub_dir_exists # In reality this should never happen because we check for this case system_sloccount = fake_system_sloccount( result: NO_INPUT_SLOCCOUNT_OUTPUT, process_status: failed_process_status ) expect{ SLOCCountScanner.new(system_sloccount).scan("my_directory") } .to raise_error SLOCCountScanner::NoInput end def fake_system_sloccount(result: nil, process_status: successful_process_status, available: true) instance_double('SystemSLOCCount').tap do |fake| allow(fake).to receive(:call).and_return [result, process_status] allow(fake).to receive(:available?).and_return(available) end end def stub_dir_exists allow(Dir).to receive(:exist?).and_return(true) end ZERO_SLOCCOUNT_OUTPUT = <<-EOS.heredoc_unindent filelist for tmp Categorizing files. Computing results. SLOC Directory SLOC-by-Language (Sorted) 0 tmp (none) SLOC total is zero, no further analysis performed. EOS NO_INPUT_SLOCCOUNT_OUTPUT = "Error: You must provide a directory or directories of source code.\n".freeze end end