diff --git a/.rubocop.yml b/.rubocop.yml index 39d0bba..3e00425 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,3 @@ -inherit_from: .rubocop_todo.yml - inherit_gem: rubocop-shopify: rubocop.yml @@ -10,3 +8,7 @@ require: AllCops: NewCops: enable TargetRubyVersion: 3.2 + +Naming/FileName: + Exclude: + - 'lib/ruby-limiter.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml deleted file mode 100644 index 9c507c7..0000000 --- a/.rubocop_todo.yml +++ /dev/null @@ -1,144 +0,0 @@ -# This configuration was generated by -# `rubocop --auto-gen-config` -# on 2023-10-28 21:14:44 UTC using RuboCop version 1.57.2. -# The point is for the user to remove these configuration records -# one by one as the offenses are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of RuboCop, may require this file to be generated again. - -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. -# Include: **/*.gemspec -Gemspec/OrderedDependencies: - Exclude: - - 'limiter.gemspec' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Layout/EmptyLineAfterGuardClause: - Exclude: - - 'lib/limiter/rate_queue.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowMultilineFinalElement. -Layout/FirstMethodArgumentLineBreak: - Exclude: - - 'bin/rake' - -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: final_newline, final_blank_line -Layout/TrailingEmptyLines: - Exclude: - - 'Rakefile' - - 'lib/ruby-limiter.rb' - -# Offense count: 1 -# Configuration parameters: AllowedParentClasses. -Lint/MissingSuper: - Exclude: - - 'test/test_helper.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Minitest/AssertOperator: - Exclude: - - 'test/limiter/clock_test.rb' - -# Offense count: 5 -# This cop supports safe autocorrection (--autocorrect). -Minitest/EmptyLineBeforeAssertionMethods: - Exclude: - - 'test/limiter/mixin_test.rb' - - 'test/limiter/rate_queue_test.rb' - -# Offense count: 1 -# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. -# CheckDefinitionPathHierarchyRoots: lib, spec, test, src -# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS -Naming/FileName: - Exclude: - - 'lib/ruby-limiter.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: def_self, self_class -Style/ClassMethodsDefinitions: - Exclude: - - 'test/limiter/mixin_test.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, AllowInnerBackticks. -# SupportedStyles: backticks, percent_x, mixed -Style/CommandLiteral: - Exclude: - - 'limiter.gemspec' - -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, always_true, never -Style/FrozenStringLiteralComment: - Exclude: - - 'lib/ruby-limiter.rb' - -# Offense count: 21 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: IgnoreMacros, AllowedMethods, AllowedPatterns, IncludedMacros, AllowParenthesesInMultilineCall, AllowParenthesesInChaining, AllowParenthesesInCamelCaseMethod, AllowParenthesesInStringInterpolation, EnforcedStyle. -# SupportedStyles: require_parentheses, omit_parentheses -Style/MethodCallWithArgsParentheses: - Exclude: - - 'lib/limiter/mixin.rb' - - 'limiter.gemspec' - - 'test/limiter/clock_test.rb' - - 'test/limiter/mixin_test.rb' - - 'test/limiter/rate_queue_test.rb' - - 'test/limiter_test.rb' - - 'test/test_helper.rb' - -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. -# AllowedMethods: present?, blank?, presence, try, try! -Style/SafeNavigation: - Exclude: - - 'lib/limiter/rate_queue.rb' - -# Offense count: 50 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiterals: - Exclude: - - 'Gemfile' - - 'bin/console' - - 'lib/limiter.rb' - - 'lib/limiter/clock.rb' - - 'lib/limiter/version.rb' - - 'lib/ruby-limiter.rb' - - 'limiter.gemspec' - - 'test/limiter/clock_test.rb' - - 'test/limiter/mixin_test.rb' - - 'test/limiter/rate_queue_test.rb' - - 'test/limiter_test.rb' - - 'test/test_helper.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, AllowedMethods. -# AllowedMethods: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym -Style/TrivialAccessors: - Exclude: - - 'test/limiter/mixin_test.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: MinSize, WordRegex. -# SupportedStyles: percent, brackets -Style/WordArray: - EnforcedStyle: percent diff --git a/Gemfile b/Gemfile index 7f4f5e9..be173b2 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" gemspec diff --git a/Rakefile b/Rakefile index aa75f3f..1d6da8e 100644 --- a/Rakefile +++ b/Rakefile @@ -10,4 +10,4 @@ Rake::TestTask.new(:test) do |t| t.warning = true end -task default: :test \ No newline at end of file +task default: :test diff --git a/bin/console b/bin/console index 3df5157..665e095 100755 --- a/bin/console +++ b/bin/console @@ -1,8 +1,8 @@ #!/usr/bin/env ruby # frozen_string_literal: true -require 'bundler/setup' -require 'limiter' +require "bundler/setup" +require "limiter" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. @@ -11,5 +11,5 @@ require 'limiter' # require 'pry' # Pry.start -require 'irb' +require "irb" IRB.start(__FILE__) diff --git a/bin/rake b/bin/rake index ea0e293..27a38c9 100755 --- a/bin/rake +++ b/bin/rake @@ -9,8 +9,10 @@ # require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) +ENV["BUNDLE_GEMFILE"] ||= File.expand_path( + "../../Gemfile", + Pathname.new(__FILE__).realpath, +) bundle_binstub = File.expand_path("../bundle", __FILE__) diff --git a/lib/limiter.rb b/lib/limiter.rb index eb8435a..f02b6ba 100644 --- a/lib/limiter.rb +++ b/lib/limiter.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'limiter/clock' -require 'limiter/mixin' -require 'limiter/rate_queue' -require 'limiter/version' +require "limiter/clock" +require "limiter/mixin" +require "limiter/rate_queue" +require "limiter/version" diff --git a/lib/limiter/clock.rb b/lib/limiter/clock.rb index 12c1eae..3c32665 100644 --- a/lib/limiter/clock.rb +++ b/lib/limiter/clock.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'singleton' -require 'forwardable' +require "singleton" +require "forwardable" module Limiter class Clock diff --git a/lib/limiter/mixin.rb b/lib/limiter/mixin.rb index f8d000c..005207a 100644 --- a/lib/limiter/mixin.rb +++ b/lib/limiter/mixin.rb @@ -16,7 +16,7 @@ def limit_method(method, rate:, interval: 60, balanced: false, &b) queue.reset end - prepend mixin + prepend(mixin) end end end diff --git a/lib/limiter/rate_queue.rb b/lib/limiter/rate_queue.rb index 30da09d..4dd7591 100644 --- a/lib/limiter/rate_queue.rb +++ b/lib/limiter/rate_queue.rb @@ -43,7 +43,8 @@ def shift def sleep_until(time) interval = time - clock.time return unless interval.positive? - @blk.call if @blk + + @blk&.call clock.sleep(interval) end diff --git a/lib/limiter/version.rb b/lib/limiter/version.rb index 7f548f8..a3724c1 100644 --- a/lib/limiter/version.rb +++ b/lib/limiter/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Limiter - VERSION = '2.3.0' + VERSION = "2.3.0" end diff --git a/lib/ruby-limiter.rb b/lib/ruby-limiter.rb index a973443..e075675 100644 --- a/lib/ruby-limiter.rb +++ b/lib/ruby-limiter.rb @@ -1 +1,3 @@ -require 'limiter' \ No newline at end of file +# frozen_string_literal: true + +require "limiter" diff --git a/limiter.gemspec b/limiter.gemspec index 0d8e595..f3190fe 100644 --- a/limiter.gemspec +++ b/limiter.gemspec @@ -1,41 +1,41 @@ # frozen_string_literal: true -lib = File.expand_path('lib', __dir__) +lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'limiter/version' +require "limiter/version" Gem::Specification.new do |spec| - spec.name = 'ruby-limiter' + spec.name = "ruby-limiter" spec.version = Limiter::VERSION - spec.authors = ['S. Brent Faulkner'] - spec.email = ['brent.faulkner@shopify.com'] + spec.authors = ["S. Brent Faulkner"] + spec.email = ["brent.faulkner@shopify.com"] - spec.summary = 'Simple Ruby rate limiting mechanism.' - spec.homepage = 'https://github.com/Shopify/limiter' - spec.license = 'MIT' + spec.summary = "Simple Ruby rate limiting mechanism." + spec.homepage = "https://github.com/Shopify/limiter" + spec.license = "MIT" spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0") if spec.respond_to?(:metadata) - spec.metadata['allowed_push_host'] = "https://rubygems.org" + spec.metadata["allowed_push_host"] = "https://rubygems.org" else raise "RubyGems 2.0 or newer is required to protect against public gem pushes." end - spec.files = `git ls-files -z`.split("\x0").reject do |f| + spec.files = %x(git ls-files -z).split("\x0").reject do |f| f.match(%r{^(test|spec|features)/}) end - spec.bindir = 'exe' + spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = %w(lib) + spec.require_paths = ["lib"] - spec.add_development_dependency 'bundler' - spec.add_development_dependency 'minitest', '~> 5.20' - spec.add_development_dependency 'minitest-focus', '~> 1.4' - spec.add_development_dependency 'mocha', '~> 2.1' - spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.57' - spec.add_development_dependency 'code-scanning-rubocop', '~> 0.6.1' - spec.add_development_dependency 'rubocop-shopify', '~> 2.14' - spec.add_development_dependency 'rubocop-minitest', '~> 0.33.0' - spec.add_development_dependency 'rubocop-rake', '~> 0.6.0' + spec.add_development_dependency("bundler") + spec.add_development_dependency("code-scanning-rubocop", "~> 0.6.1") + spec.add_development_dependency("minitest", "~> 5.20") + spec.add_development_dependency("minitest-focus", "~> 1.4") + spec.add_development_dependency("mocha", "~> 2.1") + spec.add_development_dependency("rake", "~> 13.0") + spec.add_development_dependency("rubocop", "~> 1.57") + spec.add_development_dependency("rubocop-minitest", "~> 0.33.0") + spec.add_development_dependency("rubocop-rake", "~> 0.6.0") + spec.add_development_dependency("rubocop-shopify", "~> 2.14") end diff --git a/test/limiter/clock_test.rb b/test/limiter/clock_test.rb index b2d0f50..797e3aa 100644 --- a/test/limiter/clock_test.rb +++ b/test/limiter/clock_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'test_helper' +require "test_helper" module Limiter class ClockTest < Minitest::Test @@ -10,7 +10,7 @@ def setup end def test_clock_is_advancing - assert Clock.time > @start_time + assert_operator(Clock.time, :>, @start_time) end end end diff --git a/test/limiter/mixin_test.rb b/test/limiter/mixin_test.rb index 27ee7ed..a765d2b 100644 --- a/test/limiter/mixin_test.rb +++ b/test/limiter/mixin_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'test_helper' +require "test_helper" module Limiter class MixinTest < Minitest::Test @@ -15,8 +15,8 @@ class MixinTestClass @limited = 0 - def self.limited - @limited + class << self + attr_reader :limited end limit_method :tick, rate: RATE, interval: INTERVAL @@ -89,12 +89,13 @@ def test_original_method_is_called @object.tick end - assert_equal COUNT, @object.ticks + assert_equal(COUNT, @object.ticks) end def test_arguments_are_passed - @object.tick 123 - assert_equal 123, @object.ticks + @object.tick(123) + + assert_equal(123, @object.ticks) end def test_default_keyword_arguments_are_passed @@ -102,12 +103,13 @@ def test_default_keyword_arguments_are_passed @object.tock end - assert_equal COUNT, @object.ticks + assert_equal(COUNT, @object.ticks) end def test_keyword_arguments_are_passed @object.tock(count: 321) - assert_equal 321, @object.ticks + + assert_equal(321, @object.ticks) end def test_block_was_called_on_rate_limit diff --git a/test/limiter/rate_queue_test.rb b/test/limiter/rate_queue_test.rb index 31d7fd3..2341f42 100644 --- a/test/limiter/rate_queue_test.rb +++ b/test/limiter/rate_queue_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'test_helper' +require "test_helper" module Limiter class RateQueueTest < Minitest::Test @@ -51,11 +51,13 @@ def test_block_was_called_on_rate_limit @queue.stubs(:clock).returns(FakeClock) @queue.shift @queue.shift - assert @block_hit + + assert(@block_hit) end def test_shift_is_unbalanced_by_default actual = @queue.instance_variable_get(:@ring) + actual.size.times.with_index do |idx| assert_in_delta(actual[idx], 0.0) end @@ -71,6 +73,7 @@ def test_shift_is_balanced Clock.time - 1, ] actual = subject.instance_variable_get(:@ring) + actual.size.times.with_index do |idx| assert_in_delta(actual[idx], expected[idx]) end diff --git a/test/limiter_test.rb b/test/limiter_test.rb index 22a20c1..fb0d66a 100644 --- a/test/limiter_test.rb +++ b/test/limiter_test.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require 'test_helper' +require "test_helper" class LimiterTest < Minitest::Test def test_that_it_has_a_version_number - refute_nil ::Limiter::VERSION + refute_nil(::Limiter::VERSION) end end diff --git a/test/test_helper.rb b/test/test_helper.rb index d974fd7..5dd7278 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,15 +1,16 @@ # frozen_string_literal: true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) -require 'limiter' +$LOAD_PATH.unshift(File.expand_path("../lib", __dir__)) +require "limiter" -require 'minitest/autorun' -require 'minitest/focus' -require 'mocha/minitest' +require "minitest/autorun" +require "minitest/focus" +require "mocha/minitest" module Limiter class FakeClock < Clock def initialize + super @offset = 0 end @@ -30,7 +31,7 @@ def assert_elapsed(interval) completed_at = FakeClock.time - assert_in_delta started_at + interval, completed_at, 1.1 + assert_in_delta(started_at + interval, completed_at, 1.1) end end end