Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use desciprive file names for test samples.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

package checks.FileHeaderCheck;

public class Class4 {
}
// Compliant

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package checks.FileHeaderCheck;

public class Class5 {
}
// Compliant
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* <Your-Product-Name>
* Copyright (c) <Year-From>-<Year-To> <Your-Company-Name>
*
* Please configure this header in your SonarCloud/SonarQube quality profile.
*/
package checks.FileHeaderCheck;

public class Class6 {
}
// Compliant (default header)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

package checks.FileHeaderCheck;

public class Regex5 {
}
// Compliant
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package checks.FileHeaderCheck;

public class Regex6 {
}
// Compliant
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@
@Rule(key = "S1451")
public class FileHeaderCheck extends IssuableSubscriptionVisitor {

private static final String DEFAULT_HEADER_FORMAT = "";
private static final String DEFAULT_HEADER_FORMAT = """
/*
* <Your-Product-Name>
* Copyright (c) <Year-From>-<Year-To> <Your-Company-Name>
*
* Please configure this header in your SonarCloud/SonarQube quality profile.
*/
""";
private static final String MESSAGE = "Add or update the header of this file.";

@RuleProperty(
Expand All @@ -58,23 +65,28 @@ public List<Tree.Kind> nodesToVisit() {
@Override
public void setContext(JavaFileScannerContext context) {
super.context = context;
if (isRegularExpression) {
if (searchPattern == null) {
try {
searchPattern = Pattern.compile(getHeaderFormat(), Pattern.DOTALL);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("[" + getClass().getSimpleName() + "] Unable to compile the regular expression: " + headerFormat, e);
if (headerFormat.isEmpty()) {
expectedLines = new String[] {};
isRegularExpression = false;
} else {
if (isRegularExpression) {
if (searchPattern == null) {
try {
searchPattern = Pattern.compile(getHeaderFormat(), Pattern.DOTALL);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("[" + getClass().getSimpleName() + "] Unable to compile the regular expression: " + headerFormat, e);
}
}
} else {
expectedLines = headerFormat.split("(?:\r)?\n|\r");
}
} else {
expectedLines = headerFormat.split("(?:\r)?\n|\r");
}
visitFile();
}

private String getHeaderFormat() {
String format = headerFormat;
if(format.charAt(0) != '^') {
if (format.charAt(0) != '^') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's a bad practice to do unintentional chages, because they make it hard to understand what is happening, if someone is reading a PR for some reason in the future.

format = "^" + format;
}
return format;
Expand Down Expand Up @@ -114,7 +126,6 @@ private static boolean matches(String[] expectedLines, List<String> lines) {
} else {
result = false;
}

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,26 @@ void test() {
.onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Class3.java"))
.withCheck(check)
.verifyNoIssues();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these a part of this PR or is it a copied from the other changes?

check = new FileHeaderCheck();
check.headerFormat = "";
CheckVerifier.newVerifier()
.onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Class4.java"))
.withCheck(check)
.verifyNoIssues();

check = new FileHeaderCheck();
check.headerFormat = "";
CheckVerifier.newVerifier()
.onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Class5.java"))
.withCheck(check)
.verifyNoIssues();

check = new FileHeaderCheck();
CheckVerifier.newVerifier()
.onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Class6.java"))
.withCheck(check)
.verifyNoIssues();
Comment on lines +116 to +120
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test verifies that Class6.java (which contains the default header) is compliant — but there is no negative test asserting that a file without the default header gets flagged.

This gap matters concretely: if DEFAULT_HEADER_FORMAT ever became empty (e.g., due to a text-block indentation accident), the headerFormat.isEmpty() branch would fire, set expectedLines = {}, and matches() would return true for any file. The verifyNoIssues() call would still pass, giving a false sense of correctness.

Add a complementary case that runs the default FileHeaderCheck() against a file that lacks the header and asserts an issue is raised — something like:

check = new FileHeaderCheck();
CheckVerifier.newVerifier()
  .onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Class1.java"))
  .withCheck(check)
  .verifyIssueOnFile("Add or update the header of this file.");
  • Mark as noise

}

@Test
Expand Down Expand Up @@ -139,6 +159,22 @@ void regex() {
.onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Regex4.java"))
.withCheck(check)
.verifyIssues();

check = new FileHeaderCheck();
check.headerFormat = "";
check.isRegularExpression = true;
CheckVerifier.newVerifier()
.onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Regex5.java"))
.withCheck(check)
.verifyNoIssues();

check = new FileHeaderCheck();
check.headerFormat = "";
check.isRegularExpression = true;
CheckVerifier.newVerifier()
.onFile(mainCodeSourcesPath("checks/FileHeaderCheck/Regex6.java"))
.withCheck(check)
.verifyNoIssues();
}

@Test
Expand Down
Loading