Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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.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
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.36.0'

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