Variables: Detect a name for duplicated variable (#68110)

* Variables: Detect a name for duplicated variable

* Variables: create copies of copies
This commit is contained in:
Jaryk
2023-06-28 13:53:53 +02:00
committed by GitHub
parent 3f44412bfd
commit db478ced45
2 changed files with 98 additions and 1 deletions
@@ -150,6 +150,82 @@ describe('sharedReducer', () => {
},
});
});
it('then state should be correct', () => {
const initialState: VariablesState = getVariableState(3, -1, false, true);
initialState['1'].name = 'copy_of_Name-1_2';
const payload = toVariablePayload({ id: '1', type: 'query' }, { newId: '11' });
reducerTester<VariablesState>()
.givenReducer(sharedReducer, initialState)
.whenActionIsDispatched(duplicateVariable(payload))
.thenStateShouldEqual({
...initialState,
'11': {
...initialQueryVariableModelState,
...initialState['1'],
id: '11',
name: 'copy_of_copy_of_Name-1_2',
index: 3,
},
});
});
it('then state should be correct', () => {
const initialState: VariablesState = getVariableState(3, -1, false, true);
initialState['0'].name = 'Name-0';
initialState['1'].name = 'copy_of_Name-0_2';
const payload = toVariablePayload({ id: '0', type: 'query' }, { newId: '01' });
reducerTester<VariablesState>()
.givenReducer(sharedReducer, initialState)
.whenActionIsDispatched(duplicateVariable(payload))
.thenStateShouldEqual({
...initialState,
'01': {
...initialQueryVariableModelState,
...initialState['0'],
id: '01',
name: 'copy_of_Name-0_3',
index: 3,
},
});
});
it('then state should be correct', () => {
const initialState: VariablesState = getVariableState(3, -1, false, true);
initialState['1'].name = 'copy_of_Name-1_2';
const duplicateOne = toVariablePayload({ id: '1', type: 'query' }, { newId: '11' });
const duplicateTwo = toVariablePayload({ id: '1', type: 'query' }, { newId: '12' });
const duplicateThree = toVariablePayload({ id: '1', type: 'query' }, { newId: '13' });
reducerTester<VariablesState>()
.givenReducer(sharedReducer, initialState)
.whenActionIsDispatched(duplicateVariable(duplicateOne))
.whenActionIsDispatched(duplicateVariable(duplicateTwo))
.whenActionIsDispatched(duplicateVariable(duplicateThree))
.thenStateShouldEqual({
...initialState,
'11': {
...initialQueryVariableModelState,
...initialState['1'],
id: '11',
name: 'copy_of_copy_of_Name-1_2',
index: 3,
},
'12': {
...initialQueryVariableModelState,
...initialState['1'],
id: '12',
name: 'copy_of_copy_of_Name-1_2_1',
index: 4,
},
'13': {
...initialQueryVariableModelState,
...initialState['1'],
id: '13',
name: 'copy_of_copy_of_Name-1_2_2',
index: 5,
},
});
});
});
describe('when changeVariableOrder is dispatched', () => {
@@ -73,8 +73,29 @@ const sharedReducerSlice = createSlice({
}
},
duplicateVariable: (state: VariablesState, action: PayloadAction<VariablePayload<{ newId: string }>>) => {
function escapeRegExp(string: string): string {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
const original = cloneDeep<VariableModel>(state[action.payload.id]);
const name = `copy_of_${original.name}`;
const copyRegex = new RegExp(`^copy_of_${escapeRegExp(original.name)}(_(\\d+))?$`);
const copies = Object.values(state)
.map(({ name }) => name.match(copyRegex))
.filter((v): v is RegExpMatchArray => v != null);
const numberedCopies = copies.map((match) => match[2]).filter((v): v is string => v != null);
const suffix = ((): number | null => {
if (copies.length === 0) {
return null;
}
if (numberedCopies.length === 0) {
return 1;
}
return numberedCopies.map((v) => +v).sort((a, b) => b - a)[0] + 1;
})();
const name = `copy_of_${original.name}${suffix ? `_${suffix}` : ''}`;
const newId = action.payload.data?.newId ?? name;
const index = getNextVariableIndex(Object.values(state));
state[newId] = {