From ec55f858045f3215951907d57a61279266575b90 Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Sun, 1 Dec 2013 20:34:19 +0100 Subject: [PATCH] Do not emit mutations if signed zero float/double There are two representations of zero in IEEE 754. The negative and the positive zero. This commutis removes a mutation that causes the sign to be flipped. These mutations are very uneasy to kill. Currently only these side effects are known: 1 / -0.0 => -Infinity 1 / 0.0 => Infinity 0.0.to_s => "0.0" -0.0.to_s => "-0.0" I'm happy to readd the mutation - when someone adds more wisdom to this case ;) Closes #126 --- lib/mutant/mutator/node/literal/float.rb | 6 +- .../mutant/mutator/node/literal/float_spec.rb | 67 ++++++++++++++----- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/lib/mutant/mutator/node/literal/float.rb b/lib/mutant/mutator/node/literal/float.rb index 3290281a..af3e5f89 100644 --- a/lib/mutant/mutator/node/literal/float.rb +++ b/lib/mutant/mutator/node/literal/float.rb @@ -49,7 +49,11 @@ module Mutant # @api private # def values - [0.0, 1.0, -children.first] + original = children.first + # Work around a bug in RBX/MRI or JRUBY: + [0.0, 1.0, -original].delete_if do |value| + value.eql?(original) + end end end # Float diff --git a/spec/unit/mutant/mutator/node/literal/float_spec.rb b/spec/unit/mutant/mutator/node/literal/float_spec.rb index 2b9f0d04..0b6c9259 100644 --- a/spec/unit/mutant/mutator/node/literal/float_spec.rb +++ b/spec/unit/mutant/mutator/node/literal/float_spec.rb @@ -3,25 +3,60 @@ require 'spec_helper' describe Mutant::Mutator::Node::Literal, 'float' do - let(:source) { '10.0' } - - let(:mutations) do - mutations = [] - mutations << 'nil' - mutations << '0.0' - mutations << '1.0' - mutations << random_float.to_s - mutations << '(0.0 / 0.0)' - mutations << '(1.0 / 0.0)' - mutations << '(-1.0 / 0.0)' - mutations << '-10.0' - end - - let(:random_float) { 7.123 } before do Mutant::Random.stub(float: random_float) end - it_should_behave_like 'a mutator' + let(:random_float) { 7.123 } + + context 'positive number' do + let(:source) { '10.0' } + + let(:mutations) do + mutations = [] + mutations << 'nil' + mutations << '0.0' + mutations << '1.0' + mutations << random_float.to_s + mutations << '(0.0 / 0.0)' + mutations << '(1.0 / 0.0)' + mutations << '(-1.0 / 0.0)' + mutations << '-10.0' + end + + it_should_behave_like 'a mutator' + end + + context '0.0' do + let(:source) { '0.0' } + + let(:mutations) do + mutations = [] + mutations << 'nil' + mutations << '1.0' + mutations << random_float.to_s + mutations << '(0.0 / 0.0)' + mutations << '(1.0 / 0.0)' + mutations << '(-1.0 / 0.0)' + end + + it_should_behave_like 'a mutator' + end + + context '-0.0' do + let(:source) { '-0.0' } + + let(:mutations) do + mutations = [] + mutations << 'nil' + mutations << '1.0' + mutations << random_float.to_s + mutations << '(0.0 / 0.0)' + mutations << '(1.0 / 0.0)' + mutations << '(-1.0 / 0.0)' + end + + it_should_behave_like 'a mutator' + end end