Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

corti

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

corti - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

.editorconfig

3

Gruntfile.js

@@ -9,3 +9,4 @@ module.exports = function(grunt) {

all: [
'src/corti.js'
'src/corti.js',
'test/spec/**.js'
],

@@ -12,0 +13,0 @@ options: {

{
"name": "corti",
"version": "0.1.0",
"version": "0.2.0",
"description": "Replace window.SpeechRecognition with a mock object and automate your tests",

@@ -5,0 +5,0 @@ "main": "corti.js",

@@ -13,7 +13,16 @@ # Corti

````javascript
// Patch the current environment with a mock Speech Recognition object
Corti.patch();
// Interact with the mock object, like you would with the real SpeechRecognition object
var recognition = new window.SpeechRecognition();
recognition.onstart = function() {console.log("I'm listening");};
recognition.addEventListener('result', function(sre) {
console.log(sre.results.item(sre.resultIndex).item(0).transcript);
});
recognition.addEventListener('end', function() {console.log("Quiet");});
recognition.continuous = true;
// Use extra utility methods added to the mock object to assist with testing
expect(recognition.isStarted()).toBe(false);
recognition.onstart = function() {console.log('I\'m listening');};
recognition.addEventListener('end', function() {console.log('Quiet');});
recognition.start();

@@ -23,6 +32,11 @@ expect(recognition.isStarted()).toBe(true);

expect(recognition.isStarted()).toBe(false);
Corti.unpatch();
// Simulate speech recognition
recognition.addEventListener('result', mySpyFunction);
expect(mySpyFunction).not.toHaveBeenCalled();
recognition.say("Next time you want to stab me in the back, have the guts to do it to my face");
expect(mySpyFunction).toHaveBeenCalled();
````
### Methods Currently Mocked
### Methods Mocked

@@ -34,5 +48,29 @@ * start()

### Attributes Mocked
* interimResults
* lang
* continuous
* maxAlternatives
* onstart
* onend
* onresult
### Events Mocked
* start
* end
* result
### Event Objects Mocked
* SpeechRecognitionEvent
* SpeechRecognitionResultList
* SpeechRecognitionResult
* SpeechRecognitionAlternative
### Extra Utility Methods Added To Object
* isStarted()
* say()

@@ -39,0 +77,0 @@ ### Author

//! Corti - Replaces the browser's SpeechRecognition with a fake object.
//! version : 0.1.0
//! version : 0.2.0
//! author : Tal Ater @TalAter

@@ -19,7 +19,56 @@ //! license : MIT

// Speech Recognition attributes
var _maxAlternatives = 1;
var _lang = '';
var _continuous = false;
var _interimResults = false;
var newSpeechRecognition = function() {
var _self = this;
var _listeners = document.createElement('div');
_self._started = false;
_self.eventListeners = {'start': [], 'end': []};
_self.eventListenerTypes = ['start', 'end', 'result'];
_self.maxAlternatives = 1;
// Add listeners for events registered through attributes (e.g. recognition.onend = function) and not as proper listeners
_self.eventListenerTypes.forEach(function(eventName) {
_listeners.addEventListener(eventName, function () {
if (typeof _self['on'+eventName] === 'function') {
_self['on'+eventName].apply(_listeners, arguments);
}
}, false);
});
Object.defineProperty(this, 'maxAlternatives', {
get: function() { return _maxAlternatives; },
set: function(val) {
if (typeof val === 'number') {
_maxAlternatives = Math.floor(val);
} else {
_maxAlternatives = 0;
}
}
});
Object.defineProperty(this, 'lang', {
get: function() { return _lang; },
set: function(val) {
_lang = val.toString();
}
});
Object.defineProperty(this, 'continuous', {
get: function() { return _continuous; },
set: function(val) {
_continuous = Boolean(val);
}
});
Object.defineProperty(this, 'interimResults', {
get: function() { return _interimResults; },
set: function(val) {
_interimResults = Boolean(val);
}
});
this.start = function() {

@@ -30,8 +79,6 @@ if (_self._started) {

_self._started = true;
if (typeof _self.onstart === 'function') {
_self.onstart.call();
}
_self.eventListeners['start'].forEach(function(callback) {
callback.call();
});
// Create and dispatch an event
var event = document.createEvent('CustomEvent');
event.initCustomEvent('start', false, false, null);
_listeners.dispatchEvent(event);
};

@@ -44,8 +91,6 @@

_self._started = false;
if (typeof _self.onend === 'function') {
_self.onend.call();
}
_self.eventListeners['end'].forEach(function(callback) {
callback.call();
});
// Create and dispatch an event
var event = document.createEvent('CustomEvent');
event.initCustomEvent('end', false, false, null);
_listeners.dispatchEvent(event);
};

@@ -61,7 +106,60 @@

this.addEventListener = function(event, callback) {
if (_self.eventListeners[event]) {
_self.eventListeners[event].push(callback);
this.say = function(sentence) {
// Create some speech alternatives
var results = [];
var commandIterator;
var etcIterator;
var itemFunction = function(index) {
if (undefined === index) {
throw new DOMException('Failed to execute \'item\' on \'SpeechRecognitionResult\': 1 argument required, but only 0 present.');
}
index = Number(index);
if (isNaN(index)) {
index = 0;
}
if (index >= this.length) {
return null;
} else {
return this[index];
}
};
for (commandIterator = 0; commandIterator<_maxAlternatives; commandIterator++) {
var etc = '';
for (etcIterator = 0; etcIterator<commandIterator; etcIterator++) {
etc += ' and so on';
}
results.push(sentence+etc);
}
// Create the event
var event = document.createEvent('CustomEvent');
event.initCustomEvent('result', false, false, {'sentence': sentence});
event.resultIndex = 0;
event.results = {
'item': itemFunction,
0: {
'item': itemFunction,
'final': true
}
};
for (commandIterator = 0; commandIterator<_maxAlternatives; commandIterator++) {
event.results[0][commandIterator] = {
'transcript': results[commandIterator],
'confidence': Math.max(1-0.01*commandIterator, 0.001)
};
}
Object.defineProperty(event.results, 'length', {
get: function() { return 1; }
});
Object.defineProperty(event.results[0], 'length', {
get: function() { return _maxAlternatives; }
});
event.interpretation = null;
event.emma = null;
_listeners.dispatchEvent(event);
};
this.addEventListener = function(event, callback) {
_listeners.addEventListener(event, callback, false);
};
};

@@ -68,0 +166,0 @@

@@ -60,2 +60,6 @@ (function() {

it('should contain the method say', function () {
expect(recognition.say).toEqual(jasmine.any(Function));
});
it('should contain the method start', function () {

@@ -162,2 +166,3 @@ expect(recognition.start).toEqual(jasmine.any(Function));

var spyOnStart;
var spyOnStart2;
var recognition;

@@ -167,2 +172,3 @@

spyOnStart = jasmine.createSpy();
spyOnStart2 = jasmine.createSpy();
Corti.patch();

@@ -189,2 +195,12 @@ recognition = new window.SpeechRecognition();

it('should overwrite previous callback attached with onstart', function () {
expect(spyOnStart).not.toHaveBeenCalled();
expect(spyOnStart2).not.toHaveBeenCalled();
recognition.onstart = spyOnStart;
recognition.onstart = spyOnStart2;
recognition.start();
expect(spyOnStart).not.toHaveBeenCalled();
expect(spyOnStart2.calls.count()).toEqual(1);
});
});

@@ -195,2 +211,3 @@

var spyOnEnd;
var spyOnEnd2;
var recognition;

@@ -200,2 +217,3 @@

spyOnEnd = jasmine.createSpy();
spyOnEnd2 = jasmine.createSpy();
Corti.patch();

@@ -229,8 +247,58 @@ recognition = new window.SpeechRecognition();

it('should overwrite previous callback attached with onend', function () {
expect(spyOnEnd).not.toHaveBeenCalled();
expect(spyOnEnd2).not.toHaveBeenCalled();
recognition.onend = spyOnEnd;
recognition.onend = spyOnEnd2;
recognition.start();
recognition.abort();
expect(spyOnEnd).not.toHaveBeenCalled();
expect(spyOnEnd2.calls.count()).toEqual(1);
});
});
describe('SpeechRecognition.onresult', function() {
var spyOnResult;
var spyOnResult2;
var recognition;
beforeEach(function() {
spyOnResult = jasmine.createSpy();
spyOnResult2 = jasmine.createSpy();
Corti.patch();
recognition = new window.SpeechRecognition();
});
afterEach(function() {
Corti.unpatch();
});
it('should attach a callback to result event which will be called once when the speech recognizer returns a result', function () {
recognition.onresult = spyOnResult;
recognition.start();
expect(spyOnResult).not.toHaveBeenCalled();
recognition.say("Next time you want to stab me in the back, have the guts to do it to my face");
expect(spyOnResult.calls.count()).toEqual(1);
recognition.say("Man walks down the street in a hat like that, you know he's not afraid of anything");
expect(spyOnResult.calls.count()).toEqual(2);
});
it('should overwrite previous callback attached with onresult', function () {
recognition.onresult = spyOnResult;
recognition.onresult = spyOnResult2;
recognition.start();
expect(spyOnResult).not.toHaveBeenCalled();
recognition.say("Curse your sudden but inevitable betrayal");
expect(spyOnResult).not.toHaveBeenCalled();
expect(spyOnResult2.calls.count()).toEqual(1);
});
});
describe('SpeechRecognition.addEventListener("start")', function() {
var spyOnStart;
var spyOnEnd;
var spyOnStart2;
var recognition;

@@ -240,3 +308,3 @@

spyOnStart = jasmine.createSpy();
spyOnEnd = jasmine.createSpy();
spyOnStart2 = jasmine.createSpy();
Corti.patch();

@@ -263,2 +331,12 @@ recognition = new window.SpeechRecognition();

it('can attach multiple callbacks and all will respond to an event', function () {
expect(spyOnStart).not.toHaveBeenCalled();
expect(spyOnStart2).not.toHaveBeenCalled();
recognition.addEventListener('start', spyOnStart);
recognition.addEventListener('start', spyOnStart2);
recognition.start();
expect(spyOnStart.calls.count()).toEqual(1);
expect(spyOnStart2.calls.count()).toEqual(1);
});
});

@@ -281,3 +359,3 @@

it('should attach a callback to end event which will be called once on stop', function () {
it('should attach a callback to end event which will be called once on abort', function () {
recognition.addEventListener('end', spyOnEnd);

@@ -292,3 +370,3 @@ recognition.start();

it('should attach a callback to end event which will be called once on abort', function () {
it('should attach a callback to end event which will be called once on stop', function () {
recognition.addEventListener('end', spyOnEnd);

@@ -305,2 +383,29 @@ recognition.start();

describe('SpeechRecognition.addEventListener("result")', function() {
var spyOnResult;
var recognition;
beforeEach(function() {
spyOnResult = jasmine.createSpy();
Corti.patch();
recognition = new window.SpeechRecognition();
});
afterEach(function() {
Corti.unpatch();
});
it('should attach a callback to result event which will be called once when the speech recognizer returns a result', function () {
recognition.addEventListener('result', spyOnResult);
recognition.start();
expect(spyOnResult).not.toHaveBeenCalled();
recognition.say("You can't take the sky from me");
expect(spyOnResult.calls.count()).toEqual(1);
recognition.say("Well, my time of not taking you seriously is coming to a middle");
expect(spyOnResult.calls.count()).toEqual(2);
});
});
describe('SpeechRecognition.addEventListener("blerg")', function() {

@@ -332,2 +437,362 @@

describe('SpeechRecognition.say', function() {
var spyOnResult;
var recognition;
beforeEach(function() {
spyOnResult = jasmine.createSpy();
Corti.patch();
recognition = new window.SpeechRecognition();
});
afterEach(function() {
Corti.unpatch();
});
it('should fire the result event once', function () {
recognition.addEventListener('result', spyOnResult);
recognition.start();
expect(spyOnResult).not.toHaveBeenCalled();
recognition.say("You can't take the sky from me");
expect(spyOnResult.calls.count()).toEqual(1);
recognition.say("Well, my time of not taking you seriously is coming to a middle");
expect(spyOnResult.calls.count()).toEqual(2);
});
});
describe('start event', function() {
var recognition;
var event;
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
});
afterEach(function() {
Corti.unpatch();
event = undefined;
});
it('should be returned when using addEventListener', function () {
recognition.addEventListener('start', function(ev) {
event = ev;
});
recognition.start();
expect(event).toEqual(jasmine.any(Object));
});
it('should be returned when using onstart attribute', function () {
recognition.onstart = function(ev) {
event = ev;
};
recognition.start();
expect(event).toEqual(jasmine.any(Object));
});
it('should not persist after creating a new SpeechRecognition object', function () {
recognition.start();
expect(event).toEqual(undefined);
});
});
describe('end event', function() {
var recognition;
var event;
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
});
afterEach(function() {
Corti.unpatch();
event = undefined;
});
it('should be returned when using addEventListener', function () {
recognition.addEventListener('end', function(ev) {
event = ev;
});
recognition.start();
recognition.abort();
expect(event).toEqual(jasmine.any(Object));
});
it('should be returned when using onend attribute', function () {
recognition.onend = function(ev) {
event = ev;
};
recognition.start();
recognition.abort();
expect(event).toEqual(jasmine.any(Object));
});
it('should not persist after creating a new SpeechRecognition object', function () {
recognition.start();
recognition.abort();
expect(event).toEqual(undefined);
});
});
describe('SpeechRecognitionEvent', function() {
var recognition;
var event;
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
recognition.addEventListener('result', function(ev) {
event = ev;
});
recognition.start();
recognition.say("You can't take the sky from me");
});
afterEach(function() {
Corti.unpatch();
event = undefined;
});
it('should be an object', function () {
expect(event).toEqual(jasmine.any(Object));
});
it('should contain a results property with a SpeechRecognitionResultList object', function () {
expect(event.results).toEqual(jasmine.any(Object));
});
it('should contain a resultIndex property with the value 0', function () {
expect(event.resultIndex).toEqual(0);
});
it('should contain a emma property with the value null', function () {
expect(event.emma).toEqual(null);
});
it('should contain a interpretation property with the value null', function () {
expect(event.interpretation).toEqual(null);
});
});
describe('SpeechRecognitionResultList (SpeechRecognitionEvent.results)', function() {
var recognition;
var resultsListObject;
var event;
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
recognition.addEventListener('result', function(ev) {
resultsListObject = ev.results;
event = ev;
});
recognition.start();
recognition.say("You can't take the sky from me");
});
afterEach(function() {
Corti.unpatch();
resultsListObject = undefined;
});
it('should be an object', function () {
expect(resultsListObject).toEqual(jasmine.any(Object));
});
it('should have a length attribute', function () {
expect(resultsListObject.length).toBeDefined();
});
it('should have a length of 1', function () {
expect(resultsListObject.length).toEqual(1);
});
it('should contain an item method', function () {
expect(resultsListObject.item).toEqual(jasmine.any(Function));
});
it('should contain SpeechRecognitionResult object in index defined by resultIndex', function () {
expect(resultsListObject[event.resultIndex]).toEqual(jasmine.any(Object));
});
});
describe('SpeechRecognitionResultList.item', function() {
var recognition;
var resultsListObject;
var sentence = "You can't take the sky from me";
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
recognition.maxAlternatives = 5;
recognition.addEventListener('result', function(ev) {
resultsListObject = ev.results;
});
recognition.start();
recognition.say(sentence);
});
afterEach(function() {
Corti.unpatch();
resultsListObject = undefined;
});
it('should throw an exception if called with no arguments', function () {
expect(function() {
resultsListObject.item();
}).toThrowError();
});
it('should return a SpeechRecognitionResult when called with its index', function () {
expect(resultsListObject.item(0)).toEqual(jasmine.any(Object));
expect(resultsListObject.item(0).length).toEqual(5);
});
it('should return the first SpeechRecognitionResult when argument is NaN', function () {
expect(resultsListObject.item('goldstar')).toEqual(jasmine.any(Object));
expect(resultsListObject.item('goldstar').length).toEqual(5);
expect(resultsListObject.item(NaN)).toEqual(jasmine.any(Object));
expect(resultsListObject.item(NaN).length).toEqual(5);
});
it('should return null if argument is greater than or equal to the number of SpeechRecognitionResults', function () {
expect(resultsListObject.item(99)).toEqual(null);
});
});
describe('SpeechRecognitionResult (SpeechRecognitionEvent.results[0])', function() {
var recognition;
var resultObject;
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
recognition.addEventListener('result', function(ev) {
resultObject = ev.results[ev.resultIndex];
});
recognition.start();
recognition.say("You can't take the sky from me");
});
afterEach(function() {
Corti.unpatch();
resultObject = undefined;
});
it('should have a length attribute', function () {
expect(resultObject.length).toBeDefined();
});
it('should have a length equal to the maxAlternatives setting', function () {
recognition.maxAlternatives = 1;
recognition.say("You can't take the sky from me");
expect(resultObject.length).toEqual(1);
recognition.maxAlternatives = 4;
recognition.say("You can't take the sky from me");
expect(resultObject.length).toEqual(4);
});
it('should contain an item method', function () {
expect(resultObject.item).toEqual(jasmine.any(Function));
});
it('should contain a final attribute with a value of true', function () {
expect(resultObject.final).toEqual(true);
});
});
describe('SpeechRecognitionResult.item', function() {
var recognition;
var resultObject;
var sentence = "You can't take the sky from me";
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
recognition.maxAlternatives = 5;
recognition.addEventListener('result', function(ev) {
resultObject = ev.results[ev.resultIndex];
});
recognition.start();
recognition.say(sentence);
});
afterEach(function() {
Corti.unpatch();
resultObject = undefined;
});
it('should throw an exception if called with no arguments', function () {
expect(function() {
resultObject.item();
}).toThrowError();
});
it('should return a SpeechRecognitionAlternative when called with its index', function () {
expect(resultObject.item(0)).toEqual(jasmine.any(Object));
expect(resultObject.item(0).transcript).toEqual(sentence);
expect(typeof resultObject.item(1).transcript).toEqual('string');
});
it('should return the first SpeechRecognitionAlternative when argument is NaN', function () {
expect(resultObject.item('goldstar')).toEqual(jasmine.any(Object));
expect(resultObject.item('goldstar').transcript).toEqual(sentence);
expect(resultObject.item(NaN)).toEqual(jasmine.any(Object));
expect(resultObject.item(NaN).transcript).toEqual(sentence);
});
it('should return null if argument is greater than or equal to the number of alternatives returned', function () {
expect(resultObject.item(99)).toEqual(null);
});
});
describe('SpeechRecognitionAlternative (SpeechRecognitionEvent.results[0][n])', function() {
var recognition;
var alternativeObject;
beforeEach(function() {
Corti.patch();
recognition = new window.SpeechRecognition();
recognition.addEventListener('result', function(ev) {
alternativeObject = ev.results[ev.resultIndex][0];
});
recognition.start();
recognition.say("You can't take the sky from me");
});
afterEach(function() {
Corti.unpatch();
alternativeObject = undefined;
});
it('should contain a transcript attribute with a string value', function () {
expect(typeof alternativeObject.transcript).toEqual('string');
});
it('should contain a confidence attribute with a number between 0 and 1', function () {
expect(typeof alternativeObject.confidence).toEqual('number');
expect(alternativeObject.confidence <= 1).toEqual(true);
expect(alternativeObject.confidence >= 0).toEqual(true);
});
});
})();

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc