code: ///////////////////////////////////////////////////////////////////////////////////////////////
  // 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.whitespace;
  
  import static com.google.common.truth.Truth.assertWithMessage;
  import static com.puppycrawl.tools.checkstyle.checks.whitespace.NoWhitespaceAfterCheck.MSG_KEY;
  
  import org.antlr.v4.runtime.CommonToken;
  import org.junit.jupiter.api.Test;
  
  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
  
  public class NoWhitespaceAfterCheckTest
      extends AbstractModuleTestSupport {
  
      @Override
      protected String getPackageLocation() {
          return "com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter";
      }
  
      @Test
      public void testDefault() throws Exception {
          final String[] expected = {
              "10:13: " + getCheckMessage(MSG_KEY, "."),
              "11:11: " + getCheckMessage(MSG_KEY, "."),
              "30:13: " + getCheckMessage(MSG_KEY, "-"),
              "30:20: " + getCheckMessage(MSG_KEY, "+"),
              "32:13: " + getCheckMessage(MSG_KEY, "++"),
              "32:20: " + getCheckMessage(MSG_KEY, "--"),
              "112:21: " + getCheckMessage(MSG_KEY, "!"),
              "113:22: " + getCheckMessage(MSG_KEY, "~"),
              "130:23: " + getCheckMessage(MSG_KEY, "."),
              "133:10: " + getCheckMessage(MSG_KEY, "."),
              "137:11: " + getCheckMessage(MSG_KEY, "."),
              "265:1: " + getCheckMessage(MSG_KEY, "."),
              "290:5: " + getCheckMessage(MSG_KEY, "@"),
              "291:5: " + getCheckMessage(MSG_KEY, "@"),
              "292:5: " + getCheckMessage(MSG_KEY, "@"),
              "297:28: " + getCheckMessage(MSG_KEY, "int"),
              "309:5: " + getCheckMessage(MSG_KEY, "someStuff8"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestDefault.java"), expected);
      }
  
      @Test
      public void testAssignment() throws Exception {
          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestAssignment.java"), expected);
      }
  
      @Test
      public void testDotAllowLineBreaks() throws Exception {
          final String[] expected = {
              "9:13: " + getCheckMessage(MSG_KEY, "."),
              "129:23: " + getCheckMessage(MSG_KEY, "."),
              "136:11: " + getCheckMessage(MSG_KEY, "."),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestAllowLineBreaks.java"), expected);
      }
  
      @Test
      public void testTypecast() throws Exception {
          final String[] expected = {
              "87:20: " + getCheckMessage(MSG_KEY, ")"),
              "89:13: " + getCheckMessage(MSG_KEY, ")"),
              "241:17: " + getCheckMessage(MSG_KEY, ")"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestTypecast.java"), expected);
      }
  
      @Test
      public void testArrayDeclarations() throws Exception {
          final String[] expected = {
              "14:12: " + getCheckMessage(MSG_KEY, "Object"),
              "16:23: " + getCheckMessage(MSG_KEY, "someStuff3"),
              "17:9: " + getCheckMessage(MSG_KEY, "int"),
              "18:14: " + getCheckMessage(MSG_KEY, "s"),
              "19:14: " + getCheckMessage(MSG_KEY, "d"),
              "24:15: " + getCheckMessage(MSG_KEY, "get"),
              "26:9: " + getCheckMessage(MSG_KEY, "int"),
              "27:35: " + getCheckMessage(MSG_KEY, "get1"),
              "36:9: " + getCheckMessage(MSG_KEY, "int"),
              "37:13: " + getCheckMessage(MSG_KEY, "cba"),
              "39:27: " + getCheckMessage(MSG_KEY, "String"),
              "40:28: " + getCheckMessage(MSG_KEY, "String"),
              "47:12: " + getCheckMessage(MSG_KEY, "ar"),
              "47:25: " + getCheckMessage(MSG_KEY, "int"),
              "48:17: " + getCheckMessage(MSG_KEY, "int"),
              "51:65: " + getCheckMessage(MSG_KEY, "getLongMultiArray"),
              "55:27: " + getCheckMessage(MSG_KEY, "}"),
              "57:23: " + getCheckMessage(MSG_KEY, "int"),
              "58:25: " + getCheckMessage(MSG_KEY, "]"),
              "59:36: " + getCheckMessage(MSG_KEY, "}"),
              "60:39: " + getCheckMessage(MSG_KEY, "]"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterArrayDeclarations.java"), expected);
      }
  
      @Test
      public void testArrayDeclarations2() throws Exception {
          final String[] expected = {
              "20:31: " + getCheckMessage(MSG_KEY, "]"),
              "25:41: " + getCheckMessage(MSG_KEY, "create"),
              "26:32: " + getCheckMessage(MSG_KEY, "int"),
              "37:26: " + getCheckMessage(MSG_KEY, "]"),
              "38:29: " + getCheckMessage(MSG_KEY, "int"),
              "38:42: " + getCheckMessage(MSG_KEY, "]"),
              "38:66: " + getCheckMessage(MSG_KEY, "]"),
              "43:47: " + getCheckMessage(MSG_KEY, "int"),
              "43:57: " + getCheckMessage(MSG_KEY, "]"),
              "44:19: " + getCheckMessage(MSG_KEY, "e"),
              "44:24: " + getCheckMessage(MSG_KEY, "]"),
              "44:44: " + getCheckMessage(MSG_KEY, "]"),
              "45:15: " + getCheckMessage(MSG_KEY, "e"),
              "45:19: " + getCheckMessage(MSG_KEY, "]"),
              "50:31: " + getCheckMessage(MSG_KEY, "Integer"),
              "51:21: " + getCheckMessage(MSG_KEY, "]"),
              "56:29: " + getCheckMessage(MSG_KEY, ">"),
              "56:32: " + getCheckMessage(MSG_KEY, "]"),
              "56:35: " + getCheckMessage(MSG_KEY, "]"),
              "60:35: " + getCheckMessage(MSG_KEY, "int"),
              "62:15: " + getCheckMessage(MSG_KEY, "g"),
              "63:18: " + getCheckMessage(MSG_KEY, "]"),
              "64:15: " + getCheckMessage(MSG_KEY, "g"),
              "64:19: " + getCheckMessage(MSG_KEY, "]"),
              "64:23: " + getCheckMessage(MSG_KEY, "]"),
              "70:55: " + getCheckMessage(MSG_KEY, "create"),
              "70:63: " + getCheckMessage(MSG_KEY, "]"),
              "75:33: " + getCheckMessage(MSG_KEY, "boolean"),
              "77:48: " + getCheckMessage(MSG_KEY, "String"),
              "77:52: " + getCheckMessage(MSG_KEY, "]"),
              "78:37: " + getCheckMessage(MSG_KEY, "String"),
              "89:41: " + getCheckMessage(MSG_KEY, "Integer"),
              "93:15: " + getCheckMessage(MSG_KEY, "char"),
              "94:53: " + getCheckMessage(MSG_KEY, "A"),
              "95:70: " + getCheckMessage(MSG_KEY, "Object"),
              "98:43: " + getCheckMessage(MSG_KEY, ")"),
              "98:52: " + getCheckMessage(MSG_KEY, "]"),
              "100:37: " + getCheckMessage(MSG_KEY, "Object"),
              "102:46: " + getCheckMessage(MSG_KEY, ")"),
              "105:43: " + getCheckMessage(MSG_KEY, "Object"),
              "108:45: " + getCheckMessage(MSG_KEY, "]"),
              "116:33: " + getCheckMessage(MSG_KEY, "Object"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterArrayDeclarations2.java"), expected);
      }
  
      @Test
      public void testArrayDeclarations3() throws Exception {
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterArrayDeclarations3.java"));
      }
  
      @Test
      public void testSynchronized() throws Exception {
          final String[] expected = {
              "22:9: " + getCheckMessage(MSG_KEY, "synchronized"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestSynchronized.java"), expected);
      }
  
      @Test
      public void testNpe() throws Exception {
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestNpe.java"));
      }
  
      @Test
      public void testMethodReference() throws Exception {
          final String[] expected = {
              "17:41: " + getCheckMessage(MSG_KEY, "int"),
              "18:62: " + getCheckMessage(MSG_KEY, "String"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestMethodRef.java"), expected);
      }
  
      @Test
      public void testMethodReferenceAfter() throws Exception {
          final String[] expected = {
              "25:35: " + getCheckMessage(MSG_KEY, "::"),
              "26:64: " + getCheckMessage(MSG_KEY, "::"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestMethodRefAfter.java"), expected);
      }
  
      @Test
      public void testArrayDeclarator() throws Exception {
          final String[] expected = {
              "19:32: " + getCheckMessage(MSG_KEY, "Entry"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestArrayDeclarator.java"), expected);
      }
  
      @Test
      public void testVisitTokenSwitchReflection() {
          // unexpected parent for ARRAY_DECLARATOR token
          final DetailAstImpl astImport = mockAST(TokenTypes.IMPORT, "import");
          final DetailAstImpl astArrayDeclarator = mockAST(TokenTypes.ARRAY_DECLARATOR, "[");
          final DetailAstImpl astRightBracket = mockAST(TokenTypes.RBRACK, "[");
          astImport.addChild(astArrayDeclarator);
          astArrayDeclarator.addChild(astRightBracket);
  
          final NoWhitespaceAfterCheck check = new NoWhitespaceAfterCheck();
          try {
              check.visitToken(astArrayDeclarator);
              assertWithMessage("no intended exception thrown").fail();
          }
          catch (IllegalStateException ex) {
              assertWithMessage("Invalid exception message")
                  .that(ex.getMessage())
                  .isEqualTo("unexpected ast syntax import[0x-1]");
          }
      }
  
      @Test
      public void testAllTokens() throws Exception {
          final String[] expected = {
              "10:13: " + getCheckMessage(MSG_KEY, "."),
              "11:11: " + getCheckMessage(MSG_KEY, "."),
              "30:13: " + getCheckMessage(MSG_KEY, "-"),
              "30:20: " + getCheckMessage(MSG_KEY, "+"),
              "32:13: " + getCheckMessage(MSG_KEY, "++"),
              "32:20: " + getCheckMessage(MSG_KEY, "--"),
              "88:20: " + getCheckMessage(MSG_KEY, ")"),
              "90:13: " + getCheckMessage(MSG_KEY, ")"),
              "91:13: " + getCheckMessage(MSG_KEY, ")"),
              "112:21: " + getCheckMessage(MSG_KEY, "!"),
              "113:22: " + getCheckMessage(MSG_KEY, "~"),
              "130:23: " + getCheckMessage(MSG_KEY, "."),
              "133:10: " + getCheckMessage(MSG_KEY, "."),
              "137:11: " + getCheckMessage(MSG_KEY, "."),
              "242:17: " + getCheckMessage(MSG_KEY, ")"),
              "265:1: " + getCheckMessage(MSG_KEY, "."),
              "290:5: " + getCheckMessage(MSG_KEY, "@"),
              "291:5: " + getCheckMessage(MSG_KEY, "@"),
              "292:5: " + getCheckMessage(MSG_KEY, "@"),
              "297:28: " + getCheckMessage(MSG_KEY, "int"),
              "301:18: " + getCheckMessage(MSG_KEY, ")"),
              "309:5: " + getCheckMessage(MSG_KEY, "someStuff8"),
          };
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterTestAllTokens.java"), expected);
      }
  
      @Test
      public void testArrayDeclarationsAndAnnotations() throws Exception {
          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterArrayDeclarationsAndAnno.java"), expected);
      }
  
      @Test
      public void testArrayNewTypeStructure() throws Exception {
          final String[] expected = {
              "53:17: " + getCheckMessage(MSG_KEY, "ci"),
              "54:27: " + getCheckMessage(MSG_KEY, "int"),
              "55:16: " + getCheckMessage(MSG_KEY, "double"),
              "56:62: " + getCheckMessage(MSG_KEY, "cZ"),
              "60:42: " + getCheckMessage(MSG_KEY, "transformers"),
              "61:39: " + getCheckMessage(MSG_KEY, "transformers"),
              "66:19: " + getCheckMessage(MSG_KEY, "a"),
              "67:25: " + getCheckMessage(MSG_KEY, "]"),
              "71:18: " + getCheckMessage(MSG_KEY, "]"),
              "72:25: " + getCheckMessage(MSG_KEY, "]"),
              "90:21: " + getCheckMessage(MSG_KEY, ")"),
              "92:57: " + getCheckMessage(MSG_KEY, "KeyManager"),
              "125:28: " + getCheckMessage(MSG_KEY, ")"),
              "126:28: " + getCheckMessage(MSG_KEY, ")"),
              "130:29: " + getCheckMessage(MSG_KEY, ")"),
              "149:28: " + getCheckMessage(MSG_KEY, "byte"),
              "182:12: " + getCheckMessage(MSG_KEY, "String"),
              "182:20: " + getCheckMessage(MSG_KEY, "f"),
              "214:6: " + getCheckMessage(MSG_KEY, "]"),
              "215:13: " + getCheckMessage(MSG_KEY, "]"),
              "219:5: " + getCheckMessage(MSG_KEY, "]"),
              "220:13: " + getCheckMessage(MSG_KEY, "]"),
              "226:15: " + getCheckMessage(MSG_KEY, "synchronized"),
          };
  
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterNewTypeStructure.java"), expected);
      }
  
      @Test
      public void testArrayNewGenericTypeArgument() throws Exception {
  
          final String[] expected = {
              "59:15: " + getCheckMessage(MSG_KEY, "i"),
              "59:21: " + getCheckMessage(MSG_KEY, "j"),
              "60:25: " + getCheckMessage(MSG_KEY, "u"),
              "61:27: " + getCheckMessage(MSG_KEY, "]"),
              "62:28: " + getCheckMessage(MSG_KEY, "w"),
              "63:21: " + getCheckMessage(MSG_KEY, "x"),
              "63:24: " + getCheckMessage(MSG_KEY, "]"),
              "65:24: " + getCheckMessage(MSG_KEY, "SomeClass"),
              "65:27: " + getCheckMessage(MSG_KEY, "]"),
              "67:27: " + getCheckMessage(MSG_KEY, "SomeClass"),
              "67:53: " + getCheckMessage(MSG_KEY, "ImmediateSubclass"),
              "68:13: " + getCheckMessage(MSG_KEY, "!"),
              "68:50: " + getCheckMessage(MSG_KEY, "ImmediateSubclass"),
              "71:13: " + getCheckMessage(MSG_KEY, "!"),
              "71:46: " + getCheckMessage(MSG_KEY, "FinalSubclass"),
              "74:31: " + getCheckMessage(MSG_KEY, "AnotherInterface"),
          };
  
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterNewGenericTypeArgument.java"), expected);
      }
  
      @Test
      public void testNoWhitespaceAfterWithEmoji() throws Exception {
  
          final String[] expected = {
              "16:16: " + getCheckMessage(MSG_KEY, "String"),
              "16:26: " + getCheckMessage(MSG_KEY, "{"),
              "23:24: " + getCheckMessage(MSG_KEY, "char"),
              "28:22: " + getCheckMessage(MSG_KEY, ")"),
              "28:23: " + getCheckMessage(MSG_KEY, "@"),
              "35:17: " + getCheckMessage(MSG_KEY, "!"),
              "35:22: " + getCheckMessage(MSG_KEY, "."),
          };
  
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterWithEmoji.java"), expected);
      }
  
      @Test
      public void testNoWhitespaceAfterSynchronized() throws Exception {
          final String[] expected = {
              "18:9: " + getCheckMessage(MSG_KEY, "synchronized"),
          };
  
          verifyWithInlineConfigParser(
                  getPath("InputNoWhitespaceAfterSynchronized.java"),
                  expected);
      }
  
      /**
       * Creates MOCK lexical token and returns AST node for this token.
       *
       * @param tokenType type of token
       * @param tokenText text of token
       * @return AST node for the token
       */
      private static DetailAstImpl mockAST(final int tokenType, final String tokenText) {
          final DetailAstImpl astSemi = new DetailAstImpl();
          astSemi.initialize(new CommonToken(tokenType, tokenText));
          return astSemi;
      }
  
  }
  