diff --git a/.vscode/launch.json b/.vscode/launch.json
index 68765b6af..670087730 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -15,7 +15,7 @@
"999999",
"--colors",
"-g",
- ".*addAsync.*"
+ "Test.0600 OrchestratorHelper.parseLuFile()"
],
"cwd": "${workspaceFolder}/packages/orchestratorlib",
"internalConsoleOptions": "openOnSessionStart",
diff --git a/packages/orchestrator/src/commands/orchestrator/create.ts b/packages/orchestrator/src/commands/orchestrator/create.ts
index 1990d4a5b..c4e0624bf 100644
--- a/packages/orchestrator/src/commands/orchestrator/create.ts
+++ b/packages/orchestrator/src/commands/orchestrator/create.ts
@@ -81,7 +81,7 @@ export default class OrchestratorCreate extends Command {
settings.SnapshotPath = snapshotFilePath;
settings.persist();
} catch (error) {
- throw (new CLIError(error));
+ throw (new CLIError(error as Error));
}
}
diff --git a/packages/orchestratorlib/src/orchestratorhelper.ts b/packages/orchestratorlib/src/orchestratorhelper.ts
index 5b3d74d43..790a142da 100644
--- a/packages/orchestratorlib/src/orchestratorhelper.ts
+++ b/packages/orchestratorlib/src/orchestratorhelper.ts
@@ -352,7 +352,7 @@ export class OrchestratorHelper {
default: throw new Error(`Unknown file type ${ext}`);
}
- } catch (error) {
+ } catch (error: any) {
throw new Error(`${error.message}${os.EOL}Failed to parse ${filePath}`);
}
}
@@ -421,15 +421,15 @@ export class OrchestratorHelper {
if (!luContent || luContent.length === 0) {
return;
}
- const luObject: any = {
- content: luContent,
- id: luFile,
- };
- const luisObject: any = await LuisBuilder.fromLUAsync([luObject], OrchestratorHelper.findLuFiles);
- if (Utility.toPrintDetailedDebuggingLogToConsole) {
- UtilityDispatcher.debuggingNamedLog1('OrchestratorHelper.parseLuContent(): calling getIntentsEntitiesUtterances()', luisObject, 'luisObject');
- }
try {
+ const luObject: any = {
+ content: luContent,
+ id: luFile,
+ };
+ const luisObject: any = await LuisBuilder.fromLUAsync([luObject], OrchestratorHelper.findLuFiles);
+ if (Utility.toPrintDetailedDebuggingLogToConsole) {
+ UtilityDispatcher.debuggingNamedLog1('OrchestratorHelper.parseLuContent(): calling getIntentsEntitiesUtterances()', luisObject, 'luisObject');
+ }
const rvLu: boolean = OrchestratorHelper.getIntentsEntitiesUtterances(
luisObject,
hierarchicalLabel,
@@ -440,9 +440,8 @@ export class OrchestratorHelper {
if (!rvLu) {
throw new Error('Failed to parse LUIS or JSON file on intent/entity labels');
}
- } catch (error) {
- Utility.debuggingLog(`EXCEPTION calling getIntentsEntitiesUtterances(), error=${error}`);
- throw error;
+ } catch (error: any) {
+ throw new Error(`Failed parsing lu file ${luFile} ${error.text}`);
}
}
@@ -602,20 +601,19 @@ export class OrchestratorHelper {
return;
}
- const newlines: string[] = [];
- lines.forEach((line: string) => {
- if (line.toLowerCase().indexOf('@qna.pair.source =') < 0) {
- newlines.push(line);
- }
- });
-
- // Utility.debuggingLog('OrchestratorHelper.parseQnaFile() ready to call QnaMakerBuilder.fromContent()');
- const qnaNormalized: string = Utility.cleanStringOnTabs(newlines.join('\n')); // ---- NOTE ---- QnaMakerBuilder does not like TAB
- const qnaObject: any = await QnaMakerBuilder.fromContent(qnaNormalized);
- if (qnaObject) {
+ try {
+ const newlines: string[] = [];
+ lines.forEach((line: string) => {
+ if (line.toLowerCase().indexOf('@qna.pair.source =') < 0) {
+ newlines.push(line);
+ }
+ });
+ // Utility.debuggingLog('OrchestratorHelper.parseQnaFile() ready to call QnaMakerBuilder.fromContent()');
+ const qnaNormalized: string = Utility.cleanStringOnTabs(newlines.join('\n')); // ---- NOTE ---- QnaMakerBuilder does not like TAB
+ const qnaObject: any = await QnaMakerBuilder.fromContent(qnaNormalized);
OrchestratorHelper.getQnaQuestionsAsUtterances(qnaObject, hierarchicalLabel, utteranceLabelsMap, utteranceLabelDuplicateMap);
- } else {
- throw new Error(`Failed parsing qna file ${qnaFile}`);
+ } catch (error: any) {
+ throw new Error(`Failed parsing qna file ${qnaFile} ${error.text}`);
}
}
diff --git a/packages/orchestratorlib/test/fixtures/parser/invalid.lu b/packages/orchestratorlib/test/fixtures/parser/invalid.lu
new file mode 100644
index 000000000..638d8a8cd
--- /dev/null
+++ b/packages/orchestratorlib/test/fixtures/parser/invalid.lu
@@ -0,0 +1,17 @@
+
+> LUIS application information
+> !# @app.name = Weather
+> !# @app.desc = Weather LUIS application - Bot Builder Samples
+> !# @app.versionId = 0.1
+> !# @app.culture = en-us
+> !# @app.luis_schema_version = 4.0.0
+
+
+> # Intent definitions
+- current weather ?
+- do {@Location=florida} residents usually need ice
+
+## Get Weather Forecast
+- forecast in celcius
+- get the forcast for me
+- i want to know the temperature at {@Location=death valley}
\ No newline at end of file
diff --git a/packages/orchestratorlib/test/fixtures/parser/invalid.qna b/packages/orchestratorlib/test/fixtures/parser/invalid.qna
new file mode 100644
index 000000000..8d4c5c016
--- /dev/null
+++ b/packages/orchestratorlib/test/fixtures/parser/invalid.qna
@@ -0,0 +1,10 @@
+**Prompts:**
+- [Files that Cannot Sync
+](#1)
+
+
+
+## ? Files that Cannot Sync
+```
+Files that cannot sync.
+```
diff --git a/packages/orchestratorlib/test/fixtures/parser/valid.lu b/packages/orchestratorlib/test/fixtures/parser/valid.lu
new file mode 100644
index 000000000..e755da466
--- /dev/null
+++ b/packages/orchestratorlib/test/fixtures/parser/valid.lu
@@ -0,0 +1,71 @@
+
+> LUIS application information
+> !# @app.name = Weather
+> !# @app.desc = Weather LUIS application - Bot Builder Samples
+> !# @app.versionId = 0.1
+> !# @app.culture = en-us
+> !# @app.luis_schema_version = 4.0.0
+
+
+> # Intent definitions
+
+## Get Weather Condition
+- current weather ?
+- do {@Location=florida} residents usually need ice scrapers
+- get {@Location=florence} temperature in september
+- get for me the weather conditions in {@Location=sonoma county}
+- get the daily temperature {@Location=greenwood indiana}
+- get the weather at {@Location=saint george utah}
+- how much rain does {@Location=chambersburg} get a year
+- show average rainfall for {@Location=boise}
+- temperature of {@Location=delhi} in celsius please
+- was last year about this time as wet as it is now in the {@Location=south} ?
+- what is the rain volume in {@Location=sonoma county} ?
+- what to wear in march in {@Location=california}
+- what's the weather like in {@Location=minneapolis}
+- weather in {@Location_PatternAny}
+- how's the weather in {@Location_PatternAny}
+- current weather in {@Location_PatternAny}
+
+
+## Get Weather Forecast
+- forecast in celcius
+- get the forcast for me
+- i want to know the temperature at {@Location=death valley}
+- provide me by {@Location=toronto} weather please
+- show me the forecast at {@Location=alabama}
+- soliciting today's weather
+- what is the weather in {@Location=redmond} ?
+- what is the weather today at 10 day {@Location=durham} ?
+- what will the weather be tomorrow in {@Location=new york} ?
+- what's the weather going to be like in {@Location=hawaii} ?
+- will it be raining in {@Location=ranchi}
+- will it rain this weekend
+- will it snow today
+- what's the forecast for next week in {@Location_PatternAny}
+- show me the forecast for {@Location_PatternAny}
+- what's the forecast for {@Location_PatternAny}
+
+
+## None
+
+
+> # Entity definitions
+
+@ ml Location
+
+
+> # PREBUILT Entity definitions
+
+
+> # Phrase list definitions
+
+
+> # List entities
+
+> # RegEx entities
+
+
+> # Pattern.Any entities
+
+@ patternany Location_PatternAny
diff --git a/packages/orchestratorlib/test/fixtures/parser/valid.qna b/packages/orchestratorlib/test/fixtures/parser/valid.qna
new file mode 100644
index 000000000..ff959c68a
--- /dev/null
+++ b/packages/orchestratorlib/test/fixtures/parser/valid.qna
@@ -0,0 +1,22 @@
+# ?store hours
+```
+Most our stores are open M-F 9AM-10PM.
+```
+**Prompts:**
+- [Seattle store](#1)
+- [Portland store](#2)
+
+
+
+# ?seattle
+```
+The Seattle store is open M-F 9AM-10PM.
+```
+
+
+
+# ?when is the portland store open
+- portland store hours
+```
+The Portland store is open 24/7.
+```
\ No newline at end of file
diff --git a/packages/orchestratorlib/test/orchestratorhelper.test.ts b/packages/orchestratorlib/test/orchestratorhelper.test.ts
index 251734514..19b03cbf9 100644
--- a/packages/orchestratorlib/test/orchestratorhelper.test.ts
+++ b/packages/orchestratorlib/test/orchestratorhelper.test.ts
@@ -425,7 +425,6 @@ describe('Test Suite - orchestratorhelper', () => {
assert.ok((utteranceEntityLabelsMap.get(utterance) as Label[]).length === 3,
`(utteranceEntityLabelsMap.get(utterance) as Label[]).length=${(utteranceEntityLabelsMap.get(utterance) as Label[]).length}`);
});
-
it('Test.0300 OrchestratorHelper.getJsonIntentEntityScoresUtterances()', function () {
Utility.resetFlagToPrintDebuggingLogToConsole(UnitTestHelper.getDefaultUnitTestDebuggingLogFlag());
this.timeout(UnitTestHelper.getDefaultUnitTestTimeout());
@@ -588,4 +587,54 @@ describe('Test Suite - orchestratorhelper', () => {
assert.ok(result.has('Add item'), 'Incorrect result from getUtteranceLabelsMap, missing Add item utterance');
assert.ok(result.has('delete to do go shopping'), 'Incorrect result from getUtteranceLabelsMap, missing delete to do go shopping utterance');
});
+ it('Test.0600 OrchestratorHelper.parseQnaFile()', async () => {
+ const validFile: string = './test/fixtures/parser/valid.qna';
+ const inValidFile: string = './test/fixtures/parser/invalid.qna';
+ const utteranceLabelsMap: Map> = new Map>();
+ const utteranceLabelDuplicateMap: Map> = new Map>();
+ try {
+ await OrchestratorHelper.parseQnaFile(
+ inValidFile,
+ '',
+ utteranceLabelsMap,
+ utteranceLabelDuplicateMap);
+ assert.fail('Invalid syntax exception is not thrown.');
+ } catch {}
+ assert.ok(utteranceLabelsMap.size === 0);
+ await OrchestratorHelper.parseQnaFile(
+ validFile,
+ '',
+ utteranceLabelsMap,
+ utteranceLabelDuplicateMap);
+ assert.ok(utteranceLabelsMap.size > 0);
+ });
+ it('Test.0600 OrchestratorHelper.parseLuFile()', async () => {
+ const validFile: string = './test/fixtures/parser/valid.lu';
+ const inValidFile: string = './test/fixtures/parser/invalid.lu';
+ const utteranceLabelsMap: Map> = new Map>();
+ const utteranceLabelDuplicateMap: Map> = new Map>();
+ const utteranceEntityLabelsMap: Map = new Map();
+ const utteranceEntityLabelDuplicateMap: Map = new Map();
+
+ try {
+ await OrchestratorHelper.parseLuFile(
+ inValidFile,
+ '',
+ utteranceLabelsMap,
+ utteranceLabelDuplicateMap,
+ utteranceEntityLabelsMap,
+ utteranceEntityLabelDuplicateMap);
+ assert.fail('Invalid syntax exception is not thrown.');
+ } catch {}
+ assert.ok(utteranceLabelsMap.size === 0);
+
+ await OrchestratorHelper.parseLuFile(
+ validFile,
+ '',
+ utteranceLabelsMap,
+ utteranceLabelDuplicateMap,
+ utteranceEntityLabelsMap,
+ utteranceEntityLabelDuplicateMap);
+ assert.ok(utteranceLabelsMap.size > 0);
+ });
});