@cloudpss/template
Version:
String and object template engine for Node.js and the browser.
286 lines (275 loc) • 11.1 kB
JavaScript
import { parseTemplate, parseInterpolation } from '../dist/parser.js';
describe('parseInterpolation', () => {
it('should parse simple interpolation', () => {
expect(parseInterpolation('')).toEqual({
type: 'interpolation',
templates: [''],
values: [],
});
expect(parseInterpolation('hello')).toEqual({
type: 'interpolation',
templates: ['hello'],
values: [],
});
expect(parseInterpolation('hello $name!')).toEqual({
type: 'interpolation',
templates: ['hello ', '!'],
values: ['name'],
});
expect(parseInterpolation('$$name')).toEqual({
type: 'interpolation',
templates: ['$', ''],
values: ['name'],
});
expect(parseInterpolation('$name_is_long')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['name_is_long'],
});
expect(parseInterpolation('$_001')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['_001'],
});
expect(parseInterpolation('$001$a$')).toEqual({
type: 'interpolation',
templates: ['$001', '$'],
values: ['a'],
});
expect(parseInterpolation('$$name$a')).toEqual({
type: 'interpolation',
templates: ['$', '', ''],
values: ['name', 'a'],
});
expect(parseInterpolation('$ $ $ $')).toEqual({
type: 'interpolation',
templates: ['$ $ $ $'],
values: [],
});
});
describe('should parse range', () => {
it('should throw on bad range', () => {
expect(() => parseInterpolation('xxx', -1, 0)).toThrow('start out of range');
expect(() => parseInterpolation('xxx', 0, 4)).toThrow('length out of range');
expect(() => parseInterpolation('xxx', 1, 3)).toThrow('length out of range');
expect(() => parseInterpolation('xxx', 3, -1)).toThrow('length out of range');
});
it('should parse range', () => {
expect(parseInterpolation('abcde', 0, 3)).toEqual({
type: 'interpolation',
templates: ['abc'],
values: [],
});
expect(parseInterpolation('abcde', 1, 3)).toEqual({
type: 'interpolation',
templates: ['bcd'],
values: [],
});
expect(parseInterpolation('abcde', 2, 3)).toEqual({
type: 'interpolation',
templates: ['cde'],
values: [],
});
expect(parseInterpolation('abcde', 3, 1)).toEqual({
type: 'interpolation',
templates: ['d'],
values: [],
});
expect(parseInterpolation('abcde', 5, 0)).toEqual({
type: 'interpolation',
templates: [''],
values: [],
});
});
});
});
describe('parseTemplate', () => {
describe('should parse plain', () => {
it('empty string', () => {
// @ts-expect-error test
expect(parseTemplate(null)).toEqual('');
// @ts-expect-error test
expect(parseTemplate(undefined)).toEqual('');
expect(parseTemplate('')).toEqual('');
});
it('string', () => {
expect(parseTemplate('Hello, world!')).toEqual('Hello, world!');
expect(parseTemplate('\u0000')).toEqual('\u0000');
expect(parseTemplate(' ')).toEqual(' ');
// bad surrogate pair
expect(parseTemplate('\uD800')).toEqual('\uD800');
expect(parseTemplate('\uDC00')).toEqual('\uDC00');
});
it('template like (but not)', () => {
expect(parseTemplate('$')).toBe('$');
expect(parseTemplate('=')).toBe('=');
expect(parseTemplate(' = 1+1')).toEqual(' = 1+1');
expect(parseTemplate(' =1+1')).toEqual(' =1+1');
expect(parseTemplate(' =1+1 ')).toEqual(' =1+1 ');
expect(parseTemplate(' =1+1 ')).toEqual(' =1+1 ');
expect(parseTemplate(' $aa')).toEqual(' $aa');
});
});
it('should parse formulas', () => {
expect(parseTemplate('= 1+1')).toEqual({ type: 'formula', value: ' 1+1' });
expect(parseTemplate('= 1+1 ')).toEqual({ type: 'formula', value: ' 1+1 ' });
expect(parseTemplate('=arg')).toEqual({ type: 'formula', value: 'arg' });
expect(parseTemplate('=arg1+arg2')).toEqual({ type: 'formula', value: 'arg1+arg2' });
});
describe('should parse interpolation', () => {
it('optimize for no interpolation', () => {
expect(parseTemplate('$not')).toBe('not');
expect(parseTemplate('$not interpolation')).toBe('not interpolation');
expect(parseTemplate('$$')).toBe('$');
expect(parseTemplate('$$$')).toBe('$$');
expect(parseTemplate('$$$$')).toBe('$$$');
});
it('should parse simple interpolation', () => {
expect(parseTemplate('$hello $name!')).toEqual({
type: 'interpolation',
templates: ['hello ', '!'],
values: ['name'],
});
expect(parseTemplate('$$name')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['name'],
});
expect(parseTemplate('$$name_is_long')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['name_is_long'],
});
expect(parseTemplate('$$_001')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['_001'],
});
expect(parseTemplate('$$001$a')).toEqual({
type: 'interpolation',
templates: ['$001', ''],
values: ['a'],
});
expect(parseTemplate('$$name$a')).toEqual({
type: 'interpolation',
templates: ['', '', ''],
values: ['name', 'a'],
});
});
it('should parse complex interpolation', () => {
expect(parseTemplate('$hello ${name}!')).toEqual({
type: 'interpolation',
templates: ['hello ', '!'],
values: ['name'],
});
expect(parseTemplate('$${name}')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['name'],
});
expect(parseTemplate('$${name_is_long}')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['name_is_long'],
});
expect(parseTemplate('$${_001}')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['_001'],
});
expect(parseTemplate('$1${ }2')).toEqual({
type: 'interpolation',
templates: ['1', '2'],
values: [''],
});
expect(parseTemplate('$${ name }${ a}')).toEqual({
type: 'interpolation',
templates: ['', '', ''],
values: ['name', 'a'],
});
});
it('should parse mixed interpolation', () => {
expect(parseTemplate('$$name${a}')).toEqual({
type: 'interpolation',
templates: ['', '', ''],
values: ['name', 'a'],
});
expect(parseTemplate('$${name }$a')).toEqual({
type: 'interpolation',
templates: ['', '', ''],
values: ['name', 'a'],
});
expect(
parseInterpolation(
"hello $name! I am $age years old. I'll be ${age+1} next year. And $(2*age) after $<age> years. $100",
),
).toEqual({
type: 'interpolation',
templates: ['hello ', '! I am ', " years old. I'll be ", ' next year. And ', ' after ', ' years. $100'],
values: ['name', 'age', 'age+1', '2*age', 'age'],
});
});
it('should not break on normal braces', () => {
expect(parseTemplate('$$aa{$b}')).toEqual({
type: 'interpolation',
templates: ['', '{', '}'],
values: ['aa', 'b'],
});
expect(parseTemplate('$$aa{$}')).toEqual({
type: 'interpolation',
templates: ['', '{$}'],
values: ['aa'],
});
expect(parseTemplate('$$aa{}')).toEqual({
type: 'interpolation',
templates: ['', '{}'],
values: ['aa'],
});
expect(parseTemplate('$$aa<xx>')).toEqual({
type: 'interpolation',
templates: ['', '<xx>'],
values: ['aa'],
});
expect(parseTemplate('$$$$aa{}')).toEqual({
type: 'interpolation',
templates: ['$$', '{}'],
values: ['aa'],
});
});
it('should throw on invalid interpolation', () => {
expect(() => parseTemplate('$${')).toThrow('Unexpected end of input');
expect(() => parseTemplate('$$<')).toThrow('Unexpected end of input');
expect(() => parseTemplate('$$[')).toThrow('Unexpected end of input');
expect(() => parseTemplate('$$(')).toThrow('Unexpected end of input');
expect(() => parseTemplate('$${123')).toThrow('Unexpected end of input');
expect(() => parseTemplate('$${{123}')).toThrow('Unexpected end of input');
});
it('should pair braces', () => {
expect(parseTemplate('$${n{am}e}')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['n{am}e'],
});
expect(parseTemplate('$$(n{a(m)e)')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['n{a(m)e'],
});
expect(parseTemplate('$${n{{a}m}e}')).toEqual({
type: 'interpolation',
templates: ['', ''],
values: ['n{{a}m}e'],
});
expect(parseTemplate('$aaa${n{{a}m}e}bbb')).toEqual({
type: 'interpolation',
templates: ['aaa', 'bbb'],
values: ['n{{a}m}e'],
});
expect(parseTemplate('$aaa${n{{a}m}e}${n{{a}m}e}bbb${n{{a}m}e}ccc')).toEqual({
type: 'interpolation',
templates: ['aaa', '', 'bbb', 'ccc'],
values: ['n{{a}m}e', 'n{{a}m}e', 'n{{a}m}e'],
});
});
});
});