From b4fdc7b7c642be77d34c785d1fcae0047c25294e Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Sun, 25 Nov 2018 21:43:35 +0000 Subject: [PATCH] Add Mutant::Timer --- lib/mutant.rb | 1 + lib/mutant/timer.rb | 21 ++++++++++ spec/unit/mutant/clock_monotonic_spec.rb | 52 ++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 lib/mutant/timer.rb create mode 100644 spec/unit/mutant/clock_monotonic_spec.rb diff --git a/lib/mutant.rb b/lib/mutant.rb index 2bbefeaf..15abd01a 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -177,6 +177,7 @@ require 'mutant/expression/method' require 'mutant/expression/methods' require 'mutant/expression/namespace' require 'mutant/test' +require 'mutant/timer' require 'mutant/integration' require 'mutant/selector' require 'mutant/selector/expression' diff --git a/lib/mutant/timer.rb b/lib/mutant/timer.rb new file mode 100644 index 00000000..db1a31e1 --- /dev/null +++ b/lib/mutant/timer.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Mutant + module Timer + # Monotonic elapsed time of block execution + # + # @return [Float] + def self.elapsed + start = now + yield + now - start + end + + # The now monotonic time + # + # @return [Float] + def self.now + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + end # Timer +end # Mutant diff --git a/spec/unit/mutant/clock_monotonic_spec.rb b/spec/unit/mutant/clock_monotonic_spec.rb new file mode 100644 index 00000000..c171b872 --- /dev/null +++ b/spec/unit/mutant/clock_monotonic_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +RSpec.describe Mutant::Timer do + let(:events) { [] } + + let(:times) { [1.0, 2.0] } + + before do + allow(Process).to receive(:clock_gettime) do |argument| + expect(argument).to be(Process::CLOCK_MONOTONIC) + + events << :clock_gettime + + times.fetch(events.count(:clock_gettime).pred) + end + end + + describe '.elapsed' do + def apply + described_class.elapsed { events << :yield } + end + + it 'executes events in expected sequence' do + expect { apply } + .to change(events, :to_a) + .from([]) + .to(%i[clock_gettime yield clock_gettime]) + end + + it 'returns elapsed time' do + expect(apply).to be(1.0) + end + end + + describe '.now' do + def apply + described_class.now + end + + it 'returns current monotonic time' do + expect(apply).to be(1.0) + expect(apply).to be(2.0) + end + + it 'calls expected system API' do + expect { apply } + .to change(events, :to_a) + .from([]) + .to(%i[clock_gettime]) + end + end +end