Skip to content

Commit 392f8b7

Browse files
committed
feat: validate order at compilation
1 parent 1c0f252 commit 392f8b7

File tree

20 files changed

+34
-162
lines changed

20 files changed

+34
-162
lines changed

core/flamingock-core/src/main/java/io/flamingock/internal/core/task/loaded/CodeLoadedTaskBuilder.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package io.flamingock.internal.core.task.loaded;
1717

18+
import io.flamingock.internal.common.core.preview.ChangeOrderExtractor;
1819
import io.flamingock.internal.util.StringUtil;
1920
import io.flamingock.api.annotations.Change;
2021
import io.flamingock.api.annotations.Recovery;
@@ -63,7 +64,7 @@ public static boolean supportsSourceClass(Class<?> sourceClass) {
6364

6465
private CodeLoadedTaskBuilder setPreview(CodePreviewChange preview) {
6566
setId(preview.getId());
66-
setOrderInContent(preview.getOrder().orElse(null));
67+
setOrder(preview.getOrder().orElse(null));
6768
setAuthor(preview.getAuthor());
6869
setChangeClass(preview.getSource());
6970
setRunAlways(preview.isRunAlways());
@@ -105,7 +106,7 @@ public CodeLoadedTaskBuilder setRecovery(RecoveryDescriptor recovery) {
105106
return this;
106107
}
107108

108-
public CodeLoadedTaskBuilder setOrderInContent(String orderInContent) {
109+
public CodeLoadedTaskBuilder setOrder(String orderInContent) {
109110
this.orderInContent = orderInContent;
110111
return this;
111112
}
@@ -163,8 +164,9 @@ public CodeLoadedChange build() {
163164
}
164165

165166
private void setFromFlamingockChangeAnnotation(Class<?> sourceClass, Change annotation) {
166-
setId(annotation.id());
167-
setOrderInContent(null);//TODO replace with order from class
167+
String changeId = annotation.id();
168+
setId(changeId);
169+
setOrder(ChangeOrderExtractor.extractOrderFromClassName(changeId, sourceClass.getName()));
168170
setAuthor(annotation.author());
169171
setChangeClass(sourceClass.getName());
170172
setTransactional(annotation.transactional());

core/flamingock-core/src/main/java/io/flamingock/internal/core/task/loaded/LoadedTaskBuilder.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ static CodeLoadedTaskBuilder getCodeBuilderInstance(Class<?> sourceClass) {
5353

5454
LoadedTaskBuilder<LOADED_TASK> setRecovery(RecoveryDescriptor recovery);
5555

56-
LoadedTaskBuilder<LOADED_TASK> setOrderInContent(String order);
57-
5856
LoadedTaskBuilder<LOADED_TASK> setRunAlways(boolean runAlways);
5957

6058
LoadedTaskBuilder<LOADED_TASK> setTransactional(boolean transactional);

core/flamingock-core/src/main/java/io/flamingock/internal/core/task/loaded/TemplateLoadedTaskBuilder.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class TemplateLoadedTaskBuilder implements LoadedTaskBuilder<TemplateLoad
3131

3232
private String fileName;
3333
private String id;
34-
private String orderInContent;
34+
private String order;
3535
private String author;
3636
private String templateName;
3737
private List<String> profiles;
@@ -76,8 +76,8 @@ public TemplateLoadedTaskBuilder setRecovery(RecoveryDescriptor recovery) {
7676
return this;
7777
}
7878

79-
public TemplateLoadedTaskBuilder setOrderInContent(String order) {
80-
this.orderInContent = order;
79+
public TemplateLoadedTaskBuilder setOrder(String order) {
80+
this.order = order;
8181
return this;
8282
}
8383

@@ -136,8 +136,7 @@ public TemplateLoadedChange build() {
136136
Class<? extends ChangeTemplate<?, ?, ?>> templateClass = ChangeTemplateManager.getTemplate(templateName)
137137
.orElseThrow(()-> new FlamingockException(String.format("Template[%s] not found. This is probably because template's name is wrong or template's library not imported", templateName)));
138138

139-
String order = ChangeOrderUtil.getMatchedOrderFromFile(id, orderInContent, fileName);
140-
139+
141140
return new TemplateLoadedChange(
142141
fileName,
143142
id,
@@ -157,9 +156,10 @@ public TemplateLoadedChange build() {
157156
}
158157

159158
private TemplateLoadedTaskBuilder setPreview(TemplatePreviewChange preview) {
159+
160160
setFileName(preview.getFileName());
161161
setId(preview.getId());
162-
setOrderInContent(preview.getOrder().orElse(null));
162+
setOrder(preview.getOrder().orElse(null));
163163
setAuthor(preview.getAuthor());
164164
setTemplateName(preview.getTemplateName());
165165
setProfiles(preview.getProfiles());

core/flamingock-core/src/test/java/io/flamingock/internal/core/task/loaded/CodeLoadedTaskBuilderTest.java

Lines changed: 7 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void setUp() {
3737
void shouldBuildWithOrderInContentWhenOrderInContentPresentAndNoOrderInSource() {
3838
// Given
3939
builder.setId("test-id")
40-
.setOrderInContent("001")
40+
.setOrder("001")
4141
.setChangeClass("java.lang.String") // Using existing class for simplicity
4242
.setRunAlways(false)
4343
.setTransactional(true)
@@ -52,47 +52,12 @@ void shouldBuildWithOrderInContentWhenOrderInContentPresentAndNoOrderInSource()
5252
assertEquals(String.class, result.getImplementationClass());
5353
}
5454

55-
@Test
56-
@DisplayName("Should build with order from source when orderInContent is null and order in source is present")
57-
void shouldBuildWithOrderFromSourceWhenOrderInContentIsNullAndOrderInSourceIsPresent() {
58-
// Given
59-
builder.setId("test-id")
60-
.setOrderInContent(null)
61-
.setChangeClass("com.mypackage._002__MyClass")
62-
.setRunAlways(false)
63-
.setTransactional(true)
64-
.setSystem(false);
65-
66-
// When & Then
67-
// This will throw ClassNotFoundException since the class doesn't exist
68-
// But it will call the order validation before that, so we can test the order logic
69-
RuntimeException exception = assertThrows(RuntimeException.class, () -> builder.build());
70-
assertInstanceOf(ClassNotFoundException.class, exception.getCause());
71-
}
72-
73-
@Test
74-
@DisplayName("Should build with orderInContent when orderInContent matches order in source")
75-
void shouldBuildWithOrderInContentWhenOrderInContentMatchesOrderInSource() {
76-
// Given
77-
builder.setId("test-id")
78-
.setOrderInContent("002")
79-
.setChangeClass("java.lang._002__Test") // This will extract "002" from class name
80-
.setRunAlways(false)
81-
.setTransactional(true)
82-
.setSystem(false);
83-
84-
// When & Then
85-
// This will throw ClassNotFoundException, but order validation happens first
86-
RuntimeException exception = assertThrows(RuntimeException.class, () -> builder.build());
87-
assertInstanceOf(ClassNotFoundException.class, exception.getCause());
88-
}
89-
9055
@Test
9156
@DisplayName("Should throw exception when orderInContent does not match order in source")
9257
void shouldThrowExceptionWhenOrderInContentDoesNotMatchOrderInSource() {
9358
// Given
9459
builder.setId("test-id")
95-
.setOrderInContent("001")
60+
.setOrder("001")
9661
.setChangeClass("com.mypackage._002__MyClass")
9762
.setRunAlways(false)
9863
.setTransactional(true)
@@ -110,7 +75,7 @@ void shouldThrowExceptionWhenOrderInContentDoesNotMatchOrderInSource() {
11075
void shouldThrowExceptionWhenBothOrderInContentAndOrderInSourceAreMissing() {
11176
// Given
11277
builder.setId("test-id")
113-
.setOrderInContent(null)
78+
.setOrder(null)
11479
.setChangeClass("java.lang.String")
11580
.setRunAlways(false)
11681
.setTransactional(true)
@@ -128,7 +93,7 @@ void shouldThrowExceptionWhenBothOrderInContentAndOrderInSourceAreMissing() {
12893
void shouldBuildWithOrderFromSourceWhenOrderInContentIsEmptyString() {
12994
// Given
13095
builder.setId("test-id")
131-
.setOrderInContent("")
96+
.setOrder("")
13297
.setChangeClass("com.mypackage._004__MyClass")
13398
.setRunAlways(false)
13499
.setTransactional(true)
@@ -147,7 +112,7 @@ void shouldBuildWithOrderFromSourceWhenOrderInContentIsEmptyString() {
147112
void shouldBuildWithOrderFromSourceWhenOrderInContentIsBlankString() {
148113
// Given
149114
builder.setId("test-id")
150-
.setOrderInContent(" ")
115+
.setOrder(" ")
151116
.setChangeClass("com.mypackage._005__MyClass")
152117
.setRunAlways(false)
153118
.setTransactional(true)
@@ -166,7 +131,7 @@ void shouldBuildWithOrderFromSourceWhenOrderInContentIsBlankString() {
166131
void shouldWorkWithRealClassWhenOrderValidationPasses() {
167132
// Given - using a real class that exists
168133
builder.setId("test-id")
169-
.setOrderInContent("001")
134+
.setOrder("001")
170135
.setChangeClass("java.lang.String")
171136
.setRunAlways(false)
172137
.setTransactional(true)
@@ -189,7 +154,7 @@ void shouldWorkWithRealClassWhenOrderValidationPasses() {
189154
void shouldHandleBeforeExecutionFlagCorrectly() {
190155
// Given
191156
builder.setId("test-id")
192-
.setOrderInContent("001")
157+
.setOrder("001")
193158
.setChangeClass("java.lang.String")
194159
.setBeforeExecution(true)
195160
.setRunAlways(false)

core/flamingock-core/src/test/java/io/flamingock/internal/core/task/loaded/TemplateLoadedTaskBuilderTest.java

Lines changed: 7 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void shouldBuildWithOrderInContentWhenOrderInContentPresentAndNoOrderInFileName(
8686
.thenReturn(Optional.of(TestChangeTemplate.class));
8787

8888
builder.setId("test-id")
89-
.setOrderInContent("001")
89+
.setOrder("001")
9090
.setFileName("test-file.yml")
9191
.setTemplateName("test-template")
9292
.setRunAlways(false)
@@ -116,8 +116,8 @@ void shouldBuildWithOrderFromFileNameWhenOrderInContentIsNullAndOrderInFileNameI
116116
.thenReturn(Optional.of(TestChangeTemplate.class));
117117

118118
builder.setId("test-id")
119-
.setOrderInContent(null)
120-
.setFileName("_002__test-file.yml")
119+
.setOrder("0002")
120+
.setFileName("_0002__test-file.yml")
121121
.setTemplateName("test-template")
122122
.setRunAlways(false)
123123
.setTransactional(true)
@@ -131,9 +131,9 @@ void shouldBuildWithOrderFromFileNameWhenOrderInContentIsNullAndOrderInFileNameI
131131
TemplateLoadedChange result = builder.build();
132132

133133
// Then
134-
assertEquals("002", result.getOrder().orElse(null));
134+
assertEquals("0002", result.getOrder().orElse(null));
135135
assertEquals("test-id", result.getId());
136-
assertEquals("_002__test-file.yml", result.getFileName());
136+
assertEquals("_0002__test-file.yml", result.getFileName());
137137
}
138138
}
139139

@@ -146,7 +146,7 @@ void shouldBuildWithOrderInContentWhenOrderInContentMatchesOrderInFileName() {
146146
.thenReturn(Optional.of(TestChangeTemplate.class));
147147

148148
builder.setId("test-id")
149-
.setOrderInContent("003")
149+
.setOrder("003")
150150
.setFileName("_003__test-file.yml")
151151
.setTemplateName("test-template")
152152
.setRunAlways(false);
@@ -167,92 +167,6 @@ void shouldBuildWithOrderInContentWhenOrderInContentMatchesOrderInFileName() {
167167
}
168168
}
169169

170-
@Test
171-
@DisplayName("Should throw exception when orderInContent does not match order in fileName")
172-
void shouldThrowExceptionWhenOrderInContentDoesNotMatchOrderInFileName() {
173-
// Given
174-
try (MockedStatic<ChangeTemplateManager> mockedTemplateManager = mockStatic(ChangeTemplateManager.class)) {
175-
mockedTemplateManager.when(() -> ChangeTemplateManager.getTemplate("test-template"))
176-
.thenReturn(Optional.of(TestChangeTemplate.class));
177-
178-
builder.setId("test-id")
179-
.setOrderInContent("001")
180-
.setFileName("_002__test-file.yml")
181-
.setTemplateName("test-template")
182-
.setRunAlways(false);
183-
builder.setProfiles(Collections.singletonList("test"));
184-
builder.setTransactional(true)
185-
.setSystem(false)
186-
.setConfiguration(new Object())
187-
.setApply(new Object())
188-
.setRollback(new Object());
189-
190-
// When & Then
191-
FlamingockException exception = assertThrows(FlamingockException.class, () -> builder.build());
192-
193-
194-
assertEquals("Change[test-id] Order mismatch: value in template order field='001' does not match order in fileName='002'",
195-
exception.getMessage());
196-
}
197-
}
198-
199-
@Test
200-
@DisplayName("Should throw exception when both orderInContent and order in fileName are missing")
201-
void shouldThrowExceptionWhenBothOrderInContentAndOrderInFileNameAreMissing() {
202-
// Given
203-
try (MockedStatic<ChangeTemplateManager> mockedTemplateManager = mockStatic(ChangeTemplateManager.class)) {
204-
mockedTemplateManager.when(() -> ChangeTemplateManager.getTemplate("test-template"))
205-
.thenReturn(Optional.of(TestChangeTemplate.class));
206-
207-
builder.setId("test-id")
208-
.setOrderInContent(null)
209-
.setFileName("test-file.yml")
210-
.setTemplateName("test-template")
211-
.setRunAlways(false);
212-
builder.setProfiles(Arrays.asList("test"));
213-
builder.setTransactional(true)
214-
.setSystem(false)
215-
.setConfiguration(new Object())
216-
.setApply(new Object())
217-
.setRollback(new Object());
218-
219-
// When & Then
220-
FlamingockException exception = assertThrows(FlamingockException.class, () -> builder.build());
221-
222-
assertEquals("Change[test-id] Order is required: order must be present in the template order field or in the fileName(e.g. _0001__test-id.yaml). If present in both, they must have the same value.",
223-
exception.getMessage());
224-
}
225-
}
226-
227-
@Test
228-
@DisplayName("Should throw exception when orderInContent is empty string")
229-
void shouldBuildWithOrderFromFileNameWhenOrderInContentIsEmptyString() {
230-
// Given
231-
try (MockedStatic<ChangeTemplateManager> mockedTemplateManager = mockStatic(ChangeTemplateManager.class)) {
232-
mockedTemplateManager.when(() -> ChangeTemplateManager.getTemplate("test-template"))
233-
.thenReturn(Optional.of(TestChangeTemplate.class));
234-
235-
builder.setId("test-id")
236-
.setOrderInContent("")
237-
.setFileName("_004__test-file.yml")
238-
.setTemplateName("test-template")
239-
.setRunAlways(false);
240-
builder.setProfiles(Arrays.asList("test"));
241-
builder.setTransactional(true)
242-
.setSystem(false)
243-
.setConfiguration(new Object())
244-
.setApply(new Object())
245-
.setRollback(new Object());
246-
247-
// When
248-
FlamingockException exception = assertThrows(FlamingockException.class, () -> builder.build());
249-
250-
// Then
251-
assertEquals("Change[test-id] Order mismatch: value in template order field='' does not match order in fileName='004'",
252-
exception.getMessage());
253-
}
254-
}
255-
256170
@Test
257171
@DisplayName("Should throw exception when template is not found")
258172
void shouldThrowExceptionWhenTemplateIsNotFound() {
@@ -262,7 +176,7 @@ void shouldThrowExceptionWhenTemplateIsNotFound() {
262176
.thenReturn(Optional.empty());
263177

264178
builder.setId("test-id")
265-
.setOrderInContent("001")
179+
.setOrder("001")
266180
.setFileName("test-file.yml")
267181
.setTemplateName("unknown-template");
268182

core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/couchbase/_001__CreateUsersCollectionChange.java renamed to core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/couchbase/_0001__CreateUsersCollectionChange.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import java.util.Collections;
2525

2626
@Change(id = "create-users-collection", author = "importer", transactional = false)
27-
public class _001__CreateUsersCollectionChange {
27+
public class _0001__CreateUsersCollectionChange {
2828

2929
@Apply
3030
public void execution(Bucket bucket) {

core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/legacy/_1__ClientInitializer.java renamed to core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/legacy/_0001__ClientInitializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import io.mongock.api.annotations.BeforeExecution;
2121

2222
@Change(id = "client-initializer", author = "mongock", transactional = false)
23-
public class _1__ClientInitializer {
23+
public class _0001__ClientInitializer {
2424

2525
@BeforeExecution
2626
public void beforeExecution() {

core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/legacy/_2__ClientUpdater.java renamed to core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/legacy/_0002__ClientUpdater.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import io.mongock.api.annotations.BeforeExecution;
2121

2222
@Change(id = "client-updater", author = "mongock", transactional = false)
23-
public class _2__ClientUpdater {
23+
public class _0002__ClientUpdater {
2424

2525
@BeforeExecution
2626
public void beforeExecution() {

core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/system/_0001_migration_from_mongock.yaml renamed to core/importer/flamingock-importer-couchbase-tests/src/test/java/io/flamingock/importer/couchbase/system/_0001__migration_from_mongock.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
id: migration-from-mongock
2-
order: 0001
32
transactional: false
43
template: CouchbaseImporterChangeTemplate
54
configuration:

core/importer/flamingock-importer-dynamodb-tests/src/test/java/io/flamingock/importer/dynamodb/dynamodb/_001__CreateUsersTableChange.java renamed to core/importer/flamingock-importer-dynamodb-tests/src/test/java/io/flamingock/importer/dynamodb/dynamodb/_0001__CreateUsersTableChange.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import software.amazon.awssdk.services.dynamodb.model.*;
2222

2323
@Change(id = "create-users-table", author = "importer")
24-
public class _001__CreateUsersTableChange {
24+
public class _0001__CreateUsersTableChange {
2525

2626
@Apply
2727
public void execution(DynamoDbClient dynamoDBClient) {

0 commit comments

Comments
 (0)