From b9b24923842227eec213d3b5009c42381fd45507 Mon Sep 17 00:00:00 2001 From: seraphinandrieux Date: Tue, 29 Mar 2022 10:34:31 +0200 Subject: [PATCH] Add pinia for vue 3 --- package.json | 2 + .../application/VueApplicationService.java | 4 + .../generator/client/vue/core/domain/Vue.java | 48 ++++++++++ .../vue/core/domain/VueDomainService.java | 88 +++++++++++++++---- .../client/vue/core/domain/VueService.java | 2 + .../primary/rest/VueResource.java | 9 ++ .../generator/project/domain/Constants.java | 1 + .../primary/button/Button.spec.ts.mustache | 30 +++++++ .../store/CounterStore.spec.ts.mustache | 19 ++++ .../button/Button.component.ts.mustache | 21 +++++ .../primary/button/Button.html.mustache | 5 ++ .../common/primary/button/Button.vue.mustache | 3 + .../common/primary/button/index.ts.mustache | 4 + .../primary/store/CounterStore.ts.mustache | 15 ++++ .../vue/webapp/app/router/router.ts.mustache | 2 + .../generator/dependencies/vue/package.json | 3 + src/main/webapp/app/main.ts | 5 ++ .../application/VueApplicationServiceIT.java | 11 +++ .../vue/core/application/VueAssert.java | 11 +++ .../vue/core/domain/VueDomainServiceTest.java | 50 ++++++++++- .../primary/rest/VueResourceIT.java | 26 +++++- 21 files changed, 339 insertions(+), 20 deletions(-) create mode 100644 src/main/resources/generator/client/vue/test/spec/common/primary/button/Button.spec.ts.mustache create mode 100644 src/main/resources/generator/client/vue/test/spec/common/primary/store/CounterStore.spec.ts.mustache create mode 100644 src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.component.ts.mustache create mode 100644 src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.html.mustache create mode 100644 src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.vue.mustache create mode 100644 src/main/resources/generator/client/vue/webapp/app/common/primary/button/index.ts.mustache create mode 100644 src/main/resources/generator/client/vue/webapp/app/common/primary/store/CounterStore.ts.mustache diff --git a/package.json b/package.json index 562991f155e..df43b9dcdcc 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,8 @@ }, "dependencies": { "axios": "0.26.1", + "pinia": "2.0.12", + "pinia-plugin-persist": "^1.0.0", "vue": "3.2.31", "vue-router": "4.0.14" }, diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java index 7360ed75463..b84624e7c4a 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java @@ -17,6 +17,10 @@ public void addVue(Project project) { vueService.addVue(project); } + public void addPinia(Project project) { + vueService.addPinia(project); + } + public void addStyledVue(Project project) { vueService.addStyledVue(project); } diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/Vue.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/Vue.java index cd67d52020e..28281ed3467 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/Vue.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/Vue.java @@ -1,11 +1,21 @@ package tech.jhipster.lite.generator.client.vue.core.domain; +import java.util.Collection; import java.util.List; public class Vue { public static final String ROUTER_IMPORT = "import router from \'./router/router\';"; public static final String ROUTER_PROVIDER = "app.use(router);"; + public static final Collection PINIA_IMPORTS = List.of( + "import {createPinia} from \"pinia\";", + "import piniaPersist from 'pinia-plugin-persist'" + ); + public static final Collection PINIA_PROVIDERS = List.of( + "const pinia = createPinia();", + "pinia.use(piniaPersist);", + "app.use(pinia);" + ); private Vue() {} @@ -13,6 +23,44 @@ public static List dependencies() { return List.of("vue"); } + public static List piniaDependencies() { + return List.of("pinia", "pinia-plugin-persist"); + } + + public static List piniaDevDependencies() { + return List.of("@pinia/testing"); + } + + public static List buttonForStoreExampleFiles() { + return List.of("Button.component.ts", "Button.html", "Button.vue", "index.ts"); + } + + public static List buttonForStoreExampleTestFiles() { + return List.of("Button.spec.ts"); + } + + public static List storeExampleRoutes() { + return List.of(""" + { + path: '/button', + name: 'Button', + component: ButtonVue, + }, + """); + } + + public static List storeExampleImports() { + return List.of("import { ButtonVue } from '@/common/primary/button';"); + } + + public static List storeFilesExample() { + return List.of("CounterStore.ts"); + } + + public static List storeTestFilesExample() { + return List.of("CounterStore.spec.ts"); + } + public static List routerDependencies() { return List.of("vue-router"); } diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainService.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainService.java index 393ac70ed1a..be788f5e111 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainService.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainService.java @@ -18,9 +18,17 @@ public class VueDomainService implements VueService { public static final String SOURCE = "client/vue"; public static final String NEEDLE_IMPORT = "// jhipster-needle-main-ts-import"; public static final String NEEDLE_PROVIDER = "// jhipster-needle-main-ts-provider"; - public static final String SOURCE_PRIMARY = getPath(SOURCE, "webapp/app/common/primary/app"); - public static final String DESTINATION_PRIMARY = "src/main/webapp/app/common/primary/app"; + public static final String NEEDLE_ROUTE = "// jhipster-needle-router-route"; + public static final String NEEDLE_ROUTE_IMPORT = "// jhipster-needle-router-import"; + public static final String SOURCE_PRIMARY = getPath(SOURCE, "webapp/app/common/primary"); + public static final String SOURCE_TEST_PRIMARY = getPath(SOURCE, "test/spec/common/primary"); + public static final String SOURCE_PRIMARY_APP = getPath(SOURCE_PRIMARY, "app"); + public static final String DESTINATION_PRIMARY = "src/main/webapp/app/common/primary"; + public static final String DESTINATION_PRIMARY_APP = DESTINATION_PRIMARY + "/app"; + public static final String DESTINATION_PRIMARY_TEST = "src/test/javascript/spec/common/primary"; + public static final String DESTINATION_PRIMARY_ROUTER = DESTINATION_PRIMARY + "/app"; public static final String DESTINATION_APP = "src/main/webapp/app"; + public static final String DESTINATION_ROUTER = DESTINATION_APP + "/router"; private final ProjectRepository projectRepository; private final NpmService npmService; @@ -42,6 +50,49 @@ public void addStyledVue(Project project) { addAppFilesWithCss(project); } + @Override + public void addPinia(Project project) { + Assert.notNull("project", project); + + addPiniaDependencies(project); + addPiniaMainConfiguration(project); + addStoreExample(project); + } + + private void addStoreExample(Project project) { + addStoreExampleFiles(project); + addStoreExampleTestFiles(project); + addStoreExampleRouteIntoRouter(project); + } + + public void addStoreExampleRouteIntoRouter(Project project) { + Vue + .storeExampleImports() + .forEach(importLine -> addNewNeedleLineToFile(project, importLine, DESTINATION_ROUTER, ROUTER_TYPESCRIPT, NEEDLE_ROUTE_IMPORT)); + Vue.storeExampleRoutes().forEach(route -> addNewNeedleLineToFile(project, route, DESTINATION_ROUTER, ROUTER_TYPESCRIPT, NEEDLE_ROUTE)); + } + + public void addStoreExampleFiles(Project project) { + Vue + .buttonForStoreExampleFiles() + .forEach(file -> projectRepository.template(project, getPath(SOURCE_PRIMARY, "button"), file, DESTINATION_PRIMARY + "/button")); + Vue + .storeFilesExample() + .forEach(file -> projectRepository.template(project, getPath(SOURCE_PRIMARY, "store"), file, DESTINATION_PRIMARY + "/store")); + } + + public void addStoreExampleTestFiles(Project project) { + Vue + .buttonForStoreExampleTestFiles() + .forEach(file -> + projectRepository.template(project, getPath(SOURCE_TEST_PRIMARY, "button"), file, DESTINATION_PRIMARY_TEST + "/button") + ); + Vue + .storeTestFilesExample() + .forEach(file -> projectRepository.template(project, getPath(SOURCE_TEST_PRIMARY, "store"), file, DESTINATION_PRIMARY_TEST + "/store") + ); + } + private void addCommonVue(Project project) { Assert.notNull("project", project); addDependencies(project); @@ -58,6 +109,18 @@ public void addDependencies(Project project) { Vue.dependencies().forEach(dependency -> addDependency(project, dependency)); } + public void addPiniaDependencies(Project project) { + Vue.piniaDependencies().forEach(dependency -> addDependency(project, dependency)); + Vue.piniaDevDependencies().forEach(devDependency -> addDevDependency(project, devDependency)); + } + + private void addPiniaMainConfiguration(Project project) { + Vue.PINIA_IMPORTS.forEach(importLine -> addNewNeedleLineToFile(project, importLine, DESTINATION_APP, MAIN_TYPESCRIPT, NEEDLE_IMPORT)); + Vue.PINIA_PROVIDERS.forEach(providerLine -> + addNewNeedleLineToFile(project, providerLine, DESTINATION_APP, MAIN_TYPESCRIPT, NEEDLE_PROVIDER) + ); + } + public void addDevDependencies(Project project) { Vue.devDependencies().forEach(devDependency -> addDevDependency(project, devDependency)); } @@ -126,7 +189,7 @@ private void addRouterFiles(Project project) { } private void addRouterConfigAndTestFiles(Project project) { - projectRepository.template(project, getPath(SOURCE, "webapp/app/router"), "router.ts", "src/main/webapp/app/router"); + projectRepository.template(project, getPath(SOURCE, "webapp/app/router"), ROUTER_TYPESCRIPT, "src/main/webapp/app/router"); projectRepository.template(project, getPath(SOURCE, "test/spec/router"), "Router.spec.ts", "src/test/javascript/spec/router"); } @@ -143,29 +206,24 @@ private void addNewNeedleLineToFile(Project project, String importLine, String f public void addAppFiles(Project project) { project.addDefaultConfig(BASE_NAME); - projectRepository.template(project, SOURCE_PRIMARY, "App.component.ts", DESTINATION_PRIMARY); - projectRepository.template(project, SOURCE_PRIMARY, "index.ts", DESTINATION_PRIMARY); + projectRepository.template(project, SOURCE_PRIMARY_APP, "App.component.ts", DESTINATION_PRIMARY_APP); + projectRepository.template(project, SOURCE_PRIMARY_APP, "index.ts", DESTINATION_PRIMARY_APP); - projectRepository.template( - project, - getPath(SOURCE, "test/spec/common/primary/app"), - "App.spec.ts", - "src/test/javascript/spec/common/primary/app" - ); + projectRepository.template(project, getPath(SOURCE_TEST_PRIMARY, "app"), "App.spec.ts", DESTINATION_PRIMARY_TEST + "/app"); } public void addAppFilesWithoutCss(Project project) { project.addDefaultConfig(BASE_NAME); - projectRepository.template(project, SOURCE_PRIMARY, "App.html", DESTINATION_PRIMARY); - projectRepository.template(project, SOURCE_PRIMARY, "App.vue", DESTINATION_PRIMARY); + projectRepository.template(project, SOURCE_PRIMARY_APP, "App.html", DESTINATION_PRIMARY_APP); + projectRepository.template(project, SOURCE_PRIMARY_APP, "App.vue", DESTINATION_PRIMARY_APP); } public void addAppFilesWithCss(Project project) { project.addDefaultConfig(BASE_NAME); - projectRepository.template(project, SOURCE_PRIMARY, "StyledApp.html", DESTINATION_PRIMARY, "App.html"); - projectRepository.template(project, SOURCE_PRIMARY, "StyledApp.vue", DESTINATION_PRIMARY, "App.vue"); + projectRepository.template(project, SOURCE_PRIMARY_APP, "StyledApp.html", DESTINATION_PRIMARY_APP, "App.html"); + projectRepository.template(project, SOURCE_PRIMARY_APP, "StyledApp.vue", DESTINATION_PRIMARY_APP, "App.vue"); projectRepository.add( project, diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueService.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueService.java index 66537475d9c..32ad0f43051 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueService.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueService.java @@ -6,4 +6,6 @@ public interface VueService { void addVue(Project project); void addStyledVue(Project project); + + void addPinia(Project project); } diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResource.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResource.java index cf157c69b11..81f8919d7aa 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResource.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResource.java @@ -40,4 +40,13 @@ public void addStyledVue(@RequestBody ProjectDTO projectDTO) { Project project = ProjectDTO.toProject(projectDTO); vueApplicationService.addStyledVue(project); } + + @Operation(summary = "Add Pinia", description = "Add pinia for state management") + @ApiResponse(responseCode = "500", description = "An error occurred while adding Pinia") + @PostMapping("/pinia") + @GeneratorStep(id = "vue-pinia") + public void addPinia(@RequestBody ProjectDTO projectDTO) { + Project project = ProjectDTO.toProject(projectDTO); + vueApplicationService.addPinia(project); + } } diff --git a/src/main/java/tech/jhipster/lite/generator/project/domain/Constants.java b/src/main/java/tech/jhipster/lite/generator/project/domain/Constants.java index e2dc26eb2b6..e86731179a6 100644 --- a/src/main/java/tech/jhipster/lite/generator/project/domain/Constants.java +++ b/src/main/java/tech/jhipster/lite/generator/project/domain/Constants.java @@ -25,6 +25,7 @@ private Constants() {} public static final String DOCKERFILE = "Dockerfile"; public static final String INTEGRATION_TEST = "IntegrationTest.java"; public static final String MAIN_TYPESCRIPT = "main.ts"; + public static final String ROUTER_TYPESCRIPT = "router.ts"; public static final String COMMENT_PROPERTIES_PREFIX = "#"; public static final String KEY_VALUE_PROPERTIES_SEPARATOR = "="; diff --git a/src/main/resources/generator/client/vue/test/spec/common/primary/button/Button.spec.ts.mustache b/src/main/resources/generator/client/vue/test/spec/common/primary/button/Button.spec.ts.mustache new file mode 100644 index 00000000000..9004483d2b8 --- /dev/null +++ b/src/main/resources/generator/client/vue/test/spec/common/primary/button/Button.spec.ts.mustache @@ -0,0 +1,30 @@ +import {shallowMount, VueWrapper} from "@vue/test-utils"; +import {ButtonVue} from "@/common/primary/button"; +import {createTestingPinia} from "@pinia/testing"; +import {useCounterStore} from "@/common/primary/store/CounterStore"; + +let wrapper: VueWrapper; +const wrap = () => { + wrapper = shallowMount(ButtonVue,{ + global:{ + plugins:[createTestingPinia()] + } + }); +}; + +describe('Button',()=>{ + it('should exist', () => { + wrap(); + + expect(wrapper.exists()).toBeTruthy(); + }); + + it('should get counter value from store', async () => { + await wrap(); + const store = useCounterStore(); + expect(wrapper.text()).toEqual("Store Button 0"); + const button = wrapper.find('button'); + await button.trigger('click'); + expect(store.increment).toHaveBeenCalledTimes(1); + }); +}) diff --git a/src/main/resources/generator/client/vue/test/spec/common/primary/store/CounterStore.spec.ts.mustache b/src/main/resources/generator/client/vue/test/spec/common/primary/store/CounterStore.spec.ts.mustache new file mode 100644 index 00000000000..05a3d563fee --- /dev/null +++ b/src/main/resources/generator/client/vue/test/spec/common/primary/store/CounterStore.spec.ts.mustache @@ -0,0 +1,19 @@ +import {createPinia, setActivePinia} from "pinia"; +import {useCounterStore} from "@/common/primary/store/CounterStore"; + +describe("Counter store",()=>{ + beforeEach(() => { + setActivePinia(createPinia()) + }) + + it('Should initialize counter store to 0', () => { + const counter = useCounterStore() + expect(counter.count).toBe(0) + }) + + it('Should increment counter', () => { + const counter = useCounterStore() + counter.increment(); + expect(counter.count).toBe(1) + }) +}) diff --git a/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.component.ts.mustache b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.component.ts.mustache new file mode 100644 index 00000000000..f7c44c3e2fc --- /dev/null +++ b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.component.ts.mustache @@ -0,0 +1,21 @@ +import {useCounterStore} from "@/common/primary/store/CounterStore"; + +export default { + name: 'Button', + setup: () => { + const counter = useCounterStore(); + + const increment = (): void => { + counter.increment(); + } + + const counterValue = (): number =>{ + return counter.count; + } + + return { + increment, + counterValue + }; + }, +}; diff --git a/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.html.mustache b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.html.mustache new file mode 100644 index 00000000000..fb3a4b2eed4 --- /dev/null +++ b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.html.mustache @@ -0,0 +1,5 @@ +
+ +
diff --git a/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.vue.mustache b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.vue.mustache new file mode 100644 index 00000000000..614615fd019 --- /dev/null +++ b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/Button.vue.mustache @@ -0,0 +1,3 @@ + + + diff --git a/src/main/resources/generator/client/vue/webapp/app/common/primary/button/index.ts.mustache b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/index.ts.mustache new file mode 100644 index 00000000000..f22721d511a --- /dev/null +++ b/src/main/resources/generator/client/vue/webapp/app/common/primary/button/index.ts.mustache @@ -0,0 +1,4 @@ +import ButtonComponent from './Button.component'; +import ButtonVue from './Button.vue'; + +export { ButtonComponent, ButtonVue }; diff --git a/src/main/resources/generator/client/vue/webapp/app/common/primary/store/CounterStore.ts.mustache b/src/main/resources/generator/client/vue/webapp/app/common/primary/store/CounterStore.ts.mustache new file mode 100644 index 00000000000..dd569d0a553 --- /dev/null +++ b/src/main/resources/generator/client/vue/webapp/app/common/primary/store/CounterStore.ts.mustache @@ -0,0 +1,15 @@ +import {defineStore} from "pinia"; + +export const useCounterStore = defineStore('counter', { + state: () => ({ + count: 0, + }), + actions: { + increment() { + this.count++ + }, + }, + persist: { + enabled: true + } +}) diff --git a/src/main/resources/generator/client/vue/webapp/app/router/router.ts.mustache b/src/main/resources/generator/client/vue/webapp/app/router/router.ts.mustache index 26fed265ab0..4b9caabf819 100644 --- a/src/main/resources/generator/client/vue/webapp/app/router/router.ts.mustache +++ b/src/main/resources/generator/client/vue/webapp/app/router/router.ts.mustache @@ -1,5 +1,6 @@ import { AppVue } from '@/common/primary/app'; import { createRouter, createWebHistory } from 'vue-router'; +// jhipster-needle-router-import const routes = [ { @@ -11,6 +12,7 @@ const routes = [ name: 'App', component: AppVue, }, + // jhipster-needle-router-route ]; const router = createRouter({ diff --git a/src/main/resources/generator/dependencies/vue/package.json b/src/main/resources/generator/dependencies/vue/package.json index 66aea6bf627..538fa193210 100644 --- a/src/main/resources/generator/dependencies/vue/package.json +++ b/src/main/resources/generator/dependencies/vue/package.json @@ -4,10 +4,13 @@ "description": "JHipster Lite : used for Vite+Vue3 dependencies", "license": "Apache-2.0", "dependencies": { + "pinia": "2.0.12", + "pinia-plugin-persist": "1.0.0", "vue": "3.2.31", "vue-router": "4.0.14" }, "devDependencies": { + "@pinia/testing": "0.0.10", "@rushstack/eslint-patch": "1.1.1", "@types/jest": "27.4.1", "@typescript-eslint/parser": "5.16.0", diff --git a/src/main/webapp/app/main.ts b/src/main/webapp/app/main.ts index 9fe64708a5b..1d31f455968 100644 --- a/src/main/webapp/app/main.ts +++ b/src/main/webapp/app/main.ts @@ -9,6 +9,8 @@ import ReactRepository from '@/springboot/secondary/client/ReactRepository'; import VueRepository from '@/springboot/secondary/client/VueRepository'; import SpringBootRepository from './springboot/secondary/SpringBootRepository'; import ConsoleLogger from '@/common/secondary/ConsoleLogger'; +import { createPinia } from 'pinia'; +import piniaPersist from 'pinia-plugin-persist'; const axiosHttp = new AxiosHttp(axios.create({ baseURL: 'http://localhost:7471' })); const consoleLogger = new ConsoleLogger(console); @@ -19,6 +21,8 @@ const vueRepository = new VueRepository(axiosHttp); const springBootRepository = new SpringBootRepository(axiosHttp); const app = createApp(App); +const pinia = createPinia(); +pinia.use(piniaPersist); app.provide('angularService', angularRepository); app.provide('logger', consoleLogger); app.provide('projectService', projectRepository); @@ -26,5 +30,6 @@ app.provide('reactService', reactRepository); app.provide('springBootService', springBootRepository); app.provide('vueService', vueRepository); app.use(router); +app.use(pinia); app.mount('#app'); diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationServiceIT.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationServiceIT.java index 215326fcbff..bbd54bec733 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationServiceIT.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationServiceIT.java @@ -31,6 +31,17 @@ void shouldAddVue() { VueAssert.assertJestSonar(project); } + @Test + void shouldAddPinia() { + Project project = tmpProjectWithPackageJson(); + + vueApplicationService.addVue(project); + vueApplicationService.addPinia(project); + + VueAssert.assertPiniaDependency(project); + VueAssert.assertStoreExampleFiles(project); + } + @Test void shouldAddStyledVue() { Project project = tmpProjectWithPackageJson(); diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueAssert.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueAssert.java index caf72fad4b4..257f88ea6d2 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueAssert.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/application/VueAssert.java @@ -18,6 +18,10 @@ public static void assertDependency(Project project) { Vue.devDependencies().forEach(devDependency -> assertFileContent(project, PACKAGE_JSON, DQ + devDependency + DQ)); } + public static void assertPiniaDependency(Project project) { + Vue.piniaDependencies().forEach(dependency -> assertFileContent(project, PACKAGE_JSON, DQ + dependency + DQ)); + } + public static void assertScripts(Project project) { assertFileContent(project, PACKAGE_JSON, "\"build\": \"vue-tsc --noEmit && vite build --emptyOutDir\""); assertFileContent(project, PACKAGE_JSON, "\"dev\": \"vite\""); @@ -42,6 +46,13 @@ public static void assertRootFiles(Project project) { assertFileExist(project, "src/main/webapp/app/main.ts"); } + public static void assertStoreExampleFiles(Project project) { + assertFileExist(project, MAIN_WEBAPP, "/app/common/primary/store/CounterStore.ts"); + assertFileExist(project, MAIN_WEBAPP, "/app/common/primary/button/Button.component.ts"); + assertFileExist(project, MAIN_WEBAPP, "/app/common/primary/button/Button.html"); + assertFileExist(project, MAIN_WEBAPP, "/app/common/primary/button/Button.vue"); + } + public static void assertRouterFiles(Project project) { assertFileExist(project, MAIN_WEBAPP, "/app/router/router.ts"); assertFileExist(project, TEST_JAVASCRIPT, "/router/Router.spec.ts"); diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainServiceTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainServiceTest.java index d7a2ba05e12..36c6b95a7a4 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainServiceTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueDomainServiceTest.java @@ -5,7 +5,6 @@ import static org.mockito.Mockito.*; import static tech.jhipster.lite.TestUtils.*; -import java.util.List; import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -55,6 +54,13 @@ void shouldNotAddVueWhenNoProject() { .hasMessageContaining("project"); } + @Test + void shouldNotAddPiniaWhenNoProject() { + assertThatThrownBy(() -> vueDomainService.addPinia(null)) + .isExactlyInstanceOf(MissingMandatoryValueException.class) + .hasMessageContaining("project"); + } + @Test void shouldAddStyledVue() { Project project = tmpProjectWithPackageJson(); @@ -183,4 +189,46 @@ void shouldAddAppFilesWithCss() { verify(projectRepository, times(2)).template(any(Project.class), anyString(), anyString(), anyString(), anyString()); verify(projectRepository, times(2)).add(any(Project.class), anyString(), anyString(), anyString()); } + + @Test + void shouldAddPiniaDependencies() { + Project project = tmpProject(); + + final String version = "1.0.0"; + when(npmService.getVersion(anyString(), anyString())).thenReturn(Optional.of(version)); + + vueDomainService.addPiniaDependencies(project); + ArgumentCaptor dependenciesCaptor = ArgumentCaptor.forClass(String.class); + verify(npmService, times(2)).addDependency(eq(project), dependenciesCaptor.capture(), eq(version)); + + assertThat(dependenciesCaptor.getAllValues()).containsAll(Vue.piniaDependencies()); + } + + @Test + void shouldAddStoreExampleFiles() { + Project project = tmpProject(); + + vueDomainService.addStoreExampleFiles(project); + + verify(projectRepository, times(5)).template(eq(project), anyString(), anyString(), anyString()); + } + + @Test + void shouldAddRoutesToStore() { + Project project = tmpProject(); + + vueDomainService.addStoreExampleRouteIntoRouter(project); + verify(projectRepository, times(2)).replaceText(eq(project), anyString(), eq("router.ts"), anyString(), anyString()); + } + + @Test + void shouldUpdateMainConfigurationWhenAddingPinia() { + Project project = tmpProject(); + final String version = "1.0.0"; + when(npmService.getVersion(anyString(), anyString())).thenReturn(Optional.of(version)); + + vueDomainService.addPinia(project); + + verify(projectRepository, times(5)).replaceText(eq(project), anyString(), eq("main.ts"), anyString(), anyString()); + } } diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResourceIT.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResourceIT.java index 7c7ff28b211..8f0e07b55e3 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResourceIT.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/rest/VueResourceIT.java @@ -1,9 +1,9 @@ package tech.jhipster.lite.generator.client.vue.core.infrastructure.primary.rest; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static tech.jhipster.lite.TestUtils.readFileToObject; -import static tech.jhipster.lite.common.domain.FileUtils.tmpDirForTest; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static tech.jhipster.lite.TestUtils.*; +import static tech.jhipster.lite.common.domain.FileUtils.*; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -48,6 +48,24 @@ void shouldAddVue() throws Exception { VueAssert.assertJestSonar(project); } + @Test + void shouldAddPinia() throws Exception { + ProjectDTO projectDTO = readFileToObject("json/chips.json", ProjectDTO.class).folder(tmpDirForTest()); + Project project = ProjectDTO.toProject(projectDTO); + initApplicationService.init(project); + + mockMvc + .perform(post("/api/vue").contentType(MediaType.APPLICATION_JSON).content(TestUtils.convertObjectToJsonBytes(projectDTO))) + .andExpect(status().isOk()); + + mockMvc + .perform(post("/api/vue/pinia").contentType(MediaType.APPLICATION_JSON).content(TestUtils.convertObjectToJsonBytes(projectDTO))) + .andExpect(status().isOk()); + VueAssert.assertPiniaDependency(project); + + VueAssert.assertStoreExampleFiles(project); + } + @Test void shouldAddStyledVue() throws Exception { ProjectDTO projectDTO = readFileToObject("json/chips.json", ProjectDTO.class).folder(tmpDirForTest());