containsString is undefined - junit5

I have a Junit(5) test case that's looking for an exception when a variable is out of bounds, and I raise an IllegalArgumentException for it.
#Test
void testOutOfBoundsException() {
Foo f = new Foo();
IllegalArgumentException e = assertThrows(
IllegalArgumentException.class,
() -> {
f.checkVal(10);
}
);
assertThat(e, hasMessageThat(containsString("You must enter a number between 0 and")));
}
I get the error
The method containsString(String) is undefined for the type FooTest
I've tried a number of different import statements for JUnit and hamcrest, but I simply can't seem to get this to work.

You have to add a static import for containsString from the org.hamcrest.CoreMatchers class:
import static org.hamcrest.CoreMatchers.containsString;

You can simply use like below instead :
assertThatIllegalArgumentException().isThrownBy(() -> {
f.checkVal(10);
}) .withMessage("You must enter a number between 0 and");
you might need assertj-core :
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>

Thanks to those who posted answers.
In the end I found I could simply do this:
IllegalArgumentException e = assertThrows(
IllegalArgumentException.class,
() -> {
f.checkVal(10);
},
<exception message>);
So I didn't need the second part :)

Related

Unresolved reference: grgit

This is my world server land plug-in, and I don't know much about gradle and kotlin.(Know some front-end, but every line is like a mountain)
I encountered a problem when compiling. It seems that I lack something called grgit.
How to solve this problem?
Or you can try to compile this project. If you succeed, don't forget to tell me your method. Thank you very much!
import java.time.format.DateTimeFormatter
dependencies {
// Expected everywhere.
compileOnlyApi(libs.checkerqual)
// Minecraft expectations
compileOnlyApi(libs.guava)
compileOnlyApi(libs.gson)
// Platform expectations
compileOnlyApi(libs.snakeyaml)
// Adventure
api(libs.adventure)
api(libs.minimessage)
// Guice
api(libs.guice) {
exclude(group = "com.google.guava")
}
api(libs.guiceassistedinject) {
exclude("com.google.inject", "guice")
}
compileOnlyApi(libs.findbugs)
// Plugins
compileOnlyApi(libs.worldeditCore) {
exclude(group = "bukkit-classloader-check")
exclude(group = "mockito-core")
exclude(group = "dummypermscompat")
}
testImplementation(libs.worldeditCore)
compileOnlyApi(libs.fastasyncworldeditCore) { isTransitive = false }
testImplementation(libs.fastasyncworldeditCore) { isTransitive = false }
// Logging
compileOnlyApi(libs.log4j)
// Other libraries
api(libs.prtree)
api(libs.aopalliance)
api(libs.pipeline) {
exclude(group = "com.google.guava")
}
api(libs.arkitektonika)
api(libs.paster)
}
tasks.processResources {
filesMatching("plugin.properties") {
expand(
"version" to project.version.toString(),
"commit" to rootProject.grgit.head().abbreviatedId, // The error points here
"date" to rootProject.grgit.head().dateTime.format(DateTimeFormatter.ofPattern("yy.MM.dd")) // The error points here
)
}
}
Problems arising
Address of this project: https://github.com/IntellectualSites/PlotSquared
Thanks again!
First, you need to declare the grgit variable before using it, that's why you're getting the error.
Add plugin for grgit in the plugins{} block:
id("org.ajoberstar.grgit") version "4.0.2"
Import Grgit like this:
import org.ajoberstar.grgit.Grgit
Then, declare the variable grgit like this:
val grgit = Grgit.open(mapOf("currentDir" to project.rootDir))

How to pass multiple parameters to #ValueSource

