From 51624794e6a34846eb9a5293702a8517dac2f230 Mon Sep 17 00:00:00 2001 From: Alexey Mulyukin Date: Thu, 20 Aug 2020 21:05:19 +0300 Subject: [PATCH] #545: Add tests for Tokenizer.ts to cover new cases --- src/Tokenizer.spec.ts | 165 ++++++++++++++++++++++++++++++++++++++++++ src/Tokenizer.ts | 2 +- 2 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/Tokenizer.spec.ts b/src/Tokenizer.spec.ts index 6fa92e097..706420d6d 100644 --- a/src/Tokenizer.spec.ts +++ b/src/Tokenizer.spec.ts @@ -164,4 +164,169 @@ describe('Tokenizer', () => { tokenizer.reset(); logger.log = []; }); + + test('should support attributes', () => { + const logger = new CallbackLogger(); + const tokenizer = new Tokenizer({ + xmlMode: false, + decodeEntities: false + }, logger); + + const input = '
'; + const expectedOutput = [ + "onopentagname: 'div'", + "onattribname: 'width'", + "onattribdata: '100'", + 'onattribend', + 'onopentagend', + "onclosetag: 'div'", + 'onend' + ]; + + tokenizer.write(input); + tokenizer.end(); + expect(logger.log).toEqual(expectedOutput); + }); + + test('should support double quoted attributes', () => { + const logger = new CallbackLogger(); + const tokenizer = new Tokenizer({ + xmlMode: false, + decodeEntities: false + }, logger); + + const input = '
'; + const expectedOutput = [ + "onopentagname: 'div'", + "onattribname: 'title'", + "onattribdata: 'title attribute text'", + 'onattribend', + 'onopentagend', + "onclosetag: 'div'", + 'onend' + ]; + + tokenizer.write(input); + tokenizer.end(); + expect(logger.log).toEqual(expectedOutput); + }); + + test('should support single quoted attributes', () => { + const logger = new CallbackLogger(); + const tokenizer = new Tokenizer({ + xmlMode: false, + decodeEntities: false + }, logger); + + const input = '
'; + const expectedOutput = [ + "onopentagname: 'div'", + "onattribname: 'title'", + "onattribdata: 'title attribute text'", + 'onattribend', + 'onopentagend', + "onclosetag: 'div'", + 'onend' + ]; + + tokenizer.write(input); + tokenizer.end(); + expect(logger.log).toEqual(expectedOutput); + }); + + test('should support curly braced attributes', () => { + const logger = new CallbackLogger(); + const tokenizer = new Tokenizer({ + xmlMode: false, + decodeEntities: false, + curlyBracesInAttributes: true + }, logger); + + const input = '
handleClick()}>
'; + const expectedOutput = [ + "onopentagname: 'div'", + "onattribname: 'on:click'", + "onattribdata: '() => handleClick()'", + 'onattribend', + 'onopentagend', + "onclosetag: 'div'", + 'onend' + ]; + + tokenizer.write(input); + tokenizer.end(); + expect(logger.log).toEqual(expectedOutput); + }); + + test('should support curly braced attributes with escaping in JS strings', () => { + const logger = new CallbackLogger(); + const tokenizer = new Tokenizer({ + xmlMode: false, + decodeEntities: false, + curlyBracesInAttributes: true + }, logger); + + const input = '
console.log(\'}\' + "}" + `}`)}>
'; + const expectedOutput = [ + "onopentagname: 'div'", + "onattribname: 'on:click'", + "onattribdata: '() => console.log(\'}\' + \"}\" + `}`)'", + 'onattribend', + 'onopentagend', + "onclosetag: 'div'", + 'onend' + ]; + + tokenizer.write(input); + tokenizer.end(); + expect(logger.log).toEqual(expectedOutput); + }); + + test('should support curly braced attributes with escaping by inline JS comments', () => { + const logger = new CallbackLogger(); + const tokenizer = new Tokenizer({ + xmlMode: false, + decodeEntities: false, + curlyBracesInAttributes: true + }, logger); + + const input = '
console.log("c") /* } */}>
'; + const expectedOutput = [ + "onopentagname: 'div'", + "onattribname: 'on:click'", + "onattribdata: '() => console.log(\"c\") /* } */'", + 'onattribend', + 'onopentagend', + "onclosetag: 'div'", + 'onend' + ]; + + tokenizer.write(input); + tokenizer.end(); + expect(logger.log).toEqual(expectedOutput); + }); + + test('should support curly braced attributes with nesting scopes', () => { + const logger = new CallbackLogger(); + const tokenizer = new Tokenizer({ + xmlMode: false, + decodeEntities: false, + curlyBracesInAttributes: true + }, logger); + + const input = '
'; + const expectedOutput = [ + "onopentagname: 'div'", + "onattribname: 'on:click'", + "onattribdata: '{ width: 100, height: 200 }'", + 'onattribend', + 'onopentagend', + "onclosetag: 'div'", + 'onend' + ]; + + tokenizer.write(input); + tokenizer.end(); + expect(logger.log).toEqual(expectedOutput); + }); }); \ No newline at end of file diff --git a/src/Tokenizer.ts b/src/Tokenizer.ts index 98de9ac64..e6c8e8ede 100644 --- a/src/Tokenizer.ts +++ b/src/Tokenizer.ts @@ -252,7 +252,7 @@ export default class Tokenizer { _decodeEntities: boolean; constructor( - options: { xmlMode?: boolean; decodeEntities?: boolean } | null, + options: { xmlMode?: boolean; decodeEntities?: boolean, curlyBracesInAttributes?: boolean } | null, cbs: Callbacks ) { this._cbs = cbs;