fix: correct STEP-057B weather runtime state semantics
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
@@ -55,7 +55,7 @@ public final class WeatherRuntime {
|
||||
|
||||
public FieldSubmitResult submitWindField(@NonNull String metadataJson, @NonNull byte[] payloadBytes) {
|
||||
requireEnabled();
|
||||
if (metadataJson.isEmpty() || payloadBytes.length == 0) { state = State.ERROR; return FieldSubmitResult.REJECTED_ADAPTER; }
|
||||
if (metadataJson.isEmpty() || payloadBytes.length == 0) return FieldSubmitResult.REJECTED_ADAPTER;
|
||||
FieldSubmitResult result = FieldSubmitResult.fromCode(map.submitRasterArraySourceHostField(config.sourceId, metadataJson, payloadBytes));
|
||||
state = stateAfterSubmit(state, result);
|
||||
return result;
|
||||
@@ -71,6 +71,7 @@ public final class WeatherRuntime {
|
||||
state = stateAfterDisable(color && particle && clear);
|
||||
return result(color && particle && clear);
|
||||
}
|
||||
if (state == State.ERROR) return CommandResult.REJECTED;
|
||||
if (state != State.DISABLED) return CommandResult.ACCEPTED;
|
||||
boolean color = map.setStyleLayerVisibility(config.weatherColorLayerId, weatherColorVisible);
|
||||
boolean particle = map.setStyleLayerVisibility(config.particleLayerId, particleVisible);
|
||||
@@ -105,13 +106,14 @@ public final class WeatherRuntime {
|
||||
if (submit == FieldSubmitResult.ACCEPTED_PENDING_INITIAL_WINDOW) return State.WAITING_FOR_FIELDS;
|
||||
if (submit == FieldSubmitResult.INITIAL_WINDOW_READY || submit == FieldSubmitResult.ACCEPTED_NEXT_SNAPSHOT) return State.READY;
|
||||
if (submit == FieldSubmitResult.DUPLICATE) return current;
|
||||
return State.ERROR;
|
||||
return submit == FieldSubmitResult.REJECTED_SOURCE_MODE || submit == FieldSubmitResult.UNKNOWN ? State.ERROR : current;
|
||||
}
|
||||
static State stateAfterClear(State current, boolean accepted) { return accepted ? State.WAITING_FOR_FIELDS : current; }
|
||||
static State stateAfterDisable(boolean accepted) { return accepted ? State.DISABLED : State.ERROR; }
|
||||
static State stateAfterEnable(State current, boolean accepted) {
|
||||
if (!accepted) return State.ERROR;
|
||||
return current == State.DISABLED ? State.WAITING_FOR_FIELDS : current;
|
||||
if (current == State.DISABLED) return State.WAITING_FOR_FIELDS;
|
||||
return current;
|
||||
}
|
||||
private void requireEnabled() { if (state == State.DISABLED) throw new IllegalStateException("WeatherRuntime is disabled; enable and submit fields first"); }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.maplibre.android.maps;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@@ -15,9 +16,51 @@ public class WeatherRuntimeStateTest {
|
||||
assertEquals(WeatherRuntime.State.READY, WeatherRuntime.stateAfterSubmit(WeatherRuntime.State.WAITING_FOR_FIELDS, WeatherRuntime.FieldSubmitResult.INITIAL_WINDOW_READY));
|
||||
assertEquals(WeatherRuntime.State.READY, WeatherRuntime.stateAfterSubmit(WeatherRuntime.State.READY, WeatherRuntime.FieldSubmitResult.DUPLICATE));
|
||||
}
|
||||
@Test public void ordinarySubmitRejectionsPreserveRuntimeState() {
|
||||
WeatherRuntime.FieldSubmitResult[] rejected = {
|
||||
WeatherRuntime.FieldSubmitResult.REJECTED_ADAPTER,
|
||||
WeatherRuntime.FieldSubmitResult.REJECTED_INCOMPATIBLE,
|
||||
WeatherRuntime.FieldSubmitResult.REJECTED_NON_MONOTONIC,
|
||||
WeatherRuntime.FieldSubmitResult.REJECTED_CAPACITY};
|
||||
for (WeatherRuntime.FieldSubmitResult result : rejected) {
|
||||
assertEquals(WeatherRuntime.State.READY, WeatherRuntime.stateAfterSubmit(WeatherRuntime.State.READY, result));
|
||||
assertEquals(WeatherRuntime.State.WAITING_FOR_FIELDS, WeatherRuntime.stateAfterSubmit(WeatherRuntime.State.WAITING_FOR_FIELDS, result));
|
||||
}
|
||||
}
|
||||
@Test public void onlyFacadeContractFailuresEnterError() {
|
||||
assertEquals(WeatherRuntime.State.ERROR, WeatherRuntime.stateAfterSubmit(WeatherRuntime.State.READY, WeatherRuntime.FieldSubmitResult.REJECTED_SOURCE_MODE));
|
||||
assertEquals(WeatherRuntime.State.ERROR, WeatherRuntime.stateAfterSubmit(WeatherRuntime.State.READY, WeatherRuntime.FieldSubmitResult.UNKNOWN));
|
||||
assertEquals(WeatherRuntime.State.ERROR, WeatherRuntime.stateAfterEnable(WeatherRuntime.State.ERROR, false));
|
||||
assertEquals(WeatherRuntime.State.ERROR, WeatherRuntime.stateAfterEnable(WeatherRuntime.State.ERROR, true));
|
||||
}
|
||||
@Test public void clearAndDisableUseSuccessfulCoreResult() {
|
||||
assertEquals(WeatherRuntime.State.WAITING_FOR_FIELDS, WeatherRuntime.stateAfterClear(WeatherRuntime.State.READY, true));
|
||||
assertEquals(WeatherRuntime.State.DISABLED, WeatherRuntime.stateAfterDisable(true));
|
||||
assertEquals(WeatherRuntime.State.ERROR, WeatherRuntime.stateAfterDisable(false));
|
||||
}
|
||||
|
||||
@Test public void publicFlowKeepsReadyOnInvalidSubmission() {
|
||||
MapLibreMap map = Mockito.mock(MapLibreMap.class);
|
||||
Mockito.when(map.getWeatherColorStopCapacity()).thenReturn(8);
|
||||
Mockito.when(map.submitRasterArraySourceHostField(Mockito.anyString(), Mockito.anyString(), Mockito.any(byte[].class)))
|
||||
.thenReturn(MapLibreMap.HOST_FIELD_INITIAL_WINDOW_READY)
|
||||
.thenReturn(MapLibreMap.HOST_FIELD_REJECTED_ADAPTER);
|
||||
WeatherRuntime runtime = new WeatherRuntime(map, new WeatherRuntime.Config("source", "color", "particle"));
|
||||
assertEquals(WeatherRuntime.FieldSubmitResult.INITIAL_WINDOW_READY, runtime.submitWindField("{}", new byte[] {1}));
|
||||
assertEquals(WeatherRuntime.FieldSubmitResult.REJECTED_ADAPTER, runtime.submitWindField("{}", new byte[] {1}));
|
||||
assertEquals(WeatherRuntime.State.READY, runtime.getState());
|
||||
assertEquals(WeatherRuntime.FieldSubmitResult.REJECTED_ADAPTER, runtime.submitWindField("", new byte[] {1}));
|
||||
assertEquals(WeatherRuntime.State.READY, runtime.getState());
|
||||
}
|
||||
|
||||
@Test public void publicFlowRejectsEnableFromErrorWithoutVisibilityRecovery() {
|
||||
MapLibreMap map = Mockito.mock(MapLibreMap.class);
|
||||
Mockito.when(map.getWeatherColorStopCapacity()).thenReturn(8);
|
||||
WeatherRuntime runtime = new WeatherRuntime(map, new WeatherRuntime.Config("source", "color", "particle"));
|
||||
assertEquals(WeatherRuntime.FieldSubmitResult.UNKNOWN, runtime.submitWindField("{}", new byte[] {1}));
|
||||
assertEquals(WeatherRuntime.State.ERROR, runtime.getState());
|
||||
assertEquals(WeatherRuntime.CommandResult.REJECTED, runtime.setWeatherEnabled(true));
|
||||
assertEquals(WeatherRuntime.State.ERROR, runtime.getState());
|
||||
Mockito.verify(map, Mockito.never()).setStyleLayerVisibility(Mockito.anyString(), Mockito.anyBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user