Skip to content
This repository was archived by the owner on Sep 9, 2024. It is now read-only.

Commit 42137a0

Browse files
committed
feat!: Change config map for a more convenient SetupInfo object
1 parent cad6ae4 commit 42137a0

7 files changed

Lines changed: 114 additions & 10 deletions

File tree

src/main/java/io/contract_testing/contractcase/BoundaryTriggerMapper.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,23 @@ static <T> ITriggerFunction map(
1212
TestResponseFunction<T> testResponseFunction) {
1313

1414
return config -> {
15+
16+
SetupInfo setupInfo;
17+
try {
18+
setupInfo = SetupInfo.from(config);
19+
} catch (Throwable e) {
20+
return ConnectorExceptionMapper.map(e);
21+
}
22+
1523
T ret;
1624
try {
17-
ret = trigger.call(config);
25+
ret = trigger.call(setupInfo);
1826
} catch (Throwable e) {
1927
return ConnectorExceptionMapper.mapAsTriggerFailure(e);
2028
}
2129

2230
try {
23-
testResponseFunction.call(ret);
31+
testResponseFunction.call(ret, setupInfo);
2432
} catch (Throwable e) {
2533
return ConnectorExceptionMapper.mapAsVerifyFailure(e);
2634
}
@@ -32,13 +40,19 @@ static <T> ITriggerFunction map(
3240
static <T> ITriggerFunction map(Trigger<T> trigger,
3341
TestErrorResponseFunction testErrorResponseFunction) {
3442
return config -> {
43+
SetupInfo setupInfo;
44+
try {
45+
setupInfo = SetupInfo.from(config);
46+
} catch (Throwable e) {
47+
return ConnectorExceptionMapper.map(e);
48+
}
3549
try {
36-
trigger.call(config);
50+
trigger.call(setupInfo);
3751
return ConnectorExceptionMapper.mapAsTriggerFailure(
3852
new RuntimeException("Expected the trigger to fail, but it did not"));
3953
} catch (Throwable triggerException) {
4054
try {
41-
testErrorResponseFunction.call(triggerException);
55+
testErrorResponseFunction.call(triggerException, setupInfo);
4256
} catch (Throwable verifyException) {
4357
return ConnectorExceptionMapper.mapAsVerifyFailure(verifyException);
4458
}

src/main/java/io/contract_testing/contractcase/ContractCaseCoreError.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public ContractCaseCoreError(Throwable e) {
3131
}
3232

3333
public ContractCaseCoreError(@NotNull String message, Throwable cause) {
34-
super(message, cause);
34+
super(message + "(" + cause.getMessage() + ")", cause);
3535
if (cause instanceof ContractCaseCoreError) {
3636
this.location = ((ContractCaseCoreError) cause).getLocation();
3737
} else {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package io.contract_testing.contractcase;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.Map;
6+
import java.util.stream.Collectors;
7+
8+
/**
9+
* Container for information about the mock side of a particular example
10+
*/
11+
public class SetupInfo {
12+
13+
public static final String STATE_VARIABLES_KEY = "variables";
14+
private final Map<String, Object> config;
15+
16+
private final Map<String, String> stateVariables;
17+
18+
private SetupInfo(Map<String, Object> config) {
19+
this.config = config;
20+
var variables = config.get(STATE_VARIABLES_KEY);
21+
if (variables == null) {
22+
this.stateVariables = Map.of();
23+
} else {
24+
try {
25+
this.stateVariables = Collections.unmodifiableMap((Map<String, String>) variables);
26+
} catch (ClassCastException e) {
27+
throw new ContractCaseCoreError("Invalid variables array in SetupInfo constructor", e);
28+
}
29+
}
30+
}
31+
32+
/**
33+
* Get a state variable set by a state definition or state handler
34+
*
35+
* @param key the state variable key that was defined in the state handler
36+
* @return The value of this state variable
37+
* @throws ContractCaseConfigurationError if there is no value for this key
38+
*/
39+
public String getStateVariable(String key) {
40+
if (this.stateVariables.get(key) == null) {
41+
var stateKeys = new ArrayList<>(this.stateVariables.keySet());
42+
throw new ContractCaseConfigurationError("No state variable present with name '" + key
43+
+ "'. Check the variable is defined in the contract. "
44+
+ (stateKeys.size() == 0
45+
? "There are no currently defined state variables"
46+
: "Currently defined variables are: \n"
47+
+ stateKeys
48+
.stream().map(s -> " " + s)
49+
.collect(Collectors.joining("\n"))));
50+
}
51+
return this.stateVariables.get(key);
52+
}
53+
54+
/**
55+
* Get a configuration parameter for the running mock example
56+
*
57+
* @param key the configuration key for this mock
58+
* @return The value of this configuration setting
59+
* @throws ContractCaseConfigurationError if there is no value for this key
60+
*/
61+
public String getInfo(String key) {
62+
if (this.config.get(key) == null) {
63+
throw new ContractCaseConfigurationError("No setup information for key '" + key
64+
+ "'. Check the key is correct for this mock type");
65+
}
66+
67+
try {
68+
return (String) this.config.get(key);
69+
} catch (ClassCastException e) {
70+
throw new ContractCaseCoreError(
71+
"The setup key '" + key + "' contained something that couldn't cast to a string",
72+
e
73+
);
74+
}
75+
}
76+
77+
/**
78+
* Construct a new SetupInfo convenience object from this configuration map
79+
*
80+
* @param config The configuration map from the Connector
81+
* @return a new SetupInfo object
82+
*/
83+
static SetupInfo from(Map<String, Object> config) {
84+
return new SetupInfo(config);
85+
}
86+
87+
}

src/main/java/io/contract_testing/contractcase/TestErrorResponseFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
public interface TestErrorResponseFunction {
44

5-
void call(Throwable e);
5+
void call(Throwable e, SetupInfo config);
66
}

src/main/java/io/contract_testing/contractcase/TestResponseFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
public interface TestResponseFunction<T> {
44

5-
void call(T returnedObject);
5+
void call(T returnedObject, SetupInfo config);
66
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package io.contract_testing.contractcase;
22

3-
import java.util.Map;
43
import org.jetbrains.annotations.NotNull;
54

65
public interface Trigger<T> {
76

8-
T call(final @NotNull Map<String, Object> config);
7+
T call(final @NotNull SetupInfo setupInfo);
98
}

src/main/java/io/contract_testing/contractcase/edge/ConnectorExceptionMapper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.contract_testing.contractcase.edge;
22

3+
import io.contract_testing.contractcase.ContractCaseConfigurationError;
34
import io.contract_testing.contractcase.ContractCaseCoreError;
45
import java.util.Arrays;
56
import java.util.stream.Collectors;
@@ -13,7 +14,10 @@ public static String stackTraceToString(Throwable e) {
1314

1415
public static ConnectorFailure map(Throwable e) {
1516
var failure = new ConnectorFailure(
16-
e.getClass().getName(),
17+
e instanceof ContractCaseConfigurationError
18+
? ConnectorFailureKindConstants.CASE_CONFIGURATION_ERROR
19+
: ConnectorFailureKindConstants.CASE_CORE_ERROR
20+
,
1721
e.getMessage(),
1822
stackTraceToString(e)
1923
);

0 commit comments

Comments
 (0)