I'm trying to perform a parametrized JUnit 5 test, how to accomplish the following?
#ParametrizedTest
#ValueSource //here it seems only one parameter is supported
public void myTest(String parameter, String expectedOutput)
I know I could use #MethodSource but I was wondering if in my case I just need to understand better #ValueSource.
The documentation says:
#ValueSource is one of the simplest possible sources. It lets you
specify a single array of literal values and can only be used for
providing a single argument per parameterized test invocation.
Indeed you need to use #MethodSource for multiple arguments, or implement the ArgumentsProvider interface.
You need jUnit Pioneer and the #CartesianProductTest
https://github.com/junit-pioneer/junit-pioneer
https://junit-pioneer.org/docs/cartesian-product/
POM:
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
Java:
import org.junitpioneer.jupiter.CartesianProductTest;
import org.junitpioneer.jupiter.CartesianValueSource;
#CartesianProductTest
#CartesianValueSource(ints = { 1, 2 })
#CartesianValueSource(ints = { 3, 4 })
void myCartesianTestMethod(int x, int y) {
// passing test code
}
Another approach is to use #CsvSource, which is a bit of a hack, but can autocast stringified values to primitives. If you need array data, then you can implement your own separator and manually split inside the function.
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static com.google.common.truth.Truth.assertThat;
#ParameterizedTest
#CsvSource({
"1, a",
"2, a;b",
"3, a;b;c"
})
void castTermVectorsResponse(Integer size, String encodedList) {
String[] list = encodedList.split(";");
assertThat(size).isEqualTo(list.length);
}

How to register AndroidLintInspectionBase in IntellijIdea Plugin

I'm creating a costum Android Lint Inspection and I need to register the inspection, to be run. Where do I need to register it?
I've already tried to register the inspection which provides the inspection inside plugin.xml file.
The actual inspection:
class HardcodedDimensionsInspection : AndroidLintInspectionBase("Hardcoded dimensions", HardcodedDimensDetector.ISSUE) {
override fun getShortName(): String {
return "AndroidLintHardcodedDimension"
}
}
The entry in plugin.xml file
<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
<!-- <inspectionToolProvider implementation="JavaInspectionProvider"/>-->
<globalInspection shortName="AndroidLintHardcodedDimension" displayName="Hardcoded dimensions"
enabledByDefault="true" level="WARNING"
implementationClass="HardcodedDimensionsInspection"/>
</extensions>
The actual detector
class HardcodedDimensDetector : LayoutDetector() {
override fun getApplicableAttributes(): Collection<String>? {
return Arrays.asList(
// Layouts
ATTR_TEXT
)
}
override fun appliesTo(folderType: ResourceFolderType): Boolean {
return (folderType == ResourceFolderType.LAYOUT ||
folderType == ResourceFolderType.MENU ||
folderType == ResourceFolderType.XML)
}
override fun visitAttribute(context: XmlContext, attribute: Attr) {
val value = attribute.value
}
companion object {
/** The main issue discovered by this detector */
#JvmField
val ISSUE = Issue.create(
id = "HardcodedDimension",
briefDescription = "Hardcoded dimens",
explanation = """
Brief
""",
category = Category.I18N,
priority = 5,
severity = Severity.ERROR,
implementation = Implementation(
HardcodedDimensDetector::class.java,
Scope.RESOURCE_FILE_SCOPE
)
)
}
}
I've expected to hit the breakpoints in any of the functions for Detector but the code is never called. Seems like my detector is not registered. Can you please point me to the missing part, is there a class where I should register my Detector?
Thank you.
The link to the full project: https://github.com/magicbytes/Android-Lint-Inspection
I don't see anything obvious wrong from these snippets. Could you please post on our forum and link to the full sources of your plugin? Thanks. https://intellij-support.jetbrains.com/hc/en-us/community/topics/200366979-IntelliJ-IDEA-Open-API-and-Plugin-Development
I have a workaround for now, not sure it's the official way to do it. Android Lint has a registry with all the Issue classes (built-in), the class is called LintIdeIssueRegistry. When it runs the Android Lint, it's looking in this registry for Issue processors. Since the list is hardcoded, we need to inject ours in the list. I'm using the following code for that:
val registry = LintIdeIssueRegistry()
val issue = registry.getIssue(HardcodedDimensDetector.ISSUE.id)
if (issue == null) {
val list = registry.issues as MutableList<Issue>
list.add(HardcodedDimensDetector.ISSUE)
}
Hopefully in future we will have a method called addIssue inside the LintIdeIssueRegistry.

Hive Udf exception

