How to create object from Data class? Kotlin - kotlin

I have a
data class A(){
fun c(){}
} .
I need to create a fake implementation of it for testing, but it says that class must be open. open modifier is incompatible with data class. Any ways to do it?

To mock final classes update mockito
testCompile 'org.mockito:mockito-core:2.8.9'
and then add a folder in your resources folder called mockito-extensions that includes a text file called org.mockito.plugins.MockMaker. Inside there just add
mock-maker-inline
That should solve your problem

Related

What are different between "Inject dependencies into Android classes" and "Generated components for Android classes"?

I'm learning dependency injection by the article.
I'm very confused between "Inject dependencies into Android classes" and "Generated components for Android classes" ? What are different?
For example:
Code A has generated components for Android classes with #InstallIn(ActivityComponent::class), should Code B still add the annotation #AndroidEntryPoint?
Code A
#Module
#InstallIn(ActivityComponent::class)
object AnalyticsModule {
#Provides
fun provideAnalyticsService(
#AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
): AnalyticsService {
return Retrofit.Builder()
.baseUrl("https://example.com")
.client(okHttpClient)
.build()
.create(AnalyticsService::class.java)
}
}
Code B
#AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
#Inject lateinit var mAnalyticsService: AnalyticsService
...
}
Added Content
If I havn't any #Module in my project and add only such as #AndroidEntryPoint before Acitiviy, Hilt automagically creates predetermined Component for me, is it right?
If I have some #Module such as AnalyticsModule in my project and add such as #AndroidEntryPoint before Acitiviy, Hilt automagically creates predetermined Component and my dependency injection provideAnalyticsService for me, is it right?
Inject dependencies into Android classes
This means, that you can inject dependencies (such as AnalyticsService) into android classes (such as Activities, Application or fragments), that are either annotated with #HiltAndroidApp or #AndroidEntryPoint.
If you annotate a fragment or activity with #AndroidEntryPoint, Hilt automagically creates a HiltComponent for this class (the same you do with #Module #InstallIn etc.. just in the background).
The Developers just want to tell you, that you CAN inject something into an android class, BUT you have to annotate them before doing that:
Application (by using #HiltAndroidApp)
ViewModel (by using #HiltViewModel)
Acitiviy (by using #AndroidEntryPoint)
Fragment (by using #AndroidEntryPoint)
etc
Generated components for Android classes
These are the components, that Hilt provides to YOU in order to inject something to it's corresponding class. For example, if you want to provide a dependency to the entire application (every class can access this dependency), than you would use a SingletonComponent. But if you want to provide let's say a dependency only to a viewmodel (no other class should have access to it), that you would install this dependency inside a ViewModelComponent
Edit
If I havn't any #Module in my project and add only such as #AndroidEntryPoint before Acitiviy, Hilt automagically creates predetermined Component for me, is it right?
Yes that is correct, but it only creates such components that hilt need in order to provide any dependency to an activity.
If I have some #Module such as AnalyticsModule in my project and add
such as #AndroidEntryPoint before Acitiviy, Hilt automagically creates
predetermined Component and my dependency injection
provideAnalyticsService for me, is it right?
Yes that is sorta right: With #AndroidEntryPoint hilt makes sure, that every dependency that you provide via #Module #InstallIn(...) can be injected inside a android class. You should not forget the following: Android is a framework and you as a user never create such classes like Activity or Fragment (you write code in it, but don't create them, the framework does this for you). With this in mind, you as a user have to annotate Android-Classes with #AndroidEntryPoint in order to tell hilt, that it should create it's corresponding modules so that you can inject dependencies inside a android-class.

How to move a function from one Kotlin class to another using IntelliJ?

I'm using IntelliJ IDEA to refactor some Kotlin code. I have two classes in the same file and I want to move a function from one class to another using Refactor -> Move (F6), but that doesn't work, and I get tooltip message that says: "Cannot perform refactoring. Move declaration is only supported for top-level declarations and nested classes".
Am I doing something wrong? Or that refactoring is simply not supported?
[edit1] I tried to do the same operation with Java classes and everything works perfectly; so why this is not allowed for Kotlin?
[edit2] I thought that the problem is only when to two classes are in the same file, but it turns out that is not possible to move a function between classes in separate files!
It's a well-known Kotlin-only problem.
in IDEA (both free and paid editions);
in Android Studio.
Official ticket
There is an easy, but slightly janky, work around.
You just need to wrap the function you want to move in a class:
class TopLevelClass {
fun functionToMove() {
//...
}
}
wrap it in a new class
class TopLevelClass {
class TemporaryMoveClass{ /** you can now move this entire new class */
fun functionToMove() {
//...
}
}
}
and after you do the refactor, delete the temporary wrapper class you created.
The janky part is that you need to replace all instances of functionToMove() with NewTopLevelClass.functionToMove() yourself.
One of the major benefits of doing it this way, rather than just cut and pasting it yourself, is that as soon as you wrap it in the TemporaryMoveClass it will tell you any parameters you need to introduce(Refactor>Extract>Parameter). And then you can do that inside the original TopLevelClass before you move it. (this preserves the types of any TopLevelClass properties you were using, and automatically introduces the new parameter(s) into the existing function calls)

Intellij IDEA plugin development. Action "create kotlin class"

I want to create a plugin for Intellij IDEA. I need to add an action (AnAction) that will create a class in Kotlin (not Java) in a custom package. I have two questions:
How to create files with the desired extension?
Or how to create a file with Kotlin class(from some base class) in a custom package?
One possible way to accomplish this is to use PsiFileFactory.createFileFromText() to create an in-memory Kotlin file and then to pass that file as a parameter to PsiDirectory.add() to save it to the filesystem.
Although yole's answer is correct, I would like to see more details about mistery PsiDirectory class.
//get directory by VirtualFile
PsiDirectory directory = PsiManager.getInstance(project).findDirectory((getKotlinSourceDir(project))
Get kotlin source dir:
private VirtualFile getKotlinSourceDir(Project project) {
return project.getBaseDir().findChild("src").findChild("main").findChild("kotlin");
}
And than you can create subdirectories:
//someDirectoryName it is simple name
//(i.e if you post "com.some.package" - it does not create com/some/package folder)
PsiDirectory newDirectory = psiDirectory.createSubdirectory(someDirectoryName);

How to select a different module to run when you click the Run button in IntelliJ IDEA?

In my IntelliJ IDEA project, I have 3 modules written in Kotlin:
An HTTP Servlet one.
A desktop swing application; and
A library that contains contracts that the above two listed projects share to talk to each other.
When I click the Run button, it starts the Tomcat server and loads up my servlet project. That is because, and I am guessing here, the new project creation template inside of the IDE created a new Run Configuration for the entire project and it is defined in this run configuration that it must start the module that has the servlet inside it.
Now that the servlet runs fine, I'd like to also run the desktop application written using Swing.
How do I do that? I've done this once before but I have forgotten how I did it.
Do I have to define a new Run Configuation? I tried that this way:
I selected Kotlin from the left pane titled Add New Configuration and specified the name of the class that had the main function, and also the name of the module that had this class.
Here is the source code of my main class.
package bookyard.client;
import javax.swing.SwingUtilities;
public class Program {
public fun main(args : Array<String>) {
SwingUtilities.invokeLater(LoginDialogEventLoop());
}
}
But when I click the Run button after choosing that run configuration's name, the process reports an error that suggests that the class name I specified as having the main function actually does not have the main function, which I am not sure why that is.
The main method needs to be static, and the method you have declared is not. In Kotlin, you can either declare main as a top-level function (outside of a class), or, if you want to keep it inside the class, use the following syntax:
class Program {
companion object {
#JvmStatic fun main(args: Array<String) { ... }
}
}

Flex Interface method createAutomationIDPartWithRequiredProperties error

I'm currently creating a class that extends UIComponent in Flex 3, but when the flash builder try to compile show me some errors
1044: Interface method createAutomationIDPartWithRequiredProperties in namespace mx.automation:IAutomationObject not implemented by class components:ArtWorkImage
1044: Interface method get automationEnabled in namespace mx.automation:IAutomationObject not implemented by class com.senocular.display:TransformTool
I see that UIComponent implements this interface, but I had never had this error before, I'm assuming UIComponent should made this implementation by default, so it should be something else, I already try to recreate the project or clean it, with no result, can someone please point me how maybe this can be fix, thanks for your help
oh btw I had this project before in flex builder, exported as a FXP and imported in Flash Builder, thanks!
All UI objects use an Automation delegate to handle implementation of the automation interface. Each UIComponent has a specific automation delegate registered with the Automation Framework. These automation delegate implementations are injected into the object by the Automation framework when the object is created according to the class name of the object.
For example:
UIComponent <- UIComponentAutomationImpl
ToolTip <- ToolTipAutomationImpl
DateChooser <- DateChooserAutomationImpl
Normally if you subclass a component you should inherit the Automation Implementation. However depending upon how the instances of the object are being created the automation framework may not be able to resolve the class name to the appropriate super class. In this case you may need to take additional steps to get the automation implementation into your class.
If you want your class to automatically be injected with a particulary automation implementation you should call the static registerDelegateClass method on the mx.automation.Automation class.
import mx.automation.*
Automation.registerDelegateClass(com.foo.bar.ArtWorkImage, mx.automation.delelegates.core.UIComponentAutomationImpl);
Alternatively you could directly implement the IAutomationObject methods in your UIComponent or create your own delegate class and instantiate and "inject" it into your class in its' constructor thereby by passing the Automation framework.
Here are few links that might help you understand the automation framework:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/automation/Automation.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/automation/delegates/core/UIComponentAutomationImpl.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/automation/package-detail.html