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

Fix apy modules tests - Re: #516 #522

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
62 changes: 35 additions & 27 deletions modules/apy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from modules import more
import operator
from humanize import naturaldelta
from enum import IntEnum

headers = [(
'User-Agent', 'Mozilla/5.0' +
Expand All @@ -24,6 +25,13 @@

SYNTAX_ERROR = 1
tomasff marked this conversation as resolved.
Show resolved Hide resolved

class Status(IntEnum):
OK = 0
KEYWORD_ERROR = 1
ENUM_ERROR = 2
SYNTAX_ERROR = 3
WEB_RESPONSE_ERROR = 4

def strict_check(pattern, string, function):
error = ''

Expand Down Expand Up @@ -81,17 +89,17 @@ def translate(phenny, translate_me, input_lang, output_lang='en'):
def apertium_translate(phenny, input):
'''Translates a phrase using APy.'''
pairRE = langRE + r'-' + langRE
line, line_error = strict_check(r'((?:' + pairRE + r'(?:\|' + pairRE + r')*' + r' ?)+)\s+(.*)',
line, syntax_error_msg = strict_check(r'((?:' + pairRE + r'(?:\|' + pairRE + r')*' + r' ?)+)\s+(.*)',
input.group(1), apertium_translate)

if line_error:
phenny.say(line_error)
return SYNTAX_ERROR
if syntax_error_msg:
phenny.say(syntax_error_msg)
return Status.SYNTAX_ERROR

if (len(line.group(2)) > 350) and (not input.admin):
#raise GrumbleError('Phrase must be under 350 characters.')
phenny.say('Phrase must be under 350 characters.')
return SYNTAX_ERROR
return Status.SYNTAX_ERROR

blocks = line.group(1).split(' ')
for block in blocks:
Expand All @@ -101,14 +109,14 @@ def apertium_translate(phenny, input):
if input_lang == output_lang:
#raise GrumbleError('Stop trying to confuse me! Pick different languages ;)')
phenny.say('Stop trying to confuse me! Pick different languages ;)')
return SYNTAX_ERROR
return Status.SYNTAX_ERROR

# TODO: Remove this try/except block? web.decode doesn't seem to raise any GrumbleError's
try:
translated = web.decode(translate(phenny, translated, input_lang, output_lang))
except GrumbleError as err:
phenny.say('{:s}-{:s}: {:s}'.format(input_lang, output_lang, str(err)))
return SYNTAX_ERROR
return Status.WEB_RESPONSE_ERROR
phenny.reply(web.decode(translated))

apertium_translate.name = 't'
Expand Down Expand Up @@ -182,11 +190,11 @@ def apertium_listpairs(phenny, input):

def apertium_analyse(phenny, input):
'''Analyse text using Apertium APy'''
cmd, cmd_error = strict_check(r'(' + langRE + r')\s+(.*)', input.group(1), apertium_analyse)
cmd, syntax_error_msg = strict_check(r'(' + langRE + r')\s+(.*)', input.group(1), apertium_analyse)

if cmd_error:
phenny.say(cmd_error)
return SYNTAX_ERROR
if syntax_error_msg:
phenny.say(syntax_error_msg)
return Status.SYNTAX_ERROR

opener = urllib.request.build_opener()
opener.addheaders = headers
Expand All @@ -213,11 +221,11 @@ def apertium_analyse(phenny, input):

def apertium_generate(phenny, input):
'''Use Apertium APy's generate functionality'''
cmd, cmd_error = strict_check(r'(' + langRE + r')\s+(.*)', input.group(1), apertium_generate)
cmd, syntax_error_msg = strict_check(r'(' + langRE + r')\s+(.*)', input.group(1), apertium_generate)

if cmd_error:
phenny.say(cmd_error)
return SYNTAX_ERROR
if syntax_error_msg:
phenny.say(syntax_error_msg)
return Status.SYNTAX_ERROR

opener = urllib.request.build_opener()
opener.addheaders = headers
Expand All @@ -244,12 +252,12 @@ def apertium_generate(phenny, input):

def apertium_identlang(phenny, input):
'''Identify the language for a given input.'''
text, text_error = strict_check(r'.*', input.group(1), apertium_identlang)
text, syntax_error_message = strict_check(r'.*', input.group(1), apertium_identlang)
text = text.group(0)

if text_error:
phenny.say(text_error)
return SYNTAX_ERROR
if syntax_error_message:
phenny.say(syntax_error_message)
return Status.SYNTAX_ERROR

opener = urllib.request.build_opener()
opener.addheaders = headers
Expand Down Expand Up @@ -339,11 +347,11 @@ def plural(num, word, be=False):

def apertium_calccoverage(phenny, input):
'''Calculate translation coverage for a language and a given input.'''
cmd, cmd_error = strict_check(r'(' + langRE + r')\s+(.*)', input.group(1), apertium_calccoverage)
cmd, syntax_error_msg = strict_check(r'(' + langRE + r')\s+(.*)', input.group(1), apertium_calccoverage)

if cmd_error:
phenny.say(cmd_error)
return SYNTAX_ERROR
if syntax_error_msg:
phenny.say(syntax_error_msg)
return Status.SYNTAX_ERROR

opener = urllib.request.build_opener()
opener.addheaders = headers
Expand All @@ -365,12 +373,12 @@ def apertium_calccoverage(phenny, input):

def apertium_perword(phenny, input):
'''Perform APy's tagger, morph, translate, and biltrans functions on individual words.'''
cmd, cmd_error = strict_check(r'(' + langRE + r')\s+\((.*)\)\s+(.*)', input.group(1), apertium_perword)
cmd, syntax_error_msg = strict_check(r'(' + langRE + r')\s+\((.*)\)\s+(.*)', input.group(1), apertium_perword)
valid_funcs = {'tagger', 'disambig', 'biltrans', 'translate', 'morph'}

if cmd_error:
phenny.say(cmd_error)
return SYNTAX_ERROR
if syntax_error_msg:
phenny.say(syntax_error_msg)
return Status.SYNTAX_ERROR

# validate requested functions
funcs = cmd.group(2).split(' ')
Expand Down
28 changes: 15 additions & 13 deletions modules/test/test_apy.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ def check_exceptions(self, bad_list, name, reason=None):
msg='No exception raised for {:s}!'.format(reason)):
name.__call__(self.phenny, self.input)

def check_syntax_error(self, bad_list, name, reason=None):
def check_error(self, bad_list, name, error, reason=None):
if not reason:
reason = 'invalid input to {:s}'.format(name.__name__)
for inp in bad_list:
self.input.group.return_value = inp
function_return_val = name.__call__(self.phenny, self.input)
self.assertEqual(function_return_val, apy.SYNTAX_ERROR, msg='No syntax error returned for {:s}!'.format(reason))
self.assertEqual(function_return_val, error, msg='No syntax error returned for {:s}!'.format(reason))
tomasff marked this conversation as resolved.
Show resolved Hide resolved

def test_translate_langs(self, mock_open):
# single language
Expand Down Expand Up @@ -97,10 +97,10 @@ def test_translate_non_langs(self, mock_handle, mock_open):
self.reset_mocks(self.phenny, mock_open, mock_handle)

# bad input
self.check_syntax_error([self.texts['spa'], 'spa ' + self.texts['spa'], 'spa-eng'],
apy.apertium_translate)
self.check_syntax_error(['en-en Translate to the same language?'],
apy.apertium_translate, 'self-translation')
self.check_error([self.texts['spa'], 'spa ' + self.texts['spa'], 'spa-eng'],
apy.apertium_translate, apy.Status.SYNTAX_ERROR)
self.check_error(['en-en Translate to the same language?'],
apy.apertium_translate, apy.Status.SYNTAX_ERROR, 'self-translation')
self.reset_mocks(self.phenny, mock_open, mock_handle)

# non-existent language with actual language
Expand All @@ -119,8 +119,9 @@ def test_translate_admin(self, mock_open):

# restricted length for non-admin
self.input.admin = False
self.check_syntax_error(['eng-spa ' + self.texts['eng_long']],
apy.apertium_translate, 'long non-admin translation!')
self.check_error(['eng-spa ' + self.texts['eng_long']],
apy.apertium_translate, apy.Status.SYNTAX_ERROR,
'long non-admin translation!')
self.reset_mocks(self.phenny, mock_open)

# non-restricted length for admin
Expand Down Expand Up @@ -197,8 +198,8 @@ def test_analyze_generate(self, mock_addmsgs, mock_open):
self.reset_mocks(mock_open, mock_addmsgs)

# bad input
self.check_syntax_error([' '.join(words), 'eng'], apy.apertium_analyse)
self.check_syntax_error([' '.join(words), 'eng'], apy.apertium_generate)
self.check_error([' '.join(words), 'eng'], apy.apertium_analyse, apy.Status.SYNTAX_ERROR)
self.check_error([' '.join(words), 'eng'], apy.apertium_generate, apy.Status.SYNTAX_ERROR)

@mock.patch('modules.apy.more.add_messages')
def test_identlang(self, mock_addmsgs, mock_open):
Expand Down Expand Up @@ -232,7 +233,7 @@ def test_coverage(self, mock_open):
self.reset_mocks(self.phenny, mock_open)

# bad input
self.check_syntax_error(['eng', self.texts['eng'], 'eng-spa'], apy.apertium_calccoverage)
self.check_error(['eng', self.texts['eng'], 'eng-spa'], apy.apertium_calccoverage, apy.Status.SYNTAX_ERROR)

def test_perword(self, mock_open):
# valid perword functions
Expand All @@ -258,5 +259,6 @@ def test_perword(self, mock_open):
# bad input
self.check_exceptions(['fra (tagger nonfunc) word'], apy.apertium_perword,
Androbin marked this conversation as resolved.
Show resolved Hide resolved
'invalid perword function')
self.check_syntax_error(['fra', 'fra (tagger)', '(tagger)', 'fra word',
'(tagger morph) word'], apy.apertium_perword)
self.check_error(['fra', 'fra (tagger)', '(tagger)', 'fra word',
'(tagger morph) word'], apy.apertium_perword,
apy.Status.SYNTAX_ERROR)