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

fix generate map file & refactor tests and add test for external link in toc #156

Merged
merged 2 commits into from
Jun 20, 2022
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
60 changes: 14 additions & 46 deletions src/steps/processMapFile.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import {readFileSync, writeFileSync} from 'fs';
import {dirname, extname, join} from 'path';
import yaml from 'js-yaml';
import walkSync from 'walk-sync';
import {writeFileSync} from 'fs';
import {extname, join} from 'path';

import {ArgvService} from '../services';
import {isExternalHref} from '../utils';
import {ArgvService, TocService} from '../services';
import {convertBackSlashToSlash} from '../utils';

type TocItem = {
name: string;
Expand All @@ -14,54 +12,24 @@ type TocItem = {

type TocItems = TocItem[];

type Toc = {
title: string;
items: TocItems;
};

export function prepareMapFile(): void {
const {
output: outputFolderPath,
} = ArgvService.getConfig();

const navigationPaths = {
files: collectFiles(outputFolderPath),
};
const navigationPathsWithoutExtensions =
TocService.getNavigationPaths().map((path) => {
let preparedPath = convertBackSlashToSlash(path.replace(extname(path), ''));

if (preparedPath.endsWith('/index')) {
preparedPath = preparedPath.substring(0, preparedPath.length - 5);
}

return preparedPath;
});
const navigationPaths = {files: [...new Set(navigationPathsWithoutExtensions)]};
const filesMapBuffer = Buffer.from(JSON.stringify(navigationPaths, null, '\t'), 'utf8');
const mapFile = join(outputFolderPath, 'files.json');

writeFileSync(mapFile, filesMapBuffer);
}

function walkItems(items: TocItems, source: string) {
return items.reduce((acc: string[], {href, items: subItems}) => {
if (href && !isExternalHref(href)) {
acc.push(join(source, href).replace(extname(href), ''));
}

if (subItems) {
acc.push(...walkItems(subItems, source));
}

return acc;
}, []);
}

function collectFiles(cwd: string): string[] {
const files = walkSync(cwd, {
directories: false,
globs: ['**/toc.yaml'],
});

return files
.filter((path) => !path.includes('/_'))
.reduce((acc: string[], path: string) => {
const fullPath = join(cwd, path);
const toc = yaml.load(readFileSync(fullPath, 'utf8')) as Toc;

acc.push(`${dirname(path)}/`);

return acc.concat(walkItems(toc.items, dirname(path)));
}, []);
}
39 changes: 14 additions & 25 deletions tests/e2e/generate-map.spec.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,26 @@
import {getTestPaths, compareFiles, runYfmDocs} from '../utils';
import {getTestPaths, runYfmDocs, getFileContent} from '../utils';

describe('Generate map for', () => {
test('project with single language and toc include', () => {
const testRootPath = 'mocks/generate-map/test1';
const geretateMapTestTemplate = (testTitle, testRootPath, md2md = true, md2html = true) => {
test(testTitle, () => {
const {inputPath, outputPath, expectedOutputPath} = getTestPaths(testRootPath);

runYfmDocs(inputPath, outputPath, {md2md: false, md2html: true, args: '--add-map-file'});
runYfmDocs(inputPath, outputPath, {md2md, md2html, args: '--add-map-file'});

const compareResult = compareFiles(outputPath, expectedOutputPath);
const outputContent = getFileContent(outputPath + '/files.json');
const expectedContent = getFileContent(expectedOutputPath + '/files.json');

if (typeof compareResult === 'boolean') {
expect(true).toEqual(compareResult);
} else {
const {expectedContent, outputContent} = compareResult;
const prepareFileJsonToCompare = (file) => JSON.stringify(JSON.parse(file).files.sort())

expect(expectedContent).toEqual(outputContent);
}
expect(prepareFileJsonToCompare(outputContent)).toEqual(prepareFileJsonToCompare(expectedContent));
});
}

test('project with multiple language', () => {
const testRootPath = 'mocks/generate-map/test2';
const {inputPath, outputPath, expectedOutputPath} = getTestPaths(testRootPath);

runYfmDocs(inputPath, outputPath, {md2md: false, md2html: true, args: '--add-map-file'});
describe('Generate map for', () => {
geretateMapTestTemplate('project with single language and toc include', 'mocks/generate-map/test1')

const compareResult = compareFiles(outputPath, expectedOutputPath);
geretateMapTestTemplate('project with single language and toc include - only md2html', 'mocks/generate-map/test1', false)

if (typeof compareResult === 'boolean') {
expect(true).toEqual(compareResult);
} else {
const {expectedContent, outputContent} = compareResult;
geretateMapTestTemplate('project with multiple language', 'mocks/generate-map/test2')

expect(expectedContent).toEqual(outputContent);
}
});
geretateMapTestTemplate('project with external links in toc', 'mocks/generate-map/test3')
});
9 changes: 3 additions & 6 deletions tests/mocks/generate-map/test1/expected-output/files.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
{
"files": [
"ru/folder1/folder2/",
"ru/folder1/folder2/a1",
"ru/folder1/",
"ru/folder1/a1",
"ru/",
"ru/index",
"ru/settings",
"ru/plugins/index",
"ru/plugins/",
"ru/plugins/import",
"ru/project/index",
"ru/project/",
"ru/project/config"
]
}
}
12 changes: 5 additions & 7 deletions tests/mocks/generate-map/test2/expected-output/files.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
{
"files": [
"en/",
"en/index",
"en/settings",
"en/plugins/index",
"en/plugins/",
"en/plugins/import",
"en/project/index",
"en/project/",
"en/project/config",
"ru/",
"ru/index",
"ru/settings",
"ru/plugins/index",
"ru/plugins/",
"ru/plugins/import",
"ru/project/index",
"ru/project/",
"ru/project/config"
]
}
}
10 changes: 10 additions & 0 deletions tests/mocks/generate-map/test3/expected-output/files.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"files": [
"ru/folder1/folder2/a1",
"ru/folder1/a1",
"ru/",
"ru/settings",
"ru/plugins/",
"ru/project/"
]
}
Empty file.
Empty file.
Empty file.
1 change: 1 addition & 0 deletions tests/mocks/generate-map/test3/input/ru/folder1/a1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the /folder1/a1.md file content.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the /folder1/folder1/a1.md file content.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
items:
- name: A1
href: a1.md


7 changes: 7 additions & 0 deletions tests/mocks/generate-map/test3/input/ru/folder1/toc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
items:
- name: A1
href: a1.md
- name: folder1
include:
mode: link
path: folder2/toc.yaml
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
22 changes: 22 additions & 0 deletions tests/mocks/generate-map/test3/input/ru/toc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
title: Yandex Flavored Markdown
items:
- name: Yandex Flavored Markdown
href: index.md
- name: Settings
href: settings.md
- name: Plugins
items:
- name: Overview
href: plugins/index.md
- name: Adding additional plugins
href: https://test.ru
- name: Organizing a YFM project
items:
- name: Overview
href: project/index.md
- name: Configuration file
href: https://test.ru
- name: folder1
include:
mode: link
path: folder1/toc.yaml
22 changes: 0 additions & 22 deletions tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,6 @@ export function compareDirectories(expectedOutputPath: string, outputPath: strin
return compareResult;
}

export function compareFiles(outputPath, expectedOutputPath) {
let compareResult: CompareResult = true;
const expectedContent = getFileContent(expectedOutputPath);
const outputContent = getFileContent(outputPath);

const convertedExpectedContent = convertBackSlashToSlash(expectedContent);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let preparedExpectedContent: any = convertedExpectedContent;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let preparedOutputContent: any = outputContent;

if (!isEqual(preparedExpectedContent, preparedOutputContent)) {
compareResult = {
expectedContent: preparedExpectedContent,
outputContent: preparedOutputContent,
};
}

return compareResult
}

interface RunYfmDocsArgs {
md2md?: boolean;
md2html?: boolean;
Expand Down