Skip to content

Commit

Permalink
Add tests for custom haste map
Browse files Browse the repository at this point in the history
  • Loading branch information
DiZy committed May 10, 2021
1 parent 7452947 commit 8a6d5d8
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 23 deletions.
30 changes: 30 additions & 0 deletions e2e/__tests__/customHaste.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import * as path from 'path';
import runJest from '../runJest';

describe('Custom Haste Integration', () => {
test('valid test with fake module resolutions', () => {
const config = {
haste: {
hasteMapModulePath: path.resolve(
__dirname,
'..',
'custom-haste-map/hasteMap.js',
),
},
};

const {exitCode} = runJest('custom-haste-map', [
'--config',
JSON.stringify(config),
'hasteExample.test.js',
]);
expect(exitCode).toBe(0);
});
});
18 changes: 18 additions & 0 deletions e2e/custom-haste-map/__tests__/hasteExample.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

'use strict';

const add = require('fakeModuleName');

describe('Custom Haste', () => {
test('adds ok', () => {
expect(true).toBe(true);
expect(add(1, 2)).toBe(3);
});
});
5 changes: 5 additions & 0 deletions e2e/custom-haste-map/__tests__/hasteExampleHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function add(a, b) {
return a + b;
}

module.exports = add;
139 changes: 139 additions & 0 deletions e2e/custom-haste-map/hasteMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

const path = require('path');
const fakeFile = {
file: path.resolve(__dirname, '__tests__/hasteExampleHelper.js'),
moduleName: 'fakeModuleName',
sha1: 'fakeSha1',
};

const fakeJSON = 'fakeJSON';

const testPath = path.resolve(__dirname, '__tests__/hasteExample.test.js');

const allFiles = [fakeFile.file, testPath];

class HasteFS {
getModuleName(file) {
if (file === fakeFile.file) {
return fakeFile.moduleName;
}
return null;
}

getSize(file) {
return null;
}

getDependencies(file) {
if (file === testPath) {
return fakeFile.file;
}
return [];
}

getSha1(file) {
if (file === fakeFile.file) {
return fakeFile.sha1;
}
return null;
}

exists(file) {
return allFiles.includes(file);
}

getAllFiles() {
return allFiles;
}

getFileIterator() {
return allFiles;
}

getAbsoluteFileIterator() {
return allFiles;
}

matchFiles(pattern) {
if (!(pattern instanceof RegExp)) {
pattern = new RegExp(pattern);
}
const files = [];
for (const file of this.getAbsoluteFileIterator()) {
if (pattern.test(file)) {
files.push(file);
}
}
return files;
}

matchFilesWithGlob(globs, root) {
return [];
}
}

class ModuleMap {
getModule(name, platform, supportsNativePlatform, type) {
if (name === fakeFile.moduleName) {
return fakeFile.file;
}
return null;
}

getPackage() {
return null;
}

getMockModule() {
return undefined;
}

getRawModuleMap() {
return {};
}

toJSON() {
return fakeJSON;
}
}

class HasteMap {
constructor(options) {
this._cachePath = HasteMap.getCacheFilePath(
options.cacheDirectory,
options.name,
);
}

async build() {
return {
hasteFS: new HasteFS(),
moduleMap: new ModuleMap(),
};
}

static getCacheFilePath(tmpdir, name) {
return path.join(tmpdir, name);
}

getCacheFilePath() {
return this._cachePath;
}

static getModuleMapFromJSON(json) {
if (json === fakeJSON) {
return new ModuleMap();
}
throw new Error('Failed to parse serialized module map');
}
}

module.exports = HasteMap;
7 changes: 7 additions & 0 deletions e2e/custom-haste-map/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"jest": {
"haste": {
"hasteMapModulePath": "<rootDir>/hasteMap.js"
}
}
}
1 change: 1 addition & 0 deletions packages/jest-config/src/ValidConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const initialOptions: Config.InitialOptions = {
enableSymlinks: false,
forceNodeFilesystemAPI: false,
hasteImplModulePath: '<rootDir>/haste_impl.js',
hasteMapModulePath: '',
platforms: ['ios', 'android'],
throwOnModuleCollision: false,
},
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-haste-map/src/ModuleMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type SerializableModuleMap = {
rootDir: Config.Path;
};

