From a74836844f7000fb6c745829666284cb98d656a5 Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Wed, 16 Oct 2024 12:06:35 -0500 Subject: [PATCH 1/3] NEW @W-16891765@ Config action mentions outfile --- messages/action-summary-viewer.md | 15 ++++ src/commands/code-analyzer/config.ts | 2 + src/lib/actions/ConfigAction.ts | 11 ++- src/lib/messages.ts | 1 + src/lib/viewers/ActionSummaryViewer.ts | 49 ++++++++++++ src/lib/writers/ConfigWriter.ts | 7 +- test/commands/code-analyzer/config.test.ts | 3 + .../no-outfile-created.txt.goldfile | 5 ++ .../outfile-created.txt.goldfile | 6 ++ test/lib/actions/ConfigAction.test.ts | 75 ++++++++++++++++++- test/lib/writers/ConfigWriter.test.ts | 6 +- test/stubs/SpyConfigWriter.ts | 9 ++- 12 files changed, 179 insertions(+), 10 deletions(-) create mode 100644 messages/action-summary-viewer.md create mode 100644 src/lib/viewers/ActionSummaryViewer.ts create mode 100644 test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile create mode 100644 test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile diff --git a/messages/action-summary-viewer.md b/messages/action-summary-viewer.md new file mode 100644 index 000000000..ec334bec0 --- /dev/null +++ b/messages/action-summary-viewer.md @@ -0,0 +1,15 @@ +# common.summary-header + +Summary + +# common.logfile-location + +Additional log information written to: + +# config-action.no-outfiles + +No output file was specified. + +# config-action.outfile-location + +Config written to: diff --git a/src/commands/code-analyzer/config.ts b/src/commands/code-analyzer/config.ts index 55b9c4f1d..04459fdeb 100644 --- a/src/commands/code-analyzer/config.ts +++ b/src/commands/code-analyzer/config.ts @@ -2,6 +2,7 @@ import {Flags, SfCommand} from '@salesforce/sf-plugins-core'; import {ConfigAction, ConfigDependencies} from '../../lib/actions/ConfigAction'; import {ConfigFileWriter} from '../../lib/writers/ConfigWriter'; import {ConfigStyledYamlViewer} from '../../lib/viewers/ConfigViewer'; +import {ConfigActionSummaryViewer} from '../../lib/viewers/ActionSummaryViewer'; import {CodeAnalyzerConfigFactoryImpl} from '../../lib/factories/CodeAnalyzerConfigFactory'; import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory'; import {BundleName, getMessage, getMessages} from '../../lib/messages'; @@ -70,6 +71,7 @@ export default class ConfigCommand extends SfCommand implements Displayabl logEventListeners: [new LogEventDisplayer(uxDisplay)], progressEventListeners: [new RuleSelectionProgressSpinner(uxDisplay)], modelGenerator: modelGeneratorFunction, + actionSummaryViewer: new ConfigActionSummaryViewer(uxDisplay), viewer: new ConfigStyledYamlViewer(uxDisplay) }; if (outputFile) { diff --git a/src/lib/actions/ConfigAction.ts b/src/lib/actions/ConfigAction.ts index 6f7711d42..e588334ae 100644 --- a/src/lib/actions/ConfigAction.ts +++ b/src/lib/actions/ConfigAction.ts @@ -7,6 +7,7 @@ import {ConfigViewer} from '../viewers/ConfigViewer'; import {createWorkspace} from '../utils/WorkspaceUtil'; import {LogEventListener, LogEventLogger} from '../listeners/LogEventListener'; import {ProgressEventListener} from '../listeners/ProgressEventListener'; +import {ConfigActionSummaryViewer} from '../viewers/ActionSummaryViewer'; import {ConfigModel, ConfigModelGeneratorFunction, ConfigContext} from '../models/ConfigModel'; export type ConfigDependencies = { @@ -16,11 +17,13 @@ export type ConfigDependencies = { logEventListeners: LogEventListener[]; progressEventListeners: ProgressEventListener[]; writer?: ConfigWriter; + actionSummaryViewer: ConfigActionSummaryViewer; viewer: ConfigViewer; }; export type ConfigInput = { 'config-file'?: string; + 'output-file'?: string; 'rule-selector': string[]; workspace?: string[]; }; @@ -38,7 +41,8 @@ export class ConfigAction { const defaultConfig: CodeAnalyzerConfig = CodeAnalyzerConfig.withDefaults(); // We always add a Logger Listener to the appropriate listeners list, because we should always be logging. - const logEventLogger: LogEventLogger = new LogEventLogger(await LogFileWriter.fromConfig(userConfig)); + const logFileWriter: LogFileWriter = await LogFileWriter.fromConfig(userConfig); + const logEventLogger: LogEventLogger = new LogEventLogger(logFileWriter); this.dependencies.logEventListeners.push(logEventLogger); // The User's config produces one Core. @@ -118,7 +122,10 @@ export class ConfigAction { const configModel: ConfigModel = this.dependencies.modelGenerator(relevantEngines, userConfigContext, defaultConfigContext); this.dependencies.viewer.view(configModel); - await this.dependencies.writer?.write(configModel); + const fileWritten: boolean = this.dependencies.writer + ? await this.dependencies.writer.write(configModel) + : false; + this.dependencies.actionSummaryViewer.view(logFileWriter.getLogDestination(), fileWritten ? input['output-file'] : undefined); return Promise.resolve(); } diff --git a/src/lib/messages.ts b/src/lib/messages.ts index 6d7edc4cb..218091880 100644 --- a/src/lib/messages.ts +++ b/src/lib/messages.ts @@ -5,6 +5,7 @@ import {Tokens} from '@salesforce/core/lib/messages'; Messages.importMessagesDirectory(__dirname); export enum BundleName { + ActionSummaryViewer = 'action-summary-viewer', ConfigCommand = 'config-command', ConfigModel = 'config-model', ConfigWriter = 'config-writer', diff --git a/src/lib/viewers/ActionSummaryViewer.ts b/src/lib/viewers/ActionSummaryViewer.ts new file mode 100644 index 000000000..0754696d2 --- /dev/null +++ b/src/lib/viewers/ActionSummaryViewer.ts @@ -0,0 +1,49 @@ +import {Display} from '../Display'; +import {toStyledHeader, indent} from '../utils/StylingUtil'; +import {BundleName, getMessage} from '../messages'; + +abstract class AbstractActionSummaryViewer { + protected readonly display: Display; + + protected constructor(display: Display) { + this.display = display; + } + + protected displaySummaryHeader(): void { + this.display.displayLog(toStyledHeader(getMessage(BundleName.ActionSummaryViewer, 'common.summary-header'))); + } + + protected displayLineSeparator(): void { + this.display.displayLog(""); + } + + protected displayLogFileInfo(logFile: string): void { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'common.logfile-location')); + this.display.displayLog(indent(logFile)); + } +} + +export class ConfigActionSummaryViewer extends AbstractActionSummaryViewer { + public constructor(display: Display) { + super(display); + } + + public view(logFile: string, outfile?: string): void { + this.displaySummaryHeader(); + this.displayLineSeparator(); + + if (outfile) { + this.displayOutfile(outfile); + } else { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'config-action.no-outfiles')); + } + this.displayLineSeparator(); + + this.displayLogFileInfo(logFile); + } + + private displayOutfile(outfile: string): void { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'config-action.outfile-location')); + this.display.displayLog(indent(outfile)); + } +} diff --git a/src/lib/writers/ConfigWriter.ts b/src/lib/writers/ConfigWriter.ts index da170ad5a..8a2f82573 100644 --- a/src/lib/writers/ConfigWriter.ts +++ b/src/lib/writers/ConfigWriter.ts @@ -6,7 +6,7 @@ import {Display} from '../Display'; import {exists} from '../utils/FileUtil'; export interface ConfigWriter { - write(model: ConfigModel): Promise; + write(model: ConfigModel): Promise; } export class ConfigFileWriter implements ConfigWriter { @@ -20,10 +20,13 @@ export class ConfigFileWriter implements ConfigWriter { this.display = display; } - public async write(model: ConfigModel): Promise { + public async write(model: ConfigModel): Promise { // Only write to the file if it doesn't already exist, or if the user confirms that they want to overwrite it. if (!(await exists(this.file)) || await this.display.confirm(getMessage(BundleName.ConfigWriter, 'prompt.overwrite-existing-file', [this.file]))) { fs.writeFileSync(this.file, model.toFormattedOutput(this.format)); + return true; + } else { + return false; } } diff --git a/test/commands/code-analyzer/config.test.ts b/test/commands/code-analyzer/config.test.ts index 1803e90df..986f602c3 100644 --- a/test/commands/code-analyzer/config.test.ts +++ b/test/commands/code-analyzer/config.test.ts @@ -177,6 +177,7 @@ describe('`code-analyzer config` tests', () => { expect(createActionSpy).toHaveBeenCalled(); expect(fromFileSpy).toHaveBeenCalled(); expect(receivedFile).toEqual(inputValue); + expect(receivedActionInput).toHaveProperty('output-file', inputValue); }); it('Can be referenced by its shortname, -f', async () => { @@ -186,6 +187,7 @@ describe('`code-analyzer config` tests', () => { expect(createActionSpy).toHaveBeenCalled(); expect(fromFileSpy).toHaveBeenCalled(); expect(receivedFile).toEqual(inputValue); + expect(receivedActionInput).toHaveProperty('output-file', inputValue); }); it('Cannot be supplied multiple times', async () => { @@ -201,6 +203,7 @@ describe('`code-analyzer config` tests', () => { expect(executeSpy).toHaveBeenCalled(); expect(createActionSpy).toHaveBeenCalled(); expect(fromFileSpy).not.toHaveBeenCalled(); + expect(receivedActionInput['output-file']).toBeUndefined(); }); }); diff --git a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile new file mode 100644 index 000000000..3bcdbe5f2 --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile @@ -0,0 +1,5 @@ +=== Summary + +No output file was specified. + +Additional log information written to: \ No newline at end of file diff --git a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile new file mode 100644 index 000000000..b05ed3d0a --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile @@ -0,0 +1,6 @@ +=== Summary + +Config written to: + out-config.yml + +Additional log information written to: \ No newline at end of file diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index 12c033201..16507f433 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -9,7 +9,8 @@ import {CodeAnalyzerConfigFactory} from "../../../src/lib/factories/CodeAnalyzer import {EnginePluginsFactory} from '../../../src/lib/factories/EnginePluginsFactory'; import {ConfigAction, ConfigDependencies, ConfigInput} from '../../../src/lib/actions/ConfigAction'; import {AnnotatedConfigModel} from '../../../src/lib/models/ConfigModel'; -import {ConfigStyledYamlViewer} from '../../../lib/lib/viewers/ConfigViewer'; +import {ConfigStyledYamlViewer} from '../../../src/lib/viewers/ConfigViewer'; +import {ConfigActionSummaryViewer} from '../../../src/lib/viewers/ActionSummaryViewer'; import {SpyConfigWriter} from '../../stubs/SpyConfigWriter'; import {DisplayEventType, SpyDisplay} from '../../stubs/SpyDisplay'; @@ -36,6 +37,7 @@ describe('ConfigAction tests', () => { viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), modelGenerator: AnnotatedConfigModel.fromSelection, + actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; }); @@ -159,6 +161,7 @@ describe('ConfigAction tests', () => { viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: stubConfigFactory, modelGenerator: AnnotatedConfigModel.fromSelection, + actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; }); @@ -389,6 +392,7 @@ describe('ConfigAction tests', () => { viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), modelGenerator: AnnotatedConfigModel.fromSelection, + actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; }); @@ -406,6 +410,74 @@ describe('ConfigAction tests', () => { expect(spyWriter.getCallHistory()).toHaveLength(1); }); }); + + describe('Summary generation', () => { + beforeEach(() => { + spyDisplay = new SpyDisplay(); + dependencies = { + logEventListeners: [], + progressEventListeners: [], + viewer: new ConfigStyledYamlViewer(spyDisplay), + configFactory: new DefaultStubCodeAnalyzerConfigFactory(), + modelGenerator: AnnotatedConfigModel.fromSelection, + actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), + pluginsFactory: new StubEnginePluginFactory() + } + }); + + it('When an Outfile is created, it is mentioned by the Summarizer', async () => { + // ==== SETUP ==== + // Assign a Writer to the dependencies. + dependencies.writer = new SpyConfigWriter(true); + + // ==== TESTED BEHAVIOR ==== + // Invoke the action, specifying an outfile. + const action = ConfigAction.createAction(dependencies); + const input: ConfigInput = { + 'rule-selector': ['all'], + 'output-file': 'out-config.yml' + }; + await action.execute(input); + + // ==== ASSERTIONS ==== + const displayEvents = spyDisplay.getDisplayEvents(); + const displayedLogEvents = ansis.strip(displayEvents + .filter(e => e.type === DisplayEventType.LOG) + .map(e => e.data) + .join('\n')); + + const goldfileContents: string = await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'action-summaries', 'outfile-created.txt.goldfile')); + expect(displayedLogEvents).toContain(goldfileContents); + }); + + it.each([ + {case: 'an Outfile is specified but not written', writer: new SpyConfigWriter(false), outfile: 'out-config.yml'}, + {case: 'an Outfile is not specified at all', writer: undefined, outfile: undefined} + ])('When $case, the Summarizer mentions no outfile', async ({writer, outfile}) => { + // ==== SETUP ==== + // Add the specified Writer (or lack-of-Writer) to the dependencies. + dependencies.writer = writer; + + // ==== TESTED BEHAVIOR ==== + // Invoke the action, specifying an outfile (or lack of one). + const action = ConfigAction.createAction(dependencies); + const input: ConfigInput = { + 'rule-selector': ['all'], + 'output-file': outfile + }; + await action.execute(input); + + // ==== ASSERTIONS ==== + const displayEvents = spyDisplay.getDisplayEvents(); + const displayedLogEvents = ansis.strip(displayEvents + .filter(e => e.type === DisplayEventType.LOG) + .map(e => e.data) + .join('\n')); + + const goldfileContents: string = await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'action-summaries', 'no-outfile-created.txt.goldfile')); + expect(displayedLogEvents).toContain(goldfileContents); + }); + }) // ====== HELPER FUNCTIONS ====== async function readGoldFile(goldFilePath: string): Promise { @@ -425,7 +497,6 @@ describe('ConfigAction tests', () => { // ==== OUTPUT PROCESSING ==== const displayEvents = spyDisplay.getDisplayEvents(); - expect(displayEvents).toHaveLength(1); expect(displayEvents[0].type).toEqual(DisplayEventType.LOG); return ansis.strip(displayEvents[0].data); } diff --git a/test/lib/writers/ConfigWriter.test.ts b/test/lib/writers/ConfigWriter.test.ts index b84a4ce19..367f42526 100644 --- a/test/lib/writers/ConfigWriter.test.ts +++ b/test/lib/writers/ConfigWriter.test.ts @@ -31,8 +31,9 @@ describe('ConfigWriter implementations', () => { const stubbedConfig = new StubConfigModel(); - await configFileWriter.write(stubbedConfig); + const result: boolean = await configFileWriter.write(stubbedConfig); + expect(result).toEqual(true); expect(spyDisplay.getDisplayEvents()).toHaveLength(0); expect(writeFileSpy).toHaveBeenCalled(); @@ -52,10 +53,11 @@ describe('ConfigWriter implementations', () => { const stubbedConfig = new StubConfigModel(); - await configFileWriter.write(stubbedConfig); + const result: boolean = await configFileWriter.write(stubbedConfig); const displayEvents: DisplayEvent[] = spyDisplay.getDisplayEvents(); expect(displayEvents).toHaveLength(1); + expect(result).toEqual(confirmation); // The user should be prompted to confirm override. expect(displayEvents[0].type).toEqual(DisplayEventType.CONFIRM); expect(displayEvents[0].data).toContain('overwrite'); diff --git a/test/stubs/SpyConfigWriter.ts b/test/stubs/SpyConfigWriter.ts index 82639e22a..2c56eab7a 100644 --- a/test/stubs/SpyConfigWriter.ts +++ b/test/stubs/SpyConfigWriter.ts @@ -2,11 +2,16 @@ import {ConfigModel} from '../../src/lib/models/ConfigModel'; import {ConfigWriter} from '../../src/lib/writers/ConfigWriter'; export class SpyConfigWriter implements ConfigWriter { + private simulateSuccessfulWrites: boolean; private callHistory: ConfigModel[] = []; - public write(config: ConfigModel): Promise { + public constructor(simulateSuccessfulWrites: boolean = true) { + this.simulateSuccessfulWrites = simulateSuccessfulWrites; + } + + public write(config: ConfigModel): Promise { this.callHistory.push(config); - return Promise.resolve(); + return Promise.resolve(this.simulateSuccessfulWrites); } public getCallHistory(): ConfigModel[] { From 0e71236d249f5685ad882966f82c378cf674c9e7 Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Wed, 16 Oct 2024 14:41:39 -0500 Subject: [PATCH 2/3] NEW @W-16891765@ Changed message based on feedback --- messages/action-summary-viewer.md | 2 +- .../action-summaries/outfile-created.txt.goldfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/messages/action-summary-viewer.md b/messages/action-summary-viewer.md index ec334bec0..2fe72f796 100644 --- a/messages/action-summary-viewer.md +++ b/messages/action-summary-viewer.md @@ -12,4 +12,4 @@ No output file was specified. # config-action.outfile-location -Config written to: +Configuration written to: diff --git a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile index b05ed3d0a..fbe024e3c 100644 --- a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile +++ b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/outfile-created.txt.goldfile @@ -1,6 +1,6 @@ === Summary -Config written to: +Configuration written to: out-config.yml Additional log information written to: \ No newline at end of file From b03d267654be26c0b8e9c76ba33f51f19505d89b Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Mon, 21 Oct 2024 13:03:58 -0500 Subject: [PATCH 3/3] NEW @W-16891765@ Added end-of-file comment to config output. --- messages/config-model.md | 3 +++ src/lib/models/ConfigModel.ts | 4 +++- .../header-comments/top-level-end.yml.goldfile | 3 +++ ...l.yml.goldfile => top-level-start.yml.goldfile} | 0 test/lib/actions/ConfigAction.test.ts | 14 ++++++++++---- 5 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level-end.yml.goldfile rename test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/{top-level.yml.goldfile => top-level-start.yml.goldfile} (100%) diff --git a/messages/config-model.md b/messages/config-model.md index 54eadeabd..414a20c34 100644 --- a/messages/config-model.md +++ b/messages/config-model.md @@ -12,3 +12,6 @@ Empty object used because rule selection returned no rules # template.yaml.no-rules-selected Remove this empty object {} when you are ready to specify your first rule override + +# template.common.end-of-config +END OF CODE ANALYZER CONFIGURATION diff --git a/src/lib/models/ConfigModel.ts b/src/lib/models/ConfigModel.ts index 322141012..479526d8e 100644 --- a/src/lib/models/ConfigModel.ts +++ b/src/lib/models/ConfigModel.ts @@ -114,7 +114,9 @@ abstract class YamlFormatter { this.toYamlRuleOverrides() + '\n' + '\n' + this.toYamlComment(topLevelDescription.fieldDescriptions!.engines) + '\n' + - this.toYamlEngineOverrides() + '\n'; + this.toYamlEngineOverrides() + '\n' + + '\n' + + this.toYamlSectionHeadingComment(getMessage(BundleName.ConfigModel, 'template.common.end-of-config')) + '\n'; } private toYamlRuleOverrides(): string { diff --git a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level-end.yml.goldfile b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level-end.yml.goldfile new file mode 100644 index 000000000..de1d3d889 --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level-end.yml.goldfile @@ -0,0 +1,3 @@ +# ====================================================================== +# END OF CODE ANALYZER CONFIGURATION +# ====================================================================== diff --git a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level.yml.goldfile b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level-start.yml.goldfile similarity index 100% rename from test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level.yml.goldfile rename to test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/header-comments/top-level-start.yml.goldfile diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index 16507f433..10edee0ab 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -42,13 +42,16 @@ describe('ConfigAction tests', () => { }; }); - it('Top-level overview-comment is correct', async () => { + it.each([ + {position: 'start'}, + {position: 'end'} + ])('Top-level $position comment is correct', async ({position}) => { // ==== TESTED BEHAVIOR ==== // Just select all rules for this test, since we don't care about the rules here. const output = await runActionAndGetDisplayedConfig(dependencies, ['all']); // ==== ASSERTIONS ==== - const goldFileContents = await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'header-comments', 'top-level.yml.goldfile')); + const goldFileContents = await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'header-comments', `top-level-${position}.yml.goldfile`)); expect(output).toContain(goldFileContents); }); @@ -167,7 +170,10 @@ describe('ConfigAction tests', () => { }); - it('Top-level overview-comment is correct', async () => { + it.each([ + {position: 'start'}, + {position: 'end'} + ])('Top-level $position comment is correct', async ({position}) => { // ==== SETUP ==== // Set the dummy config properties to null; it's fine for this test. stubConfigFactory.setDummyConfigRoot('null'); @@ -178,7 +184,7 @@ describe('ConfigAction tests', () => { const output = await runActionAndGetDisplayedConfig(dependencies, ['all']); // ==== ASSERTIONS ==== - const goldFileContents = await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'header-comments', 'top-level.yml.goldfile')); + const goldFileContents = await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'header-comments', `top-level-${position}.yml.goldfile`)); expect(output).toContain(goldFileContents); });