Port tests, fix issues around having not a <dict> in the root
This commit is contained in:
Родитель
b4a64b57fd
Коммит
984e575809
26
src/main.ts
26
src/main.ts
|
@ -64,7 +64,7 @@ export function parse(content: string): any {
|
|||
|
||||
let state = ROOT_STATE;
|
||||
|
||||
let cur:any = {};
|
||||
let cur:any = null;
|
||||
let stateStack:number[] = [];
|
||||
let objStack:any[] = [];
|
||||
let curKey:string = null;
|
||||
|
@ -126,6 +126,7 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
arrState.enterDict();
|
||||
} else { // ROOT_STATE
|
||||
cur = {};
|
||||
pushState(DICT_STATE, cur);
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +145,8 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
arrState.enterArray();
|
||||
} else { // ROOT_STATE
|
||||
fail('unexpected <array>');
|
||||
cur = [];
|
||||
pushState(ARR_STATE, cur);
|
||||
}
|
||||
}
|
||||
function leaveArray() {
|
||||
|
@ -178,10 +180,13 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
cur.push(val);
|
||||
} else { // ROOT_STATE
|
||||
fail('unexpected <string>');
|
||||
cur = val;
|
||||
}
|
||||
}
|
||||
function acceptReal(val:number) {
|
||||
if (isNaN(val)) {
|
||||
fail('cannot parse float');
|
||||
}
|
||||
if (state === DICT_STATE) {
|
||||
if (curKey === null) {
|
||||
fail('missing <key>');
|
||||
|
@ -191,10 +196,13 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
cur.push(val);
|
||||
} else { // ROOT_STATE
|
||||
fail('unexpected <real>');
|
||||
cur = val;
|
||||
}
|
||||
}
|
||||
function acceptInteger(val:number) {
|
||||
if (isNaN(val)) {
|
||||
fail('cannot parse integer');
|
||||
}
|
||||
if (state === DICT_STATE) {
|
||||
if (curKey === null) {
|
||||
fail('missing <key>');
|
||||
|
@ -204,7 +212,7 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
cur.push(val);
|
||||
} else { // ROOT_STATE
|
||||
fail('unexpected <integer>');
|
||||
cur = val;
|
||||
}
|
||||
}
|
||||
function acceptDate(val:Date) {
|
||||
|
@ -217,7 +225,7 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
cur.push(val);
|
||||
} else { // ROOT_STATE
|
||||
fail('unexpected <date>');
|
||||
cur = val;
|
||||
}
|
||||
}
|
||||
function acceptData(val:string) {
|
||||
|
@ -230,7 +238,7 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
cur.push(val);
|
||||
} else { // ROOT_STATE
|
||||
fail('unexpected <data>');
|
||||
cur = val;
|
||||
}
|
||||
}
|
||||
function acceptBool(val:boolean) {
|
||||
|
@ -243,7 +251,7 @@ export function parse(content: string): any {
|
|||
} else if (state === ARR_STATE) {
|
||||
cur.push(val);
|
||||
} else { // ROOT_STATE
|
||||
fail('unexpected <true> or <false>');
|
||||
cur = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,10 +401,12 @@ export function parse(content: string): any {
|
|||
continue;
|
||||
|
||||
case 'true':
|
||||
parseTagValue(tag);
|
||||
acceptBool(true);
|
||||
continue;
|
||||
|
||||
case 'false':
|
||||
parseTagValue(tag);
|
||||
acceptBool(false);
|
||||
continue;
|
||||
}
|
||||
|
|
186
test/test.ts
186
test/test.ts
|
@ -26,6 +26,192 @@ describe('parse', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('parse', () => {
|
||||
|
||||
let header = [
|
||||
'<?xml version="1.0" encoding="UTF-8"?>',
|
||||
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
||||
'<plist version="1.0">'
|
||||
];
|
||||
|
||||
let footer = [
|
||||
'</plist>'
|
||||
];
|
||||
|
||||
function assertParse(lines:string[], expected:any): void {
|
||||
let str = header.concat(lines).concat(footer).join('\n');
|
||||
let actual = parse(str);
|
||||
assert.deepEqual(actual, expected);
|
||||
}
|
||||
|
||||
function assertThrows(lines:string[]): void {
|
||||
let str = header.concat(lines).concat(footer).join('\n');
|
||||
try {
|
||||
parse(str);
|
||||
assert.ok(false, 'throws');
|
||||
} catch(err) {
|
||||
assert.ok(true, 'throws');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
it('String', function() {
|
||||
assertParse(
|
||||
[
|
||||
'<string>foo</string>'
|
||||
],
|
||||
"foo"
|
||||
);
|
||||
|
||||
assertParse(
|
||||
[
|
||||
'<string></string>'
|
||||
],
|
||||
""
|
||||
);
|
||||
|
||||
assertParse(
|
||||
[
|
||||
'<string>',
|
||||
'</string>'
|
||||
],
|
||||
"\n"
|
||||
);
|
||||
|
||||
assertParse(
|
||||
[
|
||||
'<string><foo></string>'
|
||||
],
|
||||
"<foo>"
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('Numbers', function() {
|
||||
assertParse(
|
||||
[
|
||||
'<integer>0</integer>'
|
||||
],
|
||||
0
|
||||
);
|
||||
|
||||
assertParse(
|
||||
[
|
||||
'<real>1.123</real>'
|
||||
],
|
||||
1.123
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
[
|
||||
'<integer>ab</integer>'
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('Booleans', function() {
|
||||
assertParse(
|
||||
[
|
||||
'<true />'
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
assertParse(
|
||||
[
|
||||
'<false />'
|
||||
],
|
||||
false
|
||||
);
|
||||
|
||||
assertParse(
|
||||
[
|
||||
'<false></false>'
|
||||
],
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('Dictionaries', function() {
|
||||
|
||||
// empty
|
||||
assertParse(
|
||||
[
|
||||
'<dict>',
|
||||
'</dict>'
|
||||
],
|
||||
{}
|
||||
);
|
||||
|
||||
// keys and nesting
|
||||
assertParse(
|
||||
[
|
||||
'<dict>',
|
||||
'<key>name</key>',
|
||||
'<string>Variable</string>',
|
||||
'<key>scope</key>',
|
||||
'<string>variable</string>',
|
||||
'<key>settings</key>',
|
||||
'<dict>',
|
||||
'<key>fontStyle</key>',
|
||||
'<string></string>',
|
||||
'</dict>',
|
||||
'</dict>'
|
||||
],
|
||||
{
|
||||
name: "Variable",
|
||||
scope: "variable",
|
||||
settings: {
|
||||
fontStyle: ""
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('Arrays', function() {
|
||||
|
||||
// empty
|
||||
assertParse(
|
||||
[
|
||||
'<array>',
|
||||
'</array>'
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
// multiple elements
|
||||
assertParse(
|
||||
[
|
||||
'<array>',
|
||||
'<string>1</string>',
|
||||
'<string>2</string>',
|
||||
'</array>'
|
||||
],
|
||||
[ "1", "2" ]
|
||||
);
|
||||
|
||||
// nesting
|
||||
assertParse(
|
||||
[
|
||||
'<array>',
|
||||
'<array>',
|
||||
'<integer>1</integer>',
|
||||
'<integer>2</integer>',
|
||||
'</array>',
|
||||
'<array>',
|
||||
'<true />',
|
||||
'</array>',
|
||||
'</array>'
|
||||
],
|
||||
[ [ 1, 2 ], [ true ]]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse a PLIST file using `sax`.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче