Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/846 alchemist golden test support #887

Merged
merged 15 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 12 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
11 changes: 7 additions & 4 deletions extensions/intellij/intellij_generator_plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group 'com.rx_bloc'
version '3.0.4'
version '3.1.0'


apply plugin: 'org.jetbrains.intellij'
Expand Down Expand Up @@ -55,6 +55,9 @@ patchPluginXml {
changeNotes """
<ul>
<li>
v.3.1.0 - Added the option to choose between the `golden_toolkit` and `alchemist` packages when creating golden tests.
</li>
<li>
v.3.0.4 - Replaced deprecated classes from external libraries with their updated counterparts to ensure compatibility and improve performance
</li>
<li>
Expand Down Expand Up @@ -90,7 +93,7 @@ patchPluginXml {
<li>v1.5.0
<br /> - Updated DI Dependencies to not be a singleton</li>
<br /> - Added an improvement to the - Wrap With Quick Action Support -
to analyze, filter and display a choose BloC states dialog - based on the file names and path - by the convension:
to analyze, filter and display a choose BloC states dialog - based on the file names and path - by the convention:
<br /> feature_xx
<br /> -- bloc / xx_bloc.dart
<br /> -- di
Expand All @@ -104,8 +107,8 @@ patchPluginXml {
<br /> - Introduce "New -> RxBloc List".
<br /> - Wrap With Quick Action Support (RxBlocBuilder, RxResultBuilder, RxPaginatedBuilder, RxBlocListener, RxFormFieldBuilder, RxTextFormFieldBuilder).
</li>
<li>v1.3.0 - Added option for creating an entire feature that includes bloc, page and dependency inhection</li>
<li>v1.2.0 - Added option for creating Null Safety BloC claseses</li>
<li>v1.3.0 - Added option for creating an entire feature that includes bloc, page and dependency injection</li>
<li>v1.2.0 - Added option for creating Null Safety BloC classes</li>
<li>v1.1.0 - Added option for creating BloC extensions</li>
<li>v1.0.0 - Initial release</li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.primeholding.rxbloc_generator_plugin.action.GenerateRxBlocTestDialog.TestLibrary
import com.primeholding.rxbloc_generator_plugin.generator.RxTestGeneratorBase
import com.primeholding.rxbloc_generator_plugin.generator.parser.Utils
import com.primeholding.rxbloc_generator_plugin.intention_action.BlocWrapWithIntentionAction
import java.io.File


class BootstrapSingleTestAction : AnAction() {
class BootstrapSingleTestAction : AnAction(), GenerateRxBlocTestDialog.Listener {

private var project: Project? = null
private var selectedFile: VirtualFile? = null

override fun update(e: AnActionEvent?) {
super.update(e)
Expand Down Expand Up @@ -68,30 +70,32 @@ class BootstrapSingleTestAction : AnAction() {

var file: VirtualFile?

if (e != null) {
WriteCommandAction.runWriteCommandAction(e.project!!) {
if (project != null) {
WriteCommandAction.runWriteCommandAction(project) {
CommandProcessor.getInstance().executeCommand(
e.project!!, {
project, {
for (i in 0..files?.size!!) {
file = files[i]
if (!file!!.isDirectory) {
if (isBlocFile(file)) {
generateBloc(file!!, e.project!!)
generateBloc(file!!, project!!)
break
}

if (isServiceFile(file)) {
generateService(file!!, e.project!!)
generateService(file!!, project!!)
break
}

if (isRepositoryFile(file)) {
generateRepository(file!!, e.project!!)
generateRepository(file!!, project!!)
break
}

if (isUIFile(file)) {
generateGoldenTest(file!!, e.project!!)
selectedFile = file
val dialog = GenerateRxBlocTestDialog(this)
dialog.show()
break
}
}
Expand Down Expand Up @@ -125,6 +129,12 @@ class BootstrapSingleTestAction : AnAction() {
return false
}

override fun onGenerateBlocTestClicked(selectedTestLibrary: TestLibrary) {
if(selectedFile != null) {
generateGoldenTest(selectedFile!!, project!!, selectedTestLibrary)
}
}

private fun projectLibFolder(): String = "${project?.name}${File.separator}lib"
private fun projectLibAbsolutePath(): String = "${project?.basePath}${File.separator}lib"
private fun projectTestFolder(): String = "${project?.name}${File.separator}test"
Expand Down Expand Up @@ -329,15 +339,9 @@ class BootstrapSingleTestAction : AnAction() {
}


val newFile = Utils.baseDir(project.basePath!!);
val newFile = Utils.baseDir(project.basePath!!)
FileUtil.createIfDoesntExist(File(newFilePath))


// val newFile = VfsTestUtil.createFile(
// Utils.baseDir(project.basePath!!),
// newFilePath
// )

BootstrapTestsAction.writeBlockTest(
newFile,
bloc,
Expand All @@ -348,7 +352,7 @@ class BootstrapSingleTestAction : AnAction() {
}
}

private fun generateGoldenTest(file: VirtualFile, project: Project) {
private fun generateGoldenTest(file: VirtualFile, project: Project, selectedTestLibrary: TestLibrary) {
val constructorFields: MutableMap<String, String> = mutableMapOf()
val constructorNamedFields: MutableMap<String, Boolean> = mutableMapOf()
val goldenFile = File(file.path)
Expand Down Expand Up @@ -417,36 +421,9 @@ Scaffold(
}
sb = StringBuffer()

sb.append(
"""
import 'package:flutter_test/flutter_test.dart';

import '../../helpers/golden_helper.dart';
import '../../helpers/models/scenario.dart';
import '${blocSnakeCase}_factory.dart';
import 'package:rx_bloc/rx_bloc.dart';
import 'package:rx_bloc_list/models.dart';
val goldenFileContent = (if (selectedTestLibrary == TestLibrary.GoldenToolkit) createGoldenToolkitFileContent(blocFieldCase, blocSnakeCase) else createAlchemistGoldenFileContent(blocFieldCase, blocSnakeCase))


void main () {
runGoldenTests(
[
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(), //example: Stubs.emptyList
scenario: Scenario(name: '${blocSnakeCase}_empty')),
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(), //example: Stubs.success
scenario: Scenario(name: '${blocSnakeCase}_success')),
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(), //loading
scenario: Scenario(name: '${blocSnakeCase}_loading')),
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(),
scenario: Scenario(name: '${blocSnakeCase}_error'))
]);
}
""".trimIndent()
)
sb.append(goldenFileContent)

newFile = createFile(file, "_golden_test.dart", sb.toString())
if (newFile != null) {
Expand All @@ -466,4 +443,69 @@ void main () {
}
return sb.toString()
}


private fun createGoldenToolkitFileContent(blocFieldCase: String, blocSnakeCase: String): String =
"""
import 'package:flutter_test/flutter_test.dart';

