Skip to content

Commit 951dba4

Browse files
committed
Fixed json syntax highlight code and added tests
1 parent 074cbf2 commit 951dba4

File tree

5 files changed

+197
-4
lines changed

5 files changed

+197
-4
lines changed

.github/workflows/build-and-test.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,20 @@ jobs:
77
with:
88
java_version: 21
99
secrets: inherit
10+
11+
javascript-tests:
12+
name: JavaScript Tests
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: '18'
22+
23+
- name: Run JavaScript tests
24+
run: |
25+
cd webroot/js/test
26+
node --test *.test.mjs

webroot/js/component/output.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ function highlightJSON(json) {
1717

1818
return json
1919
.replace(/("[\w\s_-]+")(\s*:)/g, '<span class="json-key">$1</span>$2')
20-
.replace(/:\s*(".*?")/g, ': <span class="json-string">$1</span>')
21-
.replace(/:\s*(\d+\.?\d*)/g, ': <span class="json-number">$1</span>')
22-
.replace(/:\s*(true|false)/g, ': <span class="json-boolean">$1</span>')
23-
.replace(/:\s*(null)/g, ': <span class="json-null">$1</span>');
20+
.replace(/(:\s*)("(?:[^"\\]|\\.)*")/g, '$1<span class="json-string">$2</span>')
21+
.replace(/(:\s*|[\[\,]\s*)(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)(?=\s*[,\]\}\n]|$)/g, '$1<span class="json-number">$2</span>')
22+
.replace(/(:\s*|[\[\,]\s*)(true|false)(?=\s*[,\]\}\n]|$)/g, '$1<span class="json-boolean">$2</span>')
23+
.replace(/(:\s*|[\[\,]\s*)(null)(?=\s*[,\]\}\n]|$)/g, '$1<span class="json-null">$2</span>');
2424
}
2525

2626
function formatOutput(data) {

webroot/js/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "module"
3+
}

webroot/js/test/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# JavaScript Unit Tests
2+
3+
This directory contains Node.js unit tests using ES modules and Node.js's built-in `node:test` module.
4+
5+
To run the tests, you need Node.js v18+ installed. Then run:
6+
7+
```bash
8+
# Run one test file
9+
node --test webroot/js/test/output.test.mjs
10+
11+
# Run all tests in the directory
12+
node --test webroot/js/test/
13+
```

