Skip to content

Commit 01bd8fd

Browse files
Do not assume org.openrewrite.dataTables messages preserve order in DataTableWatcher (#31)
* Show the issue with a unit test that randomly succeeds, but mostly fails. * Use LinkedHashMap for org.openrewrite.dataTables message values for consistent ordering of entries * Do not assume org.openrewrite.dataTables messages preserves order in DataTableWatcher * Remove newline * Switch to LinkedList for faster node removal --------- Co-authored-by: Bryce Tompkins <[email protected]>
1 parent aaead91 commit 01bd8fd

File tree

3 files changed

+78
-8
lines changed

3 files changed

+78
-8
lines changed

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ dependencies {
2727
testImplementation("io.moderne:moderne-organizations-format:latest.release")
2828
testImplementation("org.openrewrite:rewrite-test")
2929
testImplementation("org.openrewrite:rewrite-java-21:${rewriteVersion}")
30+
testImplementation(gradleApi())
31+
testImplementation("org.openrewrite.gradle.tooling:model:${rewriteVersion}")
3032
testRuntimeOnly("junit:junit:4.+")
3133
}
3234

src/main/java/io/moderne/devcenter/internal/DataTableRowWatcher.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import org.openrewrite.DataTable;
2020
import org.openrewrite.ExecutionContext;
2121

22-
import java.util.ArrayList;
22+
import java.util.LinkedList;
2323
import java.util.List;
2424
import java.util.Map;
2525

@@ -29,22 +29,22 @@
2929
public class DataTableRowWatcher<Row> {
3030
private final DataTable<Row> dataTable;
3131
private final ExecutionContext ctx;
32-
33-
int startingRowCount;
32+
private List<Row> startingRows;
3433

3534
public void start() {
36-
startingRowCount = getRows().size();
35+
startingRows = getRows();
3736
}
3837

3938
public List<Row> stop() {
4039
List<Row> rows = getRows();
41-
return rows.subList(startingRowCount, rows.size());
40+
rows.removeAll(startingRows);
41+
return rows;
4242
}
4343

4444
private List<Row> getRows() {
4545
Map<DataTable<?>, List<?>> dataTables = ctx.getMessage("org.openrewrite.dataTables", emptyMap());
4646
// TODO because two DataTable of the same type can be created
47-
List<Row> rows = new ArrayList<>();
47+
List<Row> rows = new LinkedList<>();
4848
for (Map.Entry<DataTable<?>, List<?>> dataTableEntry : dataTables.entrySet()) {
4949
if (dataTableEntry.getKey().getClass().equals(dataTable.getClass())) {
5050
//noinspection unchecked

src/test/java/io/moderne/devcenter/DevCenterTest.java

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package io.moderne.devcenter;
1717

1818
import io.moderne.devcenter.table.UpgradesAndMigrations;
19+
import org.intellij.lang.annotations.Language;
1920
import org.junit.jupiter.api.BeforeEach;
2021
import org.junit.jupiter.api.Test;
2122
import org.junit.jupiter.params.ParameterizedTest;
@@ -37,6 +38,9 @@
3738
import static io.moderne.devcenter.JavaVersionUpgrade.Measure.Java8Plus;
3839
import static org.assertj.core.api.Assertions.assertThat;
3940
import static org.assertj.core.api.Assertions.assertThatThrownBy;
41+
import static org.assertj.core.api.Assertions.tuple;
42+
import static org.openrewrite.gradle.Assertions.buildGradle;
43+
import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi;
4044
import static org.openrewrite.java.Assertions.java;
4145
import static org.openrewrite.java.Assertions.version;
4246

@@ -199,7 +203,7 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
199203
// Load io.moderne.devcenter classes (including UpgradeMigrationCard) in this classloader
200204
// to ensure they are different from the ones in the test classloader
201205
if (name.startsWith("io.moderne.devcenter.") &&
202-
!name.startsWith("io.moderne.devcenter.DevCenter")) {
206+
!name.startsWith("io.moderne.devcenter.DevCenter")) {
203207
// Get the resource path for the class
204208
String resourcePath = name.replace('.', '/') + ".class";
205209
try (var inputStream = getClass().getClassLoader().getResourceAsStream(resourcePath)) {
@@ -231,7 +235,7 @@ public String getDisplayName() {
231235
@Override
232236
public String getDescription() {
233237
return "Simulates `DeclarativeRecipe`, which is parent loaded and contains " +
234-
"child loaded sub-recipes.";
238+
"child loaded sub-recipes.";
235239
}
236240

237241
@Override
@@ -241,4 +245,68 @@ public List<Recipe> getRecipeList() {
241245
})
242246
);
243247
}
248+
249+
@Test
250+
void devcenterWithMultipleLibraryUpgradeRecipesHasCorrectData() {
251+
@Language("yaml") String recipe = """
252+
type: specs.openrewrite.org/v1beta/recipe
253+
name: io.moderne.devcenter.TwoLibraryUpgrades
254+
displayName: Starter DevCenter library version upgrade card
255+
description: Upgrade library versions.
256+
recipeList:
257+
- io.moderne.devcenter.LibraryUpgrade:
258+
cardName: Move to Spring Boot 3.5.0
259+
groupIdPattern: org.springframework.boot
260+
artifactIdPattern: '*'
261+
version: 3.5.0
262+
upgradeRecipe: io.moderne.java.spring.boot3.UpgradeSpringBoot_3_5
263+
- io.moderne.devcenter.LibraryUpgrade:
264+
cardName: Move to commons collections 3.2.2
265+
groupIdPattern: commons-collections
266+
artifactIdPattern: commons-collections
267+
version: 3.2.2
268+
""";
269+
rewriteRun(
270+
spec ->
271+
spec.recipeFromYaml(recipe, "io.moderne.devcenter.TwoLibraryUpgrades")
272+
.beforeRecipe(withToolingApi())
273+
.afterRecipe(after -> assertThat(after.getDataTableRows("io.moderne.devcenter.table.UpgradesAndMigrations"))
274+
.extracting("card", "ordinal", "value", "currentMinimumVersion")
275+
.containsExactly(
276+
tuple("Move to Spring Boot 3.5.0", 0, "Major", "2.7.18"),
277+
tuple("Move to commons collections 3.2.2", 0, "Major", "2.0")
278+
)),
279+
//language=Groovy
280+
buildGradle(
281+
"""
282+
plugins {
283+
id "java"
284+
id 'org.springframework.boot' version '2.7.18'
285+
id 'io.spring.dependency-management' version '1.1.7'
286+
}
287+
repositories {
288+
mavenCentral()
289+
}
290+
dependencies {
291+
implementation "org.springframework.boot:spring-boot-starter-web"
292+
implementation "commons-collections:commons-collections:2.0"
293+
}
294+
""",
295+
"""
296+
plugins {
297+
id "java"
298+
id 'org.springframework.boot' version '2.7.18'
299+
id 'io.spring.dependency-management' version '1.1.7'
300+
}
301+
repositories {
302+
mavenCentral()
303+
}
304+
dependencies {
305+
/*~~(org.springframework.boot:spring-boot:2.7.18,org.springframework.boot:spring-boot-autoconfigure:2.7.18,org.springframework.boot:spring-boot-starter-logging:2.7.18,org.springframework.boot:spring-boot-starter-web:2.7.18,org.springframework.boot:spring-boot-starter:2.7.18,org.springframework.boot:spring-boot-starter-tomcat:2.7.18,org.springframework.boot:spring-boot-starter-json:2.7.18)~~>*/implementation "org.springframework.boot:spring-boot-starter-web"
306+
/*~~(commons-collections:commons-collections:2.0)~~>*/implementation "commons-collections:commons-collections:2.0"
307+
}
308+
"""
309+
)
310+
);
311+
}
244312
}

0 commit comments

Comments
 (0)