-
Notifications
You must be signed in to change notification settings - Fork 369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: centralize lg parsing logic to 'shared' lib #1663
Changes from 18 commits
7088206
e975f16
531f317
9e7c541
b55f845
aae1d7c
13ce6b3
1e6b5ea
ee68dde
236b2e9
6049ebc
bd7390b
4a1c52c
c5cfb59
e3d30e6
3291366
456d08f
e3a9b69
c2a69c7
1353a50
f8b4d66
8254870
490cc65
fb991d3
06a591d
b7daa72
9c31854
02d4c15
8eb4f40
67e091a
67c064f
31d6c99
48b910b
284e8ce
216d413
d4738e6
644ae1c
fc22977
cd0aa32
6d1648b
0bda795
c7a289f
17f0929
5aa6c5f
bd9930e
7926a22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
import { jsx } from '@emotion/core'; | ||
import { useContext, FC, useEffect, useState, useRef } from 'react'; | ||
import { MarqueeSelection, Selection } from 'office-ui-fabric-react/lib/MarqueeSelection'; | ||
import { deleteAction, deleteActions } from '@bfc/shared'; | ||
import { deleteAction, deleteActions, LgTemplateRef, LgMetaData } from '@bfc/shared'; | ||
|
||
import { NodeEventTypes } from '../constants/NodeEventTypes'; | ||
import { KeyboardCommandTypes, KeyboardPrimaryTypes } from '../constants/KeyboardCommandTypes'; | ||
|
@@ -49,12 +49,10 @@ export const ObiEditor: FC<ObiEditorProps> = ({ | |
); | ||
|
||
const deleteLgTemplates = (lgTemplates: string[]) => { | ||
const lgPattern = /\[(bfd\w+-\d+)\]/; | ||
const normalizedLgTemplates = lgTemplates | ||
.map(x => { | ||
const matches = lgPattern.exec(x); | ||
if (matches && matches.length === 2) return matches[1]; | ||
return ''; | ||
const lgTemplateRef = LgTemplateRef.parse(x); | ||
return lgTemplateRef ? lgTemplateRef.name : ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can leverage the 'optional chaining' feature in ts 3.7. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
}) | ||
.filter(x => !!x); | ||
return removeLgTemplates('common', normalizedLgTemplates); | ||
|
@@ -89,16 +87,19 @@ export const ObiEditor: FC<ObiEditorProps> = ({ | |
if (eventData.$type === 'PASTE') { | ||
handler = e => { | ||
// TODO: clean this along with node deletion. | ||
const copyLgTemplateToNewNode = async (lgTemplateName: string, newNodeId: string) => { | ||
const matches = /\[(bfd\w+-(\d+))\]/.exec(lgTemplateName); | ||
if (Array.isArray(matches) && matches.length === 3) { | ||
const originLgId = matches[1]; | ||
const originNodeId = matches[2]; | ||
const newLgId = originLgId.replace(originNodeId, newNodeId); | ||
await copyLgTemplate('common', originLgId, newLgId); | ||
return `[${newLgId}]`; | ||
} | ||
return lgTemplateName; | ||
const copyLgTemplateToNewNode = async (input: string, newNodeId: string) => { | ||
const lgTemplateRef = LgTemplateRef.parse(input); | ||
if (!lgTemplateRef) return input; | ||
|
||
const lgMetadata = LgMetaData.parse(lgTemplateRef.name); | ||
if (!lgMetadata) return input; | ||
|
||
lgMetadata.designerId = newNodeId; | ||
const newLgName = lgMetadata.toLgTemplateName(); | ||
const newLgTemplateRefString = lgMetadata.toLgTemplateRefString(); | ||
|
||
await copyLgTemplate('common', lgTemplateRef.name, newLgName); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return newLgTemplateRefString; | ||
}; | ||
pasteNodes(data, e.id, e.position, clipboardActions, copyLgTemplateToNewNode).then(dialog => { | ||
onChange(dialog); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import { extractLgTemplateNames } from '../../src'; | ||
|
||
describe('extractLgTemplateRefs', () => { | ||
it('can extract lg refs from input string', () => { | ||
expect(extractLgTemplateNames('Hi')).toEqual([]); | ||
expect(extractLgTemplateNames(`-[Greeting], I'm a fancy bot, [Bye]`)).toEqual(['Greeting', 'Bye']); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import { LgMetaData } from '../../../src'; | ||
|
||
describe('LgMetaData', () => { | ||
it('can construct an instance via constructor', () => { | ||
const instance = new LgMetaData('activity', '123456'); | ||
|
||
expect(instance.type).toEqual('activity'); | ||
expect(instance.designerId).toEqual('123456'); | ||
|
||
expect(instance.toLgTemplateName).toBeDefined(); | ||
expect(instance.toLgTemplateRef).toBeDefined(); | ||
expect(instance.toLgTemplateRefString).toBeDefined(); | ||
expect(instance.toLgText).toBeDefined(); | ||
}); | ||
|
||
it('can generate correct output strings', () => { | ||
const instance = new LgMetaData('activity', '123456'); | ||
|
||
expect(instance.toLgTemplateName()).toEqual('bfdactivity-123456'); | ||
|
||
expect(instance.toLgTemplateRefString()).toEqual('[bfdactivity-123456]'); | ||
expect(instance.toLgTemplateRefString(['1', '2'])).toEqual('[bfdactivity-123456(1,2)]'); | ||
|
||
expect(instance.toLgText()).toEqual('- [bfdactivity-123456]'); | ||
expect(instance.toLgText([])).toEqual('- [bfdactivity-123456()]'); | ||
}); | ||
|
||
it('can construct instance via `parse()` method', () => { | ||
expect(LgMetaData.parse('bfdactivity-123456')).toBeInstanceOf(LgMetaData); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import { LgTemplateRef } from '../../../src'; | ||
|
||
describe('LgTemplateRef', () => { | ||
it('can construct an instance via constructor', () => { | ||
const a = new LgTemplateRef('a', undefined); | ||
expect(a.name).toEqual('a'); | ||
expect(a.parameters).toEqual(undefined); | ||
|
||
const b = new LgTemplateRef('b', []); | ||
expect(b.name).toEqual('b'); | ||
expect(b.parameters).toEqual([]); | ||
|
||
const c = new LgTemplateRef('c', ['1', '2']); | ||
expect(c.name).toEqual('c'); | ||
expect(c.parameters).toEqual(['1', '2']); | ||
}); | ||
|
||
it('can output correct strings', () => { | ||
const a = new LgTemplateRef('a', undefined); | ||
expect(a.toString()).toEqual('[a]'); | ||
expect(a.toLgText()).toEqual('- [a]'); | ||
|
||
const b = new LgTemplateRef('b', []); | ||
expect(b.toString()).toEqual('[b()]'); | ||
expect(b.toLgText()).toEqual('- [b()]'); | ||
|
||
const c = new LgTemplateRef('c', ['1', '2']); | ||
expect(c.toString()).toEqual('[c(1,2)]'); | ||
expect(c.toLgText()).toEqual('- [c(1,2)]'); | ||
}); | ||
|
||
it('can construct instance via `parse()`', () => { | ||
expect(LgTemplateRef.parse('[bfdactivity-123456]')).toBeInstanceOf(LgTemplateRef); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import parseLgParamString from '../../../src/lgUtils/parsers/parseLgParamString'; | ||
|
||
describe('parseLgParamString', () => { | ||
it('should return undefined when no params detected', () => { | ||
expect(parseLgParamString('')).toBeUndefined(); | ||
expect(parseLgParamString('xxx')).toBeUndefined(); | ||
}); | ||
|
||
it('should return params array when input valid strings', () => { | ||
expect(parseLgParamString('()')).toEqual([]); | ||
expect(parseLgParamString('(a,b)')).toEqual(['a', 'b']); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import { parseLgTemplateName, LgMetaData } from '../../../src'; | ||
|
||
describe('parseLgTemplateName', () => { | ||
it('should return null when inputs are invalid', () => { | ||
expect(parseLgTemplateName('')).toEqual(null); | ||
expect(parseLgTemplateName('xxx')).toEqual(null); | ||
}); | ||
|
||
it('should return LgMetaData when inputs are valid', () => { | ||
const result = parseLgTemplateName('bfdactivity-123456'); | ||
expect(result).toBeInstanceOf(LgMetaData); | ||
expect((result as LgMetaData).designerId).toEqual('123456'); | ||
expect((result as LgMetaData).type).toEqual('activity'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import { parseLgTemplateRef, LgTemplateRef } from '../../../src'; | ||
|
||
describe('parseLgTemplateRef', () => { | ||
it('should return null when inputs are invalid', () => { | ||
expect(parseLgTemplateRef('')).toEqual(null); | ||
yeze322 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
expect(parseLgTemplateRef('xxx')).toEqual(null); | ||
expect(parseLgTemplateRef('[0]')).toEqual(null); | ||
}); | ||
|
||
it('should return LgTemplateRef when inputs are valid', () => { | ||
const a = parseLgTemplateRef('[bfdactivity-123456]'); | ||
expect(a).toBeInstanceOf(LgTemplateRef); | ||
expect((a as LgTemplateRef).name).toEqual('bfdactivity-123456'); | ||
expect((a as LgTemplateRef).parameters).toEqual(undefined); | ||
|
||
const b = parseLgTemplateRef('[greeting(1,2)]'); | ||
expect(b).toBeInstanceOf(LgTemplateRef); | ||
expect((b as LgTemplateRef).name).toEqual('greeting'); | ||
expect((b as LgTemplateRef).parameters).toEqual(['1', '2']); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import { parseLgText, LgTemplateRef } from '../../../src'; | ||
|
||
describe('parseLgText', () => { | ||
it('should return null when inputs are invalid', () => { | ||
expect(parseLgText('')).toEqual(null); | ||
expect(parseLgText('xxx')).toEqual(null); | ||
expect(parseLgText('[bfdactivity-1234]')).toEqual(null); | ||
}); | ||
|
||
it('should return LgTemplateRef when inputs are valid', () => { | ||
const result = parseLgText('- [bfdactivity-123456]'); | ||
expect(result).toBeInstanceOf(LgTemplateRef); | ||
expect((result as LgTemplateRef).name).toEqual('bfdactivity-123456'); | ||
expect((result as LgTemplateRef).parameters).toEqual(undefined); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
import { LgTemplateRefPattern } from './lgPatterns'; | ||
import { LgTemplateName } from './models/stringTypes'; | ||
|
||
/** | ||
* | ||
* @param text string | ||
* -[Greeting], I'm a fancy bot, [Bye] ---> ['Greeting', 'Bye'] | ||
* | ||
*/ | ||
export default function extractLgTemplateNames(text: string): LgTemplateName[] { | ||
const templateNames: string[] = []; | ||
|
||
// eslint-disable-next-line security/detect-non-literal-regexp | ||
const reg = new RegExp(LgTemplateRefPattern, 'g'); | ||
|
||
let matchResult; | ||
while ((matchResult = reg.exec(text)) !== null) { | ||
const templateName = matchResult[1]; | ||
templateNames.push(templateName); | ||
} | ||
return templateNames; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
|
||
/** models */ | ||
export { default as LgMetaData } from './models/LgMetaData'; | ||
export { default as LgTemplateRef } from './models/LgTemplateRef'; | ||
|
||
/** parsers */ | ||
export { default as parseLgTemplateName } from './parsers/parseLgTemplateName'; | ||
export { default as parseLgTemplateRef } from './parsers/parseLgTemplateRef'; | ||
export { default as parseLgText } from './parsers/parseLgText'; | ||
|
||
export { default as extractLgTemplateNames } from './extractLgTemplateNames'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleteLgTemplates
will be defined asdeleteLgText
. See my next comments oncopyLgTemplate