Skip to content

Commit

Permalink
output: support multiple option input
Browse files Browse the repository at this point in the history
  • Loading branch information
1Computer1 committed Jun 26, 2020
1 parent cf0c134 commit c00b3e4
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 28 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const res = parser.parse();
{ value: 'c', raw: 'c', trailing: '' }
],
flags: Set { 'foo' },
options: Map { 'bar' => 'baz' }
options: Map { 'bar' => ['baz'] }
}

Lexure.joinTokens(res.ordered)
Expand All @@ -88,7 +88,7 @@ args.flag('foo')
>>> true

args.option('bar')
>>> 'baz'
>>> ['baz']
```
See source code and tests for more usages and documentation.
7 changes: 4 additions & 3 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class Parser implements IterableIterator<ParserOutput> {
this.shift(1);

const output = emptyOutput();
output.options.set(o, '');
output.options.set(o, []);

const n = this.input[this.position];
if (n == null) {
Expand All @@ -99,7 +99,8 @@ export class Parser implements IterableIterator<ParserOutput> {

this.shift(1);

output.options.set(o, n.value);
const xs = output.options.get(o);
xs!.push(n.value);
return output;
}

Expand All @@ -113,7 +114,7 @@ export class Parser implements IterableIterator<ParserOutput> {
this.shift(1);

const output = emptyOutput();
output.options.set(o[0], o[1]);
output.options.set(o[0], [o[1]]);
return output;
}

Expand Down
18 changes: 12 additions & 6 deletions src/parserOutput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface ParserOutput {
/**
* The parsed options mapped to their value.
*/
options: Map<string, string>;
options: Map<string, string[]>;
}

/**
Expand Down Expand Up @@ -51,11 +51,17 @@ export function mergeOutputs(...ps: ParserOutput[]): ParserOutput {
}
}());

const options = new Map(function *() {
for (const p of ps) {
yield* p.options;
const options: Map<string, string[]> = new Map();
for (const p of ps) {
for (const [o, xs] of p.options.entries()) {
if (!options.has(o)) {
options.set(o, []);
}

const ys = options.get(o);
ys!.push(...xs);
}
}());
}

return { ordered, flags, options };
}
Expand Down Expand Up @@ -83,6 +89,6 @@ export function outputFromJSON(obj: Record<string, unknown>): ParserOutput {
return {
ordered: obj.ordered as Token[],
flags: new Set(obj.flags as string[]),
options: new Map(obj.options as [string, string][])
options: new Map(obj.options as [string, string[]][])
};
}
4 changes: 2 additions & 2 deletions test/args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('args', () => {

expect(args.flag('foo')).toEqual(true);
expect(args.flag('hello')).toEqual(false);
expect(args.option('bar')).toEqual('123');
expect(args.option('bar')).toEqual(['123']);
expect(args.option('world')).toEqual(null);
});

Expand All @@ -49,7 +49,7 @@ describe('args', () => {
expect(args.single()).toEqual(null);
expect(args.flag('foo')).toEqual(true);
expect(args.flag('hello')).toEqual(false);
expect(args.option('bar')).toEqual('123');
expect(args.option('bar')).toEqual(['123']);
expect(args.option('world')).toEqual(null);
});

Expand Down
4 changes: 2 additions & 2 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('readme', () => {
{ value: 'c', raw: 'c', trailing: '' }
],
flags: new Set(['foo']),
options: new Map([['bar', 'baz']])
options: new Map([['bar', ['baz']]])
});

const j = Lexure.joinTokens(res.ordered);
Expand All @@ -72,6 +72,6 @@ describe('readme', () => {
expect(a5).toEqual(true);

const a6 = args.option('bar');
expect(a6).toEqual('baz');
expect(a6).toEqual(['baz']);
});
});
26 changes: 18 additions & 8 deletions test/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('parser', () => {
expect(out).toEqual({
ordered: ts.slice(0, 2),
flags: new Set(),
options: new Map([['baz', 'quux']])
options: new Map([['baz', ['quux']]])
});
});

Expand All @@ -38,7 +38,7 @@ describe('parser', () => {
expect(out).toEqual({
ordered: ts.slice(0, 2),
flags: new Set(),
options: new Map([['baz', '']])
options: new Map([['baz', []]])
});
});

Expand All @@ -48,7 +48,7 @@ describe('parser', () => {
expect(out).toEqual({
ordered: ts.slice(0, 2),
flags: new Set(['foo']),
options: new Map([['baz', '']])
options: new Map([['baz', []]])
});
});

Expand All @@ -58,7 +58,17 @@ describe('parser', () => {
expect(out).toEqual({
ordered: ts.slice(0, 2),
flags: new Set(),
options: new Map([['baz', 'quux']])
options: new Map([['baz', ['quux']]])
});
});

it('should parse multiple same options', () => {
const ts = new Lexer('--foo=x --foo= y --foo=z').lex();
const out = new Parser(ts).setUnorderedStrategy(longStrategy()).parse();
expect(out).toEqual({
ordered: [],
flags: new Set(),
options: new Map([['foo', ['x', 'y', 'z']]])
});
});

Expand All @@ -68,7 +78,7 @@ describe('parser', () => {
expect(out).toEqual({
ordered: [ts[0], ts[5]],
flags: new Set(['foo']),
options: new Map([['bar', '123'], ['baz', 'quux']])
options: new Map([['bar', ['123']], ['baz', ['quux']]])
});
});

Expand All @@ -81,7 +91,7 @@ describe('parser', () => {
expect(out).toEqual({
ordered: [ts[0], ts[5]],
flags: new Set(['foo']),
options: new Map([['bar', '123'], ['baz', 'quux']])
options: new Map([['bar', ['123']], ['baz', ['quux']]])
});
});

Expand All @@ -92,8 +102,8 @@ describe('parser', () => {
expect(ps).toEqual([
{ ordered: [{ value: 'hello', raw: 'hello', trailing: ' ' }], flags: new Set(), options: new Map() },
{ ordered: [], flags: new Set(['foo']), options: new Map() },
{ ordered: [], flags: new Set(), options: new Map([['bar', '123']]) },
{ ordered: [], flags: new Set(), options: new Map([['baz', 'quux']]) },
{ ordered: [], flags: new Set(), options: new Map([['bar', ['123']]]) },
{ ordered: [], flags: new Set(), options: new Map([['baz', ['quux']]]) },
{ ordered: [{ value: 'world', raw: 'world', trailing: '' }], flags: new Set(), options: new Map() }
]);
});
Expand Down
10 changes: 5 additions & 5 deletions test/parserOutput.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('mergeOutputs', () => {
{ value: 'c', raw: 'c', trailing: '' }
],
flags: new Set(),
options: new Map([['bar', 'baz']])
options: new Map([['bar', ['baz']]])
};

expect(mergeOutputs(e, a, b)).toEqual({
Expand All @@ -33,7 +33,7 @@ describe('mergeOutputs', () => {
{ value: 'c', raw: 'c', trailing: '' }
],
flags: new Set(['foo']),
options: new Map([['bar', 'baz']])
options: new Map([['bar', ['baz']]])
});
});

Expand Down Expand Up @@ -68,7 +68,7 @@ describe('json conversion', () => {
{ value: 'c', raw: 'c', trailing: '' }
],
flags: new Set(['foo']),
options: new Map([['bar', 'baz']])
options: new Map([['bar', ['baz']]])
};

const b = {
Expand All @@ -80,7 +80,7 @@ describe('json conversion', () => {
{ value: 'c', raw: 'c', trailing: '' }
],
flags: ['foo'],
options: [['bar', 'baz']]
options: [['bar', ['baz']]]
};

expect(outputToJSON(a)).toEqual(b);
Expand All @@ -104,7 +104,7 @@ describe('json conversion', () => {
});

const genOutput: fc.Arbitrary<ParserOutput> =
fc.tuple(fc.array(fc.string()), fc.array(fc.string()), fc.array(fc.tuple(fc.string(), fc.string())))
fc.tuple(fc.array(fc.string()), fc.array(fc.string()), fc.array(fc.tuple(fc.string(), fc.array(fc.string()))))
.map(([ws, fs, os]) => ({
ordered: ws.map(w => ({ value: w, raw: w, trailing: ' ' })),
flags: new Set(fs),
Expand Down

0 comments on commit c00b3e4

Please sign in to comment.