Skip to content

Commit

Permalink
test(cli): add tests for run.ts (#3441)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rwaskiewicz authored Jun 28, 2022
1 parent 700b3a9 commit a6e0141
Showing 1 changed file with 156 additions and 0 deletions.
156 changes: 156 additions & 0 deletions src/cli/test/run.spec.ts
Original file line number Diff line number Diff line change
@@ -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<typeof ParseFlags.parseFlags>,
Parameters<typeof ParseFlags.parseFlags>
>;

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<ReturnType<typeof HelpTask.taskHelp>, Parameters<typeof HelpTask.taskHelp>>;

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<ReturnType<typeof HelpTask.taskHelp>, Parameters<typeof HelpTask.taskHelp>>;
let taskTelemetrySpy: jest.SpyInstance<
ReturnType<typeof TelemetryTask.taskTelemetry>,
Parameters<typeof TelemetryTask.taskTelemetry>
>;

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);
});
});
});

0 comments on commit a6e0141

Please sign in to comment.