|
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.
|
@@ -4945,6 +4945,91 @@ public void elvisOperator_SPR17214() throws Exception {
|
4945 | 4945 | assertNull(expression.getValue(rh));
|
4946 | 4946 | }
|
4947 | 4947 |
|
| 4948 | + @Test |
| 4949 | + public void testNullComparison_SPR22358() { |
| 4950 | + SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.OFF, null); |
| 4951 | + SpelExpressionParser parser = new SpelExpressionParser(configuration); |
| 4952 | + StandardEvaluationContext ctx = new StandardEvaluationContext(); |
| 4953 | + ctx.setRootObject(new Reg(1)); |
| 4954 | + verifyCompilationAndBehaviourWithNull("value>1", parser, ctx ); |
| 4955 | + verifyCompilationAndBehaviourWithNull("value<1", parser, ctx ); |
| 4956 | + verifyCompilationAndBehaviourWithNull("value>=1", parser, ctx ); |
| 4957 | + verifyCompilationAndBehaviourWithNull("value<=1", parser, ctx ); |
| 4958 | + |
| 4959 | + verifyCompilationAndBehaviourWithNull2("value>value2", parser, ctx ); |
| 4960 | + verifyCompilationAndBehaviourWithNull2("value<value2", parser, ctx ); |
| 4961 | + verifyCompilationAndBehaviourWithNull2("value>=value2", parser, ctx ); |
| 4962 | + verifyCompilationAndBehaviourWithNull2("value<=value2", parser, ctx ); |
| 4963 | + |
| 4964 | + verifyCompilationAndBehaviourWithNull("valueD>1.0d", parser, ctx ); |
| 4965 | + verifyCompilationAndBehaviourWithNull("valueD<1.0d", parser, ctx ); |
| 4966 | + verifyCompilationAndBehaviourWithNull("valueD>=1.0d", parser, ctx ); |
| 4967 | + verifyCompilationAndBehaviourWithNull("valueD<=1.0d", parser, ctx ); |
| 4968 | + |
| 4969 | + verifyCompilationAndBehaviourWithNull2("valueD>valueD2", parser, ctx ); |
| 4970 | + verifyCompilationAndBehaviourWithNull2("valueD<valueD2", parser, ctx ); |
| 4971 | + verifyCompilationAndBehaviourWithNull2("valueD>=valueD2", parser, ctx ); |
| 4972 | + verifyCompilationAndBehaviourWithNull2("valueD<=valueD2", parser, ctx ); |
| 4973 | + |
| 4974 | + verifyCompilationAndBehaviourWithNull("valueL>1L", parser, ctx ); |
| 4975 | + verifyCompilationAndBehaviourWithNull("valueL<1L", parser, ctx ); |
| 4976 | + verifyCompilationAndBehaviourWithNull("valueL>=1L", parser, ctx ); |
| 4977 | + verifyCompilationAndBehaviourWithNull("valueL<=1L", parser, ctx ); |
| 4978 | + |
| 4979 | + verifyCompilationAndBehaviourWithNull2("valueL>valueL2", parser, ctx ); |
| 4980 | + verifyCompilationAndBehaviourWithNull2("valueL<valueL2", parser, ctx ); |
| 4981 | + verifyCompilationAndBehaviourWithNull2("valueL>=valueL2", parser, ctx ); |
| 4982 | + verifyCompilationAndBehaviourWithNull2("valueL<=valueL2", parser, ctx ); |
| 4983 | + |
| 4984 | + verifyCompilationAndBehaviourWithNull("valueF>1.0f", parser, ctx ); |
| 4985 | + verifyCompilationAndBehaviourWithNull("valueF<1.0f", parser, ctx ); |
| 4986 | + verifyCompilationAndBehaviourWithNull("valueF>=1.0f", parser, ctx ); |
| 4987 | + verifyCompilationAndBehaviourWithNull("valueF<=1.0f", parser, ctx ); |
| 4988 | + |
| 4989 | + verifyCompilationAndBehaviourWithNull("valueF>valueF2", parser, ctx ); |
| 4990 | + verifyCompilationAndBehaviourWithNull("valueF<valueF2", parser, ctx ); |
| 4991 | + verifyCompilationAndBehaviourWithNull("valueF>=valueF2", parser, ctx ); |
| 4992 | + verifyCompilationAndBehaviourWithNull("valueF<=valueF2", parser, ctx ); |
| 4993 | + } |
| 4994 | + |
| 4995 | + private void verifyCompilationAndBehaviourWithNull(String expressionText, SpelExpressionParser parser, StandardEvaluationContext ctx) { |
| 4996 | + Reg r = (Reg)ctx.getRootObject().getValue(); |
| 4997 | + r.setValue2(1); // having a value in value2 fields will enable compilation to succeed, then can switch it to null |
| 4998 | + SpelExpression fast = (SpelExpression) parser.parseExpression(expressionText); |
| 4999 | + SpelExpression slow = (SpelExpression) parser.parseExpression(expressionText); |
| 5000 | + fast.getValue(ctx); |
| 5001 | + assertTrue(fast.compileExpression()); |
| 5002 | + r.setValue2(null); |
| 5003 | + // try the numbers 0,1,2,null |
| 5004 | + for (int i=0;i<4;i++) { |
| 5005 | + r.setValue(i<3?i:null); |
| 5006 | + boolean slowResult = (Boolean)slow.getValue(ctx); |
| 5007 | + boolean fastResult = (Boolean)fast.getValue(ctx); |
| 5008 | + // System.out.println("Trying "+expressionText+" with value="+r.getValue()+" result is "+slowResult); |
| 5009 | + assertEquals(" Differing results: expression="+expressionText+ |
| 5010 | + " value="+r.getValue()+" slow="+slowResult+" fast="+fastResult, |
| 5011 | + slowResult,fastResult); |
| 5012 | + } |
| 5013 | + } |
| 5014 | + |
| 5015 | + private void verifyCompilationAndBehaviourWithNull2(String expressionText, SpelExpressionParser parser, StandardEvaluationContext ctx) { |
| 5016 | + SpelExpression fast = (SpelExpression) parser.parseExpression(expressionText); |
| 5017 | + SpelExpression slow = (SpelExpression) parser.parseExpression(expressionText); |
| 5018 | + fast.getValue(ctx); |
| 5019 | + assertTrue(fast.compileExpression()); |
| 5020 | + Reg r = (Reg)ctx.getRootObject().getValue(); |
| 5021 | + // try the numbers 0,1,2,null |
| 5022 | + for (int i=0;i<4;i++) { |
| 5023 | + r.setValue(i<3?i:null); |
| 5024 | + boolean slowResult = (Boolean)slow.getValue(ctx); |
| 5025 | + boolean fastResult = (Boolean)fast.getValue(ctx); |
| 5026 | + // System.out.println("Trying "+expressionText+" with value="+r.getValue()+" result is "+slowResult); |
| 5027 | + assertEquals(" Differing results: expression="+expressionText+ |
| 5028 | + " value="+r.getValue()+" slow="+slowResult+" fast="+fastResult, |
| 5029 | + slowResult,fastResult); |
| 5030 | + } |
| 5031 | + } |
| 5032 | + |
4948 | 5033 | @Test
|
4949 | 5034 | public void ternaryOperator_SPR15192() {
|
4950 | 5035 | SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
@@ -5039,7 +5124,7 @@ public void repeatedCompilation() throws Exception {
|
5039 | 5124 | }
|
5040 | 5125 |
|
5041 | 5126 |
|
5042 |
| - // helper methods |
| 5127 | + // Helper methods |
5043 | 5128 |
|
5044 | 5129 | private SpelNodeImpl getAst() {
|
5045 | 5130 | SpelExpression spelExpression = (SpelExpression) expression;
|
@@ -5111,7 +5196,7 @@ private void assertIsCompiled(Expression expression) {
|
5111 | 5196 | }
|
5112 | 5197 |
|
5113 | 5198 |
|
5114 |
| - // nested types |
| 5199 | + // Nested types |
5115 | 5200 |
|
5116 | 5201 | public interface Message<T> {
|
5117 | 5202 |
|
@@ -6129,4 +6214,66 @@ public static class LongHolder {
|
6129 | 6214 | public Long someLong = 3L;
|
6130 | 6215 | }
|
6131 | 6216 |
|
| 6217 | + |
| 6218 | + public class Reg { |
| 6219 | + |
| 6220 | + private Integer _value,_value2; |
| 6221 | + private Long _valueL,_valueL2; |
| 6222 | + private Double _valueD,_valueD2; |
| 6223 | + private Float _valueF,_valueF2; |
| 6224 | + |
| 6225 | + public Reg(int v) { |
| 6226 | + this._value = v; |
| 6227 | + this._valueL = new Long(v); |
| 6228 | + this._valueD = new Double(v); |
| 6229 | + this._valueF = new Float(v); |
| 6230 | + } |
| 6231 | + |
| 6232 | + public Integer getValue() { |
| 6233 | + return _value; |
| 6234 | + } |
| 6235 | + |
| 6236 | + public Long getValueL() { |
| 6237 | + return _valueL; |
| 6238 | + } |
| 6239 | + |
| 6240 | + public Double getValueD() { |
| 6241 | + return _valueD; |
| 6242 | + } |
| 6243 | + |
| 6244 | + public Float getValueF() { |
| 6245 | + return _valueF; |
| 6246 | + } |
| 6247 | + |
| 6248 | + public Integer getValue2() { |
| 6249 | + return _value2; |
| 6250 | + } |
| 6251 | + |
| 6252 | + public Long getValueL2() { |
| 6253 | + return _valueL2; |
| 6254 | + } |
| 6255 | + |
| 6256 | + public Double getValueD2() { |
| 6257 | + return _valueD2; |
| 6258 | + } |
| 6259 | + |
| 6260 | + public Float getValueF2() { |
| 6261 | + return _valueF2; |
| 6262 | + } |
| 6263 | + |
| 6264 | + public void setValue(Integer value) { |
| 6265 | + _value = value; |
| 6266 | + _valueL = value==null?null:new Long(value); |
| 6267 | + _valueD = value==null?null:new Double(value); |
| 6268 | + _valueF = value==null?null:new Float(value); |
| 6269 | + } |
| 6270 | + |
| 6271 | + public void setValue2(Integer value) { |
| 6272 | + _value2 = value; |
| 6273 | + _valueL2 = value==null?null:new Long(value); |
| 6274 | + _valueD2 = value==null?null:new Double(value); |
| 6275 | + _valueF2 = value==null?null:new Float(value); |
| 6276 | + } |
| 6277 | + } |
| 6278 | + |
6132 | 6279 | }
|
0 commit comments