import '../../helpers/golden_helper.dart';
import '../../helpers/models/scenario.dart';
import '${blocSnakeCase}_factory.dart';
import 'package:rx_bloc/rx_bloc.dart';
import 'package:rx_bloc_list/models.dart';


void main () {
runGoldenTests(
[
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(), //example: Stubs.emptyList
scenario: Scenario(name: '${blocSnakeCase}_empty')),
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(), //example: Stubs.success
scenario: Scenario(name: '${blocSnakeCase}_success')),
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(), //loading
scenario: Scenario(name: '${blocSnakeCase}_loading')),
generateDeviceBuilder(
widget: ${blocFieldCase}Factory(),
scenario: Scenario(name: '${blocSnakeCase}_error'))
]);
}
""".trimIndent()

private fun createAlchemistGoldenFileContent(blocFieldCase: String, blocSnakeCase: String): String =
"""
import 'package:flutter_test/flutter_test.dart';

import '../../helpers/golden_helper.dart';
import '../../helpers/models/scenario.dart';
import '${blocSnakeCase}_factory.dart';
import 'package:rx_bloc/rx_bloc.dart';
import 'package:rx_bloc_list/models.dart';


void main () {
runGoldenTests(
[
buildScenario(
scenario: '${blocSnakeCase}_empty',
widget: ${blocFieldCase}Factory(),
),
buildScenario(
scenario: '${blocSnakeCase}_success',
widget: ${blocFieldCase}Factory(),
),
buildScenario(
scenario: '${blocSnakeCase}_loading',
widget: ${blocFieldCase}Factory(),
),
buildScenario(
scenario: '${blocSnakeCase}_error',
widget: ${blocFieldCase}Factory(),
),
]);
}
""".trimIndent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,27 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
import com.primeholding.rxbloc_generator_plugin.action.GenerateRxBlocTestDialog.TestLibrary
import com.primeholding.rxbloc_generator_plugin.generator.parser.TestableClass
import com.primeholding.rxbloc_generator_plugin.generator.parser.Utils
import com.primeholding.rxbloc_generator_plugin.ui.ChooseBlocsDialog
import java.io.File


class BootstrapTestsAction : AnAction() {
class BootstrapTestsAction : AnAction(), GenerateRxBlocTestDialog.Listener {

private lateinit var event: AnActionEvent

override fun actionPerformed(e: AnActionEvent) {
event = e
val dialog = GenerateRxBlocTestDialog(this)
dialog.show()
}

override fun onGenerateBlocTestClicked(selectedTestLibrary: TestLibrary) {
generate(selectedTestLibrary)
}

override fun update(e: AnActionEvent?) {
super.update(e)
val files = e?.dataContext?.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY)
Expand Down Expand Up @@ -66,21 +80,17 @@ class BootstrapTestsAction : AnAction() {
return false
}

private fun isChooseBlogsDialog(file: VirtualFile): Boolean {
if (file.isDirectory && (file.name == "lib" || file.name == "src" || file.name == "test")) {
return true
}
return false
}
private fun isChooseBlogsDialog(file: VirtualFile): Boolean =
file.isDirectory && (file.name == "lib" || file.name == "src" || file.name == "test")

override fun actionPerformed(e: AnActionEvent?) {
private fun generate(selectedTestLibrary: TestLibrary) {

val allowedPrefixes = listOf("feature_", "lib_")

e?.project?.basePath?.let { baseDir ->
event.project?.basePath?.let { baseDir ->

var isShowDialog = false
val files = e.dataContext.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY)
val files = event.dataContext.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY)


val potentialBlocFolders = mutableListOf<VirtualFile>()
Expand Down Expand Up @@ -118,7 +128,7 @@ class BootstrapTestsAction : AnAction() {
val dialog = ChooseBlocsDialog(parsedLib, selected)
val showAndGet = dialog.showAndGet()
if (showAndGet) {
writeItIntoTests(test, selected, trueBaseDir.name, e.project!!, dialog.includeDiMocks())
writeItIntoTests(test, selected, trueBaseDir.name, event.project!!, dialog.includeDiMocks(), selectedTestLibrary)
}
}
} else {
Expand All @@ -129,13 +139,13 @@ class BootstrapTestsAction : AnAction() {
}
if (list.isEmpty()) {
Messages.showMessageDialog(
"No BloCs Found in the selected direcoty that follow naming convention",
"No BloCs Found in the selected directory that follow naming convention",
"No Blocs",
null
)
return
}
writeItIntoTests(test, list, trueBaseDir.name, e.project!!, true)//potentially choose the flag
writeItIntoTests(test, list, trueBaseDir.name, event.project!!, true, selectedTestLibrary)//potentially choose the flag
}
}
}
Expand All @@ -145,7 +155,8 @@ class BootstrapTestsAction : AnAction() {
blocs: List<TestableClass>,
projectName: String,
project: Project,
includeDiMocks: Boolean
includeDiMocks: Boolean,
selectedTestLibrary: TestLibrary
) {
val blocFileExt = "_bloc.dart"
WriteCommandAction.runWriteCommandAction(project) {
Expand Down Expand Up @@ -188,7 +199,8 @@ class BootstrapTestsAction : AnAction() {
folder = featureFolder.createChildDirectory(this, "view")
testFile = folder.createChildData(this, bloc.file.name.replace(blocFileExt, "_golden_test.dart"))

writeGoldenTest(testFile, bloc, projectName)
val goldenTemplateName = (if (selectedTestLibrary == TestLibrary.GoldenToolkit) "bloc_golden" else "bloc_alchemist_golden")
writeGoldenTest(testFile, bloc, projectName, goldenTemplateName)
FileEditorManager.getInstance(project).openFile(testFile, true)


Expand All @@ -211,9 +223,12 @@ class BootstrapTestsAction : AnAction() {

companion object {

fun writeGoldenTest(testFile: VirtualFile, bloc: TestableClass, projectName: String) {
fun writeGoldenTest(testFile: VirtualFile, bloc: TestableClass, projectName: String, templateName: String) {
val test = com.primeholding.rxbloc_generator_plugin.generator.components.RxTestBlocGoldenGenerator(
name = bloc.file.name.replace(".dart", ""), projectName = projectName, bloc = bloc
name = bloc.file.name.replace(".dart", ""),
templateName = templateName,
projectName = projectName,
bloc = bloc
)
FileUtil.writeToFile(File(testFile.path), test.generate())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.primeholding.rxbloc_generator_plugin.action.GenerateRxBlocTestDialog">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="436" height="297"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="a86a7" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Test library"/>
</properties>
</component>
<component id="d693" class="javax.swing.JComboBox" binding="testLibrarySelection">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<model>
<item value="Alchemist"/>
<item value="Golden Toolkit"/>
</model>
</properties>
</component>
</children>
</grid>
</form>
Loading
Loading