Refactor + add more tests (Part 1) (#847)

* Refactor mdToHtml out

* Refactor routing + move it to server instead of core

* Refactor & Add more tests for server utils

* Refactor isSeparateCss function from server & generate

* Refactor insertTableOfContents from server & generate + add tests

* undo small nits
This commit is contained in:
Endilie Yacop Sucipto 2018-07-14 02:31:37 +08:00 committed by Yangshun Tay
parent a7a214fb3a
commit defcbcc8ee
14 changed files with 322 additions and 235 deletions

View file

@ -18,17 +18,9 @@ function execute(port, options) {
const request = require('request');
const fs = require('fs-extra');
const path = require('path');
const getTOC = require('../core/getTOC');
const utils = require('../core/utils');
const {
blogRouting,
docsRouting,
dotRouting,
feedRouting,
pageRouting,
noExtRouting,
sitemapRouting,
} = require('../core/routing');
const {insertTOC} = require('../core/toc');
const {getPath} = require('../core/utils');
const {isSeparateCss} = require('./utils');
const mkdirp = require('mkdirp');
const glob = require('glob');
const chalk = require('chalk');
@ -41,6 +33,7 @@ function execute(port, options) {
const feed = require('./feed');
const sitemap = require('./sitemap');
const routing = require('./routing');
const CWD = process.cwd();
@ -101,32 +94,6 @@ function execute(port, options) {
}
}
const TABLE_OF_CONTENTS_TOKEN = '<AUTOGENERATED_TABLE_OF_CONTENTS>';
const insertTableOfContents = rawContent => {
const filterRe = /^`[^`]*`/;
const headers = getTOC(rawContent, 'h3', null);
const tableOfContents = headers
.filter(header => filterRe.test(header.rawContent))
.map(header => ` - [${header.rawContent}](#${header.hashLink})`)
.join('\n');
return rawContent.replace(TABLE_OF_CONTENTS_TOKEN, tableOfContents);
};
function isSeparateCss(file) {
if (!siteConfig.separateCss) {
return false;
}
for (let i = 0; i < siteConfig.separateCss.length; i++) {
if (file.includes(siteConfig.separateCss[i])) {
return true;
}
}
return false;
}
function requestFile(url, res, notFoundCallback) {
request.get(url, (error, response, body) => {
if (!error) {
@ -183,7 +150,7 @@ function execute(port, options) {
const app = express();
// handle all requests for document pages
app.get(docsRouting(siteConfig.baseUrl), (req, res, next) => {
app.get(routing.docs(siteConfig.baseUrl), (req, res, next) => {
const url = req.path.toString().replace(siteConfig.baseUrl, '');
// links is a map from a permalink to an id for each document
@ -193,23 +160,7 @@ function execute(port, options) {
links[metadata.permalink] = id;
});
// mdToHtml is a map from a markdown file name to its html link, used to
// change relative markdown links that work on GitHub into actual site links
const mdToHtml = {};
Object.keys(Metadata).forEach(id => {
const metadata = Metadata[id];
if (metadata.language !== 'en' || metadata.original_id) {
return;
}
let htmlLink =
siteConfig.baseUrl + metadata.permalink.replace('/next/', '/');
if (htmlLink.includes('/docs/en/')) {
htmlLink = htmlLink.replace('/docs/en/', '/docs/en/VERSION/');
} else {
htmlLink = htmlLink.replace('/docs/', '/docs/VERSION/');
}
mdToHtml[metadata.source] = htmlLink;
});
const mdToHtml = metadataUtils.mdToHtml(Metadata, siteConfig.baseUrl);
const metadata = Metadata[links[url]];
if (!metadata) {
@ -242,16 +193,14 @@ function execute(port, options) {
).rawContent;
// generate table of contents if appropriate
if (rawContent && rawContent.indexOf(TABLE_OF_CONTENTS_TOKEN) !== -1) {
rawContent = insertTableOfContents(rawContent);
}
rawContent = insertTOC(rawContent);
const defaultVersion = env.versioning.defaultVersion;
// replace any links to markdown files to their website html links
Object.keys(mdToHtml).forEach(key => {
let link = mdToHtml[key];
link = utils.getPath(link, siteConfig.cleanUrl);
link = getPath(link, siteConfig.cleanUrl);
link = link.replace('/en/', `/${language}/`);
link = link.replace(
'/VERSION/',
@ -259,14 +208,9 @@ function execute(port, options) {
? `/${metadata.version}/`
: '/'
);
// replace relative links without "./"
// replace relative links with & without "./"
rawContent = rawContent.replace(
new RegExp(`\\]\\(${key}`, 'g'),
`](${link}`
);
// replace relative links with "./"
rawContent = rawContent.replace(
new RegExp(`\\]\\(\\./${key}`, 'g'),
new RegExp(`\\]\\((${key}|\\./${key})`, 'g'),
`](${link}`
);
});
@ -305,7 +249,7 @@ function execute(port, options) {
res.send(renderToStaticMarkupWithDoctype(docComp));
});
app.get(sitemapRouting(siteConfig.baseUrl), (req, res) => {
app.get(routing.sitemap(siteConfig.baseUrl), (req, res) => {
sitemap((err, xml) => {
if (err) {
res.status(500).send('Sitemap error');
@ -316,7 +260,7 @@ function execute(port, options) {
});
});
app.get(feedRouting(siteConfig.baseUrl), (req, res, next) => {
app.get(routing.feed(siteConfig.baseUrl), (req, res, next) => {
res.set('Content-Type', 'application/rss+xml');
const file = req.path
.toString()
@ -331,7 +275,7 @@ function execute(port, options) {
});
// Handle all requests for blog pages and posts.
app.get(blogRouting(siteConfig.baseUrl), (req, res, next) => {
app.get(routing.blog(siteConfig.baseUrl), (req, res, next) => {
// Regenerate the blog metadata in case it has changed. Consider improving
// this to regenerate on file save rather than on page request.
reloadMetadataBlog();
@ -421,7 +365,7 @@ function execute(port, options) {
});
// handle all other main pages
app.get(pageRouting(siteConfig.baseUrl), (req, res, next) => {
app.get(routing.page(siteConfig.baseUrl), (req, res, next) => {
// Look for user-provided HTML file first.
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, '');
htmlFile = join(CWD, 'pages', htmlFile);
@ -541,7 +485,7 @@ function execute(port, options) {
const files = glob.sync(join(CWD, 'static', '**', '*.css'));
files.forEach(file => {
if (isSeparateCss(file)) {
if (isSeparateCss(file, siteConfig.separateCss)) {
return;
}
cssContent = `${cssContent}\n${fs.readFileSync(file, {
@ -596,7 +540,7 @@ function execute(port, options) {
// "redirect" requests to pages ending with "/" or no extension so that,
// for example, request to "blog" returns "blog/index.html" or "blog.html"
app.get(noExtRouting(), (req, res, next) => {
app.get(routing.noExtension(), (req, res, next) => {
const slash = req.path.toString().endsWith('/') ? '' : '/';
const requestUrl = `http://localhost:${port}${req.path}`;
requestFile(`${requestUrl + slash}index.html`, res, () => {
@ -612,7 +556,7 @@ function execute(port, options) {
// handle special cleanUrl case like '/blog/1.2.3' & '/blog.robots.hai'
// where we should try to serve 'blog/1.2.3.html' & '/blog.robots.hai.html'
app.get(dotRouting(), (req, res, next) => {
app.get(routing.dotfiles(), (req, res, next) => {
if (!siteConfig.cleanUrl) {
next();
return;