Merge branch 'master' into develop

This commit is contained in:
Griatch 2017-10-07 11:28:32 +02:00
commit 48a1ae1371
12 changed files with 637 additions and 533 deletions

View file

@ -24,6 +24,8 @@ from evennia.commands.default import help, general, system, admin, account, buil
from evennia.commands.command import Command, InterruptCommand
from evennia.utils import ansi, utils
from evennia.server.sessionhandler import SESSIONS
from evennia import search_object
from evennia import DefaultObject, DefaultCharacter
# set up signal here since we are not starting the server
@ -296,6 +298,73 @@ class TestBuilding(CommandTest):
def test_teleport(self):
self.call(building.CmdTeleport(), "Room2", "Room2(#2)\n|Teleported to Room2.")
def test_spawn(self):
def getObject(commandTest, objKeyStr):
# A helper function to get a spawned object and
# check that it exists in the process.
query = search_object(objKeyStr)
commandTest.assertIsNotNone(query)
obj = query[0]
commandTest.assertIsNotNone(obj)
return obj
# Tests "@spawn" without any arguments.
self.call(building.CmdSpawn(), " ", "Usage: @spawn")
# Tests "@spawn <prototype_dictionary>" without specifying location.
self.call(building.CmdSpawn(), \
"{'key':'goblin', 'typeclass':'evennia.DefaultCharacter'}", "Spawned goblin")
goblin = getObject(self, "goblin")
# Tests that the spawned object's type is a DefaultCharacter.
self.assertIsInstance(goblin, DefaultCharacter)
# Tests that the spawned object's location is the same as the caharacter's location, since
# we did not specify it.
self.assertEqual(goblin.location, self.char1.location)
goblin.delete()
# Test "@spawn <prototype_dictionary>" with a location other than the character's.
spawnLoc = self.room2
if spawnLoc == self.char1.location:
# Just to make sure we use a different location, in case someone changes
# char1's default location in the future...
spawnLoc = self.room1
self.call(building.CmdSpawn(), \
"{'prototype':'GOBLIN', 'key':'goblin', 'location':'%s'}" \
% spawnLoc.dbref, "Spawned goblin")
goblin = getObject(self, "goblin")
self.assertEqual(goblin.location, spawnLoc)
goblin.delete()
# Tests "@spawn <prototype_name>"
self.call(building.CmdSpawn(), "'BALL'", "Spawned Ball")
ball = getObject(self, "Ball")
self.assertEqual(ball.location, self.char1.location)
self.assertIsInstance(ball, DefaultObject)
ball.delete()
# Tests "@spawn/noloc ..." without specifying a location.
# Location should be "None".
self.call(building.CmdSpawn(), "/noloc 'BALL'", "Spawned Ball")
ball = getObject(self, "Ball")
self.assertIsNone(ball.location)
ball.delete()
# Tests "@spawn/noloc ...", but DO specify a location.
# Location should be the specified location.
self.call(building.CmdSpawn(), \
"/noloc {'prototype':'BALL', 'location':'%s'}" \
% spawnLoc.dbref, "Spawned Ball")
ball = getObject(self, "Ball")
self.assertEqual(ball.location, spawnLoc)
ball.delete()
# test calling spawn with an invalid prototype.
self.call(building.CmdSpawn(), \
"'NO_EXIST'", "No prototype named 'NO_EXIST'")
class TestComms(CommandTest):

View file

@ -429,7 +429,7 @@ class EvForm(object):
def _test():
"test evform. This is used by the unittest system."
form = EvForm("evennia.utils.evform_test")
form = EvForm("evennia.utils.tests.data.evform_example")
# add data to each tagged form cell
form.map(cells={"AA": "|gTom the Bouncer",

View file

@ -34,6 +34,8 @@ class EvenniaTest(TestCase):
self.room1 = create.create_object(self.room_typeclass, key="Room", nohome=True)
self.room1.db.desc = "room_desc"
settings.DEFAULT_HOME = "#%i" % self.room1.id # we must have a default home
# Set up fake prototype module for allowing tests to use named prototypes.
settings.PROTOTYPE_MODULES = "evennia.utils.tests.data.prototypes_example"
self.room2 = create.create_object(self.room_typeclass, key="Room2")
self.exit = create.create_object(self.exit_typeclass, key='out', location=self.room1, destination=self.room2)
self.obj1 = create.create_object(self.object_typeclass, key="Obj", location=self.room1, home=self.room1)

View file

@ -1,532 +0,0 @@
from builtins import range
import re
try:
from django.utils.unittest import TestCase
except ImportError:
from django.test import TestCase
from .ansi import ANSIString
from evennia import utils
from django.conf import settings
class ANSIStringTestCase(TestCase):
def checker(self, ansi, raw, clean):
"""
Verifies the raw and clean strings of an ANSIString match expected
output.
"""
self.assertEqual(unicode(ansi.clean()), clean)
self.assertEqual(unicode(ansi.raw()), raw)
def table_check(self, ansi, char, code):
"""
Verifies the indexes in an ANSIString match what they should.
"""
self.assertEqual(ansi._char_indexes, char)
self.assertEqual(ansi._code_indexes, code)
def test_instance(self):
"""
Make sure the ANSIString is always constructed correctly.
"""
clean = u'This isA|r testTest'
encoded = u'\x1b[1m\x1b[32mThis is\x1b[1m\x1b[31mA|r test\x1b[0mTest\x1b[0m'
target = ANSIString(r'|gThis is|rA||r test|nTest|n')
char_table = [9, 10, 11, 12, 13, 14, 15, 25, 26, 27, 28, 29, 30, 31, 32, 37, 38, 39, 40]
code_table = [0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 17, 18, 19, 20, 21, 22, 23, 24, 33, 34, 35, 36, 41, 42, 43, 44]
self.checker(target, encoded, clean)
self.table_check(target, char_table, code_table)
self.checker(ANSIString(target), encoded, clean)
self.table_check(ANSIString(target), char_table, code_table)
self.checker(ANSIString(encoded, decoded=True), encoded, clean)
self.table_check(ANSIString(encoded, decoded=True), char_table,
code_table)
self.checker(ANSIString('Test'), u'Test', u'Test')
self.table_check(ANSIString('Test'), [0, 1, 2, 3], [])
self.checker(ANSIString(''), u'', u'')
def test_slice(self):
"""
Verifies that slicing an ANSIString results in expected color code
distribution.
"""
target = ANSIString(r'|gTest|rTest|n')
result = target[:3]
self.checker(result, u'\x1b[1m\x1b[32mTes', u'Tes')
result = target[:4]
self.checker(result, u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m', u'Test')
result = target[:]
self.checker(
result,
u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTest\x1b[0m',
u'TestTest')
result = target[:-1]
self.checker(
result,
u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTes',
u'TestTes')
result = target[0:0]
self.checker(
result,
u'',
u'')
def test_split(self):
"""
Verifies that re.split and .split behave similarly and that color
codes end up where they should.
"""
target = ANSIString("|gThis is |nA split string|g")
first = (u'\x1b[1m\x1b[32mThis is \x1b[0m', u'This is ')
second = (u'\x1b[1m\x1b[32m\x1b[0m split string\x1b[1m\x1b[32m',
u' split string')
re_split = re.split('A', target)
normal_split = target.split('A')
self.assertEqual(re_split, normal_split)
self.assertEqual(len(normal_split), 2)
self.checker(normal_split[0], *first)
self.checker(normal_split[1], *second)
def test_join(self):
"""
Verify that joining a set of ANSIStrings works.
"""
# This isn't the desired behavior, but the expected one. Python
# concatenates the in-memory representation with the built-in string's
# join.
l = [ANSIString("|gTest|r") for _ in range(0, 3)]
# Force the generator to be evaluated.
result = "".join(l)
self.assertEqual(unicode(result), u'TestTestTest')
result = ANSIString("").join(l)
self.checker(result, u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b'
u'[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b[32mTest'
u'\x1b[1m\x1b[31m', u'TestTestTest')
def test_len(self):
"""
Make sure that length reporting on ANSIStrings does not include
ANSI codes.
"""
self.assertEqual(len(ANSIString('|gTest|n')), 4)
def test_capitalize(self):
"""
Make sure that capitalization works. This is the simplest of the
_transform functions.
"""
target = ANSIString('|gtest|n')
result = u'\x1b[1m\x1b[32mTest\x1b[0m'
self.checker(target.capitalize(), result, u'Test')
def test_mxp_agnostic(self):
"""
Make sure MXP tags are not treated like ANSI codes, but normal text.
"""
mxp1 = "|lclook|ltat|le"
mxp2 = "Start to |lclook here|ltclick somewhere here|le first"
self.assertEqual(15, len(ANSIString(mxp1)))
self.assertEqual(53, len(ANSIString(mxp2)))
# These would indicate an issue with the tables.
self.assertEqual(len(ANSIString(mxp1)), len(ANSIString(mxp1).split("\n")[0]))
self.assertEqual(len(ANSIString(mxp2)), len(ANSIString(mxp2).split("\n")[0]))
self.assertEqual(mxp1, ANSIString(mxp1))
self.assertEqual(mxp2, unicode(ANSIString(mxp2)))
def test_add(self):
"""
Verify concatenation works correctly.
"""
a = ANSIString("|gTest")
b = ANSIString("|cString|n")
c = a + b
result = u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[36mString\x1b[0m'
self.checker(c, result, u'TestString')
char_table = [9, 10, 11, 12, 22, 23, 24, 25, 26, 27]
code_table = [0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 29, 30, 31]
self.table_check(c, char_table, code_table)
def test_strip(self):
"""
Test the ansi-aware .strip() methods
"""
a = ANSIString(" |r Test of stuff |b with spaces |n ")
b = ANSIString("|r|b")
self.assertEqual(a.strip(), ANSIString("|rTest of stuff |b with spaces|n"))
self.assertEqual(a.lstrip(), ANSIString("|rTest of stuff |b with spaces |n "))
self.assertEqual(a.rstrip(), ANSIString(" |r Test of stuff |b with spaces|n"))
self.assertEqual(b.strip(), b)
class TestIsIter(TestCase):
def test_is_iter(self):
self.assertEqual(True, utils.is_iter([1, 2, 3, 4]))
self.assertEqual(False, utils.is_iter("This is not an iterable"))
class TestCrop(TestCase):
def test_crop(self):
# No text, return no text
self.assertEqual("", utils.crop("", width=10, suffix="[...]"))
# Input length equal to max width, no crop
self.assertEqual("0123456789", utils.crop("0123456789", width=10, suffix="[...]"))
# Input length greater than max width, crop (suffix included in width)
self.assertEqual("0123[...]", utils.crop("0123456789", width=9, suffix="[...]"))
# Input length less than desired width, no crop
self.assertEqual("0123", utils.crop("0123", width=9, suffix="[...]"))
# Width too small or equal to width of suffix
self.assertEqual("012", utils.crop("0123", width=3, suffix="[...]"))
self.assertEqual("01234", utils.crop("0123456", width=5, suffix="[...]"))
class TestDedent(TestCase):
def test_dedent(self):
# Empty string, return empty string
self.assertEqual("", utils.dedent(""))
# No leading whitespace
self.assertEqual("TestDedent", utils.dedent("TestDedent"))
# Leading whitespace, single line
self.assertEqual("TestDedent", utils.dedent(" TestDedent"))
# Leading whitespace, multi line
input_string = " hello\n world"
expected_string = "hello\nworld"
self.assertEqual(expected_string, utils.dedent(input_string))
class TestListToString(TestCase):
"""
Default function header from utils.py:
list_to_string(inlist, endsep="and", addquote=False)
Examples:
no endsep:
[1,2,3] -> '1, 2, 3'
with endsep=='and':
[1,2,3] -> '1, 2 and 3'
with addquote and endsep
[1,2,3] -> '"1", "2" and "3"'
"""
def test_list_to_string(self):
self.assertEqual('1, 2, 3', utils.list_to_string([1, 2, 3], endsep=""))
self.assertEqual('"1", "2", "3"', utils.list_to_string([1, 2, 3], endsep="", addquote=True))
self.assertEqual('1, 2 and 3', utils.list_to_string([1, 2, 3]))
self.assertEqual('"1", "2" and "3"', utils.list_to_string([1, 2, 3], endsep="and", addquote=True))
class TestMLen(TestCase):
"""
Verifies that m_len behaves like len in all situations except those
where MXP may be involved.
"""
def test_non_mxp_string(self):
self.assertEqual(utils.m_len('Test_string'), 11)
def test_mxp_string(self):
self.assertEqual(utils.m_len('|lclook|ltat|le'), 2)
def test_mxp_ansi_string(self):
self.assertEqual(utils.m_len(ANSIString('|lcl|gook|ltat|le|n')), 2)
def test_non_mxp_ansi_string(self):
self.assertEqual(utils.m_len(ANSIString('|gHello|n')), 5)
def test_list(self):
self.assertEqual(utils.m_len([None, None]), 2)
def test_dict(self):
self.assertEqual(utils.m_len({'hello': True, 'Goodbye': False}), 2)
from .text2html import TextToHTMLparser
class TestTextToHTMLparser(TestCase):
def setUp(self):
self.parser = TextToHTMLparser()
def tearDown(self):
del self.parser
def test_url_scheme_ftp(self):
self.assertEqual(self.parser.convert_urls('ftp.example.com'),
'<a href="ftp.example.com" target="_blank">ftp.example.com</a>')
def test_url_scheme_www(self):
self.assertEqual(self.parser.convert_urls('www.example.com'),
'<a href="www.example.com" target="_blank">www.example.com</a>')
def test_url_scheme_ftpproto(self):
self.assertEqual(self.parser.convert_urls('ftp://ftp.example.com'),
'<a href="ftp://ftp.example.com" target="_blank">ftp://ftp.example.com</a>')
def test_url_scheme_http(self):
self.assertEqual(self.parser.convert_urls('http://example.com'),
'<a href="http://example.com" target="_blank">http://example.com</a>')
def test_url_scheme_https(self):
self.assertEqual(self.parser.convert_urls('https://example.com'),
'<a href="https://example.com" target="_blank">https://example.com</a>')
def test_url_chars_slash(self):
self.assertEqual(self.parser.convert_urls('www.example.com/homedir'),
'<a href="www.example.com/homedir" target="_blank">www.example.com/homedir</a>')
def test_url_chars_colon(self):
self.assertEqual(self.parser.convert_urls('https://example.com:8000/login/'),
'<a href="https://example.com:8000/login/" target="_blank">'
'https://example.com:8000/login/</a>')
def test_url_chars_querystring(self):
self.assertEqual(self.parser.convert_urls('https://example.com/submitform?field1=val1+val3&field2=val2'),
'<a href="https://example.com/submitform?field1=val1+val3&field2=val2" target="_blank">'
'https://example.com/submitform?field1=val1+val3&field2=val2</a>')
def test_url_chars_anchor(self):
self.assertEqual(self.parser.convert_urls('http://www.example.com/menu#section_1'),
'<a href="http://www.example.com/menu#section_1" target="_blank">'
'http://www.example.com/menu#section_1</a>')
def test_url_chars_exclam(self):
self.assertEqual(self.parser.convert_urls('https://groups.google.com/forum/'
'?fromgroups#!categories/evennia/ainneve'),
'<a href="https://groups.google.com/forum/?fromgroups#!categories/evennia/ainneve"'
' target="_blank">https://groups.google.com/forum/?fromgroups#!categories/evennia/ainneve</a>')
def test_url_edge_leadingw(self):
self.assertEqual(self.parser.convert_urls('wwww.example.com'),
'w<a href="www.example.com" target="_blank">www.example.com</a>')
def test_url_edge_following_period_eol(self):
self.assertEqual(self.parser.convert_urls('www.example.com.'),
'<a href="www.example.com" target="_blank">www.example.com</a>.')
def test_url_edge_following_period(self):
self.assertEqual(self.parser.convert_urls('see www.example.com. '),
'see <a href="www.example.com" target="_blank">www.example.com</a>. ')
def test_url_edge_brackets(self):
self.assertEqual(self.parser.convert_urls('[http://example.com/]'),
'[<a href="http://example.com/" target="_blank">http://example.com/</a>]')
def test_url_edge_multiline(self):
self.assertEqual(self.parser.convert_urls(' * http://example.com/info\n * bullet'),
' * <a href="http://example.com/info" target="_blank">'
'http://example.com/info</a>\n * bullet')
def test_url_edge_following_htmlentity(self):
self.assertEqual(self.parser.convert_urls('http://example.com/info&lt;span&gt;'),
'<a href="http://example.com/info" target="_blank">http://example.com/info</a>&lt;span&gt;')
def test_url_edge_surrounded_spans(self):
self.assertEqual(self.parser.convert_urls('</span>http://example.com/<span class="red">'),
'</span><a href="http://example.com/" target="_blank">'
'http://example.com/</a><span class="red">')
from evennia.utils import evmenu
from mock import Mock
class TestEvMenu(TestCase):
"Run the EvMenu test."
def setUp(self):
self.caller = Mock()
self.caller.msg = Mock()
self.menu = evmenu.EvMenu(self.caller, "evennia.utils.evmenu", startnode="test_start_node",
persistent=True, cmdset_mergetype="Replace", testval="val", testval2="val2")
def test_kwargsave(self):
self.assertTrue(hasattr(self.menu, "testval"))
self.assertTrue(hasattr(self.menu, "testval2"))
from evennia.utils import inlinefuncs
class TestInlineFuncs(TestCase):
"""Test the nested inlinefunc module"""
def test_nofunc(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"as$382ewrw w we w werw,|44943}"),
"as$382ewrw w we w werw,|44943}")
def test_incomplete(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"testing $blah{without an ending."),
"testing $blah{without an ending.")
def test_single_func(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"this is a test with $pad(centered, 20) text in it."),
"this is a test with centered text in it.")
def test_nested(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"this $crop(is a test with $pad(padded, 20) text in $pad(pad2, 10) a crop, 80)"),
"this is a test with padded text in pad2 a crop")
def test_escaped(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"this should be $pad('''escaped,''' and '''instead,''' cropped $crop(with a long,5) text., 80)"),
"this should be escaped, and instead, cropped with text. ")
def test_escaped2(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
'this should be $pad("""escaped,""" and """instead,""" cropped $crop(with a long,5) text., 80)'),
"this should be escaped, and instead, cropped with text. ")
from evennia.utils import evform
class TestEvForm(TestCase):
def test_form(self):
self.maxDiff = None
self.assertEqual(evform._test(),
u'.------------------------------------------------.\n'
u'| |\n'
u'| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b'
u'[1m\x1b[32mthe\x1b[1m\x1b[32m \x1b[0m \x1b[0m '
u'Account: \x1b[0m\x1b[1m\x1b[33mGriatch '
u'\x1b[0m\x1b[0m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[0m\x1b[0m '
u'|\n'
u'| \x1b[0m\x1b[1m\x1b[32mBouncer\x1b[0m \x1b[0m |\n'
u'| |\n'
u' >----------------------------------------------<\n'
u'| |\n'
u'| Desc: \x1b[0mA sturdy \x1b[0m \x1b[0m'
u' STR: \x1b[0m12 \x1b[0m\x1b[0m\x1b[0m\x1b[0m'
u' DEX: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0mfellow\x1b[0m \x1b[0m'
u' INT: \x1b[0m5 \x1b[0m\x1b[0m\x1b[0m\x1b[0m'
u' STA: \x1b[0m18 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0m \x1b[0m'
u' LUC: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m'
u' MAG: \x1b[0m3 \x1b[0m\x1b[0m\x1b[0m |\n'
u'| |\n'
u' >----------.-----------------------------------<\n'
u'| | |\n'
u'| \x1b[0mHP\x1b[0m|\x1b[0mMV \x1b[0m|\x1b[0mMP\x1b[0m '
u'| \x1b[0mSkill \x1b[0m|\x1b[0mValue \x1b[0m'
u'|\x1b[0mExp \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| ~~+~~~+~~ | ~~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~~ |\n'
u'| \x1b[0m**\x1b[0m|\x1b[0m***\x1b[0m\x1b[0m|\x1b[0m**\x1b[0m\x1b[0m '
u'| \x1b[0mShooting \x1b[0m|\x1b[0m12 \x1b[0m'
u'|\x1b[0m550/1200 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0m \x1b[0m|\x1b[0m**\x1b[0m \x1b[0m|\x1b[0m*\x1b[0m \x1b[0m '
u'| \x1b[0mHerbalism \x1b[0m|\x1b[0m14 \x1b[0m'
u'|\x1b[0m990/1400 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0m \x1b[0m|\x1b[0m \x1b[0m|\x1b[0m \x1b[0m '
u'| \x1b[0mSmithing \x1b[0m|\x1b[0m9 \x1b[0m'
u'|\x1b[0m205/900 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| | |\n'
u' -----------`-------------------------------------\n')
def test_ansi_escape(self):
# note that in a msg() call, the result would be the correct |-----,
# in a print, ansi only gets called once, so ||----- is the result
self.assertEqual(unicode(evform.EvForm(form={"FORM": "\n||-----"})), "||-----")
class TestTimeformat(TestCase):
"""
Default function header from utils.py:
time_format(seconds, style=0)
"""
def test_style_0(self):
"""Test the style 0 of time_format."""
self.assertEqual(utils.time_format(0, 0), "00:00")
self.assertEqual(utils.time_format(28, 0), "00:00")
self.assertEqual(utils.time_format(92, 0), "00:01")
self.assertEqual(utils.time_format(300, 0), "00:05")
self.assertEqual(utils.time_format(660, 0), "00:11")
self.assertEqual(utils.time_format(3600, 0), "01:00")
self.assertEqual(utils.time_format(3725, 0), "01:02")
self.assertEqual(utils.time_format(86350, 0), "23:59")
self.assertEqual(utils.time_format(86800, 0), "1d 00:06")
self.assertEqual(utils.time_format(130800, 0), "1d 12:20")
self.assertEqual(utils.time_format(530800, 0), "6d 03:26")
def test_style_1(self):
"""Test the style 1 of time_format."""
self.assertEqual(utils.time_format(0, 1), "0s")
self.assertEqual(utils.time_format(28, 1), "28s")
self.assertEqual(utils.time_format(92, 1), "1m")
self.assertEqual(utils.time_format(300, 1), "5m")
self.assertEqual(utils.time_format(660, 1), "11m")
self.assertEqual(utils.time_format(3600, 1), "1h")
self.assertEqual(utils.time_format(3725, 1), "1h")
self.assertEqual(utils.time_format(86350, 1), "23h")
self.assertEqual(utils.time_format(86800, 1), "1d")
self.assertEqual(utils.time_format(130800, 1), "1d")
self.assertEqual(utils.time_format(530800, 1), "6d")
def test_style_2(self):
"""Test the style 2 of time_format."""
self.assertEqual(utils.time_format(0, 2), "0 minutes")
self.assertEqual(utils.time_format(28, 2), "0 minutes")
self.assertEqual(utils.time_format(92, 2), "1 minute")
self.assertEqual(utils.time_format(300, 2), "5 minutes")
self.assertEqual(utils.time_format(660, 2), "11 minutes")
self.assertEqual(utils.time_format(3600, 2), "1 hour, 0 minutes")
self.assertEqual(utils.time_format(3725, 2), "1 hour, 2 minutes")
self.assertEqual(utils.time_format(86350, 2), "23 hours, 59 minutes")
self.assertEqual(utils.time_format(86800, 2),
"1 day, 0 hours, 6 minutes")
self.assertEqual(utils.time_format(130800, 2),
"1 day, 12 hours, 20 minutes")
self.assertEqual(utils.time_format(530800, 2),
"6 days, 3 hours, 26 minutes")
def test_style_3(self):
"""Test the style 3 of time_format."""
self.assertEqual(utils.time_format(0, 3), "")
self.assertEqual(utils.time_format(28, 3), "28 seconds")
self.assertEqual(utils.time_format(92, 3), "1 minute 32 seconds")
self.assertEqual(utils.time_format(300, 3), "5 minutes 0 seconds")
self.assertEqual(utils.time_format(660, 3), "11 minutes 0 seconds")
self.assertEqual(utils.time_format(3600, 3),
"1 hour, 0 minutes")
self.assertEqual(utils.time_format(3725, 3),
"1 hour, 2 minutes 5 seconds")
self.assertEqual(utils.time_format(86350, 3),
"23 hours, 59 minutes 10 seconds")
self.assertEqual(utils.time_format(86800, 3),
"1 day, 0 hours, 6 minutes 40 seconds")
self.assertEqual(utils.time_format(130800, 3),
"1 day, 12 hours, 20 minutes 0 seconds")
self.assertEqual(utils.time_format(530800, 3),
"6 days, 3 hours, 26 minutes 40 seconds")
def test_style_4(self):
"""Test the style 4 of time_format."""
self.assertEqual(utils.time_format(0, 4), "0 seconds")
self.assertEqual(utils.time_format(28, 4), "28 seconds")
self.assertEqual(utils.time_format(92, 4), "a minute")
self.assertEqual(utils.time_format(300, 4), "5 minutes")
self.assertEqual(utils.time_format(660, 4), "11 minutes")
self.assertEqual(utils.time_format(3600, 4), "an hour")
self.assertEqual(utils.time_format(3725, 4), "an hour")
self.assertEqual(utils.time_format(86350, 4), "23 hours")
self.assertEqual(utils.time_format(86800, 4), "a day")
self.assertEqual(utils.time_format(130800, 4), "a day")
self.assertEqual(utils.time_format(530800, 4), "6 days")
self.assertEqual(utils.time_format(3030800, 4), "a month")
self.assertEqual(utils.time_format(7030800, 4), "2 months")
self.assertEqual(utils.time_format(40030800, 4), "a year")
self.assertEqual(utils.time_format(90030800, 4), "2 years")
def test_unknown_format(self):
"""Test that unknown formats raise exceptions."""
self.assertRaises(ValueError, utils.time_format, 0, 5)
self.assertRaises(ValueError, utils.time_format, 0, "u")