export interface IModuleMap {
export interface IModuleMap<S = SerializableModuleMap> {
getModule(
name: string,
platform?: string | null,
Expand All @@ -47,10 +47,10 @@ export interface IModuleMap {

getRawModuleMap(): RawModuleMap;

toJSON(): SerializableModuleMap;
toJSON(): S;
}

export default class ModuleMap implements IModuleMap {
export default class ModuleMap implements IModuleMap<SerializableModuleMap> {
static DuplicateHasteCandidatesError: typeof DuplicateHasteCandidatesError;
private readonly _raw: RawModuleMap;
private json: SerializableModuleMap | undefined;
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-haste-map/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,14 @@ function invariant(condition: unknown, message?: string): asserts condition {
}
}

export type HasteMapStatic = {
export type HasteMapStatic<S = SerializableModuleMap> = {
new (options: Options): HasteMap;
getCacheFilePath(
tmpdir: Config.Path,
name: string,
...extra: Array<string>
): string;
getModuleMapFromJSON(json: SerializableModuleMap): IModuleMap;
getModuleMapFromJSON(json: S): IModuleMap<S>;
};

/**
Expand Down
5 changes: 4 additions & 1 deletion packages/jest-haste-map/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import type {Stats} from 'graceful-fs';
import type {Config} from '@jest/types';
import type HasteFS from './HasteFS';
import type ModuleMap, {IModuleMap} from './ModuleMap';
// eslint-disable-next-line import/no-duplicates
import type ModuleMap from './ModuleMap';
// eslint-disable-next-line import/no-duplicates
import type {IModuleMap} from './ModuleMap';

export type IgnoreMatcher = (item: string) => boolean;

Expand Down
7 changes: 3 additions & 4 deletions packages/jest-runner/src/testWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ export function setup(setupData: {
config,
serializableModuleMap,
} of setupData.serializableResolvers) {
const HasteMapClass =
config.hasteMapModulePath !== undefined
? (require(config.hasteMapModulePath) as HasteMapStatic)
: HasteMap;
const HasteMapClass = config.haste.hasteMapModulePath
? (require(config.haste.hasteMapModulePath) as HasteMapStatic)
: HasteMap;
const moduleMap = HasteMapClass.getModuleMapFromJSON(serializableModuleMap);
resolvers.set(config.name, Runtime.createResolver(config, moduleMap));
}
Expand Down
7 changes: 3 additions & 4 deletions packages/jest-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,9 @@ export default class Runtime {
? new RegExp(ignorePatternParts.join('|'))
: undefined;

const HasteMapClass =
config.hasteMapModulePath !== undefined
? (require(config.hasteMapModulePath) as HasteMapStatic)
: HasteMap;
const HasteMapClass = config.haste.hasteMapModulePath
? (require(config.haste.hasteMapModulePath) as HasteMapStatic)
: HasteMap;

return new HasteMapClass({
cacheDirectory: config.cacheDirectory,
Expand Down
7 changes: 3 additions & 4 deletions packages/jest-test-sequencer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ export default class TestSequencer {

_getCachePath(context: Context): string {
const {config} = context;
const HasteMapClass =
config.hasteMapModulePath !== undefined
? (require(config.hasteMapModulePath) as HasteMapStatic)
: HasteMap;
const HasteMapClass = config.haste.hasteMapModulePath
? (require(config.haste.hasteMapModulePath) as HasteMapStatic)
: HasteMap;
return HasteMapClass.getCacheFilePath(
config.cacheDirectory,
'perf-cache-' + config.name,
Expand Down
7 changes: 3 additions & 4 deletions packages/jest-transform/src/ScriptTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,9 @@ class ScriptTransformer {
filename: Config.Path,
cacheKey: string,
): Config.Path {
const HasteMapClass =
this._config.hasteMapModulePath !== undefined
? (require(this._config.hasteMapModulePath) as HasteMapStatic)
: HasteMap;
const HasteMapClass = this._config.haste.hasteMapModulePath
? (require(this._config.haste.hasteMapModulePath) as HasteMapStatic)
: HasteMap;
const baseCacheDir = HasteMapClass.getCacheFilePath(
this._config.cacheDirectory,
'jest-transform-cache-' + this._config.name,
Expand Down
3 changes: 2 additions & 1 deletion packages/jest-types/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export type HasteConfig = {
platforms?: Array<string>;
/** Whether to throw on error on module collision. */
throwOnModuleCollision?: boolean;
/** Custom HasteMap */
hasteMapModulePath?: string;
};

export type CoverageReporterName = keyof ReportOptions;
Expand Down Expand Up @@ -345,7 +347,6 @@ export type ProjectConfig = {
globalTeardown?: string;
globals: ConfigGlobals;
haste: HasteConfig;
hasteMapModulePath?: Path;
injectGlobals: boolean;
moduleDirectories: Array<string>;
moduleFileExtensions: Array<string>;
Expand Down

0 comments on commit 8a6d5d8

Please sign in to comment.