Skip to content

Commit

Permalink
react-native: make automated fs-based tests platform-independent
Browse files Browse the repository at this point in the history
Summary:
@public

These tests are using a mock memory FS to start with, so there is no reason at all they should depend on the host OS or filesystem details. This changeset fixes that so that we fully mock the `fs` and `path` modules dependending on the mock platform (not the host platform). I also added an example of how we can test both platforms (regardless of the host platform) in `findPackageClassName`. Follow up changeset will be to do the same for all the other affected tests.

Related to facebook/react-native#20260.

Reviewed By: mjesun

Differential Revision: D9771024

fbshipit-source-id: b368b43e8e54292d33b6183eec9a9ea69f2e6e76
  • Loading branch information
Jean Lauliac authored and facebook-github-bot committed Sep 17, 2018
1 parent 5bf8b5a commit 5b75963
Show file tree
Hide file tree
Showing 16 changed files with 101 additions and 35 deletions.
34 changes: 26 additions & 8 deletions __mocks__/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@

'use strict';

const fs = new (require('metro-memory-fs'))({cwd: process.cwd});
const path = require('path');
const MemoryFS = require('metro-memory-fs');
let fs;

function setMockFilesystem(object) {
fs.reset();
const root = process.platform === 'win32' ? 'c:\\' : '/';
function setMockFilesystem(object, platform) {
reset(platform);
const root = platform === 'win32' ? 'c:\\' : '/';
mockDir(root, {...object});
return root;
}

function mockDir(dirPath, desc) {
for (const entName in desc) {
const ent = desc[entName];
const entPath = require('path').join(dirPath, entName);
const entPath = path.join(dirPath, entName);
if (typeof ent === 'string' || ent instanceof Buffer) {
fs.writeFileSync(entPath, ent);
continue;
Expand All @@ -37,7 +40,22 @@ function mockDir(dirPath, desc) {
}
}

fs.__setMockFilesystem = setMockFilesystem;
fs.mock = {clear: () => fs.reset()};
function reset(platform) {
if (path.mock == null) {
throw new Error(
'to use this "fs" module mock, you must also mock the "path" module',
);
}
path.mock.reset(platform);
const cwd = () => (platform === 'win32' ? 'c:\\' : '/');
fs = new MemoryFS({platform, cwd});
Object.assign(mockFs, fs);
}

const mockFs = {};
mockFs.__setMockFilesystem = setMockFilesystem;
mockFs.mock = {clear: reset};

reset('posix');

module.exports = fs;
module.exports = mockFs;
20 changes: 20 additions & 0 deletions __mocks__/path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

'use strict';

const mockPath = {};

function reset(platform) {
Object.assign(mockPath, jest.requireActual('path')[platform]);
}

mockPath.mock = {reset};

module.exports = mockPath;
11 changes: 9 additions & 2 deletions core/__fixtures__/android.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/** @format */
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

const fs = require.requireActual('fs');
const path = require('path');
const path = require.requireActual('path');

const manifest = fs.readFileSync(
path.join(__dirname, './files/AndroidManifest.xml'),
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/android/findAndroidAppFolder.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const fs = require('fs');
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/android/findManifest.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const findManifest = require('../../android/findManifest');
Expand Down
59 changes: 34 additions & 25 deletions core/__tests__/android/findPackageClassName.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,49 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const mocks = require('../../__fixtures__/android');
const findPackageClassName = require('../../android/findPackageClassName');
const fs = require('fs');
const mocks = require('../../__fixtures__/android');

describe('android::findPackageClassName', () => {
beforeAll(() => {
fs.__setMockFilesystem({
empty: {},
flatJava: {
android: mocks.valid,
},
flatKotlin: {
android: mocks.validKotlin,
},
['posix', 'win32'].forEach(platform => {
let root;
describe(`android::findPackageClassName (${platform})`, () => {
beforeAll(() => {
root = fs.__setMockFilesystem(
{
empty: {},
flatJava: {
android: mocks.valid,
},
flatKotlin: {
android: mocks.validKotlin,
},
},
platform,
);
});
});

it('returns manifest content if file exists in the folder', () => {
expect(typeof findPackageClassName('/flatJava')).toBe('string');
});
it('returns manifest content if file exists in the folder', () => {
expect(typeof findPackageClassName(root + 'flatJava')).toBe('string');
});

it('returns the name of the java class implementing ReactPackage', () => {
expect(findPackageClassName('/flatJava')).toBe('SomeExampleJavaPackage');
});
it('returns the name of the java class implementing ReactPackage', () => {
expect(findPackageClassName(root + 'flatJava')).toBe(
'SomeExampleJavaPackage',
);
});

it('returns the name of the kotlin class implementing ReactPackage', () => {
expect(findPackageClassName('/flatKotlin')).toBe(
'SomeExampleKotlinPackage',
);
});
it('returns the name of the kotlin class implementing ReactPackage', () => {
expect(findPackageClassName(root + 'flatKotlin')).toBe(
'SomeExampleKotlinPackage',
);
});

it('returns `null` if there are no matches', () => {
expect(findPackageClassName('/empty')).toBeNull();
it('returns `null` if there are no matches', () => {
expect(findPackageClassName(root + 'empty')).toBeNull();
});
});
});
1 change: 1 addition & 0 deletions core/__tests__/android/getDependencyConfig.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const getDependencyConfig = require('../../android').dependencyConfig;
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/android/getProjectConfig.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const getProjectConfig = require('../../android').projectConfig;
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/android/readManifest.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const findManifest = require('../../android/findManifest');
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/findAssets.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const findAssets = require('../findAssets');
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/ios/findPodfilePath.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const findPodfilePath = require('../../ios/findPodfilePath');
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/ios/findPodspecName.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const findPodspecName = require('../../ios/findPodspecName');
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/ios/findProject.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const findProject = require('../../ios/findProject');
Expand Down
1 change: 1 addition & 0 deletions core/__tests__/ios/getProjectConfig.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

const getProjectConfig = require('../../ios').projectConfig;
Expand Down
1 change: 1 addition & 0 deletions link/__tests__/ios/writePlist.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

jest.mock('path');
jest.mock('fs');

let plistPath = null;
Expand Down
1 change: 1 addition & 0 deletions util/__tests__/findSymlinkedModules-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* @emails oncall+javascript_foundation
*/

jest.mock('path');
jest.mock('fs');

const fs = require('fs');
Expand Down

0 comments on commit 5b75963

Please sign in to comment.