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.utils;
  
  import static com.google.common.truth.Truth.assertThat;
  import static com.google.common.truth.Truth.assertWithMessage;
  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor;
  import static org.junit.jupiter.api.Assertions.assertThrows;
  import static org.mockito.Mockito.CALLS_REAL_METHODS;
  import static org.mockito.Mockito.mock;
  import static org.mockito.Mockito.mockStatic;
  import static org.mockito.Mockito.when;
  
  import java.io.Closeable;
  import java.io.File;
  import java.io.IOException;
  import java.lang.reflect.Constructor;
  import java.net.URI;
  import java.net.URISyntaxException;
  import java.net.URL;
  import java.nio.charset.StandardCharsets;
  import java.util.Dictionary;
  import java.util.Properties;
  import java.util.regex.Pattern;
  
  import org.apache.commons.io.IOUtils;
  import org.junit.jupiter.api.Test;
  import org.mockito.MockedStatic;
  
  import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
  import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
  import com.puppycrawl.tools.checkstyle.PropertiesExpander;
  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
  import com.puppycrawl.tools.checkstyle.api.Configuration;
  
  public class CommonUtilTest extends AbstractPathTestSupport {
  
      /** After appending to path produces equivalent, but denormalized path. */
      private static final String PATH_DENORMALIZER = "/levelDown/.././";
  
      @Override
      protected String getPackageLocation() {
          return "com/puppycrawl/tools/checkstyle/utils/commonutil";
      }
  
      @Test
      public void testIsProperUtilsClass() throws ReflectiveOperationException {
          assertWithMessage("Constructor is not private")
                  .that(isUtilsClassHasPrivateConstructor(CommonUtil.class))
                  .isTrue();
      }
  
      /**
       * Test CommonUtil.countCharInString.
       */
      @Test
      public void testLengthExpandedTabs() {
          final String s1 = "\t";
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthExpandedTabs(s1, s1.length(), 8))
              .isEqualTo(8);
  
          final String s2 = "  \t";
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthExpandedTabs(s2, s2.length(), 8))
              .isEqualTo(8);
  
          final String s3 = "\t\t";
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthExpandedTabs(s3, s3.length(), 8))
              .isEqualTo(16);
  
          final String s4 = " \t ";
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthExpandedTabs(s4, s4.length(), 8))
              .isEqualTo(9);
  
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthMinusTrailingWhitespace(""))
              .isEqualTo(0);
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthMinusTrailingWhitespace(" \t "))
              .isEqualTo(0);
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthMinusTrailingWhitespace(" 23"))
              .isEqualTo(3);
          assertWithMessage("Invalid expanded tabs length")
              .that(CommonUtil.lengthMinusTrailingWhitespace(" 23 \t "))
              .isEqualTo(3);
      }
  
      @Test
      public void testCreatePattern() {
          assertWithMessage("invalid pattern")
              .that(CommonUtil.createPattern("Test").pattern())
              .isEqualTo("Test");
          assertWithMessage("invalid pattern")
              .that(CommonUtil.createPattern(".*Pattern.*")
                  .pattern())
              .isEqualTo(".*Pattern.*");
      }
  
      @Test
      public void testBadRegex() {
          final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
              CommonUtil.createPattern("[");
          });
          assertWithMessage("Invalid exception message")
                  .that(ex)
                  .hasMessageThat()
                          .isEqualTo("Failed to initialise regular expression [");
      }
  
      @Test
      public void testBadRegex2() {
          final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
              CommonUtil.createPattern("[", Pattern.MULTILINE);
          });
          assertWithMessage("Invalid exception message")
                  .that(ex)
                  .hasMessageThat()
                          .isEqualTo("Failed to initialise regular expression [");
      }
  
      @Test
      public void testFileExtensions() {
          final String[] fileExtensions = {"java"};
          final File pdfFile = new File("file.pdf");
          assertWithMessage("Invalid file extension")
                  .that(CommonUtil.matchesFileExtension(pdfFile, fileExtensions))
                  .isFalse();
          assertWithMessage("Invalid file extension")
                  .that(CommonUtil.matchesFileExtension(pdfFile))
                  .isTrue();
          assertWithMessage("Invalid file extension")
                  .that(CommonUtil.matchesFileExtension(pdfFile, (String[]) null))
                  .isTrue();
          final File javaFile = new File("file.java");
          assertWithMessage("Invalid file extension")
                  .that(CommonUtil.matchesFileExtension(javaFile, fileExtensions))
                  .isTrue();
          final File emptyExtensionFile = new File("file.");
          assertWithMessage("Invalid file extension")
                  .that(CommonUtil.matchesFileExtension(emptyExtensionFile, ""))
                  .isTrue();
          assertWithMessage("Invalid file extension")
                  .that(CommonUtil.matchesFileExtension(pdfFile, ".noMatch"))
                  .isFalse();
          assertWithMessage("Invalid file extension")
                  .that(CommonUtil.matchesFileExtension(pdfFile, ".pdf"))
                  .isTrue();
      }
  
      @Test
      public void testHasWhitespaceBefore() {
          assertWithMessage("Invalid result")
                  .that(CommonUtil.hasWhitespaceBefore(0, "a"))
                  .isTrue();
          assertWithMessage("Invalid result")
                  .that(CommonUtil.hasWhitespaceBefore(4, "    a"))
                  .isTrue();
          assertWithMessage("Invalid result")
                  .that(CommonUtil.hasWhitespaceBefore(5, "    a"))
                  .isFalse();
      }
  
      @Test
      public void testBaseClassNameForCanonicalName() {
          assertWithMessage("Invalid base class name")
              .that(CommonUtil.baseClassName("java.util.List"))
              .isEqualTo("List");
      }
  
      @Test
      public void testBaseClassNameForSimpleName() {
          assertWithMessage("Invalid base class name")
              .that(CommonUtil.baseClassName("Set"))
              .isEqualTo("Set");
      }
  
      @Test
      public void testRelativeNormalizedPath() {
          final String relativePath = CommonUtil.relativizeAndNormalizePath("/home", "/home/test");
  
          assertWithMessage("Invalid relative path")
              .that(relativePath)
              .isEqualTo("test");
      }
  
      @Test
      public void testRelativeNormalizedPathWithNullBaseDirectory() {
          final String relativePath = CommonUtil.relativizeAndNormalizePath(null, "/tmp");
  
          assertWithMessage("Invalid relative path")
              .that(relativePath)
              .isEqualTo("/tmp");
      }
  
      @Test
      public void testRelativeNormalizedPathWithDenormalizedBaseDirectory() throws IOException {
          final String sampleAbsolutePath = new File("src/main/java").getCanonicalPath();
          final String absoluteFilePath = sampleAbsolutePath + "/SampleFile.java";
          final String basePath = sampleAbsolutePath + PATH_DENORMALIZER;
  
          final String relativePath = CommonUtil.relativizeAndNormalizePath(basePath,
              absoluteFilePath);
  
          assertWithMessage("Invalid relative path")
              .that(relativePath)
              .isEqualTo("SampleFile.java");
      }
  
      @Test
      public void testPattern() {
          final boolean result = CommonUtil.isPatternValid("someValidPattern");
          assertWithMessage("Should return true when pattern is valid")
                  .that(result)
                  .isTrue();
      }
  
      @Test
      public void testInvalidPattern() {
          final boolean result = CommonUtil.isPatternValid("some[invalidPattern");
          assertWithMessage("Should return false when pattern is invalid")
                  .that(result)
                  .isFalse();
      }
  
      @Test
      public void testGetExistingConstructor() throws NoSuchMethodException {
          final Constructor<?> constructor = CommonUtil.getConstructor(String.class, String.class);
  
          assertWithMessage("Invalid constructor")
              .that(constructor)
              .isEqualTo(String.class.getConstructor(String.class));
      }
  
      @Test
      public void testGetNonExistentConstructor() {
          final IllegalStateException ex = assertThrows(IllegalStateException.class, () -> {
              CommonUtil.getConstructor(Math.class);
          });
          assertWithMessage("Invalid exception cause")
                  .that(ex)
                  .hasCauseThat()
                          .isInstanceOf(NoSuchMethodException.class);
      }
  
      @Test
      public void testInvokeConstructor() throws NoSuchMethodException {
          final Constructor<String> constructor = String.class.getConstructor(String.class);
  
          final String constructedString = CommonUtil.invokeConstructor(constructor, "string");
  
          assertWithMessage("Invalid construction result")
              .that(constructedString)
              .isEqualTo("string");
      }
  
      @SuppressWarnings("rawtypes")
      @Test
      public void testInvokeConstructorThatFails() throws NoSuchMethodException {
          final Constructor<Dictionary> constructor = Dictionary.class.getConstructor();
          final IllegalStateException ex = assertThrows(IllegalStateException.class, () -> {
              CommonUtil.invokeConstructor(constructor);
          });
          assertWithMessage("Invalid exception cause")
                  .that(ex)
                  .hasCauseThat()
                          .isInstanceOf(InstantiationException.class);
      }
  
      @Test
      public void testClose() {
          final TestCloseable closeable = new TestCloseable();
  
          CommonUtil.close(null);
          CommonUtil.close(closeable);
  
          assertWithMessage("Should be closed")
                  .that(closeable.closed)
                  .isTrue();
      }
  
      @Test
      public void testCloseWithException() {
          final IllegalStateException ex = assertThrows(IllegalStateException.class, () -> {
              CommonUtil.close(() -> {
                  throw new IOException("Test IOException");
              });
          });
          assertWithMessage("Invalid exception message")
                  .that(ex)
                  .hasMessageThat()
                          .isEqualTo("Cannot close the stream");
      }
  
      @Test
      public void testFillTemplateWithStringsByRegexp() {
          assertWithMessage("invalid result")
              .that(CommonUtil.fillTemplateWithStringsByRegexp("template",
                  "lineToPlaceInTemplate", Pattern.compile("NO MATCH")))
              .isEqualTo("template");
          assertWithMessage("invalid result")
              .that(CommonUtil.fillTemplateWithStringsByRegexp("before $0 after", "word",
                          Pattern.compile("\\w+")))
              .isEqualTo("before word after");
          assertWithMessage("invalid result")
              .that(CommonUtil.fillTemplateWithStringsByRegexp("before $0 after1 $1 after2 $2 after3",
                          "word 123", Pattern.compile("(\\w+) (\\d+)")))
              .isEqualTo("before word 123 after1 word after2 123 after3");
      }
  
      @Test
      public void testGetFileNameWithoutExtension() {
          assertWithMessage("invalid result")
              .that(CommonUtil.getFileNameWithoutExtension("filename"))
              .isEqualTo("filename");
          assertWithMessage("invalid result")
              .that(CommonUtil.getFileNameWithoutExtension("filename.extension"))
              .isEqualTo("filename");
          assertWithMessage("invalid result")
              .that(CommonUtil.getFileNameWithoutExtension("filename.subext.extension"))
              .isEqualTo("filename.subext");
      }
  
      @Test
      public void testGetFileExtension() {
          assertWithMessage("Invalid extension")
              .that(CommonUtil.getFileExtension("filename"))
              .isEqualTo("");
          assertWithMessage("Invalid extension")
              .that(CommonUtil.getFileExtension("filename.extension"))
              .isEqualTo("extension");
          assertWithMessage("Invalid extension")
              .that(CommonUtil.getFileExtension("filename.subext.extension"))
              .isEqualTo("extension");
      }
  
      @Test
      public void testIsIdentifier() {
          assertWithMessage("Should return true when valid identifier is passed")
                  .that(CommonUtil.isIdentifier("aValidIdentifier"))
                  .isTrue();
      }
  
      @Test
      public void testIsIdentifierEmptyString() {
          assertWithMessage("Should return false when empty string is passed")
                  .that(CommonUtil.isIdentifier(""))
                  .isFalse();
      }
  
      @Test
      public void testIsIdentifierInvalidFirstSymbol() {
          assertWithMessage("Should return false when invalid identifier is passed")
                  .that(CommonUtil.isIdentifier("1InvalidIdentifier"))
                  .isFalse();
      }
  
      @Test
      public void testIsIdentifierInvalidSymbols() {
          assertWithMessage("Should return false when invalid identifier is passed")
                  .that(CommonUtil.isIdentifier("invalid#Identifier"))
                  .isFalse();
      }
  
      @Test
      public void testIsName() {
          assertWithMessage("Should return true when valid name is passed")
                  .that(CommonUtil.isName("a.valid.Nam3"))
                  .isTrue();
      }
  
      @Test
      public void testIsNameEmptyString() {
          assertWithMessage("Should return false when empty string is passed")
                  .that(CommonUtil.isName(""))
                  .isFalse();
      }
  
      @Test
      public void testIsNameInvalidFirstSymbol() {
          assertWithMessage("Should return false when invalid name is passed")
                  .that(CommonUtil.isName("1.invalid.name"))
                  .isFalse();
      }
  
      @Test
      public void testIsNameEmptyPart() {
          assertWithMessage("Should return false when name has empty part")
                  .that(CommonUtil.isName("invalid..name"))
                  .isFalse();
      }
  
      @Test
      public void testIsNameEmptyLastPart() {
          assertWithMessage("Should return false when name has empty part")
                  .that(CommonUtil.isName("invalid.name."))
                  .isFalse();
      }
  
      @Test
      public void testIsNameInvalidSymbol() {
          assertWithMessage("Should return false when invalid name is passed")
                  .that(CommonUtil.isName("invalid.name#42"))
                  .isFalse();
      }
  
      @Test
      public void testIsBlank() {
          assertWithMessage("Should return false when string is not empty")
                  .that(CommonUtil.isBlank("string"))
                  .isFalse();
      }
  
      @Test
      public void testIsBlankAheadWhitespace() {
          assertWithMessage("Should return false when string is not empty")
                  .that(CommonUtil.isBlank("  string"))
                  .isFalse();
      }
  
      @Test
      public void testIsBlankBehindWhitespace() {
          assertWithMessage("Should return false when string is not empty")
                  .that(CommonUtil.isBlank("string    "))
                  .isFalse();
      }
  
      @Test
      public void testIsBlankWithWhitespacesAround() {
          assertWithMessage("Should return false when string is not empty")
                  .that(CommonUtil.isBlank("    string    "))
                  .isFalse();
      }
  
      @Test
      public void testIsBlankWhitespaceInside() {
          assertWithMessage("Should return false when string is not empty")
                  .that(CommonUtil.isBlank("str    ing"))
                  .isFalse();
      }
  
      @Test
      public void testIsBlankNullString() {
          assertWithMessage("Should return true when string is null")
                  .that(CommonUtil.isBlank(null))
                  .isTrue();
      }
  
      @Test
      public void testIsBlankWithEmptyString() {
          assertWithMessage("Should return true when string is empty")
                  .that(CommonUtil.isBlank(""))
                  .isTrue();
      }
  
      @Test
      public void testIsBlankWithWhitespacesOnly() {
          assertWithMessage("Should return true when string contains only spaces")
                  .that(CommonUtil.isBlank("   "))
                  .isTrue();
      }
  
      @Test
      public void testIsIntValidString() {
          assertWithMessage("Should return true when string is null")
                  .that(CommonUtil.isInt("42"))
                  .isTrue();
      }
  
      @Test
      public void testIsIntInvalidString() {
          assertWithMessage("Should return false when object passed is not integer")
                  .that(CommonUtil.isInt("foo"))
                  .isFalse();
      }
  
      @Test
      public void testIsIntNull() {
          assertWithMessage("Should return false when null is passed")
                  .that(CommonUtil.isInt(null))
                  .isFalse();
      }
  
      @Test
      public void testGetUriByFilenameFindsAbsoluteResourceOnClasspath() throws Exception {
          final String filename =
              "/" + getPackageLocation() + "/InputCommonUtilTest_empty_checks.xml";
          final URI uri = CommonUtil.getUriByFilename(filename);
  
          final Properties properties = System.getProperties();
          final Configuration config = ConfigurationLoader.loadConfiguration(uri.toString(),
              new PropertiesExpander(properties));
          assertWithMessage("Unexpected config name!")
              .that(config.getName())
              .isEqualTo("Checker");
      }
  
      @Test
      public void testGetUriByFilenameFindsRelativeResourceOnClasspath() throws Exception {
          final String filename =
              getPackageLocation() + "/InputCommonUtilTest_empty_checks.xml";
          final URI uri = CommonUtil.getUriByFilename(filename);
  
          final Properties properties = System.getProperties();
          final Configuration config = ConfigurationLoader.loadConfiguration(uri.toString(),
              new PropertiesExpander(properties));
          assertWithMessage("Unexpected config name!")
              .that(config.getName())
              .isEqualTo("Checker");
      }
  
      /**
       * This test illustrates #6232.
       * Without fix, the assertion will fail because the URL under test
       * "com/puppycrawl/tools/checkstyle/utils/commonutil/InputCommonUtilTest_resource.txt"
       * will be interpreted relative to the current package
       * "com/puppycrawl/tools/checkstyle/utils/"
       */
      @Test
      public void testGetUriByFilenameFindsResourceRelativeToRootClasspath() throws Exception {
          final String filename =
                  getPackageLocation() + "/InputCommonUtilTest_resource.txt";
          final URI uri = CommonUtil.getUriByFilename(filename);
          assertWithMessage("URI is null for: " + filename)
              .that(uri)
              .isNotNull();
          final String uriRelativeToPackage =
                  "com/puppycrawl/tools/checkstyle/utils/"
                          + getPackageLocation() + "/InputCommonUtilTest_resource.txt";
          assertWithMessage("URI is relative to package " + uriRelativeToPackage)
              .that(uri.toString())
              .doesNotContain(uriRelativeToPackage);
          final String content = IOUtils.toString(uri.toURL(), StandardCharsets.UTF_8);
          assertWithMessage("Content mismatches for: " + uri)
              .that(content)
              .startsWith("good");
      }
  
      @Test
      public void testGetUriByFilenameClasspathPrefixLoadConfig() throws Exception {
          final String filename = CommonUtil.CLASSPATH_URL_PROTOCOL
              + getPackageLocation() + "/InputCommonUtilTestWithChecks.xml";
          final URI uri = CommonUtil.getUriByFilename(filename);
  
          final Properties properties = System.getProperties();
          final Configuration config = ConfigurationLoader.loadConfiguration(uri.toString(),
              new PropertiesExpander(properties));
          assertWithMessage("Unexpected config name!")
              .that(config.getName())
              .isEqualTo("Checker");
      }
  
      @Test
      public void testGetUriByFilenameFindsRelativeResourceOnClasspathPrefix() throws Exception {
          final String filename = CommonUtil.CLASSPATH_URL_PROTOCOL
              + getPackageLocation() + "/InputCommonUtilTest_empty_checks.xml";
          final URI uri = CommonUtil.getUriByFilename(filename);
  
          final Properties properties = System.getProperties();
          final Configuration config = ConfigurationLoader.loadConfiguration(uri.toString(),
              new PropertiesExpander(properties));
          assertWithMessage("Unexpected config name!")
              .that(config.getName())
              .isEqualTo("Checker");
      }
  
      @Test
      public void testIsCodePointWhitespace() {
          final int[] codePoints = " 123".codePoints().toArray();
          assertThat(CommonUtil.isCodePointWhitespace(codePoints, 0))
                  .isTrue();
          assertThat(CommonUtil.isCodePointWhitespace(codePoints, 1))
                  .isFalse();
      }
  
      @Test
      public void testLoadSuppressionsUriSyntaxException() throws Exception {
          final URL configUrl = mock(URL.class);
          when(configUrl.toURI()).thenThrow(URISyntaxException.class);
          try (MockedStatic<CommonUtil> utilities =
                       mockStatic(CommonUtil.class, CALLS_REAL_METHODS)) {
              final String fileName = "/suppressions_none.xml";
              utilities.when(() -> CommonUtil.getCheckstyleResource(fileName))
                      .thenReturn(configUrl);
  
              final CheckstyleException ex = assertThrows(CheckstyleException.class, () -> {
                  CommonUtil.getUriByFilename(fileName);
              });
              assertWithMessage("Invalid exception cause")
                      .that(ex)
                      .hasCauseThat()
                              .isInstanceOf(URISyntaxException.class);
              assertWithMessage("Invalid exception message")
                      .that(ex)
                      .hasMessageThat()
                              .isEqualTo("Unable to find: " + fileName);
          }
      }
  
      private static final class TestCloseable implements Closeable {
  
          private boolean closed;
  
          @Override
          public void close() {
              closed = true;
          }
  
      }
  
  }
  