From 96788ee1ceaccaf86c5912c139c2beb0a7959d0e Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Fri, 18 Sep 2026 08:09:42 +0000 Subject: [PATCH 01/13] docs: mark the Spring and Quarkus mocks as internal API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The classes in `com.vaadin.browserless.mocks` and `com.vaadin.browserless.quarkus.mocks` are built by the framework itself — `SpringBrowserlessTest`, `QuarkusBrowserlessTest` and the application contexts construct them as local variables, and no published signature accepts or returns one. Say so, using the same wording as `BaseBrowserlessTest`, so they stay free to change. `MockWebApplicationContext` and `SpringSecurityRequestCustomizer` already carried a shorter note; they now use the full sentence like the rest. --- .../vaadin/browserless/quarkus/mocks/MockQuarkusServlet.java | 3 +++ .../browserless/quarkus/mocks/MockQuarkusServletService.java | 3 +++ .../java/com/vaadin/browserless/mocks/MockSpringServlet.java | 3 +++ .../vaadin/browserless/mocks/MockSpringServletService.java | 3 +++ .../com/vaadin/browserless/mocks/MockSpringVaadinSession.java | 3 +++ .../vaadin/browserless/mocks/MockWebApplicationContext.java | 4 ++-- .../browserless/mocks/SpringSecurityRequestCustomizer.java | 4 ++-- 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServlet.java b/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServlet.java index 18c45bfb..52db1da3 100644 --- a/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServlet.java +++ b/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServlet.java @@ -36,6 +36,9 @@ * {@link MockQuarkusServletService} is used instead of vanilla * {@link com.vaadin.quarkus.QuarkusVaadinServletService}. * + *

