import {expect} from "chai" import {Formatter} from "../../../source/text/formatter.mjs"; describe('Formatter', function () { // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/275 describe('change empty handling', function () { it('modification 1', function () { const formatter = new Formatter({ a: null, b: undefined, c : 0 }) expect(formatter.format("${a | tostring}")).to.be.equal('null'); expect(formatter.format("${b | tostring}")).to.be.equal('undefined'); expect(formatter.format("${c | tostring}")).to.be.equal('0'); }) }) // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/47 describe('examples', function () { it('rfc example should run', function () { expect(new Formatter({ a: { b: { c: "Hello" }, d: "World", e: 1 } }).format("${a.b.c} ${a.d | toupper}!")).to.be.equal('Hello WORLD!'); }) it('doc example should run', function () { expect(new Formatter({ a: { b: { c: "Hello" }, d: "world", } }).format("${a.b.c} ${a.d | ucfirst}!")).to.be.equal('Hello World!'); }) }) describe('set marker()', function () { [ ['#a#', '#', undefined, 'test'], ['{a}', '{', '}', 'test'], ['i18n{a}', 'i18n{', '}', 'test'], ].forEach(function (data) { let a = data.shift() let b = data.shift() let c = data.shift() let d = data.shift() it('format ' + a + ' with marker ' + b + ' and ' + c + ' should return ' + b, function () { expect( new Formatter({ a: "test" }).setMarker(b, c).format(a) ).to.equal(d) }); }); }) describe('examples()', function () { [ ['${a | tojson}', "{\"b\":{\"c\":\"Hello\"},\"d\":\"World\",\"e\":1}"], ['click ${a.d} times', "click World times"], [' ${a.b.c} ', ' Hello '], [' ${a.b.c}', ' Hello'], ['${a.b.c} ', 'Hello '], ['${a.b.c}', 'Hello'], ['${a.b.c}${a.b.c}', 'HelloHello'], ['${a.b.c} ${a.b.c}', 'Hello Hello'], ['${a.b.c} ${a.b.c} ', 'Hello Hello '], [' ${a.b.c} ${a.b.c} ', ' Hello Hello '], [' ${a.b.c} ${a.d} ', ' Hello World '], [' ${a.b.c} ${a.b.c | toupper | length | tostring} ', ' Hello 5 '], ].forEach(function (data) { let a = data.shift() let b = data.shift() it('format ' + a + ' should return ' + b, function () { let obj = { a: { b: { c: "Hello" }, d: "World", e: 1 } } expect(new Formatter(obj).format(a)).is.equal(b) }); }); }); describe('Marker in marker', function () { let text = '${mykey${subkey}}'; let expected = '1'; it('format ' + text + ' should ' + expected, function () { let obj = { mykey2: "1", subkey: "2" }; expect(new Formatter(obj).format(text)).is.equal(expected) }); }); describe('setParameterChars()', function () { it('setParameterChars() should return Instance', function () { expect(new Formatter({}).setParameterChars('a', 'b')).is.instanceof(Formatter); }); }); describe('with callbacks', function () { it('add callback', function () { const formatter = new Formatter({ x: '1' }, { callbacks: { my: (value) => { return "!" + value + "!" } } }); expect(formatter.format('${x | call:my}')).is.equal('!1!'); }); }); describe('Marker in marker with parameter', function () { let text = '${mykey::mykey=${subkey}}'; let expected = '2'; it('format ' + text + ' should ' + expected, function () { let obj = { subkey: "2" }; expect(new Formatter(obj).format(text)).is.equal(expected) }); }); describe('exceptions', function () { [ ['${a.b.x}', TypeError], ['${a.b.d | toupper | length}', TypeError], ['${a.b.d}', TypeError], // a.b.d return undefined by pathfinder ['${a.b.d | tolower}', TypeError], // a.b.d return undefined by pathfinder ['${a | }', Error], ].forEach(function (data) { let a = data.shift() let b = data.shift() it('format ' + a + ' should throw ' + typeof b, function () { expect(() => { new Formatter({ a: { b: { c: "test", d: 4 } } }).format(a) } ).to.throw(b); }); }); }); describe('Formatter', () => { it('should format a basic string with object values', () => { const formatter = new Formatter({name: 'John', age: 30}); const result = formatter.format('My name is ${name} and I am ${age | tostring} years old.'); expect(result).to.equal('My name is John and I am 30 years old.'); }); it('should format a string with nested markers', () => { const text = '${mykey${subkey}}'; const obj = {mykey2: '1', subkey: '2'}; const formatter = new Formatter(obj); expect(formatter.format(text)).to.equal('1'); }); it('should format a string with custom markers', () => { const formatter = new Formatter({name: 'John', age: 30}); formatter.setMarker('[', ']'); const result = formatter.format('My name is [name] and I am [age | tostring] years old.'); expect(result).to.equal('My name is John and I am 30 years old.'); }); it('should format a string using callback', () => { const formatter = new Formatter({x: '1'}, { callbacks: { quote: (value) => { return '"' + value + '"'; }, }, }); expect(formatter.format('${x | call:quote}')).to.equal('"1"'); }); it('should format a string with parameters', () => { const obj = { a: { b: { c: 'Hello', }, d: 'world', }, }; const formatter = new Formatter(obj); const result = formatter.format('${a.b.c} ${a.d | ucfirst}!'); expect(result).to.equal('Hello World!'); }); it('should throw a too deep nesting error', () => { const formatter = new Formatter({name: 'John'}); const nestedText = '${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name${name}}}}}}}}}}}}}}}}}}'; expect(() => formatter.format(nestedText)).to.throw('syntax error in formatter template'); }); it('should throw a too deep nesting error', () => { const inputObj = { mykey: '${mykey}', }; const formatter = new Formatter(inputObj); const text = '${mykey}'; let formattedText = text; // Create a string with 21 levels of nesting for (let i = 0; i < 21; i++) { formattedText = '${' + formattedText + '}'; } expect(() => formatter.format(formattedText)).to.throw('too deep nesting'); }); }); });