View file

View file

View file

@ -0,0 +1,20 @@
"""
test_prototypes
This is meant to be used with Evennia unittest framework
to provide some named prototypes for use with various tests
(for example commands that accept named prototypes, not just
prototype dictionaries)
"""
GOBLIN = {
"key" : "Goblin", \
"typeclass" : "DefaultCharacter", \
"desc" : "A goblin."
}
BALL = {
"key" : "Ball", \
"typeclass" : "DefaultObject", \
"desc" : "A ball."
}

View file

@ -0,0 +1,55 @@
"""
Unit tests for the EvForm text form generator
"""
from django.test import TestCase
from evennia.utils import evform
class TestEvForm(TestCase):
def test_form(self):
self.maxDiff = None
self.assertEqual(evform._test(),
u'.------------------------------------------------.\n'
u'| |\n'
u'| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b'
u'[1m\x1b[32mthe\x1b[1m\x1b[32m \x1b[0m \x1b[0m '
u'Account: \x1b[0m\x1b[1m\x1b[33mGriatch '
u'\x1b[0m\x1b[0m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[0m\x1b[0m '
u'|\n'
u'| \x1b[0m\x1b[1m\x1b[32mBouncer\x1b[0m \x1b[0m |\n'
u'| |\n'
u' >----------------------------------------------<\n'
u'| |\n'
u'| Desc: \x1b[0mA sturdy \x1b[0m \x1b[0m'
u' STR: \x1b[0m12 \x1b[0m\x1b[0m\x1b[0m\x1b[0m'
u' DEX: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0mfellow\x1b[0m \x1b[0m'
u' INT: \x1b[0m5 \x1b[0m\x1b[0m\x1b[0m\x1b[0m'
u' STA: \x1b[0m18 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0m \x1b[0m'
u' LUC: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m'
u' MAG: \x1b[0m3 \x1b[0m\x1b[0m\x1b[0m |\n'
u'| |\n'
u' >----------.-----------------------------------<\n'
u'| | |\n'
u'| \x1b[0mHP\x1b[0m|\x1b[0mMV \x1b[0m|\x1b[0mMP\x1b[0m '
u'| \x1b[0mSkill \x1b[0m|\x1b[0mValue \x1b[0m'
u'|\x1b[0mExp \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| ~~+~~~+~~ | ~~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~~ |\n'
u'| \x1b[0m**\x1b[0m|\x1b[0m***\x1b[0m\x1b[0m|\x1b[0m**\x1b[0m\x1b[0m '
u'| \x1b[0mShooting \x1b[0m|\x1b[0m12 \x1b[0m'
u'|\x1b[0m550/1200 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0m \x1b[0m|\x1b[0m**\x1b[0m \x1b[0m|\x1b[0m*\x1b[0m \x1b[0m '
u'| \x1b[0mHerbalism \x1b[0m|\x1b[0m14 \x1b[0m'
u'|\x1b[0m990/1400 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| \x1b[0m \x1b[0m|\x1b[0m \x1b[0m|\x1b[0m \x1b[0m '
u'| \x1b[0mSmithing \x1b[0m|\x1b[0m9 \x1b[0m'
u'|\x1b[0m205/900 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n'
u'| | |\n'
u' -----------`-------------------------------------\n')
def test_ansi_escape(self):
# note that in a msg() call, the result would be the correct |-----,
# in a print, ansi only gets called once, so ||----- is the result
self.assertEqual(unicode(evform.EvForm(form={"FORM": "\n||-----"})), "||-----")

