# -*- coding: utf-8 -*-

import unittest
from strtest import str_test

TEST_CODE1 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    TIMEOUT = 1

    @str_test.error_message('Não funcionou para caso com zero.')
    def test_numbers_3_0(self):
        self.assertEqual(self.function(3,0), 3)

    def test_numbers_3_4(self):
        self.assertEqual(self.function(3,4), 4, 'Não funcionou para caso com dois números positivos.')
'''

TARGET_CODE_0 = '''
def ex1(a, b)
    return max(a, b)
'''

TARGET_CODE_1 = '''
def ex1(a, b):
    return max(a, b)
'''

TARGET_CODE_2 = '''
def ex1(a, b):
    while True:
        pass
    return max(a, b)
'''

TARGET_CODE_3 = '''
def ex1(a, b):
    if b == 0:
        return 0
    return max(a, b)
'''

TARGET_CODE_4 = '''
def ex1(a, b):
    return a / 0
'''

TEST_CODE2 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_print_called(self):
        for i in range(5):
            text = 'hi{0}'.format(i)
            self.function(text)
            self.assertEqual(self.mock_print.calls, i+1)
            self.assertEqual(self.mock_print.printed[i], text)
'''

TARGET_CODE_5 = '''
def code_with_print(a):
    print(a)
'''

TARGET_CODE_6 = '''
def code_with_print(a):
    pass
'''

TEST_CODE3 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_input_called(self):
        self.mock_input.input_list = ['3', 2, 5, '1']
        result = self.function()
        self.assertEqual(self.mock_input.calls, 4)
        self.assertEqual(result, 8)

    def test_no_sum(self):
        self.mock_input.input_list = [0]
        result = self.function()
        self.assertEqual(self.mock_input.calls, 1)
        self.assertEqual(result, 0)
'''

TARGET_CODE_7 = '''
def input_and_sum():
    n = int(input('N?'))
    result = 0
    while n > 0:
        result += int(input('Type a number'))
        n -= 1
    return result
'''

TARGET_CODE_8 = '''
def input_and_sum():
    n = input('N?')
    result = 0
    while n > 0:
        result += input('Type a number')
        n -= 1
    return result
'''

TEST_CODE4 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_print_called(self):
        self.mock_input.input_list = ['Inspermon']
        self.program()
        self.assertEqual(self.mock_input.calls, 1)
        self.assertEqual(self.mock_print.calls, 1)
        self.assertEqual(self.mock_print.printed[0], 'Hello Inspermon!')

    def test_hello_world(self):
        self.mock_input.input_list = ['World']
        self.program()
        self.assertEqual(self.mock_input.calls, 1)
        self.assertEqual(self.mock_print.calls, 1)
        self.assertEqual(self.mock_print.printed[0], 'Hello World!')
'''

TARGET_CODE_9 = '''
name = input('Name? ')
print('Hello {0}!'.format(name))
'''

TARGET_CODE_10 = '''
name = input('Name? ')
pritn('Hello {0}!'.format(name))
'''

TEST_CODE5 = '''
from strtest import str_test
import re

class TestCase(str_test.TestCaseWrapper):
    def test_open_called(self):
        words_str = 'some,words,separated,by,comma\\nwith,some,new,lines\\n\\n'
        words = [w for w in re.split(',|\\n', words_str) if w]
        self.mock_open.files['words.csv'] =  words_str
        self.program()
        self.assertEqual(self.mock_open.calls, 1)
        self.assertEqual(len(self.mock_open.opened), 0)
        printed = [word.strip() for word in self.mock_print.printed if word.strip()]
        self.assertEqual(printed, words)
'''

TARGET_CODE_11 = '''
f = open('words.csv', 'r')
words = []
for line in f:
    words += line.split(',')
words = [word.strip() for word in words if word]
for word in words:
    print(word)
f.close()
'''

TARGET_CODE_12 = '''
with open('words.csv', 'r') as f:
    words = []
    for line in f:
        words += [w.strip() for w in line.split(',') if w.strip()]
    for word in words:
        print(word)
'''

TARGET_CODE_13 = '''
with open('file_that_doesnt_exist.txt', 'r') as f:
    words = []
    for line in f:
        words += line.split(',')
    for word in words:
        print(word)
'''

TARGET_CODE_14 = '''
with open('words.csv', 'w') as f:
    words = []
    for line in f:
        words += [w.strip() for w in line.split(',') if w.strip()]
    for word in words:
        print(word)
'''

TARGET_CODE_15 = '''
with open('words.csv', 'a') as f:
    words = []
    for line in f:
        words += [w.strip() for w in line.split(',') if w.strip()]
    for word in words:
        print(word)
'''

TARGET_CODE_16 = '''
with open('words.csv', 'r') as f:
    f.write("Shouldn't work")
'''

TEST_CODE6 = '''
from strtest import str_test
import re

class TestCase(str_test.TestCaseWrapper):
    def test_write(self):
        self.program()
        self.assertEqual(self.mock_open.calls, 1)
        self.assertEqual(len(self.mock_open.opened), 0)
        self.assertEqual(self.mock_open.files['newfile.txt'], 'New content')
'''

TARGET_CODE_17 = '''
with open('newfile.txt', 'w') as f:
    f.write('New content')
'''

