diff --git a/.github/workflows/gem_push.yml b/.github/workflows/gem_push.yml index 9e22ccf27..691475212 100644 --- a/.github/workflows/gem_push.yml +++ b/.github/workflows/gem_push.yml @@ -20,7 +20,7 @@ jobs: id-token: write steps: - uses: actions/checkout@v6 - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@v1.302.0 with: ruby-version: ruby bundler-cache: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 386f03e46..6db9d37b0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.302.0 with: ruby-version: "3.4" bundler-cache: true diff --git a/.github/workflows/mutant.yml b/.github/workflows/mutant.yml index 7c0819f1e..01b3a9945 100644 --- a/.github/workflows/mutant.yml +++ b/.github/workflows/mutant.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.302.0 with: ruby-version: '3.4' bundler-cache: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1e1fe605c..e91d689a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.302.0 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true # runs 'bundle install' and caches installed gems automatically diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 4caa209ad..6808a6440 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.302.0 with: ruby-version: '3.4' bundler-cache: true diff --git a/.github/workflows/yardstick.yml b/.github/workflows/yardstick.yml index 823619873..36a8f8321 100644 --- a/.github/workflows/yardstick.yml +++ b/.github/workflows/yardstick.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.302.0 with: ruby-version: '3.4' bundler-cache: true diff --git a/.mutant.yml b/.mutant.yml index 887f1f2ed..85b8cc167 100644 --- a/.mutant.yml +++ b/.mutant.yml @@ -13,6 +13,9 @@ includes: usage: opensource +mutation: + operators: full + matcher: subjects: - Twitter* diff --git a/lib/twitter/base.rb b/lib/twitter/base.rb index 606863099..4d9cb985c 100644 --- a/lib/twitter/base.rb +++ b/lib/twitter/base.rb @@ -165,7 +165,7 @@ def initialize(attrs = nil) # @param method [String, Symbol] Message to send to the object # @return [Object, nil] def [](method) - location = caller_locations(1, 1)&.first + location, = caller_locations(1, 1) warn "#{location&.path}:#{location&.lineno}: [DEPRECATION] #[#{method.inspect}] is deprecated. Use ##{method} to fetch the value." public_send(method.to_sym) rescue NoMethodError diff --git a/lib/twitter/profile.rb b/lib/twitter/profile.rb index bf7c8f97b..14d2eb007 100644 --- a/lib/twitter/profile.rb +++ b/lib/twitter/profile.rb @@ -145,7 +145,7 @@ def insecure_uri(uri) # @param size [Symbol] The size # @return [String] def profile_image_suffix(size) - (size.to_sym == :original) ? '\\1' : "_#{size}\\1" + {original: '\\1'}.fetch(size.to_sym) { "_#{size}\\1" } end end end diff --git a/lib/twitter/rest/direct_messages.rb b/lib/twitter/rest/direct_messages.rb index 580af966f..d8435f74d 100644 --- a/lib/twitter/rest/direct_messages.rb +++ b/lib/twitter/rest/direct_messages.rb @@ -68,7 +68,7 @@ def direct_messages_list(options = {}) # @return [Array] Direct messages received def direct_messages_received(options = {}) limit = options.fetch(:count, 20) - direct_messages_list(options).select { |dm| dm.recipient_id == user_id }.first(limit) + direct_messages_list(options).select { |dm| dm.recipient_id.eql?(user_id) }.first(limit) end # Returns Direct Messages sent by the authenticated user @@ -87,7 +87,7 @@ def direct_messages_received(options = {}) # @return [Array] Direct messages sent def direct_messages_sent(options = {}) limit = options.fetch(:count, 20) - direct_messages_list(options).select { |dm| dm.sender_id == user_id }.first(limit) + direct_messages_list(options).select { |dm| dm.sender_id.eql?(user_id) }.first(limit) end # Returns a direct message @@ -241,7 +241,7 @@ def create_direct_message(user_id, text, options = {}) def create_direct_message_event(*args) arguments = Arguments.new(args) options = arguments.options - options[:event] = {type: "message_create", message_create: {target: {recipient_id: extract_id(arguments.fetch(0))}, message_data: {text: arguments.fetch(1)}}} if arguments.length == 2 + options[:event] = {type: "message_create", message_create: {target: {recipient_id: extract_id(arguments.fetch(0))}, message_data: {text: arguments.fetch(1)}}} if arguments.length.eql?(2) response = Request.new(self, :json_post, "/1.1/direct_messages/events/new.json", options).perform DirectMessageEvent.new(response) end diff --git a/lib/twitter/rest/favorites.rb b/lib/twitter/rest/favorites.rb index b00ad2f60..ee50876da 100644 --- a/lib/twitter/rest/favorites.rb +++ b/lib/twitter/rest/favorites.rb @@ -37,7 +37,7 @@ module Favorites # @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID. def favorites(*args) arguments = Arguments.new(args) - merge_user!(arguments.options, arguments.pop) if arguments.last + merge_user!(arguments.options, arguments.pop) if arguments.any? perform_get_with_objects("/1.1/favorites/list.json", arguments.options, Tweet) end diff --git a/lib/twitter/rest/lists.rb b/lib/twitter/rest/lists.rb index e9116e7fb..7ea308008 100644 --- a/lib/twitter/rest/lists.rb +++ b/lib/twitter/rest/lists.rb @@ -526,9 +526,10 @@ def list_from_response_with_users(path, args) members = arguments.pop merge_list!(options, arguments.pop) merge_owner!(options, arguments.pop) - pmap(members.each_slice(MAX_USERS_PER_REQUEST)) do |users| + *, result = pmap(members.each_slice(MAX_USERS_PER_REQUEST)) do |users| perform_post_with_object(path, merge_users(options, users), List) - end.last + end + result end # Take a list and merge it into the hash with the correct key diff --git a/lib/twitter/rest/premium_search.rb b/lib/twitter/rest/premium_search.rb index 059aaa38b..3418e09f7 100644 --- a/lib/twitter/rest/premium_search.rb +++ b/lib/twitter/rest/premium_search.rb @@ -28,7 +28,7 @@ module PremiumSearch def premium_search(query, options = {}, request_config = {}) options = options.clone options[:maxResults] ||= MAX_TWEETS_PER_REQUEST - request_config[:request_method] = :json_post if request_config[:request_method].nil? || request_config.fetch(:request_method) == :post + request_config[:request_method] = :json_post if request_config[:request_method].nil? || request_config.fetch(:request_method).eql?(:post) request_config[:product] ||= "30day" path = "/1.1/tweets/search/#{request_config.fetch(:product)}/#{dev_environment}.json" # steep:ignore NoMethod request = Request.new(self, request_config.fetch(:request_method), path, options.merge(query:)) diff --git a/lib/twitter/rest/request.rb b/lib/twitter/rest/request.rb index 22c472529..f5271902c 100644 --- a/lib/twitter/rest/request.rb +++ b/lib/twitter/rest/request.rb @@ -124,7 +124,7 @@ def perform # @api private # @return [Hash] def request_options - options = if @options_key == :form + options = if @options_key.eql?(:form) {form: HTTP::FormData.create(@options, encoder: FormEncoder.public_method(:encode))} else {@options_key => @options} @@ -158,10 +158,10 @@ def merge_multipart_file!(options) # @return [void] def set_multipart_options!(request_method, options) if %i[multipart_post json_post].include?(request_method) - merge_multipart_file!(options) if request_method == :multipart_post + merge_multipart_file!(options) if request_method.eql?(:multipart_post) options = {} # : Hash[Symbol, untyped] @request_method = :post - elsif request_method == :json_put + elsif request_method.eql?(:json_put) @request_method = :put else @request_method = request_method @@ -212,7 +212,7 @@ def fail_or_return_response_body(code, body, response) # @return [Twitter::Error, nil] def error(code, body, response) klass = Error::ERRORS[code] - if klass == Error::Forbidden + if klass.eql?(Error::Forbidden) forbidden_error(body, response) elsif !klass.nil? klass.from_response(body, response) diff --git a/lib/twitter/rest/suggested_users.rb b/lib/twitter/rest/suggested_users.rb index a0c0022fd..e094e3e4d 100644 --- a/lib/twitter/rest/suggested_users.rb +++ b/lib/twitter/rest/suggested_users.rb @@ -31,7 +31,7 @@ module SuggestedUsers # @param options [Hash] A customizable set of options. def suggestions(*args) arguments = Arguments.new(args) - if arguments.last + if arguments.any? perform_get_with_object("/1.1/users/suggestions/#{arguments.pop}.json", arguments.options, Suggestion) else perform_get_with_objects("/1.1/users/suggestions.json", arguments.options, Suggestion) diff --git a/lib/twitter/rest/trends.rb b/lib/twitter/rest/trends.rb index ae09cc1f1..12b9599e4 100644 --- a/lib/twitter/rest/trends.rb +++ b/lib/twitter/rest/trends.rb @@ -25,7 +25,7 @@ module Trends def trends(id = 1, options = {}) options = options.dup options[:id] = id - response = perform_get("/1.1/trends/place.json", options).first + response, = perform_get("/1.1/trends/place.json", options) TrendResults.new(response) end # @!method local_trends diff --git a/lib/twitter/rest/tweets.rb b/lib/twitter/rest/tweets.rb index 0d8336435..4ad21065d 100644 --- a/lib/twitter/rest/tweets.rb +++ b/lib/twitter/rest/tweets.rb @@ -335,7 +335,8 @@ def oembeds(*args) # @param options [Hash] A customizable set of options. def retweeters_ids(*args) arguments = Arguments.new(args) - arguments.options[:id] ||= extract_id(arguments.first) + id, = arguments + arguments.options[:id] ||= extract_id(id) perform_get_with_cursor("/1.1/statuses/retweeters/ids.json", arguments.options, :ids) end diff --git a/lib/twitter/rest/upload_utils.rb b/lib/twitter/rest/upload_utils.rb index 23f430378..85856dd52 100644 --- a/lib/twitter/rest/upload_utils.rb +++ b/lib/twitter/rest/upload_utils.rb @@ -15,9 +15,9 @@ module UploadUtils # @return [Hash] def upload(media, media_category_prefix: "tweet") ext = File.extname(media) - return chunk_upload(media, "video/mp4", "#{media_category_prefix}_video") if ext == ".mp4" - return chunk_upload(media, "video/quicktime", "#{media_category_prefix}_video") if ext == ".mov" - return chunk_upload(media, "image/gif", "#{media_category_prefix}_gif") if ext == ".gif" && File.size(media) > 5_000_000 + return chunk_upload(media, "video/mp4", "#{media_category_prefix}_video") if ext.eql?(".mp4") + return chunk_upload(media, "video/quicktime", "#{media_category_prefix}_video") if ext.eql?(".mov") + return chunk_upload(media, "image/gif", "#{media_category_prefix}_gif") if ext.eql?(".gif") && File.size(media) > 5_000_000 Request.new(self, :multipart_post, "https://upload.twitter.com/1.1/media/upload.json", key: :media, file: media).perform end diff --git a/lib/twitter/rest/users.rb b/lib/twitter/rest/users.rb index 6a03a80e6..6d7d6f5ac 100644 --- a/lib/twitter/rest/users.rb +++ b/lib/twitter/rest/users.rb @@ -40,8 +40,8 @@ def settings(options = {}) request_method = options.empty? ? :get : :post response = perform_request(request_method, "/1.1/account/settings.json", options) # https://dev.twitter.com/issues/59 - empty_array = [] # : Array[untyped] - response[:trend_location] = response.fetch(:trend_location, empty_array).first + trend_location, = response[:trend_location] + response[:trend_location] = trend_location Settings.new(response) end @@ -272,7 +272,7 @@ def users(*args) # @option options [Boolean, String, Integer] :skip_status Do not include user's Tweets when set to true, 't' or 1. def user(*args) arguments = Arguments.new(args) - if arguments.last || user_id? + if arguments.any? || user_id? merge_user!(arguments.options, arguments.pop || user_id) perform_get_with_object("/1.1/users/show.json", arguments.options, User) else diff --git a/lib/twitter/search_results.rb b/lib/twitter/search_results.rb index bb2b007a0..7054f9ce2 100644 --- a/lib/twitter/search_results.rb +++ b/lib/twitter/search_results.rb @@ -116,7 +116,7 @@ def query_string_to_hash(query_string) return {} if parsed_query.nil? query = CGI.parse(parsed_query) - query.to_h { |key, value| [key.to_sym, value.first] } + query.to_h { |key, (value, *)| [key.to_sym, value] } end end end diff --git a/lib/twitter/streaming/connection.rb b/lib/twitter/streaming/connection.rb index ea5070c41..a0b876fee 100644 --- a/lib/twitter/streaming/connection.rb +++ b/lib/twitter/streaming/connection.rb @@ -49,7 +49,8 @@ def stream(request, response) # rubocop:disable Metrics/MethodLength read_pipe, @write_pipe = IO.pipe loop do read_ios, _write_ios, _exception_ios = IO.select([read_pipe, client]) - case read_ios.first + first_io, = read_ios + case first_io when client response << client.readpartial(1024) when read_pipe diff --git a/test/twitter/rest/direct_messages_test.rb b/test/twitter/rest/direct_messages_test.rb index 1d24290f2..47f955250 100644 --- a/test/twitter/rest/direct_messages_test.rb +++ b/test/twitter/rest/direct_messages_test.rb @@ -250,7 +250,7 @@ it "defaults to returning at most 20 matching sent messages" do message_class = Struct.new(:sender_id, :recipient_id) - matching = Array.new(25) { message_class.new(22_095_868, 1) } + matching = Array.new(25) { |i| message_class.new(22_095_868, i) } @client.stub(:direct_messages_list, matching) do assert_equal(matching.first(20), @client.direct_messages_sent)