Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests next #1646

Merged
merged 4 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions packages/engine-rn-next/src/sdk/__tests__/env.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { createRnvContext, fsExistsSync, getConfigProp, getContext, logWarning, parsePlugins } from '@rnv/core';
import { EnvVars } from '../env';
import { getExportDir } from '../runner';

jest.mock('@rnv/core');
jest.mock('path');
jest.mock('../runner');

describe('EnvVars', () => {
beforeEach(() => {
createRnvContext();
});

afterEach(() => {
jest.resetAllMocks();
});
describe('RNV_NEXT_TRANSPILE_MODULES', () => {
it('should return an empty array when no modules are configured', () => {
// GIVEN
jest.mocked(getConfigProp).mockReturnValueOnce(undefined);
//WHEN
const result = EnvVars.RNV_NEXT_TRANSPILE_MODULES();
//THEN
expect(result.RNV_NEXT_TRANSPILE_MODULES).toEqual([]);
});

it('should return configured modules', () => {
// GIVEN

const modules = ['module1', 'module2'];
jest.mocked(getConfigProp).mockReturnValueOnce(modules);
//WHEN
const result = EnvVars.RNV_NEXT_TRANSPILE_MODULES();
//THEN
expect(result.RNV_NEXT_TRANSPILE_MODULES).toEqual(modules);
});

it('should return modules from plugins', () => {
// GIVEN
const ctx = getContext();
const plugins = {
plugin1: { webpackConfig: { nextTranspileModules: ['module3'] } },
};
ctx.paths.project.dir = '/path/to/project';
ctx.platform = 'web';
ctx.buildConfig.plugins = plugins;

jest.mocked(getConfigProp).mockReturnValueOnce(undefined);
jest.mocked(parsePlugins).mockImplementationOnce((cb) => {
Object.keys(plugins).forEach((key) => {
cb(plugins[key], {}, key);
});
});
//WHEN
const result = EnvVars.RNV_NEXT_TRANSPILE_MODULES();
//THEN
expect(result.RNV_NEXT_TRANSPILE_MODULES).toEqual(['plugin1', 'module3']);
});
});

describe('NEXT_BASE', () => {
it('should return NEXT_BASE variables', () => {
//GIVEN
const ctx = getContext();
ctx._currentTask = 'export';
const pagesDir = 'custom/pages';
jest.mocked(getConfigProp).mockReturnValueOnce(pagesDir);
jest.mocked(fsExistsSync).mockReturnValueOnce(true);
jest.mocked(getExportDir).mockReturnValue('/path/to/export');
//WHEN
const result = EnvVars.NEXT_BASE();
//THEN
expect(result).toEqual({
NEXT_PAGES_DIR: pagesDir,
NEXT_DIST_DIR: '/path/to/export',
NEXT_EXPORT: true,
});
});

it('should log warning if custom pagesDir does not exist', () => {
//GIVEN
const ctx = getContext();
ctx._currentTask = 'export';
const pagesDir = 'custom/pages';
jest.mocked(getConfigProp).mockReturnValueOnce(pagesDir);
jest.mocked(fsExistsSync).mockReturnValueOnce(false);
jest.mocked(getExportDir).mockReturnValue('/path/to/export');
//WHEN
const result = EnvVars.NEXT_BASE();
//THEN
expect(logWarning).toHaveBeenCalledWith(expect.stringContaining('missing at'));
expect(result).toEqual({
NEXT_PAGES_DIR: pagesDir,
NEXT_DIST_DIR: '/path/to/export',
NEXT_EXPORT: true,
});
});

it('should log warning if pagesDir is not configured and use fallback', () => {
//GIVEN
const ctx = getContext();
ctx.platform = 'web';
ctx._currentTask = 'export';
jest.mocked(getConfigProp).mockReturnValueOnce(undefined);
jest.mocked(fsExistsSync).mockReturnValueOnce(true);
jest.mocked(getExportDir).mockReturnValue('/path/to/export');
//WHEN
const result = EnvVars.NEXT_BASE();
//THEN
expect(logWarning).toHaveBeenCalledWith(
expect.stringContaining("You're missing web.pagesDir config. Defaulting to 'src/app'")
);
expect(result).toEqual({
NEXT_PAGES_DIR: 'src/app',
NEXT_DIST_DIR: '/path/to/export',
NEXT_EXPORT: true,
});
});

it('should log warning if fallback pagesDir does not exist', () => {
//GIVEN
const ctx = getContext();
ctx.platform = 'web';
ctx._currentTask = 'export';
jest.mocked(getConfigProp).mockReturnValueOnce(undefined);
jest.mocked(fsExistsSync).mockReturnValueOnce(false);
jest.mocked(getExportDir).mockReturnValue('/path/to/export');
//WHEN
const result = EnvVars.NEXT_BASE();
//THEN
expect(logWarning).toHaveBeenCalledWith(expect.stringContaining('Folder src/app is missing'));
expect(result).toEqual({
NEXT_PAGES_DIR: 'src/app',
NEXT_DIST_DIR: '/path/to/export',
NEXT_EXPORT: true,
});
});
});

describe('NODE_ENV', () => {
it('should return NODE_ENV from config', () => {
//GIVEN
const env = 'production';
jest.mocked(getConfigProp).mockReturnValueOnce(env);
//WHEN
const result = EnvVars.NODE_ENV();
//THEN
expect(result.NODE_ENV).toEqual(env);
});

it('should return development if NODE_ENV is not configured', () => {
//GIVEN
jest.mocked(getConfigProp).mockReturnValueOnce(undefined);
//WHEN
const result = EnvVars.NODE_ENV();
//THEN
expect(result.NODE_ENV).toEqual('development');
});
});
});
145 changes: 145 additions & 0 deletions packages/engine-rn-next/src/sdk/__tests__/runner.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import path from 'path';
import { buildWebNext, exportWebNext, runWebNext } from '../runner';
import { checkPortInUse, confirmActiveBundler, getDevServerHost, waitForHost } from '@rnv/sdk-utils';
import {
getContext,
getConfigProp,
logDefault,
logInfo,
logSummary,
createRnvContext,
logRaw,
executeAsync,
logSuccess,
chalk,
} from '@rnv/core';

