Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.kestra.core.runners.RunContext;
import io.kestra.core.storages.kv.KVStore;
import io.kestra.core.storages.kv.KVValueAndMetadata;
import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import io.kestra.plugin.scripts.exec.TriggerRunContext;
import io.kestra.plugin.scripts.exec.scripts.models.ScriptOutput;

Expand Down Expand Up @@ -241,9 +242,9 @@ boolean matchesCondition(Output out) {
}

try {
return conditionPattern(cond).matcher(haystack).find();
return ExitConditionRegex.find(conditionPattern(cond), haystack);
} catch (Exception invalidRegex) {
return haystack.contains(cond);
return ExitConditionRegex.invalidPatternFallback(cond, haystack);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.kestra.core.runners.RunContext;
import io.kestra.core.storages.kv.KVStore;
import io.kestra.core.storages.kv.KVValueAndMetadata;
import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import io.kestra.plugin.scripts.exec.TriggerRunContext;
import io.kestra.plugin.scripts.exec.scripts.models.ScriptOutput;

Expand Down Expand Up @@ -241,9 +242,9 @@ boolean matchesCondition(Output out) {
}

try {
return conditionPattern(cond).matcher(haystack).find();
return ExitConditionRegex.find(conditionPattern(cond), haystack);
} catch (Exception invalidRegex) {
return haystack.contains(cond);
return ExitConditionRegex.invalidPatternFallback(cond, haystack);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.kestra.plugin.scripts.bun;

import io.kestra.plugin.scripts.exec.ExitConditionRegex;

import java.time.Instant;
import java.util.Map;
import java.util.regex.Pattern;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;

class CommandsTriggerConditionTest {

private final CommandsTrigger trigger = CommandsTrigger.builder().build();

@Test
void regexCondition_delegatesToHelperAndReturnsItsResult() {
String condition = "status=\\w+";
String haystack = "{status=status=ready}";
CommandsTrigger.Output output = new CommandsTrigger.Output(
Instant.now(), " " + condition + " ", 0, Map.of("status", "status=ready")
);

try (var helper = mockStatic(ExitConditionRegex.class)) {
helper.when(() -> ExitConditionRegex.find(
argThat((Pattern pattern) -> pattern.pattern().equals(condition) && pattern.flags() == 0),
eq(haystack)
)).thenReturn(true, false);

assertThat(trigger.matchesCondition(output), is(true));
assertThat(trigger.matchesCondition(output), is(false));

helper.verify(() -> ExitConditionRegex.find(
argThat((Pattern pattern) -> pattern.pattern().equals(condition) && pattern.flags() == 0),
eq(haystack)
), times(2));
helper.verifyNoMoreInteractions();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package io.kestra.plugin.scripts.bun;

import io.kestra.plugin.scripts.exec.ExitConditionRegex;

import java.time.Instant;
import java.util.Map;
import java.util.regex.Pattern;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;

/**
* Unit tests for ScriptTrigger's condition-matching logic.
*
* Calls the real, package-private ScriptTrigger#matchesCondition directly (same pattern as
* plugin-script-ruby's ScriptTriggerConditionTest), so a change to the production method is
* what these tests actually exercise, not a separately maintained copy of its logic.
*/
class ScriptTriggerTest {

private final ScriptTrigger trigger = ScriptTrigger.builder().build();
Expand Down Expand Up @@ -74,4 +74,27 @@ void noMatch_emptyCondition() {
void nullCondition_doesNotMatch() {
assertThat(trigger.matchesCondition(output(null, 0, Map.of("k", "v"))), is(false));
}

@Test
void regexCondition_delegatesToHelperAndReturnsItsResult() {
String condition = "status=\\w+";
String haystack = "{status=status=ready}";
ScriptTrigger.Output output = output(" " + condition + " ", 0, Map.of("status", "status=ready"));

try (var helper = mockStatic(ExitConditionRegex.class)) {
helper.when(() -> ExitConditionRegex.find(
argThat((Pattern pattern) -> pattern.pattern().equals(condition) && pattern.flags() == 0),
eq(haystack)
)).thenReturn(true, false);

assertThat(trigger.matchesCondition(output), is(true));
assertThat(trigger.matchesCondition(output), is(false));

helper.verify(() -> ExitConditionRegex.find(
argThat((Pattern pattern) -> pattern.pattern().equals(condition) && pattern.flags() == 0),
eq(haystack)
), times(2));
helper.verifyNoMoreInteractions();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.kestra.core.models.triggers.TriggerOutput;
import io.kestra.core.models.triggers.TriggerService;
import io.kestra.core.runners.RunContext;
import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import io.kestra.plugin.scripts.exec.TriggerRunContext;
import io.kestra.plugin.scripts.exec.scripts.models.ScriptOutput;

Expand Down Expand Up @@ -214,11 +215,7 @@ boolean matchesCondition(Output out) {
return false;
}

try {
return Pattern.compile(cond).matcher(haystack).find();
} catch (Exception invalidRegex) {
return haystack.contains(cond);
}
return ExitConditionRegex.find(cond, haystack);
}

private String buildHaystack(Output out) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.kestra.core.models.triggers.TriggerOutput;
import io.kestra.core.models.triggers.TriggerService;
import io.kestra.core.runners.RunContext;
import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import io.kestra.plugin.scripts.exec.TriggerRunContext;
import io.kestra.plugin.scripts.exec.scripts.models.ScriptOutput;

Expand Down Expand Up @@ -259,11 +260,7 @@ boolean matchesCondition(Output out) {
return false;
}

try {
return Pattern.compile(cond).matcher(haystack).find();
} catch (Exception invalidRegex) {
return haystack.contains(cond);
}
return ExitConditionRegex.find(cond, haystack);
}

private String buildHaystack(Output out) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.kestra.plugin.scripts.deno;

import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;

class ExitConditionRegexWiringTest {

@Test
void scriptTrigger_delegatesToHelperAndReturnsItsResult() {
ScriptTrigger trigger = ScriptTrigger.builder().build();
String condition = "status=\\w+";
String haystack = "{status=status=ready}";
ScriptTrigger.Output output = new ScriptTrigger.Output(
Instant.now(), " " + condition + " ", 0, Map.of("status", "status=ready")
);

try (var helper = mockStatic(ExitConditionRegex.class)) {
helper.when(() -> ExitConditionRegex.find(condition, haystack)).thenReturn(true, false);

assertThat(trigger.matchesCondition(output), is(true));
assertThat(trigger.matchesCondition(output), is(false));

helper.verify(() -> ExitConditionRegex.find(condition, haystack), times(2));
helper.verifyNoMoreInteractions();
}
}

@Test
void commandsTrigger_delegatesToHelperAndReturnsItsResult() {
CommandsTrigger trigger = CommandsTrigger.builder().build();
String condition = "status=\\w+";
String haystack = "{status=status=ready}";
CommandsTrigger.Output output = new CommandsTrigger.Output(
Instant.now(), " " + condition + " ", 0, Map.of("status", "status=ready")
);

try (var helper = mockStatic(ExitConditionRegex.class)) {
helper.when(() -> ExitConditionRegex.find(condition, haystack)).thenReturn(true, false);

assertThat(trigger.matchesCondition(output), is(true));
assertThat(trigger.matchesCondition(output), is(false));

helper.verify(() -> ExitConditionRegex.find(condition, haystack), times(2));
helper.verifyNoMoreInteractions();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.kestra.core.runners.RunContext;
import io.kestra.core.storages.kv.KVStore;
import io.kestra.core.storages.kv.KVValueAndMetadata;
import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import io.kestra.plugin.scripts.exec.TriggerRunContext;
import io.kestra.plugin.scripts.exec.scripts.models.ScriptOutput;

Expand Down Expand Up @@ -231,11 +232,7 @@ boolean matchesCondition(Output out) {
return false;
}

try {
return Pattern.compile(cond).matcher(haystack).find();
} catch (Exception invalidRegex) {
return haystack.contains(cond);
}
return ExitConditionRegex.find(cond, haystack);
}

private String buildHaystack(Output out) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.kestra.core.runners.RunContext;
import io.kestra.core.storages.kv.KVStore;
import io.kestra.core.storages.kv.KVValueAndMetadata;
import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import io.kestra.plugin.scripts.exec.TriggerRunContext;
import io.kestra.plugin.scripts.exec.scripts.models.ScriptOutput;

Expand Down Expand Up @@ -231,11 +232,7 @@ boolean matchesCondition(Output out) {
return false;
}

try {
return Pattern.compile(cond).matcher(haystack).find();
} catch (Exception invalidRegex) {
return haystack.contains(cond);
}
return ExitConditionRegex.find(cond, haystack);
}

private String buildHaystack(Output out) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.kestra.plugin.scripts.dotnet;

import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;

class ExitConditionRegexWiringTest {

@Test
void commandsTrigger_delegatesToHelperAndReturnsItsResult() {
CommandsTrigger trigger = CommandsTrigger.builder().build();
String condition = "status=\\w+";
String haystack = "{status=status=ready}";
CommandsTrigger.Output output = new CommandsTrigger.Output(
Instant.now(), " " + condition + " ", 0, Map.of("status", "status=ready")
);

try (var helper = mockStatic(ExitConditionRegex.class)) {
helper.when(() -> ExitConditionRegex.find(condition, haystack)).thenReturn(true, false);

assertThat(trigger.matchesCondition(output), is(true));
assertThat(trigger.matchesCondition(output), is(false));

helper.verify(() -> ExitConditionRegex.find(condition, haystack), times(2));
helper.verifyNoMoreInteractions();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.kestra.plugin.scripts.dotnet;

import io.kestra.plugin.scripts.exec.ExitConditionRegex;

import java.time.Instant;
import java.util.Map;

Expand All @@ -9,14 +11,9 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;

/**
* Unit tests for ScriptTrigger's condition-matching logic.
*
* Calls the real, package-private ScriptTrigger#matchesCondition directly (same pattern as
* plugin-script-ruby's ScriptTriggerConditionTest), so a change to the production method is
* what these tests actually exercise, not a separately maintained copy of its logic.
*/
class ScriptTriggerTest {

private final ScriptTrigger trigger = ScriptTrigger.builder().build();
Expand Down Expand Up @@ -74,4 +71,21 @@ void noMatch_emptyCondition() {
void nullCondition_doesNotMatch() {
assertThat(trigger.matchesCondition(output(null, 0, Map.of("k", "v"))), is(false));
}

@Test
void regexCondition_delegatesToHelperAndReturnsItsResult() {
String condition = "status=\\w+";
String haystack = "{status=status=ready}";
ScriptTrigger.Output output = output(" " + condition + " ", 0, Map.of("status", "status=ready"));

try (var helper = mockStatic(ExitConditionRegex.class)) {
helper.when(() -> ExitConditionRegex.find(condition, haystack)).thenReturn(true, false);

assertThat(trigger.matchesCondition(output), is(true));
assertThat(trigger.matchesCondition(output), is(false));

helper.verify(() -> ExitConditionRegex.find(condition, haystack), times(2));
helper.verifyNoMoreInteractions();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.kestra.core.models.triggers.TriggerOutput;
import io.kestra.core.models.triggers.TriggerService;
import io.kestra.core.runners.RunContext;
import io.kestra.plugin.scripts.exec.ExitConditionRegex;
import io.kestra.plugin.scripts.exec.TriggerRunContext;
import io.kestra.plugin.scripts.exec.scripts.models.ScriptOutput;

Expand Down Expand Up @@ -186,7 +187,7 @@ private Output runOnce(RunContext runContext) throws Exception {
}
}

private boolean matchesCondition(Output out) {
boolean matchesCondition(Output out) {
String cond = out.getCondition() == null ? "" : out.getCondition().trim();

Matcher exitMatcher = EXIT_CONDITION_PATTERN.matcher(cond);
Expand All @@ -200,11 +201,7 @@ private boolean matchesCondition(Output out) {
return false;
}

try {
return Pattern.compile(cond).matcher(haystack).find();
} catch (Exception invalidRegex) {
return haystack.contains(cond);
}
return ExitConditionRegex.find(cond, haystack);
}

private String buildHaystack(Output out) {
Expand Down
Loading
Loading