Quellcode durchsuchen

Merge pull request #2 from binhonglee/production

Added unit testing files
master
BinHong Lee vor 7 Jahren
committed by GitHub
Ursprung
Commit
3e7b5ea2f8
7 geänderte Dateien mit 471 neuen und 10 gelöschten Zeilen
  1. +11
    -0
      .travis.yml
  2. +8
    -6
      README.md
  3. +146
    -0
      package-lock.json
  4. +7
    -3
      package.json
  5. +2
    -1
      src/index.js
  6. +7
    -0
      test/dialogs/default.txt
  7. +290
    -0
      test/testflow.js

+ 11
- 0
.travis.yml Datei anzeigen

@@ -0,0 +1,11 @@
language: node_js
node_js:
- "node"
- "7"
- "6"
- "5"
- "4"
- "lts/*"
script: npm test
env:
CODECLIMATE_REPO_TOKEN: a174b03227cdc953c831f45bebcf0af357ec1b8a4b8477f36444c16f084a409f

+ 8
- 6
README.md Datei anzeigen

@@ -1,14 +1,16 @@
# Dota 2 Random - Alexa Skill

Skill is now available from the [Alexa Skill Store](https://www.amazon.com/binhonglee-Dota2-Random/dp/B073W4GDLS)!
[![Build Status](https://travis-ci.org/binhonglee/dota2-random.svg?branch=master)](https://travis-ci.org/binhonglee/dota2-random) [![Test Coverage](https://codeclimate.com/github/binhonglee/dota2-random/badges/coverage.svg)](https://codeclimate.com/github/binhonglee/dota2-random/coverage) [![Dependency Status](https://gemnasium.com/badges/github.com/binhonglee/dota2-random.svg)](https://gemnasium.com/github.com/binhonglee/dota2-random)

#### Dependency
- alexa-sdk
## Skill is now available from the [Alexa Skill Store](https://www.amazon.com/binhonglee-Dota2-Random/dp/B073W4GDLS)!

### Dependency
- node.js
- alexa-sdk

## Documentations
### Documentations

### Intents
#### Intents

| Intents | Description |
|:---------|:------------|
@@ -20,7 +22,7 @@ Skill is now available from the [Alexa Skill Store](https://www.amazon.com/binho
| `AMAZON.HelpIntent` | Provide examples on how to use the skill |
| `Stop` | Stop the skill |

### ROLE_TYPES (Custom slot)
#### ROLE_TYPES (Custom slot)
- melee
- ranged
- carry


+ 146
- 0
package-lock.json Datei anzeigen

@@ -0,0 +1,146 @@
{
"name": "dota2-random",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"alexa-sdk": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/alexa-sdk/-/alexa-sdk-1.0.11.tgz",
"integrity": "sha1-u8XZXJh4vHbEtI95Ca1iDIEESZU=",
"requires": {
"aws-sdk": "2.95.0",
"i18next": "3.5.2",
"i18next-sprintf-postprocessor": "0.2.2"
},
"dependencies": {
"aws-sdk": {
"version": "2.95.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.95.0.tgz",
"integrity": "sha1-JuIdsUlEOx8GOUnch5hPDRdwDmo=",
"requires": {
"buffer": "4.9.1",
"crypto-browserify": "1.0.9",
"events": "1.1.1",
"jmespath": "0.15.0",
"querystring": "0.2.0",
"sax": "1.2.1",
"url": "0.10.3",
"uuid": "3.0.1",
"xml2js": "0.4.17",
"xmlbuilder": "4.2.1"
},
"dependencies": {
"buffer": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"requires": {
"base64-js": "1.2.1",
"ieee754": "1.1.8",
"isarray": "1.0.0"
},
"dependencies": {
"base64-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
"integrity": "sha1-qRlH2h9KUW6jjltOwOw3c2deCIY="
},
"ieee754": {
"version": "1.1.8",
"resolved": "http://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
"integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
}
}
},
"crypto-browserify": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz",
"integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA="
},
"events": {
"version": "1.1.1",
"resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz",
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
},
"jmespath": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
"integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
},
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
},
"sax": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
"integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
},
"url": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
"integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
"requires": {
"punycode": "1.3.2",
"querystring": "0.2.0"
},
"dependencies": {
"punycode": {
"version": "1.3.2",
"resolved": "http://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
}
}
},
"uuid": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz",
"integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE="
},
"xml2js": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
"integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
"requires": {
"sax": "1.2.1",
"xmlbuilder": "4.2.1"
}
},
"xmlbuilder": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
"integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
"requires": {
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
}
}
},
"i18next": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-3.5.2.tgz",
"integrity": "sha1-kwOQ1cMYzqpIWLUt0OQOayA/n0E="
},
"i18next-sprintf-postprocessor": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/i18next-sprintf-postprocessor/-/i18next-sprintf-postprocessor-0.2.2.tgz",
"integrity": "sha1-LkCfEENXk4Jpi2otpwzapVHWfqQ="
}
}
}
}
}

