@frontity/core
Version:
The core package of the Frontity framework.
407 lines (377 loc) • 14.6 kB
text/typescript
import * as fsExtra from "fs-extra";
import {
generateClientEntryPoints,
generateServerEntryPoint,
checkForPackages,
entryPoint,
} from "../entry-points";
import * as entryExists from "../entry-exists";
jest.mock("fs-extra");
jest.mock("../entry-exists");
const mockedFsExtra = fsExtra as jest.Mocked<typeof fsExtra>;
const mockedEntryExists = entryExists as jest.Mocked<typeof entryExists>;
const site = [
{
name: "site-1",
mode: "default",
packages: ["package1", "package2"],
},
];
const sites = [
{
name: "site-html",
mode: "default",
packages: ["package1", "package2", "package2"],
},
{
name: "site-amp",
mode: "amp",
packages: ["package1", "package3"],
},
{
name: "site-2",
mode: "default",
packages: ["package1"],
},
];
beforeEach(() => {
mockedFsExtra.writeFile.mockReset();
mockedFsExtra.ensureDir.mockReset();
mockedFsExtra.ensureDir.mockImplementation(() => {
// Silence.
});
mockedFsExtra.pathExists.mockReset();
mockedFsExtra.pathExists.mockImplementation(() => Promise.resolve(true));
mockedEntryExists.default.mockImplementation((path) => {
if (path === "package1/src/index") return Promise.resolve(".ts");
if (path === "package2/src/client") return Promise.resolve(".ts");
if (path === "package2/src/server") return Promise.resolve(".ts");
if (path === "package3/src/index") return Promise.resolve(".ts");
if (path === "package3/src/client") return Promise.resolve(".ts");
if (path === "package3/src/server/index") return Promise.resolve(".ts");
if (path === "package3/src/amp/client/index") return Promise.resolve(".ts");
if (path === "package3/src/amp/server") return Promise.resolve(".ts");
return Promise.resolve(false);
});
});
describe("generateClientEntryPoints", () => {
test("should avoid creating the client file at all if packages have no entry points", async () => {
mockedEntryExists.default.mockImplementation(() => Promise.resolve(false));
const bundles = await generateClientEntryPoints({
sites: site,
outDir: "/build",
mode: "production",
});
expect(mockedFsExtra.writeFile.mock.calls.length).toBe(0);
expect(bundles).toMatchSnapshot();
});
test("should write one client entry point", async () => {
const bundles = await generateClientEntryPoints({
sites: site,
outDir: "/build",
mode: "production",
});
expect(mockedFsExtra.ensureDir.mock.calls[0]).toMatchSnapshot();
expect({
in: site,
out: mockedFsExtra.writeFile.mock.calls[0],
}).toMatchSnapshot();
expect(bundles).toMatchSnapshot();
});
test("should write multiple client entry points", async () => {
const bundles = await generateClientEntryPoints({
sites,
outDir: "/build",
mode: "production",
});
expect(mockedFsExtra.ensureDir.mock.calls).toMatchSnapshot();
expect({
in: sites,
out: mockedFsExtra.writeFile.mock.calls,
}).toMatchSnapshot();
expect(bundles).toMatchSnapshot();
});
test("should write HMR code if in development", async () => {
await generateClientEntryPoints({
sites: site,
outDir: "/build",
mode: "development",
});
expect(mockedFsExtra.writeFile.mock.calls[0][1]).toMatchSnapshot();
});
});
describe("generateServerEntryPoint", () => {
test("should write one server entry point for one site", async () => {
const bundles = await generateServerEntryPoint({
sites: site,
outDir: "/build",
});
expect({
in: site,
out: mockedFsExtra.writeFile.mock.calls[0],
}).toMatchSnapshot();
expect(bundles).toMatchSnapshot();
});
test("should write one server entry point for multiple sites", async () => {
const bundles = await generateServerEntryPoint({ sites, outDir: "/build" });
expect({
in: sites,
out: mockedFsExtra.writeFile.mock.calls,
}).toMatchSnapshot();
expect(bundles).toMatchSnapshot();
});
});
describe("checkForPackages", () => {
test("should not throw if all packages are found", async () => {
await expect(checkForPackages({ sites: site })).resolves.toBe(undefined);
});
test("should throw if one package is not found", async () => {
mockedFsExtra.pathExists.mockImplementation(() => Promise.resolve(false));
await expect(checkForPackages({ sites: site })).rejects.toThrow(
'The package "package1" doesn\'t seem to be installed. Make sure you did "npm install package1"'
);
});
});
describe("entryPoint", () => {
test("should return client in amp mode when it exists", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/client") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/amp/client");
});
test("should return client in amp mode when it's a folder", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/client/index")
return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/amp/client/index");
});
test("should return index in amp mode when client doesn't exist", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/amp");
});
test("should return index in amp mode when client doesn't exist and it's in a folder", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/index") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/amp/index");
});
test("should return default client in amp mode when amp folder doesn't exist", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/client");
});
test("should return default client in amp mode when amp folder doesn't exist and it's a folder", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client/index") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/client/index");
});
test("should return default index in amp mode when amp folder doesn't exist", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/index");
});
test("should not return path when none exist", async () => {
mockedEntryExists.default.mockImplementation(() => {
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("");
});
test("should return server in amp mode when it exists", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/server") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/server") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "server",
});
await expect(entry).toBe("@org/pkg/src/amp/server");
});
test("should return server in amp mode when it exists but it's in a folder", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/server") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/server/index")
return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "server",
});
await expect(entry).toBe("@org/pkg/src/amp/server/index");
});
test("should return index in amp mode when server doesn't exist", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/server") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "server",
});
await expect(entry).toBe("@org/pkg/src/amp");
});
test("should return index in amp mode when server doesn't exist but it's in a folder", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/server") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/index") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "server",
});
await expect(entry).toBe("@org/pkg/src/amp/index");
});
test("should return only the type in amp mode when it exists", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/client") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/amp/client");
});
test("should return the type in amp mode when default exists", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/client") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/amp/client");
});
test("should not return the type in amp mode when it doesn't exist", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp") return Promise.resolve(".ts");
if (path === "@org/pkg/src/amp/client") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "amp",
type: "server",
});
await expect(entry).toBe("@org/pkg/src/amp");
});
test("should return no-mode client in default mode", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/client") return Promise.resolve(".ts");
if (path === "@org/pkg/src/default") return Promise.resolve(".ts");
if (path === "@org/pkg/src/default/client") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "default",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/client");
});
test("should return no-mode index in default mode", async () => {
mockedEntryExists.default.mockImplementation((path) => {
if (path === "@org/pkg/src/index") return Promise.resolve(".ts");
if (path === "@org/pkg/src/default") return Promise.resolve(".ts");
if (path === "@org/pkg/src/default/client") return Promise.resolve(".ts");
return Promise.resolve(false);
});
const entry = await entryPoint({
name: "@org/pkg",
mode: "default",
type: "client",
});
await expect(entry).toBe("@org/pkg/src/index");
});
});