TEST_CODE7 = '''
from strtest import str_test
import re

class TestCase(str_test.TestCaseWrapper):
    def test_write(self):
        self.mock_open.files['test.txt'] = 'Old content'
        self.program()
        self.assertEqual(self.mock_open.calls, 1)
        self.assertEqual(len(self.mock_open.opened), 0)
        self.assertEqual(self.mock_open.files['test.txt'], 'Old content\\nNew content')
'''

TARGET_CODE_18 = '''
with open('test.txt', 'a') as f:
    f.write('\\nNew content')
'''

TEST_CODE8 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_do_nothing(self):
        self.function(0)
'''

TARGET_CODE_19 = '''
def do_nothing(arg):
    return arg

arg = input('Should not use input in function questions: ')
print(do_nothing(arg))
'''

TEST_CODE9 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_random_int(self):
        numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
        self.mock_random.randint[(1, 20)] = numbers
        for n in numbers:
            recebido = self.function()
            self.assertEqual(n, recebido, 'ESPERAVA OUTRO NUMERO. RECEBI: {0}, QUERIA: {1}'.format(recebido, n))
        self.assertEqual(len(numbers), self.mock_random.randint.calls)
'''

TARGET_CODE_20 = '''
import random

def random_int():
    return random.randint(1, 20)
'''

TARGET_CODE_21 = '''
from random import randint

def random_int():
    return randint(1, 20)
'''

TARGET_CODE_22 = '''
from random import randint

def random_int():
    return randint(1, 10)
'''

TEST_CODE10 = '''
from strtest import str_test as ch
from itertools import cycle


class TestCase(ch.TestCaseWrapper):
    TIMEOUT = 2

    def test_1(self):
        self.mock_input.input_list = cycle(['sim', 'talvez', 'ainda um pouco', 'não'])
        self.program()
        self.assertEqual(
            self.mock_input.calls, 4,
            'Número de chamadas para o input foi diferente do esperado')
        self.assertEqual(self.mock_print.calls, 4,
                         'Use exatamente um print por resposta do usuário')
        for i in range(3):
            self.assertTrue('Pratique mais' in self.mock_print.printed[i])
        self.assertTrue('Até a próxima' in self.mock_print.printed[-1])

    def test_de_primeira(self):
        self.mock_input.input_list = cycle(['não'])
        self.program()
        self.assertEqual(
            self.mock_input.calls, 1,
            'Número de chamadas para o input foi diferente do esperado')
        self.assertEqual(self.mock_print.calls, 1,
                         'Use exatamente um print por resposta do usuário')
        self.assertTrue('Até a próxima' in self.mock_print.printed[-1])
'''

TARGET_CODE_23 = '''
resp_aluno = True
while resp_aluno == True:
    resp_D_aluno = input("Você tem mais dúvidas? ")
    if resp_D_aluno == "não":
        resp_aluno = False
        print ("Até a próxima")
    else:
        print("Pratique mais")
'''

TEST_CODE11 = '''
from strtest import str_test as ch


class TestCase(ch.TestCaseWrapper):
    TIMEOUT = 2

    def test_1(self):
        self.mock_input.input_list = cycle(['sim', 'sim', 'não'])
        self.program()
        self.assertFalse(True)
'''

TARGET_CODE_24 = '''
print('Começando')
continuar = True
while continuar:
    if input('Continuar? ') != 'sim':
        continuar = False
print('Fim')
'''


class StrTestTest(unittest.TestCase):
    def test_doesnt_break_with_syntax_error(self):
        result = str_test.run_tests(TARGET_CODE_0, TEST_CODE1, 'ex1')
        print(result)
        print("_____________________________")
        self.assertFalse(result.success)
        self.assertEqual(1, len(result.failure_msgs))
        self.assertEqual('Erro de sintaxe (código Python inválido)',
                         result.failure_msgs[0])
        print(str(result.stack_traces[0]))

        self.assertEqual(2, result.total_tests)

    def test_doesnt_break_with_missing_function(self):
        f_name = 'wrong_name'
        result = str_test.run_tests(TARGET_CODE_1, TEST_CODE1, f_name)
        self.assertFalse(result.success)
        self.assertEqual(1, len(result.failure_msgs))
        self.assertEqual(
            'Função não encontrada. Sua função deveria se chamar {}'.format(
                f_name), result.failure_msgs[0])
        self.assertEqual(2, result.total_tests)

    def test_pass_all_tests(self):
        result = str_test.run_tests(TARGET_CODE_1, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(0, len(result.failure_msgs))
        self.assertEqual(2, result.total_tests)

    def test_timeout(self):
        result = str_test.run_tests(TARGET_CODE_2, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(2, len(result.failure_msgs))
        self.assertEqual(str_test.TIME_LIMIT_EXCEEDED,
                         result.failure_msgs[0])
        self.assertEqual(str_test.TIME_LIMIT_EXCEEDED,
                         result.failure_msgs[1])
        self.assertEqual(2, result.total_tests)

    def test_one_failure(self):
        result = str_test.run_tests(TARGET_CODE_3, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(1, len(result.failure_msgs))
        self.assertEqual('Não funcionou para caso com zero.',
                         result.failure_msgs[0])
        self.assertEqual(2, result.total_tests)

    def test_division_by_zero(self):
        result = str_test.run_tests(TARGET_CODE_4, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(2, len(result.failure_msgs))
        self.assertEqual('Não funcionou para caso com zero.',
                         result.failure_msgs[0])
        self.assertEqual(str_test.DEFAULT_MSG, result.failure_msgs[1])
        self.assertEqual(2, result.total_tests)

    def test_print(self):
        result = str_test.run_tests(TARGET_CODE_5, TEST_CODE2,
                                          'code_with_print')
        self.assertEqual(1, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_print_failure(self):
        result = str_test.run_tests(TARGET_CODE_6, TEST_CODE2,
                                          'code_with_print')
        self.assertEqual(1, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(1, result.total_tests)

    def test_input(self):
        result = str_test.run_tests(TARGET_CODE_7, TEST_CODE3,
                                          'input_and_sum')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_fail_input(self):
        result = str_test.run_tests(TARGET_CODE_8, TEST_CODE3,
                                          'input_and_sum')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(2, result.total_tests)

    def test_run_program_if_no_function(self):
        result = str_test.run_tests(TARGET_CODE_9, TEST_CODE4, '')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_run_program_if_none_function(self):
        result = str_test.run_tests(TARGET_CODE_9, TEST_CODE4, None)
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_run_program_with_error(self):
        result = str_test.run_tests(TARGET_CODE_10, TEST_CODE4, None)
        self.assertFalse(result.success)
        self.assertEqual(2, len(result.failure_msgs))
        for i in range(2):
            self.assertEqual('Não funcionou para algum teste',
                             result.failure_msgs[i])
        self.assertEqual(2, result.total_tests)

    def test_open(self):
        result = str_test.run_tests(TARGET_CODE_11, TEST_CODE5, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_with_open(self):
        result = str_test.run_tests(TARGET_CODE_12, TEST_CODE5, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_open_file_that_doesnt_exist(self):
        result = str_test.run_tests(TARGET_CODE_13, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('FileNotFoundError' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_read_file_opened_for_writing(self):
        result = str_test.run_tests(TARGET_CODE_14, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('UnsupportedOperation' in result.stack_traces[0])
        self.assertTrue('not readable' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_read_file_opened_for_appending(self):
        result = str_test.run_tests(TARGET_CODE_15, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('UnsupportedOperation' in result.stack_traces[0])
        self.assertTrue('not readable' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_write_file_opened_for_reading(self):
        result = str_test.run_tests(TARGET_CODE_16, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('UnsupportedOperation' in result.stack_traces[0])
        self.assertTrue('not writable' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_write(self):
        result = str_test.run_tests(TARGET_CODE_17, TEST_CODE6, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_append(self):
        result = str_test.run_tests(TARGET_CODE_18, TEST_CODE7, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_doesnt_allow_input_in_function_test(self):
        result = str_test.run_tests(TARGET_CODE_19, TEST_CODE8,
                                          'do_nothing')
        self.assertFalse(result.success)
        self.assertTrue('input' in result.failure_msgs[0])
        self.assertEqual(1, result.total_tests)

    def test_use_random_randint(self):
        result = str_test.run_tests(TARGET_CODE_20, TEST_CODE9,
                                          'random_int')
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

        result = str_test.run_tests(TARGET_CODE_21, TEST_CODE9,
                                          'random_int')
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

        result = str_test.run_tests(TARGET_CODE_22, TEST_CODE9,
                                          'random_int')
        self.assertFalse(result.success)
        self.assertTrue(
            'Não deveria executar o randint com os argumentos 1, 10' in
            result.failure_msgs[0])
        self.assertEqual(1, result.total_tests)

    def test_doesnt_break_with_multiple_inputs(self):
        result = str_test.run_tests(TARGET_CODE_23, TEST_CODE10, None)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_get_stdout(self):
        result = str_test.run_tests(TARGET_CODE_24, TEST_CODE11, None)
        self.assertFalse(result.success)
        self.assertEqual([('Começando', ), ('Continuar? ', 'sim'),
                          ('Continuar? ', 'sim'), ('Continuar? ', 'não'),
                          ('Fim', )], result.stdouts[0])
        self.assertEqual(1, result.total_tests)


class TestCaseWrapperTest(unittest.TestCase):
    def setUp(self):
        self.test_case_wrapper = str_test.TestCaseWrapper()
        self.test_case_wrapper.setUp()

    def test_assert_printed_string(self):
        expected_print = 'Who watches Bleach in 2019?'
        print(expected_print)
        self.test_case_wrapper.assert_printed(expected_print)

    def test_assert_printed_number(self):
        expected_print = 42
        print(expected_print)
        self.test_case_wrapper.assert_printed(expected_print)
        self.test_case_wrapper.assert_printed(str(expected_print))

    def test_assert_printed_substring(self):
        complete_print = 'Bleach was fine until Aizen'
        print(complete_print)
        self.test_case_wrapper.assert_printed(complete_print[2:8])

    def test_assert_printed_index(self):
        print('First string')
        print('Second string')
        self.test_case_wrapper.assert_printed('First', 0)
        self.test_case_wrapper.assert_printed('Second', 1)

    def test_assert_printed_all(self):
        print('Not related')
        print('First string')
        print('Other random')
        print('Second string')
        print('Some more prints')
        self.test_case_wrapper.assert_printed_all(['First', 'Second'])

    def test_assert_printed_all_exactly(self):
        print(10)
        print(20)
        self.test_case_wrapper.assert_printed_all([10, '20'])

    def test_assert_printed_all_not_correct_order(self):
        print('Not related')
        print('Second string')
        print('Other random')
        print('First string')
        print('Some more prints')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed_all(['First', 'Second'])

    def test_assert_printed_fails_string(self):
        print('Ora ora ora')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Yare yare daze')

    def test_assert_printed_fails_number(self):
        print(42)
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed(666)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('666')

    def test_assert_printed_fails_substring(self):
        print('Ora ora ora')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Yare')

    def test_assert_printed_fails_index(self):
        print('Ora ora ora')
        print('Yare yare daze')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Yare', 0)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Ora', 1)

    def test_assert_similar_errors(self):
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_similar('yare yara Dake', 'yars yari daze', 3, True)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_similar('yare yara Dake', 'yars yari daze', 2, True)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_similar('omae mou shindeiru nani', 'Nani', 5, True)

    def test_assert_similar_correctly(self):
        self.test_case_wrapper.assert_similar('yare yara Dake', 'yars yari daze', 3, False)
        self.test_case_wrapper.assert_similar('yare kene Dake', 'yars yari daze', 7, True)
        self.test_case_wrapper.assert_similar('omae mou shinDeiru nani', 'omae mou shindeiru', 5, False)


if __name__ == '__main__':
    unittest.main()

# -*- coding: utf-8 -*-

import unittest
from strtest import str_test

TEST_CODE1 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    TIMEOUT = 1

    @str_test.error_message('Não funcionou para caso com zero.')
    def test_numbers_3_0(self):
        self.assertEqual(self.function(3,0), 3)

    def test_numbers_3_4(self):
        self.assertEqual(self.function(3,4), 4, 'Não funcionou para caso com dois números positivos.')
'''

TARGET_CODE_0 = '''
def ex1(a, b)
    return max(a, b)
'''

TARGET_CODE_1 = '''
def ex1(a, b):
    return max(a, b)
'''

TARGET_CODE_2 = '''
def ex1(a, b):
    while True:
        pass
    return max(a, b)
'''

TARGET_CODE_3 = '''
def ex1(a, b):
    if b == 0:
        return 0
    return max(a, b)
'''

TARGET_CODE_4 = '''
def ex1(a, b):
    return a / 0
'''

TEST_CODE2 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_print_called(self):
        for i in range(5):
            text = 'hi{0}'.format(i)
            self.function(text)
            self.assertEqual(self.mock_print.calls, i+1)
            self.assertEqual(self.mock_print.printed[i], text)
'''

TARGET_CODE_5 = '''
def code_with_print(a):
    print(a)
'''

TARGET_CODE_6 = '''
def code_with_print(a):
    pass
'''

TEST_CODE3 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_input_called(self):
        self.mock_input.input_list = ['3', 2, 5, '1']
        result = self.function()
        self.assertEqual(self.mock_input.calls, 4)
        self.assertEqual(result, 8)

    def test_no_sum(self):
        self.mock_input.input_list = [0]
        result = self.function()
        self.assertEqual(self.mock_input.calls, 1)
        self.assertEqual(result, 0)
'''

TARGET_CODE_7 = '''
def input_and_sum():
    n = int(input('N?'))
    result = 0
    while n > 0:
        result += int(input('Type a number'))
        n -= 1
    return result
'''

TARGET_CODE_8 = '''
def input_and_sum():
    n = input('N?')
    result = 0
    while n > 0:
        result += input('Type a number')
        n -= 1
    return result
'''

TEST_CODE4 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_print_called(self):
        self.mock_input.input_list = ['Inspermon']
        self.program()
        self.assertEqual(self.mock_input.calls, 1)
        self.assertEqual(self.mock_print.calls, 1)
        self.assertEqual(self.mock_print.printed[0], 'Hello Inspermon!')

    def test_hello_world(self):
        self.mock_input.input_list = ['World']
        self.program()
        self.assertEqual(self.mock_input.calls, 1)
        self.assertEqual(self.mock_print.calls, 1)
        self.assertEqual(self.mock_print.printed[0], 'Hello World!')
'''

TARGET_CODE_9 = '''
name = input('Name? ')
print('Hello {0}!'.format(name))
'''

TARGET_CODE_10 = '''
name = input('Name? ')
pritn('Hello {0}!'.format(name))
'''

TEST_CODE5 = '''
from strtest import str_test
import re

class TestCase(str_test.TestCaseWrapper):
    def test_open_called(self):
        words_str = 'some,words,separated,by,comma\\nwith,some,new,lines\\n\\n'
        words = [w for w in re.split(',|\\n', words_str) if w]
        self.mock_open.files['words.csv'] =  words_str
        self.program()
        self.assertEqual(self.mock_open.calls, 1)
        self.assertEqual(len(self.mock_open.opened), 0)
        printed = [word.strip() for word in self.mock_print.printed if word.strip()]
        self.assertEqual(printed, words)
'''

TARGET_CODE_11 = '''
f = open('words.csv', 'r')
words = []
for line in f:
    words += line.split(',')
words = [word.strip() for word in words if word]
for word in words:
    print(word)
f.close()
'''

TARGET_CODE_12 = '''
with open('words.csv', 'r') as f:
    words = []
    for line in f:
        words += [w.strip() for w in line.split(',') if w.strip()]
    for word in words:
        print(word)
'''

TARGET_CODE_13 = '''
with open('file_that_doesnt_exist.txt', 'r') as f:
    words = []
    for line in f:
        words += line.split(',')
    for word in words:
        print(word)
'''

TARGET_CODE_14 = '''
with open('words.csv', 'w') as f:
    words = []
    for line in f:
        words += [w.strip() for w in line.split(',') if w.strip()]
    for word in words:
        print(word)
'''

TARGET_CODE_15 = '''
with open('words.csv', 'a') as f:
    words = []
    for line in f:
        words += [w.strip() for w in line.split(',') if w.strip()]
    for word in words:
        print(word)
'''

TARGET_CODE_16 = '''
with open('words.csv', 'r') as f:
    f.write("Shouldn't work")
'''

TEST_CODE6 = '''
from strtest import str_test
import re

class TestCase(str_test.TestCaseWrapper):
    def test_write(self):
        self.program()
        self.assertEqual(self.mock_open.calls, 1)
        self.assertEqual(len(self.mock_open.opened), 0)
        self.assertEqual(self.mock_open.files['newfile.txt'], 'New content')
'''

TARGET_CODE_17 = '''
with open('newfile.txt', 'w') as f:
    f.write('New content')
'''

TEST_CODE7 = '''
from strtest import str_test
import re

class TestCase(str_test.TestCaseWrapper):
    def test_write(self):
        self.mock_open.files['test.txt'] = 'Old content'
        self.program()
        self.assertEqual(self.mock_open.calls, 1)
        self.assertEqual(len(self.mock_open.opened), 0)
        self.assertEqual(self.mock_open.files['test.txt'], 'Old content\\nNew content')
'''

TARGET_CODE_18 = '''
with open('test.txt', 'a') as f:
    f.write('\\nNew content')
'''

TEST_CODE8 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_do_nothing(self):
        self.function(0)
'''

TARGET_CODE_19 = '''
def do_nothing(arg):
    return arg

arg = input('Should not use input in function questions: ')
print(do_nothing(arg))
'''

TEST_CODE9 = '''
from strtest import str_test

class TestCase(str_test.TestCaseWrapper):
    def test_random_int(self):
        numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
        self.mock_random.randint[(1, 20)] = numbers
        for n in numbers:
            recebido = self.function()
            self.assertEqual(n, recebido, 'ESPERAVA OUTRO NUMERO. RECEBI: {0}, QUERIA: {1}'.format(recebido, n))
        self.assertEqual(len(numbers), self.mock_random.randint.calls)
'''

TARGET_CODE_20 = '''
import random

def random_int():
    return random.randint(1, 20)
'''

TARGET_CODE_21 = '''
from random import randint

def random_int():
    return randint(1, 20)
'''

TARGET_CODE_22 = '''
from random import randint

def random_int():
    return randint(1, 10)
'''

TEST_CODE10 = '''
from strtest import str_test as ch
from itertools import cycle


class TestCase(ch.TestCaseWrapper):
    TIMEOUT = 2

    def test_1(self):
        self.mock_input.input_list = cycle(['sim', 'talvez', 'ainda um pouco', 'não'])
        self.program()
        self.assertEqual(
            self.mock_input.calls, 4,
            'Número de chamadas para o input foi diferente do esperado')
        self.assertEqual(self.mock_print.calls, 4,
                         'Use exatamente um print por resposta do usuário')
        for i in range(3):
            self.assertTrue('Pratique mais' in self.mock_print.printed[i])
        self.assertTrue('Até a próxima' in self.mock_print.printed[-1])

    def test_de_primeira(self):
        self.mock_input.input_list = cycle(['não'])
        self.program()
        self.assertEqual(
            self.mock_input.calls, 1,
            'Número de chamadas para o input foi diferente do esperado')
        self.assertEqual(self.mock_print.calls, 1,
                         'Use exatamente um print por resposta do usuário')
        self.assertTrue('Até a próxima' in self.mock_print.printed[-1])
'''

TARGET_CODE_23 = '''
resp_aluno = True
while resp_aluno == True:
    resp_D_aluno = input("Você tem mais dúvidas? ")
    if resp_D_aluno == "não":
        resp_aluno = False
        print ("Até a próxima")
    else:
        print("Pratique mais")
'''

TEST_CODE11 = '''
from strtest import str_test as ch


class TestCase(ch.TestCaseWrapper):
    TIMEOUT = 2

    def test_1(self):
        self.mock_input.input_list = cycle(['sim', 'sim', 'não'])
        self.program()
        self.assertFalse(True)
'''

TARGET_CODE_24 = '''
print('Começando')
continuar = True
while continuar:
    if input('Continuar? ') != 'sim':
        continuar = False
print('Fim')
'''


class StrTestTest(unittest.TestCase):
    def test_doesnt_break_with_syntax_error(self):
        result = str_test.run_tests(TARGET_CODE_0, TEST_CODE1, 'ex1')
        print(result)
        print("_____________________________")
        self.assertFalse(result.success)
        self.assertEqual(1, len(result.failure_msgs))
        self.assertEqual('Erro de sintaxe (código Python inválido)',
                         result.failure_msgs[0])
        print(str(result.stack_traces[0]))

        self.assertEqual(2, result.total_tests)

    def test_doesnt_break_with_missing_function(self):
        f_name = 'wrong_name'
        result = str_test.run_tests(TARGET_CODE_1, TEST_CODE1, f_name)
        self.assertFalse(result.success)
        self.assertEqual(1, len(result.failure_msgs))
        self.assertEqual(
            'Função não encontrada. Sua função deveria se chamar {}'.format(
                f_name), result.failure_msgs[0])
        self.assertEqual(2, result.total_tests)

    def test_pass_all_tests(self):
        result = str_test.run_tests(TARGET_CODE_1, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(0, len(result.failure_msgs))
        self.assertEqual(2, result.total_tests)

    def test_timeout(self):
        result = str_test.run_tests(TARGET_CODE_2, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(2, len(result.failure_msgs))
        self.assertEqual(str_test.TIME_LIMIT_EXCEEDED,
                         result.failure_msgs[0])
        self.assertEqual(str_test.TIME_LIMIT_EXCEEDED,
                         result.failure_msgs[1])
        self.assertEqual(2, result.total_tests)

    def test_one_failure(self):
        result = str_test.run_tests(TARGET_CODE_3, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(1, len(result.failure_msgs))
        self.assertEqual('Não funcionou para caso com zero.',
                         result.failure_msgs[0])
        self.assertEqual(2, result.total_tests)

    def test_division_by_zero(self):
        result = str_test.run_tests(TARGET_CODE_4, TEST_CODE1, 'ex1')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(2, len(result.failure_msgs))
        self.assertEqual('Não funcionou para caso com zero.',
                         result.failure_msgs[0])
        self.assertEqual(str_test.DEFAULT_MSG, result.failure_msgs[1])
        self.assertEqual(2, result.total_tests)

    def test_print(self):
        result = str_test.run_tests(TARGET_CODE_5, TEST_CODE2,
                                          'code_with_print')
        self.assertEqual(1, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_print_failure(self):
        result = str_test.run_tests(TARGET_CODE_6, TEST_CODE2,
                                          'code_with_print')
        self.assertEqual(1, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(1, result.total_tests)

    def test_input(self):
        result = str_test.run_tests(TARGET_CODE_7, TEST_CODE3,
                                          'input_and_sum')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_fail_input(self):
        result = str_test.run_tests(TARGET_CODE_8, TEST_CODE3,
                                          'input_and_sum')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertFalse(result.success)
        self.assertEqual(2, result.total_tests)

    def test_run_program_if_no_function(self):
        result = str_test.run_tests(TARGET_CODE_9, TEST_CODE4, '')
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_run_program_if_none_function(self):
        result = str_test.run_tests(TARGET_CODE_9, TEST_CODE4, None)
        self.assertEqual(2, result.result_obj.testsRun)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_run_program_with_error(self):
        result = str_test.run_tests(TARGET_CODE_10, TEST_CODE4, None)
        self.assertFalse(result.success)
        self.assertEqual(2, len(result.failure_msgs))
        for i in range(2):
            self.assertEqual('Não funcionou para algum teste',
                             result.failure_msgs[i])
        self.assertEqual(2, result.total_tests)

    def test_open(self):
        result = str_test.run_tests(TARGET_CODE_11, TEST_CODE5, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_with_open(self):
        result = str_test.run_tests(TARGET_CODE_12, TEST_CODE5, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_open_file_that_doesnt_exist(self):
        result = str_test.run_tests(TARGET_CODE_13, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('FileNotFoundError' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_read_file_opened_for_writing(self):
        result = str_test.run_tests(TARGET_CODE_14, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('UnsupportedOperation' in result.stack_traces[0])
        self.assertTrue('not readable' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_read_file_opened_for_appending(self):
        result = str_test.run_tests(TARGET_CODE_15, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('UnsupportedOperation' in result.stack_traces[0])
        self.assertTrue('not readable' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_write_file_opened_for_reading(self):
        result = str_test.run_tests(TARGET_CODE_16, TEST_CODE5, None)
        self.assertFalse(result.success)
        self.assertTrue('UnsupportedOperation' in result.stack_traces[0])
        self.assertTrue('not writable' in result.stack_traces[0])
        self.assertEqual(1, result.total_tests)

    def test_write(self):
        result = str_test.run_tests(TARGET_CODE_17, TEST_CODE6, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_append(self):
        result = str_test.run_tests(TARGET_CODE_18, TEST_CODE7, None)
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

    def test_doesnt_allow_input_in_function_test(self):
        result = str_test.run_tests(TARGET_CODE_19, TEST_CODE8,
                                          'do_nothing')
        self.assertFalse(result.success)
        self.assertTrue('input' in result.failure_msgs[0])
        self.assertEqual(1, result.total_tests)

    def test_use_random_randint(self):
        result = str_test.run_tests(TARGET_CODE_20, TEST_CODE9,
                                          'random_int')
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

        result = str_test.run_tests(TARGET_CODE_21, TEST_CODE9,
                                          'random_int')
        self.assertTrue(result.success)
        self.assertEqual(1, result.total_tests)

        result = str_test.run_tests(TARGET_CODE_22, TEST_CODE9,
                                          'random_int')
        self.assertFalse(result.success)
        self.assertTrue(
            'Não deveria executar o randint com os argumentos 1, 10' in
            result.failure_msgs[0])
        self.assertEqual(1, result.total_tests)

    def test_doesnt_break_with_multiple_inputs(self):
        result = str_test.run_tests(TARGET_CODE_23, TEST_CODE10, None)
        self.assertTrue(result.success)
        self.assertEqual(2, result.total_tests)

    def test_get_stdout(self):
        result = str_test.run_tests(TARGET_CODE_24, TEST_CODE11, None)
        self.assertFalse(result.success)
        self.assertEqual([('Começando', ), ('Continuar? ', 'sim'),
                          ('Continuar? ', 'sim'), ('Continuar? ', 'não'),
                          ('Fim', )], result.stdouts[0])
        self.assertEqual(1, result.total_tests)


class TestCaseWrapperTest(unittest.TestCase):
    def setUp(self):
        self.test_case_wrapper = str_test.TestCaseWrapper()
        self.test_case_wrapper.setUp()

    def test_assert_printed_string(self):
        expected_print = 'Who watches Bleach in 2019?'
        print(expected_print)
        self.test_case_wrapper.assert_printed(expected_print)

    def test_assert_printed_number(self):
        expected_print = 42
        print(expected_print)
        self.test_case_wrapper.assert_printed(expected_print)
        self.test_case_wrapper.assert_printed(str(expected_print))

    def test_assert_printed_substring(self):
        complete_print = 'Bleach was fine until Aizen'
        print(complete_print)
        self.test_case_wrapper.assert_printed(complete_print[2:8])

    def test_assert_printed_index(self):
        print('First string')
        print('Second string')
        self.test_case_wrapper.assert_printed('First', 0)
        self.test_case_wrapper.assert_printed('Second', 1)

    def test_assert_printed_all(self):
        print('Not related')
        print('First string')
        print('Other random')
        print('Second string')
        print('Some more prints')
        self.test_case_wrapper.assert_printed_all(['First', 'Second'])

    def test_assert_printed_all_exactly(self):
        print(10)
        print(20)
        self.test_case_wrapper.assert_printed_all([10, '20'])

    def test_assert_printed_all_not_correct_order(self):
        print('Not related')
        print('Second string')
        print('Other random')
        print('First string')
        print('Some more prints')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed_all(['First', 'Second'])

    def test_assert_printed_fails_string(self):
        print('Ora ora ora')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Yare yare daze')

    def test_assert_printed_fails_number(self):
        print(42)
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed(666)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('666')

    def test_assert_printed_fails_substring(self):
        print('Ora ora ora')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Yare')

    def test_assert_printed_fails_index(self):
        print('Ora ora ora')
        print('Yare yare daze')
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Yare', 0)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_printed('Ora', 1)

    def test_assert_similar_errors(self):
        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_similar('yare yara Dake', 'yars yari daze', 3, True)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_similar('yare yara Dake', 'yars yari daze', 2, True)

        with self.assertRaises(AssertionError):
            self.test_case_wrapper.assert_similar('omae mou shindeiru nani', 'Nani', 5, True)

    def test_assert_similar_correctly(self):
        self.test_case_wrapper.assert_similar('yare yara Dake', 'yars yari daze', 3, False)
        self.test_case_wrapper.assert_similar('yare kene Dake', 'yars yari daze', 7, True)
        self.test_case_wrapper.assert_similar('omae mou shinDeiru nani', 'omae mou shindeiru', 5, False)


if __name__ == '__main__':
    unittest.main()

# -*- coding: utf-8 -*- from strtest import str_test  class TestCase(str_test.TestCaseWrapper):     TIMEOUT = 1      @str_test.error_message('Não funcionou para caso com zero.')     def test_numbers_3_0(self):         self.assertEqual(self.function(3,0), 3)      def test_numbers_3_4(self):         self.assertEqual(self.function(3,4), 4, 'Não funcionou para caso com dois números positivos.') def ex1(a, b)     return max(a, b) def ex1(a, b):     return max(a, b) def ex1(a, b):     while True:         pass     return max(a, b) def ex1(a, b):     if b == 0:         return 0     return max(a, b) def ex1(a, b):     return a / 0 from strtest import str_test  class TestCase(str_test.TestCaseWrapper):     def test_print_called(self):         for i in range(5):             text = 'hi{0}'.format(i)             self.function(text)             self.assertEqual(self.mock_print.calls, i+1)             self.assertEqual(self.mock_print.printed[i], text) def code_with_print(a):     print(a) def code_with_print(a):     pass from strtest import str_test  class TestCase(str_test.TestCaseWrapper):     def test_input_called(self):         self.mock_input.input_list = ['3', 2, 5, '1']         result = self.function()         self.assertEqual(self.mock_input.calls, 4)         self.assertEqual(result, 8)      def test_no_sum(self):         self.mock_input.input_list = [0]         result = self.function()         self.assertEqual(self.mock_input.calls, 1)         self.assertEqual(result, 0) def input_and_sum():     n = int(input('N?'))     result = 0     while n > 0:         result += int(input('Type a number'))         n -= 1     return result def input_and_sum():     n = input('N?')     result = 0     while n > 0:         result += input('Type a number')         n -= 1     return result from strtest import str_test  class TestCase(str_test.TestCaseWrapper):     def test_print_called(self):         self.mock_input.input_list = ['Inspermon']         self.program()         self.assertEqual(self.mock_input.calls, 1)         self.assertEqual(self.mock_print.calls, 1)         self.assertEqual(self.mock_print.printed[0], 'Hello Inspermon!')      def test_hello_world(self):         self.mock_input.input_list = ['World']         self.program()         self.assertEqual(self.mock_input.calls, 1)         self.assertEqual(self.mock_print.calls, 1)         self.assertEqual(self.mock_print.printed[0], 'Hello World!') name = input('Name? ') print('Hello {0}!'.format(name)) name = input('Name? ') pritn('Hello {0}!'.format(name)) from strtest import str_test import re  class TestCase(str_test.TestCaseWrapper):     def test_open_called(self):         words_str = 'some,words,separated,by,comma\\nwith,some,new,lines\\n\\n'         words = [w for w in re.split(',|\\n', words_str) if w]         self.mock_open.files['words.csv'] =  words_str         self.program()         self.assertEqual(self.mock_open.calls, 1)         self.assertEqual(len(self.mock_open.opened), 0)         printed = [word.strip() for word in self.mock_print.printed if word.strip()]         self.assertEqual(printed, words) f = open('words.csv', 'r') words = [] for line in f:     words += line.split(',') words = [word.strip() for word in words if word] for word in words:     print(word) f.close() with open('words.csv', 'r') as f:     words = []     for line in f:         words += [w.strip() for w in line.split(',') if w.strip()]     for word in words:         print(word) with open('file_that_doesnt_exist.txt', 'r') as f:     words = []     for line in f:         words += line.split(',')     for word in words:         print(word) with open('words.csv', 'w') as f:     words = []     for line in f:         words += [w.strip() for w in line.split(',') if w.strip()]     for word in words:         print(word) with open('words.csv', 'a') as f:     words = []     for line in f:         words += [w.strip() for w in line.split(',') if w.strip()]     for word in words:         print(word) with open('words.csv', 'r') as f:     f.write("Shouldn't work") from strtest import str_test import re  class TestCase(str_test.TestCaseWrapper):     def test_write(self):         self.program()         self.assertEqual(self.mock_open.calls, 1)         self.assertEqual(len(self.mock_open.opened), 0)         self.assertEqual(self.mock_open.files['newfile.txt'], 'New content') with open('newfile.txt', 'w') as f:     f.write('New content') from strtest import str_test import re  class TestCase(str_test.TestCaseWrapper):     def test_write(self):         self.mock_open.files['test.txt'] = 'Old content'         self.program()         self.assertEqual(self.mock_open.calls, 1)         self.assertEqual(len(self.mock_open.opened), 0)         self.assertEqual(self.mock_open.files['test.txt'], 'Old content\\nNew content') with open('test.txt', 'a') as f:     f.write('\\nNew content') from strtest import str_test  class TestCase(str_test.TestCaseWrapper):     def test_do_nothing(self):         self.function(0) def do_nothing(arg):     return arg  arg = input('Should not use input in function questions: ') print(do_nothing(arg)) from strtest import str_test  class TestCase(str_test.TestCaseWrapper):     def test_random_int(self):         numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]         self.mock_random.randint[(1, 20)] = numbers         for n in numbers:             recebido = self.function()             self.assertEqual(n, recebido, 'ESPERAVA OUTRO NUMERO. RECEBI: {0}, QUERIA: {1}'.format(recebido, n))         self.assertEqual(len(numbers), self.mock_random.randint.calls) import random  def random_int():     return random.randint(1, 20) from random import randint  def random_int():     return randint(1, 20) from random import randint  def random_int():     return randint(1, 10) from strtest import str_test as ch from itertools import cycle   class TestCase(ch.TestCaseWrapper):     TIMEOUT = 2      def test_1(self):         self.mock_input.input_list = cycle(['sim', 'talvez', 'ainda um pouco', 'não'])         self.program()         self.assertEqual(             self.mock_input.calls, 4,             'Número de chamadas para o input foi diferente do esperado')         self.assertEqual(self.mock_print.calls, 4,                          'Use exatamente um print por resposta do usuário')         for i in range(3):             self.assertTrue('Pratique mais' in self.mock_print.printed[i])         self.assertTrue('Até a próxima' in self.mock_print.printed[-1])      def test_de_primeira(self):         self.mock_input.input_list = cycle(['não'])         self.program()         self.assertEqual(             self.mock_input.calls, 1,             'Número de chamadas para o input foi diferente do esperado')         self.assertEqual(self.mock_print.calls, 1,                          'Use exatamente um print por resposta do usuário')         self.assertTrue('Até a próxima' in self.mock_print.printed[-1]) resp_aluno = True while resp_aluno == True:     resp_D_aluno = input("Você tem mais dúvidas? ")     if resp_D_aluno == "não":         resp_aluno = False         print ("Até a próxima")     else:         print("Pratique mais") from strtest import str_test as ch   class TestCase(ch.TestCaseWrapper):     TIMEOUT = 2      def test_1(self):         self.mock_input.input_list = cycle(['sim', 'sim', 'não'])         self.program()         self.assertFalse(True) print('Começando') continuar = True while continuar:     if input('Continuar? ') != 'sim':         continuar = False print('Fim')