From e327f88f028579023ce93f04d66b9606ec476547 Mon Sep 17 00:00:00 2001 From: Jean Lauliac Date: Mon, 17 Sep 2018 05:43:43 -0700 Subject: [PATCH] react-native: make automated fs-based tests platform-independent 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 https://github.com/facebook/react-native/issues/20260. Reviewed By: mjesun Differential Revision: D9771024 fbshipit-source-id: b368b43e8e54292d33b6183eec9a9ea69f2e6e76 --- local-cli/__mocks__/fs.js | 34 +++++++--- local-cli/__mocks__/path.js | 20 ++++++ local-cli/core/__fixtures__/android.js | 11 ++- .../android/findAndroidAppFolder.spec.js | 1 + .../__tests__/android/findManifest.spec.js | 1 + .../android/findPackageClassName.spec.js | 67 +++++++++++-------- .../android/getDependencyConfig.spec.js | 1 + .../android/getProjectConfig.spec.js | 1 + .../__tests__/android/readManifest.spec.js | 1 + local-cli/core/__tests__/findAssets.spec.js | 1 + .../__tests__/ios/findPodfilePath.spec.js | 1 + .../__tests__/ios/findPodspecName.spec.js | 1 + .../core/__tests__/ios/findProject.spec.js | 1 + .../__tests__/ios/getProjectConfig.spec.js | 1 + .../link/__tests__/ios/writePlist.spec.js | 1 + .../__tests__/findSymlinkedModules-test.js | 1 + 16 files changed, 105 insertions(+), 39 deletions(-) create mode 100644 local-cli/__mocks__/path.js diff --git a/local-cli/__mocks__/fs.js b/local-cli/__mocks__/fs.js index b2e2f9766..a3691e3f3 100644 --- a/local-cli/__mocks__/fs.js +++ b/local-cli/__mocks__/fs.js @@ -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; @@ -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); +} -module.exports = fs; +const mockFs = {}; +mockFs.__setMockFilesystem = setMockFilesystem; +mockFs.mock = {clear: reset}; + +reset('posix'); + +module.exports = mockFs; diff --git a/local-cli/__mocks__/path.js b/local-cli/__mocks__/path.js new file mode 100644 index 000000000..884c3eac9 --- /dev/null +++ b/local-cli/__mocks__/path.js @@ -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; diff --git a/local-cli/core/__fixtures__/android.js b/local-cli/core/__fixtures__/android.js index 2d6447b87..07e1ee279 100644 --- a/local-cli/core/__fixtures__/android.js +++ b/local-cli/core/__fixtures__/android.js @@ -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'), diff --git a/local-cli/core/__tests__/android/findAndroidAppFolder.spec.js b/local-cli/core/__tests__/android/findAndroidAppFolder.spec.js index 00324c8e9..331dfe8e1 100644 --- a/local-cli/core/__tests__/android/findAndroidAppFolder.spec.js +++ b/local-cli/core/__tests__/android/findAndroidAppFolder.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const fs = require('fs'); diff --git a/local-cli/core/__tests__/android/findManifest.spec.js b/local-cli/core/__tests__/android/findManifest.spec.js index 4bae9022d..242b20a74 100644 --- a/local-cli/core/__tests__/android/findManifest.spec.js +++ b/local-cli/core/__tests__/android/findManifest.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const findManifest = require('../../android/findManifest'); diff --git a/local-cli/core/__tests__/android/findPackageClassName.spec.js b/local-cli/core/__tests__/android/findPackageClassName.spec.js index abf78b9df..5c15fd658 100644 --- a/local-cli/core/__tests__/android/findPackageClassName.spec.js +++ b/local-cli/core/__tests__/android/findPackageClassName.spec.js @@ -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(root + 'flatJava')).toBe('string'); + }); + + 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(root + 'flatKotlin')).toBe( + 'SomeExampleKotlinPackage', + ); + }); + + it('returns `null` if there are no matches', () => { + expect(findPackageClassName(root + 'empty')).toBeNull(); }); }); - - it('returns manifest content if file exists in the folder', () => { - expect(typeof findPackageClassName('/flatJava')).toBe('string'); - }); - - it('returns the name of the java class implementing ReactPackage', () => { - expect(findPackageClassName('/flatJava')).toBe('SomeExampleJavaPackage'); - }); - - it('returns the name of the kotlin class implementing ReactPackage', () => { - expect(findPackageClassName('/flatKotlin')).toBe( - 'SomeExampleKotlinPackage', - ); - }); - - it('returns `null` if there are no matches', () => { - expect(findPackageClassName('/empty')).toBeNull(); - }); }); diff --git a/local-cli/core/__tests__/android/getDependencyConfig.spec.js b/local-cli/core/__tests__/android/getDependencyConfig.spec.js index ddba5bf4f..7a43db319 100644 --- a/local-cli/core/__tests__/android/getDependencyConfig.spec.js +++ b/local-cli/core/__tests__/android/getDependencyConfig.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const getDependencyConfig = require('../../android').dependencyConfig; diff --git a/local-cli/core/__tests__/android/getProjectConfig.spec.js b/local-cli/core/__tests__/android/getProjectConfig.spec.js index 356f3455b..863138c95 100644 --- a/local-cli/core/__tests__/android/getProjectConfig.spec.js +++ b/local-cli/core/__tests__/android/getProjectConfig.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const getProjectConfig = require('../../android').projectConfig; diff --git a/local-cli/core/__tests__/android/readManifest.spec.js b/local-cli/core/__tests__/android/readManifest.spec.js index bd733af16..2b8f41e4f 100644 --- a/local-cli/core/__tests__/android/readManifest.spec.js +++ b/local-cli/core/__tests__/android/readManifest.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const findManifest = require('../../android/findManifest'); diff --git a/local-cli/core/__tests__/findAssets.spec.js b/local-cli/core/__tests__/findAssets.spec.js index a2d65df46..cf880b23d 100644 --- a/local-cli/core/__tests__/findAssets.spec.js +++ b/local-cli/core/__tests__/findAssets.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const findAssets = require('../findAssets'); diff --git a/local-cli/core/__tests__/ios/findPodfilePath.spec.js b/local-cli/core/__tests__/ios/findPodfilePath.spec.js index 55af185b2..227d24512 100644 --- a/local-cli/core/__tests__/ios/findPodfilePath.spec.js +++ b/local-cli/core/__tests__/ios/findPodfilePath.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const findPodfilePath = require('../../ios/findPodfilePath'); diff --git a/local-cli/core/__tests__/ios/findPodspecName.spec.js b/local-cli/core/__tests__/ios/findPodspecName.spec.js index c499b0512..14d73cd7d 100644 --- a/local-cli/core/__tests__/ios/findPodspecName.spec.js +++ b/local-cli/core/__tests__/ios/findPodspecName.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const findPodspecName = require('../../ios/findPodspecName'); diff --git a/local-cli/core/__tests__/ios/findProject.spec.js b/local-cli/core/__tests__/ios/findProject.spec.js index d792f72db..0083e9bd0 100644 --- a/local-cli/core/__tests__/ios/findProject.spec.js +++ b/local-cli/core/__tests__/ios/findProject.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const findProject = require('../../ios/findProject'); diff --git a/local-cli/core/__tests__/ios/getProjectConfig.spec.js b/local-cli/core/__tests__/ios/getProjectConfig.spec.js index 0f9b25e22..d1af61e4b 100644 --- a/local-cli/core/__tests__/ios/getProjectConfig.spec.js +++ b/local-cli/core/__tests__/ios/getProjectConfig.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); const getProjectConfig = require('../../ios').projectConfig; diff --git a/local-cli/link/__tests__/ios/writePlist.spec.js b/local-cli/link/__tests__/ios/writePlist.spec.js index b87627b1d..1bdb4ed82 100644 --- a/local-cli/link/__tests__/ios/writePlist.spec.js +++ b/local-cli/link/__tests__/ios/writePlist.spec.js @@ -10,6 +10,7 @@ 'use strict'; +jest.mock('path'); jest.mock('fs'); let plistPath = null; diff --git a/local-cli/util/__tests__/findSymlinkedModules-test.js b/local-cli/util/__tests__/findSymlinkedModules-test.js index 02337f1a2..fbdfd7463 100644 --- a/local-cli/util/__tests__/findSymlinkedModules-test.js +++ b/local-cli/util/__tests__/findSymlinkedModules-test.js @@ -8,6 +8,7 @@ * @emails oncall+javascript_foundation */ +jest.mock('path'); jest.mock('fs'); const fs = require('fs');