UNPKG

@pru-rt/spel2js

Version:

Parse Spring Expression Language in JavaScript

260 lines (218 loc) 8.7 kB
import {Tokenizer} from '../../src/Tokenizer'; import {TokenKind} from '../../src/TokenKind'; describe('tokenizer', ()=>{ let tokenize = Tokenizer.tokenize; beforeEach(()=>{ // add spies }); it('should return an array of one Int token', ()=>{ //when let tokens = tokenize('123'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(1); expect(tokens[0].getKind()).toBe(TokenKind.LITERAL_INT); expect(tokens[0].stringValue()).toBe('123'); }); it('should return an array of one long token', ()=>{ //when let tokens = tokenize('123l'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(1); expect(tokens[0].getKind()).toBe(TokenKind.LITERAL_LONG); expect(tokens[0].stringValue()).toBe('123'); }); it('should return an array of one hex int token', ()=>{ //when let tokens = tokenize('0xFF'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(1); expect(tokens[0].getKind()).toBe(TokenKind.LITERAL_HEXINT); expect(tokens[0].stringValue()).toBe('FF'); }); it('should return an array of one hex long token', ()=>{ //when let tokens = tokenize('0xFFl'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(1); expect(tokens[0].getKind()).toBe(TokenKind.LITERAL_HEXLONG); expect(tokens[0].stringValue()).toBe('FF'); }); it('should return an array of one string token', ()=>{ //when let tokens = tokenize('\'hello world!\''); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(1); expect(tokens[0].getKind()).toBe(TokenKind.LITERAL_STRING); expect(tokens[0].stringValue()).toBe('\'hello world!\''); }); it('should return an array of one real token', ()=>{ //when let tokens = tokenize('123.4'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(1); expect(tokens[0].getKind()).toBe(TokenKind.LITERAL_REAL); expect(tokens[0].stringValue()).toBe('123.4'); }); it('should return an array of one real float token', ()=>{ //when let tokens = tokenize('123.4f'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(1); expect(tokens[0].getKind()).toBe(TokenKind.LITERAL_REAL_FLOAT); expect(tokens[0].stringValue()).toBe('123.4f'); }); //more complex expressions it('should return an array of 4 tokens when given a function with 1 arg', ()=>{ //when let tokens = tokenize('hasPermission(\'DISCUSSION_POST\')'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(4); expect(tokens[0].getKind()).toBe(TokenKind.IDENTIFIER); expect(tokens[1].getKind()).toBe(TokenKind.LPAREN); expect(tokens[2].getKind()).toBe(TokenKind.LITERAL_STRING); expect(tokens[3].getKind()).toBe(TokenKind.RPAREN); }); it('should return an array of 11 tokens when given comparison of principal to arg property', ()=>{ //when let tokens = tokenize('principal.email == #comment.user[\'email\']'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(11); expect(tokens[0].getKind()).toBe(TokenKind.IDENTIFIER); expect(tokens[1].getKind()).toBe(TokenKind.DOT); expect(tokens[2].getKind()).toBe(TokenKind.IDENTIFIER); expect(tokens[3].getKind()).toBe(TokenKind.EQ); expect(tokens[4].getKind()).toBe(TokenKind.HASH); expect(tokens[5].getKind()).toBe(TokenKind.IDENTIFIER); expect(tokens[6].getKind()).toBe(TokenKind.DOT); expect(tokens[7].getKind()).toBe(TokenKind.IDENTIFIER); expect(tokens[8].getKind()).toBe(TokenKind.LSQUARE); expect(tokens[9].getKind()).toBe(TokenKind.LITERAL_STRING); expect(tokens[10].getKind()).toBe(TokenKind.RSQUARE); }); it('should tokenize unary operators', ()=>{ //when let tokens = tokenize('+ - * / ^ % ++ -- ! ='); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(10); expect(tokens[0].getKind()).toBe(TokenKind.PLUS); expect(tokens[1].getKind()).toBe(TokenKind.MINUS); expect(tokens[2].getKind()).toBe(TokenKind.STAR); expect(tokens[3].getKind()).toBe(TokenKind.DIV); expect(tokens[4].getKind()).toBe(TokenKind.POWER); expect(tokens[5].getKind()).toBe(TokenKind.MOD); expect(tokens[6].getKind()).toBe(TokenKind.INC); expect(tokens[7].getKind()).toBe(TokenKind.DEC); expect(tokens[8].getKind()).toBe(TokenKind.NOT); expect(tokens[9].getKind()).toBe(TokenKind.ASSIGN); }); it('should tokenize comparison operators', ()=>{ //when let tokens = tokenize('>= > <= < == != && ||'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(8); expect(tokens[0].getKind()).toBe(TokenKind.GE); expect(tokens[1].getKind()).toBe(TokenKind.GT); expect(tokens[2].getKind()).toBe(TokenKind.LE); expect(tokens[3].getKind()).toBe(TokenKind.LT); expect(tokens[4].getKind()).toBe(TokenKind.EQ); expect(tokens[5].getKind()).toBe(TokenKind.NE); expect(tokens[6].getKind()).toBe(TokenKind.SYMBOLIC_AND); expect(tokens[7].getKind()).toBe(TokenKind.SYMBOLIC_OR); }); //this test fails. The tokenizer from Spring does not support these /*it('should tokenize keywords', ()=>{ //when let tokens = tokenize('instanceOf matches between'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(3); expect(tokens[0].getKind()).toBe(TokenKind.INSTANCEOF); expect(tokens[1].getKind()).toBe(TokenKind.MATCHES); expect(tokens[2].getKind()).toBe(TokenKind.BETWEEN); });*/ it('should tokenize regex tokens', ()=>{ //when let tokens = tokenize('^[ $[ ? ![ ?['); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(5); expect(tokens[0].getKind()).toBe(TokenKind.SELECT_FIRST); expect(tokens[1].getKind()).toBe(TokenKind.SELECT_LAST); expect(tokens[2].getKind()).toBe(TokenKind.QMARK); expect(tokens[3].getKind()).toBe(TokenKind.PROJECT); expect(tokens[4].getKind()).toBe(TokenKind.SELECT); }); it('should tokenize miscellaneous tokens', ()=>{ //when let tokens = tokenize(', : { } ?: ?. @'); //then expect(tokens).toBeDefined(); expect(tokens.length).toBe(7); expect(tokens[0].getKind()).toBe(TokenKind.COMMA); expect(tokens[1].getKind()).toBe(TokenKind.COLON); expect(tokens[2].getKind()).toBe(TokenKind.LCURLY); expect(tokens[3].getKind()).toBe(TokenKind.RCURLY); expect(tokens[4].getKind()).toBe(TokenKind.ELVIS); expect(tokens[5].getKind()).toBe(TokenKind.SAFE_NAVI); expect(tokens[6].getKind()).toBe(TokenKind.BEAN_REF); }); it('should throw exception if using bitwise operators', ()=>{ //given let shouldThrow1 = ()=>{ tokenize('|'); }; let shouldThrow2 = ()=>{ tokenize('&'); }; //then expect(shouldThrow1).toThrow(); expect(shouldThrow2).toThrow(); }); it('should throw exception if escape character is used', ()=>{ //given let shouldThrow = ()=>{ tokenize('\\hello'); }; //then expect(shouldThrow).toThrow(); }); it('should throw exception if unsupported character is used', ()=>{ //given let shouldThrow = ()=>{ tokenize('¶'); }; //then expect(shouldThrow).toThrow(); }); it('should throw exception if string literal is unterminated', ()=>{ //given let shouldThrowSingleQuote = ()=>{ tokenize('\'this is an unterminated stateme'); }; let shouldThrowDoubleQuote = ()=>{ tokenize('"this is an unterminated stateme'); }; //then expect(shouldThrowSingleQuote).toThrow(); expect(shouldThrowDoubleQuote).toThrow(); }); it('should throw exception if long identifier used on real', ()=>{ //given let shouldThrow = ()=>{ tokenize('3.4L'); }; //then expect(shouldThrow).toThrow(); }); });