/** * Created by Srini */ describe("Test Expression Evaluation", function() { var objectValueMapperService, expressionEvaluatorService, userModel; beforeEach(module('myitsmApp')); beforeEach(inject(function (_expressionEvaluatorService_, _objectValueMapperService_, _userModel_) { expressionEvaluatorService = _expressionEvaluatorService_; objectValueMapperService = _objectValueMapperService_; userModel = _userModel_; userModel.userId = 'Allen'; sinon.stub(objectValueMapperService,'getExactValueByFieldName') .withArgs('field1').returns(-5) .withArgs('field2').returns('Hello') .withArgs('field3').returns(moment('2017-09-01T01:32:21.196Z')); sinon.stub(objectValueMapperService, 'getFieldPropertyValue') .withArgs('statusReason', 'isRequired').returns(true) .withArgs('statusReason', 'isReadOnly').returns(true) .withArgs('statusReason', 'isHidden').returns(true); })); it('should evaluate expressions with binary operators', function () { expect(expressionEvaluatorService.evaluate('1+2*3-6/2+5%3')).toBe(6); }); it('should return left operand if left operand is a string and right is null', function () { expect(expressionEvaluatorService.evaluate("'data'+null")).toBe('data'); }); it('should return right operand if right operand is a string and left is null', function () { expect(expressionEvaluatorService.evaluate('null+"data"')).toBe('data'); }); it('should return `null` if both left and right operands are null', function () { expect(expressionEvaluatorService.evaluate('null+null')).toBe(''); }); it('should evaluate expressions with unary operators', function () { expect(expressionEvaluatorService.evaluate('-5')).toBe(-5); expect(expressionEvaluatorService.evaluate('-5 == 0')).toBe(false); expect(expressionEvaluatorService.evaluate('-5 == -5')).toBe(true); expect(expressionEvaluatorService.evaluate('-5 < -(2+1)')).toBe(true); expect(expressionEvaluatorService.evaluate('$field1 == -5')).toBe(true); expect(expressionEvaluatorService.evaluate('$field2 == -5')).toBe(false); }); it('should evaluate expressions with relational operators', function () { expect(expressionEvaluatorService.evaluate('6 > 5')).toBe(true); expect(expressionEvaluatorService.evaluate('5 >= 5')).toBe(true); expect(expressionEvaluatorService.evaluate('-5 <= -5')).toBe(true); expect(expressionEvaluatorService.evaluate('-5 < -(2+1)')).toBe(true); expect(expressionEvaluatorService.evaluate('$field1 <= -5')).toBe(true); expect(expressionEvaluatorService.evaluate('$field2 >= -5')).toBe(false); }); it('should evaluate expressions with ternary operators', function () { expect(expressionEvaluatorService.evaluate('(1 == 1) ? true : false')).toBe(true); }); it('should evaluate expressions with parentheses', function () { expect(expressionEvaluatorService.evaluate('(1+3*2)+(4-2)*2')).toBe(11); }); it('should evaluate expressions with !=', function () { expect(expressionEvaluatorService.evaluate('$field1 != "jonnie" && $field2 != "demo"')).toBe(true); }); it('should evaluate empty expressions', function () { expect(expressionEvaluatorService.evaluate('')).toBe(null); expect(expressionEvaluatorService.evaluate(' ')).toBe(null); }); it('should evaluate expressions with NOT', function () { expect(expressionEvaluatorService.evaluate('! false')).toBe(true); expect(expressionEvaluatorService.evaluate('!(false)')).toBe(true); }); it('should evaluate expressions with &&', function () { expect(expressionEvaluatorService.evaluate('1 && 2')).toBe(true); expect(expressionEvaluatorService.evaluate('1 && 2')).toBe(true); expect(expressionEvaluatorService.evaluate('1 && 0')).toBe(false); expect(expressionEvaluatorService.evaluate('1 && false')).toBe(false); expect(expressionEvaluatorService.evaluate('false && 1')).toBe(false); expect(expressionEvaluatorService.evaluate('1 && "SomeText"')).toBe(true); expect(expressionEvaluatorService.evaluate('false && 1')).toBe(false); expect(expressionEvaluatorService.evaluate('true && true')).toBe(true); expect(expressionEvaluatorService.evaluate('true && false')).toBe(false); expect(expressionEvaluatorService.evaluate('false && true')).toBe(false); }); it('should evaluate expressions with OR', function () { expect(expressionEvaluatorService.evaluate('1 || 2')).toBe(true); expect(expressionEvaluatorService.evaluate('1 || 2')).toBe(true); expect(expressionEvaluatorService.evaluate('1 || 0')).toBe(true); expect(expressionEvaluatorService.evaluate('1 || false')).toBe(true); expect(expressionEvaluatorService.evaluate('false || 1')).toBe(true); expect(expressionEvaluatorService.evaluate('"SomeText" || 1')).toBe(true); expect(expressionEvaluatorService.evaluate('false || 1')).toBe(true); expect(expressionEvaluatorService.evaluate('true || true')).toBe(true); expect(expressionEvaluatorService.evaluate('true || false')).toBe(true); expect(expressionEvaluatorService.evaluate('false || true')).toBe(true); expect(expressionEvaluatorService.evaluate('0 || false')).toBe(false); }); it('should evaluate expressions with LIKE', function () { expect(expressionEvaluatorService.evaluate('"test" LIKE "t"')).toBe(true); expect(expressionEvaluatorService.evaluate('"test" LIKE "e"')).toBe(true); expect(expressionEvaluatorService.evaluate('"test" LIKE ""')).toBe(true); expect(expressionEvaluatorService.evaluate('"test" LIKE "test"')).toBe(true); expect(expressionEvaluatorService.evaluate('"test12" LIKE "test"')).toBe(true); expect(expressionEvaluatorService.evaluate('"test" LIKE "test12"')).toBe(true); expect(expressionEvaluatorService.evaluate('"test" LIKE "TEST"')).toBe(false); expect(expressionEvaluatorService.evaluate('"TEST" LIKE "test"')).toBe(false); expect(expressionEvaluatorService.evaluate('"" LIKE "test"')).toBe(true); }); it('should evaluate expressions with multiple boolean operators', function () { expect(expressionEvaluatorService.evaluate('1 && 2 && "Test"')).toBe(true); expect(expressionEvaluatorService.evaluate('1 && 2 && false')).toBe(false); expect(expressionEvaluatorService.evaluate('1 && false && 2')).toBe(false); expect(expressionEvaluatorService.evaluate('1 || false && 2')).toBe(true); expect(expressionEvaluatorService.evaluate('(true || false) && true')).toBe(true); }); it('should evaluate expressions with mixed operators', function () { expect(expressionEvaluatorService.evaluate('3*0 && true')).toBe(false); }); it('should evaluate expressions with variables', function () { expect(expressionEvaluatorService.evaluate('$field1')).toBe(-5); }); it('should throw error for invalid expressions', function () { expect(function () { expressionEvaluatorService.evaluate('a $ b $ c'); }).toThrow(); expect(function () { expressionEvaluatorService.evaluate('* a & b'); }).toThrow(); expect(function () { expect(expressionEvaluatorService.evaluate('TIME AND 213')).toBe(false); }).toThrow(); }); it('should evaluate $NULL$', function () { expect(expressionEvaluatorService.evaluate('$NULL$')).toBe(''); }); it('should evaluate $USER$', function () { expect(expressionEvaluatorService.evaluate('$USER$')).toBe('Allen'); }); it('should evaluate $NOW$', function () { var ts = expressionEvaluatorService.evaluate('$NOW$'); expect(ts).toEqual(jasmine.any(Number)); expect(moment(ts).diff(moment())).toBeLessThan(1000); //one second }); it('should evaluate $HOMEURL$', function () { var url = expressionEvaluatorService.evaluate('$HOMEURL$'); expect(url).toMatch('http(s?)://[A-Za-z0-9-+/~_:,.;]+'); }); it('should evaluate REPLACE()', function () { expect(expressionEvaluatorService.evaluate('REPLACE("Twas the night before Xmas...", "Xmas", "Christmas")')).toBe('Twas the night before Christmas...'); }); it('should evaluate REPLACE() with field reference', function () { var result = expressionEvaluatorService.evaluate('REPLACE("Hi World", "Hi", $field2)'); expect(result).toBe('Hello World'); }); xit('should evaluate DATEADD() adding days', function () { moment.locale('en'); var result = expressionEvaluatorService.evaluate('DATEADD("d", 10, 1505164006368)'); expect(result.unix()).toBe(1506028006); var result2 = expressionEvaluatorService.evaluate('DATEADD("days", -10, 1505164006368)'); expect(result2.unix()).toBe(1504300006); }); xit('should evaluate DATEADD() adding months', function () { moment.locale('en'); var result = expressionEvaluatorService.evaluate('DATEADD("M", 4, 1505164006368)'); expect(result.unix()).toBe(1515704806); var result2 = expressionEvaluatorService.evaluate('DATEADD("months", -1, 1505164006368)'); expect(result2.unix()).toBe(1502485606); }); xit('should evaluate DATEADD() adding years', function () { moment.locale('en'); var result = expressionEvaluatorService.evaluate('DATEADD("y", -2, 1505164006368)'); expect(result.unix()).toBe(1442005606); var result2 = expressionEvaluatorService.evaluate('DATEADD("years", 2, 1505164006368)'); expect(result2.unix()).toBe(1568236006); }); xit('should evaluate DATEADD() adding weeks', function () { moment.locale('en'); var result = expressionEvaluatorService.evaluate('DATEADD("w", 2, 1505164006368)'); expect(result.unix()).toBe(1506373606); var result2 = expressionEvaluatorService.evaluate('DATEADD("weeks", -3, 1505164006368)'); expect(result2.unix()).toBe(1503349606); }); /*it('should evaluate DATEADD() adding hours', function () { var result = expressionEvaluatorService.evaluate('DATEADD("h", 5, 1505164006368)'); expect(result.format('H:mm:ss')).toBe('19:06:46'); var result2 = expressionEvaluatorService.evaluate('DATEADD("hours", -2, 1505164006368)'); expect(result2.format('H:mm:ss')).toBe('12:06:46'); }); it('should evaluate DATEADD() adding minutes', function () { var result = expressionEvaluatorService.evaluate('DATEADD("m", 70, 1505164006368)'); expect(result.format('H:mm:ss')).toBe('15:16:46'); var result2 = expressionEvaluatorService.evaluate('DATEADD("minutes", -20, 1505164006368)'); expect(result2.format('H:mm:ss')).toBe('13:46:46'); }); it('should evaluate DATEADD() adding seconds', function () { var result = expressionEvaluatorService.evaluate('DATEADD("s", -50, 1505164006368)'); expect(result.format('H:mm:ss')).toBe('14:05:56'); var result2 = expressionEvaluatorService.evaluate('DATEADD("seconds", 20, 1505164006368)'); expect(result2.format('H:mm:ss')).toBe('14:07:06'); });*/ xit('should evaluate DATEADD() with field reference', function () { moment.locale('en'); var result = expressionEvaluatorService.evaluate('DATEADD("d", $field1, 1505164006368)'); expect(result.unix()).toBe(1504732006); }); it('should evaluate DATEDIFF() in days', function () { var result = expressionEvaluatorService.evaluate('DATEDIFF("d", "2017-09-01T01:32:21.196Z", "2017-08-01T01:32:21.196Z")'); expect(result).toBe(31); }); it('should evaluate DATEDIFF() in months', function () { var result = expressionEvaluatorService.evaluate('DATEDIFF("M", "2017-09-01T01:32:21.196Z", "2016-08-01T01:32:21.196Z")'); expect(result).toBe(13); }); it('should evaluate DATEDIFF() in years', function () { var result = expressionEvaluatorService.evaluate('DATEDIFF("years", "2017-09-01T01:32:21.196Z", "1996-08-01T01:32:21.196Z")'); expect(result).toBe(21); }); it('should evaluate DATEDIFF() in hours', function () { var result = expressionEvaluatorService.evaluate('DATEDIFF("hours", "2017-09-12T10:06:21.196Z", "2017-09-11T08:56:21.196Z")'); expect(result).toBe(25); }); it('should evaluate DATEDIFF() in minutes', function () { var result = expressionEvaluatorService.evaluate('DATEDIFF("MN", "2017-09-12T10:06:21.196Z", "2017-09-12T08:56:21.196Z")'); expect(result).toBe(70); }); it('should evaluate DATEDIFF() with field reference', function () { var result = expressionEvaluatorService.evaluate('DATEDIFF("mn", $field3, $field3)'); expect(result).toBe(0); }); it('should evaluate Call Expression ISREQUIRED() with field reference', function () { expect(expressionEvaluatorService.evaluate('ISREQUIRED($statusReason)')).toBe(true); }); it('should evaluate Call Expression ISREADONLY() with field reference', function () { expect(expressionEvaluatorService.evaluate('ISREADONLY($statusReason)')).toBe(true); }); it('should evaluate Call Expression ISHIDDEN() with field reference', function () { expect(expressionEvaluatorService.evaluate('ISHIDDEN($statusReason)')).toBe(true); }); it('should evaluate Call Expression ISHIDDEN() with field string reference ', function () { expect(expressionEvaluatorService.evaluate("ISHIDDEN('$statusReason')")).toBe(true); }); it('should evaluate Call Expression ONCHANGE() with field string reference ', function () { sinon.stub(objectValueMapperService, 'getProviderActionFieldName').returns('statusReason'); expect(expressionEvaluatorService.evaluate("ONCHANGE('$statusReason')")).toBe(true); }); it('should throw an error for invalid Call Expression ISHIDDEN() with field string reference ', function () { expect(function(){expressionEvaluatorService.evaluate("ISHIDDEN($statusReason == 'Future Enhancement')")}).toThrow(new Error('Cannot evaluate expression "ISHIDDEN($statusReason == \'Future Enhancement\')": Function ISHIDDEN has invalid arguments..')); }); });