Skip to content
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

feature/BOT-840-box-add-support-for-yaml-input-f #412

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/scripting/CompilerObjectBase.js
Expand Up @@ -53,15 +53,15 @@ module.exports = class CompilerObjectBase extends CompilerBase {
const conversation = []
for (const convoStepRaw of (convoRaw.steps || [])) {
convoStepLineIndex++
if (convoStepRaw.me && convoStepRaw.bot) {
throw new Error(`Use just one from 'me' and 'bot' fields in step ${JSON.stringify(convoStepRaw)}`)
if (Object.keys(convoStepRaw).length > 1) {
throw new Error(`Use just one from 'begin', 'me','bot' and 'end' fields in step ${JSON.stringify(convoStepRaw)}`)
}
if (!convoStepRaw.me && !convoStepRaw.bot) {
throw new Error(`Use 'me' or 'bot' field in step ${JSON.stringify(convoStepRaw)}`)
if (!convoStepRaw.begin && !convoStepRaw.me && !convoStepRaw.bot && !convoStepRaw.end) {
throw new Error(`Use 'begin' or 'me' or 'bot' or 'end' field in step ${JSON.stringify(convoStepRaw)}`)
}

const convoStepSender = convoStepRaw.me ? 'me' : 'bot'
const convoStepObject = convoStepRaw.me || convoStepRaw.bot
const convoStepSender = Object.keys(convoStepRaw)[0]
const convoStepObject = convoStepRaw[convoStepSender]

conversation.push(Object.assign(
{
Expand Down Expand Up @@ -93,7 +93,7 @@ module.exports = class CompilerObjectBase extends CompilerBase {

_compileUtterances (utterancesRaw) {
const result = []
const names = Object.keys(utterancesRaw)
const names = Object.keys(utterancesRaw || {})
for (const name of names) {
result.push(new Utterance({ name, utterances: utterancesRaw[name] }))
}
Expand Down
1 change: 1 addition & 0 deletions src/scripting/Constants.js
Expand Up @@ -2,6 +2,7 @@ module.exports = {
SCRIPTING_FORMAT_XSLX: 'SCRIPTING_FORMAT_XSLX',
SCRIPTING_FORMAT_TXT: 'SCRIPTING_FORMAT_TXT',
SCRIPTING_FORMAT_YAML: 'SCRIPTING_FORMAT_YAML',
SCRIPTING_FORMAT_JSON: 'SCRIPTING_FORMAT_JSON',
SCRIPTING_FORMAT_CSV: 'SCRIPTING_FORMAT_CSV',
SCRIPTING_TYPE_CONVO: 'SCRIPTING_TYPE_CONVO',
SCRIPTING_TYPE_PCONVO: 'SCRIPTING_TYPE_PCONVO',
Expand Down
19 changes: 18 additions & 1 deletion src/scripting/ScriptingProvider.js
Expand Up @@ -14,7 +14,7 @@ const ScriptingMemory = require('./ScriptingMemory')
const { BotiumError, botiumErrorFromList } = require('./BotiumError')
const { quoteRegexpString, toString } = require('./helper')

const globPattern = '**/+(*.convo.txt|*.utterances.txt|*.pconvo.txt|*.scriptingmemory.txt|*.xlsx|*.convo.csv|*.pconvo.csv)'
const globPattern = '**/+(*.convo.txt|*.utterances.txt|*.pconvo.txt|*.scriptingmemory.txt|*.xlsx|*.convo.csv|*.pconvo.csv|*.yaml|*.yml|*.json)'

const p = (fn) => new Promise((resolve, reject) => {
try {
Expand Down Expand Up @@ -291,6 +291,12 @@ module.exports = class ScriptingProvider {
const CompilerCsv = require('./CompilerCsv')
this.compilers[Constants.SCRIPTING_FORMAT_CSV] = new CompilerCsv(this._buildScriptContext(), this.caps)
this.compilers[Constants.SCRIPTING_FORMAT_CSV].Validate()
const CompilerYaml = require('./CompilerYaml')
this.compilers[Constants.SCRIPTING_FORMAT_YAML] = new CompilerYaml(this._buildScriptContext(), this.caps)
this.compilers[Constants.SCRIPTING_FORMAT_YAML].Validate()
const CompilerJson = require('./CompilerJson')
this.compilers[Constants.SCRIPTING_FORMAT_JSON] = new CompilerJson(this._buildScriptContext(), this.caps)
this.compilers[Constants.SCRIPTING_FORMAT_JSON].Validate()

debug('Using matching mode: ' + this.caps[Capabilities.SCRIPTING_MATCHING_MODE])
if (this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'regexp' || this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'regexpIgnoreCase') {
Expand Down Expand Up @@ -426,7 +432,18 @@ module.exports = class ScriptingProvider {
fileConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_CONVO)
} else if (filename.endsWith('.pconvo.csv')) {
filePartialConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_PCONVO)
} else if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {
fileUtterances = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, Constants.SCRIPTING_TYPE_UTTERANCES)
filePartialConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, Constants.SCRIPTING_TYPE_PCONVO)
fileConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, Constants.SCRIPTING_TYPE_CONVO)
fileScriptingMemories = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)
} else if (filename.endsWith('.json')) {
fileUtterances = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, Constants.SCRIPTING_TYPE_UTTERANCES)
filePartialConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, Constants.SCRIPTING_TYPE_PCONVO)
fileConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, Constants.SCRIPTING_TYPE_CONVO)
fileScriptingMemories = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)
}

// Compilers saved the convos, and we alter here the saved version too
if (fileConvos) {
fileConvos.forEach((fileConvo) => {
Expand Down
73 changes: 73 additions & 0 deletions test/compiler/compilerjson.spec.js
@@ -0,0 +1,73 @@
const fs = require('fs')
const path = require('path')
const assert = require('chai').assert
const Compiler = require('../../src/scripting/CompilerJson')
const Constants = require('../../src/scripting/Constants')
const DefaultCapabilities = require('../../src/Defaults').Capabilities

const buildContext = () => {
const result = {
IsAsserterValid: (name) => {
if (name === 'INTENT') {
return true
}

return false
},
IsUserInputValid: () => false,
IsLogicHookValid: (name) => {
if (name === 'PAUSE') {
return true
}

return false
},
AddConvos: (c) => { result.convos = result.convos.concat(c) },
AddUtterances: (u) => { result.utterances = result.utterances.concat(u) },
convos: [],
utterances: []
}
return result
}

describe('compiler.compilerjson', function () {
it('should read convos', async function () {
const scriptBuffer = fs.readFileSync(path.resolve(__dirname, 'convos', 'convos_and_utterances.json'))
const context = buildContext()
const caps = {
}
const compiler = new Compiler(context, Object.assign({}, DefaultCapabilities, caps))

compiler.Compile(scriptBuffer, Constants.SCRIPTING_TYPE_CONVO)
assert.equal(context.convos.length, 2)

assert.equal(context.convos[0].conversation.length, 3)
assert.equal(context.convos[0].conversation[0].sender, 'begin')

assert.equal(context.convos[1].conversation.length, 5)
assert.equal(context.convos[1].conversation[0].messageText, 'hi')
assert.equal(context.convos[1].conversation[1].messageText, 'hello')
assert.equal(context.convos[1].conversation[0].logicHooks.length, 1)
assert.equal(context.convos[1].conversation[0].logicHooks[0].name, 'PAUSE')
assert.equal(context.convos[1].conversation[0].logicHooks[0].args.length, 1)
assert.equal(context.convos[1].conversation[0].logicHooks[0].args[0], '500')

assert.equal(context.utterances.length, 0)
})

it('should read utterances', async function () {
const scriptBuffer = fs.readFileSync(path.resolve(__dirname, 'convos', 'convos_and_utterances.json'))
const context = buildContext()
const caps = {
}
const compiler = new Compiler(context, Object.assign({}, DefaultCapabilities, caps))

compiler.Compile(scriptBuffer, Constants.SCRIPTING_TYPE_UTTERANCES)
assert.equal(context.utterances.length, 1)
assert.equal(context.utterances[0].name, 'GREETING')
assert.equal(context.utterances[0].utterances.length, 2)
assert.equal(context.utterances[0].utterances[1], 'hello!')

assert.equal(context.convos.length, 0)
})
})
30 changes: 16 additions & 14 deletions test/compiler/compileryaml.spec.js
Expand Up @@ -40,6 +40,10 @@ describe('compiler.compileryml', function () {

compiler.Compile(scriptBuffer, Constants.SCRIPTING_TYPE_CONVO)
assert.equal(context.convos.length, 2)

assert.equal(context.convos[0].conversation.length, 3)
assert.equal(context.convos[0].conversation[0].sender, 'begin')

assert.equal(context.convos[1].conversation.length, 5)
assert.equal(context.convos[1].conversation[0].messageText, 'hi')
assert.equal(context.convos[1].conversation[1].messageText, 'hello')
Expand All @@ -51,21 +55,19 @@ describe('compiler.compileryml', function () {
assert.equal(context.utterances.length, 0)
})

describe('compiler.compileryml', function () {
it('should read utterances', async function () {
const scriptBuffer = fs.readFileSync(path.resolve(__dirname, 'convos', 'convos_and_utterances.yml'))
const context = buildContext()
const caps = {
}
const compiler = new Compiler(context, Object.assign({}, DefaultCapabilities, caps))
it('should read utterances', async function () {
const scriptBuffer = fs.readFileSync(path.resolve(__dirname, 'convos', 'convos_and_utterances.yml'))
const context = buildContext()
const caps = {
}
const compiler = new Compiler(context, Object.assign({}, DefaultCapabilities, caps))

compiler.Compile(scriptBuffer, Constants.SCRIPTING_TYPE_UTTERANCES)
assert.equal(context.utterances.length, 1)
assert.equal(context.utterances[0].name, 'GREETING')
assert.equal(context.utterances[0].utterances.length, 2)
assert.equal(context.utterances[0].utterances[1], 'hello!')
compiler.Compile(scriptBuffer, Constants.SCRIPTING_TYPE_UTTERANCES)
assert.equal(context.utterances.length, 1)
assert.equal(context.utterances[0].name, 'GREETING')
assert.equal(context.utterances[0].utterances.length, 2)
assert.equal(context.utterances[0].utterances[1], 'hello!')

assert.equal(context.convos.length, 0)
})
assert.equal(context.convos.length, 0)
})
})
64 changes: 64 additions & 0 deletions test/compiler/convos/convos_and_utterances.json
@@ -0,0 +1,64 @@
{
"convos": [
{
"name": "goodbye",
"description": "desc of convo goodbye",
"steps": [
{
"begin": [
"PAUSE 500"
]
},
{
"me": [
"bye"
]
},
{
"bot": [
"goodbye!"
]
}
]
},
{
"name": "convo 1 name",
"description": "desc of convo",
"steps": [
{
"me": [
"hi",
"PAUSE 500"
]
},
{
"bot": [
"TEXT hello",
"INTENT intent_greeting"
]
},
{
"bot": [
"what can i do for you?"
]
},
{
"me": [
"nothing"
]
},
{
"bot": [
"thanks"
]
}
]
}
],
"utterances": {
"GREETING": [
"hi",
"hello!"
]
}
}
2 changes: 2 additions & 0 deletions test/compiler/convos/convos_and_utterances.yml
Expand Up @@ -2,6 +2,8 @@ convos:
- name: goodbye
description: desc of convo goodbye
steps:
- begin:
- PAUSE 500
- me:
- bye
- bot:
Expand Down