Skip to content

Commit dbf6f7d

Browse files
committed
Polish ExpressionState[Tests]
1 parent 8fa428f commit dbf6f7d

File tree

2 files changed

+45
-72
lines changed

2 files changed

+45
-72
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public ExpressionState(EvaluationContext context, TypedValue rootObject) {
9393

9494
public ExpressionState(EvaluationContext context, TypedValue rootObject, SpelParserConfiguration configuration) {
9595
Assert.notNull(context, "EvaluationContext must not be null");
96+
Assert.notNull(context, "'rootObject' must not be null");
9697
Assert.notNull(configuration, "SpelParserConfiguration must not be null");
9798
this.relatedContext = context;
9899
this.rootObject = rootObject;
@@ -203,7 +204,7 @@ public Object convertValue(TypedValue value, TypeDescriptor targetTypeDescriptor
203204
/*
204205
* A new scope is entered when a function is invoked.
205206
*/
206-
public void enterScope(Map<String, Object> argMap) {
207+
public void enterScope(@Nullable Map<String, Object> argMap) {
207208
initVariableScopes().push(new VariableScope(argMap));
208209
initScopeRootObjects().push(getActiveContextObject());
209210
}
@@ -300,9 +301,10 @@ public VariableScope(@Nullable Map<String, Object> arguments) {
300301
}
301302

302303
public VariableScope(String name, Object value) {
303-
this.vars.put(name,value);
304+
this.vars.put(name, value);
304305
}
305306

307+
@Nullable
306308
public Object lookupVariable(String name) {
307309
return this.vars.get(name);
308310
}

spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java

Lines changed: 41 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.expression.spel;
1818

19-
import java.util.HashMap;
2019
import java.util.Map;
2120

2221
import org.junit.jupiter.api.Test;
@@ -34,27 +33,31 @@
3433
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
3534

3635
/**
37-
* Tests for the expression state object - some features are not yet exploited in the language (eg nested scopes)
36+
* Tests for {@link ExpressionState}.
37+
*
38+
* <p>Some features are not yet exploited in the language, such as nested scopes
39+
* or local variables scoped to the currently evaluated expression.
40+
*
41+
* <p>Local variables are in variable scopes which come and go during evaluation.
42+
* Normal/global variables are accessible through the {@link EvaluationContext}.
3843
*
3944
* @author Andy Clement
4045
* @author Juergen Hoeller
4146
*/
42-
public class ExpressionStateTests extends AbstractExpressionTests {
47+
class ExpressionStateTests extends AbstractExpressionTests {
48+
49+
private ExpressionState state = new ExpressionState(TestScenarioCreator.getTestEvaluationContext());
50+
4351

4452
@Test
45-
public void testConstruction() {
53+
void construction() {
4654
EvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
4755
ExpressionState state = new ExpressionState(context);
4856
assertThat(state.getEvaluationContext()).isEqualTo(context);
4957
}
5058

51-
// Local variables are in variable scopes which come and go during evaluation. Normal variables are
52-
// accessible through the evaluation context
53-
5459
@Test
55-
public void testLocalVariables() {
56-
ExpressionState state = getState();
57-
60+
void localVariables() {
5861
Object value = state.lookupLocalVariable("foo");
5962
assertThat(value).isNull();
6063

@@ -68,8 +71,7 @@ public void testLocalVariables() {
6871
}
6972

7073
@Test
71-
public void testVariables() {
72-
ExpressionState state = getState();
74+
void globalVariables() {
7375
TypedValue typedValue = state.lookupVariable("foo");
7476
assertThat(typedValue).isEqualTo(TypedValue.NULL);
7577

@@ -85,8 +87,7 @@ public void testVariables() {
8587
}
8688

8789
@Test
88-
public void testNoVariableInterference() {
89-
ExpressionState state = getState();
90+
void noVariableInterference() {
9091
TypedValue typedValue = state.lookupVariable("foo");
9192
assertThat(typedValue).isEqualTo(TypedValue.NULL);
9293

@@ -99,8 +100,7 @@ public void testNoVariableInterference() {
99100
}
100101

101102
@Test
102-
public void testLocalVariableNestedScopes() {
103-
ExpressionState state = getState();
103+
void localVariableNestedScopes() {
104104
assertThat(state.lookupLocalVariable("foo")).isNull();
105105

106106
state.setLocalVariable("foo",12);
@@ -120,30 +120,26 @@ public void testLocalVariableNestedScopes() {
120120
}
121121

122122
@Test
123-
public void testRootContextObject() {
124-
ExpressionState state = getState();
123+
void rootContextObject() {
125124
assertThat(state.getRootContextObject().getValue().getClass()).isEqualTo(Inventor.class);
126125

127-
// although the root object is being set on the evaluation context, the value in the 'state' remains what it was when constructed
126+
// Although the root object is being set on the evaluation context,
127+
// the value in the 'state' remains what it was when constructed.
128128
((StandardEvaluationContext) state.getEvaluationContext()).setRootObject(null);
129-
assertThat(state.getRootContextObject().getValue().getClass()).isEqualTo(Inventor.class);
130-
// assertEquals(null, state.getRootContextObject().getValue());
129+
assertThat(state.getRootContextObject().getValue()).isInstanceOf(Inventor.class);
131130

132131
state = new ExpressionState(new StandardEvaluationContext());
133132
assertThat(state.getRootContextObject()).isEqualTo(TypedValue.NULL);
134133

135-
136134
((StandardEvaluationContext) state.getEvaluationContext()).setRootObject(null);
137135
assertThat(state.getRootContextObject().getValue()).isNull();
138136
}
139137

140138
@Test
141-
public void testActiveContextObject() {
142-
ExpressionState state = getState();
139+
void activeContextObject() {
143140
assertThat(state.getActiveContextObject().getValue()).isEqualTo(state.getRootContextObject().getValue());
144141

145-
assertThatIllegalStateException().isThrownBy(
146-
state::popActiveContextObject);
142+
assertThatIllegalStateException().isThrownBy(state::popActiveContextObject);
147143

148144
state.pushActiveContextObject(new TypedValue(34));
149145
assertThat(state.getActiveContextObject().getValue()).isEqualTo(34);
@@ -162,8 +158,7 @@ public void testActiveContextObject() {
162158
}
163159

164160
@Test
165-
public void testPopulatedNestedScopes() {
166-
ExpressionState state = getState();
161+
void populatedNestedScopes() {
167162
assertThat(state.lookupLocalVariable("foo")).isNull();
168163

169164
state.enterScope("foo",34);
@@ -181,27 +176,22 @@ public void testPopulatedNestedScopes() {
181176
}
182177

183178
@Test
184-
public void testRootObjectConstructor() {
185-
EvaluationContext ctx = getContext();
179+
void rootObjectConstructor() {
180+
EvaluationContext ctx = TestScenarioCreator.getTestEvaluationContext();
186181
// TypedValue root = ctx.getRootObject();
187182
// supplied should override root on context
188-
ExpressionState state = new ExpressionState(ctx,new TypedValue("i am a string"));
183+
ExpressionState state = new ExpressionState(ctx, new TypedValue("i am a string"));
189184
TypedValue stateRoot = state.getRootContextObject();
190185
assertThat(stateRoot.getTypeDescriptor().getType()).isEqualTo(String.class);
191186
assertThat(stateRoot.getValue()).isEqualTo("i am a string");
192187
}
193188

194189
@Test
195-
public void testPopulatedNestedScopesMap() {
196-
ExpressionState state = getState();
190+
void populatedNestedScopesMap() {
197191
assertThat(state.lookupLocalVariable("foo")).isNull();
198192
assertThat(state.lookupLocalVariable("goo")).isNull();
199193

200-
Map<String,Object> m = new HashMap<>();
201-
m.put("foo", 34);
202-
m.put("goo", "abc");
203-
204-
state.enterScope(m);
194+
state.enterScope(Map.of("foo", 34, "goo", "abc"));
205195
assertThat(state.lookupLocalVariable("foo")).isEqualTo(34);
206196
assertThat(state.lookupLocalVariable("goo")).isEqualTo("abc");
207197

@@ -217,61 +207,42 @@ public void testPopulatedNestedScopesMap() {
217207
}
218208

219209
@Test
220-
public void testOperators() {
221-
ExpressionState state = getState();
222-
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
223-
state.operate(Operation.ADD,1,2))
210+
void operators() {
211+
assertThatExceptionOfType(SpelEvaluationException.class)
212+
.isThrownBy(() -> state.operate(Operation.ADD,1,2))
224213
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES));
225214

226-
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
227-
state.operate(Operation.ADD,null,null))
215+
assertThatExceptionOfType(SpelEvaluationException.class)
216+
.isThrownBy(() -> state.operate(Operation.ADD,null,null))
228217
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES));
229218
}
230219

231220
@Test
232-
public void testComparator() {
233-
ExpressionState state = getState();
221+
void comparator() {
234222
assertThat(state.getTypeComparator()).isEqualTo(state.getEvaluationContext().getTypeComparator());
235223
}
236224

237225
@Test
238-
public void testTypeLocator() throws EvaluationException {
239-
ExpressionState state = getState();
226+
void typeLocator() throws EvaluationException {
240227
assertThat(state.getEvaluationContext().getTypeLocator()).isNotNull();
241228
assertThat(state.findType("java.lang.Integer")).isEqualTo(Integer.class);
242-
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
243-
state.findType("someMadeUpName"))
229+
assertThatExceptionOfType(SpelEvaluationException.class)
230+
.isThrownBy(() -> state.findType("someMadeUpName"))
244231
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(SpelMessage.TYPE_NOT_FOUND));
245-
246232
}
247233

248234
@Test
249-
public void testTypeConversion() throws EvaluationException {
250-
ExpressionState state = getState();
235+
void typeConversion() throws EvaluationException {
251236
String s = (String) state.convertValue(34, TypeDescriptor.valueOf(String.class));
252237
assertThat(s).isEqualTo("34");
253238

254-
s = (String)state.convertValue(new TypedValue(34), TypeDescriptor.valueOf(String.class));
239+
s = (String) state.convertValue(new TypedValue(34), TypeDescriptor.valueOf(String.class));
255240
assertThat(s).isEqualTo("34");
256241
}
257242

258243
@Test
259-
public void testPropertyAccessors() {
260-
ExpressionState state = getState();
244+
void propertyAccessors() {
261245
assertThat(state.getPropertyAccessors()).isEqualTo(state.getEvaluationContext().getPropertyAccessors());
262246
}
263247

264-
/**
265-
* @return a new ExpressionState
266-
*/
267-
private ExpressionState getState() {
268-
EvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
269-
ExpressionState state = new ExpressionState(context);
270-
return state;
271-
}
272-
273-
private EvaluationContext getContext() {
274-
return TestScenarioCreator.getTestEvaluationContext();
275-
}
276-
277248
}

0 commit comments

Comments
 (0)