Skip to content

Commit 4d88437

Browse files
committed
fix: allow --variable-type flag to accept multiple values
1 parent b474704 commit 4d88437

File tree

3 files changed

+131
-5
lines changed

3 files changed

+131
-5
lines changed

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
- Follow the Arrange, Act, Assert structure when writing unit tests.
44
- When writing unit tests, create individual unit tests that cover each logical branching in the code.
5-
- For the happy path, can we have a single unit test where in the all the top level if conditions are executed? Maybe this might help with reducing the number of total unit tests created and still give same test coverage.
5+
- For the happy path, can we have a single unit test where all the top level if conditions are executed? This might help with reducing the number of total unit tests created and still give same test coverage.
66
- For the tests for edge cases do not create separate describe blocks, keep the hierarchy flat.
77
- For the tests for edge cases, do not skip assertions, its still worth adding all assertions similar to the happy paths tests.
88

src/adapters/base-class.test.ts

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,120 @@ describe('BaseClass', () => {
125125
);
126126
});
127127

128+
it('should handle two options: Import from stack and Manually add variables', async () => {
129+
baseClass = new BaseClass({
130+
log: logMock,
131+
exit: exitMock,
132+
config: {
133+
variableType: ['Import variables from a stack', 'Manually add custom variables to the list'],
134+
variablePreparationTypeOptions: config.variablePreparationTypeOptions,
135+
},
136+
} as any);
137+
138+
const importEnvFromStackMock = jest.spyOn(baseClass, 'importEnvFromStack').mockResolvedValueOnce();
139+
const promptForEnvValuesMock = jest.spyOn(baseClass, 'promptForEnvValues').mockResolvedValueOnce();
140+
141+
await baseClass.handleEnvImportFlow();
142+
143+
expect(importEnvFromStackMock).toHaveBeenCalled();
144+
expect(promptForEnvValuesMock).toHaveBeenCalled();
145+
expect(exitMock).not.toHaveBeenCalled();
146+
});
147+
148+
it('should handle two options: Import from stack and Import from .env.local', async () => {
149+
baseClass = new BaseClass({
150+
log: logMock,
151+
exit: exitMock,
152+
config: {
153+
variableType: ['Import variables from a stack', 'Import variables from the .env.local file'],
154+
variablePreparationTypeOptions: config.variablePreparationTypeOptions,
155+
},
156+
} as any);
157+
158+
const importEnvFromStackMock = jest.spyOn(baseClass, 'importEnvFromStack').mockResolvedValueOnce();
159+
const importVariableFromLocalConfigMock = jest
160+
.spyOn(baseClass, 'importVariableFromLocalConfig')
161+
.mockResolvedValueOnce();
162+
163+
await baseClass.handleEnvImportFlow();
164+
165+
expect(importEnvFromStackMock).toHaveBeenCalled();
166+
expect(importVariableFromLocalConfigMock).toHaveBeenCalled();
167+
expect(exitMock).not.toHaveBeenCalled();
168+
});
169+
170+
it('should handle two options: Manually add and Import from .env.local', async () => {
171+
baseClass = new BaseClass({
172+
log: logMock,
173+
exit: exitMock,
174+
config: {
175+
variableType: ['Manually add custom variables to the list', 'Import variables from the .env.local file'],
176+
variablePreparationTypeOptions: config.variablePreparationTypeOptions,
177+
},
178+
} as any);
179+
180+
const promptForEnvValuesMock = jest.spyOn(baseClass, 'promptForEnvValues').mockResolvedValueOnce();
181+
const importVariableFromLocalConfigMock = jest
182+
.spyOn(baseClass, 'importVariableFromLocalConfig')
183+
.mockResolvedValueOnce();
184+
185+
await baseClass.handleEnvImportFlow();
186+
187+
expect(promptForEnvValuesMock).toHaveBeenCalled();
188+
expect(importVariableFromLocalConfigMock).toHaveBeenCalled();
189+
expect(exitMock).not.toHaveBeenCalled();
190+
});
191+
192+
it('should handle all three options: Import from stack, Manually add, and Import from .env.local', async () => {
193+
baseClass = new BaseClass({
194+
log: logMock,
195+
exit: exitMock,
196+
config: {
197+
variableType: [
198+
'Import variables from a stack',
199+
'Manually add custom variables to the list',
200+
'Import variables from the .env.local file',
201+
],
202+
variablePreparationTypeOptions: config.variablePreparationTypeOptions,
203+
},
204+
} as any);
205+
206+
const importEnvFromStackMock = jest.spyOn(baseClass, 'importEnvFromStack').mockResolvedValueOnce();
207+
const promptForEnvValuesMock = jest.spyOn(baseClass, 'promptForEnvValues').mockResolvedValueOnce();
208+
const importVariableFromLocalConfigMock = jest
209+
.spyOn(baseClass, 'importVariableFromLocalConfig')
210+
.mockResolvedValueOnce();
211+
212+
await baseClass.handleEnvImportFlow();
213+
214+
expect(importEnvFromStackMock).toHaveBeenCalled();
215+
expect(promptForEnvValuesMock).toHaveBeenCalled();
216+
expect(importVariableFromLocalConfigMock).toHaveBeenCalled();
217+
expect(exitMock).not.toHaveBeenCalled();
218+
});
219+
220+
it('should fail when Skip is combined with other options', async () => {
221+
baseClass = new BaseClass({
222+
log: logMock,
223+
exit: exitMock,
224+
config: {
225+
variableType: ['Skip adding environment variables', 'Import variables from a stack'],
226+
variablePreparationTypeOptions: config.variablePreparationTypeOptions,
227+
},
228+
} as any);
229+
230+
const importEnvFromStackMock = jest.spyOn(baseClass, 'importEnvFromStack').mockResolvedValueOnce(undefined);
231+
232+
await baseClass.handleEnvImportFlow();
233+
234+
expect(logMock).toHaveBeenCalledWith(
235+
"The 'Skip adding environment variables' option cannot be combined with other environment variable options. Please choose either 'Skip adding environment variables' or one or more of the other available options.",
236+
'error',
237+
);
238+
expect(exitMock).toHaveBeenCalledWith(1);
239+
expect(importEnvFromStackMock).toHaveBeenCalled();
240+
});
241+
128242
it('should exit if no options are selected', async () => {
129243
(ux.inquire as jest.Mock).mockResolvedValueOnce([]);
130244

@@ -138,21 +252,30 @@ describe('BaseClass', () => {
138252
});
139253

140254
it('should exit if "Skip adding environment variables" is selected with other options', async () => {
255+
const exitMockWithThrow = jest.fn().mockImplementation(() => {
256+
throw new Error('Exit called');
257+
});
258+
baseClass = new BaseClass({
259+
log: logMock,
260+
exit: exitMockWithThrow,
261+
config: config.variablePreparationTypeOptions,
262+
} as any);
263+
141264
const importEnvFromStackMock = jest.spyOn(baseClass, 'importEnvFromStack').mockResolvedValueOnce();
142265
(ux.inquire as jest.Mock).mockResolvedValueOnce([
143266
'Skip adding environment variables',
144267
'Import variables from a stack',
145268
]);
146269

147-
await baseClass.handleEnvImportFlow();
270+
await expect(baseClass.handleEnvImportFlow()).rejects.toThrow('Exit called');
148271

149272
expect(logMock).toHaveBeenCalledWith(
150273
"The 'Skip adding environment variables' option cannot be combined with other environment variable options. Please choose either 'Skip adding environment variables' or one or more of the other available options.",
151274
'error',
152275
);
153276

154-
expect(exitMock).toHaveBeenCalledWith(1);
155-
expect(importEnvFromStackMock).toHaveBeenCalled();
277+
expect(exitMockWithThrow).toHaveBeenCalledWith(1);
278+
expect(importEnvFromStackMock).not.toHaveBeenCalled();
156279
});
157280

158281
it('should call importEnvFromStack if "Import variables from a stack" is selected', async () => {

src/commands/launch/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export default class Launch extends BaseCommand<typeof Launch> {
2929
'<%= config.bin %> <%= command.id %> --config <path/to/launch/config/file> --type <options: GitHub|FileUpload> --name=<value> --environment=<value> --branch=<value> --build-command=<value> --framework=<option> --org=<value> --out-dir=<value> --variable-type="Import variables from a stack" --alias=<value>',
3030
// eslint-disable-next-line max-len
3131
'<%= config.bin %> <%= command.id %> --config <path/to/launch/config/file> --type <options: GitHub|FileUpload> --name=<value> --environment=<value> --branch=<value> --build-command=<value> --framework=<option> --org=<value> --out-dir=<value> --variable-type="Manually add custom variables to the list" --env-variables="APP_ENV:prod, TEST_ENV:testVal"',
32+
// eslint-disable-next-line max-len
33+
'<%= config.bin %> <%= command.id %> --config <path/to/launch/config/file> --type <options: GitHub|FileUpload> --name=<value> --environment=<value> --branch=<value> --build-command=<value> --framework=<option> --org=<value> --out-dir=<value> --variable-type="Import variables from a stack" --variable-type="Manually add custom variables to the list" --alias=<value>',
3234
];
3335

3436
static flags: FlagInput = {
@@ -64,10 +66,11 @@ export default class Launch extends BaseCommand<typeof Launch> {
6466
description: '[optional] Server Command.',
6567
}),
6668
'variable-type': Flags.string({
69+
multiple: true,
6770
options: [...config.variablePreparationTypeOptions],
6871
description:
6972
// eslint-disable-next-line max-len
70-
'[optional] Provide a variable type. <options: Import variables from a stack|Manually add custom variables to the list|Import variables from the .env.local file|Skip adding environment variables>',
73+
'[optional] Provide a variable type (can specify multiple times). <options: Import variables from a stack|Manually add custom variables to the list|Import variables from the .env.local file|Skip adding environment variables>',
7174
}),
7275
'show-variables': Flags.boolean({
7376
hidden: true,

0 commit comments

Comments
 (0)