From d74204f93cefbbb94c4c187a067107d583582210 Mon Sep 17 00:00:00 2001 From: Justin Howard Date: Thu, 28 Jul 2022 23:01:26 -0700 Subject: [PATCH] Update rubocop cleanup gemspec --- .github/workflows/ci.yml | 19 +- .rubocop.yml | 206 ++++++++++++---------- .yamllint.yml | 6 + Gemfile | 6 +- faulty.gemspec | 13 +- lib/faulty/circuit.rb | 6 +- lib/faulty/deprecation.rb | 2 +- lib/faulty/patch/base.rb | 4 +- lib/faulty/patch/redis.rb | 6 +- lib/faulty/status.rb | 4 +- lib/faulty/storage/redis.rb | 16 +- spec/cache/circuit_proxy_spec.rb | 4 +- spec/cache/fault_tolerant_proxy_spec.rb | 4 +- spec/cache/mock_spec.rb | 2 +- spec/cache/null_spec.rb | 4 +- spec/circuit_spec.rb | 32 ++-- spec/faulty_spec.rb | 6 +- spec/immutable_options_spec.rb | 2 +- spec/patch/elasticsearch_spec.rb | 2 +- spec/patch/mysql2_spec.rb | 16 +- spec/patch_spec.rb | 2 +- spec/result_spec.rb | 6 +- spec/status_spec.rb | 18 +- spec/storage/circuit_proxy_spec.rb | 2 +- spec/storage/fallback_chain_spec.rb | 12 +- spec/storage/fault_tolerant_proxy_spec.rb | 6 +- 26 files changed, 223 insertions(+), 183 deletions(-) create mode 100644 .yamllint.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2616001..4b38eb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,11 +12,19 @@ jobs: strategy: fail-fast: false matrix: - redis: [4] - ruby: [2.3, 2.4, 2.5, 2.6, 2.7, 3.0, jruby-9.2.10, truffleruby-20.2.0] + ruby: ['2.5', '2.6', '2.7', '3.0', jruby-9.3.6.0, truffleruby-22.2.0] + bundler: [default] + redis: ['4'] include: - - redis: 3 - ruby: 2.7 + - ruby: '2.7' + bundler: 'default' + redis: '3' + - ruby: '2.3' + bundler: '1' + redis: '4' + - ruby: '2.4' + bundler: '1' + redis: '4' services: redis: image: redis @@ -28,12 +36,13 @@ jobs: - 9200:9200 options: -e="discovery.type=single-node" --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=3s --health-timeout=5s --health-retries=20 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 env: REDIS_VERSION: ${{ matrix.redis }} with: ruby-version: ${{ matrix.ruby }} + bundler: ${{ matrix.bundler }} bundler-cache: true - run: bundle exec rubocop if: matrix.ruby == '2.7' diff --git a/.rubocop.yml b/.rubocop.yml index a32170b..f1ea477 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,93 +5,119 @@ require: AllCops: TargetRubyVersion: 2.3 -Layout/ArgumentAlignment: - EnforcedStyle: with_fixed_indentation - -Layout/CaseIndentation: - EnforcedStyle: end - -Layout/ParameterAlignment: - EnforcedStyle: with_fixed_indentation - -Layout/EndAlignment: - EnforcedStyleAlignWith: start_of_line - -Layout/FirstArgumentIndentation: - EnforcedStyle: consistent - -Layout/FirstArrayElementIndentation: - EnforcedStyle: consistent - -Layout/FirstHashElementIndentation: - EnforcedStyle: consistent - -Layout/LineLength: - Max: 120 - -Layout/MultilineMethodCallIndentation: - EnforcedStyle: indented - -Layout/RescueEnsureAlignment: - Enabled: false - -Lint/RaiseException: - Enabled: true - -Lint/StructNewOverride: - Enabled: true - -RSpec/ExampleLength: - Enabled: false - -RSpec/FilePath: - Enabled: false - -RSpec/NamedSubject: - Enabled: false - -RSpec/MessageSpies: - Enabled: false - -RSpec/MultipleExpectations: - Enabled: false - -RSpec/SubjectStub: - Enabled: false - -Metrics/AbcSize: - Max: 35 - -Metrics/BlockLength: - Enabled: false - -Metrics/MethodLength: - Max: 30 - -Naming/MethodParameterName: - MinNameLength: 1 - -Style/Documentation: - Enabled: false - -Style/EmptyMethod: - EnforcedStyle: expanded - -Style/FrozenStringLiteralComment: - Enabled: true - EnforcedStyle: always - -Style/GuardClause: - Enabled: false - -Style/HashEachMethods: - Enabled: true - -Style/HashTransformKeys: - Enabled: false - -Style/HashTransformValues: - Enabled: false - -Style/IfUnlessModifier: - Enabled: false +Gemspec/DeprecatedAttributeAssignment: { Enabled: true } +Gemspec/RequireMFA: { Enabled: true } + +Layout/ArgumentAlignment: { EnforcedStyle: with_fixed_indentation } +Layout/CaseIndentation: { EnforcedStyle: end } +Layout/EndAlignment: { EnforcedStyleAlignWith: start_of_line } +Layout/FirstArgumentIndentation: { EnforcedStyle: consistent } +Layout/FirstArrayElementIndentation: { EnforcedStyle: consistent } +Layout/FirstHashElementIndentation: { EnforcedStyle: consistent } +Layout/LineContinuationLeadingSpace: { Enabled: true } +Layout/LineContinuationSpacing: { Enabled: true } +Layout/LineEndStringConcatenationIndentation: { Enabled: true } +Layout/LineLength: { Max: 120 } +Layout/MultilineMethodCallIndentation: { EnforcedStyle: indented } +Layout/ParameterAlignment: { EnforcedStyle: with_fixed_indentation } +Layout/RescueEnsureAlignment: { Enabled: false } +Layout/SpaceBeforeBrackets: { Enabled: true } + +Lint/AmbiguousAssignment: { Enabled: true } +Lint/AmbiguousOperatorPrecedence: { Enabled: true } +Lint/AmbiguousRange: { Enabled: true } +Lint/ConstantOverwrittenInRescue: { Enabled: true } +Lint/DeprecatedConstants: { Enabled: true } +Lint/DuplicateBranch: { Enabled: true } +Lint/DuplicateRegexpCharacterClassElement: { Enabled: true } +Lint/EmptyBlock: { Enabled: true } +Lint/EmptyClass: { Enabled: true } +Lint/EmptyInPattern: { Enabled: true } +Lint/IncompatibleIoSelectWithFiberScheduler: { Enabled: true } +Lint/LambdaWithoutLiteralBlock: { Enabled: true } +Lint/NoReturnInBeginEndBlocks: { Enabled: true } +Lint/NonAtomicFileOperation: { Enabled: true } +Lint/NumberedParameterAssignment: { Enabled: true } +Lint/OrAssignmentToConstant: { Enabled: true } +Lint/RaiseException: { Enabled: true } +Lint/RedundantDirGlobSort: { Enabled: true } +Lint/RefinementImportMethods: { Enabled: true } +Lint/RequireRangeParentheses: { Enabled: true } +Lint/RequireRelativeSelfPath: { Enabled: true } +Lint/StructNewOverride: { Enabled: true } +Lint/SymbolConversion: { Enabled: true } +Lint/ToEnumArguments: { Enabled: true } +Lint/TripleQuotes: { Enabled: true } +Lint/UnexpectedBlockArity: { Enabled: true } +Lint/UnmodifiedReduceAccumulator: { Enabled: true } +Lint/UselessRuby2Keywords: { Enabled: true } + +RSpec/BeEq: { Enabled: true } +RSpec/BeNil: { Enabled: true } +RSpec/Capybara/SpecificMatcher: { Enabled: true } +RSpec/ChangeByZero: { Enabled: true } +RSpec/ExampleLength: { Enabled: false } +RSpec/ExcessiveDocstringSpacing: { Enabled: true } +RSpec/FactoryBot/SyntaxMethods: { Enabled: true } +RSpec/FilePath: { Enabled: false } +RSpec/IdenticalEqualityAssertion: { Enabled: true } +RSpec/MessageSpies: { Enabled: false } +RSpec/MultipleExpectations: { Enabled: false } +RSpec/MultipleMemoizedHelpers: { Enabled: false } +RSpec/NamedSubject: { Enabled: false } +RSpec/Rails/AvoidSetupHook: { Enabled: true } +RSpec/Rails/HaveHttpStatus: { Enabled: true } +RSpec/SubjectDeclaration: { Enabled: true } +RSpec/SubjectStub: { Enabled: false } +RSpec/VerifiedDoubleReference: { Enabled: true } + +Metrics/AbcSize: { Max: 40 } +Metrics/BlockLength: { Enabled: false } +Metrics/CyclomaticComplexity: { Enabled: false } +Metrics/MethodLength: { Max: 30 } +Metrics/PerceivedComplexity: { Enabled: false } + +Naming/BlockForwarding: { Enabled: true } +Naming/MethodParameterName: { MinNameLength: 1 } + +Security/CompoundHash: { Enabled: true } +Security/IoMethods: { Enabled: true } + +Style/ArgumentsForwarding: { Enabled: true } +Style/CollectionCompact: { Enabled: true } +Style/DocumentDynamicEvalDefinition: { Enabled: true } +Style/Documentation: { Enabled: false } +Style/EmptyHeredoc: { Enabled: true } +Style/EmptyMethod: { EnforcedStyle: expanded } +Style/EndlessMethod: { Enabled: true } +Style/EnvHome: { Enabled: true } +Style/FetchEnvVar: { Enabled: true } +Style/FileRead: { Enabled: true } +Style/FileWrite: { Enabled: true } +Style/FrozenStringLiteralComment: { Enabled: true, EnforcedStyle: always } +Style/GuardClause: { Enabled: false } +Style/HashConversion: { Enabled: true } +Style/HashEachMethods: { Enabled: true } +Style/HashExcept: { Enabled: true } +Style/HashTransformKeys: { Enabled: false } +Style/HashTransformValues: { Enabled: false } +Style/IfUnlessModifier: { Enabled: false } +Style/IfWithBooleanLiteralBranches: { Enabled: true } +Style/InPatternThen: { Enabled: true } +Style/MapCompactWithConditionalBlock: { Enabled: true } +Style/MapToHash: { Enabled: true } +Style/MultilineInPatternThen: { Enabled: true } +Style/NegatedIfElseCondition: { Enabled: true } +Style/NestedFileDirname: { Enabled: true } +Style/NilLambda: { Enabled: true } +Style/NumberedParameters: { Enabled: true } +Style/NumberedParametersLimit: { Enabled: true } +Style/ObjectThen: { Enabled: true } +Style/OpenStructUse: { Enabled: true } +Style/QuotedSymbols: { Enabled: true } +Style/RedundantArgument: { Enabled: true } +Style/RedundantInitialize: { Enabled: true } +Style/RedundantSelfAssignmentBranch: { Enabled: true } +Style/SelectByRegexp: { Enabled: true } +Style/StringChars: { Enabled: true } +Style/SwapValues: { Enabled: true } diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..f2bb985 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,6 @@ +--- +rules: + braces: + min-spaces-inside: 1 + max-spaces-inside: 1 + diff --git a/Gemfile b/Gemfile index 2d56a17..8913709 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,6 @@ gemspec not_jruby = %i[ruby mingw x64_mingw].freeze gem 'activesupport', '>= 4.2' -gem 'bundler', '>= 1.17', '< 3' gem 'byebug', platforms: not_jruby # Open source licensed elasticsearch gem 'elasticsearch', '> 7', '< 7.14' @@ -27,6 +26,11 @@ gem 'simplecov', '>= 0.17.1' gem 'simplecov-lcov', '~> 0.7', '< 0.8' gem 'yard', '~> 0.9.25', platforms: not_jruby +if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') + gem 'rubocop', '~> 1.32.0' + gem 'rubocop-rspec', '~> 2.12' +end + if ENV['REDIS_VERSION'] gem 'redis', "~> #{ENV['REDIS_VERSION']}" end diff --git a/faulty.gemspec b/faulty.gemspec index 0e13ad7..94db015 100644 --- a/faulty.gemspec +++ b/faulty.gemspec @@ -10,13 +10,15 @@ Gem::Specification.new do |spec| spec.authors = ['Justin Howard'] spec.email = ['jmhoward0@gmail.com'] spec.licenses = ['MIT'] - spec.summary = 'Fault-tolerance tools for ruby based on circuit-breakers' spec.homepage = 'https://github.com/ParentSquare/faulty' - spec.files = `git ls-files -z` - .split("\x0") - .reject { |f| f.match(%r{^spec/}) } + rubydoc = 'https://www.rubydoc.info/gems' + spec.metadata['rubygems_mfa_required'] = 'true' + spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/master/CHANGELOG.md" + spec.metadata['documentation_uri'] = "#{rubydoc}/#{spec.name}/#{spec.version}" + + spec.files = Dir['lib/**/*.rb', '*.md', '*.txt', '.yardopts'] spec.require_paths = ['lib'] spec.required_ruby_version = '>= 2.3' @@ -29,8 +31,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'json' spec.add_development_dependency 'redis', '>= 3.0' spec.add_development_dependency 'rspec', '~> 3.8' - # 0.81 is the last rubocop version with Ruby 2.3 support - spec.add_development_dependency 'rubocop', '0.81.0' - spec.add_development_dependency 'rubocop-rspec', '1.38.1' spec.add_development_dependency 'timecop', '>= 0.9' end diff --git a/lib/faulty/circuit.rb b/lib/faulty/circuit.rb index 6522be0..46ef53d 100644 --- a/lib/faulty/circuit.rb +++ b/lib/faulty/circuit.rb @@ -462,15 +462,13 @@ def failure!(status, error) end options.notifier.notify(:circuit_failure, circuit: self, status: status, error: error) - opened = if status.half_open? + if status.half_open? reopen!(error, status.opened_at) elsif status.fails_threshold? open!(error) else false end - - opened end def deprecated_entry? @@ -550,7 +548,7 @@ def cache_write(key, value) # @return [Boolean] true if the cache should be refreshed def cache_should_refresh?(key) time = options.cache.read(cache_refresh_key(key.to_s)).to_i - time + (rand * 2 - 1) * options.cache_refresh_jitter < Faulty.current_time + time + (((rand * 2) - 1) * options.cache_refresh_jitter) < Faulty.current_time end # Get the next time to refresh the cache when writing to it diff --git a/lib/faulty/deprecation.rb b/lib/faulty/deprecation.rb index a737714..69f2fab 100644 --- a/lib/faulty/deprecation.rb +++ b/lib/faulty/deprecation.rb @@ -5,7 +5,7 @@ class Faulty module Deprecation class << self # Call to raise errors instead of logging warnings for Faulty deprecations - def raise_errors!(enabled = true) + def raise_errors!(enabled = true) # rubocop:disable Style/OptionalBooleanParameter @raise_errors = (enabled == true) end diff --git a/lib/faulty/patch/base.rb b/lib/faulty/patch/base.rb index cada00c..f871bee 100644 --- a/lib/faulty/patch/base.rb +++ b/lib/faulty/patch/base.rb @@ -31,13 +31,13 @@ module Base # # @yield A block to run inside the circuit # @return The block return value - def faulty_run + def faulty_run(&block) faulty_running_key = "faulty_running_#{object_id}" return yield unless @faulty_circuit return yield if Thread.current[faulty_running_key] Thread.current[faulty_running_key] = true - @faulty_circuit.run { yield } + @faulty_circuit.run(&block) ensure Thread.current[faulty_running_key] = nil end diff --git a/lib/faulty/patch/redis.rb b/lib/faulty/patch/redis.rb index f375d06..9235642 100644 --- a/lib/faulty/patch/redis.rb +++ b/lib/faulty/patch/redis.rb @@ -81,10 +81,8 @@ def io(&block) return super unless @faulty_circuit reply = super - if reply.is_a?(::Redis::CommandError) - if reply.message.start_with?('BUSY') - reply = BusyError.new(reply.message) - end + if reply.is_a?(::Redis::CommandError) && reply.message.start_with?('BUSY') + reply = BusyError.new(reply.message) end reply diff --git a/lib/faulty/status.rb b/lib/faulty/status.rb index f64f5ec..cdfb392 100644 --- a/lib/faulty/status.rb +++ b/lib/faulty/status.rb @@ -38,7 +38,9 @@ class Faulty :sample_size, :options, :stub - ) do + ) + + class Status include ImmutableOptions # The allowed state values diff --git a/lib/faulty/storage/redis.rb b/lib/faulty/storage/redis.rb index a79e844..eae8442 100644 --- a/lib/faulty/storage/redis.rb +++ b/lib/faulty/storage/redis.rb @@ -354,13 +354,11 @@ def current_list_block # the watch succeeds and the comparison passes # @return [Array] An array of Redis results from the commands executed # inside the block - def watch_exec(key, old) + def watch_exec(key, old, &block) redis do |r| r.watch(key) do if old.include?(r.get(key)) - r.multi do |m| - yield m - end + r.multi(&block) else r.unwatch nil @@ -373,9 +371,9 @@ def watch_exec(key, old) # # @yield [Redis] Yields the connection to the block # @return The value returned from the block - def redis + def redis(&block) if options.client.respond_to?(:with) - options.client.with { |redis| yield redis } + options.client.with(&block) else yield options.client end @@ -385,8 +383,8 @@ def redis # # @yield [Redis::Pipeline] Yields the connection to the block # @return [void] - def pipe - redis { |r| r.pipelined { |p| yield p } } + def pipe(&block) + redis { |r| r.pipelined(&block) } end # Map raw Redis history entries to Faulty format @@ -435,7 +433,7 @@ def check_redis_options! end def check_pool_options! - if options.client.class.name == 'ConnectionPool' + if options.client.instance_of?(ConnectionPool) timeout = options.client.instance_variable_get(:@timeout) warn(<<~MSG) if timeout > 2 Faulty recommends setting ConnectionPool timeouts <= 2 to prevent diff --git a/spec/cache/circuit_proxy_spec.rb b/spec/cache/circuit_proxy_spec.rb index 13e0c4d..2eb3614 100644 --- a/spec/cache/circuit_proxy_spec.rb +++ b/spec/cache/circuit_proxy_spec.rb @@ -6,7 +6,7 @@ let(:failing_cache) do Class.new do - def method_missing(*_args) # rubocop:disable Style/MethodMissingSuper + def method_missing(*_args) raise 'fail' end @@ -38,7 +38,7 @@ def respond_to_missing?(*_args) it 'delegates fault_tolerant? directly' do backend = instance_double(Faulty::Cache::Mock) marker = Object.new - expect(backend).to receive(:fault_tolerant?).and_return(marker) + allow(backend).to receive(:fault_tolerant?).and_return(marker) expect(described_class.new(backend, notifier: notifier).fault_tolerant?).to eq(marker) end end diff --git a/spec/cache/fault_tolerant_proxy_spec.rb b/spec/cache/fault_tolerant_proxy_spec.rb index 3e61517..078980d 100644 --- a/spec/cache/fault_tolerant_proxy_spec.rb +++ b/spec/cache/fault_tolerant_proxy_spec.rb @@ -5,7 +5,7 @@ let(:failing_cache_class) do Class.new do - def method_missing(*_args) # rubocop:disable Style/MethodMissingSuper + def method_missing(*_args) raise 'fail' end @@ -31,7 +31,7 @@ def respond_to_missing?(*_args) expect(notifier).to receive(:notify) .with(:cache_failure, key: 'foo', action: :read, error: instance_of(RuntimeError)) result = described_class.new(failing_cache, notifier: notifier).read('foo') - expect(result).to eq(nil) + expect(result).to be_nil end it 'delegates to backend when writing succeeds' do diff --git a/spec/cache/mock_spec.rb b/spec/cache/mock_spec.rb index a4e06ba..e085348 100644 --- a/spec/cache/mock_spec.rb +++ b/spec/cache/mock_spec.rb @@ -13,7 +13,7 @@ Timecop.travel(Time.now + 5) expect(cache.read('a key')).to eq('a value') Timecop.travel(Time.now + 6) - expect(cache.read('a key')).to eq(nil) + expect(cache.read('a key')).to be_nil end it 'is fault tolerant' do diff --git a/spec/cache/null_spec.rb b/spec/cache/null_spec.rb index 68f459e..612795c 100644 --- a/spec/cache/null_spec.rb +++ b/spec/cache/null_spec.rb @@ -5,10 +5,10 @@ it 'reads nothing after writing' do cache.write('foo', 'bar') - expect(cache.read('foo')).to eq(nil) + expect(cache.read('foo')).to be_nil end it 'is fault_tolerant' do - expect(cache.fault_tolerant?).to eq(true) + expect(cache.fault_tolerant?).to be(true) end end diff --git a/spec/circuit_spec.rb b/spec/circuit_spec.rb index 3063d08..e9e103d 100644 --- a/spec/circuit_spec.rb +++ b/spec/circuit_spec.rb @@ -52,13 +52,13 @@ it 'gets an ok result with try_run' do result = circuit.try_run { 'ok' } - expect(result.ok?).to eq(true) + expect(result.ok?).to be(true) expect(result.get).to eq('ok') end it 'captures an error with try_run' do result = circuit.try_run { raise 'fail' } - expect(result.error?).to eq(true) + expect(result.error?).to be(true) expect(result.error.cause.message).to eq('fail') end @@ -125,39 +125,39 @@ circuit.lock_open! circuit.reset! expect(circuit.history).to eq([]) - expect(circuit.status.closed?).to eq(true) - expect(circuit.status.locked_open?).to eq(false) + expect(circuit.status.closed?).to be(true) + expect(circuit.status.locked_open?).to be(false) end it 'does not close circuit until past sample threshold' do circuit = Faulty::Circuit.new('test', **options.merge(rate_threshold: 0, sample_threshold: 2)) circuit.try_run { raise 'fail' } - expect(circuit.status.closed?).to eq(true) + expect(circuit.status.closed?).to be(true) circuit.try_run { raise 'fail' } - expect(circuit.status.open?).to eq(true) + expect(circuit.status.open?).to be(true) end it 'does not close circuit until past rate threshold' do circuit = Faulty::Circuit.new('test', **options.merge(rate_threshold: 0.6, sample_threshold: 0)) circuit.try_run { 'ok' } circuit.try_run { raise 'fail' } - expect(circuit.status.closed?).to eq(true) + expect(circuit.status.closed?).to be(true) circuit.try_run { raise 'fail' } - expect(circuit.status.open?).to eq(true) + expect(circuit.status.open?).to be(true) end it 'transitions from open to half-open after cool-down elapses' do open_circuit Timecop.freeze(Time.now + 300) - expect(open_circuit.status.half_open?).to eq(true) + expect(open_circuit.status.half_open?).to be(true) end it 'opens circuit if it fails in half-open' do open_circuit Timecop.freeze(Time.now + 300) result = open_circuit.try_run { raise 'fail' } - expect(result.error?).to eq(true) - expect(open_circuit.status.open?).to eq(true) + expect(result.error?).to be(true) + expect(open_circuit.status.open?).to be(true) end it 'closes circuit if it succeeds in half-open' do @@ -165,13 +165,13 @@ Timecop.freeze(Time.now + 300) result = open_circuit.run { 'ok' } expect(result).to eq('ok') - expect(open_circuit.status.closed?).to eq(true) + expect(open_circuit.status.closed?).to be(true) end it 'skips running if open' do ran = false open_circuit.try_run { ran = true } - expect(ran).to eq(false) + expect(ran).to be(false) end it 'reads from the cache if available and does not run' do @@ -207,7 +207,7 @@ result = circuit.run(cache: 'test_cache') { raise 'fail' } expect(result).to eq('cached') # Still records the failure - expect(circuit.history.last[1]).to eq(false) + expect(circuit.history.last[1]).to be(false) end it 'raises unwrapped error if error is excluded' do @@ -277,12 +277,12 @@ it 'gets status without setting options' do circuit.status - expect(storage.get_options(circuit)).to eq(nil) + expect(storage.get_options(circuit)).to be_nil end it 'locks circuit without setting options' do circuit.lock_open! - expect(storage.get_options(circuit)).to eq(nil) + expect(storage.get_options(circuit)).to be_nil end it 'gets default options if not stored' do diff --git a/spec/faulty_spec.rb b/spec/faulty_spec.rb index 81138a0..f8226eb 100644 --- a/spec/faulty_spec.rb +++ b/spec/faulty_spec.rb @@ -94,7 +94,7 @@ described_class.init instance1 = described_class.new instance2 = described_class.new - expect(described_class.register(:named, instance1)).to eq(nil) + expect(described_class.register(:named, instance1)).to be_nil expect(described_class.register(:named, instance2)).to eq(instance1) expect(described_class[:named]).to eq(instance1) end @@ -175,8 +175,8 @@ it 'can be disabled and enabled' do described_class.disable! - expect(described_class.disabled?).to eq(true) + expect(described_class.disabled?).to be(true) described_class.enable! - expect(described_class.disabled?).to eq(false) + expect(described_class.disabled?).to be(false) end end diff --git a/spec/immutable_options_spec.rb b/spec/immutable_options_spec.rb index d6abc2f..8879e2a 100644 --- a/spec/immutable_options_spec.rb +++ b/spec/immutable_options_spec.rb @@ -51,7 +51,7 @@ def finalize if defined?(RUBY_ENGINE) && RUBY_ENGINE != 'truffleruby' it 'freezes options after initialization' do opts = example_class.new(name: 'foo') - expect { opts.name = 'bar' }.to raise_error(/can\'t modify frozen/) + expect { opts.name = 'bar' }.to raise_error(/can't modify frozen/) end end end diff --git a/spec/patch/elasticsearch_spec.rb b/spec/patch/elasticsearch_spec.rb index 9d5e39a..e18c1e1 100644 --- a/spec/patch/elasticsearch_spec.rb +++ b/spec/patch/elasticsearch_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Faulty::Patch::Elasticsearch do let(:faulty) { Faulty.new(listeners: []) } - let(:good_url) { ENV['ELASTICSEARCH_URL'] } + let(:good_url) { ENV.fetch('ELASTICSEARCH_URL', nil) } let(:bad_url) { 'localhost:9876' } let(:patched_good_client) { build_client(url: good_url, faulty: { instance: faulty }) } let(:patched_bad_client) { build_client(url: bad_url, faulty: { instance: faulty }) } diff --git a/spec/patch/mysql2_spec.rb b/spec/patch/mysql2_spec.rb index 1565679..184b59d 100644 --- a/spec/patch/mysql2_spec.rb +++ b/spec/patch/mysql2_spec.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true -RSpec.describe 'Faulty::Patch::Mysql2', if: defined?(Mysql2) do # rubocop:disable RSpec/DescribeClass +RSpec.describe 'Faulty::Patch::Mysql2', if: defined?(Mysql2) do def new_client(opts = {}) Mysql2::Client.new({ - username: ENV['MYSQL_USER'], - password: ENV['MYSQL_PASSWORD'], - host: ENV['MYSQL_HOST'], - port: ENV['MYSQL_PORT'], - socket: ENV['MYSQL_SOCKET'] + username: ENV.fetch('MYSQL_USER', nil), + password: ENV.fetch('MYSQL_PASSWORD', nil), + host: ENV.fetch('MYSQL_HOST', nil), + port: ENV.fetch('MYSQL_PORT', nil), + socket: ENV.fetch('MYSQL_SOCKET', nil) }.merge(opts)) end @@ -76,7 +76,7 @@ def trip_circuit client.query('BEGIN') client.query('INSERT INTO test VALUES(1)') trip_circuit - expect(client.query('COMMIT')).to eq(nil) + expect(client.query('COMMIT')).to be_nil expect { client.query('SELECT * FROM test') } .to raise_error(Faulty::Patch::Mysql2::OpenCircuitError) faulty.circuit('mysql2').reset! @@ -88,7 +88,7 @@ def trip_circuit client.query('BEGIN') client.query('INSERT INTO test VALUES(1)') trip_circuit - expect(client.query('/* hi there */ ROLLBACK')).to eq(nil) + expect(client.query('/* hi there */ ROLLBACK')).to be_nil expect { client.query('SELECT * FROM test') } .to raise_error(Faulty::Patch::Mysql2::OpenCircuitError) faulty.circuit('mysql2').reset! diff --git a/spec/patch_spec.rb b/spec/patch_spec.rb index d530b19..71e8661 100644 --- a/spec/patch_spec.rb +++ b/spec/patch_spec.rb @@ -27,7 +27,7 @@ it 'returns nil if hash is nil' do circuit = described_class.circuit_from_hash('test', nil) - expect(circuit).to eq(nil) + expect(circuit).to be_nil end it 'can specify a custom name' do diff --git a/spec/result_spec.rb b/spec/result_spec.rb index 931a781..bd05c82 100644 --- a/spec/result_spec.rb +++ b/spec/result_spec.rb @@ -5,11 +5,11 @@ let(:error) { described_class.new(error: StandardError.new) } it 'can be constructed with an ok' do - expect(ok.ok?).to eq(true) + expect(ok.ok?).to be(true) end it 'can be constructed with an error' do - expect(error.error?).to eq(true) + expect(error.error?).to be(true) end it 'raises an error if unchecked get is called' do @@ -39,7 +39,7 @@ end it 'does not confuse NOTHING with empty object' do - expect(described_class.new(ok: {}).ok?).to eq(true) + expect(described_class.new(ok: {}).ok?).to be(true) end it 'with ok #or_default passes value through' do diff --git a/spec/status_spec.rb b/spec/status_spec.rb index 59953f8..ccb82e4 100644 --- a/spec/status_spec.rb +++ b/spec/status_spec.rb @@ -13,7 +13,7 @@ it('is closed') { expect(status).to be_closed } it('is not open') { expect(status).not_to be_open } it('is not half_open') { expect(status).not_to be_half_open } - it('can run') { expect(status.can_run?).to eq(true) } + it('can run') { expect(status.can_run?).to be(true) } it('is not locked_open') { expect(status).not_to be_locked_open } it('is not locked_closed') { expect(status).not_to be_locked_closed } end @@ -26,7 +26,7 @@ it('is open') { expect(status).to be_open } it('is not closed') { expect(status).not_to be_closed } it('is not half_open') { expect(status).not_to be_half_open } - it('cannot run') { expect(status.can_run?).to eq(false) } + it('cannot run') { expect(status.can_run?).to be(false) } end context 'when state is open and cool_down is passed' do @@ -37,14 +37,14 @@ it('is half_open') { expect(status).to be_half_open } it('is not open') { expect(status).not_to be_open } it('is not closed') { expect(status).not_to be_closed } - it('can run') { expect(status.can_run?).to eq(true) } + it('can run') { expect(status.can_run?).to be(true) } end context 'when locked open' do subject(:status) { described_class.new(options: options, state: :closed, lock: :open) } it('is locked_open') { expect(status).to be_locked_open } - it('cannot run') { expect(status.can_run?).to eq(false) } + it('cannot run') { expect(status.can_run?).to be(false) } end context 'when locked closed' do @@ -58,31 +58,31 @@ end it('is locked_closed') { expect(status).to be_locked_closed } - it('can run') { expect(status.can_run?).to eq(true) } + it('can run') { expect(status.can_run?).to be(true) } end context 'when sample size is too small' do subject(:status) { described_class.new(options: options, sample_size: 1, failure_rate: 0.99) } - it('passes threshold') { expect(status.fails_threshold?).to eq(false) } + it('passes threshold') { expect(status.fails_threshold?).to be(false) } end context 'when failure rate is below rate_threshold' do subject(:status) { described_class.new(options: options, sample_size: 4, failure_rate: 0.4) } - it('passes threshold') { expect(status.fails_threshold?).to eq(false) } + it('passes threshold') { expect(status.fails_threshold?).to be(false) } end context 'when failure rate is above rate_threshold' do subject(:status) { described_class.new(options: options, sample_size: 4, failure_rate: 0.6) } - it('fails threshold') { expect(status.fails_threshold?).to eq(true) } + it('fails threshold') { expect(status.fails_threshold?).to be(true) } end context 'when failure rate equals rate_threshold' do subject(:status) { described_class.new(options: options, sample_size: 4, failure_rate: 0.5) } - it('fails threshold') { expect(status.fails_threshold?).to eq(true) } + it('fails threshold') { expect(status.fails_threshold?).to be(true) } end it 'rejects invalid state' do diff --git a/spec/storage/circuit_proxy_spec.rb b/spec/storage/circuit_proxy_spec.rb index b65f869..22ea159 100644 --- a/spec/storage/circuit_proxy_spec.rb +++ b/spec/storage/circuit_proxy_spec.rb @@ -7,7 +7,7 @@ let(:failing_storage) do Class.new do - def method_missing(*_args) # rubocop:disable Style/MethodMissingSuper + def method_missing(*_args) raise 'fail' end diff --git a/spec/storage/fallback_chain_spec.rb b/spec/storage/fallback_chain_spec.rb index c714d72..2a3bb35 100644 --- a/spec/storage/fallback_chain_spec.rb +++ b/spec/storage/fallback_chain_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Faulty::Storage::FallbackChain do let(:failing_class) do Class.new do - def method_missing(_method, *_args) # rubocop:disable Style/MethodMissingSuper + def method_missing(_method, *_args) raise 'fail' end @@ -72,8 +72,8 @@ def respond_to_missing?(_method, _include_all = false) context 'with #lock' do it 'delegates to all when successful' do succeeding_chain.lock(circuit, :open) - expect(memory.status(circuit).locked_open?).to eq(true) - expect(memory2.status(circuit).locked_open?).to eq(true) + expect(memory.status(circuit).locked_open?).to be(true) + expect(memory2.status(circuit).locked_open?).to be(true) end it 'continues delegating after failure and raises' do @@ -84,8 +84,8 @@ def respond_to_missing?(_method, _include_all = false) 'Faulty::Storage::FallbackChain#lock failed for some storage backends: fail' ) - expect(memory.status(circuit).locked_open?).to eq(true) - expect(memory2.status(circuit).locked_open?).to eq(true) + expect(memory.status(circuit).locked_open?).to be(true) + expect(memory2.status(circuit).locked_open?).to be(true) end it 'raises error if all storages fail' do @@ -127,7 +127,7 @@ def respond_to_missing?(_method, _include_all = false) args.empty? ? expected.with(no_args) : expected.with(*args) expect(memory).to expected expect(memory2).to expected - expect(chain.public_send(action, *args)).to eq(nil) + expect(chain.public_send(action, *args)).to be_nil end end diff --git a/spec/storage/fault_tolerant_proxy_spec.rb b/spec/storage/fault_tolerant_proxy_spec.rb index d3714f9..0d0ecf3 100644 --- a/spec/storage/fault_tolerant_proxy_spec.rb +++ b/spec/storage/fault_tolerant_proxy_spec.rb @@ -5,7 +5,7 @@ let(:failing_storage_class) do Class.new do - def method_missing(*_args) # rubocop:disable Style/MethodMissingSuper + def method_missing(*_args) raise 'fail' end @@ -30,7 +30,7 @@ def respond_to_missing?(*_args) .with(:storage_failure, circuit: circuit, action: :entry, error: instance_of(RuntimeError)) status = described_class.new(failing_storage, notifier: notifier) .entry(circuit, Faulty.current_time, false, Faulty::Status.new(options: circuit.options)) - expect(status.stub).to eq(true) + expect(status.stub).to be(true) end it 'returns stub status when getting #status' do @@ -38,7 +38,7 @@ def respond_to_missing?(*_args) .with(:storage_failure, circuit: circuit, action: :status, error: instance_of(RuntimeError)) status = described_class.new(failing_storage, notifier: notifier) .status(circuit) - expect(status.stub).to eq(true) + expect(status.stub).to be(true) end shared_examples 'delegated action' do