diff --git a/.rubocop.yml b/.rubocop.yml index 9e2b76b..6e2ceb7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,5 @@ inherit_from: .rubocop_todo.yml +require: rubocop-rspec AllCops: NewCops: enable diff --git a/heartcheck.gemspec b/heartcheck.gemspec index cf9adea..99a0814 100644 --- a/heartcheck.gemspec +++ b/heartcheck.gemspec @@ -14,6 +14,8 @@ Gem::Specification.new do |spec| spec.description = 'A simple way to check your app heart.' spec.license = 'MIT' + spec.metadata['rubygems_mfa_required'] = 'true' + spec.files = `git ls-files -z`.split("\x0").reject do |f| f.match(%r{^(test|spec|features)/}) end @@ -35,6 +37,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rake' spec.add_development_dependency 'rspec', '~> 3.5.0' spec.add_development_dependency 'rubocop' + spec.add_development_dependency 'rubocop-rspec' spec.add_development_dependency 'rubycritic' spec.add_development_dependency 'thor', '~> 0.19.1' spec.add_development_dependency 'yard', '~> 0.9.5' diff --git a/spec/lib/heartcheck/app_spec.rb b/spec/lib/heartcheck/app_spec.rb index eeaf799..7fb952e 100644 --- a/spec/lib/heartcheck/app_spec.rb +++ b/spec/lib/heartcheck/app_spec.rb @@ -6,9 +6,10 @@ describe Heartcheck::App do include Rack::Test::Methods - let(:app) { described_class.new } subject { last_response } + let(:app) { described_class.new } + describe '#body' do subject { super().body } @@ -25,21 +26,23 @@ it { is_expected.to eq(200) } end - context 'on GET /functional' do + context 'with GET /functional' do before { get '/functional' } describe '#body' do subject { super().body } + it { is_expected.to eq('[]') } end describe '#status' do subject { super().status } + it { is_expected.to eq(200) } end end - context 'on GET /dev' do + context 'with GET /dev' do before do Heartcheck.setup do |monitor| log = Logger.new($stdout) @@ -55,54 +58,62 @@ it 'has execution_time' do expect(subject.body).to match(/"execution_time":"([0-9]{1,2}).([0-9]{2}) ms"/) end + it 'has total_execution_time' do expect(subject.body).to match(/"total_execution_time":"([0-9]{1,2}).([0-9]{2}) ms"/) end describe '#status' do subject { super().status } + it { is_expected.to eq(200) } end end - context 'on GET info' do + context 'with GET info' do before { get '/info' } describe '#body' do subject { super().body } + it { is_expected.to eq('[]') } end describe '#status' do subject { super().status } + it { is_expected.to eq(200) } end end - context 'on GET health_check' do + context 'with GET health_check' do before { get '/health_check' } describe '#body' do subject { super().body } + it { is_expected.to eq(MultiJson.dump({ status: 'ok' })) } end describe '#status' do subject { super().status } + it { is_expected.to eq(200) } end end - context 'on GET other routes' do + context 'with GET other routes' do before { get '/lorem' } describe '#body' do subject { super().body } + it { is_expected.to eq('Not found') } end describe '#status' do subject { super().status } + it { is_expected.to eq(404) } end end diff --git a/spec/lib/heartcheck/caching_app_spec.rb b/spec/lib/heartcheck/caching_app_spec.rb index 89f4942..54e8c58 100644 --- a/spec/lib/heartcheck/caching_app_spec.rb +++ b/spec/lib/heartcheck/caching_app_spec.rb @@ -9,8 +9,8 @@ module Heartcheck let(:app) { described_class.new(super_app, ttl, cache) } let(:ttl) { 5 } - let(:cache) { double(Heartcheck::CachingApp::Cache) } - let(:super_app) { double(Heartcheck::App) } + let(:cache) { instance_double(Heartcheck::CachingApp::Cache) } + let(:super_app) { instance_double(Heartcheck::App) } let(:controller) { Heartcheck::Controllers::Essential } let(:response) { [200, { 'Content-type' => 'application/json' }, ['[]']] } @@ -61,7 +61,7 @@ module Heartcheck end end - context 'on an unknown route' do + context 'with an unknown route' do it 'forwards to the original app' do get '/not-found' diff --git a/spec/lib/heartcheck/checks/base_spec.rb b/spec/lib/heartcheck/checks/base_spec.rb index 841ad0f..d8f28fc 100644 --- a/spec/lib/heartcheck/checks/base_spec.rb +++ b/spec/lib/heartcheck/checks/base_spec.rb @@ -80,36 +80,40 @@ end describe '#functional?' do - context 'default is false' do + context 'when functional is not set' do describe '#functional?' do subject { super().functional? } + it { is_expected.to be_falsey } end end - context 'can change value' do + context 'when functional is set to true' do before { base.functional = true } describe '#functional?' do subject { super().functional? } + it { is_expected.to be_truthy } end end end describe '#dev?' do - context 'default is false' do + context 'when dev is not set' do describe '#dev?' do subject { super().dev? } + it { is_expected.to be_falsey } end end - context 'can change value' do + context 'when dev is set to true' do before { base.dev = true } describe '#dev?' do subject { super().dev? } + it { is_expected.to be_truthy } end end @@ -120,6 +124,7 @@ context 'with success' do before { allow(subject).to receive(:validate) } + it 'returns empty array' do expect(subject.check).to eq('base' => { 'status' => 'ok' }) end @@ -143,7 +148,7 @@ ) end - it 'should not accumulate errors' do + it 'does not accumulate errors' do subject.check expect(subject.check).to eq( 'base' => { @@ -195,24 +200,23 @@ context 'without error' do let(:response) { { 'version' => '1234' } } + before do allow(subject).to receive(:info).and_return(response) end - it 'should show a response' do + it 'shows a response' do expect(subject.informations).to eq(response) end end end describe '#uri_info' do - context 'for the base class' do - it 'returns a hash with an error message' do - expect(subject.uri_info).to include(:error) - expect(subject.uri_info).not_to include(:host) - expect(subject.uri_info).not_to include(:port) - expect(subject.uri_info).not_to include(:schema) - end + it 'returns a hash with an error message' do + expect(subject.uri_info).to include(:error) + expect(subject.uri_info).not_to include(:host) + expect(subject.uri_info).not_to include(:port) + expect(subject.uri_info).not_to include(:schema) end end end diff --git a/spec/lib/heartcheck/checks/firewall_spec.rb b/spec/lib/heartcheck/checks/firewall_spec.rb index 9fbe76d..b75f1b6 100644 --- a/spec/lib/heartcheck/checks/firewall_spec.rb +++ b/spec/lib/heartcheck/checks/firewall_spec.rb @@ -40,7 +40,7 @@ context 'without proxy' do context 'with success' do - let(:telnet) { double(Net::Telnet, close: true) } + let(:telnet) { instance_double(Net::Telnet, close: true) } let(:params) { { 'Port' => 443, 'Host' => 'lala.com', 'Timeout' => 2 } } it 'calls Net::Telnet with valid params' do @@ -50,7 +50,7 @@ end end - context 'with success' do + context 'without success' do before { allow(Net::Telnet).to receive(:new).and_raise(Timeout::Error.new) } it 'adds error message' do @@ -72,16 +72,16 @@ end context 'with proxy' do - let(:host) { 'lala.com' } - let(:port) { 443 } - let(:proxy) { 'http://uriproxy.com.br:8888' } - subject do described_class.new.tap do |c| c.add_service(port: port, host: host, proxy: proxy) end end + let(:host) { 'lala.com' } + let(:port) { 443 } + let(:proxy) { 'http://uriproxy.com.br:8888' } + it 'calls Net::Telnet with valid params of proxy' do expect(Net::Telnet).to receive(:new).with('Port' => 8888, 'Host' => 'uriproxy.com.br', 'Timeout' => 2).ordered.and_return('proxy') @@ -91,7 +91,7 @@ subject.validate end - context 'connection refused' do + context 'when getting connection is refused' do it 'avoid to adds errors array' do expect(Net::Telnet).to receive(:new).and_raise Errno::ECONNREFUSED.new subject.validate @@ -100,7 +100,7 @@ end end - context 'timeout' do + context 'when running into a timeout' do let(:proxy_uri) { 'uriproxy.com.br:8888' } let(:error_msg) do "connection refused on: #{host}:443 using proxy: #{proxy_uri}" diff --git a/spec/lib/heartcheck/checks/process_spec.rb b/spec/lib/heartcheck/checks/process_spec.rb index e5fb7d2..5263c87 100644 --- a/spec/lib/heartcheck/checks/process_spec.rb +++ b/spec/lib/heartcheck/checks/process_spec.rb @@ -3,9 +3,10 @@ require 'spec_helper' describe Heartcheck::Checks::Process do - let(:opts) { { name: 'worker', file: 'spec/fixtures/files/worker.pid' } } subject { described_class.new.tap { |c| c.add_service(opts) } } + let(:opts) { { name: 'worker', file: 'spec/fixtures/files/worker.pid' } } + describe '#validate' do context 'with success' do it 'calls process kill 0' do diff --git a/spec/lib/heartcheck/checks/watch_file_spec.rb b/spec/lib/heartcheck/checks/watch_file_spec.rb index 9209e22..67bbb44 100644 --- a/spec/lib/heartcheck/checks/watch_file_spec.rb +++ b/spec/lib/heartcheck/checks/watch_file_spec.rb @@ -8,14 +8,14 @@ end describe '#validate' do - context 'the watched file as no modifications' do + context 'when the watched file as no modifications' do it 'array errors should be empty' do subject.validate expect(subject.instance_variable_get(:@errors)).to be_empty end end - context 'the watched file have new modifications' do + context 'when the watched file have new modifications' do it 'array erros should not be empty' do allow(subject).to receive(:installed).and_return({ bacon: true }) expect { subject.validate } diff --git a/spec/lib/heartcheck/controllers/environment_spec.rb b/spec/lib/heartcheck/controllers/environment_spec.rb index 9837a51..4a7a5ae 100644 --- a/spec/lib/heartcheck/controllers/environment_spec.rb +++ b/spec/lib/heartcheck/controllers/environment_spec.rb @@ -13,14 +13,24 @@ module Controllers let(:system_info_example) { Struct.new(:example_key).new('example_value') } - context 'given Rails is used' do + context 'when Rails is used' do before do stub_const('Rails::VERSION::STRING', '5.0.0') end + let(:rails_version) do + MultiJson.load(controller.index, symbolize_keys: true)[:rails_version] + end + let(:ruby_version) do + MultiJson.load(controller.index, symbolize_keys: true)[:ruby_version] + end + let(:system_info) do + MultiJson.load(controller.index, symbolize_keys: true)[:system_info] + end + it 'gets info from the right constants and functions' do allow(Sys::Uname).to receive(:uname).and_return(system_info_example) - is_expected.to include( + expect(subject).to include( system_info: { example_key: 'example_value' }, ruby_version: '2.4.0', rails_version: '5.0.0' @@ -28,18 +38,6 @@ module Controllers expect(Sys::Uname).to have_received(:uname) end - let(:system_info) do - MultiJson.load(controller.index, symbolize_keys: true)[:system_info] - end - - let(:ruby_version) do - MultiJson.load(controller.index, symbolize_keys: true)[:ruby_version] - end - - let(:rails_version) do - MultiJson.load(controller.index, symbolize_keys: true)[:rails_version] - end - it 'gets the info in the expected format' do expect(system_info).to be_a(Hash) expect(system_info).to include( @@ -61,10 +59,10 @@ module Controllers end end - context 'given Rails is not used' do + context 'when Rails is not used' do it 'gets the info indicating Rails is not used' do allow(Sys::Uname).to receive(:uname).and_return(system_info_example) - is_expected.to include( + expect(subject).to include( system_info: { example_key: 'example_value' }, ruby_version: '2.4.0', rails_version: '(none)' diff --git a/spec/lib/heartcheck/executors/base_spec.rb b/spec/lib/heartcheck/executors/base_spec.rb index 4149dbf..12883b5 100644 --- a/spec/lib/heartcheck/executors/base_spec.rb +++ b/spec/lib/heartcheck/executors/base_spec.rb @@ -16,18 +16,16 @@ module Executors end end - it 'should register a log entry for each checker' do + it 'registers a log entry for each checker' do expect(Logger).to receive(:info).exactly(registered).times subject.dispatch(checkers) end - it 'should have a :time key in the checker response' do - subject.dispatch(checkers).each do |current| - expect(current).to include(:time) - end + it 'has a :time key in the checker response' do + expect(subject.dispatch(checkers)).to all(include(:time)) end - it 'should have a float value (time key)' do + it 'has a float value (time key)' do subject.dispatch(checkers).each do |current| expect(current[:time]).to be_a(Float) end diff --git a/spec/lib/heartcheck/executors/threaded_spec.rb b/spec/lib/heartcheck/executors/threaded_spec.rb index ac54ccd..6bad0b4 100644 --- a/spec/lib/heartcheck/executors/threaded_spec.rb +++ b/spec/lib/heartcheck/executors/threaded_spec.rb @@ -22,18 +22,16 @@ module Executors end end - it 'should register a log entry for each checker' do + it 'registers a log entry for each checker' do expect(Logger).to receive(:info).exactly(registered).times subject.dispatch(checkers) end - it 'should have a :time key in the checker response' do - subject.dispatch(checkers).each do |current| - expect(current).to include(:time) - end + it 'has a :time key in the checker response' do + expect(subject.dispatch(checkers)).to all(include(:time)) end - it 'should have a float value (time key)' do + it 'has a float value (time key)' do subject.dispatch(checkers).each do |current| expect(current[:time]).to be_a(Float) end diff --git a/spec/lib/heartcheck_spec.rb b/spec/lib/heartcheck_spec.rb index 0328abf..43230e9 100644 --- a/spec/lib/heartcheck_spec.rb +++ b/spec/lib/heartcheck_spec.rb @@ -25,7 +25,8 @@ describe '#format' do context 'with default' do - before(:each) { described_class.instance_variable_set :@formatter, nil } + before { described_class.instance_variable_set :@formatter, nil } + it 'returns a Heartcheck::Formatters::Base' do described_class.setup do |monitor| expect(monitor.formatter).to be_a(Heartcheck::Formatters::Base) @@ -34,7 +35,8 @@ end context 'with hash formatter' do - before(:each) { described_class.instance_variable_set :@formatter, nil } + before { described_class.instance_variable_set :@formatter, nil } + it 'returns a Heartcheck::Formatters::Base' do described_class.setup do |monitor| described_class.use_hash_formatter! @@ -61,7 +63,7 @@ end context 'with threaded' do - it 'returns a threaded executor' do + it 'returns a threaded executor' do described_class.use_threaded_executor! expect(described_class.executor).to be_a(Heartcheck::Executors::Threaded) end @@ -96,9 +98,8 @@ subject(:add) { described_class.add(name, &blk) } let(:name) { :process } - let(:plugin) { Heartcheck::Checks::Process.new } - let(:blk) { ->(_) {} } + let(:plugin) { Heartcheck::Checks::Process.new } before do allow(Heartcheck::Checks::Process).to receive(:new) @@ -107,7 +108,7 @@ end it 'returns the built instance' do - is_expected.to eq([plugin]) + expect(subject).to eq([plugin]) end it 'adds to context list' do @@ -118,12 +119,14 @@ ) end - let(:blk) { ->(c) { c.this_is_terrible } } + context 'with code in the block argument' do + let(:blk) { ->(c) { c.this_is_terrible } } - it 'instantiates the class passing the given block' do - expect(plugin).to receive(:this_is_terrible) + it 'instantiates the class passing the given block' do + expect(plugin).to receive(:this_is_terrible) - add + add + end end end end