+ 7
- 3
package.json Datei anzeigen

@@ -6,14 +6,18 @@
"dependencies": {
"alexa-sdk": "^1.0.7"
},
"scripts": {
"test": "npm install -g standard && standard && node test/testflow.js && npm uninstall -g standard"
},
"author": "binhonglee",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/binhonglee/dota2-alexa-skill.git"
"url": "git+ssh://git@github.com/binhonglee/dota2-random.git"
},
"bugs": {
"url": "https://github.com/binhonglee/dota2-alexa-skill/issues"
"url": "https://github.com/binhonglee/dota2-random/issues"
},
"homepage": "https://github.com/binhonglee/dota2-alexa-skill#readme"
"homepage": "https://github.com/binhonglee/dota2-random#readme",
"devDependencies": {}
}

+ 2
- 1
src/index.js Datei anzeigen

@@ -81,7 +81,8 @@ function randomHero (categories, callback) {
}

if (!possible) {
callback('Random failed')
var errorMessage = 'Random failed'
callback(errorMessage)
return
}



+ 7
- 0
test/dialogs/default.txt Datei anzeigen

@@ -0,0 +1,7 @@
LaunchRequest
AMAZON.HelpIntent
AnyRequest
RequestIntent Role=agility
RequestTwoIntent RoleOne=melee RoleTwo=ranged
RequestThreeIntent RoleOne=melee RoleTwo=intelligence RoleThree=support
Stop

+ 290
- 0
test/testflow.js Datei anzeigen

@@ -0,0 +1,290 @@
// Test Flow - a multiple intent test script for Alexa Lambda code
// Launch from a Terminal Prompt. Examples:
// node testflow
// node testflow staterequest.txt

// Originally taken from https://github.com/alexa/alexa-cookbook/blob/master/testing/TestFlow/testflow.js

// Toggle on or off various debugging outputs
const options = {
speechOutput: true,
slots: true,
stdout: false, // standard output / console.log() in your code
requestEvent: false, // show the full request JSON sent to your code
reprompt: false,
delay: 1.0 // seconds between requests
}

var locale = 'en-US'

var fs = require('fs')
var MyLambdaFunction = require('../src/index.js') // Your Lambda source with exports.handler

var MyDialog = './test/dialogs/default.txt'
var appId = '' // 'amzn1.ask.skill.d60ceb98-befe-4f49-a627-1f20f6e98d94'
var slotArray = []

if (process.argv[2]) {
MyDialog = './dialogs/' + process.argv[2]
}

console.log()
console.log('================================================================================')
console.log('Running test sequence from dialog file : ', MyDialog)
console.log()

const OriginalConsoleLog = console.log

var slotname = ''
var slotvalue = ''
var sa = {}
var currentLine = 1
var lineArray = []
var Intent = ''
var prompt = false

var context = {
'succeed': function (data) {
if (data.response.shouldEndSession) {
sa = {}
} else {
sa = data.sessionAttributes
}

console.log = OriginalConsoleLog
var textToSay = data.response.outputSpeech.ssml

if (options.speechOutput) {
console.log('\n\x1b[36m%s\x1b[0m', textToSay)
}

if (data.response.reprompt && data.response.reprompt.outputSpeech && data.response.reprompt.outputSpeech.ssml) {
var textReprompt = data.response.reprompt.outputSpeech.ssml
if (options.reprompt) {
// console.log('%s \x1b[33m\x1b[1m%s\x1b[0m \x1b[2m%s\x1b[0m', currentLine+1, Intent, sdkState)
console.log('\x1b[36m \x1b[2m%s\x1b[0m ', textReprompt)
}
}

if (data.response.shouldEndSession) {
console.log('\n================= Session Ended =================')
}

if (currentLine < lineArray.length) {
console.log()
runSingleTest(lineArray, currentLine++, sa)
} else {
console.log('')
process.exit()
}
},
'fail': function (err) {
console.log('context.fail occurred')
console.log(JSON.stringify(err, null, '\t'))
}
}

fs.readFile(MyDialog, function (err, data) { // open dialog sequence file and read Intents
// var newSession = true
if (err) {}
lineArray = cleanArray(data.toString().split('\n')) // remove empty or comment lines (# or //)
runSingleTest(lineArray, 0, {})
})

function runSingleTest (myLineArray, currentLine, sa) {
// console.log('--------------------------------------------------------------------------------')
// console.log('testing line ', currentLine)
// console.log('testing line values ', myLineArray[currentLine])
prompt = false
var newSession = true
if (currentLine > 0) {
newSession = false
}

var tokenArray = myLineArray[currentLine].split(' ')

if (tokenArray[0].replace('\r', '') === '?') { // pause and prompt the user to confirm
prompt = true
// console.log(' ----------------- > prompt')
tokenArray.shift() // removes first item
}

var requestType = tokenArray[0].replace('\r', '')
tokenArray.shift()

if (requestType === 'stop') {
console.log('')
process.exit()
}

Intent = requestType
// slotArray = []

var sdkState = ''
if (sa['STATE']) {
sdkState = sa['STATE']
}

console.log('%s \x1b[33m\x1b[1m%s\x1b[0m \x1b[2m%s\x1b[0m', currentLine + 1, Intent, sdkState)
processArray(tokenArray, function (request) {
prepareTestRequest(sa, newSession, request)
})
}

