bf: add 100% line coverage test
This commit is contained in:
parent
c40e9614f3
commit
00b441e46e
|
@ -3,16 +3,13 @@ http://brainfuck.sourceforge.net/brain.py'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import random
|
import random
|
||||||
|
import unittest
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
BUFFER_SIZE = 5000
|
|
||||||
MAX_STEPS = 1000000
|
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def bf(inp):
|
def bf(inp, max_steps=1000000, buffer_size=5000):
|
||||||
".bf <prog> -- executes brainfuck program <prog>"""
|
".bf <prog> -- executes brainfuck program <prog>"""
|
||||||
|
|
||||||
program = re.sub('[^][<>+-.,]', '', inp)
|
program = re.sub('[^][<>+-.,]', '', inp)
|
||||||
|
@ -37,7 +34,7 @@ def bf(inp):
|
||||||
ip = 0 # instruction pointer
|
ip = 0 # instruction pointer
|
||||||
mp = 0 # memory pointer
|
mp = 0 # memory pointer
|
||||||
steps = 0
|
steps = 0
|
||||||
memory = [0] * BUFFER_SIZE # initial memory area
|
memory = [0] * buffer_size # initial memory area
|
||||||
rightmost = 0
|
rightmost = 0
|
||||||
output = "" # we'll save the output here
|
output = "" # we'll save the output here
|
||||||
|
|
||||||
|
@ -54,9 +51,9 @@ def bf(inp):
|
||||||
rightmost = mp
|
rightmost = mp
|
||||||
if mp >= len(memory):
|
if mp >= len(memory):
|
||||||
# no restriction on memory growth!
|
# no restriction on memory growth!
|
||||||
memory.extend([0] * BUFFER_SIZE)
|
memory.extend([0] * buffer_size)
|
||||||
elif c == '<':
|
elif c == '<':
|
||||||
mp = mp - 1 % len(memory)
|
mp = (mp - 1) % len(memory)
|
||||||
elif c == '.':
|
elif c == '.':
|
||||||
output += chr(memory[mp])
|
output += chr(memory[mp])
|
||||||
if len(output) > 500:
|
if len(output) > 500:
|
||||||
|
@ -72,10 +69,10 @@ def bf(inp):
|
||||||
|
|
||||||
ip += 1
|
ip += 1
|
||||||
steps += 1
|
steps += 1
|
||||||
if steps > MAX_STEPS:
|
if steps > max_steps:
|
||||||
if output == '':
|
if output == '':
|
||||||
output = '(no output)'
|
output = 'no output'
|
||||||
output += '[exceeded %d iterations]' % MAX_STEPS
|
output += ' [exceeded %d iterations]' % max_steps
|
||||||
break
|
break
|
||||||
|
|
||||||
stripped_output = re.sub(r'[\x00-\x1F]', '', output)
|
stripped_output = re.sub(r'[\x00-\x1F]', '', output)
|
||||||
|
@ -86,3 +83,37 @@ def bf(inp):
|
||||||
return 'no output'
|
return 'no output'
|
||||||
|
|
||||||
return stripped_output[:430].decode('utf8', 'ignore')
|
return stripped_output[:430].decode('utf8', 'ignore')
|
||||||
|
|
||||||
|
|
||||||
|
class BFTest(unittest.TestCase):
|
||||||
|
def test_hello(self):
|
||||||
|
assert bf('--[>--->->->++>-<<<<<-------]>--.>---------.>--..+++.>---'
|
||||||
|
'-.>+++++++++.<<.+++.------.<-.>>+.') == 'Hello world!'
|
||||||
|
|
||||||
|
def test_unbalanced(self):
|
||||||
|
assert 'unbalanced' in bf('[[++]]]')
|
||||||
|
assert 'unbalanced' in bf('[[[++]]')
|
||||||
|
|
||||||
|
def test_comment(self):
|
||||||
|
assert bf('[this is a comment!]++++++[>+++++++<-]>.') == '*'
|
||||||
|
|
||||||
|
def test_unprintable(self):
|
||||||
|
assert bf('+.') == 'no printable output'
|
||||||
|
|
||||||
|
def test_empty(self):
|
||||||
|
assert bf('+++[-]') == 'no output'
|
||||||
|
|
||||||
|
def test_exceeded(self):
|
||||||
|
assert bf('+[>,[-]<]', 1000) == 'no output [exceeded 1000 iterations]'
|
||||||
|
|
||||||
|
def test_inf_mem(self):
|
||||||
|
assert 'no output [exceeded 1000 iterations]' == \
|
||||||
|
bf('+[>[.-]+]', 1000, buffer_size=10)
|
||||||
|
|
||||||
|
def test_left_wrap(self):
|
||||||
|
# eventually, wrap around and hit ourselves
|
||||||
|
assert 'aaaa' in bf('+[<[-' + '+' * ord('a') + '.[-]]+]',
|
||||||
|
2000, buffer_size=5)
|
||||||
|
|
||||||
|
def test_too_much_output(self):
|
||||||
|
assert 'a' * 430 == bf('+' * ord('a') + '[.]')
|
||||||
|
|
Loading…
Reference in New Issue