Speed up test suite by using local npm.js stub
This commit is contained in:
parent
f362fa9717
commit
c3dc2dd014
@ -3,9 +3,9 @@ module.exports = {
|
||||
'\\.css$': '<rootDir>/modules/__mocks__/styleMock.js',
|
||||
'\\.png$': '<rootDir>/modules/__mocks__/imageMock.js',
|
||||
'entry-manifest': '<rootDir>/modules/__mocks__/entryManifest.js',
|
||||
'getStats\\.js': '<rootDir>/modules/__mocks__/getStatsMock.js'
|
||||
'getStats\\.js': '<rootDir>/modules/__mocks__/getStatsMock.js',
|
||||
'utils\\/npm\\.js': '<rootDir>/modules/__mocks__/npmMock.js'
|
||||
},
|
||||
testMatch: ['**/__tests__/*-test.js'],
|
||||
testURL: 'http://localhost/',
|
||||
setupTestFrameworkScriptFile: './jest.setup.js'
|
||||
testURL: 'http://localhost/'
|
||||
};
|
||||
|
@ -1,4 +0,0 @@
|
||||
// TODO: Mock out the registry so tests don't actually hit
|
||||
// the real registry so they don't take so long. Then we can
|
||||
// remove this.
|
||||
jest.setTimeout(10000);
|
1
modules/__mocks__/metadata/@babel/core.json
Normal file
1
modules/__mocks__/metadata/@babel/core.json
Normal file
File diff suppressed because one or more lines are too long
1
modules/__mocks__/metadata/preact.json
Normal file
1
modules/__mocks__/metadata/preact.json
Normal file
File diff suppressed because one or more lines are too long
1
modules/__mocks__/metadata/react.json
Normal file
1
modules/__mocks__/metadata/react.json
Normal file
File diff suppressed because one or more lines are too long
1
modules/__mocks__/metadata/sinuous.json
Normal file
1
modules/__mocks__/metadata/sinuous.json
Normal file
File diff suppressed because one or more lines are too long
33
modules/__mocks__/npmMock.js
Normal file
33
modules/__mocks__/npmMock.js
Normal file
@ -0,0 +1,33 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
function getPackageInfo(packageName) {
|
||||
const file = path.resolve(__dirname, `./metadata/${packageName}.json`);
|
||||
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(file, 'utf-8'));
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function getVersionsAndTags(packageName) {
|
||||
const info = getPackageInfo(packageName);
|
||||
return info
|
||||
? { versions: Object.keys(info.versions), tags: info['dist-tags'] }
|
||||
: [];
|
||||
}
|
||||
|
||||
export function getPackageConfig(packageName, version) {
|
||||
const info = getPackageInfo(packageName);
|
||||
return info ? info.versions[version] : null;
|
||||
}
|
||||
|
||||
export function getPackage(packageName, version) {
|
||||
const file = path.resolve(
|
||||
__dirname,
|
||||
`./packages/${packageName}-${version}.tgz`
|
||||
);
|
||||
|
||||
return fs.existsSync(file) ? fs.createReadStream(file) : null;
|
||||
}
|
BIN
modules/__mocks__/packages/@babel/core-7.5.4.tgz
Normal file
BIN
modules/__mocks__/packages/@babel/core-7.5.4.tgz
Normal file
Binary file not shown.
BIN
modules/__mocks__/packages/preact-8.4.2.tgz
Normal file
BIN
modules/__mocks__/packages/preact-8.4.2.tgz
Normal file
Binary file not shown.
BIN
modules/__mocks__/packages/react-16.8.0.tgz
Normal file
BIN
modules/__mocks__/packages/react-16.8.0.tgz
Normal file
Binary file not shown.
BIN
modules/__mocks__/packages/sinuous-0.12.9.tgz
Normal file
BIN
modules/__mocks__/packages/sinuous-0.12.9.tgz
Normal file
Binary file not shown.
@ -10,7 +10,7 @@ describe('A request for a JavaScript file', () => {
|
||||
|
||||
it('returns 200', done => {
|
||||
request(server)
|
||||
.get('/react@16.8.6/index.js')
|
||||
.get('/react@16.8.0/index.js')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.headers['content-type']).toMatch(
|
||||
|
@ -10,7 +10,7 @@ describe('A request for metadata', () => {
|
||||
|
||||
it('returns 200', done => {
|
||||
request(server)
|
||||
.get('/react@16.8.6/?meta')
|
||||
.get('/react@16.8.0/?meta')
|
||||
.end((err, res) => {
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.headers['content-type']).toMatch(/\bapplication\/json\b/);
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
|
||||
import semver from 'semver';
|
||||
|
||||
import BrowseApp from '../client/browse/App.js';
|
||||
import MainTemplate from '../templates/MainTemplate.js';
|
||||
import asyncHandler from '../utils/asyncHandler.js';
|
||||
import getScripts from '../utils/getScripts.js';
|
||||
import { createElement, createHTML } from '../utils/markup.js';
|
||||
import { getAvailableVersions } from '../utils/npm.js';
|
||||
import { getVersionsAndTags } from '../utils/npm.js';
|
||||
|
||||
const doctype = '<!DOCTYPE html>';
|
||||
const globalURLs =
|
||||
@ -21,6 +22,15 @@ const globalURLs =
|
||||
'react-dom': '/react-dom@16.8.6/umd/react-dom.development.js'
|
||||
};
|
||||
|
||||
function byVersion(a, b) {
|
||||
return semver.lt(a, b) ? -1 : semver.gt(a, b) ? 1 : 0;
|
||||
}
|
||||
|
||||
async function getAvailableVersions(packageName) {
|
||||
const versionsAndTags = await getVersionsAndTags(packageName);
|
||||
return versionsAndTags ? versionsAndTags.versions.sort(byVersion) : [];
|
||||
}
|
||||
|
||||
async function serveBrowsePage(req, res) {
|
||||
const availableVersions = await getAvailableVersions(req.packageName);
|
||||
const data = {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import semver from 'semver';
|
||||
|
||||
import asyncHandler from '../utils/asyncHandler.js';
|
||||
import createPackageURL from '../utils/createPackageURL.js';
|
||||
import { getPackageConfig, resolveVersion } from '../utils/npm.js';
|
||||
import { getPackageConfig, getVersionsAndTags } from '../utils/npm.js';
|
||||
|
||||
function semverRedirect(req, res, newVersion) {
|
||||
res
|
||||
@ -15,6 +17,24 @@ function semverRedirect(req, res, newVersion) {
|
||||
);
|
||||
}
|
||||
|
||||
async function resolveVersion(packageName, range) {
|
||||
const versionsAndTags = await getVersionsAndTags(packageName);
|
||||
|
||||
if (versionsAndTags) {
|
||||
const { versions, tags } = versionsAndTags;
|
||||
|
||||
if (range in tags) {
|
||||
range = tags[range];
|
||||
}
|
||||
|
||||
return versions.includes(range)
|
||||
? range
|
||||
: semver.maxSatisfying(versions, range);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the package version/tag in the URL and make sure it's good. Also
|
||||
* fetch the package config and add it to req.packageConfig. Redirect to
|
||||
|
@ -1,7 +1,6 @@
|
||||
import url from 'url';
|
||||
import https from 'https';
|
||||
import LRUCache from 'lru-cache';
|
||||
import semver from 'semver';
|
||||
|
||||
import debug from './debug.js';
|
||||
import bufferStream from './bufferStream.js';
|
||||
@ -77,18 +76,16 @@ async function fetchPackageInfo(packageName) {
|
||||
|
||||
async function fetchVersionsAndTags(packageName) {
|
||||
const info = await fetchPackageInfo(packageName);
|
||||
|
||||
if (info && info.versions) {
|
||||
return {
|
||||
versions: Object.keys(info.versions),
|
||||
tags: info['dist-tags']
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
return info && info.versions
|
||||
? { versions: Object.keys(info.versions), tags: info['dist-tags'] }
|
||||
: null;
|
||||
}
|
||||
|
||||
async function getVersionsAndTags(packageName) {
|
||||
/**
|
||||
* Returns an object of available { versions, tags }.
|
||||
* Uses a cache to avoid over-fetching from the registry.
|
||||
*/
|
||||
export async function getVersionsAndTags(packageName) {
|
||||
const cacheKey = `versions-${packageName}`;
|
||||
const cacheValue = cache.get(cacheKey);
|
||||
|
||||
@ -107,45 +104,6 @@ async function getVersionsAndTags(packageName) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function byVersion(a, b) {
|
||||
return semver.lt(a, b) ? -1 : semver.gt(a, b) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of available versions, sorted by semver.
|
||||
*/
|
||||
export async function getAvailableVersions(packageName) {
|
||||
const versionsAndTags = await getVersionsAndTags(packageName);
|
||||
|
||||
if (versionsAndTags) {
|
||||
return versionsAndTags.versions.sort(byVersion);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the semver range or tag to a valid version.
|
||||
* Output is cached to avoid over-fetching from the registry.
|
||||
*/
|
||||
export async function resolveVersion(packageName, range) {
|
||||
const versionsAndTags = await getVersionsAndTags(packageName);
|
||||
|
||||
if (versionsAndTags) {
|
||||
const { versions, tags } = versionsAndTags;
|
||||
|
||||
if (range in tags) {
|
||||
range = tags[range];
|
||||
}
|
||||
|
||||
return versions.includes(range)
|
||||
? range
|
||||
: semver.maxSatisfying(versions, range);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// All the keys that sometimes appear in package info
|
||||
// docs that we don't need. There are probably more.
|
||||
const packageConfigExcludeKeys = [
|
||||
@ -160,10 +118,10 @@ const packageConfigExcludeKeys = [
|
||||
'scripts'
|
||||
];
|
||||
|
||||
function cleanPackageConfig(doc) {
|
||||
return Object.keys(doc).reduce((memo, key) => {
|
||||
function cleanPackageConfig(config) {
|
||||
return Object.keys(config).reduce((memo, key) => {
|
||||
if (!key.startsWith('_') && !packageConfigExcludeKeys.includes(key)) {
|
||||
memo[key] = doc[key];
|
||||
memo[key] = config[key];
|
||||
}
|
||||
|
||||
return memo;
|
||||
@ -172,17 +130,14 @@ function cleanPackageConfig(doc) {
|
||||
|
||||
async function fetchPackageConfig(packageName, version) {
|
||||
const info = await fetchPackageInfo(packageName);
|
||||
|
||||
if (!info || !(version in info.versions)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return cleanPackageConfig(info.versions[version]);
|
||||
return info && info.versions && version in info.versions
|
||||
? cleanPackageConfig(info.versions[version])
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns metadata about a package, mostly the same as package.json.
|
||||
* Output is cached to avoid over-fetching from the registry.
|
||||
* Uses a cache to avoid over-fetching from the registry.
|
||||
*/
|
||||
export async function getPackageConfig(packageName, version) {
|
||||
const cacheKey = `config-${packageName}-${version}`;
|
||||
|
Loading…
x
Reference in New Issue
Block a user