function processArray (arr, cb) {
if (arr.length > 0) {
var equalsPosition = arr[0].indexOf('=')
slotname = arr[0].substr(0, equalsPosition)
slotvalue = decodeURI(arr[0].substr(equalsPosition + 1, 300)).replace('\r', '')

promptForSlot(prompt, slotname, slotvalue, (newValue) => {
// console.log('slotname, slotvalue, newValue')
// console.log(slotname, slotvalue, newValue)

var answer = newValue.toString().trim()

// console.log('answer = ' + answer)

if (answer === '') {
answer = slotvalue
}

if (answer !== '') {
slotArray.push('"' + slotname + '": {"name":"' + slotname + '","value":"' + answer + '"}')
}

arr.shift()
processArray(arr, cb) // RECURSION
})
} else { // nothing left in slot array
var slotArrayString = '{' + slotArray.toString() + '}'

var slotObj = JSON.parse(slotArrayString)

var req = {
'type': 'IntentRequest',
'intent': {
'name': Intent,
'slots': slotObj
},
'locale': locale
}
cb(req)
// process.exit()
}
}

function prepareTestRequest (sa, newSession, request) {
var eventJSON = {
'session': {
'sessionId': 'SessionId.f9e6dcbb-b7da-4b47-905c.etc.etc',
'application': {
'applicationId': appId
},
'attributes': sa,
'user': {
'userId': 'amzn1.ask.account.VO3PVTGF563MOPBY.etc.etc'
},
'new': newSession
},
request,
'version': '1.0'
}

if (options.requestEvent) {
console.log(JSON.stringify(request, null, 2))
}

// blocking pause
var waitTill = new Date(new Date().getTime() + options.delay * 1000)
while (waitTill > new Date()) {}

// call the function
if (options.stdout) {
MyLambdaFunction['handler'](eventJSON, context, callback)
} else {
// console.log('setting log to {}')
console.log = function () {}
// console.log('set log to {}')

MyLambdaFunction['handler'](eventJSON, context, callback)
console.log = OriginalConsoleLog
}
}

function promptForSlot (prompt, slotname, slotvalue, callback) {
if (prompt) {
process.stdout.write('\x1b[34m' + slotname + ' \x1b[0m\x1b[32m [' + slotvalue + ']\x1b[0m: ')

// console.log('\x1b[34m%s :\x1b[0m\x1b[32m %s\x1b[0m ', slotname, slotvalue )

process.stdin.once('data', function (data) {
var answer = data.toString().trim()
// console.log(answer)
if (answer === '') {
if (slotvalue === '') {
// no default, user must type something
console.error('Error: No default slot value defined, user must type a slot value.')
process.exit()
} else {
answer = slotvalue
}
}

callback(answer)
})
} else {
if (options.slots) {
console.log('\x1b[34m%s :\x1b[0m\x1b[32m %s\x1b[0m ', slotname, slotvalue)
}

callback(slotvalue)
}
}

function callback (error, data) {
if (error) {
console.log('error: ' + error)
} else {
console.log(data)
}
}

function cleanArray (myArray) {
var cleanedArray = []

for (var i = 0; i < myArray.length; i++) {
if (myArray[i] !== '' && myArray[i].substring(0, 1) !== '#' && myArray[i].substring(0, 2) !== '//') {
cleanedArray.push(myArray[i])
}
}
return cleanedArray
}
//
// const fontcolor = {
// Reset = '\x1b[0m',
// Bright = '\x1b[1m',
// Dim = '\x1b[2m',
// Underscore = '\x1b[4m',
// Blink = '\x1b[5m',
// Reverse = '\x1b[7m',
// Hidden = '\x1b[8m',
//
// FgBlack = '\x1b[30m',
// FgRed = '\x1b[31m',
// FgGreen = '\x1b[32m',
// FgYellow = '\x1b[33m',
// FgBlue = '\x1b[34m',
// FgMagenta = '\x1b[35m',
// FgCyan = '\x1b[36m',
// FgWhite = '\x1b[37m',
//
// BgBlack = '\x1b[40m',
// BgRed = '\x1b[41m',
// BgGreen = '\x1b[42m',
// BgYellow = '\x1b[43m',
// BgBlue = '\x1b[44m',
// BgMagenta = '\x1b[45m',
// BgCyan = '\x1b[46m',
// BgWhite = '\x1b[47m'
// }

Laden…
Abbrechen
Speichern