From 45c7eb568c5db301a0f90b7cc86678f0a58adefc Mon Sep 17 00:00:00 2001 From: Munif Tanjim Date: Wed, 27 May 2020 12:24:41 +0600 Subject: [PATCH] feat: support multiple filter flags for table --- src/styled/table.ts | 32 +++++++++++++++++--------------- test/styled/table.test.ts | 14 +++++++++++--- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/styled/table.ts b/src/styled/table.ts index 1b4c123b..71aeaeaa 100644 --- a/src/styled/table.ts +++ b/src/styled/table.ts @@ -58,18 +58,20 @@ class Table { }) // filter rows - if (this.options.filter) { - /* eslint-disable-next-line prefer-const */ - let [header, regex] = this.options.filter!.split('=') - const isNot = header[0] === '-' - if (isNot) header = header.substr(1) - const col = this.findColumnFromHeader(header) - if (!col || !regex) throw new Error('Filter flag has an invalid value') - rows = rows.filter((d: any) => { - const re = new RegExp(regex) - const val = d[col!.key] - const match = val.match(re) - return isNot ? !match : match + if (!_.isEmpty(this.options.filter)) { + this.options.filter!.forEach(filter => { + /* eslint-disable-next-line prefer-const */ + let [header, regex] = filter.split('=') + const isNot = header[0] === '-' + if (isNot) header = header.substr(1) + const col = this.findColumnFromHeader(header) + if (!col || !regex) throw new Error('Filter flag has an invalid value') + rows = rows.filter((d: any) => { + const re = new RegExp(regex) + const val = d[col!.key] + const match = re.test(val) + return isNot ? !match : match + }) }) } @@ -288,7 +290,7 @@ export namespace table { export const Flags: { columns: F.IOptionFlag; sort: F.IOptionFlag; - filter: F.IOptionFlag; + filter: F.IOptionFlag; csv: F.IFlag; output: F.IOptionFlag; extended: F.IFlag; @@ -297,7 +299,7 @@ export namespace table { } = { columns: F.string({exclusive: ['extended'], description: 'only show provided columns (comma-separated)'}), sort: F.string({description: 'property to sort by (prepend \'-\' for descending)'}), - filter: F.string({description: 'filter property by partial string matching, ex: name=foo'}), + filter: F.string({description: 'filter property by partial string matching, ex: name=foo', multiple: true}), csv: F.boolean({exclusive: ['no-truncate'], description: 'output is csv format [alias: --output=csv]'}), output: F.string({ exclusive: ['no-truncate', 'csv'], @@ -345,7 +347,7 @@ export namespace table { export interface Options { [key: string]: any; sort?: string; - filter?: string; + filter?: string[]; columns?: string; extended?: boolean; 'no-truncate'?: boolean; diff --git a/test/styled/table.test.ts b/test/styled/table.test.ts index 1d03fa0f..655c4a24 100644 --- a/test/styled/table.test.ts +++ b/test/styled/table.test.ts @@ -233,16 +233,24 @@ describe('styled/table', () => { fancy .stdout() .end('filters by property & value (partial string match)', output => { - cli.table(apps, columns, {filter: 'id=123'}) + cli.table(apps, columns, {filter: ['id=123']}) expect(output.stdout).to.equal(`ID Name${ws.padEnd(14)} 123 supertable-test-1${ws}\n`) }) + fancy + .stdout() + .end('filters by multiple properties & values', output => { + cli.table(apps, {...columns, sid: {header: 'SID', get: (r: any) => r.stack && r.stack.id}}, {filter: ['id=\\d2\\d', '-sid=321']}) + expect(output.stdout).to.equal(`ID Name${ws.padEnd(12)} SID${ws} +123 supertable-test-1 123${ws}\n`) + }) + fancy .stdout() .end('does not truncate', output => { const three = {...apps[0], id: '0'.repeat(80), name: 'supertable-test-3'} - cli.table(apps.concat(three), columns, {filter: 'id=0', 'no-truncate': true}) + cli.table(apps.concat(three), columns, {filter: ['id=0'], 'no-truncate': true}) expect(output.stdout).to.equal(`ID${ws.padEnd(78)} Name${ws.padEnd(14)} ${three.id} supertable-test-3${ws}\n`) }) @@ -268,7 +276,7 @@ ${three.id} supertable-test-3${ws}\n`) fancy .stdout() .end('ignores header case', output => { - cli.table(apps, columns, {columns: 'iD,Name', filter: 'nAMe=supertable-test', sort: '-ID'}) + cli.table(apps, columns, {columns: 'iD,Name', filter: ['nAMe=supertable-test'], sort: '-ID'}) expect(output.stdout).to.equal(`ID Name${ws.padEnd(14)} 321 supertable-test-2${ws} 123 supertable-test-1${ws}\n`)