|
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);
|
@@ -5113,6 +5198,68 @@ private void assertIsCompiled(Expression expression) {
|
5113 | 5198 |
|
5114 | 5199 | // nested types
|
5115 | 5200 |
|
| 5201 | + public class Reg { |
| 5202 | + private Integer _value,_value2; |
| 5203 | + private Long _valueL,_valueL2; |
| 5204 | + private Double _valueD,_valueD2; |
| 5205 | + private Float _valueF,_valueF2; |
| 5206 | + |
| 5207 | + |
| 5208 | + public Reg(int v) { |
| 5209 | + this._value = v; |
| 5210 | + this._valueL = new Long(v); |
| 5211 | + this._valueD = new Double(v); |
| 5212 | + this._valueF = new Float(v); |
| 5213 | + } |
| 5214 | + |
| 5215 | + public Integer getValue() { |
| 5216 | + return _value; |
| 5217 | + } |
| 5218 | + |
| 5219 | + public Long getValueL() { |
| 5220 | + return _valueL; |
| 5221 | + } |
| 5222 | + |
| 5223 | + public Double getValueD() { |
| 5224 | + return _valueD; |
| 5225 | + } |
| 5226 | + |
| 5227 | + public Float getValueF() { |
| 5228 | + return _valueF; |
| 5229 | + } |
| 5230 | + |
| 5231 | + public Integer getValue2() { |
| 5232 | + return _value2; |
| 5233 | + } |
| 5234 | + |
| 5235 | + public Long getValueL2() { |
| 5236 | + return _valueL2; |
| 5237 | + } |
| 5238 | + |
| 5239 | + public Double getValueD2() { |
| 5240 | + return _valueD2; |
| 5241 | + } |
| 5242 | + |
| 5243 | + public Float getValueF2() { |
| 5244 | + return _valueF2; |
| 5245 | + } |
| 5246 | + |
| 5247 | + public void setValue(Integer value) { |
| 5248 | + _value = value; |
| 5249 | + _valueL = value==null?null:new Long(value); |
| 5250 | + _valueD = value==null?null:new Double(value); |
| 5251 | + _valueF = value==null?null:new Float(value); |
| 5252 | + } |
| 5253 | + |
| 5254 | + public void setValue2(Integer value) { |
| 5255 | + _value2 = value; |
| 5256 | + _valueL2 = value==null?null:new Long(value); |
| 5257 | + _valueD2 = value==null?null:new Double(value); |
| 5258 | + _valueF2 = value==null?null:new Float(value); |
| 5259 | + } |
| 5260 | + } |
| 5261 | + |
| 5262 | + |
5116 | 5263 | public interface Message<T> {
|
5117 | 5264 |
|
5118 | 5265 | MessageHeaders getHeaders();
|
|
0 commit comments