Repository: rails/rails
File: actionview/test/template/template_test.rb (Ruby)

Code before:
    assert_raises ActionView::Template::Error, match: "`argument` set as non-keyword argument for hello template. Locals can only be set as keyword arguments." do
      render
    end
  end

  def test_locals_cannot_be_specified_with_block_arguments
    @template = new_template("<%# locals: (&block) -%>\n<%= tag.div(&block) %>")
    assert_raises ActionView::Template::Error, match: "`block` set as non-keyword argument for hello template. Locals can only be set as keyword arguments." do
      render { "content" }
    end
  end

  def test_locals_can_be_specified
    @template = new_template("<%# locals: (message:) -%>\n<%= message %>")
    assert_equal "Hello", render(message: "Hello")
  end

  def test_default_locals_can_be_specified
    @template = new_template("<%# locals: (message: 'Hello') -%>\n<%= message %>")
    assert_equal "Hello", render
  end

  def test_locals_with_parantheses
    @template = new_template("<%# locals: (message: '(Hello)') -%>\n<%= message %>")
    assert_equal "(Hello)", render
  end

  def test_locals_can_spread_to_multiple_lines
    template = <<~ERB.chomp
        <%# locals: (arg_1:,
                     arg_2: nil,
                     arg_3: []) -%>
        <%= arg_1 %><%= arg_2 %><%= arg_3 %>
    ERB
    @template = new_template(template)
    assert_equal "First[]", render(arg_1: "First")
  end

  def test_required_locals_must_be_specified
    error = assert_raises(ActionView::Template::Error) do
      @template = new_template("<%# locals: (message:) -%>")
      render
    end

    assert_match(/missing local: :message for hello template/, error.message)
    assert_instance_of ActionView::StrictLocalsError, error.cause
  end

  def test_extra_locals_raises_strict_locals_error
    error = assert_raises(ActionView::Template::Error) do
      @template = new_template("<%# locals: (message:) -%>")

Review comment (suggestion):
I pushed an extra commit with this test to demonstrate that this PR causes a regression if one of the default values contains a paranthese.

Code after:
    assert_raises ActionView::Template::Error, match: "`argument` set as non-keyword argument for hello template. Locals can only be set as keyword arguments." do
      render
    end
  end

  def test_locals_cannot_be_specified_with_block_arguments
    @template = new_template("<%# locals: (&block) -%>\n<%= tag.div(&block) %>")
    assert_raises ActionView::Template::Error, match: "`block` set as non-keyword argument for hello template. Locals can only be set as keyword arguments." do
      render { "content" }
    end
  end

  def test_locals_can_be_specified
    @template = new_template("<%# locals: (message:) -%>\n<%= message %>")
    assert_equal "Hello", render(message: "Hello")
  end

  def test_default_locals_can_be_specified
    @template = new_template("<%# locals: (message: 'Hello') -%>\n<%= message %>")
    assert_equal "Hello", render
  end

  def test_locals_with_parentheses
    @template = new_template("<%# locals: (message: '(Hello)') -%>\n<%= message %>")
    assert_equal "(Hello)", render

    @template = new_template("<%# locals: (message: '(Hello') -%>\n<%= message %>")
    assert_equal "(Hello", render

    @template = new_template("<%# locals: (message: 'Hello)') -%>\n<%= message %>")
    assert_equal "Hello)", render
  end

  def test_locals_can_spread_to_multiple_lines
    template = <<~ERB.chomp
        <%# locals: (arg_1:,
                     arg_2: nil,
                     arg_3: []) -%>
        <%= arg_1 %><%= arg_2 %><%= arg_3 %>
    ERB
    @template = new_template(template)
    assert_equal "First[]", render(arg_1: "First")
  end

  def test_required_locals_must_be_specified
    error = assert_raises(ActionView::Template::Error) do
      @template = new_template("<%# locals: (message:) -%>")
      render
    end

    assert_match(/missing local: :message for hello template/, error.message)