Skip to content

Commit

Permalink
Add multi-line test
Browse files Browse the repository at this point in the history
  • Loading branch information
bennothommo committed Aug 8, 2023
1 parent b292f67 commit 0d4740c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
21 changes: 12 additions & 9 deletions src/utilities/JsonParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,26 @@ export default class JsonParser extends Singleton {
* @returns {string}
*/
tokenize(str, tokens) {
const tokenized = str.trim().replace(/('[^']+'|"[^"]+"|\{.*?\}\s*(?=[,{\]]|$)|\[.*\](?=[,{\]]|$))/g, (match) => {
if (match.substring(0, 1) === '\'' || match.substring(0, 1) === '"') {
tokens.strings.push(match);
const tokenized = str.trim().replace(/('[^']+'|"[^"]+"|\{.*?\}\s*(?=[,{\]]|$)|\[.*\]\s*(?=[,{\]]|$))/gs, (match) => {
const trimmed = match.trim();

if (trimmed.substring(0, 1) === '\'' || trimmed.substring(0, 1) === '"') {
tokens.strings.push(trimmed);
return `__STR$(${(tokens.strings.length - 1)})__`;
}

if (match.substring(0, 1) === '{') {
const obj = this.tokenize(match.substring(1, match.length - 1), tokens);
if (trimmed.substring(0, 1) === '{') {
const obj = this.tokenize(trimmed.substring(1, trimmed.length - 1), tokens);
tokens.objects.push(obj);
return `__OBJ$(${(tokens.objects.length - 1)})__`;
}

const obj = this.tokenize(match.substring(1, match.length - 1), tokens);
const obj = this.tokenize(trimmed.substring(1, trimmed.length - 1), tokens);
tokens.arrays.push(obj);
return `__ARR$(${(tokens.arrays.length - 1)})__`;
});

// Work out key/pair values for objects, or values for arrays, and tokenise these too.
let pairs = [];

if (tokenized.includes(',')) {
Expand Down Expand Up @@ -158,14 +161,14 @@ export default class JsonParser extends Singleton {
return tokenized.replace(/__([A-Z]{3})\$\((\d+)\)__/g, (match, tokenCode, tokenIndex) => {
switch (tokenCode) {
case 'STR':
return tokens.strings[tokenIndex];
return tokens.strings[tokenIndex].replace(/\n/g, '\\n');
case 'KEY':
return `"${tokens.keys[tokenIndex]}"`;
case 'VAL':
try {
return JSON5.parse(tokens.values[tokenIndex]);
return JSON5.parse(tokens.values[tokenIndex].replace(/\n/g, '\\n'));
} catch (e) {
return `"${tokens.values[tokenIndex]}"`;
return `"${tokens.values[tokenIndex].replace(/\n/g, '\\n')}"`;
}
case 'ARR':
return `[ ${this.detokenize(tokens.arrays[tokenIndex], tokens)} ]`;
Expand Down
43 changes: 39 additions & 4 deletions tests/utilities/JsonParser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('JsonParser utility', () => {
expect(Snowboard.jsonParser().parse('"null"')).toEqual('null');
expect(Snowboard.jsonParser().parse('\'1.23\'')).toEqual('1.23');
expect(Snowboard.jsonParser().parse('\'test\'')).toEqual('test');
expect(Snowboard.jsonParser().parse('1.2.3')).toEqual('1.2.3');
});

it('parses a string that looks like an object', () => {
Expand Down Expand Up @@ -69,10 +70,7 @@ describe('JsonParser utility', () => {
});

it('can parse a complex object with multiple layers', () => {
const parsed = Snowboard.jsonParser().parse('celebs: { tom: { holland: true, "cruise": false, "others": [ hardy, "hanks" ] } }, movies: [ { movie: "The Avengers" , stars : 4 }, { movie: "Mission: Impossible", stars: 4 } ]');
console.log(parsed);

expect(parsed).toEqual({
expect(Snowboard.jsonParser().parse('celebs: { tom: { holland: true, "cruise": false, "others": [ hardy, "hanks" ] } }, movies: [ { movie: "The Avengers" , stars : 4 }, { movie: "Mission: Impossible", stars: 4 } ]')).toEqual({
celebs: {
tom: {
holland: true,
Expand All @@ -95,4 +93,41 @@ describe('JsonParser utility', () => {
],
});
});

it('can parse an object over multiple lines', () => {
expect(Snowboard.jsonParser().parse(`celebs: {
tom:
{ holland: true, "cruise": false,
"others": [ hardy, "hanks" ] }
}
, movies: [
{ movie: "The Avengers" , stars : 4 },
{ movie:
"Mission:
Impossible",
stars:
4 }
]`)).toEqual({
celebs: {
tom: {
holland: true,
cruise: false,
others: [
'hardy',
'hanks',
],
},
},
movies: [
{
movie: 'The Avengers',
stars: 4,
},
{
movie: 'Mission:\n Impossible',
stars: 4,
},
],
});
});
});

0 comments on commit 0d4740c

Please sign in to comment.