2014-08-10 17:04:05 -04:00
|
|
|
RSpec.describe Mutant::Isolation::None do
|
2014-07-05 22:11:31 -04:00
|
|
|
before do
|
|
|
|
@initial = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.run' do
|
|
|
|
let(:object) { described_class }
|
|
|
|
|
|
|
|
it 'does not isolate side effects' do
|
|
|
|
object.call { @initial = 2 }
|
|
|
|
expect(@initial).to be(2)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'return block value' do
|
|
|
|
expect(object.call { :foo }).to be(:foo)
|
|
|
|
end
|
|
|
|
|
2014-07-05 23:12:44 -04:00
|
|
|
it 'wraps *all* exceptions' do
|
|
|
|
expect { object.call { fail } }.to raise_error(Mutant::Isolation::Error)
|
|
|
|
end
|
|
|
|
|
2014-07-05 22:11:31 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-10 17:04:05 -04:00
|
|
|
RSpec.describe Mutant::Isolation::Fork do
|
2014-07-05 22:11:31 -04:00
|
|
|
before do
|
|
|
|
@initial = 1
|
|
|
|
end
|
|
|
|
|
2014-06-24 20:13:24 -04:00
|
|
|
describe '.run' do
|
2014-06-08 13:55:13 -04:00
|
|
|
let(:object) { described_class }
|
|
|
|
|
2014-07-05 22:11:31 -04:00
|
|
|
it 'does isolate side effects' do
|
|
|
|
object.call { @initial = 2 }
|
|
|
|
expect(@initial).to be(1)
|
2014-06-09 11:36:00 -04:00
|
|
|
end
|
|
|
|
|
2014-06-24 20:13:24 -04:00
|
|
|
it 'return block value' do
|
|
|
|
expect(object.call { :foo }).to be(:foo)
|
2014-06-08 13:55:13 -04:00
|
|
|
end
|
|
|
|
|
2014-10-24 17:34:33 -04:00
|
|
|
it 'wraps exceptions' do
|
2014-12-08 17:58:18 -05:00
|
|
|
expect { object.call { fail } }.to raise_error(Mutant::Isolation::Error, 'marshal data too short')
|
2014-07-05 23:12:44 -04:00
|
|
|
end
|
|
|
|
|
2014-10-24 17:34:33 -04:00
|
|
|
it 'wraps exceptions caused by crashing ruby' do
|
2014-10-17 17:51:36 -04:00
|
|
|
expect do
|
|
|
|
object.call do
|
|
|
|
fail RbBug.call
|
|
|
|
end
|
|
|
|
end.to raise_error(Mutant::Isolation::Error)
|
|
|
|
end
|
|
|
|
|
2014-10-24 17:34:33 -04:00
|
|
|
it 'redirects $stderr of children to /dev/null' do
|
|
|
|
begin
|
|
|
|
Tempfile.open('mutant-test') do |file|
|
|
|
|
$stderr = file
|
|
|
|
object.call { $stderr.puts('test') }
|
|
|
|
file.rewind
|
|
|
|
expect(file.read).to eql('')
|
|
|
|
end
|
|
|
|
ensure
|
|
|
|
$stderr = STDERR
|
|
|
|
end
|
|
|
|
end
|
2014-11-17 11:23:12 -05:00
|
|
|
|
|
|
|
# Spec stubbing out the fork to ensure all lines are covered
|
|
|
|
# with expectations
|
|
|
|
it 'covers all lines' do
|
|
|
|
reader, writer = double('reader'), double('writer')
|
|
|
|
expect(IO).to receive(:pipe).ordered.and_return([reader, writer])
|
2014-12-08 17:57:53 -05:00
|
|
|
expect(reader).to receive(:binmode).and_return(reader).ordered
|
|
|
|
expect(writer).to receive(:binmode).and_return(writer).ordered
|
2014-11-17 11:23:12 -05:00
|
|
|
pid = double('PID')
|
|
|
|
expect(Process).to receive(:fork).ordered.and_yield.and_return(pid)
|
|
|
|
file = double('file')
|
|
|
|
expect(File).to receive(:open).ordered.with('/dev/null', 'w').and_yield(file)
|
|
|
|
expect($stderr).to receive(:reopen).ordered.with(file)
|
|
|
|
expect(reader).to receive(:close).ordered
|
|
|
|
expect(writer).to receive(:write).ordered.with(Marshal.dump(:foo))
|
|
|
|
expect(writer).to receive(:close).ordered
|
|
|
|
expect(writer).to receive(:close).ordered
|
|
|
|
expect(reader).to receive(:read).ordered.and_return(Marshal.dump(:foo))
|
|
|
|
expect(Process).to receive(:waitpid).with(pid)
|
|
|
|
|
|
|
|
expect(object.call { :foo }).to be(:foo)
|
|
|
|
end
|
2014-06-08 13:55:13 -04:00
|
|
|
end
|
|
|
|
end
|