test/openagents/forge/commit_references_test.exs

main at 436d37facc96 · 4 KB

defmodule OpenAgents.Forge.CommitReferencesTest do
  @moduledoc """
  #130: reading closing references out of a commit message. The reader runs on
  the push path, so every case here is also a statement that it returns a list
  rather than raising.
  """

  use ExUnit.Case, async: true

  alias OpenAgents.Forge.CommitReferences

  describe "the inline GitHub form" do
    test "reads a closing reference from the commit body" do
      assert CommitReferences.closing_numbers("Delegate to a Box\n\nCloses #126") == [126]
    end

    test "reads it from the subject line" do
      assert CommitReferences.closing_numbers("Closes #126") == [126]
    end

    test "treats Fixes and Resolves the same as Closes" do
      assert CommitReferences.closing_numbers("Body\n\nFixes #12") == [12]
      assert CommitReferences.closing_numbers("Body\n\nResolves #12") == [12]
    end

    test "accepts every tense of the keyword, in any case" do
      for verb <- ~w(close closes closed fix fixes fixed resolve resolves resolved) do
        assert CommitReferences.closing_numbers("Body\n\n#{verb} #9") == [9],
               "#{verb} did not read as a closing keyword"

        assert CommitReferences.closing_numbers("Body\n\n#{String.upcase(verb)} #9") == [9]
      end
    end

    test "reads a comma-separated list" do
      assert CommitReferences.closing_numbers("Body\n\nCloses #12, #13, #14") == [12, 13, 14]
    end

    test "reads a list joined with and" do
      assert CommitReferences.closing_numbers("Body\n\nFixes #7 and #8") == [7, 8]
    end

    test "reads several closing lines" do
      assert CommitReferences.closing_numbers("Body\n\nCloses #1\nFixes #2\nResolves #3") ==
               [1, 2, 3]
    end
  end

  describe "the trailer form" do
    test "reads a Closes trailer" do
      assert CommitReferences.closing_numbers("Body\n\nCloses: #126") == [126]
    end

    test "reads a trailer list" do
      assert CommitReferences.closing_numbers("Body\n\nFixes: #12, #13") == [12, 13]
    end
  end

  describe "what it refuses" do
    test "a message with no closing keyword closes nothing" do
      assert CommitReferences.closing_numbers("Fix the parser for #42") == []
      assert CommitReferences.closing_numbers("See #42 for context") == []
    end

    test "a keyword embedded in a longer word is not a keyword" do
      assert CommitReferences.closing_numbers("Enclosed #5 in the payload") == []
      assert CommitReferences.closing_numbers("Prefixes #5") == []
    end

    test "a cross-repository reference is read but not treated as local" do
      message = "Body\n\nCloses OpenAgentsInc/openagents.com#12"

      assert [reference] = CommitReferences.closing(message)
      assert reference.owner == "OpenAgentsInc"
      assert reference.repository == "openagents.com"
      assert reference.number == 12
      refute CommitReferences.same_repository?(reference)
      assert CommitReferences.closing_numbers(message) == []
    end

    test "issue zero and an out-of-range number are not references" do
      assert CommitReferences.closing_numbers("Closes #0") == []
      assert CommitReferences.closing_numbers("Closes #9999999999") == []
    end

    test "a truncated reference is not a reference" do
      assert CommitReferences.closing_numbers("Closes #") == []
      assert CommitReferences.closing_numbers("Closes") == []
      assert CommitReferences.closing_numbers("Closes #abc") == []
    end

    test "the same reference twice records once" do
      assert CommitReferences.closing_numbers("Closes #12\n\nCloses #12") == [12]
    end
  end

  describe "totality" do
    test "a non-binary message returns an empty list rather than raising" do
      for message <- [nil, 123, %{}, [], :closes, {1, 2}] do
        assert CommitReferences.closing(message) == []
        assert CommitReferences.all(message) == []
        assert CommitReferences.closing_numbers(message) == []
      end
    end

    test "invalid UTF-8 and stray punctuation return a list" do
      assert is_list(CommitReferences.closing(<<0xFF, 0xFE, "Closes #12">>))
      assert is_list(CommitReferences.closing("Closes ###12 ,,, #"))
    end

    test "a very long message is clamped rather than scanned forever" do
      message = String.duplicate("a #1 b\n", 20_000) <> "\nCloses #12"
      assert is_list(CommitReferences.closing_numbers(message))
    end

    test "no single commit records more references than the cap" do
      body = Enum.map_join(1..200, "\n", fn n -> "Closes ##{n}" end)
      assert length(CommitReferences.closing_numbers(body)) <= 32
    end
  end

  describe "all/1, which issue #12 consumes" do
    test "returns plain mentions alongside closing references" do
      references = CommitReferences.all("Closes #12\n\n- [ ] #13\n- [x] #14")

      assert Enum.map(references, & &1.number) == [12, 13, 14]
      assert Enum.map(references, & &1.closing?) == [true, false, false]
    end

    test "carries the verb that introduced a closing reference" do
      assert [%{verb: "fixes", closing?: true}] = CommitReferences.all("Fixes #12")
    end
  end
end