Skip to content

Commit b8acc96

Browse files
committed
Add stringify unit-tests
1 parent c07fca2 commit b8acc96

3 files changed

Lines changed: 104 additions & 23 deletions

File tree

src/java-props.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export function parse(str: string): Properties {
5252
return result;
5353
}
5454

55-
export function stringify(props: Properties): string { // TODO: Add unit-tests
55+
export function stringify(props: Properties): string {
5656
let str = '';
5757
for (const key in props) {
5858
if (Object.prototype.hasOwnProperty.call(props, key)) {

test/api.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const CommonJavaPropsR = require('../src/java-props');
1212

1313
apis.common = {
1414
modules: [CommonJavaProps, CommonJavaPropsW, CommonJavaPropsR],
15-
methods: ['parse'],
15+
methods: ['parse', 'stringify'],
1616
};
1717

1818
// node

test/java-props.test.ts

Lines changed: 102 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import fs from 'fs';
22
import JavaProps from '../src/java-props';
3-
import {convertLine} from '../src/utils';
3+
import {decodeLine, encodeLine} from '../src/utils';
44

55
describe('parse', () => {
66
it('validate test.properties', async () => {
77
const res = JSON.parse(fs.readFileSync(__dirname + '/test.properties-result.json', 'utf8'));
8-
const props = await JavaProps.parse(fs.readFileSync(__dirname + '/test.properties', 'utf8'));
8+
const props = JavaProps.parse(fs.readFileSync(__dirname + '/test.properties', 'utf8'));
99
expect(props).toEqual(res);
1010
});
1111

@@ -29,42 +29,123 @@ describe('parse', () => {
2929
});
3030
});
3131

32-
describe('utils.convertLine', () => {
33-
const converts: any = {
34-
t: '\t',
35-
r: '\r',
36-
n: '\n',
37-
f: '\f',
32+
describe('stringify', () => {
33+
const expectConvertBack = (props: any) => {
34+
const newProps = JavaProps.parse(JavaProps.stringify(props));
35+
expect(newProps).toEqual(props);
3836
};
37+
38+
it('convert back test.properties', async () => {
39+
expectConvertBack(JavaProps.parse(fs.readFileSync(__dirname + '/test.properties', 'utf8')));
40+
});
41+
42+
it('must handle spacings', async () => {
43+
expectConvertBack({' key': 'value'});
44+
expectConvertBack({'key': ' value'});
45+
expectConvertBack({'key ': 'value'});
46+
expectConvertBack({'key': 'value '});
47+
expectConvertBack({' ke:y= ': ' = \\nval\\ue\n '});
48+
});
49+
50+
it('must skip non-own properties', async () => {
51+
const obj = {'key': 'value'};
52+
(Object.prototype as any).notAKey = 'x';
53+
expect(JavaProps.stringify(obj)).toBe('key: value\n');
54+
});
55+
56+
it('must handle null-prototype objects', async () => {
57+
const obj = Object.create(null);
58+
obj.key = 'value';
59+
expect(JavaProps.stringify(obj)).toBe('key: value\n');
60+
});
61+
});
62+
63+
const converts: any = {
64+
t: '\t',
65+
r: '\r',
66+
n: '\n',
67+
f: '\f',
68+
};
69+
70+
describe('utils.decodeLine', () => {
3971
for (const char in converts) {
4072
if (converts.hasOwnProperty(char)) {
4173
const repl = converts[char];
42-
it('must convert \\' + char, () => {
43-
expect(convertLine('abc\\' + char + 'def\\' + char + 'ghi')).toBe('abc' + repl + 'def' + repl + 'ghi');
74+
it('must decode \\' + char, () => {
75+
expect(decodeLine('abc\\' + char + 'def\\' + char + 'ghi')).toBe('abc' + repl + 'def' + repl + 'ghi');
4476
});
4577
}
4678
}
4779

4880
it('must remove useless escapes', () => {
49-
expect(convertLine('a\\bc\\def\\\\')).toBe('abcdef\\');
81+
expect(decodeLine('a\\bc\\def\\\\')).toBe('abcdef\\');
5082
});
5183

5284
it('must replace \\uxxxx', () => {
53-
expect(convertLine('\\u0058 \\u2764')).toBe('X ❤');
54-
expect(convertLine('\\u00580')).toBe('X0');
55-
expect(convertLine('\\u0058A\\u2764Test')).toBe('XA❤Test');
56-
expect(convertLine('\\u002F \\u002f')).toBe('/ /');
85+
expect(decodeLine('\\u0058 \\u2764')).toBe('X ❤');
86+
expect(decodeLine('\\u00580')).toBe('X0');
87+
expect(decodeLine('\\u0058A\\u2764Test')).toBe('XA❤Test');
88+
expect(decodeLine('\\u002F \\u002f')).toBe('/ /');
5789
});
5890

5991
it('must throw on malformed \\uxxxx', () => {
60-
expect(() => convertLine('\\u')).toThrow();
61-
expect(() => convertLine('\\u58')).toThrow();
62-
expect(() => convertLine('\\u27g4')).toThrow();
92+
expect(() => decodeLine('\\u')).toThrow();
93+
expect(() => decodeLine('\\u58')).toThrow();
94+
expect(() => decodeLine('\\u27g4')).toThrow();
6395
});
6496

6597
it('must not replace escaped', () => {
66-
expect(convertLine('test\\nand\\\\n \\\\\\n')).toBe('test\nand\\n \\\n');
67-
expect(convertLine('abc \\\\u0000')).toBe('abc \\u0000');
68-
expect(convertLine('abc \\\\uxxxx')).toBe('abc \\uxxxx');
98+
expect(decodeLine('test\\nand\\\\n \\\\\\n')).toBe('test\nand\\n \\\n');
99+
expect(decodeLine('abc \\\\u0000')).toBe('abc \\u0000');
100+
expect(decodeLine('abc \\\\uxxxx')).toBe('abc \\uxxxx');
69101
});
70102
});
103+
104+
const origEncodeLine = encodeLine;
105+
for (const isKey of [false, true]) {
106+
const encodeLine = (line: string) => origEncodeLine(line, isKey);
107+
describe('utils.encodeLine (isKey=' + isKey + ')', () => {
108+
for (const char in converts) {
109+
if (converts.hasOwnProperty(char)) {
110+
const repl = converts[char];
111+
it('must encode \\' + char, () => {
112+
expect(encodeLine('abc' + repl + 'def' + repl + 'ghi')).toBe('abc\\' + char + 'def\\' + char + 'ghi');
113+
});
114+
}
115+
}
116+
117+
it('must escape special chars', () => {
118+
expect(encodeLine('!# :=\\')).toBe(isKey ? '\\!\\#\\ \\:\\=\\\\' : '!# :=\\\\');
119+
});
120+
121+
if (!isKey) {
122+
it('must escape beginning space', () => {
123+
expect(encodeLine(' abc def ghi jkl ')).toBe('\\ abc def ghi jkl ');
124+
});
125+
}
126+
127+
it('must not escape normal chars', () => {
128+
let str = '';
129+
for (let cc = 33; cc < 127; ++cc) {
130+
const c = String.fromCharCode(cc);
131+
if (c === '\\' || (isKey && (c === '!' || c === '#' || c === ' ' || c === ':' || c === '='))) {
132+
continue;
133+
}
134+
str += c;
135+
}
136+
expect(encodeLine(str)).toBe(str);
137+
});
138+
139+
it('must encode others unicode chars', () => {
140+
expect(encodeLine('\0')).toBe('\\u0000');
141+
expect(encodeLine('\u0014')).toBe('\\u0014');
142+
expect(encodeLine('\u007F')).toBe('\\u007F');
143+
expect(encodeLine('é')).toBe('\\u00E9');
144+
expect(encodeLine('👑')).toBe('\\uD83D\\uDC51');
145+
expect(encodeLine(String.fromCharCode(15))).toBe('\\u000F');
146+
expect(encodeLine(String.fromCharCode(255))).toBe('\\u00FF');
147+
expect(encodeLine(String.fromCharCode(4095))).toBe('\\u0FFF');
148+
expect(encodeLine(String.fromCharCode(65535))).toBe('\\uFFFF');
149+
});
150+
});
151+
}

0 commit comments

Comments
 (0)