mirror of
https://github.com/tenrok/BBob.git
synced 2026-06-17 19:21:20 +03:00
add Tokenizer tests
This commit is contained in:
@@ -1,44 +1,19 @@
|
|||||||
|
const {
|
||||||
|
convertTokenToText,
|
||||||
|
getTagName,
|
||||||
|
getTokenColumn,
|
||||||
|
getTokenLine,
|
||||||
|
getTokenValue,
|
||||||
|
isAttrNameToken,
|
||||||
|
isAttrValueToken,
|
||||||
|
isTagStart,
|
||||||
|
isTagToken,
|
||||||
|
isTextToken,
|
||||||
|
isTagEnd
|
||||||
|
} = require("./Tokenizer");
|
||||||
const Tokenizer = require("./Tokenizer");
|
const Tokenizer = require("./Tokenizer");
|
||||||
const TokenType = Tokenizer.TYPE;
|
|
||||||
const TokenChar = Tokenizer.CHAR;
|
const TokenChar = Tokenizer.CHAR;
|
||||||
const getCharCode = Tokenizer.getCharCode;
|
const getChar = Tokenizer.getChar;
|
||||||
|
|
||||||
const isTextToken = (token) => {
|
|
||||||
const type = token[Tokenizer.TOKEN.TYPE_ID];
|
|
||||||
|
|
||||||
return type === TokenType.SPACE || type === TokenType.NEW_LINE || type === TokenType.WORD
|
|
||||||
};
|
|
||||||
|
|
||||||
const isTagToken = (token) => token[Tokenizer.TOKEN.TYPE_ID] === TokenType.TAG;
|
|
||||||
|
|
||||||
const isTagStart = (token) => !isTagEnd(token);
|
|
||||||
|
|
||||||
const isTagEnd = (token) => getTokenValue(token).charCodeAt(0) === TokenChar.SLASH;
|
|
||||||
|
|
||||||
const isAttrNameToken = (token) => token[Tokenizer.TOKEN.TYPE_ID] === TokenType.ATTR_NAME;
|
|
||||||
|
|
||||||
const isAttrValueToken = (token) => token[Tokenizer.TOKEN.TYPE_ID] === TokenType.ATTR_VALUE;
|
|
||||||
|
|
||||||
const getTagName = (token) => {
|
|
||||||
const value = getTokenValue(token);
|
|
||||||
|
|
||||||
return isTagEnd(token) ? value.slice(1) : value
|
|
||||||
};
|
|
||||||
|
|
||||||
const convertTagToText = (token) => {
|
|
||||||
let text = getCharCode(TokenChar.OPEN_BRAKET);
|
|
||||||
|
|
||||||
if (isTagEnd(token)) {
|
|
||||||
text += getCharCode(TokenChar.SLASH)
|
|
||||||
}
|
|
||||||
|
|
||||||
text += getTokenValue(token);
|
|
||||||
text += getCharCode(TokenChar.CLOSE_BRAKET);
|
|
||||||
|
|
||||||
return text
|
|
||||||
};
|
|
||||||
|
|
||||||
const getTokenValue = (token) => token[Tokenizer.TOKEN.VALUE_ID];
|
|
||||||
|
|
||||||
const createTagNode = (name, attrs = {}, content = []) => ({tag: name, attrs, content});
|
const createTagNode = (name, attrs = {}, content = []) => ({tag: name, attrs, content});
|
||||||
|
|
||||||
@@ -65,6 +40,10 @@ module.exports = class Parser {
|
|||||||
const curTags = [];
|
const curTags = [];
|
||||||
const curTagsAttrName = [];
|
const curTagsAttrName = [];
|
||||||
|
|
||||||
|
const closableTags = this.findNestedTags(tokens);
|
||||||
|
|
||||||
|
const isNestedTag = (token) => closableTags.indexOf(getTokenValue(token)) >= 0;
|
||||||
|
|
||||||
const getCurTag = () => {
|
const getCurTag = () => {
|
||||||
if (curTags.length) {
|
if (curTags.length) {
|
||||||
return curTags[curTags.length - 1]
|
return curTags[curTags.length - 1]
|
||||||
@@ -124,7 +103,7 @@ module.exports = class Parser {
|
|||||||
if (isTagStart(token)) {
|
if (isTagStart(token)) {
|
||||||
createCurTag(token);
|
createCurTag(token);
|
||||||
|
|
||||||
if (this.isCloseTag(getTokenValue(token))) {
|
if (isNestedTag(token)) {
|
||||||
nestedNodes.push(getCurTag())
|
nestedNodes.push(getCurTag())
|
||||||
} else {
|
} else {
|
||||||
getNodes().push(getCurTag());
|
getNodes().push(getCurTag());
|
||||||
@@ -141,12 +120,11 @@ module.exports = class Parser {
|
|||||||
if (lastNestedNode) {
|
if (lastNestedNode) {
|
||||||
getNodes().push(lastNestedNode)
|
getNodes().push(lastNestedNode)
|
||||||
} else {
|
} else {
|
||||||
debugger;
|
console.warn(`Inconsistent tag '${getTokenValue(token)}' on line ${getTokenLine(token)} and column ${getTokenColumn(token)}`);
|
||||||
console.warn(`Inconsistent tag '${getTokenValue(token)}'`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getNodes().push(convertTagToText(token))
|
getNodes().push(convertTokenToText(token))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,8 +146,22 @@ module.exports = class Parser {
|
|||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
isCloseTag(value) {
|
findNestedTags(tokens) {
|
||||||
return this.options.closableTags && this.options.closableTags.indexOf(value) >= 0
|
const tags = tokens.filter(isTagToken).reduce((acc, token) => {
|
||||||
|
acc[getTokenValue(token)] = true;
|
||||||
|
|
||||||
|
return acc
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const closeChar = getChar(TokenChar.SLASH);
|
||||||
|
|
||||||
|
return Object.keys(tags).reduce((arr, key) => {
|
||||||
|
if (tags[key] && tags[closeChar + key]) {
|
||||||
|
arr.push(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
isAllowedTag(value) {
|
isAllowedTag(value) {
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# bbob-parser
|
||||||
|
Fast BB Code parser written in pure javascript, no dependencies
|
||||||
@@ -1,19 +1,50 @@
|
|||||||
const CHAR = require('./char');
|
const CHAR = require('./char');
|
||||||
const TOKEN = require('./token');
|
const TOKEN = require('./token');
|
||||||
|
const getChar = String.fromCharCode;
|
||||||
|
|
||||||
// const TOKEN.TYPE_ID = 0;
|
|
||||||
// const TOKEN.VALUE_ID = 1;
|
|
||||||
// const TOKEN.LINE_ID = 2;
|
|
||||||
// const TOKEN.COLUMN_ID = 3;
|
|
||||||
//
|
|
||||||
// const TOKEN.TYPE_WORD = 'word';
|
|
||||||
// const TOKEN.TYPE_TAG = 'tag';
|
|
||||||
// const TOKEN.TYPE_ATTR_NAME = 'attr-name';
|
|
||||||
// const TOKEN.TYPE_ATTR_VALUE = 'attr-value';
|
|
||||||
// const TOKEN.TYPE_SPACE = 'space';
|
|
||||||
// const TOKEN.TYPE_NEW_LINE = 'new-line';
|
|
||||||
|
|
||||||
const getCharCode = String.fromCharCode;
|
const getTokenValue = (token) => token[Tokenizer.TOKEN.VALUE_ID];
|
||||||
|
|
||||||
|
const getTokenLine = (token) => token[Tokenizer.TOKEN.LINE_ID];
|
||||||
|
const getTokenColumn = (token) => token[Tokenizer.TOKEN.COLUMN_ID];
|
||||||
|
|
||||||
|
const isTextToken = (token) => {
|
||||||
|
const type = token[Tokenizer.TOKEN.TYPE_ID];
|
||||||
|
|
||||||
|
return type === TOKEN.TYPE_SPACE || type === TOKEN.TYPE_NEW_LINE || type === TOKEN.TYPE_WORD
|
||||||
|
};
|
||||||
|
|
||||||
|
const isTagToken = (token) => token[Tokenizer.TOKEN.TYPE_ID] === TOKEN.TYPE_TAG;
|
||||||
|
|
||||||
|
const isTagStart = (token) => !isTagEnd(token);
|
||||||
|
|
||||||
|
const isTagEnd = (token) => getTokenValue(token).charCodeAt(0) === CHAR.SLASH;
|
||||||
|
|
||||||
|
const isAttrNameToken = (token) => token[Tokenizer.TOKEN.TYPE_ID] === TOKEN.TYPE_ATTR_NAME;
|
||||||
|
|
||||||
|
const isAttrValueToken = (token) => token[Tokenizer.TOKEN.TYPE_ID] === TOKEN.TYPE_ATTR_VALUE;
|
||||||
|
|
||||||
|
const getTagName = (token) => {
|
||||||
|
const value = getTokenValue(token);
|
||||||
|
|
||||||
|
return isTagEnd(token) ? value.slice(1) : value
|
||||||
|
};
|
||||||
|
|
||||||
|
const convertTagToText = (token) => {
|
||||||
|
let text = getChar(CHAR.OPEN_BRAKET);
|
||||||
|
|
||||||
|
if (isTagEnd(token)) {
|
||||||
|
text += getChar(CHAR.SLASH)
|
||||||
|
}
|
||||||
|
|
||||||
|
text += getTokenValue(token);
|
||||||
|
text += getChar(CHAR.CLOSE_BRAKET);
|
||||||
|
|
||||||
|
return text
|
||||||
|
};
|
||||||
|
|
||||||
|
const SPACE_TAB = ' ';
|
||||||
|
const SPACE = ' ';
|
||||||
|
|
||||||
class Tokenizer {
|
class Tokenizer {
|
||||||
constructor(input) {
|
constructor(input) {
|
||||||
@@ -24,7 +55,7 @@ class Tokenizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tokenize() {
|
tokenize() {
|
||||||
let wordToken = this.createWordToken('');
|
let wordToken = null;
|
||||||
let tagToken = null;
|
let tagToken = null;
|
||||||
let attrNameToken = null;
|
let attrNameToken = null;
|
||||||
let attrValueToken = null;
|
let attrValueToken = null;
|
||||||
@@ -33,7 +64,7 @@ class Tokenizer {
|
|||||||
let tokenIndex = -1;
|
let tokenIndex = -1;
|
||||||
|
|
||||||
const flushWord = () => {
|
const flushWord = () => {
|
||||||
if (wordToken[TOKEN.VALUE_ID]) {
|
if (wordToken && wordToken[TOKEN.VALUE_ID]) {
|
||||||
tokenIndex++;
|
tokenIndex++;
|
||||||
tokens[tokenIndex] = wordToken;
|
tokens[tokenIndex] = wordToken;
|
||||||
wordToken = this.createWordToken('')
|
wordToken = this.createWordToken('')
|
||||||
@@ -42,20 +73,23 @@ class Tokenizer {
|
|||||||
|
|
||||||
const flushTag = () => {
|
const flushTag = () => {
|
||||||
if (tagToken !== null) {
|
if (tagToken !== null) {
|
||||||
|
if (attrNameToken && !attrValueToken) {
|
||||||
|
tagToken[TOKEN.VALUE_ID] += SPACE + attrNameToken[TOKEN.VALUE_ID]
|
||||||
|
attrNameToken = null
|
||||||
|
}
|
||||||
|
|
||||||
tokenIndex++;
|
tokenIndex++;
|
||||||
tokens[tokenIndex] = tagToken;
|
tokens[tokenIndex] = tagToken;
|
||||||
tagToken = null;
|
tagToken = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const flushAttrName = () => {
|
const flushAttrNames = () => {
|
||||||
if (attrNameToken) {
|
if (attrNameToken) {
|
||||||
attrTokens.push(attrNameToken);
|
attrTokens.push(attrNameToken);
|
||||||
attrNameToken = null;
|
attrNameToken = null;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const flushAttrValue = () => {
|
|
||||||
if (attrValueToken) {
|
if (attrValueToken) {
|
||||||
attrTokens.push(attrValueToken);
|
attrTokens.push(attrValueToken);
|
||||||
attrValueToken = null
|
attrValueToken = null
|
||||||
@@ -85,20 +119,19 @@ class Tokenizer {
|
|||||||
|
|
||||||
if (tagToken) {
|
if (tagToken) {
|
||||||
attrNameToken = this.createAttrNameToken('');
|
attrNameToken = this.createAttrNameToken('');
|
||||||
|
} else {
|
||||||
|
const spaceCode = charCode === CHAR.TAB ? SPACE_TAB : SPACE;
|
||||||
|
|
||||||
|
tokenIndex++;
|
||||||
|
tokens[tokenIndex] = this.createSpaceToken(spaceCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const spaceCode = charCode === CHAR.TAB ? ' ' : ' ';
|
|
||||||
|
|
||||||
tokenIndex++;
|
|
||||||
tokens[tokenIndex] = this.createSpaceToken(spaceCode);
|
|
||||||
|
|
||||||
this.colPos++;
|
this.colPos++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHAR.N:
|
case CHAR.N:
|
||||||
flushWord();
|
flushWord();
|
||||||
tokenIndex++;
|
tokenIndex++;
|
||||||
tokens[tokenIndex] = this.createNewLineToken(getCharCode(charCode));
|
tokens[tokenIndex] = this.createNewLineToken(getChar(charCode));
|
||||||
|
|
||||||
this.rowPos++;
|
this.rowPos++;
|
||||||
this.colPos = 0;
|
this.colPos = 0;
|
||||||
@@ -113,8 +146,7 @@ class Tokenizer {
|
|||||||
|
|
||||||
case CHAR.CLOSE_BRAKET:
|
case CHAR.CLOSE_BRAKET:
|
||||||
flushTag();
|
flushTag();
|
||||||
flushAttrName();
|
flushAttrNames();
|
||||||
flushAttrValue();
|
|
||||||
flushAttrs();
|
flushAttrs();
|
||||||
|
|
||||||
this.colPos++;
|
this.colPos++;
|
||||||
@@ -124,7 +156,7 @@ class Tokenizer {
|
|||||||
if (tagToken) {
|
if (tagToken) {
|
||||||
attrValueToken = this.createAttrValueToken('')
|
attrValueToken = this.createAttrValueToken('')
|
||||||
} else {
|
} else {
|
||||||
wordToken[TOKEN.VALUE_ID] += getCharCode(charCode);
|
wordToken[TOKEN.VALUE_ID] += getChar(charCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.colPos++;
|
this.colPos++;
|
||||||
@@ -132,10 +164,9 @@ class Tokenizer {
|
|||||||
|
|
||||||
case CHAR.QUOTEMARK:
|
case CHAR.QUOTEMARK:
|
||||||
if (attrValueToken && attrValueToken[TOKEN.VALUE_ID] > 0) {
|
if (attrValueToken && attrValueToken[TOKEN.VALUE_ID] > 0) {
|
||||||
flushAttrName();
|
flushAttrNames();
|
||||||
flushAttrValue();
|
|
||||||
} else if (tagToken === null) {
|
} else if (tagToken === null) {
|
||||||
wordToken[TOKEN.VALUE_ID] += getCharCode(charCode);
|
wordToken[TOKEN.VALUE_ID] += getChar(charCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.colPos++;
|
this.colPos++;
|
||||||
@@ -143,13 +174,17 @@ class Tokenizer {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (tagToken && attrValueToken) {
|
if (tagToken && attrValueToken) {
|
||||||
attrValueToken[TOKEN.VALUE_ID] += getCharCode(charCode)
|
attrValueToken[TOKEN.VALUE_ID] += getChar(charCode)
|
||||||
} else if (tagToken && attrNameToken) {
|
} else if (tagToken && attrNameToken) {
|
||||||
attrNameToken[TOKEN.VALUE_ID] += getCharCode(charCode)
|
attrNameToken[TOKEN.VALUE_ID] += getChar(charCode)
|
||||||
} else if (tagToken) {
|
} else if (tagToken) {
|
||||||
tagToken[TOKEN.VALUE_ID] += getCharCode(charCode)
|
tagToken[TOKEN.VALUE_ID] += getChar(charCode)
|
||||||
} else {
|
} else {
|
||||||
wordToken[TOKEN.VALUE_ID] += getCharCode(charCode);
|
if (!wordToken) {
|
||||||
|
wordToken = this.createWordToken('')
|
||||||
|
}
|
||||||
|
|
||||||
|
wordToken[TOKEN.VALUE_ID] += getChar(charCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.colPos++;
|
this.colPos++;
|
||||||
@@ -161,7 +196,7 @@ class Tokenizer {
|
|||||||
|
|
||||||
flushWord();
|
flushWord();
|
||||||
|
|
||||||
tokens.length = tokenIndex;
|
tokens.length = tokenIndex + 1;
|
||||||
|
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
@@ -210,5 +245,16 @@ module.exports.TOKEN = {
|
|||||||
LINE_ID: TOKEN.LINE_ID,
|
LINE_ID: TOKEN.LINE_ID,
|
||||||
COLUMN_ID: TOKEN.COLUMN_ID,
|
COLUMN_ID: TOKEN.COLUMN_ID,
|
||||||
};
|
};
|
||||||
module.exports.getCharCode = getCharCode;
|
module.exports.getChar = getChar;
|
||||||
|
module.exports.getTokenValue = getTokenValue;
|
||||||
|
module.exports.getTokenLine = getTokenLine;
|
||||||
|
module.exports.getTokenColumn = getTokenColumn;
|
||||||
|
module.exports.isTextToken = isTextToken;
|
||||||
|
module.exports.isTagToken = isTagToken;
|
||||||
|
module.exports.isTagStart = isTagStart;
|
||||||
|
module.exports.isTagEnd = isTagEnd;
|
||||||
|
module.exports.isAttrNameToken = isAttrNameToken;
|
||||||
|
module.exports.isAttrValueToken = isAttrValueToken;
|
||||||
|
module.exports.getTagName = getTagName;
|
||||||
|
module.exports.convertTokenToText = convertTagToText;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,95 @@
|
|||||||
const Tokenizer = require('./Tokenizer');
|
const Tokenizer = require('./Tokenizer');
|
||||||
|
const TYPE = Tokenizer.TYPE;
|
||||||
|
|
||||||
describe("Tokenizer", () => {
|
describe("Tokenizer", () => {
|
||||||
it("tokenize single tag", () => {
|
test("tokenize single tag", () => {
|
||||||
const input = `[SingleTag]`;
|
const input = `[SingleTag]`;
|
||||||
|
const tokens = new Tokenizer(input).tokenize();
|
||||||
|
|
||||||
|
expect(tokens).toBeInstanceOf(Array);
|
||||||
|
expect(tokens).toEqual([
|
||||||
|
[TYPE.TAG, 'SingleTag', 0, 0]
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
|
test("tokenize single tag with spaces", () => {
|
||||||
|
const input = `[Single Tag]`;
|
||||||
|
const tokens = new Tokenizer(input).tokenize();
|
||||||
|
|
||||||
|
expect(tokens).toBeInstanceOf(Array);
|
||||||
|
expect(tokens).toEqual([
|
||||||
|
[TYPE.TAG, 'Single Tag', 0, 0]
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
|
test("tokenize tag as param", () => {
|
||||||
|
const input = `[color="#ff0000"]Text[/color]`;
|
||||||
|
const tokens = new Tokenizer(input).tokenize();
|
||||||
|
|
||||||
|
expect(tokens).toBeInstanceOf(Array);
|
||||||
|
expect(tokens).toEqual([
|
||||||
|
[TYPE.TAG, 'color', 0, 0],
|
||||||
|
[TYPE.ATTR_VALUE, '#ff0000', 6, 0],
|
||||||
|
[TYPE.WORD, 'Text', 17, 0],
|
||||||
|
[TYPE.TAG, '/color', 21, 0]
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
|
test("tokenize tag param without quotemarks", () => {
|
||||||
|
const input = `[style color=#ff0000]Text[/style]`;
|
||||||
|
const tokens = new Tokenizer(input).tokenize();
|
||||||
|
|
||||||
|
expect(tokens).toBeInstanceOf(Array);
|
||||||
|
expect(tokens).toEqual([
|
||||||
|
[TYPE.TAG, 'style', 0, 0],
|
||||||
|
[TYPE.ATTR_NAME, 'color', 6, 0],
|
||||||
|
[TYPE.ATTR_VALUE, '#ff0000', 12, 0],
|
||||||
|
[TYPE.WORD, 'Text', 21, 0],
|
||||||
|
[TYPE.TAG, '/style', 25, 0]
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
|
test("tokenize list tag with items", () => {
|
||||||
|
const input = `[list]
|
||||||
|
[*] Item 1.
|
||||||
|
[*] Item 2.
|
||||||
|
[*] Item 3.
|
||||||
|
[/list]`;
|
||||||
|
|
||||||
const tokens = new Tokenizer(input).tokenize();
|
const tokens = new Tokenizer(input).tokenize();
|
||||||
|
|
||||||
console.log('tokens', tokens);
|
|
||||||
|
|
||||||
expect(tokens).toBeInstanceOf(Array);
|
expect(tokens).toBeInstanceOf(Array);
|
||||||
expect(tokens[0]).toEqual(['tag', 'SingleTag', 0, 0])
|
expect(tokens).toEqual([
|
||||||
|
[TYPE.TAG, 'list', 0, 0],
|
||||||
|
[TYPE.NEW_LINE, '\n', 6, 0],
|
||||||
|
[TYPE.SPACE, ' ', 0, 1],
|
||||||
|
[TYPE.SPACE, ' ', 1, 1],
|
||||||
|
[TYPE.SPACE, ' ', 2, 1],
|
||||||
|
[TYPE.TAG, '*', 3, 1],
|
||||||
|
[TYPE.SPACE, ' ', 6, 1],
|
||||||
|
[TYPE.WORD, 'Item', 7, 1],
|
||||||
|
[TYPE.SPACE, ' ', 11, 1],
|
||||||
|
[TYPE.WORD, '1.', 11, 1],
|
||||||
|
[TYPE.NEW_LINE, '\n', 14, 1],
|
||||||
|
[TYPE.SPACE, ' ', 0, 2],
|
||||||
|
[TYPE.SPACE, ' ', 1, 2],
|
||||||
|
[TYPE.SPACE, ' ', 2, 2],
|
||||||
|
[TYPE.TAG, '*', 3, 2],
|
||||||
|
[TYPE.SPACE, ' ', 6, 2],
|
||||||
|
[TYPE.WORD, 'Item', 14, 1],
|
||||||
|
[TYPE.SPACE, ' ', 11, 2],
|
||||||
|
[TYPE.WORD, '2.', 11, 2],
|
||||||
|
[TYPE.NEW_LINE, '\n', 14, 2],
|
||||||
|
[TYPE.SPACE, ' ', 0, 3],
|
||||||
|
[TYPE.SPACE, ' ', 1, 3],
|
||||||
|
[TYPE.SPACE, ' ', 2, 3],
|
||||||
|
[TYPE.TAG, '*', 3, 3],
|
||||||
|
[TYPE.SPACE, ' ', 6, 3],
|
||||||
|
[TYPE.WORD, 'Item', 14, 2],
|
||||||
|
[TYPE.SPACE, ' ', 11, 3],
|
||||||
|
[TYPE.WORD, '3.', 11, 3],
|
||||||
|
[TYPE.NEW_LINE, '\n', 14, 3],
|
||||||
|
[TYPE.TAG, '/list', 0, 4]
|
||||||
|
])
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -6,7 +6,7 @@ const options = {
|
|||||||
|
|
||||||
const textStub = require("./test/stub");
|
const textStub = require("./test/stub");
|
||||||
|
|
||||||
const count = 10;
|
const count = 0;
|
||||||
const parsers3 = [];
|
const parsers3 = [];
|
||||||
|
|
||||||
console.time('newParser');
|
console.time('newParser');
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const OldParser = require('./OldParser')
|
|||||||
|
|
||||||
const textStub = require("./test/stub");
|
const textStub = require("./test/stub");
|
||||||
|
|
||||||
const count = 10;
|
const count = 0;
|
||||||
const oldParsers3 = [];
|
const oldParsers3 = [];
|
||||||
console.time('oldParser');
|
console.time('oldParser');
|
||||||
for (let i = 0; i <= count; i++) {
|
for (let i = 0; i <= count; i++) {
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
"author": "Nikolay Kostyurin <jilizart@gmail.com>",
|
"author": "Nikolay Kostyurin <jilizart@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jest": "^23.1.0"
|
"jest": "^23.1.0",
|
||||||
|
"xbbcode-parser": "^0.1.2"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"registry": "https://registry.npmjs.org/"
|
"registry": "https://registry.npmjs.org/"
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const parse = require('./index');
|
const parse = require('./index');
|
||||||
const OldParser = require('./benchmark/OldParser');
|
const OldParser = require('./benchmark/OldParser');
|
||||||
const tabText = require('./benchmark/test/stub');
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
closableTags: ['ch', 'syllable', 'tab'],
|
|
||||||
allowOnlyTags: ['ch', 'syllable', 'tab'],
|
allowOnlyTags: ['ch', 'syllable', 'tab'],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,8 +13,26 @@ describe("parse", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("same as old parser", () => {
|
test("same as old parser", () => {
|
||||||
const ast1 = parse(tabText, options);
|
const input = `[Verse 2]
|
||||||
const ast2 = OldParser.parse(tabText);
|
[ch]Eb[/ch] [ch]Fm[/ch]
|
||||||
|
I'm walking around
|
||||||
|
[ch]Ab[/ch] [ch]Cm[/ch]
|
||||||
|
With my little raincloud
|
||||||
|
[ch]Eb[/ch] [ch]Fm[/ch]
|
||||||
|
Hanging over my head
|
||||||
|
[ch]Cm[/ch] [ch]Ab[/ch]
|
||||||
|
And it ain’t coming down
|
||||||
|
[ch]Eb[/ch] [ch]Fm[/ch]
|
||||||
|
Where do I go?
|
||||||
|
[ch]Ab[/ch] [ch]Cm[/ch]
|
||||||
|
Gimme some sort of sign
|
||||||
|
[ch]Eb[/ch] [ch]Fm[/ch]
|
||||||
|
Hit me with lightning!
|
||||||
|
[ch]Cm[/ch] [ch]Ab[/ch]
|
||||||
|
Maybe I’ll come alive
|
||||||
|
`;
|
||||||
|
const ast1 = parse(input, options);
|
||||||
|
const ast2 = OldParser.parse(input);
|
||||||
|
|
||||||
expect(ast1).toEqual(ast2);
|
expect(ast1).toEqual(ast2);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const TOKEN_TYPE_ID = 0;
|
const TOKEN_TYPE_ID = 0;
|
||||||
const TOKEN_VALUE_ID = 1;
|
const TOKEN_VALUE_ID = 1;
|
||||||
const TOKEN_LINE_ID = 2;
|
const TOKEN_COLUMN_ID = 2;
|
||||||
const TOKEN_COLUMN_ID = 3;
|
const TOKEN_LINE_ID = 3;
|
||||||
|
|
||||||
const TOKEN_TYPE_WORD = 'word';
|
const TOKEN_TYPE_WORD = 'word';
|
||||||
const TOKEN_TYPE_TAG = 'tag';
|
const TOKEN_TYPE_TAG = 'tag';
|
||||||
|
|||||||
Reference in New Issue
Block a user