|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2018 the original author or authors. |
| 2 | + * Copyright 2002-2019 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -4943,6 +4943,91 @@ public void elvisOperator_SPR17214() throws Exception {
|
4943 | 4943 | assertNull(expression.getValue(rh));
|
4944 | 4944 | }
|
4945 | 4945 |
|
| 4946 | + @Test |
| 4947 | + public void testNullComparison_SPR22358() { |
| 4948 | + SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.OFF, null); |
| 4949 | + SpelExpressionParser parser = new SpelExpressionParser(configuration); |
| 4950 | + StandardEvaluationContext ctx = new StandardEvaluationContext(); |
| 4951 | + ctx.setRootObject(new Reg(1)); |
| 4952 | + verifyCompilationAndBehaviourWithNull("value>1", parser, ctx ); |
| 4953 | + verifyCompilationAndBehaviourWithNull("value<1", parser, ctx ); |
| 4954 | + verifyCompilationAndBehaviourWithNull("value>=1", parser, ctx ); |
| 4955 | + verifyCompilationAndBehaviourWithNull("value<=1", parser, ctx ); |
| 4956 | + |
| 4957 | + verifyCompilationAndBehaviourWithNull2("value>value2", parser, ctx ); |
| 4958 | + verifyCompilationAndBehaviourWithNull2("value<value2", parser, ctx ); |
| 4959 | + verifyCompilationAndBehaviourWithNull2("value>=value2", parser, ctx ); |
| 4960 | + verifyCompilationAndBehaviourWithNull2("value<=value2", parser, ctx ); |
| 4961 | + |
| 4962 | + verifyCompilationAndBehaviourWithNull("valueD>1.0d", parser, ctx ); |
| 4963 | + verifyCompilationAndBehaviourWithNull("valueD<1.0d", parser, ctx ); |
| 4964 | + verifyCompilationAndBehaviourWithNull("valueD>=1.0d", parser, ctx ); |
| 4965 | + verifyCompilationAndBehaviourWithNull("valueD<=1.0d", parser, ctx ); |
| 4966 | + |
| 4967 | + verifyCompilationAndBehaviourWithNull2("valueD>valueD2", parser, ctx ); |
| 4968 | + verifyCompilationAndBehaviourWithNull2("valueD<valueD2", parser, ctx ); |
| 4969 | + verifyCompilationAndBehaviourWithNull2("valueD>=valueD2", parser, ctx ); |
| 4970 | + verifyCompilationAndBehaviourWithNull2("valueD<=valueD2", parser, ctx ); |
| 4971 | + |
| 4972 | + verifyCompilationAndBehaviourWithNull("valueL>1L", parser, ctx ); |
| 4973 | + verifyCompilationAndBehaviourWithNull("valueL<1L", parser, ctx ); |
| 4974 | + verifyCompilationAndBehaviourWithNull("valueL>=1L", parser, ctx ); |
| 4975 | + verifyCompilationAndBehaviourWithNull("valueL<=1L", parser, ctx ); |
| 4976 | + |
| 4977 | + verifyCompilationAndBehaviourWithNull2("valueL>valueL2", parser, ctx ); |
| 4978 | + verifyCompilationAndBehaviourWithNull2("valueL<valueL2", parser, ctx ); |
| 4979 | + verifyCompilationAndBehaviourWithNull2("valueL>=valueL2", parser, ctx ); |
| 4980 | + verifyCompilationAndBehaviourWithNull2("valueL<=valueL2", parser, ctx ); |
| 4981 | + |
| 4982 | + verifyCompilationAndBehaviourWithNull("valueF>1.0f", parser, ctx ); |
| 4983 | + verifyCompilationAndBehaviourWithNull("valueF<1.0f", parser, ctx ); |
| 4984 | + verifyCompilationAndBehaviourWithNull("valueF>=1.0f", parser, ctx ); |
| 4985 | + verifyCompilationAndBehaviourWithNull("valueF<=1.0f", parser, ctx ); |
| 4986 | + |
| 4987 | + verifyCompilationAndBehaviourWithNull("valueF>valueF2", parser, ctx ); |
| 4988 | + verifyCompilationAndBehaviourWithNull("valueF<valueF2", parser, ctx ); |
| 4989 | + verifyCompilationAndBehaviourWithNull("valueF>=valueF2", parser, ctx ); |
| 4990 | + verifyCompilationAndBehaviourWithNull("valueF<=valueF2", parser, ctx ); |
| 4991 | + } |
| 4992 | + |
| 4993 | + private void verifyCompilationAndBehaviourWithNull(String expressionText, SpelExpressionParser parser, StandardEvaluationContext ctx) { |
| 4994 | + Reg r = (Reg)ctx.getRootObject().getValue(); |
| 4995 | + r.setValue2(1); // having a value in value2 fields will enable compilation to succeed, then can switch it to null |
| 4996 | + SpelExpression fast = (SpelExpression) parser.parseExpression(expressionText); |
| 4997 | + SpelExpression slow = (SpelExpression) parser.parseExpression(expressionText); |
| 4998 | + fast.getValue(ctx); |
| 4999 | + assertTrue(fast.compileExpression()); |
| 5000 | + r.setValue2(null); |
| 5001 | + // try the numbers 0,1,2,null |
| 5002 | + for (int i=0;i<4;i++) { |
| 5003 | + r.setValue(i<3?i:null); |
| 5004 | + boolean slowResult = (Boolean)slow.getValue(ctx); |
| 5005 | + boolean fastResult = (Boolean)fast.getValue(ctx); |
| 5006 | + // System.out.println("Trying "+expressionText+" with value="+r.getValue()+" result is "+slowResult); |
| 5007 | + assertEquals(" Differing results: expression="+expressionText+ |
| 5008 | + " value="+r.getValue()+" slow="+slowResult+" fast="+fastResult, |
| 5009 | + slowResult,fastResult); |
| 5010 | + } |
| 5011 | + } |
| 5012 | + |
| 5013 | + private void verifyCompilationAndBehaviourWithNull2(String expressionText, SpelExpressionParser parser, StandardEvaluationContext ctx) { |
| 5014 | + SpelExpression fast = (SpelExpression) parser.parseExpression(expressionText); |
| 5015 | + SpelExpression slow = (SpelExpression) parser.parseExpression(expressionText); |
| 5016 | + fast.getValue(ctx); |
| 5017 | + assertTrue(fast.compileExpression()); |
| 5018 | + Reg r = (Reg)ctx.getRootObject().getValue(); |
| 5019 | + // try the numbers 0,1,2,null |
| 5020 | + for (int i=0;i<4;i++) { |
| 5021 | + r.setValue(i<3?i:null); |
| 5022 | + boolean slowResult = (Boolean)slow.getValue(ctx); |
| 5023 | + boolean fastResult = (Boolean)fast.getValue(ctx); |
| 5024 | + // System.out.println("Trying "+expressionText+" with value="+r.getValue()+" result is "+slowResult); |
| 5025 | + assertEquals(" Differing results: expression="+expressionText+ |
| 5026 | + " value="+r.getValue()+" slow="+slowResult+" fast="+fastResult, |
| 5027 | + slowResult,fastResult); |
| 5028 | + } |
| 5029 | + } |
| 5030 | + |
4946 | 5031 | @Test
|
4947 | 5032 | public void ternaryOperator_SPR15192() {
|
4948 | 5033 | SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
@@ -5018,7 +5103,7 @@ public void ternaryOperator_SPR15192() {
|
5018 | 5103 | }
|
5019 | 5104 |
|
5020 | 5105 |
|
5021 |
| - // helper methods |
| 5106 | + // Helper methods |
5022 | 5107 |
|
5023 | 5108 | private SpelNodeImpl getAst() {
|
5024 | 5109 | SpelExpression spelExpression = (SpelExpression) expression;
|
@@ -5090,7 +5175,7 @@ private void assertIsCompiled(Expression expression) {
|
5090 | 5175 | }
|
5091 | 5176 |
|
5092 | 5177 |
|
5093 |
| - // nested types |
| 5178 | + // Nested types |
5094 | 5179 |
|
5095 | 5180 | public interface Message<T> {
|
5096 | 5181 |
|
@@ -6108,4 +6193,66 @@ public static class LongHolder {
|
6108 | 6193 | public Long someLong = 3L;
|
6109 | 6194 | }
|
6110 | 6195 |
|
| 6196 | + |
| 6197 | + public class Reg { |
| 6198 | + |
| 6199 | + private Integer _value,_value2; |
| 6200 | + private Long _valueL,_valueL2; |
| 6201 | + private Double _valueD,_valueD2; |
| 6202 | + private Float _valueF,_valueF2; |
| 6203 | + |
| 6204 | + public Reg(int v) { |
| 6205 | + this._value = v; |
| 6206 | + this._valueL = new Long(v); |
| 6207 | + this._valueD = new Double(v); |
| 6208 | + this._valueF = new Float(v); |
| 6209 | + } |
| 6210 | + |
| 6211 | + public Integer getValue() { |
| 6212 | + return _value; |
| 6213 | + } |
| 6214 | + |
| 6215 | + public Long getValueL() { |
| 6216 | + return _valueL; |
| 6217 | + } |
| 6218 | + |
| 6219 | + public Double getValueD() { |
| 6220 | + return _valueD; |
| 6221 | + } |
| 6222 | + |
| 6223 | + public Float getValueF() { |
| 6224 | + return _valueF; |
| 6225 | + } |
| 6226 | + |
| 6227 | + public Integer getValue2() { |
| 6228 | + return _value2; |
| 6229 | + } |
| 6230 | + |
| 6231 | + public Long getValueL2() { |
| 6232 | + return _valueL2; |
| 6233 | + } |
| 6234 | + |
| 6235 | + public Double getValueD2() { |
| 6236 | + return _valueD2; |
| 6237 | + } |
| 6238 | + |
| 6239 | + public Float getValueF2() { |
| 6240 | + return _valueF2; |
| 6241 | + } |
| 6242 | + |
| 6243 | + public void setValue(Integer value) { |
| 6244 | + _value = value; |
| 6245 | + _valueL = value==null?null:new Long(value); |
| 6246 | + _valueD = value==null?null:new Double(value); |
| 6247 | + _valueF = value==null?null:new Float(value); |
| 6248 | + } |
| 6249 | + |
| 6250 | + public void setValue2(Integer value) { |
| 6251 | + _value2 = value; |
| 6252 | + _valueL2 = value==null?null:new Long(value); |
| 6253 | + _valueD2 = value==null?null:new Double(value); |
| 6254 | + _valueF2 = value==null?null:new Float(value); |
| 6255 | + } |
| 6256 | + } |
| 6257 | + |
6111 | 6258 | }
|
0 commit comments