Skip to content

Commit

Permalink
Merge pull request #4079 from epam/3943-system-allow-to-create-atoms-…
Browse files Browse the repository at this point in the history
…with-charge-value-out-or-range

#3943 - System allow to create atoms with Charge value out or range
  • Loading branch information
rrodionov91 committed Apr 17, 2024
2 parents 85af0e1 + c01c79a commit c6e7c7c
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,9 @@ test.describe('Checking atom properties attributes in SMARTS format', () => {
});

test('Check that cannot add Charge more than -15', async ({ page }) => {
test.fail();
/**
* Test case: https://github.com/epam/ketcher/issues/3943
* Description: Validation should be added +-15 range allowed only
* This test will fail until https://github.com/epam/ketcher/issues/3943 is fixed
*/
await setCharge(page, '-16');
const applyButton = await page.getByText('Apply');
Expand All @@ -153,11 +151,9 @@ test.describe('Checking atom properties attributes in SMARTS format', () => {
});

test('Check that cannot add Charge more than 15', async ({ page }) => {
test.fail();
/**
* Test case: https://github.com/epam/ketcher/issues/3943
* Description: Validation should be added +-15 range allowed only
* This test will fail until https://github.com/epam/ketcher/issues/3943 is fixed
*/
await setCharge(page, '16');
const applyButton = await page.getByText('Apply');
Expand Down
10 changes: 5 additions & 5 deletions packages/ketcher-react/src/script/ui/data/convert/structconv.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ import {
StereoLabel,
getAtomType,
} from 'ketcher-core';

import { atom as atomSchema } from '../schema/struct-schema';
import { capitalize } from 'lodash/fp';
import {
sdataSchema,
getSdataDefault,
sdataCustomSchema,
} from '../schema/sdata-schema';
import { matchCharge } from '../utils';

const DefaultStereoGroupNumber = 1;

Expand Down Expand Up @@ -183,13 +182,14 @@ export function toAtom(atom) {
exactChangeFlag: 0,
});
}
const chargeRegexp = new RegExp(atomSchema.properties.charge.pattern);
const pch = chargeRegexp.exec(restAtom.charge);
const pch = matchCharge(restAtom.charge);
const charge = pch ? parseInt(pch[1] + pch[3] + pch[2]) : restAtom.charge;

const conv = Object.assign({}, restAtom, {
isotope: restAtom.isotope ? Number(restAtom.isotope) : null,
charge: restAtom.charge ? Number(charge) : null,
// empty charge value by default treated as zero,
// no need to pass and display zero values(0, -0) explicitly
charge: restAtom.charge && charge !== 0 ? Number(charge) : null,
alias: restAtom.alias || null,
exactChangeFlag: +(restAtom.exactChangeFlag ?? false),
unsaturatedAtom: +(restAtom.unsaturatedAtom ?? false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const atom = {
charge: {
title: 'Charge',
type: 'string',
pattern: '^([+-]?)([0-9]{1,3})([+-]?)$',
pattern: '^([+-]?)(1[0-5]|0|[0-9])([+-]?)$',
maxLength: 4,
default: '',
invalidMessage: 'Invalid charge value',
Expand Down
50 changes: 50 additions & 0 deletions packages/ketcher-react/src/script/ui/data/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { matchCharge } from 'src/script/ui/data/utils';

describe('data utils', () => {
describe('matchCharge', () => {
it('should return null for empty string', () => {
const result = matchCharge('');
expect(result).toBeNull();
});
it('should return null for string with positive out of range charge', () => {
const result = matchCharge('16');
expect(result).toBeNull();
});
it('should return null for string with negative out of range charge', () => {
const result = matchCharge('-16');
expect(result).toBeNull();
});
it('should return expected matched array for string with zero charge', () => {
const expectedMatchGroups = ['', '0', ''];
const [, signBefore, absoluteValue, signAfter] = matchCharge('0') || [];
expect([signBefore, absoluteValue, signAfter]).toEqual(
expectedMatchGroups,
);
});
it('should return expected matched array for string with negative zero charge', () => {
const expectedMatchGroups = ['-', '0', ''];
const [, signBefore, absoluteValue, signAfter] = matchCharge('-0') || [];
expect([signBefore, absoluteValue, signAfter]).toEqual(
expectedMatchGroups,
);
});
it('should return expected matched array for string with negative zero charge after', () => {
const expectedMatchGroups = ['', '0', '-'];
const [, signBefore, absoluteValue, signAfter] = matchCharge('0-') || [];
expect([signBefore, absoluteValue, signAfter]).toEqual(
expectedMatchGroups,
);
});
it('should return expected matched array for string with two signs number', () => {
const expectedMatchGroups = ['-', '0', '-'];
const [, signBefore, absoluteValue, signAfter] = matchCharge('-0-') || [];
expect([signBefore, absoluteValue, signAfter]).toEqual(
expectedMatchGroups,
);
});
it('should return null for string with invalid number format', () => {
const result = matchCharge('--0');
expect(result).toBeNull();
});
});
});
16 changes: 16 additions & 0 deletions packages/ketcher-react/src/script/ui/data/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { atom } from './schema/struct-schema';

/**
* Get match groups from string representation of charge. It returns RegExpExecArray for charges with values +-[0..15]
* overwise returns null
*
* @example
* matchCharge("16") === null
* matchCharge("0") === []
* matchCharge("-1") === ["-1", "-", "1", ""]
* matchCharge("15+") === ["15+", "", "15", "+"]
*/
export function matchCharge(charge: string) {
const regex = new RegExp(atom.properties.charge.pattern);
return regex.exec(charge);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AtomType, Elements, genericsList } from 'ketcher-core';
import { capitalize } from 'lodash';
import { atom as atomSchema } from '../../../../../data/schema/struct-schema';
import { matchCharge } from 'src/script/ui/data/utils';

export function atomValid(
label: string,
Expand Down Expand Up @@ -47,8 +48,7 @@ export function chargeValid(
isMultipleAtoms: boolean,
isCustomQuery: boolean,
) {
const regex = new RegExp(atomSchema.properties.charge.pattern);
const result = regex.exec(charge);
const result = matchCharge(charge);
const isValidCharge = result && (result[1] === '' || result[3] === '');
if (isCustomQuery || charge === '') {
return true;
Expand Down

0 comments on commit c6e7c7c

Please sign in to comment.