From a6e0141b8625f5e8a5c579bca29a34499e1b6705 Mon Sep 17 00:00:00 2001 From: Ryan Waskiewicz Date: Tue, 28 Jun 2022 18:35:07 -0400 Subject: [PATCH] test(cli): add tests for run.ts (#3441) this commit adds initial unit tests for `run.ts`. the goal of these tests are to get the minimal amount of coverage under the `run` and `runTask` functions so that we can (eventually) begin to change the function signatures on the functions they invoke. specifically, the stencil team is looking to make the configuration object that is used throughout the compiler stricter by making fields no longer optional on the type (internally). as a part of that effort, we're reassessing what data fields functions need. we know that we will be changing the signatures of the tasks for 'help' and 'telemetry'. by adding tests around the invocation of these tasks, we can have greater trust in the changes that we're making --- src/cli/test/run.spec.ts | 156 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/cli/test/run.spec.ts diff --git a/src/cli/test/run.spec.ts b/src/cli/test/run.spec.ts new file mode 100644 index 00000000000..d45ffab4dce --- /dev/null +++ b/src/cli/test/run.spec.ts @@ -0,0 +1,156 @@ +import type * as d from '../../declarations'; +import * as coreCompiler from '@stencil/core/compiler'; +import { mockCompilerSystem, mockConfig, mockLogger as createMockLogger } from '@stencil/core/testing'; +import * as ParseFlags from '../parse-flags'; +import { run, runTask } from '../run'; +import * as HelpTask from '../task-help'; +import * as TelemetryTask from '../task-telemetry'; +import { createTestingSystem } from '../../testing/testing-sys'; + +describe('run', () => { + describe('run()', () => { + let cliInitOptions: d.CliInitOptions; + let mockLogger: d.Logger; + let mockSystem: d.CompilerSystem; + + let parseFlagsSpy: jest.SpyInstance< + ReturnType, + Parameters + >; + + beforeEach(() => { + mockLogger = createMockLogger(); + mockSystem = createTestingSystem(); + + cliInitOptions = { + args: [], + logger: mockLogger, + sys: mockSystem, + }; + + parseFlagsSpy = jest.spyOn(ParseFlags, 'parseFlags'); + parseFlagsSpy.mockReturnValue({ + // use the 'help' task as a reasonable default for all calls to this function. + // code paths that require a different task can always override this value as needed. + task: 'help', + }); + }); + + afterEach(() => { + parseFlagsSpy.mockRestore(); + }); + + describe('help task', () => { + let taskHelpSpy: jest.SpyInstance, Parameters>; + + beforeEach(() => { + taskHelpSpy = jest.spyOn(HelpTask, 'taskHelp'); + taskHelpSpy.mockReturnValue(Promise.resolve()); + }); + + afterEach(() => { + taskHelpSpy.mockRestore(); + }); + + it("calls the help task when the 'task' field is set to 'help'", () => { + run(cliInitOptions); + + expect(taskHelpSpy).toHaveBeenCalledTimes(1); + expect(taskHelpSpy).toHaveBeenCalledWith( + { + flags: { + task: 'help', + args: [], + }, + outputTargets: [], + }, + mockLogger, + mockSystem + ); + + taskHelpSpy.mockRestore(); + }); + + it("calls the help task when the 'help' field is set on flags", () => { + parseFlagsSpy.mockReturnValue({ + help: true, + }); + + run(cliInitOptions); + + expect(taskHelpSpy).toHaveBeenCalledTimes(1); + expect(taskHelpSpy).toHaveBeenCalledWith( + { + flags: { + task: 'help', + args: [], + }, + outputTargets: [], + }, + mockLogger, + mockSystem + ); + + taskHelpSpy.mockRestore(); + }); + }); + }); + + describe('runTask()', () => { + let sys: d.CompilerSystem; + let unvalidatedConfig: d.Config; + + let taskHelpSpy: jest.SpyInstance, Parameters>; + let taskTelemetrySpy: jest.SpyInstance< + ReturnType, + Parameters + >; + + beforeEach(() => { + sys = mockCompilerSystem(); + sys.exit = jest.fn(); + + unvalidatedConfig = mockConfig(sys); + + taskHelpSpy = jest.spyOn(HelpTask, 'taskHelp'); + taskHelpSpy.mockReturnValue(Promise.resolve()); + taskTelemetrySpy = jest.spyOn(TelemetryTask, 'taskTelemetry'); + taskTelemetrySpy.mockReturnValue(Promise.resolve()); + }); + + afterEach(() => { + taskHelpSpy.mockRestore(); + taskTelemetrySpy.mockRestore(); + }); + + it('calls the help task', () => { + runTask(coreCompiler, unvalidatedConfig, 'help', sys); + + expect(taskHelpSpy).toHaveBeenCalledTimes(1); + expect(taskHelpSpy).toHaveBeenCalledWith(unvalidatedConfig, unvalidatedConfig.logger, sys); + }); + + describe('telemetry task', () => { + it('calls the telemetry task when a compiler system is present', () => { + runTask(coreCompiler, unvalidatedConfig, 'telemetry', sys); + + expect(taskTelemetrySpy).toHaveBeenCalledTimes(1); + expect(taskTelemetrySpy).toHaveBeenCalledWith(unvalidatedConfig, sys, unvalidatedConfig.logger); + }); + + it("does not call the telemetry task when a compiler system isn't present", () => { + runTask(coreCompiler, unvalidatedConfig, 'telemetry'); + + expect(taskTelemetrySpy).not.toHaveBeenCalled(); + }); + }); + + it('defaults to the help task for an unaccounted for task name', () => { + // info is a valid task name, but isn't used in the `switch` statement of `runTask` + runTask(coreCompiler, unvalidatedConfig, 'info', sys); + + expect(taskHelpSpy).toHaveBeenCalledTimes(1); + expect(taskHelpSpy).toHaveBeenCalledWith(unvalidatedConfig, unvalidatedConfig.logger, sys); + }); + }); +});