jest.mock('../env');
jest.mock('@rnv/core');
jest.mock('path');

jest.mock('chalk', () => ({
bold: {
white: jest.fn((str) => str),
},
cyan: jest.fn((str) => str),
}));

beforeEach(() => {
createRnvContext();
jest.mocked(getDevServerHost).mockReturnValue('localhost');
jest.mocked(path.join).mockReturnValue('/path/to/next');
});

afterEach(() => {
jest.resetAllMocks();
});

describe('runWebNext', () => {
it('should return if platform is not defined', async () => {
//GIVEN
const ctx = getContext();
ctx.runtime.port = 3000;
//WHEN
await runWebNext();
//THEN
expect(logDefault).toHaveBeenCalledWith('runWebNext', 'port:3000');
expect(checkPortInUse).not.toHaveBeenCalled();
});
it('should start dev server if port is not in use', async () => {
//GIVEN
const ctx = getContext();
ctx.platform = 'web';
ctx.runtime.port = 3000;
ctx.runtime.shouldOpenBrowser = true;
ctx.paths.project.dir = '/path/to/project';
jest.mocked(checkPortInUse).mockResolvedValue(false);
jest.mocked(getConfigProp).mockReturnValue(false);
jest.mocked(waitForHost).mockResolvedValue(undefined);

//WHEN
await runWebNext();

//THEN
expect(logInfo).toHaveBeenCalledWith(
'Your web devServerHost localhost at port 3000 is not running. Starting it up for you...'
);
expect(logSummary).toHaveBeenCalledWith({ header: 'BUNDLER STARTED' });
expect(logRaw).toHaveBeenCalledWith(expect.stringContaining('Dev server running at: http://localhost:3000'));
expect(executeAsync).toHaveBeenCalledWith(
expect.stringContaining('node "/path/to/next" dev --port 3000'),
expect.any(Object)
);
});
it('should handle active bundler when port is in use and reset is completed', async () => {
//GIVEN
const ctx = getContext();
ctx.platform = 'web';
ctx.runtime.port = 3000;
ctx.runtime.shouldOpenBrowser = true;
ctx.paths.project.dir = '/path/to/project';
jest.mocked(checkPortInUse).mockResolvedValue(true);
jest.mocked(confirmActiveBundler).mockResolvedValue(true);
jest.mocked(getConfigProp).mockReturnValue(false);
jest.mocked(waitForHost).mockResolvedValue(undefined);

//WHEN
await runWebNext();

//THEN
expect(confirmActiveBundler).toHaveBeenCalled();
expect(logSummary).toHaveBeenCalledWith({ header: 'BUNDLER STARTED' });
expect(logRaw).toHaveBeenCalledWith(`
Dev server running at: ${chalk().cyan(`http://localhost:${ctx.runtime.port}`)}
`);
expect(executeAsync).toHaveBeenCalledWith(
expect.stringContaining('node "/path/to/next" dev --port 3000'),
expect.any(Object)
);
});
});

describe('buildWebNext', () => {
it('should build the project and log success message', async () => {
// GIVEN
const ctx = getContext();
ctx.paths.project.dir = '/path/to/project';
const buildLocation = `${ctx.paths.project.dir}/output`;
jest.mocked(getConfigProp).mockReturnValue(buildLocation);
jest.mocked(path.isAbsolute).mockReturnValue(false);
// WHEN
await expect(buildWebNext()).resolves.toEqual(true);

// THEN
expect(logDefault).toHaveBeenCalledWith('buildWebNext');
expect(executeAsync).toHaveBeenCalledWith(
expect.stringContaining('node /path/to/next build'),
expect.any(Object)
);
expect(logSuccess).toHaveBeenCalledWith(`Your build is located in ${chalk().cyan(`${buildLocation}`)} .`);
});
});

describe('exportWebNext', () => {
it('should export the project and log success message', async () => {
// GIVEN
const ctx = getContext();
ctx.paths.project.dir = '/path/to/project';
const buildLocation = `${ctx.paths.project.dir}/output`;
jest.mocked(getConfigProp).mockReturnValue(buildLocation);
jest.mocked(path.isAbsolute).mockReturnValue(false);
// WHEN
await exportWebNext();
// THEN
expect(logDefault).toHaveBeenCalledWith('exportWebNext');
expect(executeAsync).toHaveBeenCalledWith(
expect.stringContaining('node /path/to/next build'),
expect.objectContaining({
env: expect.objectContaining({
NODE_ENV: 'production',
}),
})
);
expect(logSuccess).toHaveBeenCalledWith(`Your export is located in ${chalk().cyan(`${buildLocation}`)} .`);
});
});
33 changes: 33 additions & 0 deletions packages/engine-rn-next/src/tasks/__tests__/taskRun.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { createRnvContext, getContext } from '@rnv/core';
import taskRun from '../taskRun';
import { runWebNext } from '../../sdk/runner';

jest.mock('@rnv/core');
jest.mock('../../sdk/runner');

beforeEach(() => {
createRnvContext();
});

afterEach(() => {
jest.resetAllMocks();
});

describe('taskRun tests', () => {
it('Execute task.rnv.run -p web', async () => {
//GIVEN
const ctx = getContext();
//WHEN
await expect(
taskRun.fn?.({
ctx,
taskName: 'MOCK_taskName',
originTaskName: 'MOCK_originTaskName',
parentTaskName: 'MOCK_parentTaskName',
shouldSkip: false,
})
).resolves.toEqual(undefined);
//THEN
expect(runWebNext).toHaveBeenCalled();
});
});
Loading