Commit a35f6215 authored by Florent Chehab's avatar Florent Chehab

Added parseMoney function and test for #35

parent 114ea1cf
Pipeline #35553 passed with stages
in 6 minutes and 56 seconds
/**
* Function to get a regex object for money parsing
*
* @returns
*/
function getMoneyRegex() {
return /:(\d*[.,]?\d*)(\w{3}):/g;
}
/**
* Parses a string to determine if there are some currency in it.
*
* For example, the string: "Hi, I earn :10.15CHF:" will be converted to:
* [{ isMoney: false, text: 'Hi, I earn ' },
* { isMoney: true, amount: '10.15', currency: 'CHF' }]
*
* In the string: amount can be an int, a float with ',' or '.' as separator
* And the currency can be in mixed case, but will always be return in uppercase.
*
* @export
* @param {string} str
* @returns {Array}
*/
export default function parseMoney(str) {
if (str === "") {
return [];
}
// reusable function
const getOutputText = (str) => ({ isMoney: false, text: str });
if (!getMoneyRegex().test(str)) {
// if the string doesn't contain anything interesting
return [getOutputText(str)];
} else {
let matches = [],
match,
moneyRegEx = getMoneyRegex();
while ((match = moneyRegEx.exec(str)) !== null) {
const matchStartIndex = match.index, // index of the starting ':'
matchLastIndex = moneyRegEx.lastIndex - 1, // index of the ending ':'
amount = parseFloat(match["1"].replace(",", ".")), // fix numbers with "," as decimal separators
currency = match["2"].toUpperCase(); // make sure the currency is uppercase
matches.push({ matchStartIndex, matchLastIndex, amount, currency });
}
let res = [], lastIndex = 0;
matches.forEach((el) => {
if (lastIndex !== el.matchStartIndex) {
// we need to add a classic string that was before the currency marker
res.push(getOutputText(str.substring(lastIndex, el.matchStartIndex)));
}
// We add the element corresponding to money mount
res.push({ isMoney: true, amount: el.amount, currency: el.currency });
lastIndex = el.matchLastIndex + 1;
});
// we need to add the eventual trailing text:
if (lastIndex !== str.length) {
res.push(getOutputText(str.substring(lastIndex)));
}
return res;
}
}
import parseMoney from "../../src/utils/parseMoney";
test("parse empty string", () => {
const str = "";
expect(parseMoney(str).length).toBe(0);
});
test("Parse string with no money", () => {
const str = "A random classic string";
expect(parseMoney(str).length).toBe(1);
expect(parseMoney(str)[0].text).toBe(str);
});
test("Parse string with only money", () => {
const str = ":100CHF:",
parsed = parseMoney(str);
expect(parsed.length).toBe(1);
expect(parsed[0].amount).toBe(100);
expect(parsed[0].currency).toBe("CHF");
});
test("Parse complicated string", () => {
const str = "Hi, I earn :0,0Chf: but he earned :100.12EUR: this year !",
parsed = parseMoney(str);
expect(parsed.length).toBe(5);
expect(parsed[0].isMoney).toBe(false);
expect(parsed[1].isMoney).toBe(true);
expect(parsed[2].isMoney).toBe(false);
expect(parsed[3].isMoney).toBe(true);
expect(parsed[4].isMoney).toBe(false);
expect(parsed[0].text).toBe("Hi, I earn ");
expect(parsed[2].text).toBe(" but he earned ");
expect(parsed[4].text).toBe(" this year !");
expect(parsed[1].amount).toBe(0);
expect(parsed[3].amount).toBe(100.12);
expect(parsed[1].currency).toBe("CHF");
expect(parsed[3].currency).toBe("EUR");
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment