diff --git a/CHANGELOG.md b/CHANGELOG.md index b06a964f3..2943224bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 9.36.0 - 2025/08/26 + +## Enhancements + +- Add the ability to sort requests by URL path [783](https://github.com/bugsnag/maze-runner/pull/783) + # 9.35.3 - 2025/08/22 ## Fixes diff --git a/lib/maze.rb b/lib/maze.rb index db71a7e9d..3d87a47db 100644 --- a/lib/maze.rb +++ b/lib/maze.rb @@ -8,7 +8,7 @@ # providing an alternative to the proliferation of global variables or singletons. module Maze - VERSION = '9.35.3' + VERSION = '9.36.0' class << self attr_accessor :check, :driver, :internal_hooks, :mode, :start_time, :dynamic_retry, :public_address, diff --git a/lib/maze/request_list.rb b/lib/maze/request_list.rb index ee7ab9525..1240ad3c2 100644 --- a/lib/maze/request_list.rb +++ b/lib/maze/request_list.rb @@ -91,6 +91,17 @@ def sort_by_sent_at!(count) sub_list.each_with_index { |r, i| @requests[@current + i] = r } end + # Sorts the remaining elements of the list by the request path, if present in all of those elements + def sort_by_request_path! + list = remaining + + return if list.any? { |r| r[:request].path.nil? } + + # Sort the list by request path and overwrite in the main list + list.sort_by! { |r| r[:request].path } + list.each_with_index { |r, i| @requests[@current + i] = r } + end + # Sorts the remaining elements of the list by the field given, if present in all of those elements def sort_by!(key_path) list = remaining diff --git a/test/unit/maze/request_list_test.rb b/test/unit/maze/request_list_test.rb index 835eb9ced..903616e68 100644 --- a/test/unit/maze/request_list_test.rb +++ b/test/unit/maze/request_list_test.rb @@ -4,6 +4,23 @@ require_relative '../../../lib/maze/helper' require_relative '../../../lib/maze/request_list' +class FakeRequest + attr_accessor :body, :path + + def initialize(body) + @body = body + @path = nil + end + + def [](key) + instance_variable_get("@#{key}") + end + + def []=(key, value) + instance_variable_set("@#{key}", value) + end +end + # noinspection RubyNilAnalysis class RequestListTest < Test::Unit::TestCase @@ -35,6 +52,15 @@ def build_item_with_header(id, time) } end + def build_item_with_path(id, path) + req = FakeRequest.new("{id: '#{id}'}") + req.path = path + { + id: id, + request: req + } + end + def after_add(hash) after_add = hash.clone after_add[:run_uuid] = RUN_UUID @@ -278,4 +304,59 @@ def test_sort_by_key_path list.next assert_equal after_add(request1), list.current end + + def test_sort_by_request_path + request1 = build_item_with_path 1, '/zebra' + + request2 = build_item_with_path 2, '/antelope' + + request3 = build_item_with_path 3, '/yak' + + list = Maze::RequestList.new + list.add request1 + list.add request2 + list.add request3 + + list.sort_by_request_path! + + assert_equal [request2, request3, request1].map { |entry| after_add(entry) }, list.remaining + end + + def test_sort_by_request_path_with_missing_path + request1 = build_item_with_path 1, '/zebra' + + # No path key in request2 + request2 = build_item_with_path 2, "" + + request3 = build_item_with_path 3, '/antelope' + + list = Maze::RequestList.new + list.add request1 + list.add request2 + list.add request3 + + list.sort_by_request_path! + + # Should remain unsorted because one request has no path + assert_equal [request2, request3, request1].map { |entry| after_add(entry) }, list.remaining + end + + def test_sort_by_request_path_partial_list + request1 = build_item_with_path 1, '/zebra' + + request2 = build_item_with_path 2, '/antelope' + + request3 = build_item_with_path 3, '/yak' + + list = Maze::RequestList.new + list.add request1 + list.add request2 + list.add request3 + list.next # Skip first item + + list.sort_by_request_path! + + # Only the remaining items should be sorted + assert_equal [request2, request3].map { |entry| after_add(entry) }, list.remaining + end end