Skip to content

Commit 0af6bdd

Browse files
committed
improved string builder with tests
1 parent 4c983ba commit 0af6bdd

File tree

3 files changed

+178
-14
lines changed

3 files changed

+178
-14
lines changed

.vscode/launch.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,26 @@
156156
"./src/test/core/aztec/**/*.spec.ts"
157157
],
158158
"internalConsoleOptions": "openOnSessionStart"
159+
},
160+
{
161+
"type": "node",
162+
"request": "launch",
163+
"name": "StringBuilder",
164+
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
165+
"args": [
166+
"--require",
167+
"ts-node/register",
168+
"--require",
169+
"tsconfig-paths/register",
170+
"-u",
171+
"tdd",
172+
"--timeout",
173+
"999999",
174+
"--colors",
175+
"--recursive",
176+
"./src/test/core/util/StringBuilder.spec.ts"
177+
],
178+
"internalConsoleOptions": "openOnSessionStart"
159179
}
160180
]
161181
}

src/core/util/StringBuilder.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { char, int } from '../../customTypings';
2+
import ArgumentException from '../ArgumentException';
13
import CharacterSetECI from '../common/CharacterSetECI';
2-
import { int, char } from '../../customTypings';
34
import StringUtils from '../common/StringUtils';
45

56
export default class StringBuilder {
@@ -14,20 +15,29 @@ export default class StringBuilder {
1415
}
1516

1617
public append(s: string | number): StringBuilder {
18+
this.value += this.normalizeString(s);
19+
return this;
20+
}
21+
22+
public normalizeString(s: string | number) {
1723
if (typeof s === 'string') {
18-
this.value += s.toString();
19-
} else if (this.encoding) {
24+
return s.toString();
25+
}
26+
27+
if (this.encoding) {
2028
// use passed format (fromCharCode will return UTF8 encoding)
21-
this.value += StringUtils.castAsNonUtf8Char(s, this.encoding);
22-
} else {
23-
// correctly converts from UTF-8, but not other encodings
24-
this.value += String.fromCharCode(s);
29+
return StringUtils.castAsNonUtf8Char(s, this.encoding);
2530
}
26-
return this;
31+
32+
// correctly converts from UTF-8, but not other encodings
33+
return String.fromCharCode(s);
2734
}
2835

2936
public appendChars(str: char[] | string[], offset: int, len: int): StringBuilder {
30-
for (let i = offset; offset < offset + len; i++) {
37+
const strLength = str.length;
38+
if (strLength < len) throw new ArgumentException('`str` must be the same size or smaller than `len`');
39+
for (let i = offset; i < offset + len; i++) {
40+
if (i > strLength) throw new ArgumentException('Index out of bounds!');
3141
this.append(str[i]);
3242
}
3343
return this;
@@ -53,9 +63,6 @@ export default class StringBuilder {
5363
return this.value.substring(start, end);
5464
}
5565

56-
/**
57-
* @note helper method for RSS Expanded
58-
*/
5966
public setLengthToZero(): void {
6067
this.value = '';
6168
}
@@ -64,7 +71,10 @@ export default class StringBuilder {
6471
return this.value;
6572
}
6673

67-
public insert(n: number, c: string) {
68-
this.value = this.value.substr(0, n) + c + this.value.substr(n + c.length);
74+
public insert(n: number, s: string | number, replace: int = 0) {
75+
const c = this.normalizeString(s);
76+
const fromLength = !replace && replace !== 0 ? c.length : replace;
77+
this.value = this.value.substr(0, n) + c + this.value.substr(n + fromLength);
78+
return this;
6979
}
7080
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
2+
import StringBuilder from '../../../core/util/StringBuilder';
3+
import { assertEquals } from './AssertUtils';
4+
5+
describe('StringBuilder tests', () => {
6+
7+
it('initializes empty strings', () => {
8+
9+
const expected = '';
10+
const sb = new StringBuilder();
11+
12+
assertEquals(sb.toString(), expected);
13+
});
14+
15+
it('initializes strings', () => {
16+
17+
const expected = 'xyz';
18+
const sb = new StringBuilder('xyz');
19+
20+
assertEquals(sb.toString(), expected);
21+
});
22+
23+
it('appends strings', () => {
24+
25+
const expected1 = 'abcdef';
26+
const sb1 = new StringBuilder();
27+
const expected2 = '-abcdef';
28+
const sb2 = new StringBuilder('-');
29+
30+
sb1.append('abc');
31+
sb1.append('def');
32+
33+
sb2.append('abc');
34+
sb2.append('def');
35+
36+
assertEquals(sb1.toString(), expected1);
37+
assertEquals(sb2.toString(), expected2);
38+
});
39+
40+
it('apends chars', () => {
41+
42+
const expected = '-&8xyzxy';
43+
const sb = new StringBuilder('-&8');
44+
45+
sb.appendChars([120, 121, 122], 0, 1);
46+
sb.appendChars([120, 121, 122], 1, 1);
47+
sb.appendChars([120, 121, 122], 2, 1);
48+
sb.appendChars([120, 121, 122], 0, 2);
49+
50+
assertEquals(sb.toString(), expected);
51+
});
52+
53+
it('correctly normalizes UTF8 strings', () => {
54+
55+
const expected120 = 'x';
56+
const input120 = 120;
57+
58+
const expected54 = '6';
59+
const input54 = 54;
60+
61+
const expected80 = 'P';
62+
const input80 = 80;
63+
64+
const expected37 = '%';
65+
const input37 = 37;
66+
67+
const expected64 = '@';
68+
const input64 = 64;
69+
70+
const sb = new StringBuilder();
71+
72+
const actual120 = sb.normalizeString(input120);
73+
assertEquals(actual120, expected120);
74+
75+
const actual54 = sb.normalizeString(input54);
76+
assertEquals(actual54, expected54);
77+
78+
const actual80 = sb.normalizeString(input80);
79+
assertEquals(actual80, expected80);
80+
81+
const actual37 = sb.normalizeString(input37);
82+
assertEquals(actual37, expected37);
83+
84+
const actual64 = sb.normalizeString(input64);
85+
assertEquals(actual64, expected64);
86+
});
87+
88+
it('correctly returns lentgh', () => {
89+
const expected = 10;
90+
const sb = new StringBuilder('----------');
91+
assertEquals(sb.length(), expected);
92+
});
93+
94+
it('sets lentgh to zero', () => {
95+
const expected = 0;
96+
const sb = new StringBuilder('----------');
97+
98+
sb.setLengthToZero();
99+
100+
assertEquals(sb.length(), expected);
101+
});
102+
103+
it('returns the char at index', () => {
104+
const expected = 'a';
105+
const sb = new StringBuilder('----a----');
106+
assertEquals(sb.charAt(4), expected);
107+
});
108+
109+
it('changes the char at index', () => {
110+
const expected = 'a';
111+
const sb = new StringBuilder('---------');
112+
113+
sb.setCharAt(4, 'a');
114+
115+
assertEquals(sb.charAt(4), expected);
116+
});
117+
118+
it('inserts and replaces chars', () => {
119+
const expected1 = '----aaaa-----';
120+
const expected2 = '----bbbb-----';
121+
const expected3 = '----cccc-----';
122+
const sb = new StringBuilder('---------');
123+
124+
sb.insert(4, 'aaaa');
125+
assertEquals(sb.toString(), expected1);
126+
127+
sb.insert(4, 'bbbb', 4);
128+
assertEquals(sb.toString(), expected2);
129+
130+
sb.insert(4, 'cccc', null);
131+
assertEquals(sb.toString(), expected3);
132+
});
133+
134+
});

0 commit comments

Comments
 (0)