Skip to content

Commit

Permalink
refactoring and new functional
Browse files Browse the repository at this point in the history
  • Loading branch information
Sdju committed Dec 22, 2020
1 parent c9a8ac6 commit fa17efb
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 15 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"husky": "^4.2.3",
"jest": "^22.4.3",
"ts-jest": "^22.4.2",
"typescript": "3.4.3"
"typescript": "^4.1.3"
},
"jest": {
"globals": {
Expand All @@ -50,7 +50,7 @@
"^.+\\.(ts|tsx)$": "ts-jest"
},
"testMatch": [
"**/test/*.+(ts|tsx|js)"
"**/test/**/*.+(ts|tsx|js)"
],
"moduleFileExtensions": [
"ts",
Expand Down
1 change: 1 addition & 0 deletions src/errors/errors-symbol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const $Errors: unique symbol = Symbol('Errors of parsing');
3 changes: 3 additions & 0 deletions src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './parsing-error';
export * from './proto-error';
export * from './errors-symbol';
4 changes: 1 addition & 3 deletions src/errors.ts → src/errors/parsing-error.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
export const $Errors: unique symbol = Symbol('Errors of parsing');

export class ParsingError extends Error {
constructor(line: string, lineNumber: number) {
super(`Unsupported type of line: [${lineNumber}]"${line}"`);
super(`Unsupported type of line: [${lineNumber}] "${line}"`);
this.line = line;
this.lineNumber = lineNumber;
}
Expand Down
8 changes: 8 additions & 0 deletions src/errors/proto-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export class ProtoError extends Error {
constructor(lineNumber: number) {
super(`Unsupported section name "__proto__": [${lineNumber}]"`);
this.lineNumber = lineNumber;
}

public lineNumber: number;
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './errors';
export * from './parse';
export * from './stringify';
export * from './proto';
2 changes: 1 addition & 1 deletion src/interfaces/custom-typing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export interface ICustomTyping {
(val: string, section: string, key: string): any
(val: string, section: string | symbol, key: string): any
}
2 changes: 2 additions & 0 deletions src/interfaces/ini-object.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { $Errors, ParsingError } from '../errors';
import { IIniObjectSection } from './ini-object-section';
import { $Proto } from '../proto';

export interface IIniObject extends IIniObjectSection {
[$Errors]?: ParsingError[];
[$Proto]?: IIniObjectSection;
}
18 changes: 16 additions & 2 deletions src/parse.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { $Errors, ParsingError } from './errors';
import {
$Errors,
ParsingError,
ProtoError,
} from './errors';
import { IIniObject } from './interfaces/ini-object';
import { IniValue } from './types/ini-value';
import { IIniObjectSection } from './interfaces/ini-object-section';
import { autoType } from './helpers/auto-type';
import { ICustomTyping } from './interfaces/custom-typing';
import { $Proto } from './proto';

export interface IParseConfig {
comment?: string;
delimiter?: string;
nothrow?: boolean;
autoTyping?: boolean | ICustomTyping;
dataSections?: string[];
protoSymbol?: boolean;
}

const sectionNameRegex = /\[(.*)]$/;
Expand All @@ -22,6 +28,7 @@ export function parse(data: string, params?: IParseConfig): IIniObject {
nothrow = false,
autoTyping = true,
dataSections = [],
protoSymbol = false,
} = { ...params };
let typeParser: ICustomTyping;
if (typeof autoTyping === 'function') {
Expand All @@ -45,9 +52,16 @@ export function parse(data: string, params?: IParseConfig): IIniObject {
const match = line.match(sectionNameRegex);
if (match !== null) {
currentSection = match[1].trim();
if (currentSection === '__proto__') {
if (protoSymbol) {
currentSection = <string><any> $Proto;
} else {
throw new ProtoError(lineNumber);
}
}
isDataSection = dataSections.includes(currentSection);
if (!(currentSection in result)) {
result[currentSection] = (isDataSection) ? [] : {};
result[currentSection] = (isDataSection) ? [] : Object.create(null);
}
continue;
}
Expand Down
1 change: 1 addition & 0 deletions src/proto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const $Proto: unique symbol = Symbol('__proto__');
67 changes: 64 additions & 3 deletions test/tests.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import { parse, stringify } from '../src';
import {
parse,
stringify,
$Proto,
$Errors,
ParsingError,
} from '../src';

const ini1 = `v1 = 2
v-2=true
v 3 = string
[smbd]
v1=5
v2 = what
v2 = what
;comment
v5 = who is who = who
[test scope with spaces]
mgm*1 = 2.5`;

const ini2 = `v1 : 2
v-2:true
v 3 : string
[smbd]
v1:5
v2 : what
v2 : what
#comment
v5 : who is who = who
[test scope with spaces]
mgm*1 : 2.5`;

const ini3 = `v1=2
v-2=true
v 3=string
Expand All @@ -33,6 +41,7 @@ v5=who is who = who
[test scope with spaces]
mgm*1=2.5`;

const ini4 = `v1: 2
v-2: true
v 3: string
Expand All @@ -42,6 +51,7 @@ v2: what
v5: who is who = who
[test scope with spaces]
mgm*1: 2.5`;

const ini5 = `v1: 2
v-2: true
v 3: string
Expand All @@ -53,6 +63,24 @@ v1: 5
b1c,wdwd,15:68
wx/w':wwdlw,:d,wld
efkeofk`;

const ini6 = `
[ __proto__ ]
polluted = "polluted"`;

const ini7 = `
[scope with trash]
ok = value
trash
[scope with only trash]
only trash
[empty scope]
[normal scope]
ok = value
`;

const v1 = {
v1: 2,
'v-2': true,
Expand Down Expand Up @@ -153,3 +181,36 @@ test('ini stringify', () => {
autoTyping: false,
})).toEqual(v3);
});

test('ini parsing: proto', () => {
expect(() => parse(ini6))
.toThrow('Unsupported section name "__proto__": [2]"');

expect(parse(ini6, { protoSymbol: true }))
.toEqual({
[$Proto]: {
polluted: '"polluted"',
},
});
});

test('ini parsing: errors', () => {
expect(() => parse(ini7))
.toThrow('Unsupported type of line: [4] "trash"');

expect(parse(ini7, { nothrow: true }))
.toEqual({
'scope with trash': {
ok: 'value',
},
'scope with only trash': {},
'empty scope': {},
'normal scope': {
ok: 'value',
},
[$Errors]: [
new ParsingError('trash', 4),
new ParsingError('only trash', 7),
],
});
});

0 comments on commit fa17efb

Please sign in to comment.