2222
2323import org .springframework .core .Ordered ;
2424import org .springframework .expression .Expression ;
25+ import org .springframework .expression .spel .SpelCompilationCoverageTests ;
2526import org .springframework .expression .spel .SpelCompilerMode ;
2627import org .springframework .expression .spel .SpelParserConfiguration ;
28+ import org .springframework .expression .spel .support .StandardEvaluationContext ;
2729
2830import static org .assertj .core .api .Assertions .assertThat ;
2931
3032/**
3133 * Tests for the {@link SpelCompiler}.
3234 *
3335 * @author Sam Brannen
36+ * @author Andy Clement
3437 * @since 5.1.14
3538 */
3639class SpelCompilerTests {
3740
38- @ Test // gh-24357
41+ @ Test // gh-24357
3942 void expressionCompilesWhenMethodComesFromPublicInterface () {
4043 SpelParserConfiguration config = new SpelParserConfiguration (SpelCompilerMode .IMMEDIATE , null );
4144 SpelExpressionParser parser = new SpelExpressionParser (config );
@@ -47,6 +50,31 @@ void expressionCompilesWhenMethodComesFromPublicInterface() {
4750 IntStream .rangeClosed (1 , 5 ).forEach (i -> assertThat (expression .getValue (component )).isEqualTo (42 ));
4851 }
4952
53+ @ Test // gh-25706
54+ void defaultMethodInvocation () {
55+ SpelParserConfiguration config = new SpelParserConfiguration (SpelCompilerMode .IMMEDIATE , null );
56+ SpelExpressionParser parser = new SpelExpressionParser (config );
57+
58+ StandardEvaluationContext context = new StandardEvaluationContext ();
59+ Item item = new Item ();
60+ context .setRootObject (item );
61+
62+ Expression expression = parser .parseExpression ("#root.isEditable2()" );
63+ assertThat (SpelCompiler .compile (expression )).isFalse ();
64+ assertThat (expression .getValue (context )).isEqualTo (false );
65+ assertThat (SpelCompiler .compile (expression )).isTrue ();
66+ SpelCompilationCoverageTests .assertIsCompiled (expression );
67+ assertThat (expression .getValue (context )).isEqualTo (false );
68+
69+ context .setVariable ("user" , new User ());
70+ expression = parser .parseExpression ("#root.isEditable(#user)" );
71+ assertThat (SpelCompiler .compile (expression )).isFalse ();
72+ assertThat (expression .getValue (context )).isEqualTo (true );
73+ assertThat (SpelCompiler .compile (expression )).isTrue ();
74+ SpelCompilationCoverageTests .assertIsCompiled (expression );
75+ assertThat (expression .getValue (context )).isEqualTo (true );
76+ }
77+
5078
5179 static class OrderedComponent implements Ordered {
5280
@@ -56,4 +84,40 @@ public int getOrder() {
5684 }
5785 }
5886
87+
88+ public static class User {
89+
90+ boolean isAdmin () {
91+ return true ;
92+ }
93+ }
94+
95+
96+ public static class Item implements Editable {
97+
98+ // some fields
99+ private String someField = "" ;
100+
101+ // some getters and setters
102+
103+ @ Override
104+ public boolean hasSomeProperty () {
105+ return someField != null ;
106+ }
107+ }
108+
109+
110+ public interface Editable {
111+
112+ default boolean isEditable (User user ) {
113+ return user .isAdmin () && hasSomeProperty ();
114+ }
115+
116+ default boolean isEditable2 () {
117+ return false ;
118+ }
119+
120+ boolean hasSomeProperty ();
121+ }
122+
59123}
0 commit comments