UNPKG

@feature-sliced/filesystem

Version:

A set of utilities for locating and working with FSD roots in the file system.

315 lines (295 loc) 7.2 kB
import { join } from "node:path"; import { test, expect, describe } from "vitest"; import { getAllSlices, getIndexes, getSlices, isSlice, isSliced, isCrossImportPublicApi, type Folder, type File, } from "../index.js"; import { joinFromRoot, parseIntoFolder } from "./prepare-test.js"; test("getSlices", () => { const rootFolder = parseIntoFolder(` 📂 entities 📂 user 📂 ui 📄 index.ts 📂 posts 📂 ui 📄 index.ts 📂 features 📂 comments 📂 ui 📄 index.ts 📂 pages 📂 editor 📂 ui 📂 settings 📂 notifications 📂 ui 📄 index.ts 📂 profile 📂 ui 📄 index.ts `); expect(getSlices(rootFolder.children[0] as Folder)).toEqual({ user: (rootFolder.children[0] as Folder).children[0], posts: (rootFolder.children[0] as Folder).children[1], }); expect(getSlices(rootFolder.children[1] as Folder)).toEqual({ comments: (rootFolder.children[1] as Folder).children[0], }); expect(getSlices(rootFolder.children[2] as Folder)).toEqual({ editor: (rootFolder.children[2] as Folder).children[0], [join("settings", "notifications")]: ( (rootFolder.children[2] as Folder).children[1] as Folder ).children[0], [join("settings", "profile")]: ( (rootFolder.children[2] as Folder).children[1] as Folder ).children[1], }); }); test("getAllSlices", () => { const rootFolder = parseIntoFolder(` 📂 shared 📂 ui 📄 index.ts 📂 i18n 📄 index.ts 📂 entities 📂 user 📂 ui 📂 model 📄 index.ts 📂 features 📂 comments 📂 ui 📄 index.ts 📂 pages 📂 home 📂 ui 📄 index.ts `); const allSlices = getAllSlices(rootFolder); expect(Object.keys(allSlices).sort((a, b) => a.localeCompare(b))).toEqual([ "comments", "home", "user", ]); expect(allSlices.user).toEqual({ ...(rootFolder.children[1] as Folder).children[0], layerName: "entities", }); expect(allSlices.comments).toEqual({ ...(rootFolder.children[2] as Folder).children[0], layerName: "features", }); expect(allSlices.home).toEqual({ ...(rootFolder.children[3] as Folder).children[0], layerName: "pages", }); }); test("isSliced", () => { expect(isSliced("shared")).toBe(false); expect(isSliced("app")).toBe(false); expect(isSliced("entities")).toBe(true); expect(isSliced("features")).toBe(true); expect(isSliced("pages")).toBe(true); expect(isSliced("widgets")).toBe(true); expect( isSliced({ type: "folder", path: joinFromRoot("project", "src", "shared"), children: [], }), ).toBe(false); expect( isSliced({ type: "folder", path: joinFromRoot("project", "src", "entities"), children: [], }), ).toBe(true); }); describe("getIndexes", () => { test("basic functionality", () => { const indexFile: File = { type: "file", path: joinFromRoot("project", "src", "shared", "index.ts"), }; const fileSegment: File = { type: "file", path: joinFromRoot("project", "src", "entities", "user", "ui.ts"), }; const folderSegment = parseIntoFolder( ` 📄 Avatar.tsx 📄 User.tsx 📄 index.ts `, joinFromRoot("project", "src", "entities", "user", "ui"), ); expect(getIndexes(indexFile)).toEqual([indexFile]); expect(getIndexes(fileSegment)).toEqual([fileSegment]); expect(getIndexes(folderSegment)).toEqual([ { type: "file", path: joinFromRoot( "project", "src", "entities", "user", "ui", "index.ts", ), }, ]); }); test("recognizes index.server.js as index file", () => { const indexServerFile: File = { type: "file", path: joinFromRoot("project", "src", "shared", "index.server.js"), }; const nonIndexFile: File = { type: "file", path: joinFromRoot("project", "src", "entities", "user", "ui.ts"), }; const folderSegment = parseIntoFolder( ` 📄 Avatar.tsx 📄 User.tsx 📄 index.server.js `, joinFromRoot("project", "src", "entities", "user", "ui"), ); expect(getIndexes(indexServerFile)).toEqual([indexServerFile]); expect(getIndexes(nonIndexFile)).toEqual([nonIndexFile]); expect(getIndexes(folderSegment)).toEqual([ { type: "file", path: joinFromRoot( "project", "src", "entities", "user", "ui", "index.server.js", ), }, ]); }); test("handles multiple index files", () => { const folderSegment = parseIntoFolder( ` 📄 Avatar.tsx 📄 User.tsx 📄 index.client.js 📄 index.server.js `, joinFromRoot("project", "src", "entities", "user", "ui"), ); expect(getIndexes(folderSegment)).toEqual([ { type: "file", path: joinFromRoot( "project", "src", "entities", "user", "ui", "index.client.js", ), }, { type: "file", path: joinFromRoot( "project", "src", "entities", "user", "ui", "index.server.js", ), }, ]); }); }); test("isCrossImportPublicApi", () => { const file: File = { path: joinFromRoot( "project", "src", "entities", "user", "@x", "product.ts", ), type: "file", }; expect( isCrossImportPublicApi(file, { inSlice: "user", forSlice: "product", layerPath: joinFromRoot("project", "src", "entities"), }), ).toBe(true); expect( isCrossImportPublicApi(file, { inSlice: "product", forSlice: "user", layerPath: joinFromRoot("project", "src", "entities"), }), ).toBe(false); }); test("isCrossImportPublicApi with index files", () => { const indexFile: File = { path: joinFromRoot( "project", "src", "entities", "user", "@x", "product", "index.ts", ), type: "file", }; expect( isCrossImportPublicApi(indexFile, { inSlice: "user", forSlice: "product", layerPath: joinFromRoot("project", "src", "entities"), }), ).toBe(true); expect( isCrossImportPublicApi(indexFile, { inSlice: "product", forSlice: "user", layerPath: joinFromRoot("project", "src", "entities"), }), ).toBe(false); }); test("isSlice", () => { const sliceFolder = parseIntoFolder( ` 📂 ui 📄 Avatar.tsx 📄 User.tsx 📄 index.ts `, joinFromRoot("project", "src", "entities", "user"), ); expect(isSlice(sliceFolder)).toBe(true); const notSliceFolder = parseIntoFolder( ` 📂 shared 📂 pages 📂 app `, joinFromRoot("project", "src"), ); expect(isSlice(notSliceFolder)).toBe(false); });