shared_examples 'default trakcer attributes' do it { expect(tracker.global_time).to eql 0 } it { expect(tracker.test_files_with_time).to eql({}) } it { expect(tracker.prerun_tests_loaded).to be false } end describe KnapsackPro::Tracker do let(:adapter) { 'RSpecAdapter' } let(:tracker) { described_class.send(:new) } before do allow(KnapsackPro::Config::Env).to receive(:test_runner_adapter).and_return(adapter) allow(KnapsackPro::Config::Env).to receive(:ci_node_index).and_return(0) end it_behaves_like 'default trakcer attributes' describe '#current_test_path' do subject { tracker.current_test_path } context 'when current_test_path not set' do it { should eql nil } end context 'when current_test_path set' do context 'when current_test_path has prefix ./' do before { tracker.current_test_path = './spec/models/user_spec.rb' } it { should eql 'spec/models/user_spec.rb' } end context 'when current_test_path has no prefix ./' do before { tracker.current_test_path = 'spec/models/user_spec.rb' } it { should eql 'spec/models/user_spec.rb' } end end end describe 'track time execution' do let(:test_paths) { ['a_spec.rb', 'b_spec.rb'] } let(:delta) { 0.02 } before do tracker.set_prerun_tests(test_paths) end shared_examples '#to_a' do subject { tracker.to_a } its(:size) { should eq 2 } it { expect(subject[0][:path]).to eq 'a_spec.rb' } it { expect(subject[0][:time_execution]).to be >= 0 } it { expect(subject[1][:path]).to eq 'b_spec.rb' } it { expect(subject[1][:time_execution]).to be >= 0 } end context 'without Timecop' do before do test_paths.each_with_index do |test_path, index| tracker.current_test_path = test_path tracker.start_timer sleep index.to_f / 10 + 0.1 tracker.stop_timer end end it { expect(tracker.global_time).to be_within(delta).of(0.3) } it { expect(tracker.prerun_tests_loaded).to be true } it { expect(tracker.test_files_with_time.keys.size).to eql 2 } it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0.1) } it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0.2) } it_behaves_like '#to_a' end context "with Timecop - Timecop shouldn't have impact on the measured test time" do let(:now) { Time.now } before do test_paths.each_with_index do |test_path, index| Timecop.freeze(now) do tracker.current_test_path = test_path tracker.start_timer end delay = index + 1 Timecop.freeze(now+delay) do tracker.stop_timer end end end it { expect(tracker.global_time).to be > 0 } it { expect(tracker.global_time).to be_within(delta).of(0) } it { expect(tracker.prerun_tests_loaded).to be true } it { expect(tracker.test_files_with_time.keys.size).to eql 2 } it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0) } it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0) } it_behaves_like '#to_a' end # https://github.com/KnapsackPro/knapsack_pro-ruby/issues/32 context 'when start timer was not called (rspec-retry issue)' do before do test_paths.each_with_index do |test_path, index| tracker.current_test_path = test_path sleep 0.001 tracker.stop_timer end end it { expect(tracker.global_time).to be > 0 } it { expect(tracker.prerun_tests_loaded).to be true } it { expect(tracker.test_files_with_time.keys.size).to eql 2 } it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to eq 0 } it '2nd spec (b_spec.rb) should have recorded time execution - because start_time was set during first call of stop_timer for the first spec (a_spec.rb)' do expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be > 0 end it_behaves_like '#to_a' end context 'when a new tracker instance is created' do let(:non_pending_test_paths) { ['a_spec.rb', 'b_spec.rb'] } let(:test_paths) { non_pending_test_paths + ['pending_spec.rb'] } before do # measure tests only for non pending tests non_pending_test_paths.each_with_index do |test_path, index| tracker.current_test_path = test_path tracker.start_timer sleep index.to_f / 10 + 0.1 tracker.stop_timer end end it '2nd tracker instance loads prerun tests from the disk' do expect(tracker.prerun_tests_loaded).to be true expect(tracker.to_a.size).to eq 3 expect(tracker.to_a[0][:path]).to eq 'a_spec.rb' expect(tracker.to_a[0][:time_execution]).to be >= 0 expect(tracker.to_a[1][:path]).to eq 'b_spec.rb' expect(tracker.to_a[1][:time_execution]).to be >= 0 expect(tracker.to_a[2][:path]).to eq 'pending_spec.rb' expect(tracker.to_a[2][:time_execution]).to eq 0 tracker2 = described_class.send(:new) expect(tracker2.prerun_tests_loaded).to be false expect(tracker2.to_a.size).to eq 3 expect(tracker2.to_a[0][:path]).to eq 'a_spec.rb' expect(tracker2.to_a[0][:time_execution]).to be >= 0 expect(tracker2.to_a[1][:path]).to eq 'b_spec.rb' expect(tracker2.to_a[1][:time_execution]).to be >= 0 expect(tracker2.to_a[2][:path]).to eq 'pending_spec.rb' expect(tracker2.to_a[2][:time_execution]).to eq 0 expect(tracker2.prerun_tests_loaded).to be true end end end describe '#reset!' do let(:test_file_path) { 'a_spec.rb' } before do tracker.set_prerun_tests([test_file_path]) end before do expect(tracker.prerun_tests_loaded).to be true tracker.current_test_path = test_file_path tracker.start_timer sleep 0.1 tracker.stop_timer expect(tracker.global_time).not_to eql 0 tracker.reset! end it_behaves_like 'default trakcer attributes' it 'resets prerun_tests_loaded to false' do expect(tracker.prerun_tests_loaded).to be false end end end