Skip to content

Commit

Permalink
refactor(codegen): move getCommandOptions and getOptions to parsers-c…
Browse files Browse the repository at this point in the history
…ommons
  • Loading branch information
tarunrajput authored and dotslashtarun committed Mar 16, 2023
1 parent 0a3c555 commit 1fc02ff
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
buildSchema,
parseModuleName,
createComponentConfig,
getCommandOptions,
getOptions,
} from '../parsers-commons';
import type {ParserType} from '../errors';

Expand Down Expand Up @@ -1277,3 +1279,133 @@ describe('createComponentConfig', () => {
});
});
});

describe('getCommandOptions', () => {
it('returns null when commandOptionsExpression is null', () => {
const result = getCommandOptions(null);
expect(result).toBeNull();
});

it('parses and returns command options correctly', () => {
const commandOptionsExpression = {
properties: [
{
range: [],
loc: {},
type: '',
key: {
name: 'hotspotUpdate',
loc: {},
},
value: {
elements: [
{
value: 'value',
},
],
},
},
],
};
const result = getCommandOptions(commandOptionsExpression);
expect(result).toEqual({
hotspotUpdate: ['value'],
});
});

it('should throw an error if command options are not defined correctly', () => {
const commandOptionsExpression = {
properties: null,
};
expect(() => getCommandOptions(commandOptionsExpression)).toThrowError(
'Failed to parse command options, please check that they are defined correctly',
);
});
});

describe('getOptions', () => {
it('returns null if optionsExpression is falsy', () => {
expect(getOptions(null)).toBeNull();
expect(getOptions(undefined)).toBeNull();
expect(getOptions(false)).toBeNull();
expect(getOptions(0)).toBeNull();
expect(getOptions('')).toBeNull();
});

it('parses and returns options correctly if codegen options are defined correctly', () => {
const optionsExpression = {
properties: [
{
value: {
type: 'ArrayExpression',
value: 'value',
elements: [
{
value: 'value1',
},
],
},
key: {
name: 'keyName',
},
},
],
};
expect(getOptions(optionsExpression)).toEqual({
keyName: ['value1'],
});
});

it('throws an error if codegen options are not defined correctly', () => {
const optionsExpression = {
properties: null,
};
expect(() => getOptions(optionsExpression)).toThrowError(
'Failed to parse codegen options, please check that they are defined correctly',
);
});

it('throws an error if both paperComponentName and paperComponentNameDeprecated are used', () => {
const optionsExpression = {
properties: [
{
key: {name: 'paperComponentName'},
value: {value: 'RCTRefreshControl'},
},
{
key: {name: 'paperComponentNameDeprecated'},
value: {value: 'RCTSwitch'},
},
],
};
expect(() => getOptions(optionsExpression)).toThrowError(
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
);
});

it('returns options if only paperComponentName is used', () => {
const optionsExpression = {
properties: [
{
key: {name: 'paperComponentName'},
value: {value: 'RCTRefreshControl'},
},
],
};
const expectedOptions = {paperComponentName: 'RCTRefreshControl'};
expect(getOptions(optionsExpression)).toEqual(expectedOptions);
});

it('returns options if only paperComponentNameDeprecated is used', () => {
const optionsExpression = {
properties: [
{
key: {name: 'paperComponentNameDeprecated'},
value: {value: 'RCTRefreshControl'},
},
],
};
const expectedOptions = {paperComponentNameDeprecated: 'RCTRefreshControl'};
expect(getOptions(optionsExpression)).toEqual(expectedOptions);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@
'use strict';
import type {Parser} from '../../parser';
import type {TypeDeclarationMap} from '../../utils';
import type {CommandOptions} from './options';
import type {CommandOptions} from '../../parsers-commons';
import type {ComponentSchemaBuilderConfig} from '../../schema.js';

const {getCommands} = require('./commands');
const {getEvents} = require('./events');
const {getExtendsProps, removeKnownExtends} = require('./extends');
const {getCommandOptions, getOptions} = require('./options');
const {getProps} = require('./props');
const {getProperties} = require('./componentsUtils.js');
const {createComponentConfig} = require('../../parsers-commons');
const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
const {
createComponentConfig,
getCommandOptions,
getOptions,
} = require('../../parsers-commons');

/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
* LTI update could not be added via codemod */
Expand Down

This file was deleted.

72 changes: 72 additions & 0 deletions packages/react-native-codegen/src/parsers/parsers-commons.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
NativeModulePropertyShape,
SchemaType,
NativeModuleEnumMap,
OptionsShape,
} from '../CodegenSchema.js';

import type {Parser} from './parser';
Expand Down Expand Up @@ -61,6 +62,13 @@ const {

const invariant = require('invariant');

export type CommandOptions = $ReadOnly<{
supportedCommands: $ReadOnlyArray<string>,
}>;

// $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser
type OptionsAST = Object;

function wrapModuleSchema(
nativeModuleSchema: NativeModuleSchema,
hasteModuleName: string,
Expand Down Expand Up @@ -657,6 +665,68 @@ const buildModuleSchema = (
);
};

function getCommandOptions(
commandOptionsExpression: OptionsAST,
): ?CommandOptions {
if (commandOptionsExpression == null) {
return null;
}

let foundOptions;
try {
foundOptions = commandOptionsExpression.properties.reduce(
(options, prop) => {
options[prop.key.name] = (
(prop && prop.value && prop.value.elements) ||
[]
).map(element => element && element.value);
return options;
},
{},
);
} catch (e) {
throw new Error(
'Failed to parse command options, please check that they are defined correctly',
);
}

return foundOptions;
}

function getOptions(optionsExpression: OptionsAST): ?OptionsShape {
if (!optionsExpression) {
return null;
}
let foundOptions;
try {
foundOptions = optionsExpression.properties.reduce((options, prop) => {
if (prop.value.type === 'ArrayExpression') {
options[prop.key.name] = prop.value.elements.map(
element => element.value,
);
} else {
options[prop.key.name] = prop.value.value;
}
return options;
}, {});
} catch (e) {
throw new Error(
'Failed to parse codegen options, please check that they are defined correctly',
);
}

if (
foundOptions.paperComponentName &&
foundOptions.paperComponentNameDeprecated
) {
throw new Error(
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
);
}

return foundOptions;
}

module.exports = {
wrapModuleSchema,
unwrapNullable,
Expand All @@ -671,4 +741,6 @@ module.exports = {
createComponentConfig,
parseModuleName,
buildModuleSchema,
getCommandOptions,
getOptions,
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@
import type {ExtendsPropsShape} from '../../../CodegenSchema.js';
import type {Parser} from '../../parser';
import type {TypeDeclarationMap} from '../../utils';
import type {CommandOptions} from './options';
import type {CommandOptions} from '../../parsers-commons';
import type {ComponentSchemaBuilderConfig} from '../../schema.js';

const {getCommands} = require('./commands');
const {getEvents} = require('./events');
const {categorizeProps} = require('./extends');
const {getCommandOptions, getOptions} = require('./options');
const {getProps} = require('./props');
const {getProperties} = require('./componentsUtils.js');
const {createComponentConfig} = require('../../parsers-commons');
const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
const {
createComponentConfig,
getCommandOptions,
getOptions,
} = require('../../parsers-commons');

/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
* LTI update could not be added via codemod */
Expand Down
Loading

0 comments on commit 1fc02ff

Please sign in to comment.