Skip to content

Commit

Permalink
chore: migrate upgrade command to TS
Browse files Browse the repository at this point in the history
  • Loading branch information
thymikee committed Sep 9, 2019
1 parent 16065aa commit 37441f9
Show file tree
Hide file tree
Showing 26 changed files with 165 additions and 280 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@
"micromatch": "^3.1.10",
"mkdirp": "^0.5.1",
"string-length": "^2.0.0",
"typescript": "^3.4.5"
"typescript": "^3.6.2"
}
}
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"react-native": "^0.60.0"
},
"devDependencies": {
"@types/semver": "^6.0.2",
"slash": "^3.0.0",
"snapshot-diff": "^0.5.0"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/cliEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import commander from 'commander';
import path from 'path';

import type {CommandT, ConfigT} from 'types';

// $FlowFixMe - converted to TS
import commands from './commands';
import init from './commands/init/initCompat';
import assertRequiredOptions from './tools/assertRequiredOptions';
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/doctor/doctor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import chalk from 'chalk';
import envinfo from 'envinfo';
import {logger} from '@react-native-community/cli-tools';
import {getHealthchecks, HEALTHCHECK_TYPES} from './healthchecks';
// $FlowFixMe - converted to TS
import {getLoader} from '../../tools/loader';
import printFixOptions, {KEYS} from './printFixOptions';
import runAutomaticFix, {AUTOMATIC_FIX_LEVELS} from './runAutomaticFix';
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/doctor/healthchecks/cocoaPods.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow
import {isSoftwareInstalled} from '../checkInstallation';
// $FlowFixMe - converted to TS
import {installCocoaPods} from '../../../tools/installPods';
import {type HealthCheckInterface} from '../types';

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/doctor/healthchecks/common.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import logger from '@react-native-community/cli-tools/build/logger';
import {logger} from '@react-native-community/cli-tools';
import chalk from 'chalk';

// Space is necessary to keep correct ordering on screen
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/doctor/runAutomaticFix.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import chalk from 'chalk';
import ora from 'ora';
import logger from '../../tools/logger';
import {logger} from '@react-native-community/cli-tools';
import {HEALTHCHECK_TYPES} from './healthchecks';
import type {EnvironmentInfo} from './types';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
/**
* @flow
*/
import {type CommandT} from 'types';
import {Command} from '@react-native-community/cli-types';

// @ts-ignore - JS file
import server from './server/server';
// @ts-ignore - JS file
import bundle from './bundle/bundle';
// @ts-ignore - JS file
import ramBundle from './bundle/ramBundle';
// @ts-ignore - JS file
import link from './link/link';
// @ts-ignore - JS file
import unlink from './link/unlink';
// @ts-ignore - JS file
import install from './install/install';
// @ts-ignore - JS file
import uninstall from './install/uninstall';
import upgrade from './upgrade/upgrade';
// @ts-ignore - JS file
import info from './info/info';
// @ts-ignore - JS file
import config from './config/config';
// @ts-ignore - JS file
import init from './init';
// @ts-ignore - JS file
import doctor from './doctor';

export default ([
export default [
server,
bundle,
ramBundle,
Expand All @@ -29,4 +37,4 @@ export default ([
config,
init,
doctor,
]: CommandT[]);
] as Command[];
2 changes: 2 additions & 0 deletions packages/cli/src/commands/init/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import {
} from './template';
import {changePlaceholderInTemplate} from './editTemplate';
import * as PackageManager from '../../tools/packageManager';
// $FlowFixMe - converted to TS
import installPods from '../../tools/installPods';
import {processTemplateName} from './templateName';
import banner from './banner';
// $FlowFixMe - converted to TS
import {getLoader} from '../../tools/loader';
import {CLIError} from '@react-native-community/cli-tools';

Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/commands/link/__tests__/link-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import makeHook from '../makeHook';

jest.mock('chalk', () => ({grey: str => str, bold: str => str}));
jest.mock('../../../tools/config');
jest.mock('../../../tools/logger');
jest.mock('../makeHook', () => {
return jest.fn(() => {
return jest.fn(() => Promise.resolve());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// @flow
import execa from 'execa';
import path from 'path';
import fs from 'fs';
import snapshotDiff from 'snapshot-diff';
import stripAnsi from 'strip-ansi';
import upgrade from '../upgrade';
import {fetch, logger} from '@react-native-community/cli-tools';
import loadConfig from '../../../tools/config';
import loadConfig from '../../../tools/config'; // eslint-disable-line
import merge from '../../../tools/merge';

jest.mock('https');
Expand Down Expand Up @@ -56,7 +55,9 @@ jest.mock('@react-native-community/cli-tools', () => ({
}));

const mockFetch = (value = '', status = 200) => {
(fetch: any).mockImplementation(() => Promise.resolve({data: value, status}));
(fetch as any).mockImplementation(() =>
Promise.resolve({data: value, status}),
);
};

const mockExecaDefault = (command, args) => {
Expand Down Expand Up @@ -85,9 +86,6 @@ const currentVersion = '0.57.8';
const newVersion = '0.58.4';
const olderVersion = '0.56.0';
const ctx = loadConfig();
const opts = {
legacy: false,
};

const samplePatch = jest
.requireActual('fs')
Expand All @@ -101,34 +99,30 @@ const flushOutput = () => stripAnsi(logs.join('\n'));
beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
// $FlowFixMe
fs.writeFileSync = jest.fn(filename => mockPushLog('[fs] write', filename));
// $FlowFixMe
fs.unlinkSync = jest.fn((...args) => mockPushLog('[fs] unlink', args));
logs = [];
(execa: any).mockImplementation(mockExecaDefault);
((execa as unknown) as jest.Mock).mockImplementation(mockExecaDefault);
Object.defineProperty(process, 'platform', {
value: 'darwin',
});
});

afterEach(() => {
// $FlowFixMe
fs.writeFileSync = jest.requireMock('fs').writeFileSync;
// $FlowFixMe
fs.unlinkSync = jest.requireMock('fs').unlinkSync;
});

test('uses latest version of react-native when none passed', async () => {
await upgrade.func([], ctx, opts);
await upgrade.func([], ctx);
expect(execa).toBeCalledWith('npm', ['info', 'react-native', 'version']);
}, 60000);

test('applies patch in current working directory when nested', async () => {
mockFetch(samplePatch, 200);
(execa: any).mockImplementation(mockExecaNested);
((execa as unknown) as jest.Mock).mockImplementation(mockExecaNested);
const config = {...ctx, root: '/project/root/NestedApp'};
await upgrade.func([newVersion], config, opts);
await upgrade.func([newVersion], config);

expect(execa).toBeCalledWith('git', [
'apply',
Expand All @@ -141,33 +135,33 @@ test('applies patch in current working directory when nested', async () => {
});

test('errors when invalid version passed', async () => {
await upgrade.func(['next'], ctx, opts);
await upgrade.func(['next'], ctx);
expect(logger.error).toBeCalledWith(
'Provided version "next" is not allowed. Please pass a valid semver version',
);
}, 60000);

test('errors when older version passed', async () => {
await upgrade.func([olderVersion], ctx, opts);
await upgrade.func([olderVersion], ctx);
expect(logger.error).toBeCalledWith(
`Trying to upgrade from newer version "${currentVersion}" to older "${olderVersion}"`,
);
await upgrade.func(['0.57.10'], ctx, opts);
await upgrade.func(['0.57.10'], ctx);
expect(logger.error).not.toBeCalledWith(
`Trying to upgrade from newer version "${currentVersion}" to older "0.57.10"`,
);
}, 60000);

test('warns when dependency upgrade version is in semver range', async () => {
await upgrade.func([currentVersion], ctx, opts);
await upgrade.func([currentVersion], ctx);
expect(logger.warn).toBeCalledWith(
`Specified version "${currentVersion}" is already installed in node_modules and it satisfies "^0.57.8" semver range. No need to upgrade`,
);
}, 60000);

test('fetches empty patch and installs deps', async () => {
mockFetch();
await upgrade.func([newVersion], ctx, opts);
await upgrade.func([newVersion], ctx);
expect(flushOutput()).toMatchInlineSnapshot(`
"info Fetching diff between v0.57.8 and v0.58.4...
info Diff has no changes to apply, proceeding further
Expand All @@ -192,7 +186,6 @@ test('fetches regular patch, adds remote, applies patch, installs deps, removes
android: {packageName: 'com.testapp'},
},
}),
opts,
);
expect(flushOutput()).toMatchInlineSnapshot(`
"info Fetching diff between v0.57.8 and v0.58.4...
Expand All @@ -215,18 +208,22 @@ test('fetches regular patch, adds remote, applies patch, installs deps, removes
success Upgraded React Native to v0.58.4 🎉. Now you can review and commit the changes"
`);
expect(
snapshotDiff(samplePatch, (fs.writeFileSync: any).mock.calls[0][1], {
contextLines: 1,
}),
snapshotDiff(
samplePatch,
(fs.writeFileSync as jest.Mock).mock.calls[0][1],
{
contextLines: 1,
},
),
).toMatchSnapshot(
'RnDiffApp is replaced with app name (TestApp and com.testapp)',
);
}, 60000);
test('fetches regular patch, adds remote, applies patch, installs deps, removes remote when updated from nested directory', async () => {
mockFetch(samplePatch, 200);
(execa: any).mockImplementation(mockExecaNested);
((execa as unknown) as jest.Mock).mockImplementation(mockExecaNested);
const config = {...ctx, root: '/project/root/NestedApp'};
await upgrade.func([newVersion], config, opts);
await upgrade.func([newVersion], config);
expect(flushOutput()).toMatchInlineSnapshot(`
"info Fetching diff between v0.57.8 and v0.58.4...
[fs] write tmp-upgrade-rn.patch
Expand All @@ -250,7 +247,7 @@ test('fetches regular patch, adds remote, applies patch, installs deps, removes
}, 60000);
test('cleans up if patching fails,', async () => {
mockFetch(samplePatch, 200);
(execa: any).mockImplementation((command, args) => {
((execa as unknown) as jest.Mock).mockImplementation((command, args) => {
mockPushLog('$', 'execa', command, args);
if (command === 'npm' && args[3] === '--json') {
return Promise.resolve({
Expand All @@ -270,7 +267,7 @@ test('cleans up if patching fails,', async () => {
return Promise.resolve({stdout: ''});
});
try {
await upgrade.func([newVersion], ctx, opts);
await upgrade.func([newVersion], ctx);
} catch (error) {
expect(error.message).toBe(
'Upgrade failed. Please see the messages above for details',
Expand Down Expand Up @@ -313,12 +310,15 @@ test('works with --name-ios and --name-android', async () => {
android: {packageName: 'co.uk.customandroid.app'},
},
}),
opts,
);
expect(
snapshotDiff(samplePatch, (fs.writeFileSync: any).mock.calls[0][1], {
contextLines: 1,
}),
snapshotDiff(
samplePatch,
(fs.writeFileSync as jest.Mock).mock.calls[0][1],
{
contextLines: 1,
},
),
).toMatchSnapshot(
'RnDiffApp is replaced with app name (CustomIos and co.uk.customandroid.app)',
);
Expand Down
Loading

0 comments on commit 37441f9

Please sign in to comment.