webroot/js/test/output.test.mjs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { test, describe } from 'node:test';
2+
import assert from 'node:assert';
3+
import { highlightJSON } from '../component/output.js';
4+
5+
describe('highlightJSON', () => {
6+
test('should highlight numbers', () => {
7+
const input = { count: 42 };
8+
const result = highlightJSON(JSON.stringify(input));
9+
10+
const expected = '{<span class="json-key">"count"</span>:<span class="json-number">42</span>}';
11+
assert.strictEqual(result, expected);
12+
});
13+
14+
test('should not highlight numbers within strings', () => {
15+
const input = {
16+
link_id: "aws:us-west-2:94889860-0a55-4fbd-981e-3a9ce99ca1ec"
17+
};
18+
const result = highlightJSON(JSON.stringify(input));
19+
20+
const expected = '{<span class="json-key">"link_id"</span>:<span class="json-string">"aws:us-west-2:94889860-0a55-4fbd-981e-3a9ce99ca1ec"</span>}';
21+
assert.strictEqual(result, expected);
22+
});
23+
24+
test('should handle mixed numbers and strings', () => {
25+
const input = {
26+
service_id: 8,
27+
site_id: 276,
28+
link_id: "aws:us-west-2:94889860-0a55-4fbd-981e-3a9ce99ca1ec"
29+
};
30+
const result = highlightJSON(JSON.stringify(input, null, 2));
31+
32+
const expected = `{
33+
<span class="json-key">"service_id"</span>: <span class="json-number">8</span>,
34+
<span class="json-key">"site_id"</span>: <span class="json-number">276</span>,
35+
<span class="json-key">"link_id"</span>: <span class="json-string">"aws:us-west-2:94889860-0a55-4fbd-981e-3a9ce99ca1ec"</span>
36+
}`;
37+
assert.strictEqual(result, expected);
38+
});
39+
40+
test('should highlight strings', () => {
41+
const input = { name: "test-value" };
42+
const result = highlightJSON(JSON.stringify(input));
43+
44+
const expected = '{<span class="json-key">"name"</span>:<span class="json-string">"test-value"</span>}';
45+
assert.strictEqual(result, expected);
46+
});
47+
48+
test('should highlight keys', () => {
49+
const input = { test_key: "value" };
50+
const result = highlightJSON(JSON.stringify(input));
51+
52+
const expected = '{<span class="json-key">"test_key"</span>:<span class="json-string">"value"</span>}';
53+
assert.strictEqual(result, expected);
54+
});
55+
56+
test('should highlight booleans', () => {
57+
const input = { flag: true, disabled: false };
58+
const result = highlightJSON(JSON.stringify(input));
59+
60+
const expected = '{<span class="json-key">"flag"</span>:<span class="json-boolean">true</span>,<span class="json-key">"disabled"</span>:<span class="json-boolean">false</span>}';
61+
assert.strictEqual(result, expected);
62+
});
63+
64+
test('should highlight null', () => {
65+
const input = { value: null };
66+
const result = highlightJSON(JSON.stringify(input));
67+
68+
const expected = '{<span class="json-key">"value"</span>:<span class="json-null">null</span>}';
69+
assert.strictEqual(result, expected);
70+
});
71+
72+
test('should handle negative numbers', () => {
73+
const input = { temperature: -15 };
74+
const result = highlightJSON(JSON.stringify(input));
75+
76+
const expected = '{<span class="json-key">"temperature"</span>:<span class="json-number">-15</span>}';
77+
assert.strictEqual(result, expected);
78+
});
79+
80+
test('should handle decimal numbers', () => {
81+
const input = { price: 19.99 };
82+
const result = highlightJSON(JSON.stringify(input));
83+
84+
const expected = '{<span class="json-key">"price"</span>:<span class="json-number">19.99</span>}';
85+
assert.strictEqual(result, expected);
86+
});
87+
88+
test('should handle scientific notation', () => {
89+
const input = { value: 1.23e-4 };
90+
const result = highlightJSON(JSON.stringify(input));
91+
92+
const expected = '{<span class="json-key">"value"</span>:<span class="json-number">0.000123</span>}';
93+
assert.strictEqual(result, expected);
94+
});
95+
96+
test('should handle nested objects', () => {
97+
const input = {
98+
user: {
99+
id: 123,
100+
name: "John Doe",
101+
active: true,
102+
metadata: null,
103+
scores: [95.5, -2.3, 0]
104+
}
105+
};
106+
const result = highlightJSON(JSON.stringify(input, null, 2));
107+
108+
const expected = `{
109+
<span class="json-key">"user"</span>: {
110+
<span class="json-key">"id"</span>: <span class="json-number">123</span>,
111+
<span class="json-key">"name"</span>: <span class="json-string">"John Doe"</span>,
112+
<span class="json-key">"active"</span>: <span class="json-boolean">true</span>,
113+
<span class="json-key">"metadata"</span>: <span class="json-null">null</span>,
114+
<span class="json-key">"scores"</span>: [
115+
<span class="json-number">95.5</span>,
116+
<span class="json-number">-2.3</span>,
117+
<span class="json-number">0</span>
118+
]
119+
}
120+
}`;
121+
assert.strictEqual(result, expected);
122+
});
123+
124+
test('should handle escaped quotes', () => {
125+
const input = {
126+
message: 'He said "Hello, world!" to everyone'
127+
};
128+
const result = highlightJSON(JSON.stringify(input));
129+
130+
const expected = '{<span class="json-key">"message"</span>:<span class="json-string">"He said \\"Hello, world!\\" to everyone"</span>}';
131+
assert.strictEqual(result, expected);
132+
});
133+
134+
test('should handle empty objects and arrays', () => {
135+
const input = { empty_obj: {}, empty_array: [] };
136+
const result = highlightJSON(JSON.stringify(input));
137+
138+
const expected = '{<span class="json-key">"empty_obj"</span>:{},<span class="json-key">"empty_array"</span>:[]}';
139+
assert.strictEqual(result, expected);
140+
});
141+
142+
test('should handle special characters in strings', () => {
143+
const input = {
144+
special: "Line 1\nLine 2\tTabbed\r\nWindows line ending",
145+
unicode: "Unicode: 🚀 ñ é"
146+
};
147+
const result = highlightJSON(JSON.stringify(input));
148+
149+
const expected = '{<span class="json-key">"special"</span>:<span class="json-string">"Line 1\\nLine 2\\tTabbed\\r\\nWindows line ending"</span>,<span class="json-key">"unicode"</span>:<span class="json-string">"Unicode: 🚀 ñ é"</span>}';
150+
assert.strictEqual(result, expected);
151+
});
152+
153+
test('should handle non-object input', () => {
154+
const input = [1, 2, 3];
155+
const result = highlightJSON(JSON.stringify(input));
156+
157+
const expected = '[<span class="json-number">1</span>,<span class="json-number">2</span>,<span class="json-number">3</span>]';
158+
assert.strictEqual(result, expected);
159+
});
160+
});

0 commit comments

Comments
 (0)