Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 9.35.4 - 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
Expand Down
2 changes: 1 addition & 1 deletion lib/maze.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# providing an alternative to the proliferation of global variables or singletons.
module Maze

VERSION = '9.35.3'
VERSION = '9.35.4'

class << self
attr_accessor :check, :driver, :internal_hooks, :mode, :start_time, :dynamic_retry, :public_address,
Expand Down
11 changes: 11 additions & 0 deletions lib/maze/request_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
81 changes: 81 additions & 0 deletions test/unit/maze/request_list_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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