///////////////////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
// Copyright (C) 2001-2023 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
///////////////////////////////////////////////////////////////////////////////////////////////

package com.puppycrawl.tools.checkstyle.checks.blocks;

import static com.google.common.truth.Truth.assertWithMessage;
import static com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck.MSG_KEY_LINE_BREAK_AFTER;
import static com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck.MSG_KEY_LINE_NEW;
import static com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck.MSG_KEY_LINE_PREVIOUS;

import org.junit.jupiter.api.Test;

import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;

public class LeftCurlyCheckTest extends AbstractModuleTestSupport {

    @Override
    protected String getPackageLocation() {
        return "com/puppycrawl/tools/checkstyle/checks/blocks/leftcurly";
    }

    /* Additional test for jacoco, since valueOf()
     * is generated by javac and jacoco reports that
     * valueOf() is uncovered.
     */
    @Test
    public void testLeftCurlyOptionValueOf() {
        final LeftCurlyOption option = LeftCurlyOption.valueOf("NL");
        assertWithMessage("Invalid valueOf result")
            .that(option)
            .isEqualTo(LeftCurlyOption.NL);
    }

    @Test
    public void testGetRequiredTokens() {
        final LeftCurlyCheck checkObj = new LeftCurlyCheck();
        assertWithMessage("LeftCurlyCheck#getRequiredTokens should return empty array by default")
            .that(checkObj.getRequiredTokens())
            .isEqualTo(CommonUtil.EMPTY_INT_ARRAY);
    }

