///|
test "sort ranges orders by first then last" {
  assert_true(
    sort_ranges([
      concrete_range(10L, 20L),
      concrete_range(0L, 9L),
      concrete_range(10L, 15L),
    ]) ==
    [concrete_range(0L, 9L), concrete_range(10L, 15L), concrete_range(10L, 20L)],
  )
}

///|
test "sort ranges does not mutate input" {
  let a = [concrete_range(5L, 6L), concrete_range(0L, 1L)]
  ignore(sort_ranges(a))
  assert_i64_eq(a[0].first(), 5L)
}

///|
test "merge overlap joins intervals" {
  assert_true(
    merge_overlapping_ranges([
      concrete_range(0L, 499L),
      concrete_range(400L, 799L),
    ]) ==
    [concrete_range(0L, 799L)],
  )
}

///|
test "overlap merge keeps adjacent separate" {
  assert_int_eq(
    merge_overlapping_ranges([
      concrete_range(0L, 499L),
      concrete_range(500L, 999L),
    ]).length(),
    2,
  )
}

///|
test "adjacent merge joins touching intervals" {
  assert_true(
    merge_adjacent_ranges([concrete_range(0L, 499L), concrete_range(500L, 999L)]) ==
    [concrete_range(0L, 999L)],
  )
}

///|
test "coalesce sorts before merging" {
  assert_true(
    coalesce_ranges([concrete_range(500L, 999L), concrete_range(0L, 499L)]) ==
    [concrete_range(0L, 999L)],
  )
}

///|
test "coalesce preserves gaps" {
  assert_int_eq(
    coalesce_ranges([concrete_range(0L, 9L), concrete_range(11L, 20L)]).length(),
    2,
  )
}

///|
test "coalesce empty input" {
  assert_true(coalesce_ranges([]).is_empty())
}