View file

@ -0,0 +1,25 @@
"""
Unit tests for the EvMenu system
TODO: This need expansion.
"""
from django.test import TestCase
from evennia.utils import evmenu
from mock import Mock
class TestEvMenu(TestCase):
"Run the EvMenu testing."
def setUp(self):
self.caller = Mock()
self.caller.msg = Mock()
self.menu = evmenu.EvMenu(self.caller, "evennia.utils.evmenu", startnode="test_start_node",
persistent=True, cmdset_mergetype="Replace", testval="val",
testval2="val2")
def test_kwargsave(self):
self.assertTrue(hasattr(self.menu, "testval"))
self.assertTrue(hasattr(self.menu, "testval2"))

View file

@ -0,0 +1,277 @@
"""
Unit tests for all sorts of inline text-tag parsing, like ANSI, html conversion, inlinefuncs etc
"""
import re
from django.test import TestCase
from evennia.utils.ansi import ANSIString
from evennia.utils.text2html import TextToHTMLparser
from evennia.utils import inlinefuncs
class ANSIStringTestCase(TestCase):
def checker(self, ansi, raw, clean):
"""
Verifies the raw and clean strings of an ANSIString match expected
output.
"""
self.assertEqual(unicode(ansi.clean()), clean)
self.assertEqual(unicode(ansi.raw()), raw)
def table_check(self, ansi, char, code):
"""
Verifies the indexes in an ANSIString match what they should.
"""
self.assertEqual(ansi._char_indexes, char)
self.assertEqual(ansi._code_indexes, code)
def test_instance(self):
"""
Make sure the ANSIString is always constructed correctly.
"""
clean = u'This isA|r testTest'
encoded = u'\x1b[1m\x1b[32mThis is\x1b[1m\x1b[31mA|r test\x1b[0mTest\x1b[0m'
target = ANSIString(r'|gThis is|rA||r test|nTest|n')
char_table = [9, 10, 11, 12, 13, 14, 15, 25, 26, 27, 28, 29, 30, 31, 32, 37, 38, 39, 40]
code_table = [0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 17, 18, 19, 20, 21, 22, 23, 24, 33, 34, 35, 36, 41, 42, 43, 44]
self.checker(target, encoded, clean)
self.table_check(target, char_table, code_table)
self.checker(ANSIString(target), encoded, clean)
self.table_check(ANSIString(target), char_table, code_table)
self.checker(ANSIString(encoded, decoded=True), encoded, clean)
self.table_check(ANSIString(encoded, decoded=True), char_table,
code_table)
self.checker(ANSIString('Test'), u'Test', u'Test')
self.table_check(ANSIString('Test'), [0, 1, 2, 3], [])
self.checker(ANSIString(''), u'', u'')
def test_slice(self):
"""
Verifies that slicing an ANSIString results in expected color code
distribution.
"""
target = ANSIString(r'|gTest|rTest|n')
result = target[:3]
self.checker(result, u'\x1b[1m\x1b[32mTes', u'Tes')
result = target[:4]
self.checker(result, u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m', u'Test')
result = target[:]
self.checker(
result,
u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTest\x1b[0m',
u'TestTest')
result = target[:-1]
self.checker(
result,
u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTes',
u'TestTes')
result = target[0:0]
self.checker(
result,
u'',
u'')
def test_split(self):
"""
Verifies that re.split and .split behave similarly and that color
codes end up where they should.
"""
target = ANSIString("|gThis is |nA split string|g")
first = (u'\x1b[1m\x1b[32mThis is \x1b[0m', u'This is ')
second = (u'\x1b[1m\x1b[32m\x1b[0m split string\x1b[1m\x1b[32m',
u' split string')
re_split = re.split('A', target)
normal_split = target.split('A')
self.assertEqual(re_split, normal_split)
self.assertEqual(len(normal_split), 2)
self.checker(normal_split[0], *first)
self.checker(normal_split[1], *second)
def test_join(self):
"""
Verify that joining a set of ANSIStrings works.
"""
# This isn't the desired behavior, but the expected one. Python
# concatenates the in-memory representation with the built-in string's
# join.
l = [ANSIString("|gTest|r") for _ in range(0, 3)]
# Force the generator to be evaluated.
result = "".join(l)
self.assertEqual(unicode(result), u'TestTestTest')
result = ANSIString("").join(l)
self.checker(result, u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b'
u'[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b[32mTest'
u'\x1b[1m\x1b[31m', u'TestTestTest')
def test_len(self):
"""
Make sure that length reporting on ANSIStrings does not include
ANSI codes.
"""
self.assertEqual(len(ANSIString('|gTest|n')), 4)
def test_capitalize(self):
"""
Make sure that capitalization works. This is the simplest of the
_transform functions.
"""
target = ANSIString('|gtest|n')
result = u'\x1b[1m\x1b[32mTest\x1b[0m'
self.checker(target.capitalize(), result, u'Test')
def test_mxp_agnostic(self):
"""
Make sure MXP tags are not treated like ANSI codes, but normal text.
"""
mxp1 = "|lclook|ltat|le"
mxp2 = "Start to |lclook here|ltclick somewhere here|le first"
self.assertEqual(15, len(ANSIString(mxp1)))
self.assertEqual(53, len(ANSIString(mxp2)))
# These would indicate an issue with the tables.
self.assertEqual(len(ANSIString(mxp1)), len(ANSIString(mxp1).split("\n")[0]))
self.assertEqual(len(ANSIString(mxp2)), len(ANSIString(mxp2).split("\n")[0]))
self.assertEqual(mxp1, ANSIString(mxp1))
self.assertEqual(mxp2, unicode(ANSIString(mxp2)))
def test_add(self):
"""
Verify concatenation works correctly.
"""
a = ANSIString("|gTest")
b = ANSIString("|cString|n")
c = a + b
result = u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[36mString\x1b[0m'
self.checker(c, result, u'TestString')
char_table = [9, 10, 11, 12, 22, 23, 24, 25, 26, 27]
code_table = [0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 29, 30, 31]
self.table_check(c, char_table, code_table)
def test_strip(self):
"""
Test the ansi-aware .strip() methods
"""
a = ANSIString(" |r Test of stuff |b with spaces |n ")
b = ANSIString("|r|b")
self.assertEqual(a.strip(), ANSIString("|rTest of stuff |b with spaces|n"))
self.assertEqual(a.lstrip(), ANSIString("|rTest of stuff |b with spaces |n "))
self.assertEqual(a.rstrip(), ANSIString(" |r Test of stuff |b with spaces|n"))
self.assertEqual(b.strip(), b)
class TestTextToHTMLparser(TestCase):
def setUp(self):
self.parser = TextToHTMLparser()
def tearDown(self):
del self.parser
def test_url_scheme_ftp(self):
self.assertEqual(self.parser.convert_urls('ftp.example.com'),
'<a href="ftp.example.com" target="_blank">ftp.example.com</a>')
def test_url_scheme_www(self):
self.assertEqual(self.parser.convert_urls('www.example.com'),
'<a href="www.example.com" target="_blank">www.example.com</a>')
def test_url_scheme_ftpproto(self):
self.assertEqual(self.parser.convert_urls('ftp://ftp.example.com'),
'<a href="ftp://ftp.example.com" target="_blank">ftp://ftp.example.com</a>')
def test_url_scheme_http(self):
self.assertEqual(self.parser.convert_urls('http://example.com'),
'<a href="http://example.com" target="_blank">http://example.com</a>')
def test_url_scheme_https(self):
self.assertEqual(self.parser.convert_urls('https://example.com'),
'<a href="https://example.com" target="_blank">https://example.com</a>')
def test_url_chars_slash(self):
self.assertEqual(self.parser.convert_urls('www.example.com/homedir'),
'<a href="www.example.com/homedir" target="_blank">www.example.com/homedir</a>')
def test_url_chars_colon(self):
self.assertEqual(self.parser.convert_urls('https://example.com:8000/login/'),
'<a href="https://example.com:8000/login/" target="_blank">'
'https://example.com:8000/login/</a>')
def test_url_chars_querystring(self):
self.assertEqual(self.parser.convert_urls('https://example.com/submitform?field1=val1+val3&field2=val2'),
'<a href="https://example.com/submitform?field1=val1+val3&field2=val2" target="_blank">'
'https://example.com/submitform?field1=val1+val3&field2=val2</a>')
def test_url_chars_anchor(self):
self.assertEqual(self.parser.convert_urls('http://www.example.com/menu#section_1'),
'<a href="http://www.example.com/menu#section_1" target="_blank">'
'http://www.example.com/menu#section_1</a>')
def test_url_chars_exclam(self):
self.assertEqual(self.parser.convert_urls('https://groups.google.com/forum/'
'?fromgroups#!categories/evennia/ainneve'),
'<a href="https://groups.google.com/forum/?fromgroups#!categories/evennia/ainneve"'
' target="_blank">https://groups.google.com/forum/?fromgroups#!categories/evennia/ainneve</a>')
def test_url_edge_leadingw(self):
self.assertEqual(self.parser.convert_urls('wwww.example.com'),
'w<a href="www.example.com" target="_blank">www.example.com</a>')
def test_url_edge_following_period_eol(self):
self.assertEqual(self.parser.convert_urls('www.example.com.'),
'<a href="www.example.com" target="_blank">www.example.com</a>.')
def test_url_edge_following_period(self):
self.assertEqual(self.parser.convert_urls('see www.example.com. '),
'see <a href="www.example.com" target="_blank">www.example.com</a>. ')
def test_url_edge_brackets(self):
self.assertEqual(self.parser.convert_urls('[http://example.com/]'),
'[<a href="http://example.com/" target="_blank">http://example.com/</a>]')
def test_url_edge_multiline(self):
self.assertEqual(self.parser.convert_urls(' * http://example.com/info\n * bullet'),
' * <a href="http://example.com/info" target="_blank">'
'http://example.com/info</a>\n * bullet')
def test_url_edge_following_htmlentity(self):
self.assertEqual(self.parser.convert_urls('http://example.com/info&lt;span&gt;'),
'<a href="http://example.com/info" target="_blank">http://example.com/info</a>&lt;span&gt;')
def test_url_edge_surrounded_spans(self):
self.assertEqual(self.parser.convert_urls('</span>http://example.com/<span class="red">'),
'</span><a href="http://example.com/" target="_blank">'
'http://example.com/</a><span class="red">')
class TestInlineFuncs(TestCase):
"""Test the nested inlinefunc module"""
def test_nofunc(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"as$382ewrw w we w werw,|44943}"),
"as$382ewrw w we w werw,|44943}")
def test_incomplete(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"testing $blah{without an ending."),
"testing $blah{without an ending.")
def test_single_func(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"this is a test with $pad(centered, 20) text in it."),
"this is a test with centered text in it.")
def test_nested(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"this $crop(is a test with $pad(padded, 20) text in $pad(pad2, 10) a crop, 80)"),
"this is a test with padded text in pad2 a crop")
def test_escaped(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
"this should be $pad('''escaped,''' and '''instead,''' cropped $crop(with a long,5) text., 80)"),
"this should be escaped, and instead, cropped with text. ")
def test_escaped2(self):
self.assertEqual(inlinefuncs.parse_inlinefunc(
'this should be $pad("""escaped,""" and """instead,""" cropped $crop(with a long,5) text., 80)'),
"this should be escaped, and instead, cropped with text. ")

