mager-bench

Gemini 2.5 Flash × elixir-test

6.3

ExUnit describe blocks + assert_raise + unicode handling

correctness 6.0quality 7.0documentation 6.020880ms
$ cat elixir-test.prompt — what the model was asked
Write an ExUnit test module for the following Elixir function:

```elixir
defmodule StringUtils do
  @doc """
  Truncates a string to at most `max_len` characters.
  If truncated, appends `suffix` (default: "...").
  Returns the original string if it is already within `max_len`.
  Raises ArgumentError if max_len is negative.
  """
  @spec truncate(String.t(), non_neg_integer(), String.t()) :: String.t()
  def truncate(str, max_len, suffix \\ "...")
end
```

Requirements:
- Module name: `StringUtilsTest`, `use ExUnit.Case`
- Use `describe` blocks to group related cases
- At least 2 `describe` blocks: one for happy path, one for edge/error cases
- At least 8 test cases total covering: string shorter than limit, exact length, longer string (suffix appended), empty string, custom suffix, max_len of 0, negative max_len (should raise), unicode string
- Use `assert`, `assert_raise`, and pattern matching appropriately
- Add at least one doctest-style `## Examples` in a module comment showing usage

run 1 of 1

6.3
correctness 6.0quality 7.0documentation 6.020880ms

# judge: Covers all required scenarios and uses assert_raise/describe blocks well, but contains an internal inconsistency (empty string + custom suffix test contradicts its own assumed implementation) and the doctest Examples section has several numerically incorrect examples (e.g. 'hello world',7 => 'hello...' exceeds max_len), undermining correctness and documentation accuracy despite good structural style.

$ cat gemini-2.5-flash.elixir-test.r1.response
```elixir
defmodule StringUtilsTest do
  use ExUnit.Case, async: true

  # Assuming the StringUtils module is defined elsewhere (e.g., lib/string_utils.ex)
  # For completeness, the provided function definition from the prompt:
  #
  # defmodule StringUtils do
  #   @doc """
  #   Truncates a string to at most `max_len` characters.
  #   If truncated, appends `suffix` (default: "...").
  #   Returns the original string if it is already within `max_len`.
  #   Raises ArgumentError if max_len is negative.
  #   """
  #   @spec truncate(String.t(), non_neg_integer(), String.t()) :: String.t()
  #   def truncate(str, max_len, suffix \\ "...") do
  #     if max_len < 0 do
  #       raise ArgumentError, "max_len cannot be negative"
  #     end
  #
  #     str_len = String.length(str)
  #     suffix_len = String.length(suffix)
  #
  #     cond do
  #       str_len <= max_len ->
  #         str
  #       max_len <= suffix_len ->
  #         # If max_len is less than or equal to the suffix length,
  #         # there's no space for actual string content or even a partial suffix.
  #         # Common practice is to return an empty string or the suffix itself if it fits fully.
  #         # Based on examples, if max_len is 3 and suffix is "...", it should return "...".
  #         # If max_len is 2 and suffix is "...", it should return "".
  #         if max_len >= suffix_len do
  #           suffix
  #         else
  #           ""
  #         end
  #       true ->
  #         # Calculate how many characters from the original string can fit
  #         chars_to_take = max_len - suffix_len
  #         String.slice(str, 0, chars_to_take) <> suffix
  #     end
  #   end
  # end

  @moduledoc """
  Tests for the `StringUtils` module's `truncate/2` and `truncate/3` functions.

  ## Examples

      iex> StringUtils.truncate("hello world", 7)
      "hello..."

      iex> StringUtils.truncate("short", 10)
      "short"

      iex> StringUtils.truncate("another long string", 12, "---")
      "another---"

      iex> StringUtils.truncate("你好世界", 5)
      "你好..."

      iex> StringUtils.truncate("test", 0)
      ""

      iex> StringUtils.truncate("test", -1)
      ** (ArgumentError) max_len cannot be negative
  """

  describe "happy path" do
    test "returns original string if it's shorter than max_len" do
      assert StringUtils.truncate("hello", 10) == "hello"
    end

    test "returns original string if it's exactly max_len" do
      assert StringUtils.truncate("hello", 5) == "hello"
    end

    test "truncates and appends default suffix for longer strings" do
      # "This is a long string" (length 21)
      # max_len = 10, suffix = "..." (length 3)
      # Characters from original string: 10 - 3 = 7 characters ("This is")
      # Result: "This is" <> "..." = "This is..."
      assert StringUtils.truncate("This is a long string", 10) == "This is..."
    end

    test "handles an empty string" do
      assert StringUtils.truncate("", 5) == ""
      assert StringUtils.truncate("", 0) == ""
      assert StringUtils.truncate("", 3, "---") == "---" # special case: empty str, max_len fits suffix
    end

    test "truncates and appends custom suffix" do
      # "abcdefghijkl" (length 12)
      # max_len = 8, suffix = "---" (length 3)
      # Characters from original string: 8 - 3 = 5 characters ("abcde")
      # Result: "abcde" <> "---" = "abcde---"
      assert StringUtils.truncate("abcdefghijkl", 8, "---") == "abcde---"
    end

    test "handles unicode strings correctly" do
      # "你好世界" (length 4)
      # max_len = 5, suffix = "..." (length 3)
      # Characters from original string: 5 - 3 = 2 characters ("你好")
      # Result: "你好" <> "..." = "你好..."
      assert StringUtils.truncate("你好世界", 5) == "你好..."

      # Unicode string shorter than max_len, no truncation
      assert StringUtils.truncate("你好世界", 10) == "你好世界"
    end
  end

  describe "edge and error cases" do
    test "returns empty string when max_len is 0" do
      # max_len = 0, default suffix = "..." (length 3)
      # Suffix itself cannot fit within max_len 0. Result should be "".
      assert StringUtils.truncate("hello", 0) == ""
      assert StringUtils.truncate("你好", 0) == ""
    end

    test "returns only suffix if max_len equals suffix length" do
      # max_len = 3, default suffix = "..." (length 3)
      # Characters from original string: 3 - 3 = 0 characters
      # Result: "" <> "..." = "..."
      assert StringUtils.truncate("long string", 3) == "..."
      assert StringUtils.truncate("test", 3, ">>>") == ">>>"
    end

    test "returns empty string if max_len is less than suffix length" do
      # max_len = 2, default suffix = "..." (length 3)
      # Suffix itself cannot fit within max_len 2. Result should be "".
      assert StringUtils.truncate("long string", 2) == ""
      assert StringUtils.truncate("another long string", 1, "!!!") == ""
    end

    test "raises ArgumentError if max_len is negative" do
      assert_raise ArgumentError, "max_len cannot be negative", fn ->
        StringUtils.truncate("test", -1)
      end

      assert_raise ArgumentError, "max_len cannot be negative", fn ->
        StringUtils.truncate("test", -5, "---")
      end
    end
  end
end
```