I have a simple hive UDF:
package com.matthewrathbone.example;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
#Description(
name="SimpleUDFExample",
value="returns 'hello x', where x is whatever you give it (STRING)",
extended="SELECT simpleudfexample('world') from foo limit 1;"
)
class SimpleUDFExample extends UDF {
public Text evaluate(Text input) {
if(input == null) return null;
return new Text("Hello " + input.toString());
}
}
When I am executing it using select query :
select helloUdf(method) from tests3atable limit 10;
method is the name of column in tests3atable table.
I am getting below exception :
FAILED: SemanticException [Error 10014]: Line 1:7 Wrong arguments 'method': Unable to instantiate UDF implementation class com.matthewrathbone.example.SimpleUDFExample: java.lang.IllegalAccessException: Class org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge can not access a member of class com.matthewrathbone.example.SimpleUDFExample with modifiers ""
Declare the class as public, it should work
I also had the same issue. It turned out, eclipse was not refreshing the program which i modified. So please make sure that the modifications you make in your code gets reflected in the jar.

How to tell IDEA/Studio that the null check has been done?

I'm developing with Android Studio/IntelliJ IDEA.
I have enabled the inspection check called "Constant conditions & exceptions" that shows a warning if I am risking a NPE, such as:
String foo = foo.bar(); // Foo#bar() is #nullable
if (foo.contains("bar")) { // I'm living dangerously
...
}
I have the following in my code:
String encoding = contentEncoding == null ? null : contentEncoding.getValue();
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(entity.getContent());
} else {
inputStream = entity.getContent();
}
Here's the source code of TextUtils#isEmpty(String):
/**
* Returns true if the string is null or 0-length.
* #param str the string to be examined
* #return true if str is null or zero length
*/
public static boolean isEmpty(CharSequence str) {
if (str == null || str.length() == 0)
return true;
else
return false;
}
I'm not risking any NPE because TextUtils#isEmpty(String) would return true to a null pointer.
However I'm still getting the little Method invocation 'encoding.equalsIgnoreCase("gzip")' may produce 'java.lang.NullPointerException' warning, which can be annoying.
Is it possible to make this check smarter and ignore the NPE warning if there's already a null-check done?
You can look into the link that Peter Gromov mention in his answer.
Created some simple classes that resemble your setup:
A class with a method annotated with #Nullable:
The TextUtil class with it's isEmpty method:
And finally the main class calling the TextUtil#isEmpty:
Now if you enter the File -> Settings... and go to Inspections ->Constant conditions & exceptions part you can change the Configure Assert/Check Methods to cater for your isEmpty method:
Add a new IsNull check method:
Enter the TextUtil class, isEmpty method and CharSequence parameter:
This gives this Assert/Check Method Configuration window:
Press Ok and then Ok again to go back to the editor view and you'll see that the inspection disappeared:
You are actually telling IntelliJ that the isEmpty method is doing a null check on the str parameter.
You could use //noinspection ConstantConditions that will remove the NPE warning for the following line, like this:
String encoding = contentEncoding == null ? null : contentEncoding.getValue();
//noinspection ConstantConditions
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(entity.getContent());
} else {
inputStream = entity.getContent();
}
You can use #SuppressWarnings("ConstantConditions") annotation.
#SuppressWarnings("ConstantConditions")
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int indexViewType) {
if (inflater == null) {
inflater = LayoutInflater.from(parent.getContext());
}
ItemViewProvider provider = getProviderByIndex(indexViewType);
provider.adapter = MultiTypeAdapter.this;
return provider.onCreateViewHolder(inflater, parent);
}
Select "TextUtils.isEmpty".
Right Click -> Show Context Actions -> Add Method Contract.
Enter "null -> true".
Save the configuration xml.
Please check the details here
See http://www.jetbrains.com/idea/webhelp/configuring-check-assert-methods.html for IDEA 12.
In IDEA 13 EAP, you can add method contract: http://youtrack.jetbrains.com/issue/IDEA-93372
Unfortunately marked as "right answer" solution is of date. But I found equivalent for me solution.
The new versions of IDE work correctly with static methods. So the example from the question won't throw warning anymore.
TextUtils#isEmpty(String);
public static boolean isEmpty(CharSequence str) {
// your checks
}