View file

@ -0,0 +1,188 @@
"""
Unit tests for the utilities of the evennia.utils.utils module.
TODO: Not nearly all utilities are covered yet.
"""
from django.test import TestCase
from evennia.utils.ansi import ANSIString
from evennia.utils import utils
class TestIsIter(TestCase):
def test_is_iter(self):
self.assertEqual(True, utils.is_iter([1, 2, 3, 4]))
self.assertEqual(False, utils.is_iter("This is not an iterable"))
class TestCrop(TestCase):
def test_crop(self):
# No text, return no text
self.assertEqual("", utils.crop("", width=10, suffix="[...]"))
# Input length equal to max width, no crop
self.assertEqual("0123456789", utils.crop("0123456789", width=10, suffix="[...]"))
# Input length greater than max width, crop (suffix included in width)
self.assertEqual("0123[...]", utils.crop("0123456789", width=9, suffix="[...]"))
# Input length less than desired width, no crop
self.assertEqual("0123", utils.crop("0123", width=9, suffix="[...]"))
# Width too small or equal to width of suffix
self.assertEqual("012", utils.crop("0123", width=3, suffix="[...]"))
self.assertEqual("01234", utils.crop("0123456", width=5, suffix="[...]"))
class TestDedent(TestCase):
def test_dedent(self):
# Empty string, return empty string
self.assertEqual("", utils.dedent(""))
# No leading whitespace
self.assertEqual("TestDedent", utils.dedent("TestDedent"))
# Leading whitespace, single line
self.assertEqual("TestDedent", utils.dedent(" TestDedent"))
# Leading whitespace, multi line
input_string = " hello\n world"
expected_string = "hello\nworld"
self.assertEqual(expected_string, utils.dedent(input_string))
class TestListToString(TestCase):
"""
Default function header from utils.py:
list_to_string(inlist, endsep="and", addquote=False)
Examples:
no endsep:
[1,2,3] -> '1, 2, 3'
with endsep=='and':
[1,2,3] -> '1, 2 and 3'
with addquote and endsep
[1,2,3] -> '"1", "2" and "3"'
"""
def test_list_to_string(self):
self.assertEqual('1, 2, 3', utils.list_to_string([1, 2, 3], endsep=""))
self.assertEqual('"1", "2", "3"', utils.list_to_string([1, 2, 3], endsep="", addquote=True))
self.assertEqual('1, 2 and 3', utils.list_to_string([1, 2, 3]))
self.assertEqual('"1", "2" and "3"', utils.list_to_string([1, 2, 3], endsep="and", addquote=True))
class TestMLen(TestCase):
"""
Verifies that m_len behaves like len in all situations except those
where MXP may be involved.
"""
def test_non_mxp_string(self):
self.assertEqual(utils.m_len('Test_string'), 11)
def test_mxp_string(self):
self.assertEqual(utils.m_len('|lclook|ltat|le'), 2)
def test_mxp_ansi_string(self):
self.assertEqual(utils.m_len(ANSIString('|lcl|gook|ltat|le|n')), 2)
def test_non_mxp_ansi_string(self):
self.assertEqual(utils.m_len(ANSIString('|gHello|n')), 5)
def test_list(self):
self.assertEqual(utils.m_len([None, None]), 2)
def test_dict(self):
self.assertEqual(utils.m_len({'hello': True, 'Goodbye': False}), 2)
class TestTimeformat(TestCase):
"""
Default function header from utils.py:
time_format(seconds, style=0)
"""
def test_style_0(self):
"""Test the style 0 of time_format."""
self.assertEqual(utils.time_format(0, 0), "00:00")
self.assertEqual(utils.time_format(28, 0), "00:00")
self.assertEqual(utils.time_format(92, 0), "00:01")
self.assertEqual(utils.time_format(300, 0), "00:05")
self.assertEqual(utils.time_format(660, 0), "00:11")
self.assertEqual(utils.time_format(3600, 0), "01:00")
self.assertEqual(utils.time_format(3725, 0), "01:02")
self.assertEqual(utils.time_format(86350, 0), "23:59")
self.assertEqual(utils.time_format(86800, 0), "1d 00:06")
self.assertEqual(utils.time_format(130800, 0), "1d 12:20")
self.assertEqual(utils.time_format(530800, 0), "6d 03:26")
def test_style_1(self):
"""Test the style 1 of time_format."""
self.assertEqual(utils.time_format(0, 1), "0s")
self.assertEqual(utils.time_format(28, 1), "28s")
self.assertEqual(utils.time_format(92, 1), "1m")
self.assertEqual(utils.time_format(300, 1), "5m")
self.assertEqual(utils.time_format(660, 1), "11m")
self.assertEqual(utils.time_format(3600, 1), "1h")
self.assertEqual(utils.time_format(3725, 1), "1h")
self.assertEqual(utils.time_format(86350, 1), "23h")
self.assertEqual(utils.time_format(86800, 1), "1d")
self.assertEqual(utils.time_format(130800, 1), "1d")
self.assertEqual(utils.time_format(530800, 1), "6d")
def test_style_2(self):
"""Test the style 2 of time_format."""
self.assertEqual(utils.time_format(0, 2), "0 minutes")
self.assertEqual(utils.time_format(28, 2), "0 minutes")
self.assertEqual(utils.time_format(92, 2), "1 minute")
self.assertEqual(utils.time_format(300, 2), "5 minutes")
self.assertEqual(utils.time_format(660, 2), "11 minutes")
self.assertEqual(utils.time_format(3600, 2), "1 hour, 0 minutes")
self.assertEqual(utils.time_format(3725, 2), "1 hour, 2 minutes")
self.assertEqual(utils.time_format(86350, 2), "23 hours, 59 minutes")
self.assertEqual(utils.time_format(86800, 2),
"1 day, 0 hours, 6 minutes")
self.assertEqual(utils.time_format(130800, 2),
"1 day, 12 hours, 20 minutes")
self.assertEqual(utils.time_format(530800, 2),
"6 days, 3 hours, 26 minutes")
def test_style_3(self):
"""Test the style 3 of time_format."""
self.assertEqual(utils.time_format(0, 3), "")
self.assertEqual(utils.time_format(28, 3), "28 seconds")
self.assertEqual(utils.time_format(92, 3), "1 minute 32 seconds")
self.assertEqual(utils.time_format(300, 3), "5 minutes 0 seconds")
self.assertEqual(utils.time_format(660, 3), "11 minutes 0 seconds")
self.assertEqual(utils.time_format(3600, 3),
"1 hour, 0 minutes")
self.assertEqual(utils.time_format(3725, 3),
"1 hour, 2 minutes 5 seconds")
self.assertEqual(utils.time_format(86350, 3),
"23 hours, 59 minutes 10 seconds")
self.assertEqual(utils.time_format(86800, 3),
"1 day, 0 hours, 6 minutes 40 seconds")
self.assertEqual(utils.time_format(130800, 3),
"1 day, 12 hours, 20 minutes 0 seconds")
self.assertEqual(utils.time_format(530800, 3),
"6 days, 3 hours, 26 minutes 40 seconds")
def test_style_4(self):
"""Test the style 4 of time_format."""
self.assertEqual(utils.time_format(0, 4), "0 seconds")
self.assertEqual(utils.time_format(28, 4), "28 seconds")
self.assertEqual(utils.time_format(92, 4), "a minute")
self.assertEqual(utils.time_format(300, 4), "5 minutes")
self.assertEqual(utils.time_format(660, 4), "11 minutes")
self.assertEqual(utils.time_format(3600, 4), "an hour")
self.assertEqual(utils.time_format(3725, 4), "an hour")
self.assertEqual(utils.time_format(86350, 4), "23 hours")
self.assertEqual(utils.time_format(86800, 4), "a day")
self.assertEqual(utils.time_format(130800, 4), "a day")
self.assertEqual(utils.time_format(530800, 4), "6 days")
self.assertEqual(utils.time_format(3030800, 4), "a month")
self.assertEqual(utils.time_format(7030800, 4), "2 months")
self.assertEqual(utils.time_format(40030800, 4), "a year")
self.assertEqual(utils.time_format(90030800, 4), "2 years")
def test_unknown_format(self):
"""Test that unknown formats raise exceptions."""
self.assertRaises(ValueError, utils.time_format, 0, 5)
self.assertRaises(ValueError, utils.time_format, 0, "u")