+ * For internal use only. May be renamed or removed in a future release. + * * @since 1.0 */ public class MockQuarkusServlet extends QuarkusVaadinServlet { diff --git a/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServletService.java b/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServletService.java index 4186c39e..d44da1e2 100644 --- a/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServletService.java +++ b/quarkus/src/main/java/com/vaadin/browserless/quarkus/mocks/MockQuarkusServletService.java @@ -37,6 +37,9 @@ * * The class is intentionally opened, to be extensible in user's library. * + *

+ * For internal use only. May be renamed or removed in a future release. + * * @since 1.0 */ public class MockQuarkusServletService extends QuarkusVaadinServletService { diff --git a/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServlet.java b/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServlet.java index 5bde516d..591110ee 100644 --- a/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServlet.java +++ b/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServlet.java @@ -47,6 +47,9 @@ * {@link MockSpringServletService} is used instead of vanilla * {@link com.vaadin.flow.spring.SpringVaadinServletService}. * + *

+ * For internal use only. May be renamed or removed in a future release. + * * @author mavi * @since 1.0 */ diff --git a/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServletService.java b/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServletService.java index f5b49e61..3a5f854c 100644 --- a/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServletService.java +++ b/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringServletService.java @@ -38,6 +38,9 @@ * * The class is intentionally opened, to be extensible in user's library. * + *

+ * For internal use only. May be renamed or removed in a future release. + * * @author mavi * @since 1.0 */ diff --git a/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringVaadinSession.java b/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringVaadinSession.java index 826c9697..a1695496 100644 --- a/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringVaadinSession.java +++ b/spring/src/main/java/com/vaadin/browserless/mocks/MockSpringVaadinSession.java @@ -35,6 +35,9 @@ * {@link MockVaadin#afterSessionClose}. * * + *

+ * For internal use only. May be renamed or removed in a future release. + * * @author mavi * @since 1.0 */ diff --git a/spring/src/main/java/com/vaadin/browserless/mocks/MockWebApplicationContext.java b/spring/src/main/java/com/vaadin/browserless/mocks/MockWebApplicationContext.java index d048f2f8..f78c7ad5 100644 --- a/spring/src/main/java/com/vaadin/browserless/mocks/MockWebApplicationContext.java +++ b/spring/src/main/java/com/vaadin/browserless/mocks/MockWebApplicationContext.java @@ -40,8 +40,8 @@ /** * An adapter to make a generic Spring ApplicationContext act like a * WebApplicationContext. - * - * For internal use only. + *

+ * For internal use only. May be renamed or removed in a future release. * * @since 1.0 */ diff --git a/spring/src/main/java/com/vaadin/browserless/mocks/SpringSecurityRequestCustomizer.java b/spring/src/main/java/com/vaadin/browserless/mocks/SpringSecurityRequestCustomizer.java index 7c442009..49e7df5f 100644 --- a/spring/src/main/java/com/vaadin/browserless/mocks/SpringSecurityRequestCustomizer.java +++ b/spring/src/main/java/com/vaadin/browserless/mocks/SpringSecurityRequestCustomizer.java @@ -19,8 +19,8 @@ /** * Configures mock request with authentication details from Spring Security. - * - * For internal use only. + *

+ * For internal use only. May be renamed or removed in a future release. * * @since 1.0 */ From 922bd5883244435a31c9773250fd723efca3f76b Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Fri, 18 Sep 2026 08:18:09 +0000 Subject: [PATCH 02/13] refactor!: port the mocks package from Kotlin to Java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 12 Kotlin files under `shared/src/main/kotlin/com/vaadin/browserless/mocks` become 14 Java files. First phase of removing Kotlin from `shared`; the plan for the rest is in `de-kotlin-plan.md`. `MockHttpEnvironment.kt` splits into `MockHttpEnvironment`, `MockServletConfig` and `MockUtils`, and the top-level helpers of `MockVaadinServlet.kt` become statics on `MockVaadinServlet`. Every class is marked internal, and the KDoc is rewritten as Javadoc: each mock now says which container behaviour it reproduces and where it stops. Kotlin properties are kept as accessors rather than flattened into public fields, so most call sites are untouched — including the Kotlin ones, which see a Java getter/setter pair as a property. Breaking changes: * `MockVaadinServlet.createServletService` declares `throws ServiceException` and `createDeploymentConfiguration` declares `throws ServletException`, as `VaadinServlet` does. An override that calls `super` has to declare it too. * `MockHttpEnvironment.INSTANCE.setLocalPort(…)` becomes `MockHttpEnvironment.setLocalPort(…)`; same for `MockVaadinHelper`. * `MockHttpSession.Companion.create(…)` becomes `MockHttpSession.create(…)`. * `MockRequest.isUserInRole` takes a `BiPredicate` and the principal provider a `Supplier`, in place of the Kotlin function types. * The `HttpSession.attributes` extension is gone; use `new SessionAttributeMap(session)`. * `MockResponse` no longer exposes `_status`, `_bufferSize`, `_locale`, `_contentType` and `_characterEncoding`; use the `HttpServletResponse` getters and setters that back them. * The `WebBrowser(request)` factory is renamed `createWebBrowser(request)`. `MockInstantiator` is now `@Deprecated(forRemoval = true)` and forwards `getPageTitleGenerator()`, which the wrapper was missing. --- .gitignore | 2 + CONVENTIONS.md | 4 +- de-kotlin-plan.md | 338 ++++++++ guidelines/repository.md | 7 +- .../browserless/mocks/MockRequestTest.kt | 2 +- .../mocks/SessionAttributeMapTest.kt | 2 +- .../vaadin/browserless/mocks/MockContext.java | 506 ++++++++++++ .../mocks/MockHttpEnvironment.java | 154 ++++ .../browserless/mocks/MockHttpSession.java | 243 ++++++ .../browserless/mocks/MockInstantiator.java | 152 ++++ .../vaadin/browserless/mocks/MockRequest.java | 744 ++++++++++++++++++ .../browserless/mocks/MockResponse.java | 306 +++++++ .../vaadin/browserless/mocks/MockService.java | 114 +++ .../browserless/mocks/MockServletConfig.java | 105 +++ .../vaadin/browserless/mocks/MockUtils.java | 57 ++ .../browserless/mocks/MockVaadinHelper.java | 372 +++++++++ .../browserless/mocks/MockVaadinServlet.java | 254 ++++++ .../browserless/mocks/MockVaadinSession.java | 70 ++ .../vaadin/browserless/mocks/MockedUI.java | 179 +++++ .../mocks/SessionAttributeMap.java | 205 +++++ .../vaadin/browserless/internal/MockVaadin.kt | 15 +- .../vaadin/browserless/mocks/MockContext.kt | 294 ------- .../browserless/mocks/MockHttpEnvironment.kt | 69 -- .../browserless/mocks/MockHttpSession.kt | 146 ---- .../browserless/mocks/MockInstantiator.kt | 91 --- .../vaadin/browserless/mocks/MockRequest.kt | 351 --------- .../vaadin/browserless/mocks/MockResponse.kt | 166 ---- .../vaadin/browserless/mocks/MockService.kt | 47 -- .../browserless/mocks/MockVaadinHelper.kt | 170 ---- .../browserless/mocks/MockVaadinServlet.kt | 116 --- .../browserless/mocks/MockVaadinSession.kt | 38 - .../com/vaadin/browserless/mocks/MockedUI.kt | 124 --- .../browserless/mocks/SessionAttributeMap.kt | 109 --- .../BuilderVaadinConfigurationTest.java | 4 +- .../mocks/MockInstantiatorTest.java | 2 +- .../mocks/BrowserlessLookupInitializerTest.kt | 16 +- 36 files changed, 3827 insertions(+), 1747 deletions(-) create mode 100644 de-kotlin-plan.md create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockContext.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockHttpEnvironment.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockHttpSession.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockInstantiator.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockRequest.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockResponse.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockService.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockServletConfig.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockUtils.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockVaadinHelper.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockVaadinServlet.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockVaadinSession.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/MockedUI.java create mode 100644 shared/src/main/java/com/vaadin/browserless/mocks/SessionAttributeMap.java delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockContext.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockHttpEnvironment.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockHttpSession.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockInstantiator.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockRequest.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockResponse.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockService.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockVaadinHelper.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockVaadinServlet.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockVaadinSession.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/MockedUI.kt delete mode 100644 shared/src/main/kotlin/com/vaadin/browserless/mocks/SessionAttributeMap.kt diff --git a/.gitignore b/.gitignore index e6a82ae2..47021b1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ target spotless-index +*.iml +.idea diff --git a/CONVENTIONS.md b/CONVENTIONS.md index 2eadf3ff..4f03c060 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -109,8 +109,8 @@ and session lifecycle events through the `VaadinService` event bus, and forward `Instantiator` calls to the real instantiator instead of reimplementing them. New code in `shared` is written in Java. The Kotlin sources under -`shared/src/main/kotlin` are the older mock and internal layer and are being -ported to Java; do not add new Kotlin files there. +`shared/src/main/kotlin` are the older internal layer and are being ported to +Java; do not add new Kotlin files there. See [`guidelines/architecture.md`](guidelines/architecture.md). diff --git a/de-kotlin-plan.md b/de-kotlin-plan.md new file mode 100644 index 00000000..9fb1a0de --- /dev/null +++ b/de-kotlin-plan.md @@ -0,0 +1,338 @@ +# Migrating the Kotlin sources to plain Java + +Working plan for removing Kotlin from `browserless-test`. The goal is that +`shared/src/main` is 100% Java and that downstream consumers of +`browserless-test-shared` pull no Kotlin runtime transitively. + +## Current state + +| Area | Files | LOC | Notes | +| --- | --- | --- | --- | +| `shared/src/main/kotlin/…/mocks` | 12 | 1,721 | servlet API mocks, `MockService`, `MockedUI` | +| `shared/src/main/kotlin/…/internal` | 12 | 3,043 | `MockVaadin`, `Locator`, `Routes`, `PrettyPrintTree`, utilities | +| `shared/src/main/kotlin/…/component/Grid.kt` | 1 | 901 | the heaviest single file | +| `junit6/src/test/kotlin` | 23 | ~3,050 | DynaTest + Karibu DSL | +| `shared/src/test/kotlin` | 2 | 144 | DynaTest | + +`spring`, `quarkus`, `junit6/src/main` and `locator-processor` are already pure +Java, but about 48 Java files reference the Kotlin packages and 24 call sites go +through Kotlin file facades (`LocatorKt`, `PrettyPrintTreeKt`, `GridKt`, +`UtilsKt`, `BasicUtilsKt`, `ShortcutsKt`). + +## Prior art + +`origin/feat/no-kotlin-grid` carries a complete five-commit port of all 25 +main-source Kotlin files, verified green on all four suites +(20 / 1007 / 29 / 27 tests). It branched from `a333ccc` and is 82 commits behind +`main`, so it is a source to rebase from, not a branch to merge. + +Reviewer notes from that effort live on the branch in `de-kotlin-review/`. + +Drift to reconcile while rebasing — most files differ only by the +commercial → Apache license header swap (`08abcfa`); the real drift is: + +| File | Drift | Why | +| --- | --- | --- | +| `internal/MockVaadin.kt` | +222 | reload / window-name plumbing, `liveUI`, `fireSessionDestroyAndDrain`, multi-user session objects | +| `mocks/MockInstantiator.kt` | +118 | deprecated, forwarders hand-unrolled | +| `internal/PrettyPrintTree.kt` | +93 | `hrefValue()` already rewritten in plain Java reflection — expect a conflict with Phase 3 | +| `component/Grid.kt` | +86 | selection and click additions | +| `mocks/MockedUI.kt` | +82 | `navigate()` override and `toLocation()` | +| `internal/TestingLifecycleHook.kt` | +60 | slot / children rules | +| `mocks/MockRequest.kt` | +60 | role checker, principal provider | +| `mocks/MockHttpSession.kt` | +39 | `changeSessionId()` | + +`df099d0` already dropped `kotlin-reflect` on `main`, so that dependency win is +banked independently of this work. + +## Phases + +Each phase is independently mergeable and leaves the build green. + +### Phase 0 — prerequisites + +Decisions that constrain later phases: + +- **Nullability annotations.** 11 Java files in `shared`, `spring` and + `quarkus` import `org.jetbrains.annotations.@NotNull` / `@Nullable`, which + arrives transitively via `kotlin-stdlib`. Move them to JSpecify (already used + in 5 files) or add a direct `org.jetbrains:annotations` dependency. Without + this the build breaks the moment `kotlin-stdlib` leaves compile scope. +- **`SearchSpec.count`.** Pick the replacement for `kotlin.ranges.IntRange` + (the prior effort introduced a small `CountRange` helper). This constrains + Phases 4 and 5. +- **Test-side Kotlin.** In or out of scope — see below. + +### Phase 1 — `mocks/` — done + +12 Kotlin files → 14 Java files, on `refactor/no-kotlin-mocks`. All five suites +match the `main` baseline exactly: shared 42, junit6 1406, junit6-cdi-tests 4, +spring 41, quarkus 31. + +- `MockHttpEnvironment.kt` splits into `MockHttpEnvironment`, + `MockServletConfig` and a `MockUtils.putOrRemove` helper. +- `MockVaadinServlet.kt`'s top-level factories (`serviceSafe`, + `createVaadinServletRequest` / `…Response`, `_createVaadinSession`, + `WebBrowser(request)`) become statics on `MockVaadinServlet`. The last one is + renamed `createWebBrowser` to avoid clashing with + `com.vaadin.flow.server.WebBrowser`. +- `SessionAttributeMap` becomes a public class; the `HttpSession.attributes` + extension property disappears and callers construct it directly. +- `MockInstantiator`'s `Instantiator by delegate` is unrolled by hand — see the + silent-risk list below. +- `MockRequest` keeps an explicit `setUserInRole(BiPredicate)` setter, matching + what Kotlin's `is`-prefix property convention emitted. +- `MockVaadinServlet.createServletService` now declares + `throws ServiceException`, as its `VaadinServlet` superclass does — see the + breaking changes below. +- KDoc is rewritten as Javadoc rather than carried over verbatim: `[Foo]` + becomes `{@link Foo}`, `*` bullets become `