    @Test
    public void testDefault() throws Exception {
        final String[] expected = {
            "17:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "19:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "23:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "27:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "31:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestDefault.java"), expected);
    }

    @Test
    public void testNl() throws Exception {
        final String[] expected = {
            "36:14: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 14),
            "40:14: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 14),
            "45:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "49:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "54:12: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 12),
            "59:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "64:20: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 20),
            "67:27: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 27),
            "68:23: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 23),
            "69:25: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 25),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyDefaultTestNl.java"), expected);
    }

    @Test
    public void testNlow() throws Exception {
        final String[] expected = {
            "17:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "19:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "23:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "27:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "31:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "36:14: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 14),
            "40:14: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 14),
            "45:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "49:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "54:12: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 12),
            "59:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "64:20: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 20),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyDefaultTestNlow.java"), expected);
    }

    @Test
    public void testDefault2() throws Exception {
        final String[] expected = {
            "17:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "22:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "29:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "32:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "36:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "44:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "46:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "51:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "54:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "58:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "70:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "74:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "82:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "85:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "89:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyMethod.java"), expected);
    }

    @Test
    public void testNewline2() throws Exception {
        final String[] expected = {
            "19:44: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 44),
            "26:20: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 20),
            "39:31: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 31),
            "48:24: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 24),
            "61:35: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 35),
            "65:17: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 17),
            "79:20: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 20),
            "92:31: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 31),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyMethodTestNewLine2.java"), expected);
    }

    @Test
    public void testDefault3() throws Exception {
        final String[] expected = {
            "17:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "20:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "24:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "26:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "28:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "35:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "39:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "47:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "51:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "57:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "59:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "68:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "81:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "88:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "94:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "102:19: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 19),
            "111:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "114:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "123:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "125:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "134:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "136:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "138:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "153:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "162:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "169:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestDefault3.java"), expected);
    }

    @Test
    public void testNewline3() throws Exception {
        final String[] expected = {
            "31:33: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 33),
            "96:19: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 19),
            "102:19: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 19),
            "147:49: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 49),
            "163:12: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 12),
            "170:16: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 16),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestNewLine3.java"), expected);
    }

    @Test
    public void testMissingBraces() throws Exception {
        final String[] expected = {
            "17:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "20:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "26:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "39:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "56:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "74:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "110:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestMissingBraces.java"), expected);
    }

    @Test
    public void testDefaultWithAnnotations() throws Exception {
        final String[] expected = {
            "23:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "27:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "34:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "40:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "63:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "71:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestDefaultWithAnnotations.java"), expected);
    }

    @Test
    public void testNlWithAnnotations() throws Exception {
        final String[] expected = {
            "48:55: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 55),
            "51:41: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 41),
            "57:27: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 27),
            "79:42: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 42),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestNlWithAnnotations.java"), expected);
    }

    @Test
    public void testNlowWithAnnotations() throws Exception {
        final String[] expected = {
            "23:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "27:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "34:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "40:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "63:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "71:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestNlowWithAnnotations.java"), expected);
    }

    @Test
    public void testLineBreakAfter() throws Exception {
        final String[] expected = {
            "22:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "25:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "29:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "31:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "33:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "39:22: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 22),
            "41:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "48:33: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 33),
            "49:21: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 21),
            "52:29: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 29),
            "52:34: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 34),
            "58:37: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 37),
            "64:12: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 12),
            "67:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "69:19: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 19),
            "79:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestLineBreakAfter.java"), expected);
    }

    @Test
    public void testIgnoreEnumsOptionTrue() throws Exception {
        final String[] expectedWhileTrue = {
            "21:44: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 44),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyIgnoreEnumsOptTrue.java"), expectedWhileTrue);
    }

    @Test
    public void testIgnoreEnumsOptionFalse() throws Exception {
        final String[] expectedWhileFalse = {
            "17:17: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 17),
            "21:44: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 44),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyIgnoreEnumsOptFalse.java"), expectedWhileFalse);
    }

    @Test
    public void testDefaultLambda() throws Exception {
        final String[] expected = {
            "17:1: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 1),
            "24:32: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 32),
            "27:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestDefaultLambda.java"),
                expected);
    }

    @Test
    public void testNewLineOptionWithLambda() throws Exception {
        final String[] expected = {
            "18:32: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 32),
            "24:32: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 32),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestNewLineOptionWithLambda.java"),
                expected);
    }

    @Test
    public void testEolSwitch() throws Exception {
        final String[] expected = {
            "22:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "26:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "33:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "47:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "52:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestEolSwitch.java"), expected);
    }

    @Test
    public void testNlSwitch() throws Exception {
        final String[] expected = {
            "24:21: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 21),
            "56:14: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 14),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestNlSwitch.java"), expected);
    }

    @Test
    public void testNlowSwitch() throws Exception {
        final String[] expected = {
            "22:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestNlowSwitch.java"), expected);
    }

    @Test
    public void testLeftCurlySwitchExpressions() throws Exception {
        final String[] expected = {
            "20:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "22:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "27:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "32:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "36:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "45:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "47:21: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 21),
            "51:21: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 21),
            "55:21: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 21),
            "59:21: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 21),
        };
        verifyWithInlineConfigParser(
                getNonCompilablePath("InputLeftCurlyTestSwitchExpressions.java"), expected);
    }

    @Test
    public void testLeftCurlySwitchExpressionsNewLine() throws Exception {

        final String[] expected = {
            "17:57: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 57),
            "18:25: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 25),
            "43:25: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 25),
            "54:23: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 23),
        };
        verifyWithInlineConfigParser(
                getNonCompilablePath("InputLeftCurlyTestSwitchExpressionsNewLine.java"),
            expected);
    }

    @Test
    public void testGetAcceptableTokens() {
        final LeftCurlyCheck check = new LeftCurlyCheck();
        final int[] actual = check.getAcceptableTokens();
        final int[] expected = {
            TokenTypes.ANNOTATION_DEF,
            TokenTypes.CLASS_DEF,
            TokenTypes.CTOR_DEF,
            TokenTypes.ENUM_CONSTANT_DEF,
            TokenTypes.ENUM_DEF,
            TokenTypes.INTERFACE_DEF,
            TokenTypes.LAMBDA,
            TokenTypes.LITERAL_CASE,
            TokenTypes.LITERAL_CATCH,
            TokenTypes.LITERAL_DEFAULT,
            TokenTypes.LITERAL_DO,
            TokenTypes.LITERAL_ELSE,
            TokenTypes.LITERAL_FINALLY,
            TokenTypes.LITERAL_FOR,
            TokenTypes.LITERAL_IF,
            TokenTypes.LITERAL_SWITCH,
            TokenTypes.LITERAL_SYNCHRONIZED,
            TokenTypes.LITERAL_TRY,
            TokenTypes.LITERAL_WHILE,
            TokenTypes.METHOD_DEF,
            TokenTypes.OBJBLOCK,
            TokenTypes.STATIC_INIT,
            TokenTypes.RECORD_DEF,
            TokenTypes.COMPACT_CTOR_DEF,
        };
        assertWithMessage("Default acceptable tokens are invalid")
            .that(actual)
            .isEqualTo(expected);
    }

    @Test
    public void testFirstLine() throws Exception {
        final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestFirstLine.java"), expected);
    }

    @Test
    public void testCoverageIncrease() throws Exception {
        final String[] expected = {
            "21:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "30:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "39:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "48:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "62:14: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 14),
            "67:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "71:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
            "76:12: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 12),
            "81:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 18),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyTestCoverageIncrease.java"), expected);
    }

    @Test
    public void testLeftCurlyRecordsAndCompactCtors() throws Exception {
        final String[] expected = {
            "22:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "24:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "34:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "36:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "43:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "56:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getNonCompilablePath("InputLeftCurlyTestRecordsAndCompactCtors.java"), expected);
    }

    @Test
    public void testLeftCurlyWithEmoji() throws Exception {
        final String[] expected = {
            "17:32: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 32),
            "37:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "39:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "46:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "50:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "54:17: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 17),
            "60:32: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 32),
            "67:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "72:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "78:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
            "81:13: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 13),
        };
        verifyWithInlineConfigParser(getPath("InputLeftCurlyWithEmoji.java"), expected);
    }

    @Test
    public void testLeftCurlyWithEmojiNewLine() throws Exception {
        final String[] expected = {
            "18:32: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 32),
            "20:27: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 27),
            "25:29: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 29),
            "28:32: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 32),
            "31:28: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 28),
            "34:28: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 28),
            "43:39: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 39),
            "60:27: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 27),
            "61:28: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 28),
            "75:26: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 26),
            "76:26: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 26),
            "77:24: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 24),
            "89:52: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 52),
        };
        verifyWithInlineConfigParser(getPath("InputLeftCurlyWithEmojiNl.java"), expected);
    }

    @Test
    public void testInvalidOption() throws Exception {

        try {
            final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;

            verifyWithInlineConfigParser(
                    getPath("InputLeftCurlyTestInvalidOption.java"), expected);
            assertWithMessage("exception expected").fail();
        }
        catch (CheckstyleException ex) {
            assertWithMessage("Invalid exception message")
                .that(ex.getMessage())
                .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
                    + "cannot initialize module com.puppycrawl.tools.checkstyle.checks."
                    + "blocks.LeftCurlyCheck - "
                    + "Cannot set property 'option' to 'invalid_option'");
        }
    }

    @Test
    public void testTrimOptionProperty() throws Exception {
        final String[] expected = {
            "13:12: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 12),
            "20:16: " + getCheckMessage(MSG_KEY_LINE_NEW, "{", 16),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyWithTrimOptionProperty.java"), expected);
    }

    @Test
    public void testForEnumConstantDef() throws Exception {
        final String[] expected = {
            "14:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
            "19:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyEnumConstantDef.java"), expected);
    }

    @Test
    public void commentBeforeLeftCurly() throws Exception {
        final String[] expected = {
            "32:5: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 5),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyCommentBeforeLeftCurly.java"), expected);
    }

    @Test
    public void commentBeforeLeftCurly2() throws Exception {
        final String[] expected = {
            "54:9: " + getCheckMessage(MSG_KEY_LINE_PREVIOUS, "{", 9),
            "66:29: " + getCheckMessage(MSG_KEY_LINE_BREAK_AFTER, "{", 29),
        };
        verifyWithInlineConfigParser(
                getPath("InputLeftCurlyCommentBeforeLeftCurly2.java"), expected);
    }
}
