Skip to content

Commit

Permalink
fix: list and set NUTs
Browse files Browse the repository at this point in the history
  • Loading branch information
iowillhoit committed Sep 27, 2022
1 parent d89d967 commit 667d294
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 12 deletions.
4 changes: 0 additions & 4 deletions messages/alias.set.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ Set one or more aliases.

You can associate an alias with only one value at a time. If you’ve set an alias multiple times, the alias points to the most recent value.

# flags.name.summary

Description of a flag.

# examples

- <%= config.bin %> <%= command.id %>
Expand Down
15 changes: 10 additions & 5 deletions src/commands/alias/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
*/

import { SfCommand } from '@salesforce/sf-plugins-core';
import { Nullable } from '@salesforce/ts-types';
import { StateAggregator, Messages } from '@salesforce/core';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.load('@salesforce/plugin-settings', 'alias.list', ['summary', 'description', 'examples']);

type AliasListResult = {
export type AliasListResult = {
alias: string;
value?: Nullable<string>;
value: string;
};

export default class AliasList extends SfCommand<AliasListResult[]> {
Expand All @@ -24,7 +23,7 @@ export default class AliasList extends SfCommand<AliasListResult[]> {

public async run(): Promise<AliasListResult[]> {
const stateAggregator = await StateAggregator.getInstance();
const aliases = stateAggregator.aliases.getAll() || {};
const aliases = stateAggregator.aliases.getAll();

const results = Object.keys(aliases).map((key) => ({ alias: key, value: aliases[key] }));

Expand All @@ -33,7 +32,13 @@ export default class AliasList extends SfCommand<AliasListResult[]> {
value: { header: 'Value' },
};

this.table(results, columns, { title: 'List Aliases' });
// TODO: Add an "no results" option to ux.table?
if (results.length === 0) {
// TODO: Should this be a 'log' or 'warn'? A warn will show up in the json `warnings` array
this.warn('No aliases found');
} else {
this.table(results, columns, { title: 'Alias List', 'no-truncate': true });
}

return results;
}
Expand Down
7 changes: 4 additions & 3 deletions src/commands/alias/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const messages = Messages.load('@salesforce/plugin-settings', 'alias.set', [
'error.ValueRequired',
]);

type AliasSetResult = {
export type AliasSetResult = {
alias: string;
value?: Nullable<string>;
};
Expand All @@ -31,13 +31,14 @@ export default class AliasSet extends SfCommand<AliasSetResult[]> {
public static examples = messages.getMessages('examples');

// This allows varargs
// TODO: This causes issues with flag spelling mistakes. Typing `bin/dev alias set --hekp` takes '--hekp' as an arg and not an unknown flag
public static readonly strict = false;

public async run(): Promise<AliasSetResult[]> {
const stateAggregator = await StateAggregator.getInstance();
// TODO: add success: true ?
// TODO: add example of `alias set foo bar` to both alias and config
// TODO: add error to `config:set`
// TODO: add error to `config set`
const args = await this.parseConfigKeysAndValues();

const results = Object.keys(args).map((key) => {
Expand All @@ -53,7 +54,7 @@ export default class AliasSet extends SfCommand<AliasSetResult[]> {
value: { header: 'Value' },
};

this.table(results, columns, { title: 'Set Aliases' });
this.table(results, columns, { title: 'Alias Set' });

return results;
}
Expand Down
109 changes: 109 additions & 0 deletions test/commands/alias/list.nut.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import * as os from 'os';
import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
import { expect } from 'chai';

function unsetAll() {
execCmd('sf alias unset DevHub');
execCmd('sf alias unset Admin');
execCmd('sf alias unset user');
}

describe('alias list NUTs', () => {
let session: TestSession;

before(async () => {
session = await TestSession.create({
project: { name: 'aliasListNUTs' },
authStrategy: 'NONE',
});
});

after(async () => {
await session?.clean();
});

describe('alias list without results', () => {
beforeEach(() => {
unsetAll();
});

it('lists no aliases correctly', () => {
const { result } = execCmd('alias list --json', { ensureExitCode: 0 }).jsonOutput;
expect(result).to.deep.equal([]);
});

it('lists no aliases stdout', () => {
const res: string = execCmd('alias list').shellOutput;
expect(res).to.include('No aliases found');
});
});

describe('alias list with singular result', () => {
beforeEach(() => {
unsetAll();
execCmd('alias set [email protected]');
});

it('lists singular alias correctly', () => {
const { result } = execCmd('alias list --json', { ensureExitCode: 0 }).jsonOutput;
expect(result).to.deep.equal([
{
alias: 'DevHub',
value: '[email protected]',
},
]);
});

it('lists singular result correctly stdout', () => {
const res: string = execCmd('alias list', { ensureExitCode: 0 }).shellOutput;
expect(res).to.include(`Alias List${os.EOL}=====`); // Table header
expect(res).to.include('DevHub');
expect(res).to.include('[email protected]');
});
});

describe('alias list with multiple results', () => {
beforeEach(() => {
unsetAll();
execCmd('alias set [email protected]');
execCmd('alias set [email protected]');
execCmd('alias set [email protected]');
});

it('lists multiple results correctly JSON', () => {
const { result } = execCmd('alias list --json', { ensureExitCode: 0 }).jsonOutput;
expect(result).to.deep.equal([
{
alias: 'DevHub',
value: '[email protected]',
},
{
alias: 'Admin',
value: '[email protected]',
},
{
alias: 'user',
value: '[email protected]',
},
]);
});

it('lists multiple results correctly stdout', () => {
const res: string = execCmd('alias list', { ensureExitCode: 0 }).shellOutput;
expect(res).to.include(`Alias List${os.EOL}=====`); // Table header
expect(res).to.include('DevHub');
expect(res).to.include('[email protected]');
expect(res).to.include('Admin');
expect(res).to.include('[email protected]');
expect(res).to.include('user');
expect(res).to.include('[email protected]');
});
});
});
132 changes: 132 additions & 0 deletions test/commands/alias/set.nut.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import * as os from 'os';
import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
import { getNumber, getString } from '@salesforce/ts-types';
import { expect } from 'chai';
import { Messages } from '@salesforce/core';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.load('@salesforce/plugin-settings', 'alias.set', [
// 'summary',
// 'description',
// 'examples',
'error.ArgumentsRequired',
// 'error.DuplicateArgument',
// 'error.InvalidArgumentFormat',
'error.ValueRequired',
]);

function unsetAll() {
execCmd('alias unset DevHub Admin user');
}

describe('alias set NUTs', () => {
let session: TestSession;

before(async () => {
session = await TestSession.create({
project: { name: 'aliasSetNUTs' },
authStrategy: 'NONE',
});
});

after(async () => {
await session?.clean();
});

describe('initial alias setup', () => {
beforeEach(() => {
unsetAll();
});

it('alias set multiple values and json', () => {
const { result } = execCmd('alias set [email protected] [email protected] --json', {
ensureExitCode: 0,
}).jsonOutput;

expect(result).to.deep.equal([
{ alias: 'DevHub', value: '[email protected]' },
{ alias: 'Admin', value: '[email protected]' },
]);
});

it('alias set multiple values stdout', () => {
const res: string = execCmd('alias set [email protected] [email protected]', {
ensureExitCode: 0,
}).shellOutput;

expect(res).to.include(`Alias Set${os.EOL}=====`); // Table header
expect(res).to.include('Alias Value');
expect(res).to.include('DevHub');
expect(res).to.include('[email protected]');
expect(res).to.include('Admin');
expect(res).to.include('[email protected]');
});
});

describe('alias set overwrites existing entry', () => {
beforeEach(() => {
unsetAll();
execCmd('alias set [email protected]');
});

it('alias set overwrites existing entry correctly json', () => {
// overwriting DevHub entry to point to newdevhub
const { result } = execCmd('alias set [email protected] [email protected] --json', {
ensureExitCode: 0,
}).jsonOutput;

expect(result).to.deep.equal([
// newdevhub verified
{ alias: 'DevHub', value: '[email protected]' },
{ alias: 'Admin', value: '[email protected]' },
]);
});

it('alias set overwrites entry correctly stdout', () => {
const res: string = execCmd('alias set [email protected] [email protected]', {
ensureExitCode: 0,
}).shellOutput;
expect(res).to.include(`Alias Set${os.EOL}=====`); // Table header
expect(res).to.include('Alias Value');
expect(res).to.include('DevHub');
expect(res).to.include('[email protected]');
expect(res).to.include('Admin');
expect(res).to.include('[email protected]');
});

it('alias set DevHub= shows error to use alias unset command', () => {
const res = execCmd('alias set DevHub=', {
ensureExitCode: 1,
}).shellOutput.stderr;

expect(res).to.include(messages.getMessages('error.ValueRequired'));
});
});

describe('alias set without varargs throws error', () => {
it('alias set --json', () => {
// access each member individually because the stack trace will be different
const res = execCmd('alias set --json');
expect(getNumber(res.jsonOutput, 'status')).to.equal(1);
expect(getString(res.jsonOutput, 'name')).to.equal('ArgumentsRequiredError');
expect(getString(res.jsonOutput, 'stack')).to.contain('ArgumentsRequiredError');
expect(getString(res.jsonOutput, 'message')).to.include(messages.getMessages('error.ArgumentsRequired'));
expect(getNumber(res.jsonOutput, 'exitCode')).to.equal(1);
});

it('alias set without varargs stdout', () => {
const res: string = execCmd('alias set', {
ensureExitCode: 1,
}).shellOutput.stderr;

expect(res).to.include(messages.getMessages('error.ArgumentsRequired'));
});
});
});

0 comments on commit 667d294

Please sign in to comment.