empath-sentiment-analysis
Advanced tools
Comparing version 1.0.0 to 1.0.1
{ | ||
"name": "empath-sentiment-analysis", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Tools to analyse sentiment in the browser", | ||
@@ -5,0 +5,0 @@ "main": "empath.js", |
@@ -8,1 +8,75 @@ Empath can be used to perform client side sentiment analysis. It is designed to work with emails. | ||
- egoismAnalyser (so you can figure out how selfish someone is based on their communication) | ||
Usage: | ||
1. npm install --save-dev empath-sentiment-analysis | ||
2. Sentiment analyser: | ||
Modified from https://github.com/thisandagain/sentiment/blob/master/lib/index.js | ||
import empath from 'empath-sentiment-analysis'; | ||
empath.analyseSentiment(phrase = '', attributesOfInterest = []); | ||
Result: | ||
{ | ||
wordListDidNotMatch: tryAnotherWordList, | ||
score: score, | ||
comparative: score / tokens.length, | ||
tokens: tokens, | ||
words: words, | ||
positive: positive, | ||
negative: negative, | ||
attributeScores: attributeScores | ||
}; | ||
Attribute scores are useful if you have a number of products for which you want to analyse sentiment. Review the test cases for more details. | ||
3. DISC Profile Guesser | ||
import empath from 'empath-sentiment-analysis'; | ||
empath.guessDISCProfile.getUserReadableDISCProfile(email); | ||
result: | ||
{ | ||
'D': D, | ||
'I': I, | ||
'S': S, | ||
'C': C, | ||
} | ||
or | ||
empath.guessDISCProfile.getUserReadableDISCProfile(email); | ||
result: two letters indicating primary and secondary profile, e.g. DC | ||
4. Email parser | ||
import empath from 'empath-sentiment-analysis'; | ||
const emailWithoutSignatureAndQuotedReplies = empath.parseEmail(email); | ||
If you supply an email with a long signature and quoted replies from the thread, it will trim everything except the first email. | ||
5. Readability analyser | ||
import empath from 'empath-sentiment-analysis'; | ||
const readabilityScore = empath.calculateReadabilityScore(email); | ||
Anything above 4.0 is considered advanced vocab | ||
6. Egoism analyser | ||
import empath from 'empath-sentiment-analysis'; | ||
const egoismScore = empath.analyseEgoism(email); | ||
Result: | ||
{ | ||
selfish, | ||
controlling, | ||
conforming | ||
}; | ||
Selfish = number of selfish words used | ||
Controlling = number of command/imperative words used | ||
Conforming = number of we/group style words | ||
Ratio can yield interesting insights about personality |
@@ -1,124 +0,120 @@ | ||
import * as sentimentAnalyser from './analyseSentiment.js'; | ||
import * as egoismAnalyser from './utils/egoismAnalyser.js'; | ||
import sentimentAnalyser from './analyseSentiment.js'; | ||
import egoismAnalyser from './utils/egoismAnalyser.js'; | ||
import { calculateReadabilityScore } from './utils/calculateReadingLevel.js'; | ||
export var discProfileAnalyser = (function () { | ||
'use strict'; | ||
let sentimentScores, | ||
prefixModifiers, | ||
postfixModifiers, | ||
currentPrefixModifierScore, | ||
currentPostfixModifierScore, | ||
lastNormalTokenSentimentScore; | ||
var sentimentScores, | ||
prefixModifiers, | ||
postfixModifiers, | ||
currentPrefixModifierScore, | ||
currentPostfixModifierScore, | ||
lastNormalTokenSentimentScore; | ||
function getUserReadableDISCProfile(emailContents) { | ||
const bestGuessAtDISCProfile = analyseEmail(emailContents); | ||
let highestProfileScore = 1; | ||
let highestProfile = ''; | ||
let secondHighestProfileScore = 1; | ||
let secondHighestProfile = ''; | ||
function getUserReadableDISCProfile(emailContents, readabilityScore) { | ||
var bestGuessAtDISCProfile = analyseEmail(emailContents, readabilityScore), | ||
highestProfileScore = 1, | ||
highestProfile = '', | ||
secondHighestProfileScore = 1, | ||
secondHighestProfile = ''; | ||
Object.keys(bestGuessAtDISCProfile).forEach(function (profile) { | ||
if (bestGuessAtDISCProfile[profile] > highestProfileScore) { | ||
highestProfile = profile; | ||
highestProfileScore = bestGuessAtDISCProfile[profile]; | ||
} else if (bestGuessAtDISCProfile[profile] > secondHighestProfileScore) { | ||
secondHighestProfile = profile; | ||
secondHighestProfileScore = bestGuessAtDISCProfile[profile]; | ||
} | ||
}); | ||
Object.keys(bestGuessAtDISCProfile).forEach(function (profile) { | ||
if (bestGuessAtDISCProfile[profile] > highestProfileScore) { | ||
highestProfile = profile; | ||
highestProfileScore = bestGuessAtDISCProfile[profile]; | ||
} else if (bestGuessAtDISCProfile[profile] > secondHighestProfileScore) { | ||
secondHighestProfile = profile; | ||
secondHighestProfileScore = bestGuessAtDISCProfile[profile]; | ||
} | ||
}); | ||
return highestProfile + secondHighestProfile; | ||
} | ||
return highestProfile + secondHighestProfile; | ||
} | ||
/** | ||
* Attempts to guess the DISC profile of a sender based on an email they've sent | ||
* | ||
* @param {String} emailContents Contents of email to analyse | ||
* @param {Integer} readabilityScore Readability score of email (analysed already) | ||
* | ||
* @return {Object} | ||
*/ | ||
function analyseEmail(emailContents = '') { | ||
const readabilityScore = calculateReadabilityScore(emailContents); | ||
const guessAtDISCProfile = { | ||
'D': 1, | ||
'I': 1, | ||
'S': 1, | ||
'C': 1, | ||
}; | ||
/** | ||
* Attempts to guess the DISC profile of a sender based on an email they've sent | ||
* | ||
* @param {String} emailContents Contents of email to analyse | ||
* @param {Integer} readabilityScore Readability score of email (analysed already) | ||
* | ||
* @return {Object} | ||
*/ | ||
function analyseEmail(emailContents = '', readabilityScore) { | ||
addGuessBasedOnSentiment(emailContents, guessAtDISCProfile); | ||
addGuessBasedOnVocabulary(readabilityScore, guessAtDISCProfile); | ||
addGuessBasedOnEgoism(emailContents, guessAtDISCProfile); | ||
var guessAtDISCProfile = { | ||
'D': 1, | ||
'I': 1, | ||
'S': 1, | ||
'C': 1, | ||
}; | ||
reduceGuessesThatExceedThreshold(guessAtDISCProfile); | ||
addGuessBasedOnSentiment(emailContents, guessAtDISCProfile); | ||
addGuessBasedOnVocabulary(readabilityScore, guessAtDISCProfile); | ||
addGuessBasedOnEgoism(emailContents, guessAtDISCProfile); | ||
return guessAtDISCProfile; | ||
} | ||
reduceGuessesThatExceedThreshold(guessAtDISCProfile); | ||
function addGuessBasedOnSentiment(emailContents, guessAtDISCProfile) { | ||
const sentimentScore = sentimentAnalyser(emailContents).score; | ||
const lengthOfEmail = emailContents.length; | ||
const LENGTH_OF_SHORT_EMAIL = 30; | ||
const CHEERFUL_SENTIMENT_SCORE = 5; | ||
const HYPER_CHEERFUL_SENTIMENT_SCORE = 15; | ||
return guessAtDISCProfile; | ||
} | ||
function addGuessBasedOnSentiment(emailContents, guessAtDISCProfile) { | ||
const sentimentScore = sentimentAnalyser.analyseSentiment(emailContents).score; | ||
const lengthOfEmail = emailContents.length; | ||
const LENGTH_OF_SHORT_EMAIL = 30; | ||
const CHEERFUL_SENTIMENT_SCORE = 5; | ||
const HYPER_CHEERFUL_SENTIMENT_SCORE = 15; | ||
if (sentimentScore < CHEERFUL_SENTIMENT_SCORE) { | ||
if (lengthOfEmail < LENGTH_OF_SHORT_EMAIL) { | ||
guessAtDISCProfile.D += 4; | ||
} | ||
else { | ||
guessAtDISCProfile.C += 3; | ||
} | ||
if (sentimentScore < CHEERFUL_SENTIMENT_SCORE) { | ||
if (lengthOfEmail < LENGTH_OF_SHORT_EMAIL) { | ||
guessAtDISCProfile.D += 4; | ||
} | ||
else { | ||
guessAtDISCProfile.C += 3; | ||
} | ||
} else { | ||
if (sentimentScore > HYPER_CHEERFUL_SENTIMENT_SCORE) { | ||
guessAtDISCProfile.I += 5; | ||
} else { | ||
if (sentimentScore > HYPER_CHEERFUL_SENTIMENT_SCORE) { | ||
guessAtDISCProfile.I += 5; | ||
} else { | ||
guessAtDISCProfile.S += 3; | ||
} | ||
guessAtDISCProfile.S += 3; | ||
} | ||
} | ||
} | ||
function addGuessBasedOnVocabulary(readabilityScore, guessAtDISCProfile) { | ||
const ADVANCED_VOCAB_LEVEL = 4.0; | ||
function addGuessBasedOnVocabulary(readabilityScore, guessAtDISCProfile) { | ||
const ADVANCED_VOCAB_LEVEL = 4.0; | ||
if (readabilityScore >= ADVANCED_VOCAB_LEVEL) { | ||
guessAtDISCProfile.C += 2; | ||
} | ||
if (readabilityScore >= ADVANCED_VOCAB_LEVEL) { | ||
guessAtDISCProfile.C += 2; | ||
} | ||
} | ||
function addGuessBasedOnEgoism(emailContents, guessAtDISCProfile) { | ||
var egoismScores = egoismAnalyser.analyseEgoism(emailContents); | ||
function addGuessBasedOnEgoism(emailContents, guessAtDISCProfile) { | ||
var egoismScores = egoismAnalyser(emailContents); | ||
if (egoismScores.selfish > egoismScores.controlling && | ||
egoismScores.selfish > egoismScores.conforming) { | ||
if (egoismScores.selfish > egoismScores.controlling && | ||
egoismScores.selfish > egoismScores.conforming) { | ||
guessAtDISCProfile.I += 2; | ||
guessAtDISCProfile.I += 2; | ||
} else if (egoismScores.controlling > egoismScores.selfish && | ||
egoismScores.controlling > egoismScores.conforming) { | ||
} else if (egoismScores.controlling > egoismScores.selfish && | ||
egoismScores.controlling > egoismScores.conforming) { | ||
guessAtDISCProfile.D += 2; | ||
guessAtDISCProfile.D += 2; | ||
} else if (egoismScores.conforming > egoismScores.controlling) { | ||
guessAtDISCProfile.S += 2; | ||
} | ||
} | ||
} else if (egoismScores.conforming > egoismScores.controlling) { | ||
guessAtDISCProfile.S += 2; | ||
} | ||
} | ||
function reduceGuessesThatExceedThreshold(guessAtDISCProfile) { | ||
const MAX_SCORE = 7; | ||
function reduceGuessesThatExceedThreshold(guessAtDISCProfile) { | ||
const MAX_SCORE = 7; | ||
Object.keys(guessAtDISCProfile).forEach(function (profile) { | ||
if (guessAtDISCProfile[profile] > MAX_SCORE) { | ||
guessAtDISCProfile[profile] = MAX_SCORE; | ||
} | ||
}); | ||
} | ||
Object.keys(guessAtDISCProfile).forEach(function (profile) { | ||
if (guessAtDISCProfile[profile] > MAX_SCORE) { | ||
guessAtDISCProfile[profile] = MAX_SCORE; | ||
} | ||
}); | ||
} | ||
return { | ||
analyseEmail: analyseEmail, | ||
getUserReadableDISCProfile: getUserReadableDISCProfile | ||
}; | ||
})(); | ||
export default { | ||
analyseEmail, | ||
getUserReadableDISCProfile | ||
}; |
import _ from '../node_modules/underscore/underscore.js'; | ||
import sentimentWordLists from './sentimentWordList.js'; | ||
import * as regexList from './utils/regexList.js'; | ||
import regexList from './utils/regexList.js'; | ||
export let analyseSentiment = (function () { | ||
'use strict'; | ||
let currentPrefixes = []; | ||
let currentPostfixes = []; | ||
let sentimentScores, | ||
prefixModifiers, | ||
postfixModifiers, | ||
currentPrefixModifierScore, | ||
currentPostfixModifierScore, | ||
lastNormalTokenSentimentScore; | ||
let currentPrefixes = []; | ||
let currentPostfixes = []; | ||
let sentimentScores, | ||
prefixModifiers, | ||
postfixModifiers, | ||
currentPrefixModifierScore, | ||
currentPostfixModifierScore, | ||
lastNormalTokenSentimentScore; | ||
/** | ||
* Modified from https://github.com/thisandagain/sentiment/blob/master/lib/index.js | ||
* Performs sentiment analysis on the provided input "phrase". | ||
* | ||
* @param {String} Input phrase | ||
* @param {Object} Optional sentiment additions to sentimentScores (hash k/v pairs) | ||
* | ||
* @return {Object} | ||
*/ | ||
export default function analyseSentiment (phrase = '', attributesOfInterest = [], inject = null, callback = null) { | ||
let result; | ||
/** | ||
* Modified from https://github.com/thisandagain/sentiment/blob/master/lib/index.js | ||
* Performs sentiment analysis on the provided input "phrase". | ||
* | ||
* @param {String} Input phrase | ||
* @param {Object} Optional sentiment additions to sentimentScores (hash k/v pairs) | ||
* | ||
* @return {Object} | ||
*/ | ||
function analyseSentiment (phrase = '', attributesOfInterest = [], inject = null, callback = null) { | ||
let result; | ||
Object.keys(sentimentWordLists).forEach(function (wordListKey) { | ||
//try another word list if we don't get any matches | ||
if (!result || result.tryAnotherWordList) { | ||
result = useWordListToAnalyseSentiment(sentimentWordLists[wordListKey], phrase, attributesOfInterest, inject, callback); | ||
} | ||
}); | ||
Object.keys(sentimentWordLists).forEach(function (wordListKey) { | ||
//try another word list if we don't get any matches | ||
if (!result || result.tryAnotherWordList) { | ||
result = useWordListToAnalyseSentiment(sentimentWordLists[wordListKey], phrase, attributesOfInterest, inject, callback); | ||
} | ||
}); | ||
return result; | ||
} | ||
return result; | ||
} | ||
function useWordListToAnalyseSentiment (wordList, phrase, attributesOfInterest, inject, callback) { | ||
setupWordList(wordList, inject); | ||
function useWordListToAnalyseSentiment (wordList, phrase, attributesOfInterest, inject, callback) { | ||
setupWordList(wordList, inject); | ||
// Storage objects | ||
let tokens = tokenize(phrase), | ||
score = 0, | ||
words = [], | ||
positive = [], | ||
negative = [], | ||
scoreForCurrentSentence = 0, | ||
attributeScores = {}, | ||
currentAttributeBeingDiscussed, | ||
tryAnotherWordList = false, | ||
THRESHOLD_BEFORE_WE_TRY_ANOTHER_WORDLIST = 50; | ||
// Storage objects | ||
let tokens = tokenize(phrase), | ||
score = 0, | ||
words = [], | ||
positive = [], | ||
negative = [], | ||
scoreForCurrentSentence = 0, | ||
attributeScores = {}, | ||
currentAttributeBeingDiscussed, | ||
tryAnotherWordList = false, | ||
THRESHOLD_BEFORE_WE_TRY_ANOTHER_WORDLIST = 50; | ||
currentPrefixModifierScore = 1; | ||
currentPostfixModifierScore = 1; | ||
lastNormalTokenSentimentScore = 0; | ||
currentPrefixModifierScore = 1; | ||
currentPostfixModifierScore = 1; | ||
lastNormalTokenSentimentScore = 0; | ||
tokens.forEach(function(word, index) { | ||
tokens.forEach(function(word, index) { | ||
const isFinalWord = index === tokens.length - 1; | ||
const isFinalWord = index === tokens.length - 1; | ||
if (tokens.length < 3 && index > THRESHOLD_BEFORE_WE_TRY_ANOTHER_WORDLIST) { | ||
tryAnotherWordList = true; | ||
return; | ||
} | ||
if (tokens.length < 3 && index > THRESHOLD_BEFORE_WE_TRY_ANOTHER_WORDLIST) { | ||
tryAnotherWordList = true; | ||
return; | ||
const wordSentimentAnalysis = analyseSentimentForWord(word, isFinalWord); | ||
const wordSentimentScore = wordSentimentAnalysis.score; | ||
const processedWord = wordSentimentAnalysis.word; | ||
const attributeCorrespondingToThisWord = getAttributeCorrespondingToThisWord(word, attributesOfInterest, tokens, index); | ||
const hasSameWordAfterwards = tokens[index + 1] === word; | ||
const endOfSentence = (word === '?' || word === '!' || word === '.') && | ||
//don't consider sentence over if the next word is same e.g !!! | ||
!hasSameWordAfterwards; | ||
if (attributeCorrespondingToThisWord) { | ||
if (!attributeScores[attributeCorrespondingToThisWord]) { | ||
attributeScores[attributeCorrespondingToThisWord] = 0; | ||
} | ||
const wordSentimentAnalysis = analyseSentimentForWord(word, isFinalWord); | ||
const wordSentimentScore = wordSentimentAnalysis.score; | ||
const processedWord = wordSentimentAnalysis.word; | ||
const attributeCorrespondingToThisWord = getAttributeCorrespondingToThisWord(word, attributesOfInterest, tokens, index); | ||
const hasSameWordAfterwards = tokens[index + 1] === word; | ||
const endOfSentence = (word === '?' || word === '!' || word === '.') && | ||
//don't consider sentence over if the next word is same e.g !!! | ||
!hasSameWordAfterwards; | ||
if (attributeCorrespondingToThisWord) { | ||
if (!attributeScores[attributeCorrespondingToThisWord]) { | ||
attributeScores[attributeCorrespondingToThisWord] = 0; | ||
} | ||
currentAttributeBeingDiscussed = attributeCorrespondingToThisWord; | ||
} | ||
currentAttributeBeingDiscussed = attributeCorrespondingToThisWord; | ||
scoreForCurrentSentence += wordSentimentScore; | ||
if (endOfSentence) { | ||
//end of sentence - give score to current attribute | ||
//e.g. Sentence is "I really like Zoho Support" - should get score from `really like` | ||
if (currentAttributeBeingDiscussed) { | ||
attributeScores[currentAttributeBeingDiscussed] += scoreForCurrentSentence; | ||
} | ||
scoreForCurrentSentence = 0; | ||
} | ||
scoreForCurrentSentence += wordSentimentScore; | ||
if (!wordSentimentScore) { | ||
return; | ||
} | ||
if (endOfSentence) { | ||
//end of sentence - give score to current attribute | ||
//e.g. Sentence is "I really like Zoho Support" - should get score from `really like` | ||
if (currentAttributeBeingDiscussed) { | ||
attributeScores[currentAttributeBeingDiscussed] += scoreForCurrentSentence; | ||
} | ||
scoreForCurrentSentence = 0; | ||
} | ||
words.push(processedWord); | ||
if (!wordSentimentScore) { | ||
return; | ||
} | ||
if (wordSentimentScore > 0) { | ||
positive.push(processedWord); | ||
} else if (wordSentimentScore < 0) { | ||
negative.push(processedWord); | ||
} | ||
words.push(processedWord); | ||
score += wordSentimentScore; | ||
}); | ||
if (wordSentimentScore > 0) { | ||
positive.push(processedWord); | ||
} else if (wordSentimentScore < 0) { | ||
negative.push(processedWord); | ||
} | ||
let result = { | ||
wordListDidNotMatch: tryAnotherWordList, | ||
score: score, | ||
comparative: score / tokens.length, | ||
tokens: tokens, | ||
words: words, | ||
positive: positive, | ||
negative: negative, | ||
attributeScores: attributeScores | ||
}; | ||
score += wordSentimentScore; | ||
}); | ||
if (callback === null) { | ||
return result; | ||
} | ||
let result = { | ||
wordListDidNotMatch: tryAnotherWordList, | ||
score: score, | ||
comparative: score / tokens.length, | ||
tokens: tokens, | ||
words: words, | ||
positive: positive, | ||
negative: negative, | ||
attributeScores: attributeScores | ||
}; | ||
_.defer(function () { | ||
callback(null, result); | ||
}); | ||
} | ||
if (callback === null) { | ||
return result; | ||
} | ||
function analyseSentimentForWord(word, isFinalWord) { | ||
const lowerCaseWord = word.toLowerCase(); | ||
const tokenPrefixModifierScore = prefixModifiers[lowerCaseWord]; | ||
const tokenPostfixModifierScore = postfixModifiers[lowerCaseWord]; | ||
const tokenSentimentScore = sentimentScores[lowerCaseWord]; | ||
const isAllUpperCase = word.toUpperCase() === word; | ||
const MULTIPLIER_FOR_ALL_UPPER_CASE = 2; | ||
let processedSentimentScore = 0; | ||
let shouldAddToScore = tokenPrefixModifierScore || tokenPostfixModifierScore || tokenSentimentScore; | ||
let processedWord; | ||
_.defer(function () { | ||
callback(null, result); | ||
}); | ||
if (tokenPrefixModifierScore) { | ||
currentPrefixes.push(word); | ||
currentPrefixModifierScore *= (tokenPrefixModifierScore); | ||
shouldAddToScore = false; | ||
} | ||
function analyseSentimentForWord(word, isFinalWord) { | ||
const lowerCaseWord = word.toLowerCase(); | ||
const tokenPrefixModifierScore = prefixModifiers[lowerCaseWord]; | ||
const tokenPostfixModifierScore = postfixModifiers[lowerCaseWord]; | ||
const tokenSentimentScore = sentimentScores[lowerCaseWord]; | ||
const isAllUpperCase = word.toUpperCase() === word; | ||
const MULTIPLIER_FOR_ALL_UPPER_CASE = 2; | ||
let processedSentimentScore = 0; | ||
let shouldAddToScore = tokenPrefixModifierScore || tokenPostfixModifierScore || tokenSentimentScore; | ||
let processedWord; | ||
if (tokenPostfixModifierScore) { | ||
currentPostfixes.push(word); | ||
currentPostfixModifierScore *= (tokenPostfixModifierScore - 1); | ||
shouldAddToScore = false; | ||
} | ||
if (tokenPrefixModifierScore) { | ||
currentPrefixes.push(word); | ||
currentPrefixModifierScore *= (tokenPrefixModifierScore); | ||
shouldAddToScore = false; | ||
} | ||
if (tokenSentimentScore) { | ||
lastNormalTokenSentimentScore = tokenSentimentScore; | ||
if (tokenPostfixModifierScore) { | ||
currentPostfixes.push(word); | ||
currentPostfixModifierScore *= (tokenPostfixModifierScore - 1); | ||
shouldAddToScore = false; | ||
if (isAllUpperCase) { | ||
lastNormalTokenSentimentScore *= MULTIPLIER_FOR_ALL_UPPER_CASE; | ||
} | ||
} | ||
if (tokenSentimentScore) { | ||
lastNormalTokenSentimentScore = tokenSentimentScore; | ||
if (isFinalWord) { | ||
shouldAddToScore = true; | ||
} | ||
if (isAllUpperCase) { | ||
lastNormalTokenSentimentScore *= MULTIPLIER_FOR_ALL_UPPER_CASE; | ||
} | ||
} | ||
if (lastNormalTokenSentimentScore && shouldAddToScore) { | ||
processedSentimentScore = lastNormalTokenSentimentScore * currentPrefixModifierScore * currentPostfixModifierScore; | ||
currentPrefixModifierScore = 1; | ||
currentPostfixModifierScore = 1; | ||
processedWord = currentPrefixes.join(' ') + ' ' + word + ' ' + currentPostfixes.join(' '); | ||
currentPostfixes = []; | ||
currentPrefixes = []; | ||
} | ||
if (isFinalWord) { | ||
shouldAddToScore = true; | ||
} | ||
return { | ||
score: processedSentimentScore, | ||
word: processedWord | ||
}; | ||
} | ||
if (lastNormalTokenSentimentScore && shouldAddToScore) { | ||
processedSentimentScore = lastNormalTokenSentimentScore * currentPrefixModifierScore * currentPostfixModifierScore; | ||
currentPrefixModifierScore = 1; | ||
currentPostfixModifierScore = 1; | ||
processedWord = currentPrefixes.join(' ') + ' ' + word + ' ' + currentPostfixes.join(' '); | ||
currentPostfixes = []; | ||
currentPrefixes = []; | ||
} | ||
function setupWordList(sentimentWordList, inject) { | ||
if (!sentimentScores) { | ||
sentimentScores = _.clone(sentimentWordList.SENTIMENT_SCORES); | ||
} | ||
return { | ||
score: processedSentimentScore, | ||
word: processedWord | ||
}; | ||
if (!prefixModifiers) { | ||
prefixModifiers = _.clone(sentimentWordList.PREFIX_MODIFIERS); | ||
} | ||
function setupWordList(sentimentWordList, inject) { | ||
if (!sentimentScores) { | ||
sentimentScores = _.clone(sentimentWordList.SENTIMENT_SCORES); | ||
} | ||
if (!postfixModifiers) { | ||
postfixModifiers = _.clone(sentimentWordList.POSTFIX_MODIFIERS); | ||
} | ||
if (!prefixModifiers) { | ||
prefixModifiers = _.clone(sentimentWordList.PREFIX_MODIFIERS); | ||
} | ||
// Merge | ||
if (inject !== null) { | ||
sentimentScores = _.extend(sentimentScores, inject); | ||
} | ||
} | ||
if (!postfixModifiers) { | ||
postfixModifiers = _.clone(sentimentWordList.POSTFIX_MODIFIERS); | ||
} | ||
/** | ||
* Tokenizes an input string. | ||
* | ||
* @param {String} Input | ||
* | ||
* @return {Array} | ||
*/ | ||
function tokenize (input) { | ||
// Merge | ||
if (inject !== null) { | ||
sentimentScores = _.extend(sentimentScores, inject); | ||
} | ||
if (!input) { | ||
return input; | ||
} | ||
/** | ||
* Tokenizes an input string. | ||
* | ||
* @param {String} Input | ||
* | ||
* @return {Array} | ||
*/ | ||
function tokenize (input) { | ||
const BR_Tags = 'divbr', | ||
EXCLAMATION_MARKS = /(\!)/g, | ||
QUESTION_MARKS = /\?/g, | ||
FULL_STOPS = /\./g, | ||
EXTRA_SPACES = '/ {2,}/'; | ||
if (!input) { | ||
return input; | ||
} | ||
return input | ||
.replace(regexList.EMOJI_REGEX, ' $1 ') | ||
.replace(BR_Tags, '') | ||
.replace(EXCLAMATION_MARKS, ' $1 ') | ||
.replace(QUESTION_MARKS, ' ? ') | ||
.replace(FULL_STOPS, ' . ') | ||
.replace(EXTRA_SPACES,' ') | ||
.split(' ') | ||
.filter(token => token.length); | ||
} | ||
const BR_Tags = 'divbr', | ||
EXCLAMATION_MARKS = /(\!)/g, | ||
QUESTION_MARKS = /\?/g, | ||
FULL_STOPS = /\./g, | ||
EXTRA_SPACES = '/ {2,}/'; | ||
function getAttributeCorrespondingToThisWord(word, attributesOfInterest, tokens, wordIndex) { | ||
const attributesOfInterestLowerCase = attributesOfInterest.map(attribute => attribute.toLowerCase()); | ||
let attributeFound; | ||
return input | ||
.replace(regexList.EMOJI_REGEX, ' $1 ') | ||
.replace(BR_Tags, '') | ||
.replace(EXCLAMATION_MARKS, ' $1 ') | ||
.replace(QUESTION_MARKS, ' ? ') | ||
.replace(FULL_STOPS, ' . ') | ||
.replace(EXTRA_SPACES,' ') | ||
.split(' ') | ||
.filter(token => token.length); | ||
} | ||
attributesOfInterestLowerCase.forEach(function (attribute) { | ||
if (!attributeFound) { | ||
const attributeParts = attribute.split(' '); | ||
attributeParts.forEach(function (attributePart, attributePartIndex) { | ||
if (!attributeFound) { | ||
attributeFound = checkThatAllAttributePartsMatch(attribute, attributeParts, attributePart, attributePartIndex, word, tokens, wordIndex); | ||
} | ||
}); | ||
} | ||
}); | ||
function getAttributeCorrespondingToThisWord(word, attributesOfInterest, tokens, wordIndex) { | ||
const attributesOfInterestLowerCase = attributesOfInterest.map(attribute => attribute.toLowerCase()); | ||
let attributeFound; | ||
return attributesOfInterest[attributesOfInterestLowerCase.indexOf(attributeFound)]; | ||
} | ||
attributesOfInterestLowerCase.forEach(function (attribute) { | ||
if (!attributeFound) { | ||
const attributeParts = attribute.split(' '); | ||
attributeParts.forEach(function (attributePart, attributePartIndex) { | ||
if (!attributeFound) { | ||
attributeFound = checkThatAllAttributePartsMatch(attribute, attributeParts, attributePart, attributePartIndex, word, tokens, wordIndex); | ||
} | ||
}); | ||
function checkThatAllAttributePartsMatch (attribute, attributeParts, attributePart, attributePartIndex, word, tokens, wordIndex) { | ||
let attributeFound; | ||
if (!attributeFound && attributePart === word.toLowerCase()) { | ||
if (attributeParts.length > 1) { | ||
let entirePhraseMatches = true; | ||
for (let i = attributePartIndex; i > 0 && entirePhraseMatches; i--) { | ||
if (attributeParts[i] !== tokens[wordIndex - (attributePartIndex - i)].toLowerCase()) { | ||
entirePhraseMatches = false; | ||
} | ||
} | ||
}); | ||
return attributesOfInterest[attributesOfInterestLowerCase.indexOf(attributeFound)]; | ||
} | ||
function checkThatAllAttributePartsMatch (attribute, attributeParts, attributePart, attributePartIndex, word, tokens, wordIndex) { | ||
let attributeFound; | ||
if (!attributeFound && attributePart === word.toLowerCase()) { | ||
if (attributeParts.length > 1) { | ||
let entirePhraseMatches = true; | ||
for (let i = attributePartIndex; i > 0 && entirePhraseMatches; i--) { | ||
if (attributeParts[i] !== tokens[wordIndex - (attributePartIndex - i)].toLowerCase()) { | ||
entirePhraseMatches = false; | ||
} | ||
for (let i = attributePartIndex; i < attributeParts.length && entirePhraseMatches; i++) { | ||
if (attributeParts[i] !== tokens[wordIndex + (i - attributePartIndex)].toLowerCase()) { | ||
entirePhraseMatches = false; | ||
} | ||
for (let i = attributePartIndex; i < attributeParts.length && entirePhraseMatches; i++) { | ||
if (attributeParts[i] !== tokens[wordIndex + (i - attributePartIndex)].toLowerCase()) { | ||
entirePhraseMatches = false; | ||
} | ||
} | ||
} | ||
if (entirePhraseMatches) { | ||
attributeFound = attribute; | ||
} | ||
} else { | ||
if (entirePhraseMatches) { | ||
attributeFound = attribute; | ||
} | ||
} else { | ||
attributeFound = attribute; | ||
} | ||
return attributeFound; | ||
} | ||
return analyseSentiment; | ||
})(); | ||
return attributeFound; | ||
} |
@@ -1,13 +0,13 @@ | ||
import sentimentAnalyser from './analyseSentiment.js'; | ||
import discProfileAnalyser from './analyseDISCProfile.js'; | ||
import emailParser from './utils/emailParseUtil.js'; | ||
import readabilityAnalyser from './utils/calculateReadingLevel.js'; | ||
import egoismAnalyser from './utils/egoismAnalyser.js'; | ||
import analyseSentiment from './analyseSentiment.js'; | ||
import guessDISCProfile from './analyseDISCProfile.js'; | ||
import emailParseUtil from './utils/emailParseUtil.js'; | ||
import { calculateReadabilityScore } from './utils/calculateReadingLevel.js'; | ||
import analyseEgoism from './utils/egoismAnalyser.js'; | ||
export default { | ||
sentimentAnalyser, | ||
discProfileAnalyser, | ||
emailParser, | ||
readabilityAnalyser, | ||
egoismAnalyser | ||
analyseSentiment, | ||
guessDISCProfile, | ||
parseEmail: emailParseUtil.removeQuotedTextFromEmail, | ||
calculateReadabilityScore, | ||
analyseEgoism | ||
}; |
@@ -12,5 +12,5 @@ //adapted from https://www.npmjs.com/package/automated-readability-index | ||
export function getQualitativeVocabularyLevel(text) { | ||
var readingLevel = calculateReadabilityScore(text); | ||
const ADVANCED_THRESHOLD = 8, | ||
SUPER_ADVANCED_THRESHOLD = 12; | ||
const readingLevel = calculateReadabilityScore(text); | ||
const ADVANCED_THRESHOLD = 8; | ||
const SUPER_ADVANCED_THRESHOLD = 12; | ||
@@ -29,7 +29,6 @@ if (readingLevel < ADVANCED_THRESHOLD) { | ||
function analyseText(text) { | ||
var strippedText = text.replace(NON_WORD_CHARACTERS, ''), | ||
words = strippedText.match(/\S+/g), | ||
numWords = 0, | ||
numCharacters, | ||
readabilityScore; | ||
const strippedText = text.replace(NON_WORD_CHARACTERS, ''); | ||
const words = strippedText.match(/\S+/g); | ||
let numWords = 0; | ||
let numCharacters, readabilityScore; | ||
@@ -46,4 +45,4 @@ if (words) { | ||
var getAutomatedReadabilityIndex = function(numWords, numCharacters) { | ||
function getAutomatedReadabilityIndex(numWords, numCharacters) { | ||
return (numCharacters / numWords).toFixed(1); | ||
}; | ||
} |
export var analyseEgoism = function(text) { | ||
export default function analyseEgoism(text) { | ||
if (text.length) { | ||
@@ -12,3 +12,3 @@ return analyseText(text); | ||
}; | ||
}; | ||
} | ||
@@ -32,4 +32,2 @@ const NON_WORD_CHARACTERS = /[";:,.?¿\-\—!¡]+/g, | ||
}; | ||
} | ||
@@ -1,28 +0,22 @@ | ||
import * as emailSignatureParser from './emailSignatureParser.js'; | ||
import emailSignatureParser from './emailSignatureParser.js'; | ||
export default (function() { | ||
let extractSignature = emailSignatureParser.extractSignature; | ||
'use strict'; | ||
/** | ||
* Emails often come with copies of old emails from earlier in the thread | ||
* We don't want to process the old emails when we're analysing as we'll have a false positive otherwise | ||
**/ | ||
function removeQuotedTextFromEmail (emailContents) { | ||
let strippedHTML = stripHTML(emailContents); | ||
let processedEmail = extractSignature(strippedHTML).text || emailContents; | ||
let extractSignature = emailSignatureParser.extractSignature; | ||
return processedEmail; | ||
} | ||
/** | ||
* Emails often come with copies of old emails from earlier in the thread | ||
* We don't want to process the old emails when we're analysing as we'll have a false positive otherwise | ||
**/ | ||
function removeQuotedTextFromEmail (emailContents) { | ||
let strippedHTML = stripHTML(emailContents); | ||
let processedEmail = extractSignature(strippedHTML).text || emailContents; | ||
function stripHTML(message) { | ||
return message.replace(/<(?:.|\n)*?>/gm, '\n').replace(/</g,'').replace(/>/g,'').replace(/&/g,'').replace(/ /g, '\s'); | ||
} | ||
return processedEmail; | ||
} | ||
function stripHTML(message) { | ||
return message.replace(/<(?:.|\n)*?>/gm, '\n').replace(/</g,'').replace(/>/g,'').replace(/&/g,'').replace(/ /g, '\s'); | ||
} | ||
return { | ||
removeQuotedTextFromEmail | ||
}; | ||
})(); | ||
export default { | ||
removeQuotedTextFromEmail | ||
}; |
//modified from https://www.npmjs.com/package/emoji-regex/ | ||
//added text emojis: :) and wrapped in capture group | ||
export var EMOJI_REGEX = /((?:0\u20E3|1\u20E3|2\u20E3|3\u20E3|4\u20E3|5\u20E3|6\u20E3|7\u20E3|8\u20E3|9\u20E3|#\u20E3|\*\u20E3|\uD83C(?:\uDDE6\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF2|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFD|\uDDFF)|\uDDE7\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFC|\uDDFE|\uDDFF)|\uDDE8\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDE9\uD83C(?:\uDDEA|\uDDEC|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDFF)|\uDDEA\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDED|\uDDF7|\uDDF8|\uDDF9|\uDDFA)|\uDDEB\uD83C(?:\uDDEE|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDF7)|\uDDEC\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF1|\uDDF2|\uDDF3|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFE)|\uDDED\uD83C(?:\uDDF0|\uDDF2|\uDDF3|\uDDF7|\uDDF9|\uDDFA)|\uDDEE\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9)|\uDDEF\uD83C(?:\uDDEA|\uDDF2|\uDDF4|\uDDF5)|\uDDF0\uD83C(?:\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDF2|\uDDF3|\uDDF5|\uDDF7|\uDDFC|\uDDFE|\uDDFF)|\uDDF1\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDEE|\uDDF0|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFE)|\uDDF2\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDF3\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFF)|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C(?:\uDDE6|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF7|\uDDF8|\uDDF9|\uDDFC|\uDDFE)|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C(?:\uDDEA|\uDDF4|\uDDF8|\uDDFA|\uDDFC)|\uDDF8\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDE9|\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFD|\uDDFE|\uDDFF)|\uDDF9\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF9|\uDDFB|\uDDFC|\uDDFF)|\uDDFA\uD83C(?:\uDDE6|\uDDEC|\uDDF2|\uDDF8|\uDDFE|\uDDFF)|\uDDFB\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDEE|\uDDF3|\uDDFA)|\uDDFC\uD83C(?:\uDDEB|\uDDF8)|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C(?:\uDDEA|\uDDF9)|\uDDFF\uD83C(?:\uDDE6|\uDDF2|\uDDFC)))|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2694\u2696\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD79\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED0\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3]|\uD83E[\uDD10-\uDD18\uDD80-\uDD84\uDDC0]|:\)|:\()/g; | ||
export default /((?:0\u20E3|1\u20E3|2\u20E3|3\u20E3|4\u20E3|5\u20E3|6\u20E3|7\u20E3|8\u20E3|9\u20E3|#\u20E3|\*\u20E3|\uD83C(?:\uDDE6\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF2|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFD|\uDDFF)|\uDDE7\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFC|\uDDFE|\uDDFF)|\uDDE8\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDE9\uD83C(?:\uDDEA|\uDDEC|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDFF)|\uDDEA\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDED|\uDDF7|\uDDF8|\uDDF9|\uDDFA)|\uDDEB\uD83C(?:\uDDEE|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDF7)|\uDDEC\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF1|\uDDF2|\uDDF3|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFE)|\uDDED\uD83C(?:\uDDF0|\uDDF2|\uDDF3|\uDDF7|\uDDF9|\uDDFA)|\uDDEE\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9)|\uDDEF\uD83C(?:\uDDEA|\uDDF2|\uDDF4|\uDDF5)|\uDDF0\uD83C(?:\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDF2|\uDDF3|\uDDF5|\uDDF7|\uDDFC|\uDDFE|\uDDFF)|\uDDF1\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDEE|\uDDF0|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFE)|\uDDF2\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDF3\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFF)|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C(?:\uDDE6|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF7|\uDDF8|\uDDF9|\uDDFC|\uDDFE)|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C(?:\uDDEA|\uDDF4|\uDDF8|\uDDFA|\uDDFC)|\uDDF8\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDE9|\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFD|\uDDFE|\uDDFF)|\uDDF9\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF9|\uDDFB|\uDDFC|\uDDFF)|\uDDFA\uD83C(?:\uDDE6|\uDDEC|\uDDF2|\uDDF8|\uDDFE|\uDDFF)|\uDDFB\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDEE|\uDDF3|\uDDFA)|\uDDFC\uD83C(?:\uDDEB|\uDDF8)|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C(?:\uDDEA|\uDDF9)|\uDDFF\uD83C(?:\uDDE6|\uDDF2|\uDDFC)))|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2694\u2696\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD79\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED0\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3]|\uD83E[\uDD10-\uDD18\uDD80-\uDD84\uDDC0]|:\)|:\()/g; |
@@ -1,2 +0,1 @@ | ||
import discProfileAnalyser from '../../../../src/analyseDISCProfile.js'; | ||
import assert from 'cucumber-assert'; | ||
@@ -20,4 +19,3 @@ import { World } from '../support/world.js'; | ||
emailData.forEach(function (individualEmail) { | ||
let readabilityScore = thisWorld.readabilityAnalyser.calculateReadabilityScore(individualEmail[0]), | ||
discProfile = thisWorld.discProfileAnalyser.analyseEmail(individualEmail[0], readabilityScore); | ||
const discProfile = thisWorld.discProfileAnalyser.analyseEmail(individualEmail[0]); | ||
@@ -24,0 +22,0 @@ actualDISCProfileResults.push(discProfile) |
@@ -21,3 +21,3 @@ | ||
emailData.forEach(function (individualEmail) { | ||
let egoismScore = thisWorld.egoismAnalyser.analyseEgoism(individualEmail[0]); | ||
let egoismScore = thisWorld.egoismAnalyser(individualEmail[0]); | ||
@@ -24,0 +24,0 @@ egoismScores.push(egoismScore); |
@@ -21,3 +21,3 @@ | ||
emailData.forEach(function (individualEmail) { | ||
let readabilityScore = thisWorld.readabilityAnalyser.calculateReadabilityScore(individualEmail[0]); | ||
let readabilityScore = thisWorld.readabilityAnalyser(individualEmail[0]); | ||
@@ -24,0 +24,0 @@ readabilityScores.push(readabilityScore); |
@@ -21,3 +21,3 @@ | ||
emailData.forEach(function (individualEmail) { | ||
let sentimentScore = thisWorld.sentimentAnalyser.analyseSentiment(individualEmail[0]); | ||
let sentimentScore = thisWorld.sentimentAnalyser(individualEmail[0]); | ||
@@ -38,3 +38,3 @@ sentimentScores.push(sentimentScore) | ||
if (actualScore !== expectedScore) { | ||
console.log('Expected ' + expectedScore + ' to equal ' + actualScore); | ||
console.log('Expected ' + actualScore + ' to equal ' + expectedScore); | ||
allTestsPass = false; | ||
@@ -41,0 +41,0 @@ } |
@@ -0,9 +1,13 @@ | ||
import discProfileAnalyser from '../../../../src/analyseDISCProfile.js'; | ||
import sentimentAnalyser from '../../../../src/analyseSentiment.js'; | ||
import { calculateReadabilityScore } from '../../../../src/utils/calculateReadingLevel.js'; | ||
import analyseEgoism from '../../../../src/utils/egoismAnalyser.js'; | ||
function WorldConstructor() { | ||
this.sentimentAnalyser = require('../../../../src/analyseSentiment.js'); | ||
this.discProfileAnalyser = require('../../../../src/analyseDISCProfile.js').discProfileAnalyser; | ||
this.readabilityAnalyser = require('../../../../src/utils/calculateReadingLevel.js'); | ||
this.egoismAnalyser = require('../../../../src/utils/egoismAnalyser.js'); | ||
this.sentimentAnalyser = sentimentAnalyser; | ||
this.discProfileAnalyser = discProfileAnalyser; | ||
this.readabilityAnalyser = calculateReadabilityScore; | ||
this.egoismAnalyser = analyseEgoism; | ||
} | ||
module.exports.World = WorldConstructor; | ||
module.exports.World = WorldConstructor; |
import {test} from 'tape'; | ||
import {analyseSentiment} from '../../src/analyseSentiment.js'; | ||
import analyseSentiment from '../../src/analyseSentiment.js'; | ||
(function () { | ||
'use strict'; | ||
test('Sentiment Analyser should correctly identify sentiment for attributes of interest', function (expect) { | ||
const email = `Hey guys, | ||
just letting you know that I really like Zoho Support! | ||
But I've gotta be honest: I really don't like Zoho Projects. It has a lot of problems. It needs the ability to have | ||
workflow statuses.`; | ||
const expectedOutput = { | ||
attributeScores: { | ||
'Zoho Support': 6, | ||
'Zoho Projects': -14 | ||
} | ||
}; | ||
const actualOutput = analyseSentiment(email, ['Zoho Support', 'Zoho Projects']); | ||
expect.deepEqual(actualOutput.attributeScores, expectedOutput.attributeScores); | ||
expect.end(); | ||
}); | ||
test('Sentiment Analyser should correctly identify sentiment for attributes of interest', function (expect) { | ||
const email = `Hey guys, | ||
just letting you know that I really like Zoho Support! | ||
But I've gotta be honest: I really don't like Zoho Projects. It has a lot of problems. It needs the ability to have | ||
workflow statuses.`; | ||
const expectedOutput = { | ||
attributeScores: { | ||
'Zoho Support': 6, | ||
'Zoho Projects': -14 | ||
} | ||
}; | ||
const actualOutput = analyseSentiment(email, ['Zoho Support', 'Zoho Projects']); | ||
expect.deepEqual(actualOutput.attributeScores, expectedOutput.attributeScores); | ||
expect.end(); | ||
}); | ||
test('Sentiment Analyser should correctly handle German messages', function (expect) { | ||
const email = `Hallo Leute, | ||
ich will sagen dass ich Zoho Support wirklich mag! | ||
Aber ich muss ernstlich sein. Ich hasse unglaublicherweise Zoho Projects! Es hat viele Probleme. Z.b. es braucht | ||
die Faehigkeit mehrere Workflow Statuses zu haben.`; | ||
const expectedOutput = { | ||
attributeScores: { | ||
'Zoho Support': 2, | ||
'Zoho Projects': -15 | ||
} | ||
}; | ||
const actualOutput = analyseSentiment(email, ['Zoho Support', 'Zoho Projects']); | ||
expect.deepEqual(actualOutput.attributeScores, expectedOutput.attributeScores); | ||
expect.end(); | ||
}); | ||
})(); | ||
test('Sentiment Analyser should correctly handle German messages', function (expect) { | ||
const email = `Hallo Leute, | ||
ich will sagen dass ich Zoho Support wirklich mag! | ||
Aber ich muss ernstlich sein. Ich hasse unglaublicherweise Zoho Projects! Es hat viele Probleme. Z.b. es braucht | ||
die Faehigkeit mehrere Workflow Statuses zu haben.`; | ||
const expectedOutput = { | ||
attributeScores: { | ||
'Zoho Support': 2, | ||
'Zoho Projects': -15 | ||
} | ||
}; | ||
const actualOutput = analyseSentiment(email, ['Zoho Support', 'Zoho Projects']); | ||
expect.deepEqual(actualOutput.attributeScores, expectedOutput.attributeScores); | ||
expect.end(); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
193281
31
2514
81